From 26244c990cc91270c7264a591397424f37eaffee Mon Sep 17 00:00:00 2001 From: ect0s <73128770+ect0s@users.noreply.github.com> Date: Wed, 9 Nov 2022 19:46:41 -0500 Subject: [PATCH 1/4] EventStore Session State Break eventstore into stateful sub objects, clearEventStore method for management. --- core/log-parser/index.js | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/core/log-parser/index.js b/core/log-parser/index.js index 8f8867e..c0fe808 100644 --- a/core/log-parser/index.js +++ b/core/log-parser/index.js @@ -14,7 +14,12 @@ export default class LogParser extends EventEmitter { options.filename = filename; - this.eventStore = {}; + this.eventStore = { + disconnected: {}, // holding area, cleared on map change. + players: {}, // persistent data, steamid, controller, suffix. + session: {}, // old eventstore, nonpersistent data + clients: {} // used in the connection chain before we resolve a player. + }; this.linesPerMinute = 0; this.matchingLinesPerMinute = 0; @@ -61,6 +66,19 @@ export default class LogParser extends EventEmitter { this.linesPerMinute++; } + // manage cleanup disconnected players, session data. + clearEventStore() { + Logger.verbose('LogParser', 2, 'Cleaning Eventstore'); + for (const player of Object.values(this.eventStore.players)) { + if (this.eventStore.disconnected[player.steamID] === true) { + Logger.verbose('LogParser', 2, `Removing ${player.steamID} from eventStore`); + delete this.eventStore.players[player.steamID]; + delete this.eventStore.disconnected[player.steamID]; + } + } + this.eventStore.matchData = {}; + } + getRules() { return []; } From 49809169b870e54e2c0b2089a3d2c1a30d80ecd7 Mon Sep 17 00:00:00 2001 From: ect0s <73128770+ect0s@users.noreply.github.com> Date: Wed, 9 Nov 2022 20:20:50 -0500 Subject: [PATCH 2/4] Player Connection/Disconnection Flow. cleareventStore caller pending connection destroyed: error path for clients that fail to connect, required to cleanup connection state in this error case. client-connected: Supersedes steamid connected, use base unreal engine client flow. Removes dependancy on EAC (broken as of squad 3.4). First step in resolving a new client connection. this gets us a connection id, steamid. client-login: 2nd step in player connected flow, this setups the steamid into eventstore.steamid-connected. playercontroller connected: gets us player controller. used in player connected flow. player-connected: update to use new eventStore layout, now all players should always have suffix,steamid,controller. These are now also cached within the logparser for lookup. last step in player connected flow. player-disconnected: uses new eventStore layout, marks players in eventStore.disconnected but doesn't remove cached players till map change; may be needed in cases with delayed logs, needs further testing. Broken as of Squad 3.4 due to EAC changes steamid-connected: Removed in favor of client-connected, no longer works as of squad 3.4 due to EAC changes. --- core/log-parser/index.js | 2 +- squad-server/log-parser/client-connected.js | 19 ++++++++++++++++++ squad-server/log-parser/client-login.js | 20 +++++++++++++++++++ squad-server/log-parser/index.js | 10 ++++++++-- squad-server/log-parser/new-game.js | 1 + .../pending-connection-destroyed.js | 20 +++++++++++++++++++ squad-server/log-parser/player-connected.js | 15 +++++++++++++- .../log-parser/player-disconnected.js | 6 ++++-- .../log-parser/playercontroller-connected.js | 16 +++++++++++++++ squad-server/log-parser/steamid-connected.js | 7 ------- 10 files changed, 103 insertions(+), 13 deletions(-) create mode 100644 squad-server/log-parser/client-connected.js create mode 100644 squad-server/log-parser/client-login.js create mode 100644 squad-server/log-parser/pending-connection-destroyed.js create mode 100644 squad-server/log-parser/playercontroller-connected.js delete mode 100644 squad-server/log-parser/steamid-connected.js diff --git a/core/log-parser/index.js b/core/log-parser/index.js index c0fe808..2a91ebb 100644 --- a/core/log-parser/index.js +++ b/core/log-parser/index.js @@ -76,7 +76,7 @@ export default class LogParser extends EventEmitter { delete this.eventStore.disconnected[player.steamID]; } } - this.eventStore.matchData = {}; + this.eventStore.session = {}; } getRules() { diff --git a/squad-server/log-parser/client-connected.js b/squad-server/log-parser/client-connected.js new file mode 100644 index 0000000..55e8dbc --- /dev/null +++ b/squad-server/log-parser/client-connected.js @@ -0,0 +1,19 @@ +export default { + regex: + /^\[([0-9.:-]+)]\[([ 0-9]*)]LogNet: AddClientConnection: Added client connection: \[UNetConnection\] RemoteAddr: ([0-9]{17}):[0-9]+, Name: (SteamNetConnection_[0-9]+), Driver: GameNetDriver (SteamNetDriver_[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], + 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.clients[args[4]] = args[3]; + logParser.emit('CLIENT_CONNECTED', data); + } +}; diff --git a/squad-server/log-parser/client-login.js b/squad-server/log-parser/client-login.js new file mode 100644 index 0000000..97d59f0 --- /dev/null +++ b/squad-server/log-parser/client-login.js @@ -0,0 +1,20 @@ +export default { + regex: + /^\[([0-9.:-]+)]\[([ 0-9]*)]LogSquad: Login: NewPlayer: SteamNetConnection \/Engine\/Transient\.(SteamNetConnection_[0-9]+)/, + onMatch: (args, logParser) => { + const data = { + raw: args[0], + time: args[1], + chainID: args[2], + connection: args[3] + }; + /* This is Called when a player begins the Login process + We use this to get a SteamID into playerConnected. + 2nd Step in player connected path + */ + + logParser.eventStore['steamid-connected'] = logParser.eventStore.clients[args[3]]; + delete logParser.eventStore.clients[args[3]]; + logParser.emit('CLIENT_LOGIN', data); + } +}; diff --git a/squad-server/log-parser/index.js b/squad-server/log-parser/index.js index 990f41f..db2d705 100644 --- a/squad-server/log-parser/index.js +++ b/squad-server/log-parser/index.js @@ -4,6 +4,7 @@ import AdminBroadcast from './admin-broadcast.js'; import DeployableDamaged from './deployable-damaged.js'; import NewGame from './new-game.js'; import PlayerConnected from './player-connected.js'; +import PlayerControllerConnected from './playercontroller-connected.js'; import PlayerDisconnected from './player-disconnected.js'; import PlayerDamaged from './player-damaged.js'; import PlayerDied from './player-died.js'; @@ -13,7 +14,9 @@ import PlayerUnPossess from './player-un-possess.js'; import PlayerWounded from './player-wounded.js'; import RoundWinner from './round-winner.js'; import ServerTickRate from './server-tick-rate.js'; -import SteamIDConnected from './steamid-connected.js'; +import ClientConnected from './client-connected.js'; +import ClientLogin from './client-login.js'; +import PendingConnectionDestroyed from './pending-connection-destroyed.js'; import SquadCreated from './squad-created.js'; export default class SquadLogParser extends LogParser { @@ -27,6 +30,7 @@ export default class SquadLogParser extends LogParser { DeployableDamaged, NewGame, PlayerConnected, + PlayerControllerConnected, PlayerDisconnected, PlayerDamaged, PlayerDied, @@ -36,7 +40,9 @@ export default class SquadLogParser extends LogParser { PlayerWounded, RoundWinner, ServerTickRate, - SteamIDConnected, + ClientConnected, + ClientLogin, + PendingConnectionDestroyed, SquadCreated ]; } diff --git a/squad-server/log-parser/new-game.js b/squad-server/log-parser/new-game.js index 251285d..477de2f 100644 --- a/squad-server/log-parser/new-game.js +++ b/squad-server/log-parser/new-game.js @@ -18,5 +18,6 @@ export default { delete logParser.eventStore.WON; logParser.emit('NEW_GAME', data); + logParser.clearEventStore(); } }; diff --git a/squad-server/log-parser/pending-connection-destroyed.js b/squad-server/log-parser/pending-connection-destroyed.js new file mode 100644 index 0000000..3d4aa1c --- /dev/null +++ b/squad-server/log-parser/pending-connection-destroyed.js @@ -0,0 +1,20 @@ +export default { + 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/, + onMatch: (args, logParser) => { + const data = { + raw: args[0], + time: args[1], + chainID: args[2], + steamID: args[3], + connection: args[4], + driver: args[5] + }; + /* This is Called when a pending client fails + Only used to cleanup clients in eventstore + */ + + delete logParser.eventStore.clients[args[4]]; + logParser.emit('PENDING_CONNECTION_DESTROYED', data); + } +}; diff --git a/squad-server/log-parser/player-connected.js b/squad-server/log-parser/player-connected.js index b3e5b06..70af6ba 100644 --- a/squad-server/log-parser/player-connected.js +++ b/squad-server/log-parser/player-connected.js @@ -6,9 +6,22 @@ export default { time: args[1], chainID: args[2], playerSuffix: args[3], - steamID: logParser.eventStore['steamid-connected'] + steamID: logParser.eventStore['steamid-connected'], // player connected + controller: logParser.eventStore['player-controller'] // playercontroller connected }; + delete logParser.eventStore['steamid-connected']; + delete logParser.eventStore['player-controller']; + + // Handle Reconnecting players + if (logParser.eventStore.disconnected[data.steamID]) { + delete logParser.eventStore.disconnected[data.steamID]; + } logParser.emit('PLAYER_CONNECTED', data); + logParser.eventStore.players[data.steamID] = { + steamID: data.steamID, + suffix: data.playerSuffix, + controller: data.controller + }; } }; diff --git a/squad-server/log-parser/player-disconnected.js b/squad-server/log-parser/player-disconnected.js index d3c87ee..6df5e64 100644 --- a/squad-server/log-parser/player-disconnected.js +++ b/squad-server/log-parser/player-disconnected.js @@ -1,14 +1,16 @@ export default { regex: - /^\[([0-9.:-]+)]\[([ 0-9]*)]LogEasyAntiCheatServer: \[[0-9:]+] \[[A-z]+] \[EAC Server] \[Info] \[UnregisterClient] Client: ([A-z0-9]+) PlayerGUID: ([0-9]{17})/, + /^\[([0-9.:-]+)]\[([ 0-9]*)]LogNet: UNetConnection::Close: \[UNetConnection\] RemoteAddr: ([0-9]{17}):[0-9]+, Name: SteamNetConnection_[0-9]+, Driver: GameNetDriver SteamNetDriver_[0-9]+, IsServer: YES, PC: (BP_PlayerController_C_[0-9]+), Owner: BP_PlayerController_C_[0-9]+, UniqueId: Steam:UNKNOWN \[.*\], Channels: [0-9]+, Time: [0-9.:-]+/, onMatch: (args, logParser) => { const data = { raw: args[0], time: args[1], chainID: args[2], - steamID: args[4] + steamID: args[3], + playerController: args[4] }; + logParser.eventStore.disconnected[data.steamID] = true; logParser.emit('PLAYER_DISCONNECTED', data); } }; diff --git a/squad-server/log-parser/playercontroller-connected.js b/squad-server/log-parser/playercontroller-connected.js new file mode 100644 index 0000000..18a0216 --- /dev/null +++ b/squad-server/log-parser/playercontroller-connected.js @@ -0,0 +1,16 @@ +export default { + regex: + /^\[([0-9.:-]+)]\[([ 0-9]*)]LogSquad: PostLogin: NewPlayer: BP_PlayerController_C .+(BP_PlayerController_C_[0-9]+)/, + onMatch: (args, logParser) => { + const data = { + raw: args[0], + time: args[1], + chainID: args[2], + controller: args[3] + }; + + logParser.eventStore['player-controller'] = args[3]; + + logParser.emit('PLAYER_CONTROLLER_CONNECTED', data); + } +}; diff --git a/squad-server/log-parser/steamid-connected.js b/squad-server/log-parser/steamid-connected.js deleted file mode 100644 index 4066ca2..0000000 --- a/squad-server/log-parser/steamid-connected.js +++ /dev/null @@ -1,7 +0,0 @@ -export default { - regex: - /^\[([0-9.:-]+)]\[([ 0-9]*)]LogEasyAntiCheatServer: \[[0-9:]+] \[[A-z]+] \[EAC Server] \[Info] \[RegisterClient] Client: ([A-z0-9]+) PlayerGUID: ([0-9]{17}) PlayerIP: [0-9]{17} OwnerGUID: [0-9]{17} PlayerName: (.+)/, - onMatch: async (args, logParser) => { - logParser.eventStore['steamid-connected'] = args[4]; - } -}; From 1301c227f27afc567bcb10061ef68441217eb4d0 Mon Sep 17 00:00:00 2001 From: ect0s <73128770+ect0s@users.noreply.github.com> Date: Wed, 9 Nov 2022 20:26:04 -0500 Subject: [PATCH 3/4] Move events to eventstore.sessions for cleanup --- squad-server/log-parser/deployable-damaged.js | 2 +- squad-server/log-parser/player-damaged.js | 2 +- squad-server/log-parser/player-died.js | 4 ++-- squad-server/log-parser/player-possess.js | 2 +- squad-server/log-parser/player-revived.js | 2 +- squad-server/log-parser/player-un-possess.js | 5 +++-- squad-server/log-parser/player-wounded.js | 4 ++-- 7 files changed, 11 insertions(+), 10 deletions(-) diff --git a/squad-server/log-parser/deployable-damaged.js b/squad-server/log-parser/deployable-damaged.js index 9cd1958..91e653d 100644 --- a/squad-server/log-parser/deployable-damaged.js +++ b/squad-server/log-parser/deployable-damaged.js @@ -14,7 +14,7 @@ export default { healthRemaining: args[8] }; - logParser.eventStore[args[3]] = data; + logParser.eventStore.session[args[3]] = data; logParser.emit('DEPLOYABLE_DAMAGED', data); } diff --git a/squad-server/log-parser/player-damaged.js b/squad-server/log-parser/player-damaged.js index e19fcb8..a37c56c 100644 --- a/squad-server/log-parser/player-damaged.js +++ b/squad-server/log-parser/player-damaged.js @@ -12,7 +12,7 @@ export default { weapon: args[6] }; - logParser.eventStore[args[3]] = data; + logParser.eventStore.session[args[3]] = data; logParser.emit('PLAYER_DAMAGED', data); } diff --git a/squad-server/log-parser/player-died.js b/squad-server/log-parser/player-died.js index fb175e8..a253d2f 100644 --- a/squad-server/log-parser/player-died.js +++ b/squad-server/log-parser/player-died.js @@ -3,7 +3,7 @@ export default { /^\[([0-9.:-]+)]\[([ 0-9]*)]LogSquadTrace: \[DedicatedServer](?:ASQSoldier::)?Die\(\): Player:(.+) KillingDamage=(?:-)*([0-9.]+) from ([A-z_0-9]+) caused by ([A-z_0-9]+)_C/, onMatch: (args, logParser) => { const data = { - ...logParser.eventStore[args[3]], + ...logParser.eventStore.session[args[3]], raw: args[0], time: args[1], woundTime: args[1], @@ -14,7 +14,7 @@ export default { weapon: args[6] }; - logParser.eventStore[args[3]] = data; + logParser.eventStore.session[args[3]] = data; logParser.emit('PLAYER_DIED', data); } diff --git a/squad-server/log-parser/player-possess.js b/squad-server/log-parser/player-possess.js index ce96ea8..68dda70 100644 --- a/squad-server/log-parser/player-possess.js +++ b/squad-server/log-parser/player-possess.js @@ -10,7 +10,7 @@ export default { possessClassname: args[4] }; - logParser.eventStore[args[3]] = args[2]; + logParser.eventStore.session[args[3]] = args[2]; logParser.emit('PLAYER_POSSESS', data); } diff --git a/squad-server/log-parser/player-revived.js b/squad-server/log-parser/player-revived.js index 8661b8a..bb412ee 100644 --- a/squad-server/log-parser/player-revived.js +++ b/squad-server/log-parser/player-revived.js @@ -3,7 +3,7 @@ export default { regex: /^\[([0-9.:-]+)]\[([ 0-9]*)]LogSquad: (.+) has revived (.+)\./, onMatch: (args, logParser) => { const data = { - ...logParser.eventStore[args[3]], + ...logParser.eventStore.session[args[3]], raw: args[0], time: args[1], chainID: args[2], diff --git a/squad-server/log-parser/player-un-possess.js b/squad-server/log-parser/player-un-possess.js index 2e697dd..d2b9bc4 100644 --- a/squad-server/log-parser/player-un-possess.js +++ b/squad-server/log-parser/player-un-possess.js @@ -7,10 +7,11 @@ export default { time: args[1], chainID: args[2], playerSuffix: args[3], - switchPossess: args[3] in logParser.eventStore && logParser.eventStore[args[3]] === args[2] + switchPossess: + args[3] in logParser.eventStore.session && logParser.eventStore.session[args[3]] === args[2] }; - delete logParser.eventStore[args[3]]; + delete logParser.eventStore.session[args[3]]; logParser.emit('PLAYER_UNPOSSESS', data); } diff --git a/squad-server/log-parser/player-wounded.js b/squad-server/log-parser/player-wounded.js index ae05d30..d275e73 100644 --- a/squad-server/log-parser/player-wounded.js +++ b/squad-server/log-parser/player-wounded.js @@ -3,7 +3,7 @@ export default { /^\[([0-9.:-]+)]\[([ 0-9]*)]LogSquadTrace: \[DedicatedServer](?:ASQSoldier::)?Wound\(\): Player:(.+) KillingDamage=(?:-)*([0-9.]+) from ([A-z_0-9]+) caused by ([A-z_0-9]+)_C/, onMatch: (args, logParser) => { const data = { - ...logParser.eventStore[args[3]], + ...logParser.eventStore.session[args[3]], raw: args[0], time: args[1], chainID: args[2], @@ -13,7 +13,7 @@ export default { weapon: args[6] }; - logParser.eventStore[args[3]] = data; + logParser.eventStore.session[args[3]] = data; logParser.emit('PLAYER_WOUNDED', data); } From 616982927b3dbf17f07bef8509c66c3e123b2190 Mon Sep 17 00:00:00 2001 From: ect0s <73128770+ect0s@users.noreply.github.com> Date: Mon, 2 Jan 2023 23:27:12 -0500 Subject: [PATCH 4/4] rename steamid-connected to client-login, roll forward to master Resolve conflict with master Change steamid-connected to client-login for consistent naming --- squad-server/log-parser/client-login.js | 2 +- squad-server/log-parser/player-connected.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/squad-server/log-parser/client-login.js b/squad-server/log-parser/client-login.js index 97d59f0..20b84d7 100644 --- a/squad-server/log-parser/client-login.js +++ b/squad-server/log-parser/client-login.js @@ -13,7 +13,7 @@ export default { 2nd Step in player connected path */ - logParser.eventStore['steamid-connected'] = logParser.eventStore.clients[args[3]]; + logParser.eventStore['client-login'] = logParser.eventStore.clients[args[3]]; delete logParser.eventStore.clients[args[3]]; logParser.emit('CLIENT_LOGIN', data); } diff --git a/squad-server/log-parser/player-connected.js b/squad-server/log-parser/player-connected.js index 70af6ba..279257d 100644 --- a/squad-server/log-parser/player-connected.js +++ b/squad-server/log-parser/player-connected.js @@ -6,11 +6,11 @@ export default { time: args[1], chainID: args[2], playerSuffix: args[3], - steamID: logParser.eventStore['steamid-connected'], // player connected + steamID: logParser.eventStore['client-login'], // player connected controller: logParser.eventStore['player-controller'] // playercontroller connected }; - delete logParser.eventStore['steamid-connected']; + delete logParser.eventStore['client-login']; delete logParser.eventStore['player-controller']; // Handle Reconnecting players