mirror of
https://github.com/AsgardEternal/SquadJS.git
synced 2024-09-28 14:04:25 -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>
|
<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>
|
||||||
|
@ -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,
|
||||||
|
@ -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",
|
||||||
|
@ -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);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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],
|
||||||
|
@ -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]],
|
||||||
|
@ -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]],
|
||||||
|
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;
|
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 (.*)/
|
||||||
);
|
);
|
||||||
|
Loading…
Reference in New Issue
Block a user