const init = (registerNotify, serviceResolver, config, scriptHelper) => { registerNotify('IGameServerEventSubscriptions.MonitoringStarted', (monitorStartEvent, _) => plugin.onServerMonitoringStart(monitorStartEvent)); plugin.onLoad(serviceResolver, config, scriptHelper); return plugin; }; const serverLocationCache = []; const serverOrderCache = []; const plugin = { author: 'RaidMax', version: '1.0', name: 'Server Banner', serviceResolver: null, scriptHelper: null, config: null, manager: null, logger: null, webfrontUrl: null, onLoad: function (serviceResolver, config, scriptHelper) { this.serviceResolver = serviceResolver; this.config = config; this.scriptHelper = scriptHelper; this.manager = serviceResolver.resolveService('IManager'); this.logger = serviceResolver.resolveService('ILogger', ['ScriptPluginV2']); this.webfrontUrl = serviceResolver.resolveService('ApplicationConfiguration').webfrontUrl; }, onServerMonitoringStart: function (startEvent) { let lookupComplete = true; if (serverLocationCache[startEvent.server.listenAddress] === undefined) { serverLocationCache[startEvent.server.listenAddress] = 'SO'; lookupComplete = false; } if (serverOrderCache[startEvent.server.gameCode] === undefined) { serverOrderCache[startEvent.server.gameCode] = []; } serverOrderCache[startEvent.server.gameCode].push(startEvent.server); serverOrderCache[startEvent.server.gameCode].sort((a, b) => b.clientNum - a.clientNum); serverOrderCache.sort((a, b) => b[Object.keys(b)[0].clientNum] - b[Object.keys(a)[0].clientNum]); if (lookupComplete) { return; } const lookupIp = startEvent.server.resolvedIpEndPoint.address.isInternal() ? this.manager.externalIPAddress : startEvent.server.resolvedIpEndPoint.toString().split(':')[0]; this.logger.logInformation('Looking up server location for IP {IP}', lookupIp); this.scriptHelper.getUrl(`https://ipinfo.io/${lookupIp}/country`, (result) => { let error = true; try { JSON.parse(result); } catch { error = false; } if (!error) { serverLocationCache[startEvent.server.listenAddress] = String(result); } else { this.logger.logWarning('Could not determine server location from IP'); } }); }, interactions: [{ name: 'Banner', action: function (_, __, ___) { const helpers = importNamespace('SharedLibraryCore.Helpers'); const interactionData = new helpers.InteractionData(); interactionData.interactionId = 'banner'; interactionData.minimumPermission = 0; interactionData.interactionType = 1; interactionData.source = plugin.name; interactionData.scriptAction = (sourceId, targetId, game, meta, token) => { const serverId = meta['serverId']; let server; let colorLeft = 'color: #f5f5f5; text-shadow: -1px 1px 8px #000000cc;'; let colorRight = 'color: #222222; text-shadow: -1px 1px 8px #ecececcc;'; const colorMappingOverride = { 't6': { right: colorLeft }, 'iw3': { left: colorRight, }, 'iw5': { left: colorRight }, 'iw6': { right: colorLeft }, 't4': { left: colorRight, right: colorLeft }, 't5': { right: colorLeft }, 't7': { right: colorLeft }, 'shg1': { right: colorLeft }, 'h1': { right: colorLeft }, 'csgo': { right: colorLeft }, }; plugin.manager.getServers().forEach(eachServer => { if (eachServer.id === serverId) { server = eachServer; } }); if (serverLocationCache[server.listenAddress] === undefined) { plugin.onServerMonitoringStart({ server: server }); } if (serverOrderCache[server.gameCode] === undefined) { plugin.onServerMonitoringStart({ server: server }); } let gameCode = server.gameCode.toLowerCase(); colorLeft = colorMappingOverride[gameCode]?.left || colorLeft; colorRight = colorMappingOverride[gameCode]?.right || colorRight; const font = 'Noto Sans Mono'; let status = '
ONLINE
'; if (server.throttled) { status = '
OFFLINE
'; } const displayIp = server.resolvedIpEndPoint.address.isInternal() ? plugin.manager.externalIPAddress : server.resolvedIpEndPoint.toString().split(':')[0]; return `
${server.serverName.stripColors()}
${displayIp}:${server.listenPort}
${server.throttled ? '-' : server.clientNum}/${server.maxClients} Players
${serverLocationCache[server.listenAddress]}
${server.map.alias}
${server.gametypeName}
${status}
`; }; return interactionData; } }, { name: 'Webfront::Nav::Main::BannerPreview', action: function (_, __, ___) { const helpers = importNamespace('SharedLibraryCore.Helpers'); const interactionData = new helpers.InteractionData(); interactionData.interactionId = 'Webfront::Nav::Main::BannerPreview'; interactionData.minimumPermission = 0; interactionData.interactionType = 2; interactionData.source = plugin.name; interactionData.name = 'Banners'; interactionData.description = interactionData.name; interactionData.displayMeta = 'oi-image'; interactionData.scriptAction = (_, __, ___, ____, _____) => { if (Object.keys(serverOrderCache).length === 0) { plugin.manager.getServers().forEach(server => { plugin.onServerMonitoringStart({ server: server }); }); } let response = '
'; Object.keys(serverOrderCache).forEach(key => { const servers = serverOrderCache[key]; servers.forEach(eachServer => { response += `
${eachServer.gameCode}
${eachServer.serverName.stripColors()}
Show Embed
`; }); }); response += '
'; response += '' return response; }; return interactionData; } }] };