forked from simrail/simrail.pro
code cleanup for v3
This commit is contained in:
parent
9c84989063
commit
e2732c2008
Binary file not shown.
Before Width: | Height: | Size: 22 KiB |
Binary file not shown.
Before Width: | Height: | Size: 29 KiB |
Binary file not shown.
Before Width: | Height: | Size: 40 KiB |
@ -1,9 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="WEB_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$" />
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
@ -1,9 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="WEB_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$" />
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
@ -1,85 +0,0 @@
|
||||
import { Router } from 'express';
|
||||
import dayjs from 'dayjs';
|
||||
import { msToTime } from '../../util/time.js';
|
||||
|
||||
import { PipelineStage } from 'mongoose';
|
||||
import { MProfile, raw_schema } from '../../mongo/profile.js';
|
||||
import { GitUtil } from '../../util/git.js';
|
||||
import { escapeRegexString } from '../../util/functions.js';
|
||||
|
||||
const generateSearch = (regex: RegExp) => [
|
||||
{
|
||||
steam: { $regex: regex },
|
||||
},
|
||||
{
|
||||
steamName: { $regex: regex },
|
||||
},
|
||||
]
|
||||
|
||||
export class LeaderboardRoute {
|
||||
static load() {
|
||||
const app = Router();
|
||||
|
||||
app.get('/train', async (req, res) => {
|
||||
const s = req.query.q?.toString().split(',').map(x => new RegExp(escapeRegexString(x), "i"));
|
||||
|
||||
const filter: PipelineStage[] = [];
|
||||
|
||||
|
||||
s && filter.push({
|
||||
$match: {
|
||||
$and: [
|
||||
...s.map(x => ({ $or: generateSearch(x) }))
|
||||
]
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
const records = await MProfile.aggregate(filter)
|
||||
.sort({ trainPoints: -1 })
|
||||
.limit(10)
|
||||
|
||||
|
||||
|
||||
res.render('leaderboard/index.ejs', {
|
||||
records,
|
||||
dayjs,
|
||||
msToTime,
|
||||
type: 'train',
|
||||
q: req.query.q,
|
||||
...GitUtil.getData(),
|
||||
});
|
||||
})
|
||||
|
||||
|
||||
app.get('/station', async (req, res) => {
|
||||
const s = req.query.q?.toString().split(',').map(x => new RegExp(escapeRegexString(x), "i"));
|
||||
|
||||
const filter: PipelineStage[] = [];
|
||||
|
||||
|
||||
s && filter.push({
|
||||
$match: {
|
||||
$and: [
|
||||
...s.map(x => ({ $or: generateSearch(x) }))
|
||||
]
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
const records = await MProfile.aggregate(filter)
|
||||
.sort({ dispatcherTime: -1 })
|
||||
.limit(10)
|
||||
res.render('leaderboard/index.ejs', {
|
||||
records,
|
||||
dayjs,
|
||||
msToTime,
|
||||
type: 'station',
|
||||
q: req.query.q,
|
||||
...GitUtil.getData(),
|
||||
});
|
||||
})
|
||||
|
||||
return app;
|
||||
}
|
||||
}
|
@ -1,98 +0,0 @@
|
||||
import { Router } from 'express';
|
||||
import { MLog } from '../../mongo/logs.js';
|
||||
import dayjs from 'dayjs';
|
||||
import { msToTime } from '../../util/time.js';
|
||||
import { PipelineStage } from 'mongoose';
|
||||
import { MBlacklist } from '../../mongo/blacklist.js';
|
||||
import { SteamUtil } from '../../util/SteamUtil.js';
|
||||
import { GitUtil } from '../../util/git.js';
|
||||
import { escapeRegexString } from '../../util/functions.js';
|
||||
|
||||
const generateSearch = (regex: RegExp) => [
|
||||
{
|
||||
stationName: { $regex: regex },
|
||||
},
|
||||
{
|
||||
userUsername: { $regex: regex },
|
||||
},
|
||||
{
|
||||
stationShort: { $regex: regex },
|
||||
},
|
||||
{
|
||||
userSteamId: { $regex: regex },
|
||||
},
|
||||
{
|
||||
server: { $regex: regex },
|
||||
}
|
||||
]
|
||||
|
||||
export class StationsRoute {
|
||||
static load() {
|
||||
const app = Router();
|
||||
|
||||
app.get('/', async (req, res) => {
|
||||
const s = req.query.q?.toString().split(',').map(x => new RegExp(escapeRegexString(x), "i"));
|
||||
|
||||
const filter: PipelineStage[] = [];
|
||||
|
||||
|
||||
s && filter.push({
|
||||
$match: {
|
||||
$and: [
|
||||
...s.map(x => ({ $or: generateSearch(x) }))
|
||||
]
|
||||
}
|
||||
})
|
||||
|
||||
const records = await MLog.aggregate(filter)
|
||||
.sort({ leftDate: -1 })
|
||||
.limit(30)
|
||||
res.render('stations/index.ejs', {
|
||||
records,
|
||||
dayjs,
|
||||
q: req.query.q,
|
||||
msToTime,
|
||||
...GitUtil.getData()
|
||||
});
|
||||
})
|
||||
|
||||
app.get('/details/:id', async (req, res) => {
|
||||
if (!req.params.id) return res.redirect('/stations/');
|
||||
const record = await MLog.findOne({ id: req.params.id });
|
||||
const blacklist = await MBlacklist.findOne({ steam: record?.userSteamId! });
|
||||
if (blacklist && blacklist.status) return res.redirect('/stations/');
|
||||
const player = await SteamUtil.getPlayer(record?.userSteamId!);
|
||||
|
||||
res.render('stations/details.ejs', {
|
||||
record,
|
||||
dayjs,
|
||||
player,
|
||||
msToTime,
|
||||
...GitUtil.getData()
|
||||
});
|
||||
})
|
||||
|
||||
|
||||
// API ENDPOINTS
|
||||
// CREATE AN ISSUE IF YOU NEED API ACCESS: https://git.alekswilc.dev/alekswilc/simrail-logs/issues
|
||||
/*
|
||||
app.get('/api/last', async (req, res) => {
|
||||
const records = await MLog.find()
|
||||
.sort({ leftDate: -1 })
|
||||
.limit(30)
|
||||
res.json({ code: 200, records });
|
||||
})
|
||||
|
||||
app.get('/api/search', async (req, res) => {
|
||||
if (!req.query.q) return res.send('invalid');
|
||||
const records = await MLog.find({ $text: { $search: req.query.q as string } })
|
||||
.sort({ leftDate: -1 })
|
||||
.limit(30)
|
||||
|
||||
res.json({ code: 200, records });
|
||||
})*/
|
||||
|
||||
|
||||
return app;
|
||||
}
|
||||
}
|
@ -1,133 +0,0 @@
|
||||
import { Router } from 'express';
|
||||
import dayjs from 'dayjs';
|
||||
import { msToTime } from '../../util/time.js';
|
||||
import { PipelineStage } from 'mongoose';
|
||||
import { MTrainLog, raw_schema } from '../../mongo/trainLogs.js';
|
||||
import { MBlacklist } from '../../mongo/blacklist.js';
|
||||
import { SteamUtil } from '../../util/SteamUtil.js';
|
||||
import { GitUtil } from '../../util/git.js';
|
||||
import { escapeRegexString } from '../../util/functions.js';
|
||||
|
||||
const generateSearch = (regex: RegExp) => [
|
||||
{
|
||||
trainNumber: { $regex: regex },
|
||||
},
|
||||
{
|
||||
userSteamId: { $regex: regex },
|
||||
},
|
||||
{
|
||||
server: { $regex: regex },
|
||||
},
|
||||
{
|
||||
userUsername: { $regex: regex },
|
||||
},
|
||||
]
|
||||
|
||||
export class TrainsRoute {
|
||||
static load() {
|
||||
const app = Router();
|
||||
|
||||
app.get('/', async (req, res) => {
|
||||
const s = req.query.q?.toString().split(',').map(x => new RegExp(escapeRegexString(x), "i"));
|
||||
|
||||
const filter: PipelineStage[] = [];
|
||||
|
||||
|
||||
s && filter.push({
|
||||
$match: {
|
||||
$and: [
|
||||
...s.map(x => ({ $or: generateSearch(x) }))
|
||||
]
|
||||
}
|
||||
})
|
||||
|
||||
const records = await MTrainLog.aggregate(filter)
|
||||
.sort({ leftDate: -1 })
|
||||
.limit(30)
|
||||
res.render('trains/index.ejs', {
|
||||
records,
|
||||
dayjs,
|
||||
q: req.query.q,
|
||||
msToTime,
|
||||
...GitUtil.getData()
|
||||
});
|
||||
})
|
||||
|
||||
app.get('/details/:id', async (req, res) => {
|
||||
if (!req.params.id) return res.redirect('/trains/');
|
||||
const record = await MTrainLog.findOne({ id: req.params.id });
|
||||
const player = await SteamUtil.getPlayer(record?.userSteamId!);
|
||||
const blacklist = await MBlacklist.findOne({ steam: record?.userSteamId! });
|
||||
if (blacklist && blacklist.status) return res.redirect('/trains/');
|
||||
|
||||
res.render('trains/details.ejs', {
|
||||
record,
|
||||
dayjs,
|
||||
player,
|
||||
msToTime,
|
||||
...GitUtil.getData()
|
||||
});
|
||||
})
|
||||
|
||||
app.get('/leaderboard/', async (req, res) => {
|
||||
const s = req.query.q?.toString().split(',').map(x => new RegExp(escapeRegexString(x), "i"));
|
||||
|
||||
const data = Object.keys(raw_schema)
|
||||
.reduce((o, key) => ({ ...o, [key]: `$${key}` }), {});
|
||||
|
||||
const filter: PipelineStage[] = [
|
||||
{
|
||||
$project: {
|
||||
// record.leftDate - record.joinedDate
|
||||
result: { $subtract: ['$leftDate', '$joinedDate'] },
|
||||
...data
|
||||
}
|
||||
},
|
||||
];
|
||||
|
||||
s && filter.unshift(
|
||||
{
|
||||
$match: {
|
||||
$and: [
|
||||
...s.map(x => ({ $or: generateSearch(x) }))
|
||||
]
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
const records = await MTrainLog.aggregate(filter)
|
||||
.sort({ result: -1 })
|
||||
.limit(30)
|
||||
res.render('trains/leaderboard.ejs', {
|
||||
records,
|
||||
dayjs,
|
||||
q: req.query.q,
|
||||
msToTime
|
||||
});
|
||||
})
|
||||
|
||||
|
||||
// API ENDPOINTS
|
||||
// CREATE AN ISSUE IF YOU NEED API ACCESS: https://git.alekswilc.dev/alekswilc/simrail-logs/issues
|
||||
/*
|
||||
app.get('/api/last', async (req, res) => {
|
||||
const records = await MLog.find()
|
||||
.sort({ leftDate: -1 })
|
||||
.limit(30)
|
||||
res.json({ code: 200, records });
|
||||
})
|
||||
|
||||
app.get('/api/search', async (req, res) => {
|
||||
if (!req.query.q) return res.send('invalid');
|
||||
const records = await MLog.find({ $text: { $search: req.query.q as string } })
|
||||
.sort({ leftDate: -1 })
|
||||
.limit(30)
|
||||
|
||||
res.json({ code: 200, records });
|
||||
})*/
|
||||
|
||||
|
||||
return app;
|
||||
}
|
||||
}
|
@ -1,51 +0,0 @@
|
||||
import { Server, Station } from '@simrail/types';
|
||||
import { MLog } from '../mongo/logs.js';
|
||||
import { IPlayer } from '../types/player.js';
|
||||
import { SimrailClientEvents } from '../util/SimrailClient.js';
|
||||
import { v4 } from 'uuid';
|
||||
import { MProfile } from '../mongo/profile.js';
|
||||
import { SteamUtil } from '../util/SteamUtil.js';
|
||||
|
||||
export class StationsModule {
|
||||
public static load() {
|
||||
|
||||
client.on(SimrailClientEvents.StationLeft, async (server: Server, station: Station, player: IPlayer, joinedAt: number) => {
|
||||
const stats = await SteamUtil.getPlayerStats(player.steamid);
|
||||
const date = new Date();
|
||||
if (stats) {
|
||||
const time = joinedAt ? (date.getTime() - joinedAt) : 0;
|
||||
|
||||
const userProfile = await MProfile.findOne({ steam: player.steamid }) ?? await MProfile.create({ steam: player.steamid, id: v4(), steamName: player.personaname });
|
||||
if (!userProfile.dispatcherStats) userProfile.dispatcherStats = {};
|
||||
|
||||
if (userProfile.dispatcherStats[station.Name]) {
|
||||
userProfile.dispatcherStats[station.Name].time = userProfile.dispatcherStats[station.Name].time + time;
|
||||
} else {
|
||||
userProfile.dispatcherStats[station.Name] = {
|
||||
time
|
||||
}
|
||||
}
|
||||
|
||||
if (Number.isNaN(userProfile.dispatcherStats[station.Name].time)) userProfile.dispatcherStats[station.Name].time = 0;
|
||||
|
||||
if (!userProfile.dispatcherTime) userProfile.dispatcherTime = 0;
|
||||
|
||||
userProfile.dispatcherTime = userProfile.dispatcherTime + time;
|
||||
|
||||
await MProfile.findOneAndUpdate({ id: userProfile.id }, { dispatcherStats: userProfile.dispatcherStats, dispatcherTime: userProfile.dispatcherTime })
|
||||
}
|
||||
|
||||
MLog.create({
|
||||
id: v4(),
|
||||
userSteamId: player.steamid,
|
||||
userAvatar: player.avatarfull,
|
||||
userUsername: player.personaname,
|
||||
joinedDate: joinedAt,
|
||||
leftDate: date.getTime(),
|
||||
stationName: station.Name,
|
||||
stationShort: station.Prefix,
|
||||
server: server.ServerCode
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
@ -1,61 +0,0 @@
|
||||
import { Server, Station, Train } from '@simrail/types';
|
||||
import { MLog } from '../mongo/logs.js';
|
||||
import { IPlayer } from '../types/player.js';
|
||||
import { SimrailClientEvents } from '../util/SimrailClient.js';
|
||||
import { v4 } from 'uuid';
|
||||
import { getVehicle } from '../util/contants.js';
|
||||
import { MProfile } from '../mongo/profile.js';
|
||||
import { MTrainLog } from '../mongo/trainLogs.js';
|
||||
|
||||
export class TrainsModule {
|
||||
public static load() {
|
||||
|
||||
client.on(SimrailClientEvents.TrainLeft, async (server: Server, train: Train, player: IPlayer, joinedAt: number, leftAt: number, points: number, distance: number, vehicle: string) => {
|
||||
if (distance) {
|
||||
const time = joinedAt ? (leftAt - joinedAt) : 0;
|
||||
const userProfile = await MProfile.findOne({ steam: player.steamid }) ?? await MProfile.create({ steam: player.steamid, id: v4(), steamName: player.personaname });
|
||||
|
||||
const vehicleName = getVehicle(vehicle) ?? vehicle;
|
||||
|
||||
if (!userProfile.trainStats) userProfile.trainStats = {};
|
||||
|
||||
if (userProfile.trainStats[vehicleName]) {
|
||||
userProfile.trainStats[vehicleName].distance = userProfile.trainStats[vehicleName].distance + distance;
|
||||
userProfile.trainStats[vehicleName].score = userProfile.trainStats[vehicleName].score + points;
|
||||
userProfile.trainStats[vehicleName].time = userProfile.trainStats[vehicleName].time + time;
|
||||
} else {
|
||||
userProfile.trainStats[vehicleName] = {
|
||||
distance, score: points, time
|
||||
}
|
||||
}
|
||||
|
||||
if (!userProfile.trainTime) userProfile.trainTime = 0;
|
||||
|
||||
userProfile.trainTime = userProfile.trainTime + time;
|
||||
|
||||
if (!userProfile.trainPoints) userProfile.trainPoints = 0;
|
||||
|
||||
userProfile.trainPoints = userProfile.trainPoints + points;
|
||||
|
||||
if (!userProfile.trainDistance) userProfile.trainDistance = 0;
|
||||
|
||||
userProfile.trainDistance = userProfile.trainDistance + distance;
|
||||
|
||||
await MProfile.findOneAndUpdate({ id: userProfile.id }, { trainStats: userProfile.trainStats, trainTime: userProfile.trainTime, trainPoints: userProfile.trainPoints, trainDistance: userProfile.trainDistance });
|
||||
}
|
||||
|
||||
MTrainLog.create({
|
||||
id: v4(),
|
||||
userSteamId: player.steamid,
|
||||
userAvatar: player.avatarfull,
|
||||
userUsername: player.personaname,
|
||||
joinedDate: joinedAt,
|
||||
leftDate: leftAt,
|
||||
trainNumber: train.TrainNoLocal,
|
||||
server: server.ServerCode,
|
||||
distance, points,
|
||||
trainName: train.TrainName
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
@ -1,236 +0,0 @@
|
||||
import { EventEmitter } from 'node:events';
|
||||
|
||||
import { IPlayer } from '../types/player.js';
|
||||
import { PlayerUtil } from './PlayerUtil.js';
|
||||
import { Station, ApiResponse, Server, Train } from '@simrail/types';
|
||||
|
||||
export enum SimrailClientEvents {
|
||||
StationJoined = 'stationJoined',
|
||||
StationLeft = 'stationLeft',
|
||||
TrainJoined = 'trainJoined',
|
||||
TrainLeft = 'trainLeft',
|
||||
|
||||
}
|
||||
|
||||
export declare interface SimrailClient {
|
||||
on(event: SimrailClientEvents.StationJoined, listener: (server: Server, station: Station, player: IPlayer) => void): this;
|
||||
on(event: SimrailClientEvents.StationLeft, listener: (server: Server, station: Station, player: IPlayer, joinedAt: number) => void): this;
|
||||
|
||||
|
||||
on(event: SimrailClientEvents.TrainJoined, listener: (server: Server, train: Train, player: IPlayer, startDistance: number) => void): this;
|
||||
on(event: SimrailClientEvents.TrainLeft, listener: (server: Server, train: Train, player: IPlayer, joinedAt: number, leftAt: number, points: number, distance: number, vehicle: string) => void): this;
|
||||
|
||||
//on(event: string, listener: Function): this;
|
||||
}
|
||||
|
||||
export type OccupiedStation = {
|
||||
SteamId: string;
|
||||
JoinedAt: number;
|
||||
}
|
||||
|
||||
export type OccupiedTrain = {
|
||||
SteamId: string;
|
||||
JoinedAt: number;
|
||||
StartPlayerDistance: number;
|
||||
StartPlayerPoints: number;
|
||||
}
|
||||
|
||||
export class SimrailClient extends EventEmitter {
|
||||
public stations: Record<Server['ServerCode'], Station[]> = {};
|
||||
public stationsOccupied: Record<Server['ServerCode'], Record<string, OccupiedStation | null>> = {};
|
||||
|
||||
public trains: Record<Server['ServerCode'], Train[]> = {};
|
||||
public trainsOccupied: Record<Server['ServerCode'], Record<string, OccupiedTrain | null>> = {};
|
||||
|
||||
public constructor() {
|
||||
super();
|
||||
this.setup();
|
||||
setTimeout(() => setInterval(() => this.update(), 500), 1000)
|
||||
}
|
||||
|
||||
public getStation(server: Server['ServerCode'], name: string) {
|
||||
if (!this.stationsOccupied[server] || !this.stationsOccupied[server][name]) return null;
|
||||
const player = PlayerUtil.getPlayer(this.stationsOccupied[server][name]?.SteamId ?? "");
|
||||
return { player, joinedAt: this.stationsOccupied[name].joinedAt };
|
||||
}
|
||||
|
||||
public getTrain(server: Server['ServerCode'], name: string) {
|
||||
if (!this.trainsOccupied[server] || !this.trainsOccupied[server][name]) return null;
|
||||
const player = PlayerUtil.getPlayer(this.trainsOccupied[server][name]?.SteamId ?? "");
|
||||
return { player, joinedAt: this.trainsOccupied[server][name]?.JoinedAt, startPlayerDistance: this.trainsOccupied[server][name]?.StartPlayerDistance };
|
||||
}
|
||||
|
||||
private async setup() {
|
||||
console.log(Date.now() - (Number(await redis.get('last_updated'))));
|
||||
if (!await redis.get('last_updated')) {
|
||||
await redis.json.set('trains_occupied', '$', {});
|
||||
await redis.json.set('trains', '$', []);
|
||||
await redis.json.set('stations', '$', []);
|
||||
await redis.json.set('stations_occupied', '$', {});
|
||||
}
|
||||
|
||||
const lastUpdated = Date.now() - (Number(await redis.get('last_updated')) ?? 0);
|
||||
|
||||
if (lastUpdated > 300_000) {
|
||||
console.log('REDIS: last updated more than > 5 mins');
|
||||
await redis.json.set('trains_occupied', '$', {});
|
||||
await redis.json.set('trains', '$', []);
|
||||
await redis.json.set('stations', '$', []);
|
||||
await redis.json.set('stations_occupied', '$', {});
|
||||
}
|
||||
|
||||
if (!await redis.json.get('stations'))
|
||||
redis.json.set('stations', '$', []);
|
||||
if (!await redis.json.get('trains'))
|
||||
redis.json.set('trains', '$', []);
|
||||
if (!await redis.json.get('trains_occupied'))
|
||||
redis.json.set('trains_occupied', '$', {});
|
||||
if (!await redis.json.get('stations_occupied'))
|
||||
redis.json.set('stations_occupied', '$', {});
|
||||
|
||||
this.stations = (await redis.json.get('stations') as unknown as SimrailClient['stations']);
|
||||
this.stationsOccupied = (await redis.json.get('stations_occupied') as unknown as SimrailClient['stationsOccupied']);
|
||||
this.trains = (await redis.json.get('trains') as unknown as SimrailClient['trains']);
|
||||
this.trainsOccupied = (await redis.json.get('trains_occupied') as unknown as SimrailClient['trainsOccupied']);
|
||||
|
||||
redis.set('last_updated', Date.now().toString());
|
||||
}
|
||||
|
||||
private async processStation(server: Server, stations: ApiResponse<Station>) {
|
||||
if (stations.result) {
|
||||
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);
|
||||
redis.set('last_updated', Date.now().toString());
|
||||
}
|
||||
|
||||
stations.data.forEach(async (x) => {
|
||||
const data = this.stations[server.ServerCode].find(y => y.Name === x.Name);
|
||||
if (!data) return;
|
||||
|
||||
if (data.DispatchedBy[0]?.SteamId !== x.DispatchedBy[0]?.SteamId) {
|
||||
if (!data.DispatchedBy[0]?.SteamId) {
|
||||
// join
|
||||
const date = new Date();
|
||||
const player = await PlayerUtil.getPlayer(x.DispatchedBy[0]?.SteamId);
|
||||
|
||||
this.emit(SimrailClientEvents.StationJoined, server, x, player);
|
||||
this.stationsOccupied[server.ServerCode][data.Prefix] = {
|
||||
SteamId: x.DispatchedBy[0]?.SteamId,
|
||||
JoinedAt: date.getTime()
|
||||
};
|
||||
|
||||
return;
|
||||
}
|
||||
// leave
|
||||
const player = await PlayerUtil.getPlayer(data.DispatchedBy[0]?.SteamId)
|
||||
|
||||
this.emit(SimrailClientEvents.StationLeft, server, x, player, this.stationsOccupied[server.ServerCode][data.Prefix]?.JoinedAt);
|
||||
delete this.stationsOccupied[server.ServerCode][data.Prefix];
|
||||
|
||||
}
|
||||
})
|
||||
redis.json.set('stations_occupied', '$', this.stationsOccupied);
|
||||
this.stations[server.ServerCode] = stations.data;
|
||||
redis.json.set('stations', '$', this.stations);
|
||||
redis.set('last_updated', Date.now().toString());
|
||||
}
|
||||
}
|
||||
|
||||
private async processTrain(server: Server, trains: ApiResponse<Train>) {
|
||||
if (trains.result) {
|
||||
if (!this.trains[server.ServerCode]) this.trains[server.ServerCode] = [];
|
||||
if (!this.trainsOccupied[server.ServerCode]) this.trainsOccupied[server.ServerCode] = {};
|
||||
|
||||
if (!this.trains[server.ServerCode].length) {
|
||||
this.trains[server.ServerCode] = trains.data;
|
||||
|
||||
redis.json.set('trains', '$', this.trains);
|
||||
redis.set('last_updated', Date.now().toString());
|
||||
return;
|
||||
}
|
||||
|
||||
trains.data.forEach(async (x) => {
|
||||
const data = this.trains[server.ServerCode].find(y => y.id === x.id);
|
||||
if (!data) return;
|
||||
|
||||
if (data.TrainData.ControlledBySteamID !== x.TrainData.ControlledBySteamID) {
|
||||
|
||||
if (!data.TrainData.ControlledBySteamID) {
|
||||
if (!x.TrainData.ControlledBySteamID) return;
|
||||
// join
|
||||
const date = new Date();
|
||||
|
||||
const player = await PlayerUtil.getPlayer(x.TrainData.ControlledBySteamID!);
|
||||
|
||||
const playerStats = await PlayerUtil.getPlayerStats(x.TrainData.ControlledBySteamID!);
|
||||
|
||||
|
||||
this.emit(SimrailClientEvents.TrainJoined, server, x, player, playerStats?.stats.find(x => x.name === 'DISTANCE_M')?.value);
|
||||
|
||||
this.trainsOccupied[server.ServerCode][x.TrainNoLocal] = {
|
||||
SteamId: x.TrainData.ControlledBySteamID!,
|
||||
JoinedAt: date.getTime(),
|
||||
StartPlayerDistance: playerStats?.stats.find(x => x.name === 'DISTANCE_M')?.value!,
|
||||
StartPlayerPoints: playerStats?.stats.find(x => x.name === "SCORE")?.value!,
|
||||
};
|
||||
return;
|
||||
}
|
||||
|
||||
if (!data.TrainData.ControlledBySteamID) return;
|
||||
const date = new Date();
|
||||
|
||||
const player = await PlayerUtil.getPlayer(data.TrainData.ControlledBySteamID!);
|
||||
|
||||
const playerId = data.TrainData.ControlledBySteamID!;
|
||||
const trainOccupied = this.trainsOccupied[server.ServerCode][data.TrainNoLocal] && JSON.parse(JSON.stringify(this.trainsOccupied[server.ServerCode][data.TrainNoLocal])) || null;
|
||||
|
||||
setTimeout(() => {
|
||||
|
||||
|
||||
PlayerUtil.getPlayerStats(playerId).then(playerStats => {
|
||||
const oldKm = trainOccupied?.StartPlayerDistance ?? 0;
|
||||
|
||||
const distance = oldKm ? (playerStats?.stats.find(x => x.name === 'DISTANCE_M')?.value ?? 0) - oldKm : 0;
|
||||
|
||||
const oldPoints = trainOccupied?.StartPlayerPoints ?? 0;
|
||||
|
||||
const points = oldPoints ? (playerStats?.stats.find(x => x.name === 'SCORE')?.value ?? 0) - oldPoints : 0;
|
||||
|
||||
|
||||
this.emit(SimrailClientEvents.TrainLeft, server, data, player, trainOccupied?.JoinedAt, date.getTime(), points, distance, x.Vehicles[0]);
|
||||
})
|
||||
}, 80_000)
|
||||
delete this.trainsOccupied[server.ServerCode][data.TrainNoLocal];
|
||||
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
this.trains[server.ServerCode] = trains.data;
|
||||
redis.json.set('trains', '$', this.trains);
|
||||
redis.json.set('trains_occupied', '$', this.trainsOccupied);
|
||||
redis.set('last_updated', Date.now().toString());
|
||||
}
|
||||
}
|
||||
|
||||
private async update() {
|
||||
const servers = (await fetch('https://panel.simrail.eu:8084/servers-open').then(x => x.json()).catch(x => ({ data: [], result: false })) as ApiResponse<Server>)
|
||||
.data?.filter(x => x.ServerName.includes('Polski')) ?? []; // no plans to support other servers
|
||||
|
||||
if (!servers.length) console.log('SimrailAPI is down')
|
||||
|
||||
// TODO: maybe node:worker_threads?
|
||||
// TODO: check performance
|
||||
servers.forEach(async (server) => {
|
||||
const stations = (await fetch('https://panel.simrail.eu:8084/stations-open?serverCode=' + server.ServerCode).then(x => x.json()).catch(() => ({ result: false }))) as ApiResponse<Station>;
|
||||
const trains = (await fetch('https://panel.simrail.eu:8084/trains-open?serverCode=' + server.ServerCode).then(x => x.json()).catch(() => ({ result: false }))) as ApiResponse<Train>;
|
||||
|
||||
this.processStation(server, stations);
|
||||
this.processTrain(server, trains);
|
||||
});
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user