mirror of
https://github.com/AsgardEternal/SquadJS.git
synced 2024-09-28 19:54:25 -05:00
Merge pull request #318 from fantinodavide/eos-integration
EOS integration, major rewrite.
This commit is contained in:
commit
dffc8b6119
@ -16,9 +16,13 @@ export default class LogParser extends EventEmitter {
|
|||||||
|
|
||||||
this.eventStore = {
|
this.eventStore = {
|
||||||
disconnected: {}, // holding area, cleared on map change.
|
disconnected: {}, // holding area, cleared on map change.
|
||||||
players: {}, // persistent data, steamid, controller, suffix.
|
players: [], // persistent data, steamid, controller, suffix.
|
||||||
|
playersEOS: [], // proxies from EOSID to persistent data, steamid, controller, suffix.
|
||||||
|
connectionIdToSteamID: new Map(),
|
||||||
session: {}, // old eventstore, nonpersistent data
|
session: {}, // old eventstore, nonpersistent data
|
||||||
clients: {} // used in the connection chain before we resolve a player.
|
clients: {}, // used in the connection chain before we resolve a player.
|
||||||
|
lastConnection: {}, // used to store the last client connection data to then associate a steamid
|
||||||
|
joinRequests: []
|
||||||
};
|
};
|
||||||
|
|
||||||
this.linesPerMinute = 0;
|
this.linesPerMinute = 0;
|
||||||
|
@ -337,8 +337,7 @@ export default class Rcon extends EventEmitter {
|
|||||||
|
|
||||||
if (type === SERVERDATA_AUTH) {
|
if (type === SERVERDATA_AUTH) {
|
||||||
this.callbackIds.push({ id: this.count, cmd: body });
|
this.callbackIds.push({ id: this.count, cmd: body });
|
||||||
Logger.verbose('RCON', 2, `Writing Auth Packet`);
|
|
||||||
Logger.verbose('RCON', 4, `Writing packet with type "${type}" and body "${body}".`);
|
|
||||||
this.responseCallbackQueue.push(() => {});
|
this.responseCallbackQueue.push(() => {});
|
||||||
this.responseCallbackQueue.push((decodedPacket) => {
|
this.responseCallbackQueue.push((decodedPacket) => {
|
||||||
this.client.removeListener('error', onError);
|
this.client.removeListener('error', onError);
|
||||||
@ -352,7 +351,6 @@ export default class Rcon extends EventEmitter {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
Logger.verbose('RCON', 2, `Writing packet with type "${type}" and body "${body}".`);
|
|
||||||
this.callbackIds.push({ id: this.count, cmd: body });
|
this.callbackIds.push({ id: this.count, cmd: body });
|
||||||
this.responseCallbackQueue.push((response) => {
|
this.responseCallbackQueue.push((response) => {
|
||||||
this.client.removeListener('error', onError);
|
this.client.removeListener('error', onError);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "SquadJS",
|
"name": "SquadJS",
|
||||||
"version": "3.8.2",
|
"version": "4.0.0",
|
||||||
"repository": "https://github.com/Team-Silver-Sphere/SquadJS.git",
|
"repository": "https://github.com/Team-Silver-Sphere/SquadJS.git",
|
||||||
"author": "Thomas Smyth <https://github.com/Thomas-Smyth>",
|
"author": "Thomas Smyth <https://github.com/Thomas-Smyth>",
|
||||||
"license": "BSL-1.0",
|
"license": "BSL-1.0",
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import EventEmitter from 'events';
|
import EventEmitter from 'events';
|
||||||
|
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import Gamedig from 'gamedig';
|
|
||||||
|
|
||||||
import Logger from 'core/logger';
|
import Logger from 'core/logger';
|
||||||
import { SQUADJS_API_DOMAIN } from 'core/constants';
|
import { SQUADJS_API_DOMAIN } from 'core/constants';
|
||||||
@ -19,7 +18,7 @@ export default class SquadServer extends EventEmitter {
|
|||||||
constructor(options = {}) {
|
constructor(options = {}) {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
for (const option of ['host', 'queryPort'])
|
for (const option of ['host'])
|
||||||
if (!(option in options)) throw new Error(`${option} must be specified.`);
|
if (!(option in options)) throw new Error(`${option} must be specified.`);
|
||||||
|
|
||||||
this.id = options.id;
|
this.id = options.id;
|
||||||
@ -73,13 +72,13 @@ export default class SquadServer extends EventEmitter {
|
|||||||
this.admins = await fetchAdminLists(this.options.adminLists);
|
this.admins = await fetchAdminLists(this.options.adminLists);
|
||||||
|
|
||||||
await this.rcon.connect();
|
await this.rcon.connect();
|
||||||
await this.logParser.watch();
|
|
||||||
|
|
||||||
await this.updateSquadList();
|
await this.updateSquadList();
|
||||||
await this.updatePlayerList();
|
await this.updatePlayerList(this);
|
||||||
await this.updateLayerInformation();
|
await this.updateLayerInformation();
|
||||||
await this.updateA2SInformation();
|
await this.updateA2SInformation();
|
||||||
|
|
||||||
|
await this.logParser.watch();
|
||||||
|
|
||||||
Logger.verbose('SquadServer', 1, `Watching ${this.serverName}...`);
|
Logger.verbose('SquadServer', 1, `Watching ${this.serverName}...`);
|
||||||
|
|
||||||
await this.pingSquadJSAPI();
|
await this.pingSquadJSAPI();
|
||||||
@ -154,9 +153,12 @@ export default class SquadServer extends EventEmitter {
|
|||||||
});
|
});
|
||||||
|
|
||||||
this.rcon.on('SQUAD_CREATED', async (data) => {
|
this.rcon.on('SQUAD_CREATED', async (data) => {
|
||||||
data.player = await this.getPlayerBySteamID(data.playerSteamID, true);
|
data.player = await this.getPlayerByEOSID(data.playerEOSID, true);
|
||||||
|
data.player.squadID = data.squadID;
|
||||||
|
|
||||||
delete data.playerName;
|
delete data.playerName;
|
||||||
delete data.playerSteamID;
|
delete data.playerSteamID;
|
||||||
|
delete data.playerEOSID;
|
||||||
|
|
||||||
this.emit('SQUAD_CREATED', data);
|
this.emit('SQUAD_CREATED', data);
|
||||||
});
|
});
|
||||||
@ -207,7 +209,13 @@ export default class SquadServer extends EventEmitter {
|
|||||||
});
|
});
|
||||||
|
|
||||||
this.logParser.on('PLAYER_CONNECTED', async (data) => {
|
this.logParser.on('PLAYER_CONNECTED', async (data) => {
|
||||||
data.player = await this.getPlayerBySteamID(data.steamID);
|
Logger.verbose(
|
||||||
|
'SquadServer',
|
||||||
|
1,
|
||||||
|
`Player connected ${data.playerSuffix} - SteamID: ${data.steamID} - EOSID: ${data.eosID} - IP: ${data.ip}`
|
||||||
|
);
|
||||||
|
|
||||||
|
data.player = await this.getPlayerByEOSID(data.eosID);
|
||||||
if (data.player) data.player.suffix = data.playerSuffix;
|
if (data.player) data.player.suffix = data.playerSuffix;
|
||||||
|
|
||||||
delete data.steamID;
|
delete data.steamID;
|
||||||
@ -217,7 +225,7 @@ export default class SquadServer extends EventEmitter {
|
|||||||
});
|
});
|
||||||
|
|
||||||
this.logParser.on('PLAYER_DISCONNECTED', async (data) => {
|
this.logParser.on('PLAYER_DISCONNECTED', async (data) => {
|
||||||
data.player = await this.getPlayerBySteamID(data.steamID);
|
data.player = await this.getPlayerByEOSID(data.eosID);
|
||||||
|
|
||||||
delete data.steamID;
|
delete data.steamID;
|
||||||
|
|
||||||
@ -226,12 +234,16 @@ export default class SquadServer extends EventEmitter {
|
|||||||
|
|
||||||
this.logParser.on('PLAYER_DAMAGED', async (data) => {
|
this.logParser.on('PLAYER_DAMAGED', async (data) => {
|
||||||
data.victim = await this.getPlayerByName(data.victimName);
|
data.victim = await this.getPlayerByName(data.victimName);
|
||||||
data.attacker = await this.getPlayerByName(data.attackerName);
|
data.attacker = await this.getPlayerByEOSID(data.attackerEOSID);
|
||||||
|
|
||||||
if (data.victim && data.attacker)
|
if (data.attacker && !data.attacker.playercontroller && data.attackerController)
|
||||||
|
data.attacker.playercontroller = data.attackerController;
|
||||||
|
|
||||||
|
if (data.victim && data.attacker) {
|
||||||
data.teamkill =
|
data.teamkill =
|
||||||
data.victim.teamID === data.attacker.teamID &&
|
data.victim.teamID === data.attacker.teamID &&
|
||||||
data.victim.steamID !== data.attacker.steamID;
|
data.victim.steamID !== data.attacker.steamID;
|
||||||
|
}
|
||||||
|
|
||||||
delete data.victimName;
|
delete data.victimName;
|
||||||
delete data.attackerName;
|
delete data.attackerName;
|
||||||
@ -241,7 +253,7 @@ export default class SquadServer extends EventEmitter {
|
|||||||
|
|
||||||
this.logParser.on('PLAYER_WOUNDED', async (data) => {
|
this.logParser.on('PLAYER_WOUNDED', async (data) => {
|
||||||
data.victim = await this.getPlayerByName(data.victimName);
|
data.victim = await this.getPlayerByName(data.victimName);
|
||||||
data.attacker = await this.getPlayerByName(data.attackerName);
|
data.attacker = await this.getPlayerByEOSID(data.attackerEOSID);
|
||||||
if (!data.attacker)
|
if (!data.attacker)
|
||||||
data.attacker = await this.getPlayerByController(data.attackerPlayerController);
|
data.attacker = await this.getPlayerByController(data.attackerPlayerController);
|
||||||
|
|
||||||
@ -259,7 +271,7 @@ export default class SquadServer extends EventEmitter {
|
|||||||
|
|
||||||
this.logParser.on('PLAYER_DIED', async (data) => {
|
this.logParser.on('PLAYER_DIED', async (data) => {
|
||||||
data.victim = await this.getPlayerByName(data.victimName);
|
data.victim = await this.getPlayerByName(data.victimName);
|
||||||
data.attacker = await this.getPlayerByName(data.attackerName);
|
data.attacker = await this.getPlayerByEOSID(data.attackerEOSID);
|
||||||
if (!data.attacker)
|
if (!data.attacker)
|
||||||
data.attacker = await this.getPlayerByController(data.attackerPlayerController);
|
data.attacker = await this.getPlayerByController(data.attackerPlayerController);
|
||||||
|
|
||||||
@ -275,9 +287,9 @@ export default class SquadServer extends EventEmitter {
|
|||||||
});
|
});
|
||||||
|
|
||||||
this.logParser.on('PLAYER_REVIVED', async (data) => {
|
this.logParser.on('PLAYER_REVIVED', async (data) => {
|
||||||
data.victim = await this.getPlayerByName(data.victimName);
|
data.victim = await this.getPlayerByEOSID(data.victimEOSID);
|
||||||
data.attacker = await this.getPlayerByName(data.attackerName);
|
data.attacker = await this.getPlayerByEOSID(data.attackerEOSID);
|
||||||
data.reviver = await this.getPlayerByName(data.reviverName);
|
data.reviver = await this.getPlayerByEOSID(data.reviverEOSID);
|
||||||
|
|
||||||
delete data.victimName;
|
delete data.victimName;
|
||||||
delete data.attackerName;
|
delete data.attackerName;
|
||||||
@ -287,7 +299,7 @@ export default class SquadServer extends EventEmitter {
|
|||||||
});
|
});
|
||||||
|
|
||||||
this.logParser.on('PLAYER_POSSESS', async (data) => {
|
this.logParser.on('PLAYER_POSSESS', async (data) => {
|
||||||
data.player = await this.getPlayerByNameSuffix(data.playerSuffix);
|
data.player = await this.getPlayerByEOSID(data.playerEOSID);
|
||||||
if (data.player) data.player.possessClassname = data.possessClassname;
|
if (data.player) data.player.possessClassname = data.possessClassname;
|
||||||
|
|
||||||
delete data.playerSuffix;
|
delete data.playerSuffix;
|
||||||
@ -296,7 +308,7 @@ export default class SquadServer extends EventEmitter {
|
|||||||
});
|
});
|
||||||
|
|
||||||
this.logParser.on('PLAYER_UNPOSSESS', async (data) => {
|
this.logParser.on('PLAYER_UNPOSSESS', async (data) => {
|
||||||
data.player = await this.getPlayerByNameSuffix(data.playerSuffix);
|
data.player = await this.getPlayerByEOSID(data.playerEOSID);
|
||||||
|
|
||||||
delete data.playerSuffix;
|
delete data.playerSuffix;
|
||||||
|
|
||||||
@ -310,6 +322,23 @@ export default class SquadServer extends EventEmitter {
|
|||||||
this.logParser.on('TICK_RATE', (data) => {
|
this.logParser.on('TICK_RATE', (data) => {
|
||||||
this.emit('TICK_RATE', data);
|
this.emit('TICK_RATE', data);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.logParser.on('CLIENT_EXTERNAL_ACCOUNT_INFO', (data) => {
|
||||||
|
this.rcon.addIds(data.steamID, data.eosID);
|
||||||
|
});
|
||||||
|
// this.logParser.on('CLIENT_CONNECTED', (data) => {
|
||||||
|
// Logger.verbose("SquadServer", 1, `Client connected. Connection: ${data.connection} - SteamID: ${data.steamID}`)
|
||||||
|
// })
|
||||||
|
// this.logParser.on('CLIENT_LOGIN_REQUEST', (data) => {
|
||||||
|
// Logger.verbose("SquadServer", 1, `Login request. ChainID: ${data.chainID} - Suffix: ${data.suffix} - EOSID: ${data.eosID}`)
|
||||||
|
|
||||||
|
// })
|
||||||
|
// this.logParser.on('RESOLVED_EOS_ID', (data) => {
|
||||||
|
// Logger.verbose("SquadServer", 1, `Resolved EOSID. ChainID: ${data.chainID} - Suffix: ${data.suffix} - EOSID: ${data.eosID}`)
|
||||||
|
// })
|
||||||
|
// this.logParser.on('ADDING_CLIENT_CONNECTION', (data) => {
|
||||||
|
// Logger.verbose("SquadServer", 1, `Adding client connection`, data)
|
||||||
|
// })
|
||||||
}
|
}
|
||||||
|
|
||||||
async restartLogParser() {
|
async restartLogParser() {
|
||||||
@ -352,7 +381,7 @@ export default class SquadServer extends EventEmitter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const players = [];
|
const players = [];
|
||||||
for (const player of await this.rcon.getListPlayers())
|
for (const player of await this.rcon.getListPlayers(this))
|
||||||
players.push({
|
players.push({
|
||||||
...oldPlayerInfo[player.steamID],
|
...oldPlayerInfo[player.steamID],
|
||||||
...player,
|
...player,
|
||||||
@ -380,6 +409,13 @@ export default class SquadServer extends EventEmitter {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.a2sPlayerCount > 0 && players.length === 0)
|
||||||
|
Logger.verbose(
|
||||||
|
'SquadServer',
|
||||||
|
1,
|
||||||
|
`Real Player Count: ${this.a2sPlayerCount} but loaded ${players.length}`
|
||||||
|
);
|
||||||
|
|
||||||
this.emit('UPDATED_PLAYER_INFORMATION');
|
this.emit('UPDATED_PLAYER_INFORMATION');
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
Logger.verbose('SquadServer', 1, 'Failed to update player list.', err);
|
Logger.verbose('SquadServer', 1, 'Failed to update player list.', err);
|
||||||
@ -441,53 +477,70 @@ export default class SquadServer extends EventEmitter {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
async updateA2SInformation() {
|
updateA2SInformation() {
|
||||||
|
return this.updateServerInformation();
|
||||||
|
}
|
||||||
|
|
||||||
|
async updateServerInformation() {
|
||||||
if (this.updateA2SInformationTimeout) clearTimeout(this.updateA2SInformationTimeout);
|
if (this.updateA2SInformationTimeout) clearTimeout(this.updateA2SInformationTimeout);
|
||||||
|
|
||||||
Logger.verbose('SquadServer', 1, `Updating A2S information...`);
|
Logger.verbose('SquadServer', 1, `Updating server information...`);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const data = await Gamedig.query({
|
const rawData = await this.rcon.execute(`ShowServerInfo`);
|
||||||
type: 'squad',
|
Logger.verbose('SquadServer', 3, `Server information raw data`, rawData);
|
||||||
host: this.options.host,
|
const data = JSON.parse(rawData);
|
||||||
port: this.options.queryPort
|
Logger.verbose('SquadServer', 2, `Server information data`, JSON.data);
|
||||||
});
|
|
||||||
|
|
||||||
const info = {
|
const info = {
|
||||||
raw: data.raw,
|
raw: data,
|
||||||
serverName: data.name,
|
serverName: data.ServerName_s,
|
||||||
|
|
||||||
maxPlayers: parseInt(data.maxplayers),
|
maxPlayers: parseInt(data.MaxPlayers),
|
||||||
publicSlots: parseInt(data.raw.rules.NUMPUBCONN),
|
publicQueueLimit: parseInt(data.PublicQueueLimit_I),
|
||||||
reserveSlots: parseInt(data.raw.rules.NUMPRIVCONN),
|
reserveSlots: parseInt(data.PlayerReserveCount_I),
|
||||||
|
|
||||||
a2sPlayerCount: parseInt(data.raw.rules.PlayerCount_i),
|
playerCount: parseInt(data.PlayerCount_I),
|
||||||
publicQueue: parseInt(data.raw.rules.PublicQueue_i),
|
a2sPlayerCount: parseInt(data.PlayerCount_I),
|
||||||
reserveQueue: parseInt(data.raw.rules.ReservedQueue_i),
|
publicQueue: parseInt(data.PublicQueue_I),
|
||||||
|
reserveQueue: parseInt(data.ReservedQueue_I),
|
||||||
|
|
||||||
matchTimeout: parseFloat(data.raw.rules.MatchTimeout_f),
|
currentLayer: data.MapName_s,
|
||||||
gameVersion: data.raw.version
|
nextLayer: data.NextLayer_s,
|
||||||
|
|
||||||
|
teamOne: data.TeamOne_s?.replace(new RegExp(data.MapName_s, 'i'), '') || '',
|
||||||
|
teamTwo: data.TeamTwo_s?.replace(new RegExp(data.MapName_s, 'i'), '') || '',
|
||||||
|
|
||||||
|
matchTimeout: parseFloat(data.MatchTimeout_d),
|
||||||
|
matchStartTime: this.getMatchStartTimeByPlaytime(data.PLAYTIME_I),
|
||||||
|
gameVersion: data.GameVersion_s
|
||||||
};
|
};
|
||||||
|
|
||||||
this.serverName = info.serverName;
|
this.serverName = info.serverName;
|
||||||
|
|
||||||
this.maxPlayers = info.maxPlayers;
|
this.maxPlayers = info.maxPlayers;
|
||||||
this.publicSlots = info.publicSlots;
|
this.publicSlots = info.maxPlayers - info.reserveSlots;
|
||||||
this.reserveSlots = info.reserveSlots;
|
this.reserveSlots = info.reserveSlots;
|
||||||
|
|
||||||
this.a2sPlayerCount = info.a2sPlayerCount;
|
this.a2sPlayerCount = info.playerCount;
|
||||||
|
this.playerCount = info.playerCount;
|
||||||
this.publicQueue = info.publicQueue;
|
this.publicQueue = info.publicQueue;
|
||||||
this.reserveQueue = info.reserveQueue;
|
this.reserveQueue = info.reserveQueue;
|
||||||
|
|
||||||
this.matchTimeout = info.matchTimeout;
|
this.matchTimeout = info.matchTimeout;
|
||||||
|
this.matchStartTime = info.matchStartTime;
|
||||||
this.gameVersion = info.gameVersion;
|
this.gameVersion = info.gameVersion;
|
||||||
|
|
||||||
|
if (!this.currentLayer) this.currentLayer = Layers.getLayerByClassname(info.currentLayer);
|
||||||
|
if (!this.nextLayer) this.nextLayer = Layers.getLayerByClassname(info.nextLayer);
|
||||||
|
|
||||||
this.emit('UPDATED_A2S_INFORMATION', info);
|
this.emit('UPDATED_A2S_INFORMATION', info);
|
||||||
|
this.emit('UPDATED_SERVER_INFORMATION', info);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
Logger.verbose('SquadServer', 1, 'Failed to update A2S information.', err);
|
Logger.verbose('SquadServer', 1, 'Failed to update server information.', err);
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger.verbose('SquadServer', 1, `Updated A2S information.`);
|
Logger.verbose('SquadServer', 1, `Updated server information.`);
|
||||||
|
|
||||||
this.updateA2SInformationTimeout = setTimeout(
|
this.updateA2SInformationTimeout = setTimeout(
|
||||||
this.updateA2SInformation,
|
this.updateA2SInformation,
|
||||||
@ -542,6 +595,10 @@ export default class SquadServer extends EventEmitter {
|
|||||||
return this.getPlayerByCondition((player) => player.steamID === steamID, forceUpdate);
|
return this.getPlayerByCondition((player) => player.steamID === steamID, forceUpdate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getPlayerByEOSID(eosID, forceUpdate) {
|
||||||
|
return this.getPlayerByCondition((player) => player.eosID === eosID, forceUpdate);
|
||||||
|
}
|
||||||
|
|
||||||
async getPlayerByName(name, forceUpdate) {
|
async getPlayerByName(name, forceUpdate) {
|
||||||
return this.getPlayerByCondition((player) => player.name === name, forceUpdate);
|
return this.getPlayerByCondition((player) => player.name === name, forceUpdate);
|
||||||
}
|
}
|
||||||
@ -606,4 +663,8 @@ export default class SquadServer extends EventEmitter {
|
|||||||
|
|
||||||
this.pingSquadJSAPITimeout = setTimeout(this.pingSquadJSAPI, this.pingSquadJSAPIInterval);
|
this.pingSquadJSAPITimeout = setTimeout(this.pingSquadJSAPI, this.pingSquadJSAPIInterval);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getMatchStartTimeByPlaytime(playtime) {
|
||||||
|
return new Date(Date.now() - +playtime * 1000);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
20
squad-server/log-parser/adding-client-connection.js
Normal file
20
squad-server/log-parser/adding-client-connection.js
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
export default {
|
||||||
|
regex:
|
||||||
|
/^\[([0-9.:-]+)]\[([ 0-9]*)]LogNet: AddClientConnection: Added client connection: \[UNetConnection\] RemoteAddr: ([\d.]+):[0-9]+, Name: (EOSIpNetConnection_[0-9]+), Driver: GameNetDriver (EOSNetDriver_[0-9]+), IsServer: YES, PC: NULL, Owner: NULL, UniqueId: INVALID/,
|
||||||
|
onMatch: (args, logParser) => {
|
||||||
|
const data = {
|
||||||
|
raw: args[0],
|
||||||
|
time: args[1],
|
||||||
|
chainID: args[2],
|
||||||
|
// steamID: args[ 3 ],
|
||||||
|
ip: args[3],
|
||||||
|
connection: args[4],
|
||||||
|
driver: args[5]
|
||||||
|
};
|
||||||
|
/* This is Called when unreal engine adds a client connection
|
||||||
|
First Step in Adding a Player to server
|
||||||
|
*/
|
||||||
|
logParser.eventStore['last-connection'] = data;
|
||||||
|
logParser.emit('ADDING_CLIENT_CONNECTION', data);
|
||||||
|
}
|
||||||
|
};
|
15
squad-server/log-parser/check-permission-resolve-eosid.js
Normal file
15
squad-server/log-parser/check-permission-resolve-eosid.js
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
export default {
|
||||||
|
regex:
|
||||||
|
/^\[([0-9.:-]+)]\[([ 0-9]*)]LogSquadCommon: SQCommonStatics Check Permissions, UniqueId:([\da-f]+)$/,
|
||||||
|
onMatch: (args, logParser) => {
|
||||||
|
const data = {
|
||||||
|
raw: args[0],
|
||||||
|
time: args[1],
|
||||||
|
chainID: +args[2],
|
||||||
|
eosID: args[3]
|
||||||
|
};
|
||||||
|
|
||||||
|
logParser.eventStore.joinRequests[data.chainID].eosID = data.eosID;
|
||||||
|
logParser.emit('RESOLVED_EOS_ID', { ...logParser.eventStore.joinRequests[data.chainID] });
|
||||||
|
}
|
||||||
|
};
|
21
squad-server/log-parser/client-external-account-info.js
Normal file
21
squad-server/log-parser/client-external-account-info.js
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
export default {
|
||||||
|
regex:
|
||||||
|
/^\[([0-9.:-]+)]\[([ 0-9]+)]LogEOS: Verbose: \[LogEOSConnect] FConnectClient::CacheExternalAccountInfo - ProductUserId: (?<eosId>[0-9a-f]{32}), AccountType: (\d), AccountId: (?<steamId>[0-9]{17}), DisplayName: <Redacted>/,
|
||||||
|
onMatch: (args, logParser) => {
|
||||||
|
const data = {
|
||||||
|
raw: args[0],
|
||||||
|
time: args[1],
|
||||||
|
chainID: args[2],
|
||||||
|
eosID: args.groups.eosId,
|
||||||
|
steamID: args.groups.steamId
|
||||||
|
};
|
||||||
|
|
||||||
|
logParser.eventStore.players[data.steamID] = {
|
||||||
|
eosID: data.eosID,
|
||||||
|
steamID: data.steamID
|
||||||
|
};
|
||||||
|
logParser.eventStore.playersEOS[data.eosID] = logParser.eventStore.players[data.steamID];
|
||||||
|
|
||||||
|
logParser.emit('CLIENT_EXTERNAL_ACCOUNT_INFO', data);
|
||||||
|
}
|
||||||
|
};
|
@ -1,6 +1,6 @@
|
|||||||
export default {
|
export default {
|
||||||
regex:
|
regex:
|
||||||
/^\[([0-9.:-]+)]\[([ 0-9]*)]LogSquad: Login: NewPlayer: SteamNetConnection \/Engine\/Transient\.(SteamNetConnection_[0-9]+)/,
|
/^\[([0-9.:-]+)]\[([ 0-9]*)]LogSquad: Login: NewPlayer: EOSIpNetConnection \/Engine\/Transient\.(EOSIpNetConnection_[0-9]+)/,
|
||||||
onMatch: (args, logParser) => {
|
onMatch: (args, logParser) => {
|
||||||
const data = {
|
const data = {
|
||||||
raw: args[0],
|
raw: args[0],
|
||||||
@ -13,7 +13,7 @@ export default {
|
|||||||
2nd Step in player connected path
|
2nd Step in player connected path
|
||||||
*/
|
*/
|
||||||
|
|
||||||
logParser.eventStore['client-login'] = logParser.eventStore.clients[args[3]];
|
logParser.eventStore.joinRequests[data.chainID].connection = data.connection;
|
||||||
delete logParser.eventStore.clients[args[3]];
|
delete logParser.eventStore.clients[args[3]];
|
||||||
logParser.emit('CLIENT_LOGIN', data);
|
logParser.emit('CLIENT_LOGIN', data);
|
||||||
}
|
}
|
||||||
|
@ -16,10 +16,15 @@ import RoundEnded from './round-ended.js';
|
|||||||
import RoundTickets from './round-tickets.js';
|
import RoundTickets from './round-tickets.js';
|
||||||
import RoundWinner from './round-winner.js';
|
import RoundWinner from './round-winner.js';
|
||||||
import ServerTickRate from './server-tick-rate.js';
|
import ServerTickRate from './server-tick-rate.js';
|
||||||
import ClientConnected from './client-connected.js';
|
import AddingClientConnection from './adding-client-connection.js';
|
||||||
import ClientLogin from './client-login.js';
|
import ClientLogin from './client-login.js';
|
||||||
import PendingConnectionDestroyed from './pending-connection-destroyed.js';
|
import PendingConnectionDestroyed from './pending-connection-destroyed.js';
|
||||||
|
import ClientExternalAccountInfo from './client-external-account-info.js';
|
||||||
|
import SendingAuthResult from './sending-auth-result.js';
|
||||||
|
import LoginRequest from './login-request.js';
|
||||||
|
import JoinRequest from './join-request.js';
|
||||||
|
import PlayerJoinSucceeded from './player-join-succeeded.js';
|
||||||
|
import CheckPermissionResolveEosid from './check-permission-resolve-eosid.js';
|
||||||
export default class SquadLogParser extends LogParser {
|
export default class SquadLogParser extends LogParser {
|
||||||
constructor(options) {
|
constructor(options) {
|
||||||
super('SquadGame.log', options);
|
super('SquadGame.log', options);
|
||||||
@ -43,9 +48,15 @@ export default class SquadLogParser extends LogParser {
|
|||||||
RoundTickets,
|
RoundTickets,
|
||||||
RoundWinner,
|
RoundWinner,
|
||||||
ServerTickRate,
|
ServerTickRate,
|
||||||
ClientConnected,
|
AddingClientConnection,
|
||||||
ClientLogin,
|
ClientLogin,
|
||||||
PendingConnectionDestroyed
|
PendingConnectionDestroyed,
|
||||||
|
ClientExternalAccountInfo,
|
||||||
|
SendingAuthResult,
|
||||||
|
LoginRequest,
|
||||||
|
JoinRequest,
|
||||||
|
PlayerJoinSucceeded,
|
||||||
|
CheckPermissionResolveEosid
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
15
squad-server/log-parser/join-request.js
Normal file
15
squad-server/log-parser/join-request.js
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
export default {
|
||||||
|
regex: /^\[([0-9.:-]+)]\[([ 0-9]*)]LogNet: Join request: .+\?Name=(.+)\?SplitscreenCount=\d$/,
|
||||||
|
onMatch: (args, logParser) => {
|
||||||
|
const data = {
|
||||||
|
raw: args[0],
|
||||||
|
time: args[1],
|
||||||
|
chainID: +args[2],
|
||||||
|
suffix: args[3]
|
||||||
|
};
|
||||||
|
|
||||||
|
logParser.eventStore.joinRequests[data.chainID] = data;
|
||||||
|
// console.log(logParser.eventStore.loginRequests[ data.chainID ])
|
||||||
|
logParser.emit('CLIENT_JOIN_REQUEST', data);
|
||||||
|
}
|
||||||
|
};
|
17
squad-server/log-parser/login-request.js
Normal file
17
squad-server/log-parser/login-request.js
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
export default {
|
||||||
|
regex:
|
||||||
|
/^\[([0-9.:-]+)]\[([ 0-9]*)]LogNet: Login request: \?Name=(.+?)(?:\?PASSWORD=(?:.+?))? userId: RedpointEOS:([\da-f]{32}) platform: RedpointEOS/,
|
||||||
|
onMatch: (args, logParser) => {
|
||||||
|
const data = {
|
||||||
|
raw: args[0],
|
||||||
|
time: args[1],
|
||||||
|
chainID: +args[2],
|
||||||
|
suffix: args[3],
|
||||||
|
eosID: args[4]
|
||||||
|
};
|
||||||
|
|
||||||
|
// logParser.eventStore.loginRequests[ data.chainID ] = data;
|
||||||
|
// console.log(logParser.eventStore.loginRequests[ data.chainID ])
|
||||||
|
logParser.emit('CLIENT_LOGIN_REQUEST', data);
|
||||||
|
}
|
||||||
|
};
|
@ -1,6 +1,6 @@
|
|||||||
export default {
|
export default {
|
||||||
regex:
|
regex:
|
||||||
/^\[([0-9.:-]+)]\[([ 0-9]*)]LogNet: UNetConnection::PendingConnectionLost\. \[UNetConnection\] RemoteAddr: ([0-9]{17}):[0-9]+, Name: (SteamNetConnection_[0-9]+), Driver: GameNetDriver (SteamNetDriver_[0-9]+), IsServer: YES, PC: NULL, Owner: NULL, UniqueId: (?:Steam:UNKNOWN \[.+\]|INVALID) bPendingDestroy=0/,
|
/^\[([0-9.:-]+)]\[([ 0-9]*)]LogNet: UNetConnection::PendingConnectionLost\. \[UNetConnection\] RemoteAddr: ([0-9a-f]{32}):[0-9]+, Name: (SteamNetConnection_[0-9]+), Driver: GameNetDriver (SteamNetDriver_[0-9]+), IsServer: YES, PC: NULL, Owner: NULL, UniqueId: (?:Steam:UNKNOWN \[.+\]|INVALID) bPendingDestroy=0/,
|
||||||
onMatch: (args, logParser) => {
|
onMatch: (args, logParser) => {
|
||||||
const data = {
|
const data = {
|
||||||
raw: args[0],
|
raw: args[0],
|
||||||
|
@ -1,27 +1,25 @@
|
|||||||
export default {
|
export default {
|
||||||
regex: /^\[([0-9.:-]+)]\[([ 0-9]*)]LogNet: Join succeeded: (.+)/,
|
regex:
|
||||||
|
/^\[([0-9.:-]+)]\[([ 0-9]*)]LogSquad: PostLogin: NewPlayer: BP_PlayerController_C .+PersistentLevel\.([^\s]+) \(IP: ([\d.]+) \| Online IDs: EOS: ([0-9a-f]{32}) steam: (\d+)\)/,
|
||||||
onMatch: (args, logParser) => {
|
onMatch: (args, logParser) => {
|
||||||
const data = {
|
const data = {
|
||||||
raw: args[0],
|
raw: args[0],
|
||||||
time: args[1],
|
time: args[1],
|
||||||
chainID: args[2],
|
chainID: +args[2],
|
||||||
playerSuffix: args[3],
|
playercontroller: args[3],
|
||||||
steamID: logParser.eventStore['client-login'], // player connected
|
ip: args[4],
|
||||||
controller: logParser.eventStore['player-controller'] // playercontroller connected
|
eosID: args[5],
|
||||||
|
steamID: args[6]
|
||||||
};
|
};
|
||||||
|
|
||||||
delete logParser.eventStore['client-login'];
|
const joinRequestData = logParser.eventStore.joinRequests[+args[2]];
|
||||||
delete logParser.eventStore['player-controller'];
|
data.connection = joinRequestData.connection;
|
||||||
|
data.playerSuffix = joinRequestData.suffix;
|
||||||
|
|
||||||
|
if (!logParser.eventStore.players[data.steamID])
|
||||||
|
logParser.eventStore.players[data.steamID] = {};
|
||||||
|
logParser.eventStore.players[data.steamID].controller = data.playercontroller;
|
||||||
|
|
||||||
// Handle Reconnecting players
|
|
||||||
if (logParser.eventStore.disconnected[data.steamID]) {
|
|
||||||
delete logParser.eventStore.disconnected[data.steamID];
|
|
||||||
}
|
|
||||||
logParser.emit('PLAYER_CONNECTED', data);
|
logParser.emit('PLAYER_CONNECTED', data);
|
||||||
logParser.eventStore.players[data.steamID] = {
|
|
||||||
steamID: data.steamID,
|
|
||||||
suffix: data.playerSuffix,
|
|
||||||
controller: data.controller
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
export default {
|
export default {
|
||||||
regex:
|
regex:
|
||||||
/^\[([0-9.:-]+)]\[([ 0-9]*)]LogSquad: Player:(.+) ActualDamage=([0-9.]+) from (.+) caused by ([A-z_0-9-]+)_C/,
|
/^\[([0-9.:-]+)]\[([ 0-9]*)]LogSquad: Player:(.+) ActualDamage=([0-9.]+) from (.+) \(Online IDs: EOS: ([0-9a-f]{32}) steam: (\d{17}) \| Player Controller ID: ([^ ]+)\)caused by ([A-z_0-9-]+)_C/,
|
||||||
onMatch: (args, logParser) => {
|
onMatch: (args, logParser) => {
|
||||||
const data = {
|
const data = {
|
||||||
raw: args[0],
|
raw: args[0],
|
||||||
@ -9,11 +9,18 @@ export default {
|
|||||||
victimName: args[3],
|
victimName: args[3],
|
||||||
damage: parseFloat(args[4]),
|
damage: parseFloat(args[4]),
|
||||||
attackerName: args[5],
|
attackerName: args[5],
|
||||||
weapon: args[6]
|
attackerEOSID: args[6],
|
||||||
|
attackerSteamID: args[7],
|
||||||
|
attackerController: args[8],
|
||||||
|
weapon: args[9]
|
||||||
};
|
};
|
||||||
|
|
||||||
logParser.eventStore.session[args[3]] = data;
|
logParser.eventStore.session[args[3]] = data;
|
||||||
|
|
||||||
|
if (!logParser.eventStore.players[data.attackerSteamID])
|
||||||
|
logParser.eventStore.players[data.attackerSteamID] = {};
|
||||||
|
logParser.eventStore.players[data.attackerSteamID].controller = data.attackerController;
|
||||||
|
|
||||||
logParser.emit('PLAYER_DAMAGED', data);
|
logParser.emit('PLAYER_DAMAGED', data);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
export default {
|
export default {
|
||||||
regex:
|
regex:
|
||||||
/^\[([0-9.:-]+)]\[([ 0-9]*)]LogSquadTrace: \[DedicatedServer](?:ASQSoldier::)?Die\(\): Player:(.+) KillingDamage=(?:-)*([0-9.]+) from ([A-z_0-9]+) caused by ([A-z_0-9-]+)_C/,
|
/^\[([0-9.:-]+)]\[([ 0-9]*)]LogSquadTrace: \[DedicatedServer](?:ASQSoldier::)?Die\(\): Player:(.+) KillingDamage=(?:-)*([0-9.]+) from ([A-z_0-9]+) \(Online IDs: EOS: ([\w\d]{32}) steam: (\d{17}) \| Contoller ID: ([\w\d]+)\) caused by ([A-z_0-9-]+)_C/,
|
||||||
onMatch: (args, logParser) => {
|
onMatch: (args, logParser) => {
|
||||||
const data = {
|
const data = {
|
||||||
...logParser.eventStore.session[args[3]],
|
...logParser.eventStore.session[args[3]],
|
||||||
@ -11,7 +11,9 @@ export default {
|
|||||||
victimName: args[3],
|
victimName: args[3],
|
||||||
damage: parseFloat(args[4]),
|
damage: parseFloat(args[4]),
|
||||||
attackerPlayerController: args[5],
|
attackerPlayerController: args[5],
|
||||||
weapon: args[6]
|
attackerEOSID: args[6],
|
||||||
|
attackerSteamID: args[7],
|
||||||
|
weapon: args[9]
|
||||||
};
|
};
|
||||||
|
|
||||||
logParser.eventStore.session[args[3]] = data;
|
logParser.eventStore.session[args[3]] = data;
|
||||||
|
@ -1,16 +1,18 @@
|
|||||||
export default {
|
export default {
|
||||||
regex:
|
regex:
|
||||||
/^\[([0-9.:-]+)]\[([ 0-9]*)]LogNet: UChannel::Close: Sending CloseBunch\. ChIndex == [0-9]+\. Name: \[UChannel\] ChIndex: [0-9]+, Closing: [0-9]+ \[UNetConnection\] RemoteAddr: ([0-9]{17}):[0-9]+, Name: SteamNetConnection_[0-9]+, Driver: GameNetDriver SteamNetDriver_[0-9]+, IsServer: YES, PC: ([^ ]+PlayerController_C_[0-9]+), Owner: [^ ]+PlayerController_C_[0-9]+/,
|
/^\[([0-9.:-]+)]\[([ 0-9]*)]LogNet: UChannel::Close: Sending CloseBunch\. ChIndex == [0-9]+\. Name: \[UChannel\] ChIndex: [0-9]+, Closing: [0-9]+ \[UNetConnection\] RemoteAddr: ([\d.]+):[\d]+, Name: EOSIpNetConnection_[0-9]+, Driver: GameNetDriver EOSNetDriver_[0-9]+, IsServer: YES, PC: ([^ ]+PlayerController_C_[0-9]+), Owner: [^ ]+PlayerController_C_[0-9]+, UniqueId: RedpointEOS:([\d\w]+)/,
|
||||||
onMatch: (args, logParser) => {
|
onMatch: (args, logParser) => {
|
||||||
const data = {
|
const data = {
|
||||||
raw: args[0],
|
raw: args[0],
|
||||||
time: args[1],
|
time: args[1],
|
||||||
chainID: args[2],
|
chainID: args[2],
|
||||||
steamID: args[3],
|
ip: args[3],
|
||||||
playerController: args[4]
|
playerController: args[4],
|
||||||
|
eosID: args[5]
|
||||||
};
|
};
|
||||||
|
|
||||||
logParser.eventStore.disconnected[data.steamID] = true;
|
logParser.eventStore.disconnected[data.steamID] = true;
|
||||||
|
|
||||||
logParser.emit('PLAYER_DISCONNECTED', data);
|
logParser.emit('PLAYER_DISCONNECTED', data);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
28
squad-server/log-parser/player-join-succeeded.js
Normal file
28
squad-server/log-parser/player-join-succeeded.js
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
export default {
|
||||||
|
regex: /^\[([0-9.:-]+)]\[([ 0-9]*)]LogNet: Join succeeded: (.+)/,
|
||||||
|
onMatch: (args, logParser) => {
|
||||||
|
const data = {
|
||||||
|
raw: args[0],
|
||||||
|
time: args[1],
|
||||||
|
chainID: +args[2],
|
||||||
|
playerSuffix: args[3]
|
||||||
|
};
|
||||||
|
|
||||||
|
const joinRequestsData = { ...logParser.eventStore.joinRequests[data.chainID] };
|
||||||
|
|
||||||
|
data.eosID = joinRequestsData.eosID;
|
||||||
|
data.controller = joinRequestsData.controller;
|
||||||
|
data.steamID = `${logParser.eventStore.connectionIdToSteamID.get(joinRequestsData.connection)}`;
|
||||||
|
|
||||||
|
logParser.eventStore.connectionIdToSteamID.delete(joinRequestsData.connection);
|
||||||
|
|
||||||
|
delete logParser.eventStore.joinRequests[+data.chainID];
|
||||||
|
|
||||||
|
// Handle Reconnecting players
|
||||||
|
if (logParser.eventStore.disconnected[data.steamID]) {
|
||||||
|
delete logParser.eventStore.disconnected[data.steamID];
|
||||||
|
}
|
||||||
|
|
||||||
|
logParser.emit('JOIN_SUCCEEDED', data);
|
||||||
|
}
|
||||||
|
};
|
@ -1,13 +1,15 @@
|
|||||||
export default {
|
export default {
|
||||||
regex:
|
regex:
|
||||||
/^\[([0-9.:-]+)]\[([ 0-9]*)]LogSquadTrace: \[DedicatedServer](?:ASQPlayerController::)?OnPossess\(\): PC=(.+) Pawn=([A-z0-9_]+)_C/,
|
/^\[([0-9.:-]+)]\[([ 0-9]*)]LogSquadTrace: \[DedicatedServer](?:ASQPlayerController::)?OnPossess\(\): PC=(.+) \(Online IDs: EOS: ([\w\d]{32}) steam: (\d{17})\) Pawn=([A-z0-9_]+)_C/,
|
||||||
onMatch: (args, logParser) => {
|
onMatch: (args, logParser) => {
|
||||||
const data = {
|
const data = {
|
||||||
raw: args[0],
|
raw: args[0],
|
||||||
time: args[1],
|
time: args[1],
|
||||||
chainID: args[2],
|
chainID: args[2],
|
||||||
playerSuffix: args[3],
|
playerSuffix: args[3],
|
||||||
possessClassname: args[4],
|
playerEOSID: args[4],
|
||||||
|
playerSteamID: args[5],
|
||||||
|
possessClassname: args[6],
|
||||||
pawn: args[5]
|
pawn: args[5]
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
export default {
|
export default {
|
||||||
// the names are currently the wrong way around in these logs
|
// the names are currently the wrong way around in these logs
|
||||||
regex: /^\[([0-9.:-]+)]\[([ 0-9]*)]LogSquad: (.+) has revived (.+)\./,
|
regex:
|
||||||
|
/^\[([0-9.:-]+)]\[([ 0-9]*)]LogSquad: (.+) \(Online IDs: EOS: ([0-9a-f]{32}) steam: (\d{17})\) has revived (.+) \(Online IDs: EOS: ([0-9a-f]{32}) steam: (\d{17})\)\./,
|
||||||
onMatch: (args, logParser) => {
|
onMatch: (args, logParser) => {
|
||||||
const data = {
|
const data = {
|
||||||
...logParser.eventStore.session[args[3]],
|
...logParser.eventStore.session[args[3]],
|
||||||
@ -8,7 +9,11 @@ export default {
|
|||||||
time: args[1],
|
time: args[1],
|
||||||
chainID: args[2],
|
chainID: args[2],
|
||||||
reviverName: args[3],
|
reviverName: args[3],
|
||||||
victimName: args[4]
|
reviverEOSID: args[4],
|
||||||
|
reviverSteamID: args[5],
|
||||||
|
victimName: args[6],
|
||||||
|
victimEOSID: args[7],
|
||||||
|
victimSteamID: args[8]
|
||||||
};
|
};
|
||||||
|
|
||||||
logParser.emit('PLAYER_REVIVED', data);
|
logParser.emit('PLAYER_REVIVED', data);
|
||||||
|
@ -1,14 +1,16 @@
|
|||||||
export default {
|
export default {
|
||||||
regex:
|
regex:
|
||||||
/^\[([0-9.:-]+)]\[([ 0-9]*)]LogSquadTrace: \[DedicatedServer](?:ASQPlayerController::)?OnUnPossess\(\): PC=(.+)/,
|
/^\[([0-9.:-]+)]\[([ 0-9]*)]LogSquadTrace: \[DedicatedServer](?:ASQPlayerController::)?OnUnPossess\(\): PC=(.+) \(Online IDs: EOS: ([\w\d]{32}) steam: (\d{17})\)/,
|
||||||
onMatch: (args, logParser) => {
|
onMatch: (args, logParser) => {
|
||||||
const data = {
|
const data = {
|
||||||
raw: args[0],
|
raw: args[0],
|
||||||
time: args[1],
|
time: args[1],
|
||||||
chainID: args[2],
|
chainID: args[2],
|
||||||
playerSuffix: args[3],
|
playerSuffix: args[3],
|
||||||
|
playerEOSID: args[4],
|
||||||
|
playerSteamID: args[5],
|
||||||
switchPossess:
|
switchPossess:
|
||||||
args[3] in logParser.eventStore.session && logParser.eventStore.session[args[3]] === args[2]
|
args[4] in logParser.eventStore.session && logParser.eventStore.session[args[4]] === args[2]
|
||||||
};
|
};
|
||||||
|
|
||||||
delete logParser.eventStore.session[args[3]];
|
delete logParser.eventStore.session[args[3]];
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
export default {
|
export default {
|
||||||
regex:
|
regex:
|
||||||
/^\[([0-9.:-]+)]\[([ 0-9]*)]LogSquadTrace: \[DedicatedServer](?:ASQSoldier::)?Wound\(\): Player:(.+) KillingDamage=(?:-)*([0-9.]+) from ([A-z_0-9]+) caused by ([A-z_0-9-]+)_C/,
|
/^\[([0-9.:-]+)]\[([ 0-9]*)]LogSquadTrace: \[DedicatedServer](?:ASQSoldier::)?Wound\(\): Player:(.+) KillingDamage=(?:-)*([0-9.]+) from ([A-z_0-9]+) \(Online IDs: EOS: ([\w\d]{32}) steam: (\d{17}) \| Controller ID: ([\w\d]+)\) caused by ([A-z_0-9-]+)_C/,
|
||||||
onMatch: (args, logParser) => {
|
onMatch: (args, logParser) => {
|
||||||
const data = {
|
const data = {
|
||||||
...logParser.eventStore.session[args[3]],
|
...logParser.eventStore.session[args[3]],
|
||||||
@ -10,7 +10,9 @@ export default {
|
|||||||
victimName: args[3],
|
victimName: args[3],
|
||||||
damage: parseFloat(args[4]),
|
damage: parseFloat(args[4]),
|
||||||
attackerPlayerController: args[5],
|
attackerPlayerController: args[5],
|
||||||
weapon: args[6]
|
attackerEOSID: args[6],
|
||||||
|
attackerSteamID: args[7],
|
||||||
|
weapon: args[9]
|
||||||
};
|
};
|
||||||
|
|
||||||
logParser.eventStore.session[args[3]] = data;
|
logParser.eventStore.session[args[3]] = data;
|
||||||
|
@ -5,12 +5,11 @@ export default {
|
|||||||
const data = {
|
const data = {
|
||||||
raw: args[0],
|
raw: args[0],
|
||||||
time: args[1],
|
time: args[1],
|
||||||
chainID: args[2],
|
chainID: +args[2],
|
||||||
controller: args[3]
|
controller: args[3]
|
||||||
};
|
};
|
||||||
|
|
||||||
logParser.eventStore['player-controller'] = args[3];
|
logParser.eventStore.joinRequests[data.chainID].controller = data.controller;
|
||||||
|
|
||||||
logParser.emit('PLAYER_CONTROLLER_CONNECTED', data);
|
logParser.emit('PLAYER_CONTROLLER_CONNECTED', data);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
21
squad-server/log-parser/sending-auth-result.js
Normal file
21
squad-server/log-parser/sending-auth-result.js
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
export default {
|
||||||
|
regex:
|
||||||
|
/^\[([0-9.:-]+)]\[([ 0-9]*)]LogOnline: STEAM: AUTH HANDLER: Sending auth result to user (\d{17}) with flag success\? 1/,
|
||||||
|
onMatch: (args, logParser) => {
|
||||||
|
if (!logParser.eventStore['last-connection']) return;
|
||||||
|
|
||||||
|
const data = {
|
||||||
|
...logParser.eventStore['last-connection'],
|
||||||
|
steamID: args[3]
|
||||||
|
};
|
||||||
|
/* This is Called when unreal engine adds a client connection
|
||||||
|
First Step in Adding a Player to server
|
||||||
|
*/
|
||||||
|
|
||||||
|
logParser.eventStore.clients[data.connection] = data.steamID;
|
||||||
|
logParser.eventStore.connectionIdToSteamID.set(data.connection, data.steamID);
|
||||||
|
logParser.emit('CLIENT_CONNECTED', data);
|
||||||
|
|
||||||
|
delete logParser.eventStore['last-connection'];
|
||||||
|
}
|
||||||
|
};
|
@ -2,7 +2,7 @@ import Sequelize from 'sequelize';
|
|||||||
|
|
||||||
import BasePlugin from './base-plugin.js';
|
import BasePlugin from './base-plugin.js';
|
||||||
|
|
||||||
const { DataTypes } = Sequelize;
|
const { DataTypes, QueryTypes } = Sequelize;
|
||||||
|
|
||||||
export default class DBLog extends BasePlugin {
|
export default class DBLog extends BasePlugin {
|
||||||
static get description() {
|
static get description() {
|
||||||
@ -146,6 +146,44 @@ export default class DBLog extends BasePlugin {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
this.createModel(
|
||||||
|
'Player',
|
||||||
|
{
|
||||||
|
id: {
|
||||||
|
type: DataTypes.INTEGER,
|
||||||
|
primaryKey: true,
|
||||||
|
autoIncrement: true
|
||||||
|
},
|
||||||
|
eosID: {
|
||||||
|
type: DataTypes.STRING,
|
||||||
|
unique: true
|
||||||
|
},
|
||||||
|
steamID: {
|
||||||
|
type: DataTypes.STRING,
|
||||||
|
notNull: true,
|
||||||
|
unique: true
|
||||||
|
},
|
||||||
|
lastName: {
|
||||||
|
type: DataTypes.STRING
|
||||||
|
},
|
||||||
|
lastIP: {
|
||||||
|
type: DataTypes.STRING
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
charset: 'utf8mb4',
|
||||||
|
collate: 'utf8mb4_unicode_ci',
|
||||||
|
indexes: [
|
||||||
|
{
|
||||||
|
fields: ['eosID']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
fields: ['steamID']
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
this.createModel(
|
this.createModel(
|
||||||
'Wound',
|
'Wound',
|
||||||
{
|
{
|
||||||
@ -329,37 +367,44 @@ export default class DBLog extends BasePlugin {
|
|||||||
onDelete: 'CASCADE'
|
onDelete: 'CASCADE'
|
||||||
});
|
});
|
||||||
|
|
||||||
this.models.SteamUser.hasMany(this.models.Wound, {
|
this.models.Player.hasMany(this.models.Wound, {
|
||||||
|
sourceKey: 'steamID',
|
||||||
foreignKey: { name: 'attacker' },
|
foreignKey: { name: 'attacker' },
|
||||||
onDelete: 'CASCADE'
|
onDelete: 'CASCADE'
|
||||||
});
|
});
|
||||||
|
|
||||||
this.models.SteamUser.hasMany(this.models.Wound, {
|
this.models.Player.hasMany(this.models.Wound, {
|
||||||
|
sourceKey: 'steamID',
|
||||||
foreignKey: { name: 'victim' },
|
foreignKey: { name: 'victim' },
|
||||||
onDelete: 'CASCADE'
|
onDelete: 'CASCADE'
|
||||||
});
|
});
|
||||||
|
|
||||||
this.models.SteamUser.hasMany(this.models.Death, {
|
this.models.Player.hasMany(this.models.Death, {
|
||||||
|
sourceKey: 'steamID',
|
||||||
foreignKey: { name: 'attacker' },
|
foreignKey: { name: 'attacker' },
|
||||||
onDelete: 'CASCADE'
|
onDelete: 'CASCADE'
|
||||||
});
|
});
|
||||||
|
|
||||||
this.models.SteamUser.hasMany(this.models.Death, {
|
this.models.Player.hasMany(this.models.Death, {
|
||||||
|
sourceKey: 'steamID',
|
||||||
foreignKey: { name: 'victim' },
|
foreignKey: { name: 'victim' },
|
||||||
onDelete: 'CASCADE'
|
onDelete: 'CASCADE'
|
||||||
});
|
});
|
||||||
|
|
||||||
this.models.SteamUser.hasMany(this.models.Revive, {
|
this.models.Player.hasMany(this.models.Revive, {
|
||||||
|
sourceKey: 'steamID',
|
||||||
foreignKey: { name: 'attacker' },
|
foreignKey: { name: 'attacker' },
|
||||||
onDelete: 'CASCADE'
|
onDelete: 'CASCADE'
|
||||||
});
|
});
|
||||||
|
|
||||||
this.models.SteamUser.hasMany(this.models.Revive, {
|
this.models.Player.hasMany(this.models.Revive, {
|
||||||
|
sourceKey: 'steamID',
|
||||||
foreignKey: { name: 'victim' },
|
foreignKey: { name: 'victim' },
|
||||||
onDelete: 'CASCADE'
|
onDelete: 'CASCADE'
|
||||||
});
|
});
|
||||||
|
|
||||||
this.models.SteamUser.hasMany(this.models.Revive, {
|
this.models.Player.hasMany(this.models.Revive, {
|
||||||
|
sourceKey: 'steamID',
|
||||||
foreignKey: { name: 'reviver' },
|
foreignKey: { name: 'reviver' },
|
||||||
onDelete: 'CASCADE'
|
onDelete: 'CASCADE'
|
||||||
});
|
});
|
||||||
@ -392,9 +437,12 @@ export default class DBLog extends BasePlugin {
|
|||||||
this.onTickRate = this.onTickRate.bind(this);
|
this.onTickRate = this.onTickRate.bind(this);
|
||||||
this.onUpdatedA2SInformation = this.onUpdatedA2SInformation.bind(this);
|
this.onUpdatedA2SInformation = this.onUpdatedA2SInformation.bind(this);
|
||||||
this.onNewGame = this.onNewGame.bind(this);
|
this.onNewGame = this.onNewGame.bind(this);
|
||||||
|
this.onPlayerConnected = this.onPlayerConnected.bind(this);
|
||||||
this.onPlayerWounded = this.onPlayerWounded.bind(this);
|
this.onPlayerWounded = this.onPlayerWounded.bind(this);
|
||||||
this.onPlayerDied = this.onPlayerDied.bind(this);
|
this.onPlayerDied = this.onPlayerDied.bind(this);
|
||||||
this.onPlayerRevived = this.onPlayerRevived.bind(this);
|
this.onPlayerRevived = this.onPlayerRevived.bind(this);
|
||||||
|
this.migrateSteamUsersIntoPlayers = this.migrateSteamUsersIntoPlayers.bind(this);
|
||||||
|
this.dropAllForeignKeys = this.dropAllForeignKeys.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
createModel(name, schema) {
|
createModel(name, schema) {
|
||||||
@ -409,12 +457,15 @@ export default class DBLog extends BasePlugin {
|
|||||||
await this.models.TickRate.sync();
|
await this.models.TickRate.sync();
|
||||||
await this.models.PlayerCount.sync();
|
await this.models.PlayerCount.sync();
|
||||||
await this.models.SteamUser.sync();
|
await this.models.SteamUser.sync();
|
||||||
|
await this.models.Player.sync();
|
||||||
await this.models.Wound.sync();
|
await this.models.Wound.sync();
|
||||||
await this.models.Death.sync();
|
await this.models.Death.sync();
|
||||||
await this.models.Revive.sync();
|
await this.models.Revive.sync();
|
||||||
}
|
}
|
||||||
|
|
||||||
async mount() {
|
async mount() {
|
||||||
|
await this.migrateSteamUsersIntoPlayers();
|
||||||
|
|
||||||
await this.models.Server.upsert({
|
await this.models.Server.upsert({
|
||||||
id: this.options.overrideServerID || this.server.id,
|
id: this.options.overrideServerID || this.server.id,
|
||||||
name: this.server.serverName
|
name: this.server.serverName
|
||||||
@ -427,6 +478,7 @@ export default class DBLog extends BasePlugin {
|
|||||||
this.server.on('TICK_RATE', this.onTickRate);
|
this.server.on('TICK_RATE', this.onTickRate);
|
||||||
this.server.on('UPDATED_A2S_INFORMATION', this.onUpdatedA2SInformation);
|
this.server.on('UPDATED_A2S_INFORMATION', this.onUpdatedA2SInformation);
|
||||||
this.server.on('NEW_GAME', this.onNewGame);
|
this.server.on('NEW_GAME', this.onNewGame);
|
||||||
|
this.server.on('PLAYER_CONNECTED', this.onPlayerConnected);
|
||||||
this.server.on('PLAYER_WOUNDED', this.onPlayerWounded);
|
this.server.on('PLAYER_WOUNDED', this.onPlayerWounded);
|
||||||
this.server.on('PLAYER_DIED', this.onPlayerDied);
|
this.server.on('PLAYER_DIED', this.onPlayerDied);
|
||||||
this.server.on('PLAYER_REVIVED', this.onPlayerRevived);
|
this.server.on('PLAYER_REVIVED', this.onPlayerRevived);
|
||||||
@ -436,6 +488,7 @@ export default class DBLog extends BasePlugin {
|
|||||||
this.server.removeEventListener('TICK_RATE', this.onTickRate);
|
this.server.removeEventListener('TICK_RATE', this.onTickRate);
|
||||||
this.server.removeEventListener('UPDATED_A2S_INFORMATION', this.onTickRate);
|
this.server.removeEventListener('UPDATED_A2S_INFORMATION', this.onTickRate);
|
||||||
this.server.removeEventListener('NEW_GAME', this.onNewGame);
|
this.server.removeEventListener('NEW_GAME', this.onNewGame);
|
||||||
|
this.server.removeEventListener('PLAYER_CONNECTED', this.onPlayerConnected);
|
||||||
this.server.removeEventListener('PLAYER_WOUNDED', this.onPlayerWounded);
|
this.server.removeEventListener('PLAYER_WOUNDED', this.onPlayerWounded);
|
||||||
this.server.removeEventListener('PLAYER_DIED', this.onPlayerDied);
|
this.server.removeEventListener('PLAYER_DIED', this.onPlayerDied);
|
||||||
this.server.removeEventListener('PLAYER_REVIVED', this.onPlayerRevived);
|
this.server.removeEventListener('PLAYER_REVIVED', this.onPlayerRevived);
|
||||||
@ -479,15 +532,27 @@ export default class DBLog extends BasePlugin {
|
|||||||
|
|
||||||
async onPlayerWounded(info) {
|
async onPlayerWounded(info) {
|
||||||
if (info.attacker)
|
if (info.attacker)
|
||||||
await this.models.SteamUser.upsert({
|
await this.models.Player.upsert(
|
||||||
steamID: info.attacker.steamID,
|
{
|
||||||
lastName: info.attacker.name
|
eosID: info.attacker.eosID,
|
||||||
});
|
steamID: info.attacker.steamID,
|
||||||
|
lastName: info.attacker.name
|
||||||
|
},
|
||||||
|
{
|
||||||
|
conflictFields: ['steamID']
|
||||||
|
}
|
||||||
|
);
|
||||||
if (info.victim)
|
if (info.victim)
|
||||||
await this.models.SteamUser.upsert({
|
await this.models.Player.upsert(
|
||||||
steamID: info.victim.steamID,
|
{
|
||||||
lastName: info.victim.name
|
eosID: info.victim.eosID,
|
||||||
});
|
steamID: info.victim.steamID,
|
||||||
|
lastName: info.victim.name
|
||||||
|
},
|
||||||
|
{
|
||||||
|
conflictFields: ['steamID']
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
await this.models.Wound.create({
|
await this.models.Wound.create({
|
||||||
server: this.options.overrideServerID || this.server.id,
|
server: this.options.overrideServerID || this.server.id,
|
||||||
@ -509,15 +574,27 @@ export default class DBLog extends BasePlugin {
|
|||||||
|
|
||||||
async onPlayerDied(info) {
|
async onPlayerDied(info) {
|
||||||
if (info.attacker)
|
if (info.attacker)
|
||||||
await this.models.SteamUser.upsert({
|
await this.models.Player.upsert(
|
||||||
steamID: info.attacker.steamID,
|
{
|
||||||
lastName: info.attacker.name
|
eosID: info.attacker.eosID,
|
||||||
});
|
steamID: info.attacker.steamID,
|
||||||
|
lastName: info.attacker.name
|
||||||
|
},
|
||||||
|
{
|
||||||
|
conflictFields: ['steamID']
|
||||||
|
}
|
||||||
|
);
|
||||||
if (info.victim)
|
if (info.victim)
|
||||||
await this.models.SteamUser.upsert({
|
await this.models.Player.upsert(
|
||||||
steamID: info.victim.steamID,
|
{
|
||||||
lastName: info.victim.name
|
eosID: info.victim.eosID,
|
||||||
});
|
steamID: info.victim.steamID,
|
||||||
|
lastName: info.victim.name
|
||||||
|
},
|
||||||
|
{
|
||||||
|
conflictFields: ['steamID']
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
await this.models.Death.create({
|
await this.models.Death.create({
|
||||||
server: this.options.overrideServerID || this.server.id,
|
server: this.options.overrideServerID || this.server.id,
|
||||||
@ -540,20 +617,38 @@ export default class DBLog extends BasePlugin {
|
|||||||
|
|
||||||
async onPlayerRevived(info) {
|
async onPlayerRevived(info) {
|
||||||
if (info.attacker)
|
if (info.attacker)
|
||||||
await this.models.SteamUser.upsert({
|
await this.models.Player.upsert(
|
||||||
steamID: info.attacker.steamID,
|
{
|
||||||
lastName: info.attacker.name
|
eosID: info.attacker.eosID,
|
||||||
});
|
steamID: info.attacker.steamID,
|
||||||
|
lastName: info.attacker.name
|
||||||
|
},
|
||||||
|
{
|
||||||
|
conflictFields: ['steamID']
|
||||||
|
}
|
||||||
|
);
|
||||||
if (info.victim)
|
if (info.victim)
|
||||||
await this.models.SteamUser.upsert({
|
await this.models.Player.upsert(
|
||||||
steamID: info.victim.steamID,
|
{
|
||||||
lastName: info.victim.name
|
eosID: info.victim.eosID,
|
||||||
});
|
steamID: info.victim.steamID,
|
||||||
|
lastName: info.victim.name
|
||||||
|
},
|
||||||
|
{
|
||||||
|
conflictFields: ['steamID']
|
||||||
|
}
|
||||||
|
);
|
||||||
if (info.reviver)
|
if (info.reviver)
|
||||||
await this.models.SteamUser.upsert({
|
await this.models.Player.upsert(
|
||||||
steamID: info.reviver.steamID,
|
{
|
||||||
lastName: info.reviver.name
|
eosID: info.reviver.eosID,
|
||||||
});
|
steamID: info.reviver.steamID,
|
||||||
|
lastName: info.reviver.name
|
||||||
|
},
|
||||||
|
{
|
||||||
|
conflictFields: ['steamID']
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
await this.models.Revive.create({
|
await this.models.Revive.create({
|
||||||
server: this.options.overrideServerID || this.server.id,
|
server: this.options.overrideServerID || this.server.id,
|
||||||
@ -577,4 +672,89 @@ export default class DBLog extends BasePlugin {
|
|||||||
reviverSquadID: info.reviver ? info.reviver.squadID : null
|
reviverSquadID: info.reviver ? info.reviver.squadID : null
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async onPlayerConnected(info) {
|
||||||
|
await this.models.Player.upsert(
|
||||||
|
{
|
||||||
|
eosID: info.eosID,
|
||||||
|
steamID: info.player.steamID,
|
||||||
|
lastName: info.player.name,
|
||||||
|
lastIP: info.ip
|
||||||
|
},
|
||||||
|
{
|
||||||
|
conflictFields: ['steamID']
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
async migrateSteamUsersIntoPlayers() {
|
||||||
|
try {
|
||||||
|
const steamUsersCount = await this.models.SteamUser.count();
|
||||||
|
const playersCount = await this.models.Player.count();
|
||||||
|
|
||||||
|
if (steamUsersCount < playersCount) {
|
||||||
|
this.verbose(
|
||||||
|
1,
|
||||||
|
`Skipping migration from SteamUsers to Players due to a previous successful migration.`
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.dropAllForeignKeys();
|
||||||
|
|
||||||
|
const steamUsers = (await this.models.SteamUser.findAll()).map((u) => u.dataValues);
|
||||||
|
await this.models.Player.bulkCreate(steamUsers);
|
||||||
|
|
||||||
|
this.verbose(1, `Migration from SteamUsers to Players successful`);
|
||||||
|
} catch (error) {
|
||||||
|
this.verbose(1, `Error during Migration from SteamUsers to Players: ${error}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async dropAllForeignKeys() {
|
||||||
|
this.verbose(
|
||||||
|
1,
|
||||||
|
`Starting to drop constraints on DB: ${this.options.database.config.database} related to DBLog_SteamUsers deptecated table.`
|
||||||
|
);
|
||||||
|
for (const modelName in this.models) {
|
||||||
|
const model = this.models[modelName];
|
||||||
|
const tableName = model.tableName;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const result = await this.options.database.query(
|
||||||
|
`SELECT * FROM information_schema.key_column_usage WHERE referenced_table_name IS NOT NULL AND table_schema = '${this.options.database.config.database}' AND table_name = '${tableName}';`,
|
||||||
|
{ type: QueryTypes.SELECT }
|
||||||
|
);
|
||||||
|
|
||||||
|
for (const r of result) {
|
||||||
|
if (r.REFERENCED_TABLE_NAME === 'DBLog_SteamUsers') {
|
||||||
|
this.verbose(
|
||||||
|
1,
|
||||||
|
`Found constraint ${r.COLUMN_NAME} on table ${tableName}, referencing ${r.REFERENCED_COLUMN_NAME} on ${r.REFERENCED_TABLE_NAME}`
|
||||||
|
);
|
||||||
|
|
||||||
|
await this.options.database
|
||||||
|
.query(`ALTER TABLE ${tableName} DROP FOREIGN KEY ${r.CONSTRAINT_NAME}`, {
|
||||||
|
type: QueryTypes.RAW
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
this.verbose(1, `Dropped foreign key ${r.COLUMN_NAME} on table ${tableName}`);
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
this.verbose(
|
||||||
|
1,
|
||||||
|
`Error dropping foreign key ${r.COLUMN_NAME} on table ${tableName}:`,
|
||||||
|
e
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
this.verbose(1, `Error dropping foreign keys for table ${tableName}:`, error);
|
||||||
|
} finally {
|
||||||
|
model.sync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
await this.models.Player.sync();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@ import Rcon from 'core/rcon';
|
|||||||
export default class SquadRcon extends Rcon {
|
export default class SquadRcon extends Rcon {
|
||||||
processChatPacket(decodedPacket) {
|
processChatPacket(decodedPacket) {
|
||||||
const matchChat = decodedPacket.body.match(
|
const matchChat = decodedPacket.body.match(
|
||||||
/\[(ChatAll|ChatTeam|ChatSquad|ChatAdmin)] \[SteamID:([0-9]{17})] (.+?) : (.*)/
|
/\[(ChatAll|ChatTeam|ChatSquad|ChatAdmin)] \[Online IDs:EOS: ([0-9a-f]{32}) steam: (\d{17})\] (.+?) : (.*)/
|
||||||
);
|
);
|
||||||
if (matchChat) {
|
if (matchChat) {
|
||||||
Logger.verbose('SquadRcon', 2, `Matched chat message: ${decodedPacket.body}`);
|
Logger.verbose('SquadRcon', 2, `Matched chat message: ${decodedPacket.body}`);
|
||||||
@ -12,9 +12,10 @@ export default class SquadRcon extends Rcon {
|
|||||||
this.emit('CHAT_MESSAGE', {
|
this.emit('CHAT_MESSAGE', {
|
||||||
raw: decodedPacket.body,
|
raw: decodedPacket.body,
|
||||||
chat: matchChat[1],
|
chat: matchChat[1],
|
||||||
steamID: matchChat[2],
|
eosID: matchChat[2],
|
||||||
name: matchChat[3],
|
steamID: matchChat[3],
|
||||||
message: matchChat[4],
|
name: matchChat[4],
|
||||||
|
message: matchChat[5],
|
||||||
time: new Date()
|
time: new Date()
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -22,14 +23,14 @@ export default class SquadRcon extends Rcon {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const matchPossessedAdminCam = decodedPacket.body.match(
|
const matchPossessedAdminCam = decodedPacket.body.match(
|
||||||
/\[SteamID:([0-9]{17})] (.+?) has possessed admin camera./
|
/\[Online Ids:EOS: ([0-9a-f]{32}) steam: (\d{17})\] (.+) has possessed admin camera\./
|
||||||
);
|
);
|
||||||
if (matchPossessedAdminCam) {
|
if (matchPossessedAdminCam) {
|
||||||
Logger.verbose('SquadRcon', 2, `Matched admin camera possessed: ${decodedPacket.body}`);
|
Logger.verbose('SquadRcon', 2, `Matched admin camera possessed: ${decodedPacket.body}`);
|
||||||
this.emit('POSSESSED_ADMIN_CAMERA', {
|
this.emit('POSSESSED_ADMIN_CAMERA', {
|
||||||
raw: decodedPacket.body,
|
raw: decodedPacket.body,
|
||||||
steamID: matchPossessedAdminCam[1],
|
steamID: matchPossessedAdminCam[2],
|
||||||
name: matchPossessedAdminCam[2],
|
name: matchPossessedAdminCam[3],
|
||||||
time: new Date()
|
time: new Date()
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -37,14 +38,14 @@ export default class SquadRcon extends Rcon {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const matchUnpossessedAdminCam = decodedPacket.body.match(
|
const matchUnpossessedAdminCam = decodedPacket.body.match(
|
||||||
/\[SteamID:([0-9]{17})] (.+?) has unpossessed admin camera./
|
/\[Online IDs:EOS: ([0-9a-f]{32}) steam: (\d{17})\] (.+) has unpossessed admin camera\./
|
||||||
);
|
);
|
||||||
if (matchUnpossessedAdminCam) {
|
if (matchUnpossessedAdminCam) {
|
||||||
Logger.verbose('SquadRcon', 2, `Matched admin camera possessed: ${decodedPacket.body}`);
|
Logger.verbose('SquadRcon', 2, `Matched admin camera possessed: ${decodedPacket.body}`);
|
||||||
this.emit('UNPOSSESSED_ADMIN_CAMERA', {
|
this.emit('UNPOSSESSED_ADMIN_CAMERA', {
|
||||||
raw: decodedPacket.body,
|
raw: decodedPacket.body,
|
||||||
steamID: matchUnpossessedAdminCam[1],
|
steamID: matchUnpossessedAdminCam[2],
|
||||||
name: matchUnpossessedAdminCam[2],
|
name: matchUnpossessedAdminCam[3],
|
||||||
time: new Date()
|
time: new Date()
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -68,7 +69,7 @@ export default class SquadRcon extends Rcon {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const matchKick = decodedPacket.body.match(
|
const matchKick = decodedPacket.body.match(
|
||||||
/Kicked player ([0-9]+)\. \[steamid=([0-9]{17})] (.*)/
|
/Kicked player ([0-9]+)\. \[Online IDs= EOS: ([0-9a-f]{32}) steam: (\d{17})] (.*)/
|
||||||
);
|
);
|
||||||
if (matchKick) {
|
if (matchKick) {
|
||||||
Logger.verbose('SquadRcon', 2, `Matched kick message: ${decodedPacket.body}`);
|
Logger.verbose('SquadRcon', 2, `Matched kick message: ${decodedPacket.body}`);
|
||||||
@ -76,8 +77,8 @@ export default class SquadRcon extends Rcon {
|
|||||||
this.emit('PLAYER_KICKED', {
|
this.emit('PLAYER_KICKED', {
|
||||||
raw: decodedPacket.body,
|
raw: decodedPacket.body,
|
||||||
playerID: matchKick[1],
|
playerID: matchKick[1],
|
||||||
steamID: matchKick[2],
|
steamID: matchKick[3],
|
||||||
name: matchKick[3],
|
name: matchKick[4],
|
||||||
time: new Date()
|
time: new Date()
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -85,18 +86,14 @@ export default class SquadRcon extends Rcon {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const matchSqCreated = decodedPacket.body.match(
|
const matchSqCreated = decodedPacket.body.match(
|
||||||
/(.+) \(Steam ID: ([0-9]{17})\) has created Squad (\d+) \(Squad Name: (.+)\) on (.+)/
|
/(?<playerName>.+) \(Online IDs: EOS: (?<playerEOSID>[\da-f]{32})(?: steam: (?<playerSteamID>\d{17}))?\) has created Squad (?<squadID>\d+) \(Squad Name: (?<squadName>.+)\) on (?<teamName>.+)/
|
||||||
);
|
);
|
||||||
if (matchSqCreated) {
|
if (matchSqCreated) {
|
||||||
Logger.verbose('SquadRcon', 2, `Matched Squad Created: ${decodedPacket.body}`);
|
Logger.verbose('SquadRcon', 2, `Matched Squad Created: ${decodedPacket.body}`);
|
||||||
|
|
||||||
this.emit('SQUAD_CREATED', {
|
this.emit('SQUAD_CREATED', {
|
||||||
time: new Date(),
|
time: new Date(),
|
||||||
playerName: matchSqCreated[1],
|
...matchSqCreated.groups
|
||||||
playerSteamID: matchSqCreated[2],
|
|
||||||
squadID: matchSqCreated[3],
|
|
||||||
squadName: matchSqCreated[4],
|
|
||||||
teamName: matchSqCreated[5]
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@ -143,19 +140,17 @@ export default class SquadRcon extends Rcon {
|
|||||||
|
|
||||||
for (const line of response.split('\n')) {
|
for (const line of response.split('\n')) {
|
||||||
const match = line.match(
|
const match = line.match(
|
||||||
/ID: ([0-9]+) \| SteamID: ([0-9]{17}) \| Name: (.+) \| Team ID: ([0-9]+) \| Squad ID: ([0-9]+|N\/A) \| Is Leader: (True|False) \| Role: ([A-Za-z0-9_]*)\b/
|
/^ID: (?<playerID>\d+) \| Online IDs: EOS: (?<eosID>[a-f\d]{32}) (?:steam: (?<steamID>\d{17}) )?\| Name: (?<name>.+) \| Team ID: (?<teamID>\d|N\/A) \| Squad ID: (?<squadID>\d+|N\/A) \| Is Leader: (?<isLeader>True|False) \| Role: (?<role>.+)$/
|
||||||
);
|
);
|
||||||
if (!match) continue;
|
if (!match) continue;
|
||||||
|
|
||||||
players.push({
|
const data = match.groups;
|
||||||
playerID: match[1],
|
data.playerID = +data.playerID;
|
||||||
steamID: match[2],
|
data.isLeader = data.isLeader === 'True';
|
||||||
name: match[3],
|
data.teamID = data.teamID !== 'N/A' ? +data.teamID : null;
|
||||||
teamID: match[4],
|
data.squadID = data.squadID !== 'N/A' ? +data.squadID : null;
|
||||||
squadID: match[5] !== 'N/A' ? match[5] : null,
|
|
||||||
isLeader: match[6] === 'True',
|
players.push(data);
|
||||||
role: match[7]
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return players;
|
return players;
|
||||||
@ -172,21 +167,17 @@ export default class SquadRcon extends Rcon {
|
|||||||
|
|
||||||
for (const line of responseSquad.split('\n')) {
|
for (const line of responseSquad.split('\n')) {
|
||||||
const match = line.match(
|
const match = line.match(
|
||||||
/ID: ([0-9]+) \| Name: (.+) \| Size: ([0-9]+) \| Locked: (True|False) \| Creator Name: (.+) \| Creator Steam ID: ([0-9]{17})/
|
/ID: (?<squadID>\d+) \| Name: (?<squadName>.+) \| Size: (?<size>\d+) \| Locked: (?<locked>True|False) \| Creator Name: (?<creatorName>.+) \| Creator Online IDs: EOS: (?<creatorEOSID>[a-f\d]{32})(?: steam: (?<creatorSteamID>\d{17}))?/
|
||||||
);
|
);
|
||||||
const matchSide = line.match(/Team ID: (1|2) \((.+)\)/);
|
const matchSide = line.match(/Team ID: (\d) \((.+)\)/);
|
||||||
if (matchSide) {
|
if (matchSide) {
|
||||||
teamID = matchSide[1];
|
teamID = +matchSide[1];
|
||||||
teamName = matchSide[2];
|
teamName = matchSide[2];
|
||||||
}
|
}
|
||||||
if (!match) continue;
|
if (!match) continue;
|
||||||
|
match.groups.squadID = +match.groups.squadID;
|
||||||
squads.push({
|
squads.push({
|
||||||
squadID: match[1],
|
...match.groups,
|
||||||
squadName: match[2],
|
|
||||||
size: match[3],
|
|
||||||
locked: match[4],
|
|
||||||
creatorName: match[5],
|
|
||||||
creatorSteamID: match[6],
|
|
||||||
teamID: teamID,
|
teamID: teamID,
|
||||||
teamName: teamName
|
teamName: teamName
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user