Merge remote-tracking branch 'upstream/master' into LogParser-Sessions

This commit is contained in:
ect0s 2023-01-02 23:24:13 -05:00
commit 4233213acd
13 changed files with 197 additions and 34 deletions

View File

@ -639,6 +639,29 @@ Grafana:
<pre><code>16761867</code></pre></li></ul> <pre><code>16761867</code></pre></li></ul>
</details> </details>
<details>
<summary>DiscordRoundEnded</summary>
<h2>DiscordRoundEnded</h2>
<p>The <code>DiscordRoundEnded</code> plugin will send the round winner to a Discord channel.</p>
<h3>Options</h3>
<ul><li><h4>discordClient (Required)</h4>
<h6>Description</h6>
<p>Discord connector name.</p>
<h6>Default</h6>
<pre><code>discord</code></pre></li>
<li><h4>channelID (Required)</h4>
<h6>Description</h6>
<p>The ID of the channel to log round end events to.</p>
<h6>Default</h6>
<pre><code></code></pre></li><h6>Example</h6>
<pre><code>667741905228136459</code></pre>
<li><h4>color</h4>
<h6>Description</h6>
<p>The color of the embed.</p>
<h6>Default</h6>
<pre><code>16761867</code></pre></li></ul>
</details>
<details> <details>
<summary>DiscordServerStatus</summary> <summary>DiscordServerStatus</summary>
<h2>DiscordServerStatus</h2> <h2>DiscordServerStatus</h2>

View File

@ -166,6 +166,13 @@
"channelID": "", "channelID": "",
"color": 16761867 "color": 16761867
}, },
{
"plugin": "DiscordRoundEnded",
"enabled": true,
"discordClient": "discord",
"channelID": "",
"color": 16761867
},
{ {
"plugin": "DiscordServerStatus", "plugin": "DiscordServerStatus",
"enabled": true, "enabled": true,

View File

@ -1,6 +1,6 @@
{ {
"name": "SquadJS", "name": "SquadJS",
"version": "3.6.0", "version": "3.6.1",
"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",

View File

@ -152,6 +152,14 @@ export default class SquadServer extends EventEmitter {
this.emit('PLAYER_BANNED', data); this.emit('PLAYER_BANNED', data);
}); });
this.rcon.on('SQUAD_CREATED', async (data) => {
data.player = await this.getPlayerBySteamID(data.playerSteamID, true);
delete data.playerName;
delete data.playerSteamID;
this.emit('SQUAD_CREATED', data);
});
} }
async restartRCON() { async restartRCON() {
@ -290,17 +298,12 @@ export default class SquadServer extends EventEmitter {
this.emit('PLAYER_UNPOSSESS', data); this.emit('PLAYER_UNPOSSESS', data);
}); });
this.logParser.on('TICK_RATE', (data) => { this.logParser.on('ROUND_ENDED', async (data) => {
this.emit('TICK_RATE', data); this.emit('ROUND_ENDED', data);
}); });
this.logParser.on('SQUAD_CREATED', async (data) => { this.logParser.on('TICK_RATE', (data) => {
data.player = await this.getPlayerBySteamID(data.playerSteamID, true); this.emit('TICK_RATE', data);
delete data.playerName;
delete data.playerSteamID;
delete data.squadID;
this.emit('SQUAD_CREATED', data);
}); });
} }

View File

@ -12,12 +12,13 @@ import PlayerPossess from './player-possess.js';
import PlayerRevived from './player-revived.js'; import PlayerRevived from './player-revived.js';
import PlayerUnPossess from './player-un-possess.js'; import PlayerUnPossess from './player-un-possess.js';
import PlayerWounded from './player-wounded.js'; import PlayerWounded from './player-wounded.js';
import RoundEnded from './round-ended.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 ClientConnected from './client-connected.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 SquadCreated from './squad-created.js';
export default class SquadLogParser extends LogParser { export default class SquadLogParser extends LogParser {
constructor(options) { constructor(options) {
@ -38,12 +39,13 @@ export default class SquadLogParser extends LogParser {
PlayerRevived, PlayerRevived,
PlayerUnPossess, PlayerUnPossess,
PlayerWounded, PlayerWounded,
RoundEnded,
RoundTickets,
RoundWinner, RoundWinner,
ServerTickRate, ServerTickRate,
ClientConnected, ClientConnected,
ClientLogin, ClientLogin,
PendingConnectionDestroyed, PendingConnectionDestroyed
SquadCreated
]; ];
} }
} }

View File

@ -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 (.+) caused by ([A-z_0-9-]+)_C/,
onMatch: (args, logParser) => { onMatch: (args, logParser) => {
const data = { const data = {
raw: args[0], raw: args[0],

View File

@ -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]+) 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]],

View File

@ -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]+) 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]],

View File

