mirror of
https://github.com/AsgardEternal/squad-js-map-vote.git
synced 2025-01-23 23:03:51 -06:00
feat: import layer data from owi sheet + rcon ListLayers
This commit is contained in:
parent
ab3c03563e
commit
254f66927f
124
mapvote.js
124
mapvote.js
@ -218,6 +218,7 @@ export default class MapVote extends DiscordBasePlugin {
|
|||||||
this.endVotingGently = this.endVotingGently.bind(this);
|
this.endVotingGently = this.endVotingGently.bind(this);
|
||||||
this.formatChoice = this.formatChoice.bind(this);
|
this.formatChoice = this.formatChoice.bind(this);
|
||||||
this.updateNextMap = this.updateNextMap.bind(this);
|
this.updateNextMap = this.updateNextMap.bind(this);
|
||||||
|
this.mapLayer = this.mapLayer.bind(this);
|
||||||
|
|
||||||
this.broadcast = async (msg) => { await this.server.rcon.broadcast(msg); };
|
this.broadcast = async (msg) => { await this.server.rcon.broadcast(msg); };
|
||||||
this.warn = async (steamid, msg) => { await this.server.rcon.warn(steamid, msg); };
|
this.warn = async (steamid, msg) => { await this.server.rcon.warn(steamid, msg); };
|
||||||
@ -235,7 +236,7 @@ export default class MapVote extends DiscordBasePlugin {
|
|||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.verbose(1, 'Enabled late listeners.');
|
this.verbose(1, 'Enabled late listeners.');
|
||||||
this.server.on('PLAYER_CONNECTED', this.setSeedingMode);
|
this.server.on('PLAYER_CONNECTED', this.setSeedingMode);
|
||||||
}, 10 * 1000) // wait 10 seconds to be sure to have an updated player list
|
}, 15 * 1000) // wait 10 seconds to be sure to have an updated player list
|
||||||
this.verbose(1, 'Map vote was mounted.');
|
this.verbose(1, 'Map vote was mounted.');
|
||||||
this.verbose(1, "Blacklisted Layers/Levels: " + this.options.layerLevelBlacklist.join(', '))
|
this.verbose(1, "Blacklisted Layers/Levels: " + this.options.layerLevelBlacklist.join(', '))
|
||||||
// await this.checkUpdates();
|
// await this.checkUpdates();
|
||||||
@ -253,17 +254,19 @@ export default class MapVote extends DiscordBasePlugin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async onNewGame() {
|
async onNewGame() {
|
||||||
for (let x of this.timeout_ps) clearTimeout(this.timeout_ps.pop())
|
for (let x of this.timeout_ps)
|
||||||
|
clearTimeout(x)
|
||||||
|
this.timeout_ps = [];
|
||||||
|
|
||||||
this.endVotingTimeout = setTimeout(async () => {
|
if (this.options.automaticVoteStart) this.autovotestart = setTimeout(this.beginVoting, toMils(this.options.voteWaitTimeFromMatchStart));
|
||||||
this.endVoting();
|
// this.endVotingTimeout = setTimeout(async () => {
|
||||||
this.trackedVotes = {};
|
// this.endVoting();
|
||||||
this.tallies = [];
|
// this.trackedVotes = {};
|
||||||
this.nominations = [];
|
// this.tallies = [];
|
||||||
this.factionStrings = [];
|
// this.nominations = [];
|
||||||
if (this.options.automaticVoteStart) this.autovotestart = setTimeout(this.beginVoting, toMils(this.options.voteWaitTimeFromMatchStart));
|
// this.factionStrings = [];
|
||||||
setTimeout(() => this.setSeedingMode(true), 10000);
|
// // setTimeout(() => this.setSeedingMode(true), 10000);
|
||||||
}, 10000)
|
// }, 10000)
|
||||||
}
|
}
|
||||||
|
|
||||||
async onPlayerDisconnected() {
|
async onPlayerDisconnected() {
|
||||||
@ -312,8 +315,8 @@ export default class MapVote extends DiscordBasePlugin {
|
|||||||
// this.msgBroadcast("[MapVote] Seeding mode active")
|
// this.msgBroadcast("[MapVote] Seeding mode active")
|
||||||
const baseDataExist = this && this.options && this.server && this.server.players;
|
const baseDataExist = this && this.options && this.server && this.server.players;
|
||||||
if (baseDataExist) {
|
if (baseDataExist) {
|
||||||
this.verbose(1, "Checking seeding mode");
|
|
||||||
if (this.options.automaticSeedingMode) {
|
if (this.options.automaticSeedingMode) {
|
||||||
|
this.verbose(1, "Checking seeding mode");
|
||||||
if (this.server.players.length >= 1 && this.server.players.length < 40) {
|
if (this.server.players.length >= 1 && this.server.players.length < 40) {
|
||||||
const seedingMaps = Layers.layers.filter((l) => l.layerid && l.gamemode.toUpperCase() == "SEED" && !this.options.layerLevelBlacklist.find((fl) => l.layerid.toLowerCase().startsWith(fl.toLowerCase())))
|
const seedingMaps = Layers.layers.filter((l) => l.layerid && l.gamemode.toUpperCase() == "SEED" && !this.options.layerLevelBlacklist.find((fl) => l.layerid.toLowerCase().startsWith(fl.toLowerCase())))
|
||||||
|
|
||||||
@ -328,7 +331,7 @@ export default class MapVote extends DiscordBasePlugin {
|
|||||||
}
|
}
|
||||||
} else this.verbose(1, "Bad data (currentLayer). Seeding mode for current layer skipped to prevent errors.");
|
} else this.verbose(1, "Bad data (currentLayer). Seeding mode for current layer skipped to prevent errors.");
|
||||||
|
|
||||||
if (+(new Date()) - +this.layerHistory[ 0 ].time > 30 * 1000) {
|
if (+(new Date()) - +this.server.layerHistory[ 0 ].time > 30 * 1000) {
|
||||||
if (this.server.nextLayer) {
|
if (this.server.nextLayer) {
|
||||||
const nextMaps = seedingMaps.filter((l) => (!this.server.currentLayer || l.layerid != this.server.currentLayer.layerid))
|
const nextMaps = seedingMaps.filter((l) => (!this.server.currentLayer || l.layerid != this.server.currentLayer.layerid))
|
||||||
let rndMap2;
|
let rndMap2;
|
||||||
@ -360,6 +363,7 @@ export default class MapVote extends DiscordBasePlugin {
|
|||||||
const subCommand = commandSplit[ 0 ];
|
const subCommand = commandSplit[ 0 ];
|
||||||
if (!isNaN(subCommand)) // if this succeeds player is voting for a map
|
if (!isNaN(subCommand)) // if this succeeds player is voting for a map
|
||||||
{
|
{
|
||||||
|
|
||||||
const mapNumber = parseInt(subCommand); //try to get a vote number
|
const mapNumber = parseInt(subCommand); //try to get a vote number
|
||||||
if (this.nominations[ mapNumber ]) {
|
if (this.nominations[ mapNumber ]) {
|
||||||
if (!this.votingEnabled) {
|
if (!this.votingEnabled) {
|
||||||
@ -466,6 +470,7 @@ export default class MapVote extends DiscordBasePlugin {
|
|||||||
|
|
||||||
updateNextMap() //sets next map to current mapvote winner, if there is a tie will pick at random
|
updateNextMap() //sets next map to current mapvote winner, if there is a tie will pick at random
|
||||||
{
|
{
|
||||||
|
if (!this.votingEnabled) return;
|
||||||
this.lastMapUpdate = new Date();
|
this.lastMapUpdate = new Date();
|
||||||
let cpyWinners = this.currentWinners;
|
let cpyWinners = this.currentWinners;
|
||||||
let skipSetNextMap = false;
|
let skipSetNextMap = false;
|
||||||
@ -538,11 +543,13 @@ export default class MapVote extends DiscordBasePlugin {
|
|||||||
'United States Marine Corps': "USMC",
|
'United States Marine Corps': "USMC",
|
||||||
'Russian Ground Forces': "RUS",
|
'Russian Ground Forces': "RUS",
|
||||||
'British Army': "GB",
|
'British Army': "GB",
|
||||||
|
'British Armed Forces': "GB",
|
||||||
'Canadian Army': "CAF",
|
'Canadian Army': "CAF",
|
||||||
'Australian Defence Force': "AUS",
|
'Australian Defence Force': "AUS",
|
||||||
'Irregular Militia Forces': "IRR",
|
'Irregular Militia Forces': "MIL",
|
||||||
'Middle Eastern Alliance': "MEA",
|
'Middle Eastern Alliance': "MEA",
|
||||||
'Insurgent Forces': "INS",
|
'Insurgent Forces': "INS",
|
||||||
|
'Unknown': "Unk"
|
||||||
}
|
}
|
||||||
|
|
||||||
this.nominations = [];
|
this.nominations = [];
|
||||||
@ -596,9 +603,13 @@ export default class MapVote extends DiscordBasePlugin {
|
|||||||
if (cmdLayers.length <= maxOptions) {
|
if (cmdLayers.length <= maxOptions) {
|
||||||
let i = 1;
|
let i = 1;
|
||||||
for (let cl of cmdLayers) {
|
for (let cl of cmdLayers) {
|
||||||
const cls = cl.split('_');
|
|
||||||
|
const cls = cl.toLowerCase().split('_');
|
||||||
const fLayers = sanitizedLayers.filter((l) => (
|
const fLayers = sanitizedLayers.filter((l) => (
|
||||||
(cls[ 0 ] == "*" || l.layerid.toLowerCase().startsWith(cls[ 0 ]))
|
(
|
||||||
|
(cls[ 0 ] == "*" || l.layerid.toLowerCase().startsWith(cls[ 0 ]))
|
||||||
|
|| (cls[ 0 ].toLowerCase().startsWith('f:') && [ getTranslation(l.teams[ 0 ]), getTranslation(l.teams[ 1 ]) ].includes(cls[ 0 ].substring(2).toUpperCase()))
|
||||||
|
)
|
||||||
&& (l.gamemode.toLowerCase().startsWith(cls[ 1 ]) || (!cls[ 1 ] && this.options.gamemodeWhitelist.includes(l.gamemode.toUpperCase())))
|
&& (l.gamemode.toLowerCase().startsWith(cls[ 1 ]) || (!cls[ 1 ] && this.options.gamemodeWhitelist.includes(l.gamemode.toUpperCase())))
|
||||||
&& (!cls[ 2 ] || l.version.toLowerCase().startsWith("v" + cls[ 2 ].replace(/v/gi, '')))
|
&& (!cls[ 2 ] || l.version.toLowerCase().startsWith("v" + cls[ 2 ].replace(/v/gi, '')))
|
||||||
// && !(this.options.factionsBlacklist.find((f) => [ getTranslation(l.teams[ 0 ]), getTranslation(l.teams[ 1 ]) ].includes(f)))
|
// && !(this.options.factionsBlacklist.find((f) => [ getTranslation(l.teams[ 0 ]), getTranslation(l.teams[ 1 ]) ].includes(f)))
|
||||||
@ -1022,9 +1033,88 @@ export default class MapVote extends DiscordBasePlugin {
|
|||||||
if (!Layers.layers.find((e) => e.layerid == layer.rawName)) Layers.layers.push(new Layer(layer));
|
if (!Layers.layers.find((e) => e.layerid == layer.rawName)) Layers.layers.push(new Layer(layer));
|
||||||
}
|
}
|
||||||
|
|
||||||
this.verbose(1, 'Layer list updated');
|
const sheetCsv = (await axios.get('https://docs.google.com/spreadsheets/d/1OYO1IvNI0wrUZWKz_pz6Ka1xFAvBjBupddYn2E4fNFg/gviz/tq?tqx=out:csv&sheet=Map%20Layers')).data?.replace(/\"/g, '').split('\n')//.map((l) => l.split(','))
|
||||||
|
// this.verbose(1, 'Sheet', Layers.layers.length, sheetCsv.length, sheetCsv.find(l => l[ 2 ] == "Manicouagan_RAAS_v1"))
|
||||||
|
// this.verbose(1, 'Sheet', sheetCsv)
|
||||||
|
|
||||||
|
const rconLayers = (await this.server.rcon.execute('ListLayers')).split('\n');
|
||||||
|
rconLayers.shift();
|
||||||
|
// this.verbose(1, 'RCON Layers', this.mapLayer(rconLayers[ 0 ]))
|
||||||
|
for (const layer of rconLayers) {
|
||||||
|
if (!Layers.layers.find((e) => e.layerid == layer)) {
|
||||||
|
let newLayer = this.mapLayer(layer);
|
||||||
|
|
||||||
|
const csvLayer = sheetCsv.find(l => l.includes(newLayer.layerid))?.split(',');
|
||||||
|
// console.log(newLayer.layerid, csvLayer[ 2 ]);
|
||||||
|
if (csvLayer) {
|
||||||
|
if (csvLayer[ 6 ]) newLayer.teams[ 0 ].faction = csvLayer[ 6 ]
|
||||||
|
newLayer.teams[ 0 ].name = newLayer.teams[ 0 ].faction
|
||||||
|
if (csvLayer[ 9 ]) newLayer.teams[ 0 ].numberOfTanks = parseNumberOfAssets(csvLayer[ 9 ])
|
||||||
|
if (csvLayer[ 13 ]) newLayer.teams[ 0 ].numberOfHelicopters = parseNumberOfAssets(csvLayer[ 13 ])
|
||||||
|
if (csvLayer[ 5 ]) newLayer.teams[ 0 ].commander = csvLayer[ 5 ].toLowerCase() == 'yes'
|
||||||
|
|
||||||
|
if (csvLayer[ 10 ]) newLayer.teams[ 1 ].faction = csvLayer[ 10 ]
|
||||||
|
newLayer.teams[ 1 ].name = newLayer.teams[ 1 ].faction
|
||||||
|
newLayer.teams[ 1 ].numberOfTanks = newLayer.teams[ 0 ].numberOfTanks
|
||||||
|
newLayer.teams[ 1 ].numberOfHelicopters = newLayer.teams[ 0 ].numberOfHelicopters
|
||||||
|
newLayer.teams[ 1 ].commander = newLayer.teams[ 0 ].commander
|
||||||
|
}
|
||||||
|
|
||||||
|
Layers.layers.push(newLayer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sheetCsv.shift();
|
||||||
|
|
||||||
|
|
||||||
|
this.verbose(1, 'Layer list updated', Layers.layers.length, 'total layers');
|
||||||
|
// this.verbose(1, 'Layers', Layers.layers);
|
||||||
|
function parseNumberOfAssets(string) {
|
||||||
|
return /^x(\d)/.exec(string)[ 1 ]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mapLayer(l) {
|
||||||
|
l = l.replace(/[^a-z_\d]/gi, '')
|
||||||
|
// this.verbose(1, 'Parsing layer', l)
|
||||||
|
const gl = /^(?<level>\w+)_(?<gamemode>\w+)_(?<version>\w+)$/i.exec(l)?.groups
|
||||||
|
// this.verbose(1, 'Parsed layer', gl)
|
||||||
|
if (Object.keys(gl).length != 3) return;
|
||||||
|
|
||||||
|
let teams = []
|
||||||
|
for (const t of [ 'team1', 'team2' ]) {
|
||||||
|
teams.push({
|
||||||
|
faction: 'Unknown',
|
||||||
|
name: 'Unknown',
|
||||||
|
tickets: 0,
|
||||||
|
commander: false,
|
||||||
|
vehicles: [],
|
||||||
|
numberOfTanks: 0,
|
||||||
|
numberOfHelicopters: 0
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// this.verbose(1, 'teams', teams)
|
||||||
|
|
||||||
|
return {
|
||||||
|
name: l.replace(/_/g, ' '),
|
||||||
|
classname: gl.level,
|
||||||
|
layerid: l,
|
||||||
|
map: {
|
||||||
|
name: gl.level
|
||||||
|
},
|
||||||
|
gamemode: gl.gamemode,
|
||||||
|
gamemodeType: gl.gamemode,
|
||||||
|
version: gl.version,
|
||||||
|
size: '0.0x0.0 km',
|
||||||
|
sizeType: 'Playable Area',
|
||||||
|
numberOfCapturePoints: 0,
|
||||||
|
lighting: {
|
||||||
|
name: 'Unknown',
|
||||||
|
classname: 'Unknown'
|
||||||
|
},
|
||||||
|
teams: teams
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
formatChoice(choiceIndex, mapString, currentVotes, hideVoteCount) {
|
formatChoice(choiceIndex, mapString, currentVotes, hideVoteCount) {
|
||||||
return `${choiceIndex}➤ ${mapString} ` + (!hideVoteCount ? `(${currentVotes})` : "");
|
return `${choiceIndex}➤ ${mapString} ` + (!hideVoteCount ? `(${currentVotes})` : "");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user