diff --git a/Application/IW4MServer.cs b/Application/IW4MServer.cs index 5abcdc502..1993137a9 100644 --- a/Application/IW4MServer.cs +++ b/Application/IW4MServer.cs @@ -9,6 +9,7 @@ using SharedLibraryCore.Interfaces; using System; using System.Collections.Generic; +using System.Globalization; using System.IO; using System.Linq; using System.Net; @@ -771,17 +772,28 @@ await Manager.GetPenaltyService().RemoveActivePenalties(E.Target.AliasLinkId, E. else if (E.Type == GameEvent.EventType.MetaUpdated) { - if (E.Extra is "PersistentStatClientId" && int.TryParse(E.Data, out var persistentClientId)) + if (E.Extra is "PersistentClientGuid") { - var penalties = await Manager.GetPenaltyService().GetActivePenaltiesByClientId(persistentClientId); - var banPenalty = penalties.FirstOrDefault(penalty => penalty.Type == EFPenalty.PenaltyType.Ban); + var parts = E.Data.Split(","); - if (banPenalty is not null && E.Origin.Level != Permission.Banned) + if (parts.Length == 2 && int.TryParse(parts[0], out var high) && + int.TryParse(parts[1], out var low)) { - ServerLogger.LogInformation( - "Banning {Client} as they have have provided a persistent clientId of {PersistentClientId}, which is banned", - E.Origin.ToString(), persistentClientId); - E.Origin.Ban(loc["SERVER_BAN_EVADE"].FormatExt(persistentClientId), Utilities.IW4MAdminClient(this), true); + var guid = long.Parse(high.ToString("X") + low.ToString("X"), NumberStyles.HexNumber); + + var penalties = await Manager.GetPenaltyService() + .GetActivePenaltiesByIdentifier(null, guid, (Reference.Game)GameName); + var banPenalty = + penalties.FirstOrDefault(penalty => penalty.Type == EFPenalty.PenaltyType.Ban); + + if (banPenalty is not null && E.Origin.Level != Permission.Banned) + { + ServerLogger.LogInformation( + "Banning {Client} as they have have provided a persistent clientId of {PersistentClientId}, which is banned", + E.Origin.ToString(), guid); + E.Origin.Ban(loc["SERVER_BAN_EVADE"].FormatExt(guid), + Utilities.IW4MAdminClient(this), true); + } } } } @@ -1289,28 +1301,17 @@ await this.SetDvarAsync("sv_sayname", Manager.GetApplicationSettings().Configura this.GamePassword = gamePassword.Value; UpdateMap(mapname); - if (RconParser.CanGenerateLogPath) + if (RconParser.CanGenerateLogPath && string.IsNullOrEmpty(ServerConfig.ManualLogPath)) { - bool needsRestart = false; - if (logsync.Value == 0) { await this.SetDvarAsync("g_logsync", 2, Manager.CancellationToken); // set to 2 for continous in other games, clamps to 1 for IW4 - needsRestart = true; } if (string.IsNullOrWhiteSpace(logfile.Value)) { logfile.Value = "games_mp.log"; await this.SetDvarAsync("g_log", logfile.Value, Manager.CancellationToken); - needsRestart = true; - } - - if (needsRestart) - { - // disabling this for the time being - /*Logger.WriteWarning("Game log file not properly initialized, restarting map..."); - await this.ExecuteCommandAsync("map_restart");*/ } // this DVAR isn't set until the a map is loaded diff --git a/GameFiles/_integration.gsc b/GameFiles/_integration.gsc index f4b382fd5..9bb55c292 100644 --- a/GameFiles/_integration.gsc +++ b/GameFiles/_integration.gsc @@ -59,7 +59,7 @@ init() OnPlayerConnect() { - level endon ( "disconnect" ); + level endon ( "game_ended" ); for ( ;; ) { @@ -67,7 +67,7 @@ OnPlayerConnect() level.iw4adminIntegrationDebug = GetDvarInt( "sv_iw4madmin_integration_debug" ); - if ( isDefined(player.pers["isBot"]) && player.pers["isBot"] ) + if ( isDefined( player.pers["isBot"] ) && player.pers["isBot"] ) { // we don't want to track bots continue; @@ -104,7 +104,7 @@ OnPlayerSpawned() OnPlayerDisconnect() { - level endon ( "disconnect" ); + self endon ( "disconnect" ); for ( ;; ) { @@ -139,8 +139,6 @@ OnPlayerJoinedSpectators() OnGameEnded() { - level endon ( "disconnect" ); - for ( ;; ) { level waittill( "game_ended" ); @@ -167,24 +165,29 @@ DisplayWelcomeData() SetPersistentData() { - storedClientId = self GetPlayerData( "bests", "none" ); + guidHigh = self GetPlayerData( "bests", "none" ); + guidLow = self GetPlayerData( "awards", "none" ); + persistentGuid = guidHigh + "," + guidLow; - if ( storedClientId != 0 ) + if ( guidHigh != 0 && guidLow != 0) { if ( level.iw4adminIntegrationDebug == 1 ) { - IPrintLn( "Uploading persistent client id " + storedClientId ); + IPrintLn( "Uploading persistent guid " + persistentGuid ); } - SetClientMeta( "PersistentStatClientId", storedClientId ); + SetClientMeta( "PersistentClientGuid", persistentGuid ); } if ( level.iw4adminIntegrationDebug == 1 ) { - IPrintLn( "Persisting client id " + self.persistentClientId ); + IPrintLn( "Persisting client guid " + persistentGuid ); } - self SetPlayerData( "bests", "none", int( self.persistentClientId ) ); + guid = self SplitGuid(); + + self SetPlayerData( "bests", "none", guid["high"] ); + self SetPlayerData( "awards", "none", guid["low"] ); } PlayerConnectEvents() @@ -228,8 +231,7 @@ PlayerTrackingOnInterval() MonitorClientEvents() { - level endon( "disconnect" ); - self endon( "disconnect" ); + level endon( "game_ended" ); for ( ;; ) { @@ -324,6 +326,107 @@ DecrementClientMeta( metaKey, decrementValue, clientId ) SetClientMeta( metaKey, decrementValue, clientId, "decrement" ); } +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; + } +} + GenerateJoinTeamString( isSpectator ) { team = self.team; @@ -476,7 +579,7 @@ MonitorBus() QueueEvent( request, eventType, notifyEntity ) { - level endon( "disconnect" ); + level endon( "game_ended" ); start = GetTime(); maxWait = level.eventBus.timeout * 1000; // 30 seconds @@ -510,6 +613,8 @@ QueueEvent( request, eventType, notifyEntity ) { notifyEntity NotifyClientEventTimeout( eventType ); } + + SetDvar( level.eventBus.inVar, "" ); return; } @@ -923,7 +1028,7 @@ GotoCoordImpl( data ) return; } - position = ( int(data["x"]), int(data["y"]), int(data["z"]) ); + position = ( int( data["x"] ), int( data["y"] ), int( data["z"]) ); self SetOrigin( position ); self IPrintLnBold( "Moved to " + "("+ position[0] + "," + position[1] + "," + position[2] + ")" ); }