@ -0,0 +1,21 @@
/**
* Matches when Map state Changes to PostMatch (ScoreBoard)
*
* Emits winner and loser from eventstore
*
* winner and loser may be null if the match ends with a draw
*/
export default {
regex:
/^\[([0-9.:-]+)]\[([ 0-9]*)]LogGameState: Match State Changed from InProgress to WaitingPostMatch/,
onMatch: (args, logParser) => {
const data = {
winner: logParser.eventStore.ROUND_WINNER ? logParser.eventStore.ROUND_WINNER : null,
loser: logParser.eventStore.ROUND_LOSER ? logParser.eventStore.ROUND_LOSER : null,
time: args[1]
};
logParser.emit('ROUND_ENDED', data);
delete logParser.eventStore.ROUND_WINNER;
delete logParser.eventStore.ROUND_LOSER;
}
};

View File

@ -0,0 +1,28 @@
/**
* Matches when tickets appear in the log
*
* Will not match on Draw or Map Changes before the game has started
*/
export default {
regex:
/^\[([0-9.:-]+)]\[([ 0-9]*)]LogSquadGameEvents: Display: Team ([0-9]), (.*) \( ?(.*?) ?\) has (won|lost) the match with ([0-9]+) Tickets on layer (.*) \(level (.*)\)!/,
onMatch: (args, logParser) => {
const data = {
raw: args[0],
time: args[1],
chainID: args[2],
team: args[3],
subfaction: args[4],
faction: args[5],
action: args[6],
tickets: args[7],
layer: args[8],
level: args[9]
};
if (data.action === 'won') {
logParser.eventStore.ROUND_WINNER = data;
} else {
logParser.eventStore.ROUND_LOSER = data;
}
}
};

View File

@ -1,18 +0,0 @@
export default {
regex:
/^\[([0-9.:-]+)]\[([ 0-9]*)]LogSquad: (.+) \(Steam ID: ([0-9]{17})\) has created Squad (\d+) \(Squad Name: (.+)\) on (.+)/,
onMatch: async (args, logParser) => {
const data = {
raw: args[0],
time: args[1],
chainID: args[2],
playerName: args[3],
playerSteamID: args[4],
squadID: args[5],
squadName: args[6],
teamName: args[7]
};
logParser.emit('SQUAD_CREATED', data);
}
};

View File

@ -0,0 +1,79 @@
import DiscordBasePlugin from './discord-base-plugin.js';
export default class DiscordRoundEnded extends DiscordBasePlugin {
static get description() {
return 'The <code>DiscordRoundEnded</code> plugin will send the round winner to a Discord channel.';
}
static get defaultEnabled() {
return true;
}
static get optionsSpecification() {
return {
...DiscordBasePlugin.optionsSpecification,
channelID: {
required: true,
description: 'The ID of the channel to log round end events to.',
default: '',
example: '667741905228136459'
},
color: {
required: false,
description: 'The color of the embed.',
default: 16761867
}
};
}
constructor(server, options, connectors) {
super(server, options, connectors);
this.onRoundEnd = this.onRoundEnd.bind(this);
}
async mount() {
this.server.on('ROUND_ENDED', this.onRoundEnd);
}
async unmount() {
this.server.removeEventListener('ROUND_ENDED', this.onRoundEnd);
}
async onRoundEnd(info) {
if (!info.winner || !info.loser) {
await this.sendDiscordMessage({
embed: {
title: 'Round Ended',
description: 'This match Ended in a Draw',
color: this.options.color,
timestamp: info.time.toISOString()
}
});
return;
}
await this.sendDiscordMessage({
embed: {
title: 'Round Ended',
description: `${info.winner.layer} - ${info.winner.level}`,
color: this.options.color,
fields: [
{
name: `Team ${info.winner.team} Won`,
value: `${info.winner.subfaction}\n ${info.winner.faction}\n won with ${info.winner.tickets} tickets.`
},
{
name: `Team ${info.loser.team} Lost`,
value: `${info.loser.subfaction}\n ${info.loser.faction}\n lost with ${info.loser.tickets} tickets.`
},
{
name: 'Ticket Difference',
value: `${info.winner.tickets - info.loser.tickets}.`
}
],
timestamp: info.time.toISOString()
}
});
}
}

View File

@ -84,6 +84,24 @@ export default class SquadRcon extends Rcon {
return; return;
} }
const matchSqCreated = decodedPacket.body.match(
/(.+) \(Steam ID: ([0-9]{17})\) has created Squad (\d+) \(Squad Name: (.+)\) on (.+)/
);
if (matchSqCreated) {
Logger.verbose('SquadRcon', 2, `Matched Squad Created: ${decodedPacket.body}`);
this.emit('SQUAD_CREATED', {
time: new Date(),
playerName: matchSqCreated[1],
playerSteamID: matchSqCreated[2],
squadID: matchSqCreated[3],
squadName: matchSqCreated[4],
teamName: matchSqCreated[5]
});
return;
}
const matchBan = decodedPacket.body.match( const matchBan = decodedPacket.body.match(
/Banned player ([0-9]+)\. \[steamid=(.*?)\] (.*) for interval (.*)/ /Banned player ([0-9]+)\. \[steamid=(.*?)\] (.*) for interval (.*)/
); );