Áƒ*žE…H›x;vï´.Ð=½êB¼–3Ó+x—"›„›…NoneSendQueryPacketUdpServerUplink GetItemName GetRules ParseQueryParseNextQueryGetInfo SendAPacket SendPlayers SendText GetBasic GetPlayerEngine MasterUplinkCoreTimer IpServer BindPort ReceivedTextSystemIpDrvGetPlayerProperty ValidateResumeGetLevelPropertyUdpServerQueryGetServerPortGetGameProperty PreBeginPlayHaltMasterServerPortPostBeginPlayUpdateMinutes QueryNameResolve ResolvedConsoleCommandResolveFailed PlayerPawn GetMultiSkin GameNameTargetQueryName ServerNameTeam MaxPlayersLevelActor SkinNameResultP NumPlayers AdminEmail PlayerNameScorebIsABotGameRegion nextPawnEngineVersionMinNetVersion PawnList ResultSetTextSkinPawn AdminNameReceivedSecretChecksumGameReplicationInfoTitleUdpLink InternetLink UdpBeaconTagClassPlayerReplicationInfoiIpAddr ScriptTextPortAddrValidationStringUdpServerQueryPort boundportQueryMasterServerAddressMasterServerIpAddr MinNetVerPackage TextBufferObject ReturnValueCurrentQueryNum ReplyDataOldQueryPortNumberbRestartServerOnPortSwapBeaconQueryRemaining QueryNum PacketNum Function QueryType QueryValue QueryRest bFinalPacket TempQuery ClosingSlashStruct StrPropertyStructProperty SendStringClassProperty bRecieved NameProperty PlayerNumObjectProperty SendResultFloatPropertyProp BoolProperty IntProperty ByteProperty DoUplinkGetPropertyText GameInfo MenuNameHeartbeatMessage UplinkPort LevelInfo FaceName FinalPacket QueryStrNoneD@DDJ@DDDDb€DD€DD{€DDDDW€DD€@DD€@DD€DŽD@DD@DD@DDA€@DDL€@DD(D•VDÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿQš»Ôñ•6…Ž’íu[ƒŽ”ˆ@1CƒŽ”ƒŽ”ƒŽ”ˆ@1C“žtȃŽ”ˆ@1C“žtÈŽ’íu[”{#U¿Ž’íu[”{#U¿Ž’íu[Ž’íu[”{#U¿Ž’íu[Ž’íu[Ž’íu[Ž’íu[Ž’íu[”{#U¿Ž’íu[ƒŽ”ˆ@1CƒŽ”ˆ@1CZƒŽ”ˆ@1CZƒŽ”ˆ@1CZƒŽ”ˆ@1CZƒŽ”ˆ@1CZƒŽ”ˆ@1CƒŽ”ƒŽ”ˆ@1CƒŽ”ˆ@1CƒŽ”ˆ@1CƒŽ”ˆ@1CƒŽ”ˆ@1CƒŽ”ˆ@1CƒŽ”ˆ@1CƒŽ”ƒŽ”ƒŽ”ƒŽ”ƒŽ”ˆ@1CƒŽ”ƒŽ”ƒŽ”ƒŽ”ƒŽ”ˆ@1CZƒŽ”ˆ@1CƒŽ”ˆ@1C›™N5ƒŽ”ˆ@1C ’")-utDDD“D=@DD.@DDDDDD@DDDD'DD/€@DD0DD2€@DDDDU€@DD @DDDg@@DHDDFDD#@DD"@DDGDD1DDDDDD DD;@DD<@DDDDX@DD€@DD@DDDD€@DDDDP€DDD@DD7€DD8€DDz€DDDŽDDD9DD5@DDQ@DD@€@DD@DDD›DE€@DDI€@DD@DD&@DDP€@DDIDD@DDaDDDDK@DD@DDA€DDN€DDO€DDS€DD6€@DD@DDDD[€DDj€DDT€DD€DD*D@DDM€DDY€DDZ€@DD[€DD@DD_€DD$€@DD@DDDD€@DD%€@DDe@D!@Dc€DDh@Di@DDZ€@DDv€DDk€DDl€DDm€DDq€DD³ro$R B6Ÿ6Ÿodš6Ÿ%çUdpServerUplink: Invalid master server address, aborting. çpppUdpServerUplink: Master Server is !:S6§-’&š-'%çUdpServerUplink: Error binding port, aborting. çppUdpServerUplink: Port S- successfully bound. D-DD¤d$ÇG-dçDoUplink is not set. Not connecting to Master Server. /a0 i``10´r*çUdpServerUplink: Could not find a UdpServerQuery object, aborting. 6|!unreal.epicgames.com0ppppp\heartbeat\S\gamename\ \gamever\†™x0ppp\heartbeat\S\gamename\ 6§gºz!!ppmasterSh.gamespy.com#! D¸p&n" IçUdpServerUplink: Failed to resolve master server address, aborting. D·s:vÇ R-: 0P-:çFailed to send heartbeat to master server. D}näþx pppp \queryid\Sm.S£lPšk& p \final\-3 n  -3 D3€DDY„Äa?e,<' D¥wfל¥(—(,d(&H(%cGz%-"(O-"'š-"%f%Haz%-"(—-"'O Du4õ†-)'?—’} }Pè-)467% p P}š8&-)4678-) D)€DD €@DDy~ šp\gamename\ pp\gamever\†™š‚™J†œ˜J†™pp\minnetver\SÄpp\minnetver\†œpp\location\S†‹–¹ DBŸIÍ%-b =;-vz basic- Å°z info-Åëz rules-Åez players?—†‹—%- b-ÅKz status- %-%š†‹—%-H-%- ÅŽz echo-p\echo\Åíz secureQp\validate\ -QÅ6z level_property-Å~z game_property-ÅÅz player_property-= D€@DDx ©@gz (cz€ &\~ê “} &\Gš%(] ê “} &€ê “} ’},É„z š}&Afinal'ÛÛz€&\'~\ ™%2€2ê “} ’’}}2,^zAfinal'`'e( D+€@DD`€DDG iV [z (Wz€ &\~ê “} &\Gš%(` ê “} &€ê “} ’},Äz š}&L&'ÕÕz€&\'~\™%/€/ê “} ’’}}/,RzL&'T'Y( D|FF-(p\hostname\†‹–´pp\hostport\S†‹pp\maptitle\†µpp\mapname\€V†~V†.&|V†‹šSmartCTFGame-'pp\gametype\CTFGameXŽ|V†‹šEUTTeamGamePlus-'pp\gametype\TeamGamePlusXú|V†‹šEUTDeathMatchPlus-'pp\gametype\DeathMatchPlusXX|V†‹šLeagueAssault-'pp\gametype\Assaultœ-pp\gametype\V†‹špp\numplayers\S†‹—pp\maxplayers\S†‹¶p\gamemode\openplayingpp\gamever\†™«‚™J†œ˜J†™pp\minnetver\SÕpp\minnetver\†œp†‹ DK>Ûµ2`/a0 Ž9W¥;+pppppp+\>_S;\9  >10+ D]€DD€@DD¥N^NÆ«¥*—*,d*&F*$_Gz$-#(O-#'I% ©-#$^$FIžz$-#(¦-#'^ D\ßC¿-&[,<5G4-&Pz,basic-&'··z,secureDp\validate\< -&\DZ£YG5 D?€@DDCLmj'톋{†‹–¦pp\AdminName\†‹–¦å{†‹–¨pp\AdminEMail\†‹–¨ DUBϵ1<?ppp\B\†‹  B? D€@DD,€@DDªO@ ?p./a0 ›@%@»10ª D¤W'xÖ«W†‹'eš%çUdpServerQuery: Port failed to bind. çppUdpServerQuery(crt): Port S successfully bound.Ô-XÆ›.% 5š..b DC€@DDJ  )·ppp\player_S\ žºpppp\frags_S\SD ž¬pppp\ping_S\ %GETPINGpppp\team_S\R ž­pppp\mesh_S\ ®¥r £* ( JKpppp\skin_S\Jpppp\face_S\Kþpppp\skin_S\V £ppp\face_S\NoneE ž-¯ppp\ngsecret_S\bot¯„ -°ppp\ngsecret_S\true¯ppp\ngsecret_S\false DLj//============================================================================= // UdpServerUplink // // Version: 1.3 // // This uplink is compliant with the GameSpy Uplink Specification. // The specification is available at http://www.gamespy.com/developer // and might be of use to progammers who want to adapt their own // server uplinks. // // UdpServerUplink sends a heartbeat to the specified master server // every five minutes. The heartbeat is in the form: // \heartbeat\QueryPort\gamename\unreal // // Full documentation on this class is available at http://unreal.epicgames.com/ // //============================================================================= class UdpServerUplink extends UdpLink config; // Master Uplink Config. var() config bool DoUplink; // If true, do the uplink var() config int UpdateMinutes; // Period of update (in minutes) var() config string MasterServerAddress; // Address of the master server var() config int MasterServerPort; // Optional port that the master server is listening on var() config int Region; // Region of the game server var() name TargetQueryName; // Name of the query server object to use. var IpAddr MasterServerIpAddr; // Master server's address. var string HeartbeatMessage; // The message that is sent to the master server. var UdpServerQuery Query; // The query object. var int CurrentQueryNum; // Query ID Number. // Initialize. function PreBeginPlay() { // If master server uplink isn't wanted, exit. if( !DoUplink ) { Log("DoUplink is not set. Not connecting to Master Server."); return; } /* if( Level.NetMode == NM_ListenServer ) { Log("This is a Listen server. Not connecting to Master Server."); return; } */ // Find a the server query handler. foreach AllActors(class'UdpServerQuery', Query, TargetQueryName) break; if( Query==None ) { Log("UdpServerUplink: Could not find a UdpServerQuery object, aborting."); return; } // Set heartbeat message. if( MasterServerAddress ~= "unreal.epicgames.com" ) HeartbeatMessage = "\\heartbeat\\"$Query.Port$"\\gamename\\"$Query.GameName$"\\gamever\\"$Level.EngineVersion; else HeartbeatMessage = "\\heartbeat\\"$Query.Port$"\\gamename\\"$Query.GameName; // Set the Port. MasterServerIpAddr.Port = MasterServerPort; // Resolve the Address. if( MasterServerAddress=="" ) MasterServerAddress = "master"$Region$".gamespy.com"; Resolve( MasterServerAddress ); } // When master server address is resolved. function Resolved( IpAddr Addr ) { local bool Result; local int UplinkPort; // Set the address MasterServerIpAddr.Addr = Addr.Addr; // Handle failure. if( MasterServerIpAddr.Addr == 0 ) { Log("UdpServerUplink: Invalid master server address, aborting."); return; } // Display success message. Log("UdpServerUplink: Master Server is "$MasterServerAddress$":"$MasterServerIpAddr.Port); // Bind the local port. UplinkPort = Query.Port + 1; if( BindPort(UplinkPort, true) == 0 ) { Log( "UdpServerUplink: Error binding port, aborting." ); return; } Log("UdpServerUplink: Port "$UplinkPort$" successfully bound."); // Start transmitting. Resume(); } // Host resolution failue. function ResolveFailed() { Log("UdpServerUplink: Failed to resolve master server address, aborting."); } // Notify the MasterServer we exist. function Timer() { local bool Result; Result = SendText( MasterServerIpAddr, HeartbeatMessage ); if ( !Result ) Log( "Failed to send heartbeat to master server."); } // Stop the uplink. function Halt() { SetTimer(0.0, false); } // Resume the uplink. function Resume() { SetTimer(UpdateMinutes * 60, true); Timer(); } // Received a query request. event ReceivedText( IpAddr Addr, string Text ) { local string Query; local bool QueryRemaining; local int QueryNum, PacketNum; // Assign this packet a unique value from 1 to 100 CurrentQueryNum++; if (CurrentQueryNum > 100) CurrentQueryNum = 1; QueryNum = CurrentQueryNum; Query = Text; if (Query == "") // If the string is empty, don't parse it QueryRemaining = false; else QueryRemaining = true; while (QueryRemaining) { Query = ParseQuery(Addr, Query, QueryNum, PacketNum); if (Query == "") QueryRemaining = false; else QueryRemaining = true; } } function bool ParseNextQuery( string Query, out string QueryType, out string QueryValue, out string QueryRest, out string FinalPacket ) { local string TempQuery; local int ClosingSlash; if (Query == "") return false; // Query should be: // \[type]\ if (Left(Query, 1) == "\\") { // Check to see if closed. ClosingSlash = InStr(Right(Query, Len(Query)-1), "\\"); if (ClosingSlash == 0) return false; TempQuery = Query; // Query looks like: // \[type]\ QueryType = Right(Query, Len(Query)-1); QueryType = Left(QueryType, ClosingSlash); QueryRest = Right(Query, Len(Query) - (Len(QueryType) + 2)); if ((QueryRest == "") || (Len(QueryRest) == 1)) { FinalPacket = "final"; return true; } else if (Left(QueryRest, 1) == "\\") return true; // \type\\ // Query looks like: // \type\value ClosingSlash = InStr(QueryRest, "\\"); if (ClosingSlash >= 0) QueryValue = Left(QueryRest, ClosingSlash); else QueryValue = QueryRest; QueryRest = Right(Query, Len(Query) - (Len(QueryType) + Len(QueryValue) + 3)); if (QueryRest == "") { FinalPacket = "final"; return true; } else return true; } else { return false; } } function string ParseQuery( IpAddr Addr, coerce string QueryStr, int QueryNum, out int PacketNum ) { local string QueryType, QueryValue, QueryRest, ValidationString; local bool Result; local string FinalPacket; Result = ParseNextQuery(QueryStr, QueryType, QueryValue, QueryRest, FinalPacket); if( !Result ) return ""; if( QueryType=="basic" ) { // Ignore. Result = true; } else if( QueryType=="secure" ) { ValidationString = "\\validate\\"$Validate(QueryValue, Query.GameName); Result = SendQueryPacket(Addr, ValidationString, QueryNum, ++PacketNum, FinalPacket); } return QueryRest; } // SendQueryPacket is a wrapper for SendText that allows for packet numbering. function bool SendQueryPacket(IpAddr Addr, coerce string SendString, int QueryNum, int PacketNum, string FinalPacket) { local bool Result; if (FinalPacket == "final") { SendString = SendString$"\\final\\"; } SendString = SendString$"\\queryid\\"$QueryNum$"."$PacketNum; Result = SendText(Addr, SendString); return Result; } •RTÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ SO•ú=•6…š»Ôñš»Ôñš»Ôñš»ÔñƒŽ”š»Ôñš»Ôñ ’!""ül*DDHVô¿t'zjfinalp\final\pppp\queryid\SU.ST-R V-R DXEÅÝ03Cppp\E\†  EC DOÍ//============================================================================= // UdpServerQuery // // Version: 1.5 // // This query server is compliant with the GameSpy Uplink Specification. // The specification is available at http://www.gamespy.com/developer // and might be of use to progammers who are writing or maintaining // their own stat gathering/game querying software. // // Note: Currently, SendText returns false if successful. // // Full documentation on this class is available at http://unreal.epicgames.com/ // //============================================================================= class UdpServerQuery extends UdpLink config; // Game Server Config. var() name QueryName; // Name to set this object's Tag to. var int CurrentQueryNum; // Query ID Number. var globalconfig string GameName; //crt var string ReplyData; var globalconfig int MinNetVer; //!! Hack to prevent port swapping var globalconfig int OldQueryPortNumber; var globalconfig bool bRestartServerOnPortSwap; // Initialize. function PreBeginPlay() { local int boundport; // Set the Tag Tag = QueryName; // Bind the listen socket boundport = BindPort(Level.Game.GetServerPort(), true); if( boundport == 0 ) { Log("UdpServerQuery: Port failed to bind."); return; } Log("UdpServerQuery(crt): Port "$boundport$" successfully bound."); if( bRestartServerOnPortSwap ) { if( OldQueryPortNumber != 0 ) assert( OldQueryPortNumber == boundport ); OldQueryPortNumber = boundport; SaveConfig(); } } function PostBeginPlay() { local UdpBeacon Beacon; foreach AllActors(class'UdpBeacon', Beacon) { Beacon.UdpServerQueryPort = Port; } Super.PostBeginPlay(); } // Received a query request. event ReceivedText( IpAddr Addr, string Text ) { local string Query; local bool QueryRemaining; local int QueryNum, PacketNum; // Assign this packet a unique value from 1 to 100 CurrentQueryNum++; if (CurrentQueryNum > 100) CurrentQueryNum = 1; QueryNum = CurrentQueryNum; Query = Text; if (Query == "") // If the string is empty, don't parse it QueryRemaining = false; else QueryRemaining = true; //crt PacketNum = 0; ReplyData = ""; while (QueryRemaining) { Query = ParseQuery(Addr, Query, QueryNum, PacketNum); if (Query == "") QueryRemaining = false; else QueryRemaining = true; } } function bool ParseNextQuery( string Query, out string QueryType, out string QueryValue, out string QueryRest, out int bFinalPacket ) { local string TempQuery; local int ClosingSlash; if (Query == "") return false; // Query should be: // \[type]\ if (Left(Query, 1) == "\\") { // Check to see if closed. ClosingSlash = InStr(Right(Query, Len(Query)-1), "\\"); if (ClosingSlash == 0) return false; TempQuery = Query; // Query looks like: // \[type]\ QueryType = Right(Query, Len(Query)-1); QueryType = Left(QueryType, ClosingSlash); QueryRest = Right(Query, Len(Query) - (Len(QueryType) + 2)); if ((QueryRest == "") || (Len(QueryRest) == 1)) { bFinalPacket = 1; return true; } else if (Left(QueryRest, 1) == "\\") return true; // \type\\ // Query looks like: // \type\value ClosingSlash = InStr(QueryRest, "\\"); if (ClosingSlash >= 0) QueryValue = Left(QueryRest, ClosingSlash); else QueryValue = QueryRest; QueryRest = Right(Query, Len(Query) - (Len(QueryType) + Len(QueryValue) + 3)); if (QueryRest == "") { bFinalPacket = 1; return true; } else return true; } else { return false; } } function string ParseQuery( IpAddr Addr, coerce string Query, int QueryNum, out int PacketNum ) { local string QueryType, QueryValue, QueryRest, ValidationString; local bool Result; local int bFinalPacket; bFinalPacket = 0; Result = ParseNextQuery(Query, QueryType, QueryValue, QueryRest, bFinalPacket); if( !Result ) return ""; //Log("Got Query: " $ QueryNum $ "." $ PacketNum $ ":" $ QueryType); if( QueryType=="basic" ) { Result = SendQueryPacket(Addr, GetBasic(), QueryNum, PacketNum, bFinalPacket); } else if( QueryType=="info" ) { Result = SendQueryPacket(Addr, GetInfo(), QueryNum, PacketNum, bFinalPacket); } else if( QueryType=="rules" ) { Result = SendQueryPacket(Addr, GetRules(), QueryNum, PacketNum, bFinalPacket); } else if( QueryType=="players" ) { if( Level.Game.NumPlayers > 0 ) Result = SendPlayers(Addr, QueryNum, PacketNum, bFinalPacket); else Result = SendQueryPacket(Addr, "", QueryNum, PacketNum, bFinalPacket); } else if( QueryType=="status" ) { Result = SendQueryPacket(Addr, GetBasic(), QueryNum, PacketNum, 0); Result = SendQueryPacket(Addr, GetInfo(), QueryNum, PacketNum, 0); if( Level.Game.NumPlayers == 0 ) { Result = SendQueryPacket(Addr, GetRules(), QueryNum, PacketNum, bFinalPacket); } else { Result = SendQueryPacket(Addr, GetRules(), QueryNum, PacketNum, 0); Result = SendPlayers(Addr, QueryNum, PacketNum, bFinalPacket); } } else if( QueryType=="echo" ) { // Respond to an echo with the same string Result = SendQueryPacket(Addr, "\\echo\\"$QueryValue, QueryNum, PacketNum, bFinalPacket); } else if( QueryType=="secure" ) { ValidationString = "\\validate\\"$Validate(QueryValue, GameName); Result = SendQueryPacket(Addr, ValidationString, QueryNum, PacketNum, bFinalPacket); } else if( QueryType=="level_property" ) { Result = SendQueryPacket(Addr, GetLevelProperty(QueryValue), QueryNum, PacketNum, bFinalPacket); } else if( QueryType=="game_property" ) { Result = SendQueryPacket(Addr, GetGameProperty(QueryValue), QueryNum, PacketNum, bFinalPacket); } else if( QueryType=="player_property" ) { Result = SendQueryPacket(Addr, GetPlayerProperty(QueryValue), QueryNum, PacketNum, bFinalPacket); } return QueryRest; } function bool SendAPacket(IpAddr Addr, int QueryNum, out int PacketNum, int bFinalPacket) { local bool Result; ReplyData = ReplyData$"\\queryid\\"$QueryNum$"."$++PacketNum; if (bFinalPacket == 1) { ReplyData = ReplyData $ "\\final\\"; } Result = SendText(Addr, ReplyData); ReplyData = ""; return Result; } // SendQueryPacket is a wrapper for SendText that allows for packet numbering. function bool SendQueryPacket(IpAddr Addr, coerce string SendString, int QueryNum, out int PacketNum, int bFinalPacket) { local bool Result; //Log("Send Query: " $ QueryNum $ "." $ PacketNum $ ":" $ bFinalPacket); result = true; if (len(ReplyData) + len(SendString) > 1000) result = SendAPacket(Addr, QueryNum, PacketNum, 0); ReplyData = ReplyData $ SendString; if (bFinalPacket == 1) result = SendAPacket(Addr, QueryNum, PacketNum, bFinalPacket); return Result; } // Return a string of basic information. function string GetBasic() { local string ResultSet; // The name of this game. ResultSet = "\\gamename\\"$GameName; // The version of this game. ResultSet = ResultSet$"\\gamever\\"$Level.EngineVersion; // The most recent network compatible version. if( MinNetVer >= Int(Level.MinNetVersion) && MinNetVer <= Int(Level.EngineVersion) ) ResultSet = ResultSet$"\\minnetver\\"$string(MinNetVer); else ResultSet = ResultSet$"\\minnetver\\"$Level.MinNetVersion; // The regional location of this game. ResultSet = ResultSet$"\\location\\"$Level.Game.GameReplicationInfo.Region; return ResultSet; } // Return a string of important system information. function string GetInfo() { local string ResultSet; local bool bRecieved; bRecieved = false; // The server name, i.e.: Bob's Server ResultSet = "\\hostname\\"$Level.Game.GameReplicationInfo.ServerName; // The short server name //ResultSet = ResultSet$"\\shortname\\"$Level.Game.GameReplicationInfo.ShortName; // The server port. ResultSet = ResultSet$"\\hostport\\"$Level.Game.GetServerPort(); // (optional) The server IP // if (ServerIP != "") // ResultSet = ResultSet$"\\hostip\\"$ServerIP; // The map/level title ResultSet = ResultSet$"\\maptitle\\"$Level.Title; // Map name ResultSet = ResultSet$"\\mapname\\"$Left(string(Level), InStr(string(Level), ".")); // The mod or game type if(GetItemName(string(Level.Game.Class)) ~= "SmartCTFGame") { bRecieved = true; ResultSet = ResultSet$"\\gametype\\"$"CTFGame"; } else if(GetItemName(string(Level.Game.Class)) ~= "EUTTeamGamePlus") { bRecieved = true; ResultSet = ResultSet$"\\gametype\\"$"TeamGamePlus"; } else if(GetItemName(string(Level.Game.Class)) ~= "EUTDeathMatchPlus") { bRecieved = true; ResultSet = ResultSet$"\\gametype\\"$"DeathMatchPlus"; } else if(GetItemName(string(Level.Game.Class)) ~= "LeagueAssault") { bRecieved = true; ResultSet = ResultSet$"\\gametype\\"$"Assault"; } if(!bRecieved) { ResultSet = ResultSet$"\\gametype\\"$GetItemName(string(Level.Game.Class)); } // The number of players ResultSet = ResultSet$"\\numplayers\\"$Level.Game.NumPlayers; // The maximum number of players ResultSet = ResultSet$"\\maxplayers\\"$Level.Game.MaxPlayers; // The game mode: openplaying ResultSet = ResultSet$"\\gamemode\\openplaying"; // The version of this game. ResultSet = ResultSet$"\\gamever\\"$Level.EngineVersion; // The most recent network compatible version. if( MinNetVer >= Int(Level.MinNetVersion) && MinNetVer <= Int(Level.EngineVersion) ) ResultSet = ResultSet$"\\minnetver\\"$string(MinNetVer); else ResultSet = ResultSet$"\\minnetver\\"$Level.MinNetVersion; ResultSet = ResultSet$Level.Game.GetInfo(); return ResultSet; } // Return a string of miscellaneous information. // Game specific information, user defined data, custom parameters for the command line. function string GetRules() { local string ResultSet; ResultSet = Level.Game.GetRules(); // Admin's Name if( Level.Game.GameReplicationInfo.AdminName != "" ) ResultSet = ResultSet$"\\AdminName\\"$Level.Game.GameReplicationInfo.AdminName; // Admin's Email if( Level.Game.GameReplicationInfo.AdminEmail != "" ) ResultSet = ResultSet$"\\AdminEMail\\"$Level.Game.GameReplicationInfo.AdminEmail; return ResultSet; } // Return a string of information on a player. function string GetPlayer( PlayerPawn P, int PlayerNum ) { local string ResultSet; local string SkinName, FaceName; // Name ResultSet = "\\player_"$PlayerNum$"\\"$P.PlayerReplicationInfo.PlayerName; // Frags ResultSet = ResultSet$"\\frags_"$PlayerNum$"\\"$int(P.PlayerReplicationInfo.Score); // Ping ResultSet = ResultSet$"\\ping_"$PlayerNum$"\\"$P.ConsoleCommand("GETPING"); // Team ResultSet = ResultSet$"\\team_"$PlayerNum$"\\"$P.PlayerReplicationInfo.Team; // Class ResultSet = ResultSet$"\\mesh_"$PlayerNum$"\\"$P.Menuname; // Skin if(P.Skin == None) { P.static.GetMultiSkin(P, SkinName, FaceName); ResultSet = ResultSet$"\\skin_"$PlayerNum$"\\"$SkinName; ResultSet = ResultSet$"\\face_"$PlayerNum$"\\"$FaceName; } else { ResultSet = ResultSet$"\\skin_"$PlayerNum$"\\"$string(P.Skin); ResultSet = ResultSet$"\\face_"$PlayerNum$"\\None"; } if( P.PlayerReplicationInfo.bIsABot ) ResultSet = ResultSet$"\\ngsecret_"$PlayerNum$"\\bot"; else if( P.ReceivedSecretChecksum ) ResultSet = ResultSet$"\\ngsecret_"$PlayerNum$"\\true"; else ResultSet = ResultSet$"\\ngsecret_"$PlayerNum$"\\false"; return ResultSet; } // Send data for each player function bool SendPlayers(IpAddr Addr, int QueryNum, out int PacketNum, int bFinalPacket) { local Pawn P; local int i; local bool Result, SendResult; Result = false; P = Level.PawnList; while( i < Level.Game.NumPlayers ) { if (P.IsA('PlayerPawn')) { if( i==Level.Game.NumPlayers-1 && bFinalPacket==1) SendResult = SendQueryPacket(Addr, GetPlayer(PlayerPawn(P), i), QueryNum, PacketNum, 1); else SendResult = SendQueryPacket(Addr, GetPlayer(PlayerPawn(P), i), QueryNum, PacketNum, 0); Result = SendResult || Result; i++; } P = P.nextPawn; } return Result; } // Get an arbitrary property from the level object. function string GetLevelProperty( string Prop ) { local string ResultSet; ResultSet = "\\"$Prop$"\\"$Level.GetPropertyText(Prop); return ResultSet; } // Get an arbitrary property from the game object. function string GetGameProperty( string Prop ) { local string ResultSet; ResultSet = "\\"$Prop$"\\"$Level.Game.GetPropertyText(Prop); return ResultSet; } // Get an arbitrary property from the players. function string GetPlayerProperty( string Prop ) { local string ResultSet; local int i; local PlayerPawn P; foreach AllActors(class'PlayerPawn', P) { i++; ResultSet = ResultSet$"\\"$Prop$"_"$i$"\\"$P.GetPropertyText(Prop); } return ResultSet; } D€@DDQM ¬ˆ.(-'(†²–†‹—a/!'·‚š“†‹—& šS&-1M .ŽNO&é-1M .ŽNO%-'„-1-'¥±-' Dt~z a( DR€DD€DX XJÿÿÿÿ@JþÿÿÿlJÿÿÿÿ/sûÿÿÿ.JþÿÿÿxJÿÿÿÿ|XJþÿÿÿdsýÿÿÿ8J÷ÿÿÿGJþÿÿÿwJÿÿÿÿ'kôÿÿÿMJÿÿÿÿDJþÿÿÿmJþÿÿÿZJÿÿÿÿAJÿÿÿÿKJ÷ÿÿÿFsøÿÿÿDxøÿÿÿ3Jþÿÿÿslýÿÿÿ;oîÿÿÿJJ÷ÿÿÿHlýÿÿÿ<xôÿÿÿOsíÿÿÿKxñÿÿÿPdîÿÿÿ{JþÿÿÿYJþÿÿÿqsûÿÿÿ@dûÿÿÿdëÿÿÿlðÿÿÿBxñÿÿÿOlðÿÿÿ4JþÿÿÿJdûÿÿÿ qûÿÿÿIuìÿÿÿ6yìÿÿÿ,líÿÿÿ}wìÿÿÿ7wòÿÿÿCsíÿÿÿ:sýÿÿÿ=dôÿÿÿ$lðÿÿÿ+lýÿÿÿExøÿÿÿ-dûÿÿÿdôÿÿÿ&xðÿÿÿ9lìÿÿÿ5xåÿÿÿR„ƒ>@"„‘>N"}1]"‘}Pk"‡}b{"‡}cI#‡}hX#‡‘rf#„‚Tu#„TC$˜‘2Q$„}e`$„]n$„|>|$„gJ%„‚gY%˜“Th%•j w%˜˜2a2„}fp2‡W~2‡‚jL3ƒpZ3„Š>h3‡jv3‡˜LD4„‚eR4‘“V`4„eo4‡S}4„”nK5„)Z5„“Uh5xav5‡aE6„‡TT6„xTb6ˆ1p6˜16‡“\M7y1[7‡\i7„„>w7„ˆeE8‡pS8‡^a8„‚fp8„“~~8˜tL9„fZ9u1h9‘yPv9„ˆgF:‡ybU:‡ycc:‡yhq:˜„2@;t1O;‡„L];„ˆfk;„}gy;„„vH<„‹>W<˜Ž`e<„Bt<„‹vC=„•>R=„ˆQ`=„•vn=‡‡b}=„ˆBL>‡xbZ>‡‡ci>„‘0w>„‘AF?‡‚hT?‘˜Pc?‡˜bs?‡˜cB@„ynQ@„}Q_@”1m@‡˜h{@‡”cJA‡”bYA‘”PhA¢" wA_DB‡ˆcRB‡ˆbaB„ˆCpB‘ˆPB„iOC‘‡P]C„‡?mC„‚i{C‡xcID„}TWD„x?eD“zsD‡“! AE‘xPNE‡“^E‡“9lE¢“* zE„”BGF‡uhVF‡uceF‡ubtF‘uPCG‘pPSGŠ³“$ocGp1RLŠ¤“X`LŠ¸“&dxRŠ·“^\TŠqzUu[kWŠ“,yWŠ¥“AeXŠjfZy[P\„}[^\Š Vl\Š_ B`„|[aiŠ“Voi„„[En‚[SnŠJbnŠS lrŠZ~[Y€„ƒ[h€Š¥Kv€Š“[Aƒ„‹[\…Š~j…ŠEhˆ„Š[m‰„ˆ[{‰Šª :IŠŠ¤FC‹„•[IŽŠ SXŽ¡“N4Xjk–•hCŠ“rkƒŠA]…¡N4\Í^†„‘[zÓŠ PHÔŠ“&X×”[~ט[MØ