mirror of
https://github.com/AsgardEternal/SquadJS.git
synced 2024-09-28 11:54:23 -05:00
Merge remote-tracking branch 'upstream/master' into LogParser-Sessions
This commit is contained in:
commit
4233213acd
23
README.md
23
README.md
@ -639,6 +639,29 @@ Grafana:
|
||||
<pre><code>16761867</code></pre></li></ul>
|
||||
</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>
|
||||
<summary>DiscordServerStatus</summary>
|
||||
<h2>DiscordServerStatus</h2>
|
||||
|
@ -166,6 +166,13 @@
|
||||
"channelID": "",
|
||||
"color": 16761867
|
||||
},
|
||||
{
|
||||
"plugin": "DiscordRoundEnded",
|
||||
"enabled": true,
|
||||
"discordClient": "discord",
|
||||
"channelID": "",
|
||||
"color": 16761867
|
||||
},
|
||||
{
|
||||
"plugin": "DiscordServerStatus",
|
||||
"enabled": true,
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "SquadJS",
|
||||
"version": "3.6.0",
|
||||
"version": "3.6.1",
|
||||
"repository": "https://github.com/Team-Silver-Sphere/SquadJS.git",
|
||||
"author": "Thomas Smyth <https://github.com/Thomas-Smyth>",
|
||||
"license": "BSL-1.0",
|
||||
|
@ -152,6 +152,14 @@ export default class SquadServer extends EventEmitter {
|
||||
|
||||
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() {
|
||||
@ -290,17 +298,12 @@ export default class SquadServer extends EventEmitter {
|
||||
this.emit('PLAYER_UNPOSSESS', data);
|
||||
});
|
||||
|
||||
this.logParser.on('TICK_RATE', (data) => {
|
||||
this.emit('TICK_RATE', data);
|
||||
this.logParser.on('ROUND_ENDED', async (data) => {
|
||||
this.emit('ROUND_ENDED', data);
|
||||
});
|
||||
|
||||
this.logParser.on('SQUAD_CREATED', async (data) => {
|
||||
data.player = await this.getPlayerBySteamID(data.playerSteamID, true);
|
||||
delete data.playerName;
|
||||
delete data.playerSteamID;
|
||||
delete data.squadID;
|
||||
|
||||
this.emit('SQUAD_CREATED', data);
|
||||
this.logParser.on('TICK_RATE', (data) => {
|
||||
this.emit('TICK_RATE', data);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -12,12 +12,13 @@ import PlayerPossess from './player-possess.js';
|
||||
import PlayerRevived from './player-revived.js';
|
||||
import PlayerUnPossess from './player-un-possess.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 ServerTickRate from './server-tick-rate.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 {
|
||||
constructor(options) {
|
||||
@ -38,12 +39,13 @@ export default class SquadLogParser extends LogParser {
|
||||
PlayerRevived,
|
||||
PlayerUnPossess,
|
||||
PlayerWounded,
|
||||
RoundEnded,
|
||||
RoundTickets,
|
||||
RoundWinner,
|
||||
ServerTickRate,
|
||||
ClientConnected,
|
||||
ClientLogin,
|
||||
PendingConnectionDestroyed,
|
||||
SquadCreated
|
||||
PendingConnectionDestroyed
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
export default {
|
||||
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) => {
|
||||
const data = {
|
||||
raw: args[0],
|
||||
|
@ -1,6 +1,6 @@
|
||||
export default {
|
||||
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) => {
|
||||
const data = {
|
||||
...logParser.eventStore.session[args[3]],
|
||||
|
@ -1,6 +1,6 @@
|
||||
export default {
|
||||
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) => {
|
||||
const data = {
|
||||
...logParser.eventStore.session[args[3]],
|
||||
|
21
squad-server/log-parser/round-ended.js
Normal file
21
squad-server/log-parser/round-ended.js
Normal 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;
|
||||
}
|
||||
};
|
28
squad-server/log-parser/round-tickets.js
Normal file
28
squad-server/log-parser/round-tickets.js
Normal 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;
|
||||
}
|
||||
}
|
||||
};
|
@ -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);
|
||||
}
|
||||
};
|
79
squad-server/plugins/discord-roundended.js
Normal file
79
squad-server/plugins/discord-roundended.js
Normal 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()
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@ -84,6 +84,24 @@ export default class SquadRcon extends Rcon {
|
||||
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(
|
||||
/Banned player ([0-9]+)\. \[steamid=(.*?)\] (.*) for interval (.*)/
|
||||
);
|
||||
|
Loading…
Reference in New Issue
Block a user