Skip to content
Permalink

Comparing changes

This is a direct comparison between two commits made in this repository or its related repositories. View the default comparison for this range or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: CatalysmsServerManager/7-days-to-die-server-manager
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 1eba8251ced5a38d6f8c70f530a28a026ac1d32a
Choose a base ref
..
head repository: CatalysmsServerManager/7-days-to-die-server-manager
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: c46eb649af5a9f56b2557b4767ca7d361f853321
Choose a head ref
2 changes: 1 addition & 1 deletion api/controllers/Player/ban.js
Original file line number Diff line number Diff line change
@@ -46,7 +46,7 @@ module.exports = {

const response = await sails.helpers.sdtdApi.executeConsoleCommand(
SdtdServer.getAPIConfig(server),
`ban add Steam_${player.steamId} ${inputs.duration} ${inputs.durationUnit.toLowerCase()} "${inputs.reason}"`
`ban add ${player.crossId} ${inputs.duration} ${inputs.durationUnit.toLowerCase()} "${inputs.reason}"`
);

return exits.success(response);
1 change: 1 addition & 0 deletions api/controllers/SdtdServer/get-players-datatable.js
Original file line number Diff line number Diff line change
@@ -9,6 +9,7 @@ async function getPlayersDataTable(req, res) {
whereObj.or = [
{ name: { contains: req.body.searchText } },
{ steamId: { contains: req.body.searchText } },
{ crossId: { contains: req.body.searchText } },
{ ip: { contains: req.body.searchText } }
];
if (!isNaN(req.body.searchText)) {
5 changes: 3 additions & 2 deletions api/helpers/sdtd/load-all-player-data.js
Original file line number Diff line number Diff line change
@@ -61,11 +61,12 @@ module.exports = {

}

await Player.createEach(newPlayers);
const uniqueBySteamId = _.uniqBy(newPlayers, 'steamId');
await Player.createEach(uniqueBySteamId);

let dateEnded = new Date();

sails.log.debug(`load-all-player-data - Created ${newPlayers.length} new records out of ${apiResult.players.length} total players for server ${server.name} - Took ${dateEnded.valueOf() - dateStarted.valueOf()} ms`, {serverId: inputs.serverId});
sails.log.debug(`load-all-player-data - Created ${newPlayers.length} new records out of ${apiResult.players.length} total players for server ${server.name} - Took ${dateEnded.valueOf() - dateStarted.valueOf()} ms`, { serverId: inputs.serverId });

return exits.success(apiResult.players);

5 changes: 3 additions & 2 deletions api/hooks/sdtdLogs/LoggingObject.js
Original file line number Diff line number Diff line change
@@ -23,14 +23,15 @@ class LoggingObject extends EventEmitter {
async handleMessage(newLog) {
let enrichedLog = newLog;
enrichedLog.server = this.server;
enrichedLog.data.server = this.server;

if (newLog.type !== 'logLine') {
enrichedLog = await enrichEventData(enrichedLog);
enrichedLog.data = await enrichEventData(enrichedLog.data);
sails.helpers.getQueueObject('hooks').add({ type: 'logLine', data: enrichedLog.data, server: this.server });
}

sails.log.debug(
`Log line for server ${this.server.id} - ${newLog.type} - ${newLog.data.msg}`, {serverId: this.server.id}
`Log line for server ${this.server.id} - ${newLog.type} - ${newLog.data.msg}`, { serverId: this.server.id }
);

sails.helpers.getQueueObject('hooks').add(enrichedLog);
4 changes: 2 additions & 2 deletions api/hooks/sdtdLogs/enrichers/index.js
Original file line number Diff line number Diff line change
@@ -15,8 +15,8 @@ module.exports = async (event) => {

return enriched;
} catch (error) {
sails.log.warn('Error trying to enrich a log line, this should be OK to fail...', {server: event.server, player: event.players});
sails.log.error(error.message,{server: event.server, player: event.players});
sails.log.warn('Error trying to enrich a log line, this should be OK to fail...', { server: event.server, player: event.players });
sails.log.error(error, { server: event.server, player: event.players });
return event;
}
};
52 changes: 41 additions & 11 deletions api/hooks/sdtdLogs/enrichers/player.js
Original file line number Diff line number Diff line change
@@ -1,42 +1,72 @@
const steamIdRegex = /\d{17}/g;
const crossIdRegex = /EOS_[\d\w]{32}/;

module.exports = async (event) => {
let player;

if (!_.isEmpty(event.data.playerID)) {
event.data.steamId = event.data.playerID;
if (!_.isEmpty(event.playerID)) {
event.steamId = event.playerID;
}

let player;

if (!_.isEmpty(event.data.steamId)) {
if (!_.isEmpty(event.steamId)) {
player = await sails.helpers.sdtd.loadPlayerData.with({
serverId: event.server.id,
steamId: event.data.steamId
steamId: event.steamId
});
player = player[0];
}

if (!_.isEmpty(event.data.steamID)) {
if (!_.isEmpty(event.crossId)) {
// TODO: Replace this with a loadPlayerData call when Allocs API is updated to send it...
player = await Player.findOne({
server: event.server.id,
crossId: event.crossId
});
}

if (!_.isEmpty(event.steamID)) {
player = await sails.helpers.sdtd.loadPlayerData.with({
serverId: event.server.id,
steamId: event.data.steamID
steamId: event.steamID
});
player = player[0];
}

// If we do not find the player via steamId, we try via name.
if (_.isUndefined(player)) {
if (!_.isEmpty(event.data.playerName)) {
if (!_.isEmpty(event.playerName)) {

player = await Player.findOne({
name: event.data.playerName,
name: event.playerName,
server: event.server.id
});
}
}

// If at this point we still haven't found the player,
// We check if there is a 'msg' from the log line and try to extract an ID
if (_.isUndefined(player)) {
if (event.msg) {
const detectedSteamIdMatch = event.msg.match(steamIdRegex);
const detectedCrossIdMatch = event.msg.match(crossIdRegex);

if (detectedSteamIdMatch) {
const steamId = detectedSteamIdMatch[0];
player = await Player.findOne({ steamId });
}

if (detectedCrossIdMatch) {
const crossId = detectedCrossIdMatch[0];
player = await Player.findOne({ crossId });
}
}
}


if (player) {
player.role = await sails.helpers.sdtd.getPlayerRole(player.id);
}

event.data.player = player;
event.player = player;
return event;
};
12 changes: 6 additions & 6 deletions api/hooks/sdtdLogs/enrichers/playerDied.js
Original file line number Diff line number Diff line change
@@ -5,14 +5,14 @@ module.exports = async (event) => {
event.type !== 'playerSuicide'
) { return event; }

if (!event.data.player) { throw new Error('Cannot store last death location when no player defined'); }
if (!event.player) { throw new Error('Cannot store last death location when no player defined'); }

const onlinePlayers = await sails.helpers.sdtdApi.getOnlinePlayers(SdtdServer.getAPIConfig(event.server));
const onlinePlayers = await sails.helpers.sdtdApi.getOnlinePlayers(SdtdServer.getAPIConfig(event.server));

const player = onlinePlayers.find(p => p.steamid === event.data.player.steamId);
const player = onlinePlayers.find(p => p.steamid === event.player.steamId);

const updatedPlayers = await Player.update(
{ id: event.data.player.id },
{ id: event.player.id },
{
lastDeathLocationX: player.position.x,
lastDeathLocationY: player.position.y,
@@ -23,8 +23,8 @@ module.exports = async (event) => {
throw new Error('Player not found? Shouldnt happen, watcha doin mate..');
}

event.data.player = updatedPlayers[0];
sails.log.debug(`Updated player ${event.data.player.id} last death location to ${event.data.player.positionX},${event.data.player.positionY},${event.data.player.positionZ}`, {playerId: event.data.player.id, server:event.data.server});
event.player = updatedPlayers[0];
sails.log.debug(`Updated player ${event.player.id} last death location to ${event.player.positionX},${event.player.positionY},${event.player.positionZ}`, { playerId: event.player.id, server: event.server });


return event;
14 changes: 7 additions & 7 deletions api/hooks/sdtdLogs/enrichers/playerKilled.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
module.exports = async (event) => {
if (event.type !== 'playerKilled') {return event;}
if (event.type !== 'playerKilled') { return event; }

event.data.victim = await Player.findOne({
event.victim = await Player.findOne({
server: event.server.id,
name: event.data.victimName
name: event.victimName
});
event.data.killer = await Player.findOne({
event.killer = await Player.findOne({
server: event.server.id,
name: event.data.killerName
name: event.killerName
});
event.data.victim.role = await sails.helpers.sdtd.getPlayerRole(event.data.victim.id);
event.data.killer.role = await sails.helpers.sdtd.getPlayerRole(event.data.killer.id);
event.victim.role = await sails.helpers.sdtd.getPlayerRole(event.victim.id);
event.killer.role = await sails.helpers.sdtd.getPlayerRole(event.killer.id);

return event;
};
51 changes: 35 additions & 16 deletions api/hooks/sdtdLogs/eventDetectors/7d2dSSE.js
Original file line number Diff line number Diff line change
@@ -8,14 +8,17 @@ class SdtdSSE extends LoggingObject {
constructor(server) {
super(server);

const RATE_LIMIT_MINUTES = parseInt(process.env.SSE_RATE_LIMIT_MINUTES, 10) || 5;
const RATE_LIMIT_AMOUNT = parseInt(process.env.SSE_RATE_LIMIT_AMOUNT, 10) || 2500;
const THROTTLE_DELAY = parseInt(process.env.SSE_THROTTLE_DELAY, 10) || 1000 * 60 * 1;
const SSE_THROTTLE_RECONNECT_DELAY = parseInt(process.env.SSE_THROTTLE_RECONNECT_DELAY, 10) || 1000 * 60 * 5;
const SSE_RECONNECT_INTERVAL = parseInt(process.env.SSE_RECONNECT_INTERVAL, 10) || 1000 * 60 * 5;
this.RATE_LIMIT_MINUTES = parseInt(process.env.SSE_RATE_LIMIT_MINUTES, 10) || 5;
this.RATE_LIMIT_AMOUNT = parseInt(process.env.SSE_RATE_LIMIT_AMOUNT, 10) || 2500;
this.THROTTLE_DELAY = parseInt(process.env.SSE_THROTTLE_DELAY, 10) || 1000 * 60 * 1;
this.SSE_THROTTLE_RECONNECT_DELAY = parseInt(process.env.SSE_THROTTLE_RECONNECT_DELAY, 10) || 1000 * 60 * 5;
this.SSE_RECONNECT_INTERVAL = parseInt(process.env.SSE_RECONNECT_INTERVAL, 10) || 1000 * 60 * 3;
// If we last received a message longer ago than this, we'll force a reconnect
this.LAST_MESSAGE_THRESHOLD = parseInt(process.env.SSE_RECONNECT_INTERVAL, 10) || 1000 * 60 * 5;


this.SSERegex = /\d+-\d+-\d+T\d+:\d+:\d+ \d+\.\d+ INF (.+)/;
this.throttledFunction = new ThrottledFunction(this.SSEListener.bind(this), RATE_LIMIT_AMOUNT, RATE_LIMIT_MINUTES);
this.throttledFunction = new ThrottledFunction(this.SSEListener.bind(this), this.RATE_LIMIT_AMOUNT, this.RATE_LIMIT_MINUTES);
this.listener = this.throttledFunction.listener;
this.queuedChatMessages = [];
this.lastMessage = Date.now();
@@ -32,11 +35,11 @@ class SdtdSSE extends LoggingObject {

this.throttledFunction.on('throttled', () => {
sails.log.debug(`SSE throttled for server ${this.server.id}`, { server: this.server });
this.throttleDestructionTimeout = setTimeout(this.destroy.bind(this), THROTTLE_DELAY);
this.throttleReconnectTimeout = setTimeout(this.start.bind(this), SSE_THROTTLE_RECONNECT_DELAY);
this.throttleDestructionTimeout = setTimeout(this.destroy.bind(this), this.THROTTLE_DELAY);
this.throttleReconnectTimeout = setTimeout(this.start.bind(this), this.SSE_THROTTLE_RECONNECT_DELAY);
});

this.reconnectInterval = setInterval(() => this.reconnectListener(), SSE_RECONNECT_INTERVAL);
this.reconnectInterval = setInterval(() => this.reconnectListener(), this.SSE_RECONNECT_INTERVAL);
}

reconnectListener() {
@@ -45,20 +48,36 @@ class SdtdSSE extends LoggingObject {
return;
}

if (this.eventSource.readyState === EventSource.OPEN && (this.lastMessage > (Date.now() - 300000))) {
return;
if (this.lastMessage < (Date.now() - this.LAST_MESSAGE_THRESHOLD)) {
this.keepAliveHandler();
}

sails.log.debug(`Trying to reconnect SSE for server ${this.server.id}`, { serverId: this.server.id });
this.destroy();
this.start();
}

keepAliveHandler() {
if (!this.keepAliveSent) {
sails.log.debug(`Sending keepalive to SSE for server ${this.server.id}`, { server: this.server });
sails.helpers.sdtdApi.executeConsoleCommand(SdtdServer.getAPIConfig(this.server), `version`)
// Only catch to prevent unhandledRejections
// No need to await, this is fire and forget
.catch(e => {
// Do nothing
// If this fails, the next time this is called, it will try to reconnect
});
this.keepAliveSent = true;
} else {
this.keepAliveSent = false;
sails.log.debug(`Trying to reconnect SSE for server ${this.server.id}`, { serverId: this.server.id });
this.destroy();
this.start();
}
}

get url() {
return `http://${this.server.ip}:${this.server.webPort}/sse/log?adminuser=${this.server.authName}&admintoken=${this.server.authToken}`;
}

async start() {
start() {
if (this.eventSource) {
return;
}
@@ -77,7 +96,7 @@ class SdtdSSE extends LoggingObject {
};
}

async destroy() {
destroy() {
if (!this.eventSource) {
return;
}
18 changes: 14 additions & 4 deletions api/hooks/sdtdLogs/index.js
Original file line number Diff line number Diff line change
@@ -186,14 +186,24 @@ module.exports = function sdtdLogs(sails) {
notificationType: 'playerConnected',
player: connectedMsg.player
});
if (connectedMsg.country !== null && connectedMsg.steamId) {

if (connectedMsg.steamId) {
const updateObject = {};

if (connectedMsg.country) {
updateObject.country = connectedMsg.country;
}

if (connectedMsg.crossId) {
updateObject.crossId = connectedMsg.crossId;
}

await Player.update({
server: server.id,
steamId: connectedMsg.steamId
}, {
country: connectedMsg.country
});
}, updateObject);
}

sails.sockets.broadcast(server.id, 'playerConnected', connectedMsg);
connectedMsg.player = _.omit(connectedMsg.player, 'inventory');
sails.log.debug(`Detected a player connected`, {server, player: connectedMsg.player});
5 changes: 5 additions & 0 deletions api/models/Player.js
Original file line number Diff line number Diff line change
@@ -26,6 +26,11 @@ module.exports = {
required: true
},

crossId: {
type: 'string',
allowNull: true
},

/**
* @var {number} entityId
* @memberof Player
2 changes: 0 additions & 2 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -44,8 +44,6 @@ services:

cache:
image: redis
volumes:
- ./redis-data:/data
command: ["redis-server", "--appendonly", "yes"]
restart: unless-stopped

22 changes: 22 additions & 0 deletions migrations/20220121194709-player-cross-id.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
'use strict';

module.exports = {
async up (queryInterface, Sequelize) {
await queryInterface.addColumn(
'player',
'crossId',
{
type: Sequelize.DataTypes.STRING(255),
allowNull: true,
defaultValue: null,
}
);
},

async down (queryInterface, Sequelize) {
await queryInterface.removeColumn(
'player',
'crossId'
);
}
};
Loading