Merge branch 'multiple-stations'
This commit is contained in:
commit
7e6095f541
16
package-lock.json
generated
16
package-lock.json
generated
@ -9,6 +9,8 @@
|
|||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@simrail/types": "^0.0.4",
|
||||||
|
"@types/mongoose": "^5.11.97",
|
||||||
"dayjs": "^1.11.12",
|
"dayjs": "^1.11.12",
|
||||||
"ejs": "^3.1.10",
|
"ejs": "^3.1.10",
|
||||||
"express": "^4.19.2",
|
"express": "^4.19.2",
|
||||||
@ -85,6 +87,11 @@
|
|||||||
"@redis/client": "^1.0.0"
|
"@redis/client": "^1.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@simrail/types": {
|
||||||
|
"version": "0.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/@simrail/types/-/types-0.0.4.tgz",
|
||||||
|
"integrity": "sha512-AknM5FP+crERb3m/YtZqCgdFbrwUEwYB4BXfv1z+b7CVSrRsidAnaMIJZw/MhmsGxAmNIqQK7RPhDEx8qNzblA=="
|
||||||
|
},
|
||||||
"node_modules/@types/body-parser": {
|
"node_modules/@types/body-parser": {
|
||||||
"version": "1.19.5",
|
"version": "1.19.5",
|
||||||
"resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz",
|
"resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz",
|
||||||
@ -140,6 +147,15 @@
|
|||||||
"integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==",
|
"integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/mongoose": {
|
||||||
|
"version": "5.11.97",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/mongoose/-/mongoose-5.11.97.tgz",
|
||||||
|
"integrity": "sha512-cqwOVYT3qXyLiGw7ueU2kX9noE8DPGRY6z8eUxudhXY8NZ7DMKYAxyZkLSevGfhCX3dO/AoX5/SO9lAzfjon0Q==",
|
||||||
|
"deprecated": "Mongoose publishes its own types, so you do not need to install this package.",
|
||||||
|
"dependencies": {
|
||||||
|
"mongoose": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@types/node": {
|
"node_modules/@types/node": {
|
||||||
"version": "22.0.0",
|
"version": "22.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.0.0.tgz",
|
||||||
|
@ -4,7 +4,8 @@
|
|||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "tsc",
|
"build": "tsc",
|
||||||
"postbuild": "copyfiles --error --up 1 src/http/views/*.* dist"
|
"postbuild": "copyfiles --error --up 1 src/http/views/*.* dist",
|
||||||
|
"dev": "npm run build && doppler run node dist"
|
||||||
},
|
},
|
||||||
"keywords": [],
|
"keywords": [],
|
||||||
"author": "",
|
"author": "",
|
||||||
@ -19,6 +20,8 @@
|
|||||||
},
|
},
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@simrail/types": "^0.0.4",
|
||||||
|
"@types/mongoose": "^5.11.97",
|
||||||
"dayjs": "^1.11.12",
|
"dayjs": "^1.11.12",
|
||||||
"ejs": "^3.1.10",
|
"ejs": "^3.1.10",
|
||||||
"express": "^4.19.2",
|
"express": "^4.19.2",
|
||||||
|
@ -5,7 +5,6 @@ Prosty projekt, logujący wyjścia z posterunków.
|
|||||||
- Ułatwienie zgłaszania graczy, którzy robią "Hit and Run" (psuje i wychodze z posterunku)
|
- Ułatwienie zgłaszania graczy, którzy robią "Hit and Run" (psuje i wychodze z posterunku)
|
||||||
|
|
||||||
## Dalszy rozwój
|
## Dalszy rozwój
|
||||||
- Wybieranie serwerów
|
|
||||||
- Obsługa pociagów, a nie tylko posterunków
|
- Obsługa pociagów, a nie tylko posterunków
|
||||||
|
|
||||||
# Jak korzystać?
|
# Jak korzystać?
|
||||||
|
@ -26,9 +26,37 @@ export class ApiModule {
|
|||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const generateSearch = (regex: RegExp) => [
|
||||||
|
{
|
||||||
|
stationName: { $regex: regex },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
userUsername: { $regex: regex },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
stationShort: { $regex: regex },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
userSteamId: { $regex: regex },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
server: { $regex: regex },
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
app.get('/search', async (req, res) => {
|
app.get('/search', async (req, res) => {
|
||||||
if (!req.query.q) return res.redirect('/');
|
if (!req.query.q) return res.redirect('/');
|
||||||
const records = await MLog.find({ $text: { $search: req.query.q as string } })
|
const s = req.query.q.toString().split(',').map(x => new RegExp(x, "i"));
|
||||||
|
|
||||||
|
const records = await MLog.aggregate([
|
||||||
|
{
|
||||||
|
$match: {
|
||||||
|
$and: [
|
||||||
|
...s.map(x => ({ $or: generateSearch(x) }))
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
])
|
||||||
.sort({ leftDate: -1 })
|
.sort({ leftDate: -1 })
|
||||||
.limit(30)
|
.limit(30)
|
||||||
res.render('search.ejs', {
|
res.render('search.ejs', {
|
||||||
|
@ -44,8 +44,8 @@
|
|||||||
|
|
||||||
<body>
|
<body>
|
||||||
<header>
|
<header>
|
||||||
<h1><a style="color: white; text-decoration: none;" href="/">SimRail Logs [<span
|
<h1><a style="color: white; text-decoration: none;" href="/">SimRail Logs</a></h1>
|
||||||
style="color:hotpink">PL2</span>]</a></h1>
|
<p><a href="https://git.alekswilc.dev/alekswilc/simrail-logs">Dokumentacja</a></p>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<div class="details">
|
<div class="details">
|
||||||
@ -55,8 +55,10 @@
|
|||||||
</a></p>
|
</a></p>
|
||||||
<p>Stacja: <%= record.stationName %>
|
<p>Stacja: <%= record.stationName %>
|
||||||
</p>
|
</p>
|
||||||
<p>Data wejścia: <%= dayjs(record.joinedDate).format('HH:mm DD/MM/YYYY') %> (<%=
|
<p>Serwer: <%= record.server.toUpperCase() %>
|
||||||
dayjs(record.joinedDate).fromNow() %>)</p>
|
</p>
|
||||||
|
<p>Data wejścia: <%= record.joinedDate ? dayjs(record.joinedDate).format('HH:mm DD/MM/YYYY') : '--:-- --/--/--' %> (<%=
|
||||||
|
record.joinedDate ? dayjs(record.joinedDate).fromNow() : '--' %>)</p>
|
||||||
<p>Data wyjścia: <%= dayjs(record.leftDate).format('HH:mm DD/MM/YYYY') %> (<%= dayjs(record.leftDate).fromNow()
|
<p>Data wyjścia: <%= dayjs(record.leftDate).format('HH:mm DD/MM/YYYY') %> (<%= dayjs(record.leftDate).fromNow()
|
||||||
%>)</p>
|
%>)</p>
|
||||||
|
|
||||||
@ -65,8 +67,9 @@
|
|||||||
<br />
|
<br />
|
||||||
<code class="clickable" style="white-space: pre-line" onclick="copydata()" id="data">;station: <%= record.stationName %>
|
<code class="clickable" style="white-space: pre-line" onclick="copydata()" id="data">;station: <%= record.stationName %>
|
||||||
;steam: <%= record.userSteamId %>
|
;steam: <%= record.userSteamId %>
|
||||||
|
;server: <%= record.server %>
|
||||||
;name: <%= record.userUsername %>
|
;name: <%= record.userUsername %>
|
||||||
;joined: <%=dayjs(record.joinedDate).format()%>
|
;joined: <%=record.joinedDate ? dayjs(record.joinedDate).format() : 'no-data'%>
|
||||||
;left: <%=dayjs(record.leftDate).format()%>
|
;left: <%=dayjs(record.leftDate).format()%>
|
||||||
;url: https://simrail.alekswilc.dev/details/<%= record.id %>/
|
;url: https://simrail.alekswilc.dev/details/<%= record.id %>/
|
||||||
</code>
|
</code>
|
||||||
|
@ -22,27 +22,39 @@
|
|||||||
|
|
||||||
<body>
|
<body>
|
||||||
<header>
|
<header>
|
||||||
<h1><a style="color: white; text-decoration: none;" href="/">SimRail Logs [<span style="color:hotpink">PL2</span>]</a></h1>
|
<h1><a style="color: white; text-decoration: none;" href="/">SimRail Logs</a></h1>
|
||||||
|
<p><a href="https://git.alekswilc.dev/alekswilc/simrail-logs">Dokumentacja</a></p>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<h2>Wyszukaj posterunek lub osobe</h2>
|
<h2>Wyszukaj posterunek, osobe lub serwer</h2>
|
||||||
|
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<input type="text" id="search">
|
<input type="text" id="search">
|
||||||
<button onclick="search()">Szukaj</button>
|
<button onclick="search()">Szukaj</button>
|
||||||
|
<p>Użyj przecinka, aby wyszukać wiele wartości: pl2,Łazy</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h2>Ostatnie opuszczenia posterunków</h2>
|
<h2>Ostatnie opuszczenia posterunków</h2>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<% records.forEach(record => { %>
|
<% records.forEach(record=> { %>
|
||||||
<li>
|
<li>
|
||||||
<details>
|
<details>
|
||||||
|
<summary>[<span style="color:lightskyblue">
|
||||||
<summary>[<span style="color:lightskyblue"><%= record.stationShort %></span>] <span style="color: lightskyblue"><%= record.stationName %></span> - <span style="color:hotpink"><%= record.userUsername %></span>
|
<%= record.server.toUpperCase() %>
|
||||||
<p style="margin-bottom: 0; opacity: 0.5;"><%= dayjs(record.leftDate).format('HH:mm DD/MM/YYYY') %></p></summary>
|
</span>] <span style="color: lightskyblue">
|
||||||
<p>Data dołączenia: <%= dayjs(record.joinedDate).format('HH:mm DD/MM/YYYY') %> (<%= dayjs(record.joinedDate).fromNow() %>)</p>
|
<%= record.stationName %>
|
||||||
<p>Data wyjścia: <%= dayjs(record.leftDate).format('HH:mm DD/MM/YYYY') %> (<%= dayjs(record.leftDate).fromNow() %>)</p>
|
</span> - <span style="color:hotpink">
|
||||||
|
<%= record.userUsername %>
|
||||||
|
</span>
|
||||||
|
<p style="margin-bottom: 0; opacity: 0.5;">
|
||||||
|
<%= dayjs(record.leftDate).format('HH:mm DD/MM/YYYY') %>
|
||||||
|
</p>
|
||||||
|
</summary>
|
||||||
|
<p>Data dołączenia: <%= record.joinedDate ? dayjs(record.joinedDate).format('HH:mm DD/MM/YYYY') : '--:-- --/--/--' %> (<%=
|
||||||
|
record.joinedDate ? dayjs(record.joinedDate).fromNow() : '--' %>)</p>
|
||||||
|
<p>Data wyjścia: <%= dayjs(record.leftDate).format('HH:mm DD/MM/YYYY') %> (<%=
|
||||||
|
dayjs(record.leftDate).fromNow() %>)</p>
|
||||||
<a href="/details/<%= record.id %>">
|
<a href="/details/<%= record.id %>">
|
||||||
<button>Więcej</button>
|
<button>Więcej</button>
|
||||||
</a>
|
</a>
|
||||||
|
@ -23,16 +23,17 @@
|
|||||||
|
|
||||||
<body>
|
<body>
|
||||||
<header>
|
<header>
|
||||||
<h1><a style="color: white; text-decoration: none;" href="/">SimRail Logs [<span
|
<h1><a style="color: white; text-decoration: none;" href="/">SimRail Logs</a></h1>
|
||||||
style="color:hotpink">PL2</span>]</a></h1>
|
<p><a href="https://git.alekswilc.dev/alekswilc/simrail-logs">Dokumentacja</a></p>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<h2>Wyszukaj posterunek lub osobe</h2>
|
<h2>Wyszukaj posterunek, osobe lub serwer</h2>
|
||||||
|
|
||||||
|
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<input type="text" id="search" value="<%=q%>">
|
<input type="text" id="search" value="<%=q%>">
|
||||||
<button onclick="search()">Szukaj</button>
|
<button onclick="search()">Szukaj</button>
|
||||||
|
<p>Użyj przecinka, aby wyszukać wiele wartości: pl2,Łazy</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h2>Wyniki wyszukiwania</h2>
|
<h2>Wyniki wyszukiwania</h2>
|
||||||
@ -41,9 +42,8 @@
|
|||||||
<% records.forEach(record=> { %>
|
<% records.forEach(record=> { %>
|
||||||
<li>
|
<li>
|
||||||
<details>
|
<details>
|
||||||
|
|
||||||
<summary>[<span style="color:lightskyblue">
|
<summary>[<span style="color:lightskyblue">
|
||||||
<%= record.stationShort %>
|
<%= record.server.toUpperCase() %>
|
||||||
</span>] <span style="color: lightskyblue">
|
</span>] <span style="color: lightskyblue">
|
||||||
<%= record.stationName %>
|
<%= record.stationName %>
|
||||||
</span> - <span style="color:hotpink">
|
</span> - <span style="color:hotpink">
|
||||||
@ -53,8 +53,8 @@
|
|||||||
<%= dayjs(record.leftDate).format('HH:mm DD/MM/YYYY') %>
|
<%= dayjs(record.leftDate).format('HH:mm DD/MM/YYYY') %>
|
||||||
</p>
|
</p>
|
||||||
</summary>
|
</summary>
|
||||||
<p>Data dołączenia: <%= dayjs(record.joinedDate).format('HH:mm DD/MM/YYYY') %> (<%=
|
<p>Data dołączenia: <%= record.joinedDate ? dayjs(record.joinedDate).format('HH:mm DD/MM/YYYY') : '--:-- --/--/--' %> (<%=
|
||||||
dayjs(record.joinedDate).fromNow() %>)</p>
|
record.joinedDate ? dayjs(record.joinedDate).fromNow() : '--' %>)</p>
|
||||||
<p>Data wyjścia: <%= dayjs(record.leftDate).format('HH:mm DD/MM/YYYY') %> (<%=
|
<p>Data wyjścia: <%= dayjs(record.leftDate).format('HH:mm DD/MM/YYYY') %> (<%=
|
||||||
dayjs(record.leftDate).fromNow() %>)</p>
|
dayjs(record.leftDate).fromNow() %>)</p>
|
||||||
<a href="/details/<%= record.id %>">
|
<a href="/details/<%= record.id %>">
|
||||||
|
10
src/index.ts
10
src/index.ts
@ -5,8 +5,8 @@ import dayjs from 'dayjs';
|
|||||||
import { StationsModule } from './modules/stations.js';
|
import { StationsModule } from './modules/stations.js';
|
||||||
import { ApiModule } from './http/api.js';
|
import { ApiModule } from './http/api.js';
|
||||||
import mongoose from 'mongoose';
|
import mongoose from 'mongoose';
|
||||||
import { IStation } from './types/station.js';
|
|
||||||
import { IPlayer } from './types/player.js';
|
import { IPlayer } from './types/player.js';
|
||||||
|
import { Station, Server } from '@simrail/types';
|
||||||
|
|
||||||
|
|
||||||
; (async () => {
|
; (async () => {
|
||||||
@ -22,12 +22,12 @@ import { IPlayer } from './types/player.js';
|
|||||||
console.log('MongoDB connected');
|
console.log('MongoDB connected');
|
||||||
global.client = new SimrailClient();
|
global.client = new SimrailClient();
|
||||||
|
|
||||||
client.on(SimrailClientEvents.StationJoined, (station: IStation, player: IPlayer) => {
|
client.on(SimrailClientEvents.StationJoined, (server: Server, station: Station, player: IPlayer) => {
|
||||||
console.log(`${station.Name} | ${player.personaname} joined`);
|
console.log(`${server.ServerCode} |${station.Name} | ${player.personaname} joined`);
|
||||||
});
|
});
|
||||||
|
|
||||||
client.on(SimrailClientEvents.StationLeft, (station: IStation, player: IPlayer, joinedAt: number) => {
|
client.on(SimrailClientEvents.StationLeft, (server: Server, station: Station, player: IPlayer, joinedAt: number) => {
|
||||||
console.log(`${station.Name} | ${player.personaname} left. | ${joinedAt ? dayjs(joinedAt).fromNow() : 'no time data.'}`);
|
console.log(`${server.ServerCode} | ${station.Name} | ${player.personaname} left. | ${joinedAt ? dayjs(joinedAt).fromNow() : 'no time data.'}`);
|
||||||
});
|
});
|
||||||
|
|
||||||
StationsModule.load();
|
StationsModule.load();
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
|
import { Server, Station } from '@simrail/types';
|
||||||
import { MLog } from '../mongo/logs.js';
|
import { MLog } from '../mongo/logs.js';
|
||||||
import { IPlayer } from '../types/player.js';
|
import { IPlayer } from '../types/player.js';
|
||||||
import { IStation } from '../types/station.js';
|
|
||||||
import { SimrailClientEvents } from '../util/SimrailClient.js';
|
import { SimrailClientEvents } from '../util/SimrailClient.js';
|
||||||
import { v4 } from 'uuid';
|
import { v4 } from 'uuid';
|
||||||
|
|
||||||
export class StationsModule {
|
export class StationsModule {
|
||||||
public static load() {
|
public static load() {
|
||||||
|
|
||||||
client.on(SimrailClientEvents.StationLeft, (station: IStation, player: IPlayer, joinedAt: number) => {
|
client.on(SimrailClientEvents.StationLeft, (server: Server, station: Station, player: IPlayer, joinedAt: number) => {
|
||||||
const date = new Date();
|
const date = new Date();
|
||||||
|
|
||||||
MLog.create({
|
MLog.create({
|
||||||
@ -19,7 +19,7 @@ export class StationsModule {
|
|||||||
leftDate: date.getTime(),
|
leftDate: date.getTime(),
|
||||||
stationName: station.Name,
|
stationName: station.Name,
|
||||||
stationShort: station.Prefix,
|
stationShort: station.Prefix,
|
||||||
server: 'pl2'
|
server: server.ServerCode
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,7 @@ const schema = new Schema<ILog>(
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
schema.index({ stationName: 'text', userUsername: 'text', stationShort: 'text', userSteamId: 'text' })
|
schema.index({ stationName: 'text', userUsername: 'text', stationShort: 'text', userSteamId: 'text', server: 'text' })
|
||||||
|
|
||||||
export type TMLog = Model<ILog>
|
export type TMLog = Model<ILog>
|
||||||
|
|
||||||
|
@ -1,4 +0,0 @@
|
|||||||
export type ISimrailPayload = {
|
|
||||||
result: boolean;
|
|
||||||
description: string;
|
|
||||||
}
|
|
@ -1,3 +1,5 @@
|
|||||||
|
/* steam api */
|
||||||
|
|
||||||
export type IPlayer = {
|
export type IPlayer = {
|
||||||
steamid: string,
|
steamid: string,
|
||||||
communityvisibilitystate: number,
|
communityvisibilitystate: number,
|
||||||
|
@ -1,23 +0,0 @@
|
|||||||
import { ISimrailPayload } from './payload.js';
|
|
||||||
|
|
||||||
export type IStation = {
|
|
||||||
Name: string;
|
|
||||||
Prefix: string;
|
|
||||||
DifficultyLevel: number;
|
|
||||||
Latititude: number;
|
|
||||||
Longitude: number;
|
|
||||||
MainImageURL: string;
|
|
||||||
AdditionalImage1URL: string;
|
|
||||||
AdditionalImage2URL: string;
|
|
||||||
DispatchedBy: IStationDispatch[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export type IStationDispatch = {
|
|
||||||
ServerCode: string,
|
|
||||||
SteamId: number
|
|
||||||
}
|
|
||||||
|
|
||||||
export type IStationPayload = {
|
|
||||||
data: IStation[];
|
|
||||||
count: number;
|
|
||||||
} & ISimrailPayload;
|
|
@ -3,7 +3,7 @@ import { IPlayerPayload } from '../types/player.js';
|
|||||||
const STEAM_API_KEY = process.env.STEAM_APIKEY;
|
const STEAM_API_KEY = process.env.STEAM_APIKEY;
|
||||||
|
|
||||||
export class PlayerUtil {
|
export class PlayerUtil {
|
||||||
public static async getPlayer(steamId: string) {
|
public static async getPlayer(steamId: number | string) {
|
||||||
const data = (await fetch(`https://api.steampowered.com/ISteamUser/GetPlayerSummaries/v2/?key=${STEAM_API_KEY}&format=json&steamids=${steamId}`).then(x => x.json())) as IPlayerPayload;
|
const data = (await fetch(`https://api.steampowered.com/ISteamUser/GetPlayerSummaries/v2/?key=${STEAM_API_KEY}&format=json&steamids=${steamId}`).then(x => x.json())) as IPlayerPayload;
|
||||||
if (!data.response.players) return;
|
if (!data.response.players) return;
|
||||||
return data.response.players[0];
|
return data.response.players[0];
|
||||||
|
@ -1,25 +1,29 @@
|
|||||||
import { EventEmitter } from 'node:events';
|
import { EventEmitter } from 'node:events';
|
||||||
import { IStation, IStationPayload } from '../types/station.js';
|
|
||||||
import { IPlayer } from '../types/player.js';
|
import { IPlayer } from '../types/player.js';
|
||||||
import { PlayerUtil } from './PlayerUtil.js';
|
import { PlayerUtil } from './PlayerUtil.js';
|
||||||
|
import { Station, ApiResponse, Server } from '@simrail/types';
|
||||||
|
|
||||||
export enum SimrailClientEvents {
|
export enum SimrailClientEvents {
|
||||||
StationJoined = 'stationJoined',
|
StationJoined = 'stationJoined',
|
||||||
StationLeft = 'stationLeft',
|
StationLeft = 'stationLeft',
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export declare interface SimrailClient {
|
export declare interface SimrailClient {
|
||||||
on(event: SimrailClientEvents.StationJoined, listener: (station: IStation, player: IPlayer) => void): this;
|
on(event: SimrailClientEvents.StationJoined, listener: (server: Server, station: Station, player: IPlayer) => void): this;
|
||||||
on(event: SimrailClientEvents.StationLeft, listener: (station: IStation, player: IPlayer, joinedAt: number) => void): this;
|
on(event: SimrailClientEvents.StationLeft, listener: (server: Server, station: Station, player: IPlayer, joinedAt: number) => void): this;
|
||||||
|
|
||||||
on(event: string, listener: Function): this;
|
//on(event: string, listener: Function): this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type OccupiedStation = {
|
||||||
|
SteamId: string;
|
||||||
|
JoinedAt: number;
|
||||||
|
}
|
||||||
|
|
||||||
export class SimrailClient extends EventEmitter {
|
export class SimrailClient extends EventEmitter {
|
||||||
public stations: IStation[] = [];
|
public stations: Record<Server['ServerCode'], Station[]> = {};
|
||||||
public stationsOccupied: Record<string, { steamId: string; joinedAt: number } | null> = {};
|
public stationsOccupied: Record<Server['ServerCode'], Record<string, OccupiedStation | null>> = {};
|
||||||
|
|
||||||
public constructor() {
|
public constructor() {
|
||||||
super();
|
super();
|
||||||
@ -27,9 +31,9 @@ export class SimrailClient extends EventEmitter {
|
|||||||
setTimeout(() => setInterval(() => this.update(), 500), 1000)
|
setTimeout(() => setInterval(() => this.update(), 500), 1000)
|
||||||
}
|
}
|
||||||
|
|
||||||
public getStation(name: string) {
|
public getStation(server: Server['ServerCode'], name: string) {
|
||||||
if (!this.stationsOccupied[name]) return null;
|
if (!this.stationsOccupied[server] || !this.stationsOccupied[server][name]) return null;
|
||||||
const player = PlayerUtil.getPlayer(this.stationsOccupied[name].steamId);
|
const player = PlayerUtil.getPlayer(this.stationsOccupied[server][name].SteamId);
|
||||||
return { player, joinedAt: this.stationsOccupied[name].joinedAt };
|
return { player, joinedAt: this.stationsOccupied[name].joinedAt };
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -41,55 +45,62 @@ export class SimrailClient extends EventEmitter {
|
|||||||
if (!await redis.json.get('stations_occupied'))
|
if (!await redis.json.get('stations_occupied'))
|
||||||
redis.json.set('stations_occupied', '$', {});
|
redis.json.set('stations_occupied', '$', {});
|
||||||
|
|
||||||
this.stations = (await redis.json.get('stations') as unknown as IStation[]);
|
this.stations = (await redis.json.get('stations') as unknown as SimrailClient['stations']);
|
||||||
this.stationsOccupied = (await redis.json.get('stations_occupied') as unknown as Record<string, { steamId: string; joinedAt: number } | null>);
|
this.stationsOccupied = (await redis.json.get('stations_occupied') as unknown as SimrailClient['stationsOccupied']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private async update() {
|
private async update() {
|
||||||
const servers = (await fetch('https://panel.simrail.eu:8084/stations-open?serverCode=pl2').then(x => x.json())) as IStationPayload;
|
const servers = (await fetch('https://panel.simrail.eu:8084/servers-open').then(x => x.json()) as ApiResponse<Server>)
|
||||||
if (!servers.result) return
|
.data?.filter(x => x.ServerName.includes('Polski')) ?? []; // no plans to support other servers
|
||||||
|
|
||||||
|
|
||||||
if (!this.stations.length) {
|
// TODO: maybe node:worker_threads?
|
||||||
this.stations = servers.data;
|
// TODO: check performance
|
||||||
redis.json.set('list', '$', this.stations);
|
servers.forEach(async (server) => {
|
||||||
return
|
const stations = (await fetch('https://panel.simrail.eu:8084/stations-open?serverCode=' + server.ServerCode).then(x => x.json())) as ApiResponse<Station>;
|
||||||
|
if (!stations.result) return;
|
||||||
|
|
||||||
|
if (!this.stations[server.ServerCode]) this.stations[server.ServerCode] = [];
|
||||||
|
if (!this.stationsOccupied[server.ServerCode]) this.stationsOccupied[server.ServerCode] = {};
|
||||||
|
|
||||||
|
if (!this.stations[server.ServerCode].length) {
|
||||||
|
this.stations[server.ServerCode] = stations.data;
|
||||||
|
redis.json.set('stations', '$', this.stations);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
stations.data.forEach(async (x) => {
|
||||||
servers.data.forEach(async (x) => {
|
const data = this.stations[server.ServerCode].find(y => y.Name === x.Name);
|
||||||
const data = this.stations.find(y => y.Name === x.Name);
|
|
||||||
if (!data) return;
|
if (!data) return;
|
||||||
|
|
||||||
|
|
||||||
if (data.DispatchedBy[0]?.SteamId !== x.DispatchedBy[0]?.SteamId) {
|
if (data.DispatchedBy[0]?.SteamId !== x.DispatchedBy[0]?.SteamId) {
|
||||||
|
|
||||||
if (!data.DispatchedBy[0]?.SteamId) {
|
if (!data.DispatchedBy[0]?.SteamId) {
|
||||||
// join
|
// join
|
||||||
const date = new Date();
|
const date = new Date();
|
||||||
const player = await PlayerUtil.getPlayer(x.DispatchedBy[0]?.SteamId.toString());
|
const player = await PlayerUtil.getPlayer(x.DispatchedBy[0]?.SteamId);
|
||||||
|
|
||||||
this.emit(SimrailClientEvents.StationJoined, x, player);
|
this.emit(SimrailClientEvents.StationJoined, server, x, player);
|
||||||
this.stationsOccupied[data.Prefix] = {
|
this.stationsOccupied[server.ServerCode][data.Prefix] = {
|
||||||
steamId: x.DispatchedBy[0]?.SteamId.toString(),
|
SteamId: x.DispatchedBy[0]?.SteamId,
|
||||||
joinedAt: date.getTime()
|
JoinedAt: date.getTime()
|
||||||
}
|
};
|
||||||
redis.json.set('stations_occupied', '$', this.stationsOccupied);
|
redis.json.set('stations_occupied', '$', this.stationsOccupied);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// leave
|
||||||
|
const player = await PlayerUtil.getPlayer(data.DispatchedBy[0]?.SteamId)
|
||||||
|
|
||||||
const player = await PlayerUtil.getPlayer(data.DispatchedBy[0]?.SteamId.toString())
|
this.emit(SimrailClientEvents.StationLeft, server, x, player, this.stationsOccupied[server.ServerCode][data.Prefix]?.JoinedAt);
|
||||||
|
delete this.stationsOccupied[server.ServerCode][data.Prefix];
|
||||||
this.emit(SimrailClientEvents.StationLeft, x, player, this.stationsOccupied[data.Prefix]?.joinedAt);
|
|
||||||
delete this.stationsOccupied[data.Prefix];
|
|
||||||
redis.json.set('stations_occupied', '$', this.stationsOccupied);
|
redis.json.set('stations_occupied', '$', this.stationsOccupied);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
this.stations = servers.data;
|
this.stations[server.ServerCode] = stations.data;
|
||||||
redis.json.set('stations', '$', this.stations);
|
redis.json.set('stations', '$', this.stations);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user