mirror of
https://github.com/AsgardEternal/squad-js-map-vote.git
synced 2025-01-23 20:43:52 -06:00
feat: data persistency
This commit is contained in:
parent
e339b07647
commit
b19310aa20
10
README.MD
10
README.MD
@ -183,6 +183,15 @@ The ID of the channel to log votes to.
|
||||
```json
|
||||
"112233445566778899"
|
||||
```
|
||||
#### persistentDataFile
|
||||
###### Description
|
||||
Path to file in which to store important data that should be restored after a restart.
|
||||
###### Important
|
||||
Make sure the persistent data file is not inside the plugin folder.
|
||||
###### Default
|
||||
```json
|
||||
""
|
||||
```
|
||||
#### timezone
|
||||
###### Description
|
||||
Timezone relative to UTC time. 0 for UTC, 2 for CEST (UTC+2), -1 (UTC-1)
|
||||
@ -235,6 +244,7 @@ Array of timeframes that allows to override options based on local time. See exa
|
||||
"allowedSameMapEntries": 1,
|
||||
"logToDiscord": true,
|
||||
"channelID": "112233445566778899",
|
||||
"persistentDataFile": "",
|
||||
"timezone": 2,
|
||||
"timeFrames": [
|
||||
{
|
||||
|
95
mapvote.js
95
mapvote.js
@ -5,6 +5,8 @@ import DiscordBasePlugin from './discord-base-plugin.js';
|
||||
import { Layers } from "../layers/index.js"
|
||||
import axios from "axios"
|
||||
import Layer from '../layers/layer.js';
|
||||
import fs from 'fs'
|
||||
import process from 'process'
|
||||
|
||||
export default class MapVote extends DiscordBasePlugin {
|
||||
static get description() {
|
||||
@ -134,6 +136,11 @@ export default class MapVote extends DiscordBasePlugin {
|
||||
default: '',
|
||||
example: '112233445566778899'
|
||||
},
|
||||
persistentDataFile: {
|
||||
required: false,
|
||||
description: 'Path to file in which to store important data that should be restored after a restart',
|
||||
default: ""
|
||||
},
|
||||
timezone: {
|
||||
required: false,
|
||||
description: "Timezone relative to UTC time. 0 for UTC, 2 for CEST (UTC+2), -1 (UTC-1) ",
|
||||
@ -159,7 +166,6 @@ export default class MapVote extends DiscordBasePlugin {
|
||||
this.trackedVotes = {}; //player votes, keyed by steam id
|
||||
this.tallies = []; //votes per layer, parellel with nominations
|
||||
this.votingEnabled = false;
|
||||
this.onConnectBound = false;
|
||||
this.broadcastIntervalTask = null;
|
||||
this.firstBroadcast = true;
|
||||
this.newVoteTimeout = null;
|
||||
@ -181,13 +187,21 @@ export default class MapVote extends DiscordBasePlugin {
|
||||
this.setSeedingMode = this.setSeedingMode.bind(this);
|
||||
this.logVoteToDiscord = this.logVoteToDiscord.bind(this);
|
||||
this.timeframeOptionOverrider = this.timeframeOptionOverrider.bind(this);
|
||||
this.savePersistentData = this.savePersistentData.bind(this)
|
||||
this.restorePersistentData = this.restorePersistentData.bind(this)
|
||||
|
||||
this.broadcast = (msg) => { this.server.rcon.broadcast(msg); };
|
||||
this.warn = (steamid, msg) => { this.server.rcon.warn(steamid, msg); };
|
||||
|
||||
process.on('uncaughtException', function (err) {
|
||||
this.savePersistentData();
|
||||
throw err;
|
||||
});
|
||||
}
|
||||
|
||||
async mount() {
|
||||
await this.updateLayerList();
|
||||
this.restorePersistentData();
|
||||
this.server.on('NEW_GAME', this.onNewGame);
|
||||
this.server.on('CHAT_MESSAGE', this.onChatMessage);
|
||||
this.server.on('PLAYER_DISCONNECTED', this.onPlayerDisconnected);
|
||||
@ -200,6 +214,7 @@ export default class MapVote extends DiscordBasePlugin {
|
||||
// await this.checkUpdates();
|
||||
this.timeframeOptionOverrider();
|
||||
setInterval(this.timeframeOptionOverrider, 1 * 60 * 1000)
|
||||
setInterval(this.savePersistentData, 20 * 1000)
|
||||
}
|
||||
|
||||
async unmount() {
|
||||
@ -399,6 +414,15 @@ export default class MapVote extends DiscordBasePlugin {
|
||||
|
||||
await this.warn(steamID, msg + `\nMapVote SquadJS plugin built by JetDave`);
|
||||
return;
|
||||
case "endsqjs":
|
||||
case "closesqjs":
|
||||
case "stopesqjs":
|
||||
case "restartsqjs":
|
||||
if (!isAdmin) return;
|
||||
this.warn(steamID, "Saving persistent data.\nTerminating SquadJS process.\nIf managed by a process manager it will automatically restart.")
|
||||
this.savePersistentData();
|
||||
process.exit(0);
|
||||
return;
|
||||
default:
|
||||
//give them an error
|
||||
await this.warn(steamID, `Unknown vote subcommand: ${subCommand}`);
|
||||
@ -495,10 +519,11 @@ export default class MapVote extends DiscordBasePlugin {
|
||||
|
||||
const sanitizedLayers = Layers.layers.filter((l) => l.layerid && l.map);
|
||||
const maxOptions = this.options.showRerollOption ? 5 : 6;
|
||||
if (!cmdLayers || cmdLayers.length == 0) {
|
||||
const recentlyPlayedMaps = this.objArrToValArr(this.server.layerHistory.slice(0, this.options.numberRecentMapsToExlude), "layer", "map", "name");
|
||||
this.verbose(1, "Recently played maps: " + recentlyPlayedMaps.filter((l) => l && l.map && l.map.name).map((l) => l.map.name).join(', '))
|
||||
|
||||
const recentlyPlayedMaps = this.objArrToValArr(this.server.layerHistory.slice(0, this.options.numberRecentMapsToExlude), "layer", "map", "name");
|
||||
this.verbose(1, "Recently played maps: " + recentlyPlayedMaps.join(', '));//recentlyPlayedMaps.filter((l) => l && l.map && l.map.name).map((l) => l.map.name).join(', '))
|
||||
|
||||
if (!cmdLayers || cmdLayers.length == 0) {
|
||||
const all_layers = sanitizedLayers.filter((l) =>
|
||||
this.options.gamemodeWhitelist.includes(l.gamemode.toUpperCase()) &&
|
||||
![ this.server.currentLayer ? this.server.currentLayer.map.name : null, ...recentlyPlayedMaps ].includes(l.map.name) &&
|
||||
@ -531,7 +556,7 @@ export default class MapVote extends DiscordBasePlugin {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (cmdLayers.length == 1) for (let i = 0; i < maxOptions; i++) cmdLayers.push(cmdLayers[ 0 ])
|
||||
if (cmdLayers.length == 1) while (cmdLayers.length < maxOptions) cmdLayers.push(cmdLayers[ 0 ])
|
||||
|
||||
if (cmdLayers.length <= maxOptions) {
|
||||
let i = 1;
|
||||
@ -764,6 +789,66 @@ export default class MapVote extends DiscordBasePlugin {
|
||||
}
|
||||
}
|
||||
|
||||
restorePersistentData() {
|
||||
this.verbose(1, `Restoring persistent data from: ${this.options.persistentDataFile}`)
|
||||
|
||||
if (this.options.persistentDataFile == "") return;
|
||||
|
||||
if (!fs.existsSync(this.options.persistentDataFile)) return;
|
||||
|
||||
let bkData = fs.readFileSync(this.options.persistentDataFile);
|
||||
if (bkData == "") return;
|
||||
|
||||
try {
|
||||
bkData = JSON.parse(bkData)
|
||||
} catch (e) {
|
||||
this.verbose(1, "Error restoring persistent data", e)
|
||||
return
|
||||
}
|
||||
|
||||
for (let k in bkData.server) this.server[ k ] = bkData.server[ k ];
|
||||
|
||||
const maxSecondsDiffierence = 60
|
||||
if ((new Date() - new Date(bkData.saveDateTime)) / 1000 > maxSecondsDiffierence) return
|
||||
|
||||
this.verbose(1, "Restoring data:", bkData)
|
||||
|
||||
// if (bkData.custom.layerHistory) this.server.layerHistory = Layers.layers.filter(l => bkData.custom.layerHistory.includes(l.layerid));
|
||||
this.verbose(1, "Recently played maps: " + this.server.layerHistory.filter((l) => l && l.map && l.map.name).map((l) => l.layer.map.name).join(', '))
|
||||
|
||||
for (let k in bkData.plugin) this[ k ] = bkData.plugin[ k ];
|
||||
if (this.votingEnabled) {
|
||||
this.broadcastIntervalTask = setInterval(this.broadcastNominations, toMils(this.options.voteBroadcastInterval));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
savePersistentData() {
|
||||
if (this.options.persistentDataFile == "") return;
|
||||
|
||||
|
||||
const saveDt = {
|
||||
custom: {
|
||||
// layerHistory: this.server.layerHistory.slice(0, this.options.numberRecentMapsToExlude * 2).filter(l => l && l.layerid).map(l => l.layerid),
|
||||
},
|
||||
server: {
|
||||
layerHistory: this.server.layerHistory
|
||||
},
|
||||
plugin: {
|
||||
nominations: this.nominations,
|
||||
trackedVotes: this.trackedVotes,
|
||||
tallies: this.tallies,
|
||||
votingEnabled: this.votingEnabled,
|
||||
factionStrings: this.factionStrings,
|
||||
firstBroadcast: this.firstBroadcast
|
||||
},
|
||||
saveDateTime: new Date()
|
||||
}
|
||||
// this.verbose(1, `Saving persistent data to: ${this.options.persistentDataFile}\n`, saveDt.server.layerHistory)
|
||||
|
||||
fs.writeFileSync(this.options.persistentDataFile, JSON.stringify(saveDt, null, 2))
|
||||
}
|
||||
|
||||
//calculates the current winner(s) of the vote and returns thier strings in an array
|
||||
get currentWinners() {
|
||||
const ties = [];
|
||||
|
Loading…
x
Reference in New Issue
Block a user