From 7323c6e3d7869696ef3d192b53d47b4d339aa4c3 Mon Sep 17 00:00:00 2001 From: RaidMax Date: Thu, 1 Jun 2023 20:45:05 -0500 Subject: [PATCH] clean-up and make game interface gsc consistent --- GameFiles/GameInterface/_integration_base.gsc | 156 ++++------- GameFiles/GameInterface/_integration_iw4x.gsc | 47 ++-- GameFiles/GameInterface/_integration_iw5.gsc | 211 ++------------- .../GameInterface/_integration_shared.gsc | 247 ++++++++++-------- GameFiles/GameInterface/_integration_t5.gsc | 208 ++------------- GameFiles/GameInterface/_integration_t5zm.gsc | 220 ++-------------- GameFiles/GameInterface/_integration_t6.gsc | 228 ++-------------- .../_integration_t6zm_helper.gsc | 35 ++- 8 files changed, 316 insertions(+), 1036 deletions(-) diff --git a/GameFiles/GameInterface/_integration_base.gsc b/GameFiles/GameInterface/_integration_base.gsc index fac8a6688..3c4aa0c07 100644 --- a/GameFiles/GameInterface/_integration_base.gsc +++ b/GameFiles/GameInterface/_integration_base.gsc @@ -19,11 +19,15 @@ Setup() level.commonFunctions = spawnstruct(); level.commonFunctions.setDvar = "SetDvarIfUninitialized"; - level.commonFunctions.isBot = "IsBot"; - level.commonFunctions.getXuid = "GetXuid"; level.commonFunctions.getPlayerFromClientNum = "GetPlayerFromClientNum"; + level.commonFunctions.waittillNotifyOrTimeout = "WaittillNotifyOrTimeout"; + + level.overrideMethods = []; + level.overrideMethods[level.commonFunctions.setDvar] = scripts\_integration_base::NotImplementedFunction; + level.overrideMethods[level.commonFunctions.getPlayerFromClientNum] = ::_GetPlayerFromClientNum; level.commonKeys = spawnstruct(); + level.commonKeys.enabled = "sv_iw4madmin_integration_enabled"; level.notifyTypes = spawnstruct(); level.notifyTypes.gameFunctionsInitialized = "GameFunctionsInitialized"; @@ -51,12 +55,11 @@ Setup() level.clientCommandCallbacks = []; level.clientCommandRusAsTarget = []; level.logger = spawnstruct(); - level.overrideMethods = []; level.iw4madminIntegrationDebug = GetDvarInt( "sv_iw4madmin_integration_debug" ); InitializeLogger(); - wait ( 0.05 ); // needed to give script engine time to propagate notifies + wait ( 0.05 * 2 ); // needed to give script engine time to propagate notifies level notify( level.notifyTypes.integrationBootstrapInitialized ); level waittill( level.notifyTypes.gameFunctionsInitialized ); @@ -65,105 +68,26 @@ Setup() _SetDvarIfUninitialized( level.eventBus.inVar, "" ); _SetDvarIfUninitialized( level.eventBus.outVar, "" ); - _SetDvarIfUninitialized( "sv_iw4madmin_integration_enabled", 1 ); + _SetDvarIfUninitialized( level.commonKeys.enabled, 1 ); _SetDvarIfUninitialized( "sv_iw4madmin_integration_debug", 0 ); - if ( GetDvarInt( "sv_iw4madmin_integration_enabled" ) != 1 ) + if ( GetDvarInt( level.commonKeys.enabled) != 1 ) { return; } // start long running tasks - level thread MonitorClientEvents(); - level thread MonitorBus(); - level thread OnPlayerConnect(); + thread MonitorClientEvents(); + thread MonitorBus(); } ////////////////////////////////// // Client Methods ////////////////////////////////// -OnPlayerConnect() -{ - level endon ( "game_ended" ); - - for ( ;; ) - { - level waittill( "connected", player ); - - if ( _IsBot( player ) ) - { - // we don't want to track bots - continue; - } - - if ( !IsDefined( player.pers[level.clientDataKey] ) ) - { - player.pers[level.clientDataKey] = spawnstruct(); - } - - player thread OnPlayerSpawned(); - } -} - -OnPlayerSpawned() -{ - self endon( "disconnect" ); - - for ( ;; ) - { - self waittill( "spawned_player" ); - self PlayerSpawnEvents(); - } -} - -OnGameEnded() -{ - for ( ;; ) - { - level waittill( "game_ended" ); - // note: you can run data code here but it's possible for - // data to get truncated, so we will try a timer based approach for now - } -} - -DisplayWelcomeData() -{ - self endon( "disconnect" ); - - clientData = self.pers[level.clientDataKey]; - - if ( clientData.permissionLevel == "User" || clientData.permissionLevel == "Flagged" ) - { - return; - } - - self IPrintLnBold( "Welcome, your level is ^5" + clientData.permissionLevel ); - wait( 2.0 ); - self IPrintLnBold( "You were last seen ^5" + clientData.lastConnection ); -} - -PlayerSpawnEvents() -{ - self endon( "disconnect" ); - - clientData = self.pers[level.clientDataKey]; - - // this gives IW4MAdmin some time to register the player before making the request; - // although probably not necessary some users might have a slow database or poll rate - wait ( 2 ); - - if ( IsDefined( clientData.state ) && clientData.state == "complete" ) - { - return; - } - - self RequestClientBasicData(); -} - MonitorClientEvents() { - level endon( "game_ended" ); + level endon( level.eventTypes.gameEnd ); for ( ;; ) { @@ -178,6 +102,7 @@ MonitorClientEvents() client [[eventHandler]]( client.event ); LogDebug( "notify client for " + client.event.type ); client notify( level.eventTypes.localClientEvent, client.event ); + client notify( client.event.type, client.event ); } client.eventData = []; @@ -188,11 +113,13 @@ MonitorClientEvents() // Helper Methods ////////////////////////////////// -_IsBot( entity ) +NotImplementedFunction( a, b, c, d, e, f ) { - // there already is a cgame function exists as "IsBot", for IW4, but unsure what all titles have it defined, - // so we are defining it here - return IsDefined( entity.pers["isBot"] ) && entity.pers["isBot"]; + LogWarning( "Function not implemented" ); + if ( IsDefined ( a ) ) + { + LogWarning( a ); + } } _SetDvarIfUninitialized( dvarName, dvarValue ) @@ -200,9 +127,22 @@ _SetDvarIfUninitialized( dvarName, dvarValue ) [[level.overrideMethods[level.commonFunctions.setDvar]]]( dvarName, dvarValue ); } -NotImplementedFunction( a, b, c, d, e, f ) +_GetPlayerFromClientNum( clientNum ) { - LogWarning( "Function not implemented" ); + if ( clientNum < 0 ) + { + return undefined; + } + + for ( i = 0; i < level.players.size; i++ ) + { + if ( level.players[i] getEntityNumber() == clientNum ) + { + return level.players[i]; + } + } + + return undefined; } // Not every game can output to console or even game log. @@ -285,13 +225,13 @@ RegisterLogger( logger ) RequestClientMeta( metaKey ) { getClientMetaEvent = BuildEventRequest( true, level.eventTypes.clientDataRequested, "Meta", self, metaKey ); - level thread QueueEvent( getClientMetaEvent, level.eventTypes.clientDataRequested, self ); + thread QueueEvent( getClientMetaEvent, level.eventTypes.clientDataRequested, self ); } RequestClientBasicData() { getClientDataEvent = BuildEventRequest( true, level.eventTypes.clientDataRequested, "None", self, "" ); - level thread QueueEvent( getClientDataEvent, level.eventTypes.clientDataRequested, self ); + thread QueueEvent( getClientDataEvent, level.eventTypes.clientDataRequested, self ); } IncrementClientMeta( metaKey, incrementValue, clientId ) @@ -326,7 +266,7 @@ SetClientMeta( metaKey, metaValue, clientId, direction ) } setClientMetaEvent = BuildEventRequest( true, level.eventTypes.setClientDataRequested, "Meta", clientNumber, data ); - level thread QueueEvent( setClientMetaEvent, level.eventTypes.setClientDataRequested, self ); + thread QueueEvent( setClientMetaEvent, level.eventTypes.setClientDataRequested, self ); } BuildEventRequest( responseExpected, eventType, eventSubtype, entOrId, data ) @@ -359,7 +299,7 @@ BuildEventRequest( responseExpected, eventType, eventSubtype, entOrId, data ) MonitorBus() { - level endon( "game_ended" ); + level endon( level.eventTypes.gameEnd ); for( ;; ) { @@ -387,7 +327,7 @@ MonitorBus() QueueEvent( request, eventType, notifyEntity ) { - level endon( "game_ended" ); + level endon( level.eventTypes.gameEnd ); start = GetTime(); maxWait = level.eventBus.timeout * 1000; // 30 seconds @@ -395,7 +335,7 @@ QueueEvent( request, eventType, notifyEntity ) while ( GetDvar( level.eventBus.inVar ) != "" && ( GetTime() - start ) < maxWait ) { - level [[level.overrideMethods["waittill_notify_or_timeout"]]]( "bus_ready", 1 ); + level [[level.overrideMethods[level.commonFunctions.waittillNotifyOrTimeout]]]( "bus_ready", 1 ); if ( GetDvar( level.eventBus.inVar ) != "" ) { @@ -541,7 +481,7 @@ OnClientDataReceived( event ) metaKey = event.data[0]; clientData.meta[metaKey] = event.data[metaKey]; - LogDebug( "Meta Key=" + metaKey + ", Meta Value=" + event.data[metaKey] ); + LogDebug( "Meta Key=" + CoerceUndefined( metaKey ) + ", Meta Value=" + CoerceUndefined( event.data[metaKey] ) ); return; } @@ -553,8 +493,6 @@ OnClientDataReceived( event ) clientData.performance = event.data["performance"]; clientData.state = "complete"; self.persistentClientId = event.data["clientId"]; - - self thread DisplayWelcomeData(); } OnExecuteCommand( event ) @@ -590,5 +528,15 @@ OnExecuteCommand( event ) OnSetClientDataCompleted( event ) { // IW4MAdmin let us know it persisted (success or fail) - LogDebug( "Set Client Data -> subtype = " + event.subType + " status = " + event.data["status"] ); + LogDebug( "Set Client Data -> subtype = " + CoerceUndefined( event.subType ) + ", status = " + CoerceUndefined( event.data["status"] ) ); +} + +CoerceUndefined( object ) +{ + if ( !IsDefined( object ) ) + { + return "undefined"; + } + + return object; } diff --git a/GameFiles/GameInterface/_integration_iw4x.gsc b/GameFiles/GameInterface/_integration_iw4x.gsc index a072e7347..bfa1ce0b3 100644 --- a/GameFiles/GameInterface/_integration_iw4x.gsc +++ b/GameFiles/GameInterface/_integration_iw4x.gsc @@ -8,18 +8,17 @@ Init() Setup() { level endon( "game_ended" ); + waittillframeend; - // it's possible that the notify type has not been defined yet so we have to hard code it - level waittill( "SharedFunctionsInitialized" ); + level waittill( level.notifyTypes.sharedFunctionsInitialized ); level.eventBus.gamename = "IW4"; scripts\_integration_base::RegisterLogger( ::Log2Console ); - level.overrideMethods["GetTotalShotsFired"] = ::GetTotalShotsFired; - level.overrideMethods[level.commonFunctions.setDvar] = ::_SetDvarIfUninitialized; - level.overrideMethods[level.commonFunctions.isBot] = ::IsTestClient; - level.overrideMethods[level.commonFunctions.getXuid] = ::_GetXUID; - level.overrideMethods["waittill_notify_or_timeout"] = ::_waittill_notify_or_timeout; + level.overrideMethods[level.commonFunctions.getTotalShotsFired] = ::GetTotalShotsFired; + level.overrideMethods[level.commonFunctions.setDvar] = ::SetDvarIfUninitializedWrapper; + level.overrideMethods[level.commonFunctions.isBot] = ::IsBotWrapper; + level.overrideMethods[level.commonFunctions.getXuid] = ::GetXuidWrapper; level.overrideMethods[level.commonFunctions.changeTeam] = ::ChangeTeam; level.overrideMethods[level.commonFunctions.getTeamCounts] = ::CountPlayers; level.overrideMethods[level.commonFunctions.getMaxClients] = ::GetMaxClients; @@ -28,19 +27,18 @@ Setup() level.overrideMethods[level.commonFunctions.getClientKillStreak] = ::GetClientKillStreak; level.overrideMethods[level.commonFunctions.backupRestoreClientKillStreakData] = ::BackupRestoreClientKillStreakData; level.overrideMethods[level.commonFunctions.waitTillAnyTimeout] = ::WaitTillAnyTimeout; + level.overrideMethods[level.commonFunctions.waittillNotifyOrTimeout] = ::WaitillNotifyOrTimeoutWrapper; RegisterClientCommands(); - _SetDvarIfUninitialized( "sv_iw4madmin_autobalance", 0 ); - level notify( level.notifyTypes.gameFunctionsInitialized ); - if ( GetDvarInt( "sv_iw4madmin_integration_enabled" ) != 1 ) + if ( GetDvarInt( level.commonKeys.enabled ) != 1 ) { return; } - level thread OnPlayerConnect(); + thread OnPlayerConnect(); } OnPlayerConnect() @@ -51,7 +49,7 @@ OnPlayerConnect() { level waittill( "connected", player ); - if ( player call [[ level.overrideMethods[ level.commonFunctions.isBot ] ]]() ) + if ( player IsTestClient() ) { // we don't want to track bots continue; @@ -186,12 +184,7 @@ GetTotalShotsFired() return maps\mp\_utility::getPlayerStat( "mostshotsfired" ); } -_SetDvarIfUninitialized( dvar, value ) -{ - SetDvarIfUninitialized( dvar, value ); -} - -_waittill_notify_or_timeout( _notify, timeout ) +WaitillNotifyOrTimeoutWrapper( _notify, timeout ) { common_scripts\utility::waittill_notify_or_timeout( _notify, timeout ); } @@ -201,11 +194,21 @@ Log2Console( logLevel, message ) PrintConsole( "[" + logLevel + "] " + message + "\n" ); } -_GetXUID() +SetDvarIfUninitializedWrapper( dvar, value ) +{ + SetDvarIfUninitialized( dvar, value ); +} + +GetXuidWrapper() { return self GetXUID(); } +IsBotWrapper( client ) +{ + return client IsTestClient(); +} + ////////////////////////////////// // GUID helpers ///////////////////////////////// @@ -519,11 +522,7 @@ HideImpl() AlertImpl( event, data ) { - if ( level.eventBus.gamename == "IW4" ) - { - self thread maps\mp\gametypes\_hud_message::oldNotifyMessage( data["alertType"], data["message"], "compass_waypoint_target", ( 1, 0, 0 ), "ui_mp_nukebomb_timer", 7.5 ); - } - + self thread maps\mp\gametypes\_hud_message::oldNotifyMessage( data["alertType"], data["message"], "compass_waypoint_target", ( 1, 0, 0 ), "ui_mp_nukebomb_timer", 7.5 ); return "Sent alert to " + self.name; } diff --git a/GameFiles/GameInterface/_integration_iw5.gsc b/GameFiles/GameInterface/_integration_iw5.gsc index 75057e375..16140fd84 100644 --- a/GameFiles/GameInterface/_integration_iw5.gsc +++ b/GameFiles/GameInterface/_integration_iw5.gsc @@ -8,50 +8,22 @@ Init() Setup() { level endon( "game_ended" ); + waittillframeend; - // it's possible that the notify type has not been defined yet so we have to hard code it - level waittill( "SharedFunctionsInitialized" ); + level waittill( level.notifyTypes.sharedFunctionsInitialized ); level.eventBus.gamename = "IW5"; scripts\_integration_base::RegisterLogger( ::Log2Console ); - level.overrideMethods["GetTotalShotsFired"] = ::GetTotalShotsFired; - level.overrideMethods["SetDvarIfUninitialized"] = ::_SetDvarIfUninitialized; - level.overrideMethods["waittill_notify_or_timeout"] = ::_waittill_notify_or_timeout; - level.overrideMethods[level.commonFunctions.isBot] = ::IsTestClient; - level.overrideMethods[level.commonFunctions.getXuid] = ::_GetXUID; + level.overrideMethods[level.commonFunctions.getTotalShotsFired] = ::GetTotalShotsFired; + level.overrideMethods[level.commonFunctions.setDvar] = ::SetDvarIfUninitializedWrapper; + level.overrideMethods[level.commonFunctions.waittillNotifyOrTimeout] = ::WaitillNotifyOrTimeoutWrapper; + level.overrideMethods[level.commonFunctions.isBot] = ::IsBotWrapper; + level.overrideMethods[level.commonFunctions.getXuid] = ::GetXuidWrapper; RegisterClientCommands(); - _SetDvarIfUninitialized( "sv_iw4madmin_autobalance", 0 ); - level notify( level.notifyTypes.gameFunctionsInitialized ); - - if ( GetDvarInt( "sv_iw4madmin_integration_enabled" ) != 1 ) - { - return; - } - - level thread OnPlayerConnect(); -} - -OnPlayerConnect() -{ - level endon ( "game_ended" ); - - for ( ;; ) - { - level waittill( "connected", player ); - - if ( player call [[ level.overrideMethods[ level.commonFunctions.isBot ] ]]() ) - { - // we don't want to track bots - continue; - } - - player thread SetPersistentData(); - player thread WaitForClientEvents(); - } } RegisterClientCommands() @@ -69,39 +41,17 @@ RegisterClientCommands() scripts\_integration_base::AddClientCommand( "NoClip", false, ::NoClipImpl ); } -WaitForClientEvents() -{ - self endon( "disconnect" ); - - // example of requesting a meta value - lastServerMetaKey = "LastServerPlayed"; - // self scripts\_integration_base::RequestClientMeta( lastServerMetaKey ); - - for ( ;; ) - { - self waittill( level.eventTypes.localClientEvent, event ); - - scripts\_integration_base::LogDebug( "Received client event " + event.type ); - - if ( event.type == level.eventTypes.clientDataReceived && event.data[0] == lastServerMetaKey ) - { - clientData = self.pers[level.clientDataKey]; - lastServerPlayed = clientData.meta[lastServerMetaKey]; - } - } -} - GetTotalShotsFired() { return maps\mp\_utility::getPlayerStat( "mostshotsfired" ); } -_SetDvarIfUninitialized( dvar, value ) +SetDvarIfUninitializedWrapper( dvar, value ) { SetDvarIfUninitialized( dvar, value ); } -_waittill_notify_or_timeout( _notify, timeout ) +WaitillNotifyOrTimeoutWrapper( _notify, timeout ) { common_scripts\utility::waittill_notify_or_timeout( _notify, timeout ); } @@ -111,142 +61,16 @@ Log2Console( logLevel, message ) Print( "[" + logLevel + "] " + message + "\n" ); } -_GetXUID() +IsBotWrapper( client ) +{ + return client IsTestClient(); +} + +GetXuidWrapper() { return self GetXUID(); } -////////////////////////////////// -// GUID helpers -///////////////////////////////// - -SetPersistentData() -{ - self endon( "disconnect" ); - - guidHigh = self GetPlayerData( "bests", "none" ); - guidLow = self GetPlayerData( "awards", "none" ); - persistentGuid = guidHigh + "," + guidLow; - guidIsStored = guidHigh != 0 && guidLow != 0; - - if ( guidIsStored ) - { - // give IW4MAdmin time to collect IP - wait( 15 ); - scripts\_integration_base::LogDebug( "Uploading persistent guid " + persistentGuid ); - scripts\_integration_base::SetClientMeta( "PersistentClientGuid", persistentGuid ); - return; - } - - guid = self SplitGuid(); - - scripts\_integration_base::LogDebug( "Persisting client guid " + guidHigh + "," + guidLow ); - - self SetPlayerData( "bests", "none", guid["high"] ); - self SetPlayerData( "awards", "none", guid["low"] ); -} - -SplitGuid() -{ - guid = self GetGuid(); - - if ( isDefined( self.guid ) ) - { - guid = self.guid; - } - - firstPart = 0; - secondPart = 0; - stringLength = 17; - firstPartExp = 0; - secondPartExp = 0; - - for ( i = stringLength - 1; i > 0; i-- ) - { - char = GetSubStr( guid, i - 1, i ); - if ( char == "" ) - { - char = "0"; - } - - if ( i > stringLength / 2 ) - { - value = GetIntForHexChar( char ); - power = Pow( 16, secondPartExp ); - secondPart = secondPart + ( value * power ); - secondPartExp++; - } - else - { - value = GetIntForHexChar( char ); - power = Pow( 16, firstPartExp ); - firstPart = firstPart + ( value * power ); - firstPartExp++; - } - } - - split = []; - split["low"] = int( secondPart ); - split["high"] = int( firstPart ); - - return split; -} - -Pow( num, exponent ) -{ - result = 1; - while( exponent != 0 ) - { - result = result * num; - exponent--; - } - - return result; -} - -GetIntForHexChar( char ) -{ - char = ToLower( char ); - // generated by co-pilot because I can't be bothered to make it more "elegant" - switch( char ) - { - case "0": - return 0; - case "1": - return 1; - case "2": - return 2; - case "3": - return 3; - case "4": - return 4; - case "5": - return 5; - case "6": - return 6; - case "7": - return 7; - case "8": - return 8; - case "9": - return 9; - case "a": - return 10; - case "b": - return 11; - case "c": - return 12; - case "d": - return 13; - case "e": - return 14; - case "f": - return 15; - default: - return 0; - } -} - ////////////////////////////////// // Command Implementations ///////////////////////////////// @@ -427,10 +251,7 @@ HideImpl() AlertImpl( event, data ) { - if ( level.eventBus.gamename == "IW5" ) { - self thread maps\mp\gametypes\_hud_message::oldNotifyMessage( data["alertType"], data["message"], undefined, ( 1, 0, 0 ), "ui_mp_nukebomb_timer", 7.5 ); - } - + self thread maps\mp\gametypes\_hud_message::oldNotifyMessage( data["alertType"], data["message"], undefined, ( 1, 0, 0 ), "ui_mp_nukebomb_timer", 7.5 ); return "Sent alert to " + self.name; } diff --git a/GameFiles/GameInterface/_integration_shared.gsc b/GameFiles/GameInterface/_integration_shared.gsc index 2c0d87bd1..aa517b6b8 100644 --- a/GameFiles/GameInterface/_integration_shared.gsc +++ b/GameFiles/GameInterface/_integration_shared.gsc @@ -1,4 +1,3 @@ - Init() { thread Setup(); @@ -6,10 +5,10 @@ Init() Setup() { + wait ( 0.05 ); level endon( "game_ended" ); - // it's possible that the notify type has not been defined yet so we have to hard code it - level waittill( "IntegrationBootstrapInitialized" ); + level waittill( level.notifyTypes.integrationBootstrapInitialized ); level.commonFunctions.changeTeam = "ChangeTeam"; level.commonFunctions.getTeamCounts = "GetTeamCounts"; @@ -18,7 +17,10 @@ Setup() level.commonFunctions.getClientTeam = "GetClientTeam"; level.commonFunctions.getClientKillStreak = "GetClientKillStreak"; level.commonFunctions.backupRestoreClientKillStreakData = "BackupRestoreClientKillStreakData"; + level.commonFunctions.getTotalShotsFired = "GetTotalShotsFired"; level.commonFunctions.waitTillAnyTimeout = "WaitTillAnyTimeout"; + level.commonFunctions.isBot = "IsBot"; + level.commonFunctions.getXuid = "GetXuid"; level.overrideMethods[level.commonFunctions.changeTeam] = scripts\_integration_base::NotImplementedFunction; level.overrideMethods[level.commonFunctions.getTeamCounts] = scripts\_integration_base::NotImplementedFunction; @@ -28,16 +30,19 @@ Setup() level.overrideMethods[level.commonFunctions.getClientKillStreak] = scripts\_integration_base::NotImplementedFunction; level.overrideMethods[level.commonFunctions.backupRestoreClientKillStreakData] = scripts\_integration_base::NotImplementedFunction; level.overrideMethods[level.commonFunctions.waitTillAnyTimeout] = scripts\_integration_base::NotImplementedFunction; - level.overrideMethods["GetPlayerFromClientNum"] = ::GetPlayerFromClientNum; + level.overrideMethods[level.commonFunctions.getXuid] = scripts\_integration_base::NotImplementedFunction; + level.overrideMethods[level.commonFunctions.isBot] = scripts\_integration_base::NotImplementedFunction; // these can be overridden per game if needed level.commonKeys.team1 = "allies"; level.commonKeys.team2 = "axis"; level.commonKeys.teamSpectator = "spectator"; + level.commonKeys.autoBalance = "sv_iw4madmin_autobalance"; level.eventTypes.connect = "connected"; level.eventTypes.disconnect = "disconnect"; level.eventTypes.joinTeam = "joined_team"; + level.eventTypes.joinSpec = "joined_spectators"; level.eventTypes.spawned = "spawned_player"; level.eventTypes.gameEnd = "game_ended"; @@ -45,13 +50,20 @@ Setup() level notify( level.notifyTypes.sharedFunctionsInitialized ); level waittill( level.notifyTypes.gameFunctionsInitialized ); - - if ( GetDvarInt( "sv_iw4madmin_integration_enabled" ) != 1 ) + + scripts\_integration_base::_SetDvarIfUninitialized( level.commonKeys.autoBalance, 0 ); + + if ( GetDvarInt( level.commonKeys.enabled ) != 1 ) { return; } - level thread OnPlayerConnect(); + thread OnPlayerConnect(); +} + +_IsBot( player ) +{ + return [[level.overrideMethods[level.commonFunctions.isBot]]]( player ); } OnPlayerConnect() @@ -62,17 +74,23 @@ OnPlayerConnect() { level waittill( level.eventTypes.connect, player ); - if ( scripts\_integration_base::_IsBot( player ) ) + if ( _IsBot( player ) ) { // we don't want to track bots continue; } + + if ( !IsDefined( player.pers[level.clientDataKey] ) ) + { + player.pers[level.clientDataKey] = spawnstruct(); + } + player thread OnPlayerSpawned(); player thread OnPlayerJoinedTeam(); player thread OnPlayerJoinedSpectators(); player thread PlayerTrackingOnInterval(); - if ( GetDvarInt( "sv_iw4madmin_autobalance" ) != 1 || !IsDefined( [[level.overrideMethods[level.commonFunctions.getTeamBased]]]() ) ) + if ( GetDvarInt( level.commonKeys.autoBalance ) != 1 || !IsDefined( [[level.overrideMethods[level.commonFunctions.getTeamBased]]]() ) ) { continue; } @@ -85,13 +103,91 @@ OnPlayerConnect() teamToJoin = player GetTeamToJoin(); player [[level.overrideMethods[level.commonFunctions.changeTeam]]]( teamToJoin ); - player thread OnClientFirstSpawn(); - player thread OnClientJoinedTeam(); - player thread OnClientDisconnect(); + player thread OnPlayerFirstSpawn(); + player thread OnPlayerDisconnect(); } } -OnClientDisconnect() +PlayerSpawnEvents() +{ + self endon( level.eventTypes.disconnect ); + + clientData = self.pers[level.clientDataKey]; + + // this gives IW4MAdmin some time to register the player before making the request; + // although probably not necessary some users might have a slow database or poll rate + wait ( 2 ); + + if ( IsDefined( clientData.state ) && clientData.state == "complete" ) + { + return; + } + + self scripts\_integration_base::RequestClientBasicData(); + + self waittill( level.eventTypes.clientDataReceived, clientEvent ); + + if ( clientData.permissionLevel == "User" || clientData.permissionLevel == "Flagged" ) + { + return; + } + + self IPrintLnBold( "Welcome, your level is ^5" + clientData.permissionLevel ); + wait( 2.0 ); + self IPrintLnBold( "You were last seen ^5" + clientData.lastConnection ); +} + + +PlayerTrackingOnInterval() +{ + self endon( level.eventTypes.disconnect ); + + for ( ;; ) + { + wait ( 120 ); + if ( IsAlive( self ) ) + { + self SaveTrackingMetrics(); + } + } +} + +SaveTrackingMetrics() +{ + if ( !IsDefined( self.persistentClientId ) ) + { + return; + } + + scripts\_integration_base::LogDebug( "Saving tracking metrics for " + self.persistentClientId ); + + if ( !IsDefined( self.lastShotCount ) ) + { + self.lastShotCount = 0; + } + + currentShotCount = self [[level.overrideMethods["GetTotalShotsFired"]]](); + change = currentShotCount - self.lastShotCount; + self.lastShotCount = currentShotCount; + + scripts\_integration_base::LogDebug( "Total Shots Fired increased by " + change ); + + if ( !IsDefined( change ) ) + { + change = 0; + } + + if ( change == 0 ) + { + return; + } + + scripts\_integration_base::IncrementClientMeta( "TotalShotsFired", change, self.persistentClientId ); +} + +// #region team balance + +OnPlayerDisconnect() { level endon( level.eventTypes.gameEnd ); self endon( "disconnect_logic_end" ); @@ -106,7 +202,7 @@ OnClientDisconnect() } } -OnClientJoinedTeam() +OnPlayerJoinedTeam() { self endon( level.eventTypes.disconnect ); @@ -114,6 +210,14 @@ OnClientJoinedTeam() { self waittill( level.eventTypes.joinTeam ); + wait( 0.25 ); + LogPrint( GenerateJoinTeamString( false ) ); + + if ( GetDvarInt( level.commonKeys.autoBalance ) != 1 ) + { + continue; + } + if ( IsDefined( self.wasAutoBalanced ) && self.wasAutoBalanced ) { self.wasAutoBalanced = false; @@ -141,12 +245,34 @@ OnClientJoinedTeam() } } -OnClientFirstSpawn() +OnPlayerSpawned() +{ + self endon( level.eventTypes.disconnect ); + + for ( ;; ) + { + self waittill( level.eventTypes.spawned ); + self thread PlayerSpawnEvents(); + } +} + +OnPlayerJoinedSpectators() +{ + self endon( level.eventTypes.disconnect ); + + for( ;; ) + { + self waittill( level.eventTypes.joinSpec ); + LogPrint( GenerateJoinTeamString( true ) ); + } +} + +OnPlayerFirstSpawn() { self endon( level.eventTypes.disconnect ); timeoutResult = self [[level.overrideMethods[level.commonFunctions.waitTillAnyTimeout]]]( 30, level.eventTypes.spawned ); - if ( timeoutResult != "timeout" ) + if ( timeoutResult != level.eventBus.timeoutKey ) { return; } @@ -467,48 +593,6 @@ GetClientPerformanceOrDefault() return performance; } -GetPlayerFromClientNum( clientNum ) -{ - if ( clientNum < 0 ) - { - return undefined; - } - - for ( i = 0; i < level.players.size; i++ ) - { - if ( level.players[i] getEntityNumber() == clientNum ) - { - return level.players[i]; - } - } - - return undefined; -} - -OnPlayerJoinedTeam() -{ - self endon( "disconnect" ); - - for( ;; ) - { - self waittill( "joined_team" ); - // join spec and join team occur at the same moment - out of order logging would be problematic - wait( 0.25 ); - LogPrint( GenerateJoinTeamString( false ) ); - } -} - -OnPlayerJoinedSpectators() -{ - self endon( "disconnect" ); - - for( ;; ) - { - self waittill( "joined_spectators" ); - LogPrint( GenerateJoinTeamString( true ) ); - } -} - GenerateJoinTeamString( isSpectator ) { team = self.team; @@ -540,49 +624,4 @@ GenerateJoinTeamString( isSpectator ) return "JT;" + guid + ";" + self getEntityNumber() + ";" + team + ";" + self.name + "\n"; } -PlayerTrackingOnInterval() -{ - self endon( "disconnect" ); - - for ( ;; ) - { - wait ( 120 ); - if ( IsAlive( self ) ) - { - self SaveTrackingMetrics(); - } - } -} - -SaveTrackingMetrics() -{ - if ( !IsDefined( self.persistentClientId ) ) - { - return; - } - - scripts\_integration_base::LogDebug( "Saving tracking metrics for " + self.persistentClientId ); - - if ( !IsDefined( self.lastShotCount ) ) - { - self.lastShotCount = 0; - } - - currentShotCount = self [[level.overrideMethods["GetTotalShotsFired"]]](); - change = currentShotCount - self.lastShotCount; - self.lastShotCount = currentShotCount; - - scripts\_integration_base::LogDebug( "Total Shots Fired increased by " + change ); - - if ( !IsDefined( change ) ) - { - change = 0; - } - - if ( change == 0 ) - { - return; - } - - scripts\_integration_base::IncrementClientMeta( "TotalShotsFired", change, self.persistentClientId ); -} \ No newline at end of file +// #end region diff --git a/GameFiles/GameInterface/_integration_t5.gsc b/GameFiles/GameInterface/_integration_t5.gsc index 139847179..962da312e 100644 --- a/GameFiles/GameInterface/_integration_t5.gsc +++ b/GameFiles/GameInterface/_integration_t5.gsc @@ -8,49 +8,22 @@ Init() Setup() { level endon( "game_ended" ); + waittillframeend; - // it's possible that the notify type has not been defined yet so we have to hard code it - level waittill( "SharedFunctionsInitialized" ); + level waittill( level.notifyTypes.sharedFunctionsInitialized ); level.eventBus.gamename = "T5"; scripts\_integration_base::RegisterLogger( ::Log2Console ); - level.overrideMethods["GetTotalShotsFired"] = ::GetTotalShotsFired; - level.overrideMethods["SetDvarIfUninitialized"] = ::_SetDvarIfUninitialized; - level.overrideMethods["waittill_notify_or_timeout"] = ::_waittill_notify_or_timeout; - level.overrideMethods[level.commonFunctions.getXuid] = ::_GetXUID; + level.overrideMethods[level.commonFunctions.getTotalShotsFired] = ::GetTotalShotsFired; + level.overrideMethods[level.commonFunctions.setDvar] = ::SetDvarIfUninitializedWrapper; + level.overrideMethods[level.commonFunctions.waittillNotifyOrTimeout] = ::WaitillNotifyOrTimeoutWrapper; + level.overrideMethods[level.commonFunctions.isBot] = ::IsBotWrapper; + level.overrideMethods[level.commonFunctions.getXuid] = ::GetXuidWrapper; RegisterClientCommands(); - _SetDvarIfUninitialized( "sv_iw4madmin_autobalance", 0 ); - level notify( level.notifyTypes.gameFunctionsInitialized ); - - if ( GetDvarInt( "sv_iw4madmin_integration_enabled" ) != 1 ) - { - return; - } - - level thread OnPlayerConnect(); -} - -OnPlayerConnect() -{ - level endon ( "game_ended" ); - - for ( ;; ) - { - level waittill( "connected", player ); - - if ( scripts\_integration_base::_IsBot( player ) ) - { - // we don't want to track bots - continue; - } - - //player thread SetPersistentData(); - player thread WaitForClientEvents(); - } } RegisterClientCommands() @@ -68,39 +41,17 @@ RegisterClientCommands() scripts\_integration_base::AddClientCommand( "NoClip", false, ::NoClipImpl ); } -WaitForClientEvents() -{ - self endon( "disconnect" ); - - // example of requesting a meta value - lastServerMetaKey = "LastServerPlayed"; - // self scripts\_integration_base::RequestClientMeta( lastServerMetaKey ); - - for ( ;; ) - { - self waittill( level.eventTypes.localClientEvent, event ); - - scripts\_integration_base::LogDebug( "Received client event " + event.type ); - - if ( event.type == level.eventTypes.clientDataReceived && event.data[0] == lastServerMetaKey ) - { - clientData = self.pers[level.clientDataKey]; - lastServerPlayed = clientData.meta[lastServerMetaKey]; - } - } -} - GetTotalShotsFired() { return maps\mp\gametypes\_persistence::statGet( "total_shots" ); } -_SetDvarIfUninitialized(dvar, value) +SetDvarIfUninitializedWrapper( dvar, value ) { - maps\mp\_utility::set_dvar_if_unset(dvar, value); + maps\mp\_utility::set_dvar_if_unset( dvar, value ); } -_waittill_notify_or_timeout( msg, timer ) +WaitillNotifyOrTimeoutWrapper( msg, timer ) { self endon( msg ); wait( timer ); @@ -113,7 +64,6 @@ Log2Console( logLevel, message ) God() { - if ( !IsDefined( self.godmode ) ) { self.godmode = false; @@ -131,142 +81,16 @@ God() } } -_GetXUID() +IsBotWrapper( client ) +{ + return client maps\mp\_utility::is_bot(); +} + +GetXuidWrapper() { return self GetXUID(); } -////////////////////////////////// -// GUID helpers -///////////////////////////////// - -/*SetPersistentData() -{ - self endon( "disconnect" ); - - guidHigh = self GetPlayerData( "bests", "none" ); - guidLow = self GetPlayerData( "awards", "none" ); - persistentGuid = guidHigh + "," + guidLow; - guidIsStored = guidHigh != 0 && guidLow != 0; - - if ( guidIsStored ) - { - // give IW4MAdmin time to collect IP - wait( 15 ); - scripts\_integration_base::LogDebug( "Uploading persistent guid " + persistentGuid ); - scripts\_integration_base::SetClientMeta( "PersistentClientGuid", persistentGuid ); - return; - } - - guid = self SplitGuid(); - - scripts\_integration_base::LogDebug( "Persisting client guid " + guidHigh + "," + guidLow ); - - self SetPlayerData( "bests", "none", guid["high"] ); - self SetPlayerData( "awards", "none", guid["low"] ); -} - -SplitGuid() -{ - guid = self GetGuid(); - - if ( isDefined( self.guid ) ) - { - guid = self.guid; - } - - firstPart = 0; - secondPart = 0; - stringLength = 17; - firstPartExp = 0; - secondPartExp = 0; - - for ( i = stringLength - 1; i > 0; i-- ) - { - char = GetSubStr( guid, i - 1, i ); - if ( char == "" ) - { - char = "0"; - } - - if ( i > stringLength / 2 ) - { - value = GetIntForHexChar( char ); - power = Pow( 16, secondPartExp ); - secondPart = secondPart + ( value * power ); - secondPartExp++; - } - else - { - value = GetIntForHexChar( char ); - power = Pow( 16, firstPartExp ); - firstPart = firstPart + ( value * power ); - firstPartExp++; - } - } - - split = []; - split["low"] = int( secondPart ); - split["high"] = int( firstPart ); - - return split; -} - -Pow( num, exponent ) -{ - result = 1; - while( exponent != 0 ) - { - result = result * num; - exponent--; - } - - return result; -} - -GetIntForHexChar( char ) -{ - char = ToLower( char ); - // generated by co-pilot because I can't be bothered to make it more "elegant" - switch( char ) - { - case "0": - return 0; - case "1": - return 1; - case "2": - return 2; - case "3": - return 3; - case "4": - return 4; - case "5": - return 5; - case "6": - return 6; - case "7": - return 7; - case "8": - return 8; - case "9": - return 9; - case "a": - return 10; - case "b": - return 11; - case "c": - return 12; - case "d": - return 13; - case "e": - return 14; - case "f": - return 15; - default: - return 0; - } -}*/ - ////////////////////////////////// // Command Implementations ///////////////////////////////// diff --git a/GameFiles/GameInterface/_integration_t5zm.gsc b/GameFiles/GameInterface/_integration_t5zm.gsc index d01e9dc28..e7d461e96 100644 --- a/GameFiles/GameInterface/_integration_t5zm.gsc +++ b/GameFiles/GameInterface/_integration_t5zm.gsc @@ -9,48 +9,21 @@ Setup() { level endon( "game_ended" ); - // it's possible that the notify type has not been defined yet so we have to hard code it - level waittill( "SharedFunctionsInitialized" ); + level waittill( level.notifyTypes.sharedFunctionsInitialized ); level.eventBus.gamename = "T5"; scripts\_integration_base::RegisterLogger( ::Log2Console ); - level.overrideMethods["GetTotalShotsFired"] = ::GetTotalShotsFired; - level.overrideMethods["SetDvarIfUninitialized"] = ::_SetDvarIfUninitialized; - level.overrideMethods["waittill_notify_or_timeout"] = ::_waittill_notify_or_timeout; - level.overrideMethods["GetPlayerFromClientNum"] = ::_GetPlayerFromClientNum; + level.overrideMethods[level.commonFunctions.getTotalShotsFired] = ::GetTotalShotsFired; + level.overrideMethods[level.commonFunctions.setDvar] = ::SetDvarIfUninitializedWrapper; + level.overrideMethods[level.commonFunctions.waittillNotifyOrTimeout] = ::WaitillNotifyOrTimeoutWrapper; + level.overrideMethods[level.commonFunctions.isBot] = ::IsBotWrapper; + level.overrideMethods[level.commonFunctions.getXuid] = ::GetXuidWrapper; + level.overrideMethods[level.commonFunction.getPlayerFromClientNum] = ::_GetPlayerFromClientNum; RegisterClientCommands(); - _SetDvarIfUninitialized( "sv_iw4madmin_autobalance", 0 ); - level notify( level.notifyTypes.gameFunctionsInitialized ); - - if ( GetDvarInt( "sv_iw4madmin_integration_enabled" ) != 1 ) - { - return; - } - - level thread OnPlayerConnect(); -} - -OnPlayerConnect() -{ - level endon ( "game_ended" ); - - for ( ;; ) - { - level waittill( "connected", player ); - - if ( scripts\_integration_base::_IsBot( player ) ) - { - // we don't want to track bots - continue; - } - - //player thread SetPersistentData(); - player thread WaitForClientEvents(); - } } RegisterClientCommands() @@ -68,45 +41,23 @@ RegisterClientCommands() scripts\_integration_base::AddClientCommand( "NoClip", false, ::NoClipImpl ); } -WaitForClientEvents() -{ - self endon( "disconnect" ); - - // example of requesting a meta value - lastServerMetaKey = "LastServerPlayed"; - // self scripts\_integration_base::RequestClientMeta( lastServerMetaKey ); - - for ( ;; ) - { - self waittill( level.eventTypes.localClientEvent, event ); - - scripts\_integration_base::LogDebug( "Received client event " + event.type ); - - if ( event.type == level.eventTypes.clientDataReceived && event.data[0] == lastServerMetaKey ) - { - clientData = self.pers[level.clientDataKey]; - lastServerPlayed = clientData.meta[lastServerMetaKey]; - } - } -} - GetTotalShotsFired() { return 0; //ZM has no shot tracking. TODO: add tracking function for event weapon_fired } -_SetDvarIfUninitialized(dvar, value) +SetDvarIfUninitializedWrapper( dvar, value ) { - if (GetDvar(dvar)=="" ) + if ( GetDvar( dvar ) == "" ) { - SetDvar(dvar, value); + SetDvar( dvar, value ); return value; } - return GetDvar(dvar); + return GetDvar( dvar ); } -_waittill_notify_or_timeout( msg, timer ) +WaitillNotifyOrTimeoutWrapper( msg, timer ) { self endon( msg ); wait( timer ); @@ -119,7 +70,6 @@ Log2Console( logLevel, message ) God() { - if ( !IsDefined( self.godmode ) ) { self.godmode = false; @@ -137,6 +87,16 @@ God() } } +IsBotWrapper( client ) +{ + return ( IsDefined ( client.pers["isBot"] ) && client.pers["isBot"] != 0 ); +} + +GetXuidWrapper() +{ + return self GetXUID(); +} + _GetPlayerFromClientNum( clientNum ) { if ( clientNum < 0 ) @@ -148,7 +108,8 @@ _GetPlayerFromClientNum( clientNum ) for ( i = 0; i < players.size; i++ ) { - scripts\_integration_base::LogDebug(i+"/"+players.size+ "=" + players[i].name); + scripts\_integration_base::LogDebug( i+"/"+players.size+ "=" + players[i].name ); + if ( players[i] getEntityNumber() == clientNum ) { return players[i]; @@ -158,137 +119,6 @@ _GetPlayerFromClientNum( clientNum ) return undefined; } -////////////////////////////////// -// GUID helpers -///////////////////////////////// - -/*SetPersistentData() -{ - self endon( "disconnect" ); - - guidHigh = self GetPlayerData( "bests", "none" ); - guidLow = self GetPlayerData( "awards", "none" ); - persistentGuid = guidHigh + "," + guidLow; - guidIsStored = guidHigh != 0 && guidLow != 0; - - if ( guidIsStored ) - { - // give IW4MAdmin time to collect IP - wait( 15 ); - scripts\_integration_base::LogDebug( "Uploading persistent guid " + persistentGuid ); - scripts\_integration_base::SetClientMeta( "PersistentClientGuid", persistentGuid ); - return; - } - - guid = self SplitGuid(); - - scripts\_integration_base::LogDebug( "Persisting client guid " + guidHigh + "," + guidLow ); - - self SetPlayerData( "bests", "none", guid["high"] ); - self SetPlayerData( "awards", "none", guid["low"] ); -} - -SplitGuid() -{ - guid = self GetGuid(); - - if ( isDefined( self.guid ) ) - { - guid = self.guid; - } - - firstPart = 0; - secondPart = 0; - stringLength = 17; - firstPartExp = 0; - secondPartExp = 0; - - for ( i = stringLength - 1; i > 0; i-- ) - { - char = GetSubStr( guid, i - 1, i ); - if ( char == "" ) - { - char = "0"; - } - - if ( i > stringLength / 2 ) - { - value = GetIntForHexChar( char ); - power = Pow( 16, secondPartExp ); - secondPart = secondPart + ( value * power ); - secondPartExp++; - } - else - { - value = GetIntForHexChar( char ); - power = Pow( 16, firstPartExp ); - firstPart = firstPart + ( value * power ); - firstPartExp++; - } - } - - split = []; - split["low"] = int( secondPart ); - split["high"] = int( firstPart ); - - return split; -} - -Pow( num, exponent ) -{ - result = 1; - while( exponent != 0 ) - { - result = result * num; - exponent--; - } - - return result; -} - -GetIntForHexChar( char ) -{ - char = ToLower( char ); - // generated by co-pilot because I can't be bothered to make it more "elegant" - switch( char ) - { - case "0": - return 0; - case "1": - return 1; - case "2": - return 2; - case "3": - return 3; - case "4": - return 4; - case "5": - return 5; - case "6": - return 6; - case "7": - return 7; - case "8": - return 8; - case "9": - return 9; - case "a": - return 10; - case "b": - return 11; - case "c": - return 12; - case "d": - return 13; - case "e": - return 14; - case "f": - return 15; - default: - return 0; - } -}*/ - ////////////////////////////////// // Command Implementations ///////////////////////////////// @@ -472,7 +302,7 @@ HideImpl( event, data ) AlertImpl( event, data ) { //self thread maps\mp\gametypes\_hud_message::oldNotifyMessage( data["alertType"], data["message"], undefined, ( 1, 0, 0 ), "mpl_sab_ui_suitcasebomb_timer", 7.5 ); - self IPrintLnBold(data["message"]); + self IPrintLnBold( data["message"] ); return "Sent alert to " + self.name; } diff --git a/GameFiles/GameInterface/_integration_t6.gsc b/GameFiles/GameInterface/_integration_t6.gsc index 07b67b649..3c5d578b1 100644 --- a/GameFiles/GameInterface/_integration_t6.gsc +++ b/GameFiles/GameInterface/_integration_t6.gsc @@ -9,49 +9,22 @@ Init() Setup() { level endon( "game_ended" ); + waittillframeend; - // it's possible that the notify type has not been defined yet so we have to hard code it - level waittill( "SharedFunctionsInitialized" ); + level waittill( level.notifyTypes.sharedFunctionsInitialized ); level.eventBus.gamename = "T6"; scripts\_integration_base::RegisterLogger( ::Log2Console ); - level.overrideMethods["GetTotalShotsFired"] = ::GetTotalShotsFired; - level.overrideMethods["SetDvarIfUninitialized"] = ::_SetDvarIfUninitialized; - level.overrideMethods["waittill_notify_or_timeout"] = ::_waittill_notify_or_timeout; - level.overrideMethods[level.commonFunctions.getXuid] = ::_GetXUID; + level.overrideMethods[level.commonFunctions.getTotalShotsFired] = ::GetTotalShotsFired; + level.overrideMethods[level.commonFunctions.setDvar] = ::SetDvarIfUninitializedWrapper; + level.overrideMethods[level.commonFunctions.waittillNotifyOrTimeout] = ::WaitillNotifyOrTimeoutWrapper; + level.overrideMethods[level.commonFunctions.isBot] = ::IsBotWrapper; + level.overrideMethods[level.commonFunctions.getXuid] = ::GetXuidWrapper; RegisterClientCommands(); - - _SetDvarIfUninitialized( "sv_iw4madmin_autobalance", 0 ); - + level notify( level.notifyTypes.gameFunctionsInitialized ); - - if ( GetDvarInt( "sv_iw4madmin_integration_enabled" ) != 1 ) - { - return; - } - - level thread OnPlayerConnect(); -} - -OnPlayerConnect() -{ - level endon ( "game_ended" ); - - for ( ;; ) - { - level waittill( "connected", player ); - - if ( scripts\_integration_base::_IsBot( player ) ) - { - // we don't want to track bots - continue; - } - - //player thread SetPersistentData(); - player thread WaitForClientEvents(); - } } RegisterClientCommands() @@ -69,39 +42,17 @@ RegisterClientCommands() scripts\_integration_base::AddClientCommand( "NoClip", false, ::NoClipImpl ); } -WaitForClientEvents() -{ - self endon( "disconnect" ); - - // example of requesting a meta value - lastServerMetaKey = "LastServerPlayed"; - // self scripts\_integration_base::RequestClientMeta( lastServerMetaKey ); - - for ( ;; ) - { - self waittill( level.eventTypes.localClientEvent, event ); - - scripts\_integration_base::LogDebug( "Received client event " + event.type ); - - if ( event.type == level.eventTypes.clientDataReceived && event.data[0] == lastServerMetaKey ) - { - clientData = self.pers[level.clientDataKey]; - lastServerPlayed = clientData.meta[lastServerMetaKey]; - } - } -} - GetTotalShotsFired() { - return self.pers[ "total_shots" ]; + return self.pers["total_shots"]; } -_SetDvarIfUninitialized(dvar, value) +SetDvarIfUninitializedWrapper( dvar, value ) { - maps\mp\_utility::set_dvar_if_unset(dvar, value); + maps\mp\_utility::set_dvar_if_unset( dvar, value ); } -_waittill_notify_or_timeout( msg, timer ) +WaitillNotifyOrTimeoutWrapper( msg, timer ) { self endon( msg ); wait( timer ); @@ -114,7 +65,6 @@ Log2Console( logLevel, message ) God() { - if ( !IsDefined( self.godmode ) ) { self.godmode = false; @@ -132,142 +82,16 @@ God() } } -_GetXUID() +IsBotWrapper( client ) +{ + return client maps\mp\_utility::is_bot(); +} + +GetXuidWrapper() { return self GetXUID(); } -////////////////////////////////// -// GUID helpers -///////////////////////////////// - -/*SetPersistentData() -{ - self endon( "disconnect" ); - - guidHigh = self GetPlayerData( "bests", "none" ); - guidLow = self GetPlayerData( "awards", "none" ); - persistentGuid = guidHigh + "," + guidLow; - guidIsStored = guidHigh != 0 && guidLow != 0; - - if ( guidIsStored ) - { - // give IW4MAdmin time to collect IP - wait( 15 ); - scripts\_integration_base::LogDebug( "Uploading persistent guid " + persistentGuid ); - scripts\_integration_base::SetClientMeta( "PersistentClientGuid", persistentGuid ); - return; - } - - guid = self SplitGuid(); - - scripts\_integration_base::LogDebug( "Persisting client guid " + guidHigh + "," + guidLow ); - - self SetPlayerData( "bests", "none", guid["high"] ); - self SetPlayerData( "awards", "none", guid["low"] ); -} - -SplitGuid() -{ - guid = self GetGuid(); - - if ( isDefined( self.guid ) ) - { - guid = self.guid; - } - - firstPart = 0; - secondPart = 0; - stringLength = 17; - firstPartExp = 0; - secondPartExp = 0; - - for ( i = stringLength - 1; i > 0; i-- ) - { - char = GetSubStr( guid, i - 1, i ); - if ( char == "" ) - { - char = "0"; - } - - if ( i > stringLength / 2 ) - { - value = GetIntForHexChar( char ); - power = Pow( 16, secondPartExp ); - secondPart = secondPart + ( value * power ); - secondPartExp++; - } - else - { - value = GetIntForHexChar( char ); - power = Pow( 16, firstPartExp ); - firstPart = firstPart + ( value * power ); - firstPartExp++; - } - } - - split = []; - split["low"] = int( secondPart ); - split["high"] = int( firstPart ); - - return split; -} - -Pow( num, exponent ) -{ - result = 1; - while( exponent != 0 ) - { - result = result * num; - exponent--; - } - - return result; -} - -GetIntForHexChar( char ) -{ - char = ToLower( char ); - // generated by co-pilot because I can't be bothered to make it more "elegant" - switch( char ) - { - case "0": - return 0; - case "1": - return 1; - case "2": - return 2; - case "3": - return 3; - case "4": - return 4; - case "5": - return 5; - case "6": - return 6; - case "7": - return 7; - case "8": - return 8; - case "9": - return 9; - case "a": - return 10; - case "b": - return 11; - case "c": - return 12; - case "d": - return 13; - case "e": - return 14; - case "f": - return 15; - default: - return 0; - } -}*/ - ////////////////////////////////// // Command Implementations ///////////////////////////////// @@ -456,17 +280,7 @@ HideImpl( event, data ) AlertImpl( event, data ) { - /*if ( !sessionmodeiszombiesgame() ) - {*/ - self thread oldNotifyMessage( data["alertType"], data["message"], undefined, ( 1, 0, 0 ), "mpl_sab_ui_suitcasebomb_timer", 7.5 ); - /*} - else - { - self IPrintLnBold( data["alertType"] ); - self IPrintLnBold( data["message"] ); - }*/ - - + self thread oldNotifyMessage( data["alertType"], data["message"], undefined, ( 1, 0, 0 ), "mpl_sab_ui_suitcasebomb_timer", 7.5 ); return "Sent alert to " + self.name; } @@ -550,7 +364,7 @@ SetSpectatorImpl( event, data ) ///////////////////////////////// /* -1:1 the same on MP and ZM but in different includes. Since we probably want to be able to send Alerts on non teambased wagermatechs use our own copy. +1:1 the same on MP and ZM but in different includes. Since we probably want to be able to send Alerts on non teambased wagermatches use our own copy. */ oldnotifymessage( titletext, notifytext, iconname, glowcolor, sound, duration ) { @@ -567,5 +381,3 @@ oldnotifymessage( titletext, notifytext, iconname, glowcolor, sound, duration ) self.startmessagenotifyqueue[ self.startmessagenotifyqueue.size ] = notifydata; self notify( "received award" ); } - - diff --git a/GameFiles/GameInterface/_integration_t6zm_helper.gsc b/GameFiles/GameInterface/_integration_t6zm_helper.gsc index 69a26dbda..22ea47eec 100644 --- a/GameFiles/GameInterface/_integration_t6zm_helper.gsc +++ b/GameFiles/GameInterface/_integration_t6zm_helper.gsc @@ -1,45 +1,48 @@ -init() +Init() { - level.startmessagedefaultduration = 2; level.regulargamemessages = spawnstruct(); level.regulargamemessages.waittime = 6; - - level thread onplayerconnect(); + thread OnPlayerConnect(); } -onplayerconnect() +OnPlayerConnect() { for ( ;; ) { level waittill( "connecting", player ); - player thread displaypopupswaiter(); + player thread DisplaypopupsWaiter()(); } } -displaypopupswaiter() +DisplaypopupsWaiter() { self endon( "disconnect" ); self.ranknotifyqueue = []; - if ( !isDefined( self.pers[ "challengeNotifyQueue" ] ) ) + + if ( !IsDefined( self.pers[ "challengeNotifyQueue" ] ) ) { self.pers[ "challengeNotifyQueue" ] = []; } - if ( !isDefined( self.pers[ "contractNotifyQueue" ] ) ) + if ( !IsDefined( self.pers[ "contractNotifyQueue" ] ) ) { self.pers[ "contractNotifyQueue" ] = []; } + self.messagenotifyqueue = []; self.startmessagenotifyqueue = []; self.wagernotifyqueue = []; + while ( !level.gameended ) { if ( self.startmessagenotifyqueue.size == 0 && self.messagenotifyqueue.size == 0 ) { self waittill( "received award" ); } + waittillframeend; + if ( level.gameended ) { return; @@ -50,7 +53,7 @@ displaypopupswaiter() { nextnotifydata = self.startmessagenotifyqueue[ 0 ]; arrayremoveindex( self.startmessagenotifyqueue, 0, 0 ); - if ( isDefined( nextnotifydata.duration ) ) + if ( IsDefined( nextnotifydata.duration ) ) { duration = nextnotifydata.duration; } @@ -58,15 +61,18 @@ displaypopupswaiter() { duration = level.startmessagedefaultduration; } + self maps\mp\gametypes_zm\_hud_message::shownotifymessage( nextnotifydata, duration ); - wait duration; + wait ( duration ); + continue; } else if ( self.messagenotifyqueue.size > 0 ) { nextnotifydata = self.messagenotifyqueue[ 0 ]; arrayremoveindex( self.messagenotifyqueue, 0, 0 ); - if ( isDefined( nextnotifydata.duration ) ) + + if ( IsDefined( nextnotifydata.duration ) ) { duration = nextnotifydata.duration; } @@ -74,13 +80,14 @@ displaypopupswaiter() { duration = level.regulargamemessages.waittime; } + self maps\mp\gametypes_zm\_hud_message::shownotifymessage( nextnotifydata, duration ); continue; } else { - wait 1; + wait ( 1 ); } } } -} \ No newline at end of file +}