diff --git a/GameFiles/GameInterface/_integration_base.gsc b/GameFiles/GameInterface/_integration_base.gsc index 2cf4196b9..dffb68c5b 100644 --- a/GameFiles/GameInterface/_integration_base.gsc +++ b/GameFiles/GameInterface/_integration_base.gsc @@ -41,9 +41,11 @@ Setup() level.busMethods[level.commonFunctions.setOutboundData] = ::_SetOutboundData; level.commonKeys = spawnstruct(); - level.commonKeys.enabled = "sv_iw4madmin_integration_enabled"; - level.commonKeys.busMode = "sv_iw4madmin_integration_busmode"; - level.commonKeys.busDir = "sv_iw4madmin_integration_busdir"; + level.commonKeys.enabled = "sv_iw4madmin_integration_enabled"; + level.commonKeys.busMode = "sv_iw4madmin_integration_busmode"; + level.commonKeys.busDir = "sv_iw4madmin_integration_busdir"; + level.eventBus.inLocation = ""; + level.eventBus.outLocation = ""; level.notifyTypes = spawnstruct(); level.notifyTypes.gameFunctionsInitialized = "GameFunctionsInitialized"; @@ -175,22 +177,22 @@ _GetPlayerFromClientNum( clientNum ) return undefined; } -_GetInboundData() +_GetInboundData( location ) { return GetDvar( level.eventBus.inVar ); } -_GetOutboundData() +_GetOutboundData( location ) { return GetDvar( level.eventBus.outVar ); } -_SetInboundData( data ) +_SetInboundData( location, data ) { return SetDvar( level.eventBus.inVar, data ); } -_SetOutboundData( data ) +_SetOutboundData( location, data ) { return SetDvar( level.eventBus.outVar, data ); } @@ -361,22 +363,25 @@ MonitorBus() { level endon( level.eventTypes.gameEnd ); - [[level.overrideMethods[level.commonFunctions.SetInboundData]]]( "" ); - [[level.overrideMethods[level.commonFunctions.SetOutboundData]]]( "" ); + level.eventBus.inLocation = level.eventBus.inVar + "_" + GetDvar( "net_port" ); + level.eventBus.outLocation = level.eventBus.outVar + "_" + GetDvar( "net_port" ); + + [[level.overrideMethods[level.commonFunctions.SetInboundData]]]( level.eventBus.inLocation, "" ); + [[level.overrideMethods[level.commonFunctions.SetOutboundData]]]( level.eventBus.outLocation, "" ); for( ;; ) { wait ( 0.1 ); // check to see if IW4MAdmin is ready to receive more data - inVal = [[level.busMethods[level.commonFunctions.getInboundData]]](); + inVal = [[level.busMethods[level.commonFunctions.getInboundData]]]( level.eventBus.inLocation ); if ( !IsDefined( inVal ) || inVal == "" ) { level notify( "bus_ready" ); } - eventString = [[level.busMethods[level.commonFunctions.getOutboundData]]](); + eventString = [[level.busMethods[level.commonFunctions.getOutboundData]]]( level.eventBus.outLocation ); if ( !IsDefined( eventString ) || eventString == "" ) { @@ -388,7 +393,7 @@ MonitorBus() groupSeparator = GetSubStr( GetDvar( "GroupSeparatorChar" ), 0, 1 ); NotifyEvent( strtok( eventString, groupSeparator ) ); - [[level.busMethods[level.commonFunctions.SetOutboundData]]]( "" ); + [[level.busMethods[level.commonFunctions.SetOutboundData]]]( level.eventBus.outLocation, "" ); } } @@ -400,11 +405,11 @@ QueueEvent( request, eventType, notifyEntity ) maxWait = level.eventBus.timeout * 1000; // 30 seconds timedOut = ""; - while ( [[level.busMethods[level.commonFunctions.getInboundData]]]() != "" && ( GetTime() - start ) < maxWait ) + while ( [[level.busMethods[level.commonFunctions.getInboundData]]]( level.eventBus.inLocation ) != "" && ( GetTime() - start ) < maxWait ) { level [[level.overrideMethods[level.commonFunctions.waittillNotifyOrTimeout]]]( "bus_ready", 1 ); - if ( [[level.busMethods[level.commonFunctions.getInboundData]]]() != "" ) + if ( [[level.busMethods[level.commonFunctions.getInboundData]]]( level.eventBus.inLocation ) != "" ) { LogDebug( "A request is already in progress..." ); timedOut = "set"; @@ -423,14 +428,14 @@ QueueEvent( request, eventType, notifyEntity ) notifyEntity NotifyClientEventTimeout( eventType ); } - [[level.busMethods[level.commonFunctions.SetInboundData]]]( "" ); + [[level.busMethods[level.commonFunctions.SetInboundData]]]( level.eventBus.inLocation, "" ); return; } LogDebug( "<- " + request ); - [[level.busMethods[level.commonFunctions.setInboundData]]]( request ); + [[level.busMethods[level.commonFunctions.setInboundData]]]( level.eventBus.inLocation, request ); } ParseDataString( data ) diff --git a/GameFiles/GameInterface/_integration_iw4x.gsc b/GameFiles/GameInterface/_integration_iw4x.gsc index 26e94565f..9a717d0eb 100644 --- a/GameFiles/GameInterface/_integration_iw4x.gsc +++ b/GameFiles/GameInterface/_integration_iw4x.gsc @@ -102,24 +102,24 @@ WaitForClientEvents() } } -GetInboundData() +GetInboundData( location ) { - return FileRead( level.eventBus.inVar); + return FileRead( location ); } -GetOutboundData() +GetOutboundData( location ) { - return FileRead( level.eventBus.outVar ); + return FileRead( location ); } -SetInboundData( data ) +SetInboundData( location, data ) { - FileWrite( level.eventBus.inVar, data, "write" ); + FileWrite( location, data, "write" ); } -SetOutboundData( data ) +SetOutboundData( location, data ) { - FileWrite(level.eventBus.outVar, data, "write" ); + FileWrite( location, data, "write" ); } GetMaxClients() diff --git a/GameFiles/GameInterface/_integration_shared.gsc b/GameFiles/GameInterface/_integration_shared.gsc index c4336d421..fc2b30073 100644 --- a/GameFiles/GameInterface/_integration_shared.gsc +++ b/GameFiles/GameInterface/_integration_shared.gsc @@ -202,6 +202,8 @@ OnBusModeRequestedCallback( event ) data = []; data["mode"] = GetDvar( level.commonKeys.busMode ); data["directory"] = GetDvar( level.commonKeys.busDir ); + data["inLocation"] = level.eventBus.inLocation; + data["outLocation"] = level.eventBus.outLocation; scripts\_integration_base::LogDebug( "Bus mode requested" ); diff --git a/Plugins/ScriptPlugins/GameInterface.js b/Plugins/ScriptPlugins/GameInterface.js index 28d56b1a1..135ee1fa2 100644 --- a/Plugins/ScriptPlugins/GameInterface.js +++ b/Plugins/ScriptPlugins/GameInterface.js @@ -1,8 +1,7 @@ const servers = {}; -const inDvar = 'sv_iw4madmin_in'; -const outDvar = 'sv_iw4madmin_out'; +let inDvar = 'sv_iw4madmin_in'; +let outDvar = 'sv_iw4madmin_out'; const integrationEnabledDvar = 'sv_iw4madmin_integration_enabled'; -const pollingRate = 300; const groupSeparatorChar = '\x1d'; const recordSeparatorChar = '\x1e'; const unitSeparatorChar = '\x1f'; @@ -15,6 +14,7 @@ const init = (registerNotify, serviceResolver, config, scriptHelper) => { registerNotify('IGameServerEventSubscriptions.ServerValueReceived', (serverValueEvent, _) => plugin.onServerValueReceived(serverValueEvent)); registerNotify('IGameServerEventSubscriptions.ServerValueSetCompleted', (serverValueEvent, _) => plugin.onServerValueSetCompleted(serverValueEvent)); registerNotify('IGameServerEventSubscriptions.MonitoringStarted', (monitorStartEvent, _) => plugin.onServerMonitoringStart(monitorStartEvent)); + registerNotify('IGameEventSubscriptions.MatchStarted', (matchStartEvent, _) => plugin.onMatchStart(matchStartEvent)); registerNotify('IManagementEventSubscriptions.ClientPenaltyAdministered', (penaltyEvent, _) => plugin.onPenalty(penaltyEvent)); plugin.onLoad(serviceResolver, config, scriptHelper); @@ -30,14 +30,31 @@ const plugin = { logger: null, commands: null, scriptHelper: null, + configWrapper: null, + config: { + pollingRate: 300 + }, - onLoad: function (serviceResolver, config, scriptHelper) { + onLoad: function (serviceResolver, configWrapper, scriptHelper) { this.serviceResolver = serviceResolver; this.eventManager = serviceResolver.resolveService('IManager'); this.logger = serviceResolver.resolveService('ILogger', ['ScriptPluginV2']); this.commands = commands; - this.config = config; + this.configWrapper = configWrapper; this.scriptHelper = scriptHelper; + + const storedConfig = this.configWrapper.getValue('config', newConfig => { + if (newConfig) { + plugin.logger.logInformation('{Name} config reloaded.', plugin.name); + plugin.config = newConfig; + } + }); + + if (storedConfig != null) { + this.config = storedConfig + } else { + this.configWrapper.setValue('config', this.config); + } }, onClientEnteredMatch: function (clientEvent) { @@ -110,6 +127,11 @@ const plugin = { this.initializeServer(monitorStartEvent.server); }, + onMatchStart: function (matchStartEvent) { + busMode = 'rcon'; + this.sendEventMessage(matchStartEvent.server, true, 'GetBusModeRequested', null, null, null, {}); + }, + initializeServer: function (server) { servers[server.id] = { enabled: false, @@ -138,6 +160,9 @@ const plugin = { serverState.enabled = true; serverState.running = true; serverState.initializationInProgress = false; + + // todo: this might not work for all games + responseEvent.server.rconParser.configuration.floodProtectInterval = 150; this.sendEventMessage(responseEvent.server, true, 'GetBusModeRequested', null, null, null, {}); this.sendEventMessage(responseEvent.server, true, 'GetCommandsRequested', null, null, null, {}); @@ -346,7 +371,11 @@ const plugin = { if (event.eventType === 'GetBusModeRequested') { if (event.data?.directory && event.data?.mode) { busMode = event.data.mode; - busDir = event.data.directory; + busDir = event.data.directory.replace('\'', '').replace('"', ''); + if (event.data?.inLocation && event.data?.outLocation) { + inDvar = event.data?.inLocation; + outDvar = event.data?.outLocation; + } this.logger.logDebug('Setting bus mode to {mode} {dir}', busMode, busDir); } } @@ -408,7 +437,7 @@ const plugin = { const serverEvents = importNamespace('SharedLibraryCore.Events.Server'); const requestEvent = new serverEvents.ServerValueRequestEvent(dvarName, server); - requestEvent.delayMs = pollingRate; + requestEvent.delayMs = this.config.pollingRate; requestEvent.timeoutMs = 2000; requestEvent.source = this.name; @@ -418,7 +447,7 @@ const plugin = { const diff = new Date().getTime() - end.getTime(); if (diff < extraDelay) { - requestEvent.delayMs = (extraDelay - diff) + pollingRate; + requestEvent.delayMs = (extraDelay - diff) + this.config.pollingRate; this.logger.logDebug('Increasing delay time to {Delay}ms due to recent map change', requestEvent.delayMs); } } @@ -468,7 +497,7 @@ const plugin = { const serverEvents = importNamespace('SharedLibraryCore.Events.Server'); const requestEvent = new serverEvents.ServerValueSetRequestEvent(dvarName, dvarValue, server); - requestEvent.delayMs = pollingRate; + requestEvent.delayMs = this.config.pollingRate; requestEvent.timeoutMs = 2000; requestEvent.source = this.name; @@ -478,7 +507,7 @@ const plugin = { const diff = new Date().getTime() - end.getTime(); if (diff < extraDelay) { - requestEvent.delayMs = (extraDelay - diff) + pollingRate; + requestEvent.delayMs = (extraDelay - diff) + this.config.pollingRate; this.logger.logDebug('Increasing delay time to {Delay}ms due to recent map change', requestEvent.delayMs); } }