diff --git a/Plugins/ScriptPlugins/ServerBanner.js b/Plugins/ScriptPlugins/ServerBanner.js new file mode 100644 index 000000000..1be7a41a5 --- /dev/null +++ b/Plugins/ScriptPlugins/ServerBanner.js @@ -0,0 +1,285 @@ +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) { + if (serverLocationCache[startEvent.server.listenAddress] === undefined) { + serverLocationCache[startEvent.server.listenAddress] = 'UA'; + } + + if (serverOrderCache[startEvent.server.gameCode] === undefined) { + serverOrderCache[startEvent.server.gameCode] = []; + } + + const lookupIp = startEvent.server.resolvedIpEndPoint.address.isInternal() ? + this.manager.externalIPAddress : + startEvent.server.listenAddress; + + serverOrderCache[startEvent.server.gameCode].push(startEvent.server); + serverOrderCache[startEvent.server.gameCode].sort((a, b) => b.clientNum - a.clientNum); + + 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.listenAddress; + + 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 += '
'; + return response; + }; + + return interactionData; + } + }] +};