*ESqopG>gZ a=a>a?a@aAaBaCaDaEaFqSNoneDeleteElementAddSortedElement AddElementUpdateDefaultMapsUTServerAdminConsoleCommandGenerateMapListSelectReloadExcludeMapsCore AddMessagePadLeftReloadIncludeMaps UsedMutatorsSystem ServerTravelGenerateMutatorListSelectGenerateGameTypeOptionsQueryCurrentConsoleSendQueryRestartPageQueryDefaultsQueryDefaultsRulesConsoleQueryCurrentConsoleLogQueryCurrentMutatorsQueryDefaultsMapsQueryCurrentConsoleQueryDefaultsMenuQueryDefaultsSettingsQueryCurrentMenu QueryCurrent QueryMenu QueryRootQueryDefaultsBotsGenerateMapListOptionsQueryCurrentGameQueryDefaultsServerQueryDefaultsIPPolicyMoveElementUpMoveElementDownQueryCurrentPlayersLoadGameTypesFormatMessageFailAuthentication ApplyMapListUWebQuery LoadMutatorsInitUserEngine SendTextClientMessageBroadcastMessageReceiveLocalizedMessage TeamMessageRunTestHighlightedBG DefaultBG MessageUHTMDefaultsRestartPageDefaultsIPPolicyPageDefaultsServerPageDefaultsBotsPageDefaultsSettingsPageDefaultsRulesPageDefaultsMapsPageDefaultsMenuPage DefaultsPageCurrentRestartPageCurrentMutatorsPageDefaultSendTextCurrentConsoleSendPageCurrentConsoleLogPageCurrentConsolePageCurrentGamePageCurrentPlayersPageCurrentIndexPageCurrentMenuPageClientVoiceMessage RootPage MenuPage CurrentPageSpectatorType AdminRealmSayTeamSaybClientMessagesReceivedMsgMaxbTeamMessagesUTServerAdminSpectatorUTImageServerPlayerMessagebLocalizedMessages ListItemCheckIPPolicy FindItem MOTDLine3 MOTDLine4 MOTDLine2 PlayerName PlayerID TeamNameScorebIsABot bIsSpectator AdminName MOTDLine1 PawnList Difficulty GameSpeedMaxSpectatorsAdminPassword GamePassword MapListType AdminEmail MaxPlayers IPPolicies BaseMutatorGameEngineVersion NextDesc MapPrefixMapsTest tempClassWidthkSort NewElementPage Spectator WebResponse WebRequestWebApplication ImageServer WebServerRequest bWorldLog ServerURLURISubst ClearSubst IncludeUHTMMapList GameName NextMutator NewClass ResponseGetVariableNumberPrevPing GameType MinPlayers FragLimit TimeLimitbHardCoreMode bMegaSpeed BytePropertyBotConfigTypeNextMapFriendlyFireScale MaxTeamsGoalTeamScore bAdjustSkill bRandomOrder NextGame GameStyle MutatorListNumDefaultClassesDefaultBaseClass NextDefault FirstMapTestMap IncludeCountMessagingSpectatorNumMutatorClasses IpServerUdpServerUplink DoUplinkBotpackAssault TeamGamePlus ServerNameDeathMatchPlusCTFGame bDeleteMe DominationLastManStanding bDumbDownbMultiWeaponStaybForceRespawn bTournamentbUseTranslocatorbBalanceTeamsbPlayersBalanceTeams FRIENDLYFIREStaticSaveConfigDynamicLoadObject GameClassDataIPfirst MessageListReceivedMsgNum Username GetVariable PlayerListbVoiceMessages PasswordTempMsgjAdminUsernameGetVariableCountGetPlayerNetworkAddress GameTypeList IncludeMaps ExcludeMapsIncludeMutatorsExcludeMutatorsSenderM MessageID MessageType RecipientPRINext nextPawn SelectedItem AirControl bIsPlayerposOptionalObject RelatedPRI_2 RelatedPRI_1PTypebBeepGetNextIntDesc GetNextIntMapNameText LocalMessagePathChallengeBotInfoi TempItemInStrOutStrS ResponseStr SelectedStr ReturnValuePadStr ScriptText MapListClassMutator LevelInfo GameInfoPlayerReplicationInfoCurrentGameType OptionStrGameReplicationInfoLevelActor GroupPagePawn PlayerPawnPlayerNetConnectionPlayerListSubstTempStr PawnCountCount NewGameTypeMessageSendStrTitle LogSubstLogStrTagClassPackageSwitchPageStr TextBufferObject MoveCount Function FragNamePlayersBalanceTeams ForceRespawn WeaponsStay TournamentStructUseTranslocator StrPropertyAutoAdjustSkill RandomOrder BalanceTeams DumbDownBotDifficultyStructProperty bDoUplinkClassProperty bJustMoved NamePropertyObjectProperty FirstElementTournamentGameInfo SearchDataFloatProperty BoolProperty MoveItem TempCount IntProperty BotConfigNoneNoneNoneNoneNoneNoneNoneNoneNoneNone AdminActionbLogAdminActions ActionToTake MaxAttemptsMinutesSecondsRemainingTime LoginSecondsLoginDelaySecondsMaxLoginAttemptsbAdminLogging LoginActiona_^yCј<,CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC FFFFFFFFFF FF%@FFGFFFF@FFFFFFPFFFFFFrFF?FFFFFFZFF FFaFFEFFcFFFF@@FFSFF:FFI@FFb@@FFFFTFF@FF|@@FF FF]FFFF5@FFNFF$FFHFFf@FFDFF FFFF\FFFFQFFLFFZFFjFFq@@FF@FFDFFe@@FFGFFq@FFkFF]FFfFF0FFpFF&FF}@@FFF[iZ 6BK$M o{#U{#UCCC2 1X WY]FFd@FFC@FF~FFeFFH@FF@FFFF,FF@FFFF'FFFFoFF\@@FFFFM@FF1F]ye T xDDPPPPDDPDDPPPPPPPQ$9PPPPQ$9Q$9Q$9Q$9Q$9PQ$9Q$9Q$9Q$90Ni0Ni0Ni0Ni0Ni0Ni0NiPPPPPPO=PDDDDDDDDDDDDDDDD0Ni0Ni0Ni0Ni0Ni0Ni0Ni0NiO=O=PPPPPPPPPPPPPQ$9Q$9Q$9Q$9Q$9Q$9Q$9Q$9Q$9Q$9Q$9Q$9Q$9Q$9Q$9Q$9Q$9DCы-%nDDRD-%nDRDRD}"#DLRR-%nRR}"#LQ$9Q$9Q$9Q$9Q$9Q$9Q$9Q$9Q$9Q$9DCы-%n-%nD-%n-%nQ$9-%n-%nQ$9-%n-%nQ$9-%n-%n-%nDD-%nD-%nD-%nQ$9Q$9Q$9Q$9Q$9Q$9Q$9Q$9DCхD-%n-%nQ$9D-%n-%nQ$9-%n-%n}"#-%nDD}"#D-%nD-%nD-%nQ$9Q$9Q$9Q$9D}"#}"#D-%n-%nQ$9D-%nQ$9-%nD}"#}"#Q$9D}"#}"#Q$9Q$9Q$9Q$9Q$9Q$9DDDDDDCхDCCхDDDDCхDCCхDDCCCхDCCCхDDDDCCCCCхDCCCCCхDCCCфQ$9Q$9Q$9Q$9Q$9Q$9Q$9Q$9DDPDDQ$9Q$9Q$9Q$9Q$9Q$9Q$9Q$9Q$9Q$9Q$9Q$9Q$9Q$9Q$9Q$9Q$9Q$9Q$9Q$9Q$9Q$9Q$9Q$9Q$9Q$9Q$9Q$9DPDQ$9Q$9Q$9Q$9PPP-%nP0NiP0NiP0NiPP0NiPQ$9DDCхDCCхDDDCхDCCхDDCCCхDCCCфQ$9Q$9Q$9Q$9PPQ$9Q$9Q$9Q$9Q$9Q$9PPP-%nP0NiP0NiP0NiPP0NiPQ$9BK$MCCCфQ$9OcQ$9Q$9DBK$MPBK$MQ$9Q$9Q$9PPP-%nP0NiP0NiP0NiPP0NiPQ$9DPDDQ$9Q$9DDQ$9DDQ$9Q$9Q$9-%nQ$9Q$9Q$9DPDPQ$9Q$9DQ$9PPQ$9Q$9Q$9PQ$9Q$9Q$9PPP-%nP0NiP0NiP0NiPP0NiPQ$9DPTT+DT{#U+PPPPPPPT{#U+TDT{#UPT{#U+TTDP-%nDPPTTTT{#UCCєT{#UT{#UT{#U+CCєT{#UT{#UT{#UT{#UCєT{#UCєT{#UCєT{#UCєT{#UCєTCCCCCCфQ$9Q$9Q$9Q$9P-%nQ$9DQ$9Q$9Q$9Q$9Q$9Q$9Q$9Q$9Q$9Q$9Q$9Q$9Q$9Q$9Q$9Q$9Q$9Q$9DQ$9Q$9Q$9Q$9Q$9Q$9DQ$9Q$9Q$9Q$9Q$9Q$9DQ$9Q$9Q$9DDQ$9Q$9DQ$9Q$9Q$9Q$9Q$9Q$9Q$9Q$9Q$9Q$9Q$9Q$9Q$9Q$9Q$9Q$9Q$9Q$9Q$9Q$9Q$9Q$9Q$9Q$9Q$9CCCCCCыPCCCCCыCCыCыCыCCCCCCCыPCCCCцPCыCыCCCCCCCCCCCцPCCCCцPP=$:e=$:eCѧ=$:eCѧ=$:e=$:ePCыCCцPPP- SBQ]menuP]rootR] currentN] current_menuM]current_indexL]current_playersK] current_gameJ]current_consoleI]current_console_logH]current_console_sendG]say F]current_mutatorsE]current_restartD] defaultsC]defaults_menuB]defaults_mapsAMdefaults_rules@]defaults_settings?]defaults_bots>]defaults_server=]defaults_ippolicy<]defaults_restart;] message.uhtm:] #aaaaaa9] #ffffffT]UT Remote Admin ServerT]adminp]adminFFl@FFFFFFxFFFFFZFFb@FF_@@FF@@@FF]@@FF^@@FFz@@FFFFzFF@FFc@FFK@@FFjFF2@FF;FBF7@@FFFFaFF@FFD@FFXFF~FFm@FFp@FFYFFGFFg@FFf@FFF@FFIFFFF@FFg@FF@FF}FFBFFFF{@FFxFFBFFeFFY@FFFFFFR@FFFF[FF*@FFcFFo@@FF@FFg@FFFFR@FFO@FF FFe@FF`@FFS@FFEFF[@FF@FF@FFT@FF3FFG@FFFFC@FFJFFXFFP@FF_FFt@FFUFFt@FFl@FFh@FFi@FF\@FFbFF@FFvFFy@@FFB@FFw@@FFs@@FF4@@FF@FF@@FF[FFxFF@FF@@FF"@@FFu@@FFP@@FFy@@FFS@FF@FFzFFFF@FFvFF6FFU@FF@FFr@FF8FFK@FFsFF@FFL@FF9@FFFFVFFFFV@FFFFfFFM@FF@FFhBFuFF-FFOFFQ@FFFF)FFqFF+FF~FF{@@FF@FFOFFIFFV@FFmFFUFFFFEFFCFFwFFs@FFAFFW@FFr@FF}@FFK@FFFFu@FFE@FFM@FFL@FFtFF`@@FF@FF|@FFpFF{FFw@FFuFFsFFA@FFA@FFDFFG@FFB@FFa@FFNFFW\FQPe![pppppV~V..unr?game=V?mutator= (RTitlePlease WaitR{MessageThe server is now restarting the current map. Please allow 10-15 seconds while the server changes levels.R y FMF V}~%~ yFG}yayp~y!ya FY#r}  SectionRulesT#GameType;T d#&MaxPlayersSdSJd%Jd MaxPlayersdc#)MaxSpectatorsScSJc%Jc MaxSpectatorscT-{T-w*DT-r*CT-U{#Applyyw*D#"PlayersBalanceTeamsfalse-|Dtruer*C#ForceRespawnfalse-KC#WeaponsStayfalse-K{#Tournamentfalse-K{|true WeaponsStay checked|{true Tournament checkedr*|CtrueC checkedC ForceRespawnSubstppForce Respawnsw*|DtrueD checkedD BalanceSubstppForce Balanced Teams8w*r*w*9#%FragLimitU9SJ9%L9MMax Team Score9#%FragLimitS9SJ9%DL9MFrag Limit FragSubstppppM8r*q#%TimeLimitSqSJq% TimeLimitSubstppTime LimitDLqp w*a a p#$MaxTeamsSpSJp%Jp,, TeamSubstppMax Teams w*m#-FriendlyFireU?,dmSJm%,dLmB FriendlyFireSubstppFriendly Fire: [0-100]% PostAction\ GameTypeT p\.uhtm  FNFF[d4rd*<dw<*l<-%l selected<-%(fpppppppf<<?f Fn@FF<@FFRFF~LddNDefaultSendTextyNPostActioneNpo.uhtm FpFFy@FFJ|,8NAA }*|Be, I%LIenzIALw|*B||IAwB*r}*}B} Bp*** Unknown map in Map List: IABp*** Empty exclude list, i=SIIA FW03@P+wW*haWBha B)/ FL@FF`p"V"Ajp )rj*bVjMzbtCustomgCustomrb *9{t \,2|rth selectedhipppppppib\tgi FI.%g)w*w.*%?.j,<%kD??,<ippin(Sj: Sk,,0remaining )eiin\Areai{.AddMutatorZ.ExcludeMutatorsSelect3%3Zw*6."ExcludeMutatorsSelect3w*-%'jr*~ pExclude mutator not found: ."ExcludeMutatorsSelect33t:{.DelMutatorZ.IncludeMutatorsSelect3%73Z-w*6."IncludeMutatorsSelect3w*-%'r*-pInclude mutator not found: ."IncludeMutatorsSelect331t{.AddAllMutatorsw* w*-%'r* btt{.DelAllMutatorstw* qw*-%'Xr*q\)ExcludeMutatorsOptions\)IncludeMutatorsOptions\PostAction`\p`.uhtm F^?SectionMaps&GameType5MapListTypeCustom&  &{MapListSet5MapListSelectCustom{5Custom, &5& {AddMapEExcludeMapsSelect%_EUw*2ExcludeMapsSelectw*-%'r *  UpExclude map not found: ExcludeMapsSelectj5Custom& {DelMap&IncludeMapsSelect%EIncludeMapsSelect%Ew * 2 IncludeMapsSelectw*-%'r*pInclude map not found: IncludeMapsSelect5Custom& {AddAllMapw* w*-%'r *  75Custom& {DelAllMapbw *  _w*-%'Fr*_5Custom& {MoveMap~DLMoveMapCount~%EIncludeMapsSelect|MoveMapDown Ww*,w*%E|IncludeMapsSelect-%' ' ~tb w*%E|IncludeMapsSelect-%' & ~0& ?MapListType5?&MapListOptions"&5?%ExcludeMapsOptions?%IncludeMapsOptions ?PostActionP?GameType&?pP.uhtm? FAFF\N 5r*Xnxwn*XppX,nnn6X F_@/g *!Engine.Mutator%zg){z @,22* A~g,A2 g2 gA2zr*22@%Engine.Mutator@zg1*Z wZ*2VZw2*r*2 2Unknown Mutator in use: VZZZV F|FFQu}QGameTypeIQ PagedzV{QGameTypeSetKQGameTypeSelect|KK PostAction" GameType PageI "GameTypeOptions DefaultBG MapsBG RulesBG SettingsBG BotsBG ServerBG IPPolicyBG RestartBGI qP MapsBGl \ RulesBGl _ SettingsBGl ^ BotsBGl ] ServerBGl ?@ IPPolicyBGl i} RestartBGl  :MapsURIpppp"?GameType=&Page=P ;RulesURIpppp"?GameType=&Page=\ >SettingsURIpppp"?GameType=&Page=_ :BotsURIpppp"?GameType=&Page=^ <ServerURIpppp"?GameType=&Page=] >IPPolicyURIpppp"?GameType=&Page=@ =RestartURIpppp"?GameType=&Page=} p|.uhtm  FUc)G;*c UTournamentGameInfo%{Us~U.cU l* l clUr;*;l; lU!TournamentGameInfo@< FkmD F;wF*B|mFe selectedJetppppppptFF t FW_w?& 4r_*>_w>*B|>q>-%B selectedppppppppp>>?p F\/#RD)w*w.*%?.n,<%mD??,<fppin(Sn: Sm,,0remaining )efinAreaf${/SwitchGameTypeAndMapapppp/MapSelect?game=/GameTypeSelect?mutator= (TitlePlease WaitMessageppppThe server is now switching to map '/MapSelect' and game type '/GameTypeSelect'. Please allow 10-15 seconds while the server changes levels. yB{/SwitchGameTypeu/GameTypeSelectXu au a_uGameTypeButtonSMapButtongGameTypeSelectpppXMapSelect_PostAction7p7.uhtmBb{/SwitchMapZpppp/MapSelect?game=V?mutator= (TitlePlease WaitMessageppThe server is now switching to map '/MapSelect'. Please allow 10-15 seconds while the server changes levels. yBaV a_VRGameTypeButtonHMapButtoncGameTypeSelectpp7MapSelect_pV~V..unrPostAction7p7.uhtm FFFdFFTow~ o*9zw Ibw%*I|If {I[|*}*,pw-tutorialL* L*|*,.unrL *}*,)L *Bro*oL[ooL*bw*&f*g FMFFgFFoh6P FFFEo/@o x%x, |wW*x@WWWx@x"@ FjFFlFFmFFtnOK FFFKS LSGameType;L i-'S&-'S&SGameStyleSS 0-(-(1Normal selected `1-(-'1HardCore selected 2-'-'1Turbo selected fDBjDBLT-{SApplyfJSGameSpeedSf, ,?fBjJSAirControlSj%,d?jBLSUseTranslocatorfalse-KL1GameSpeedSf1AirControlSj|Ltrue1!UseTranslocator checked1PostAction_1GameTypeL1p_.uhtm1 Fh@FFF@FFx}7D: -E }{| FFFJFFi@@FF{z4>-u *z FXJ%F{JUpdate JJPolicyNo-1  % "{  X  ppJAcceptDeny,JIPMaskb1{JDelete JJPolicyNo-11 %  &"{   & j & b,p@-h.uhtm % "{ P~ ,'| PDENY,AcceptCheck,DenyCheckcheckedh,AcceptCheckchecked,DenyCheck,5IPMask P&,-PostActionpp@?PolicyNo=S ,p@-d.uhtm W,PostAction@,p@-f.uhtm FK@FF@v*,wv*>b!UKppv: [wb!VKppp[v]: [Kppp(Wb) [b!K[Kppp(Wb) [K FFF>@FFHv)aa)w*w.*%?.p,<%qD??,<hppin(Sp: Sq,,0remaining )ehinJAreahshXws*GpppG> s
ssJ;LogRefreshpppp/K#ENDJLogTextGJpK.uhtm FXhsEh(GameTypeVUhPagePU;IndexURIpppp|?GameType=E&Page=UU)MainURIppU?GameType=EUp".uhtmU FXC 4N* N*CDGLrX*XN`X N:x:tX X FH@FFA@FFO(lV2wV*VVVOOVO* Fa.~( l{{{{({u{u +b !BugAddressutpg@utpg.org&  s   r  4AreaCurrent  VqAreaCurrent  iSectionPlayer List(  7SectionCurrent Game#  eSectionServer Console  ]KSectionServer Console  oSectionServer Console  `SectionMutators  z <}AreaPlease WaitSection  v"AreaDefaults  |AreaDefaults  PAreaDefaultsSectionMaps  a\AreaDefaultsSectionRules  _AreaDefaultsSectionSettings  ^AreaDefaultsSectionBots!  o]AreaDefaultsSectionServer$  @AreaDefaults"SectionIP Bans / Accepts%  )3ERROR: Page not found or enabled. Ffg Mv 1rM* wM*N%N, "{NM'g(gNMer'*'* 'NME|',.unr' '}',b' '~rm*m'm 'NC FCYnTYRw*x - r*---*R;;t - r*Y-----R  FZFFbk^vkSendText{vg|v,say h5pAdmin: v,F v{Fh *F!CLogURIKCSayURIoCpe.uhtm Fq=!'Q=GameType;Q :M{=ApplykJ=BotDifficultySk:=kaJ=MinPlayersSa%,aV=AutoAdjustSkillfalse:-KV[=RandomOrderfalse:-K[/w*G=BalanceTeamsfalse-KG/w*H=DumbDowntrue-KH:k::aVT:-[T:-w*GT-w*HT-0(pBotDifficultySk selected0MinPlayersSa|Vtrue0!AutoAdjustSkill checked|[true0RandomOrder checkedaw*|GtrueG checkedG0BalanceSubstppBots Balance Teamsaw*|HfalseH checkedH0DumbDownSubstppEnhanced AI0PostAction^0GameTypeQ0p^.uhtm0 FFw`9KWGwW*0|WwWWW* Fj@FFWFFeFFJHEE=w*&|[ z[rHr*HwH*H*w*w***= FFHFDl 4xlGroup4w&MenuURIppr?Group=xwMainURIxwroot.uhtm FFFOFFN]&b GEw)*GH3G%w)*8))8w)*))8)w8*88)88))r8]])GHHG FPn5GACurrentBGADefaultsBGnGroup" 4ACurrentBG "ADefaultsBG A)CurrentURIpps?Group=4A*DefaultsURIpps?Group="Apr.uhtmA FR@FFTj8jPage7E&IndexURIppq?Page=EMainURIEp4.uhtmE FUFFI($u־] C Y T S ` P eUdSO(get engine.gameinfo GamePasswordR)get engine.gameinfo AdminPasswordb:-c--^ --J-{(Apply](ServerNameC(AdminNameY(AdminEmailT(MOTDLine1S(MOTDLine2`(MOTDLine3P(MOTDLine4e(LoginDelayd(MaximumLogins-cK(LogAdmins-^K(DoUplinkfalse-JK(WorldLogfalseO(GamePasswordR(AdminPasswordbJ(LoginReactionSb ] C Y T S ` P  --^ LeJd--c:bb P%$ q&$ ,$ ,$ ,$ --J0pset engine.gameinfo GamePassword O1pset engine.gameinfo AdminPassword R$ServerName]$AdminNameC$AdminEmailY$MOTDLine1T$MOTDLine2S$MOTDLine3`$MOTDLine4P$GamePasswordO$AdminPasswordR$LoginDelaye,$MaximumLoginsd$#pReactionSb selectedF-c$LogAdmins checkedr-^$DoUplink checked-J$WorldLog checked$PostAction]$p].uhtm FS`'z GEw+*DD3D%w+*6++6w+*++6+w6*66+66+)r+``6DDDD FVi9ciPage7DefaultBGPlayersBGGameBGConsoleBGMutatorsBGRestartBGc iPlayersBG 07GameBG ZeConsoleBG `MutatorsBG zRestartBG (PlayersURIpp4?Page=i%GameURIpp4?Page=7(ConsoleURIpp4?Page=e)MutatorsURIpp4?Page=`(RestartURIpp4?Page=zpq.uhtm Fqclass UTServerAdminSpectator extends MessagingSpectator config; struct PlayerMessage { var PlayerReplicationInfo PRI; var String Text; var Name Type; var PlayerMessage Next; // pointer to next message }; var ListItem MessageList; var byte ReceivedMsgNum; var config byte ReceivedMsgMax; var config bool bClientMessages; var config bool bTeamMessages; var config bool bVoiceMessages; var config bool bLocalizedMessages; function AddMessage(PlayerReplicationInfo PRI, String S, name Type) { local ListItem TempMsg; TempMsg = new(None) class'ListItem'; TempMsg.Data = FormatMessage(PRI, S, Type); if (MessageList == None) MessageList = TempMsg; else MessageList.AddElement(TempMsg); if ((ReceivedMsgNum++) >= ReceivedMsgMax) MessageList.DeleteElement(MessageList); // delete the first element } function String FormatMessage(PlayerReplicationInfo PRI, String Text, name Type) { local String Message; // format Say and TeamSay messages if (PRI != None) { if (Type == 'Say') Message = PRI.PlayerName$": "$Text; else if (Type == 'TeamSay') Message = "["$PRI.PlayerName$"]: "$Text; else Message = "("$Type$") "$Text; } else if (Type == 'Console') Message = Text; else Message = "("$Type$") "$Text; return Message; } function ClientMessage( coerce string S, optional name Type, optional bool bBeep ) { if (bClientMessages) AddMessage(None, S, Type); } function TeamMessage( PlayerReplicationInfo PRI, coerce string S, name Type, optional bool bBeep ) { if (bTeamMessages) AddMessage(PRI, S, Type); } function ClientVoiceMessage(PlayerReplicationInfo Sender, PlayerReplicationInfo Recipient, name messagetype, byte messageID) { // do nothing? } function ReceiveLocalizedMessage( class Message, optional int Switch, optional PlayerReplicationInfo RelatedPRI_1, optional PlayerReplicationInfo RelatedPRI_2, optional Object OptionalObject ) { // do nothing? } FZr(:?3 )w*w.*%?.o,<%lD??,<gppin(So: Sl,,0remaining )eginYAreagFrSortNamew*w.*w*w..*{r+pBanPlayerS!. _!!!~!:pAdding IP Ban for: !O%OzOO1OOpDENY,!b-pWebadmin banned.duringV~V..unr!Ga{r,pKickPlayerS-pWebadmin kicked.fromV~V..unr!GaB{rSetMinPlayers.JrMinPlayersS%%,b w*j --r.B*Z* - M (Bot)qpppp
i-M (Spectator)qMw.*!.!!~!:!pppppppppppp
M
 
S
SD
!
F Name 8 Team  ,08 Ping  S,08   SD,08 Q rQ*Qj QQV3 Z% |FScoreQ w*RpR 0 Q0 w*RpR  R** No Players Connected **YPlayerListRYPostActioniYSortFY/MinPlayersS.Ypi.uhtm Faclass UTServerAdmin expands WebApplication config; var() class SpectatorType; var UTServerAdminSpectator Spectator; var ListItem GameTypeList; var ListItem IncludeMaps; var ListItem ExcludeMaps; var ListItem IncludeMutators; var ListItem ExcludeMutators; var config string MenuPage; var config string RootPage; var config string CurrentPage; var config string CurrentMenuPage; var config string CurrentIndexPage; var config string CurrentPlayersPage; var config string CurrentGamePage; var config string CurrentConsolePage; var config string CurrentConsoleLogPage; var config string CurrentConsoleSendPage; var config string DefaultSendText; var config string CurrentMutatorsPage; var config string CurrentRestartPage; var config string DefaultsPage; var config string DefaultsMenuPage; var config string DefaultsMapsPage; var config string DefaultsRulesPage; var config string DefaultsSettingsPage; var config string DefaultsBotsPage; var config string DefaultsServerPage; var config string DefaultsIPPolicyPage; var config string DefaultsRestartPage; var config string MessageUHTM; var config string DefaultBG; var config string HighlightedBG; var config string AdminRealm; var config string AdminUsername; var config string AdminPassword; event Init() { Super.Init(); if (SpectatorType != None) Spectator = Level.Spawn(SpectatorType); else Spectator = Level.Spawn(class'UTServerAdminSpectator'); // won't change as long as the server is up LoadGameTypes(); LoadMutators(); } function LoadGameTypes() { local class TempClass; local String NextGame; local ListItem TempItem; local int i, Pos; // reinitialize list if needed GameTypeList = None; // Compile a list of all gametypes. TempClass = class'TournamentGameInfo'; NextGame = Level.GetNextInt("TournamentGameInfo", 0); while (NextGame != "") { Pos = InStr(NextGame, "."); TempClass = class(DynamicLoadObject(NextGame, class'Class')); TempItem = new(None) class'ListItem'; TempItem.Tag = TempClass.Default.GameName; TempItem.Data = NextGame; if (GameTypeList == None) GameTypeList = TempItem; else GameTypeList.AddElement(TempItem); NextGame = Level.GetNextInt("TournamentGameInfo", ++i); } } function LoadMutators() { local int NumMutatorClasses; local string NextMutator, NextDesc; local listitem TempItem; local Mutator M; local int j; local int k; ExcludeMutators = None; Level.GetNextIntDesc("Engine.Mutator", 0, NextMutator, NextDesc); while( (NextMutator != "") && (NumMutatorClasses < 50) ) { TempItem = new(None) class'ListItem'; k = InStr(NextDesc, ","); if (k == -1) TempItem.Tag = NextDesc; else TempItem.Tag = Left(NextDesc, k); TempItem.Data = NextMutator; if (ExcludeMutators == None) ExcludeMutators = TempItem; else ExcludeMutators.AddSortedElement(ExcludeMutators, TempItem); NumMutatorClasses++; Level.GetNextIntDesc("Engine.Mutator", NumMutatorClasses, NextMutator, NextDesc); } IncludeMutators = None; for (M = Level.Game.BaseMutator.NextMutator; M != None; M = M.NextMutator) { TempItem = ExcludeMutators.DeleteElement(ExcludeMutators, String(M.Class)); if (TempItem != None) { if (IncludeMutators == None) IncludeMutators = TempItem; else IncludeMutators.AddElement(TempItem); } else log("Unknown Mutator in use: "@String(M.Class)); } } function String UsedMutators() { local ListItem TempItem; local String OutStr; if(IncludeMutators == None) return ""; OutStr = IncludeMutators.Data; for (TempItem = IncludeMutators.Next; TempItem != None; TempItem = TempItem.Next) { OutStr = OutStr$","$TempItem.Data; } return OutStr; } function String GenerateMutatorListSelect(ListItem MutatorList) { local ListItem TempItem; local String ResponseStr, SelectedStr; if (MutatorList == None) return ""; for (TempItem = MutatorList; TempItem != None; TempItem = TempItem.Next) { SelectedStr = ""; if (TempItem.bJustMoved) { SelectedStr = " selected"; TempItem.bJustMoved=false; } ResponseStr = ResponseStr$""; } return ResponseStr; } function String PadLeft(String InStr, int Width, String PadStr) { local String OutStr; if (Len(PadStr) == 0) PadStr = " "; for (OutStr=InStr; Len(OutStr) < Width; OutStr=PadStr$OutStr); return Right(OutStr, Width); // in case PadStr is more than one character } function ApplyMapList(out ListItem ExcludeMaps, out ListItem IncludeMaps, String GameType, String MapListType) { local class MapListClass; local ListItem TempItem; local int IncludeCount, i; MapListClass = Class(DynamicLoadObject(MapListType, class'Class')); IncludeMaps = None; ReloadExcludeMaps(ExcludeMaps, GameType); IncludeCount = ArrayCount(MapListClass.Default.Maps); for(i=0;i GameClass; local ListItem TempItem; local int i; GameClass = class(DynamicLoadObject(GameType, class'Class')); if(GameClass.Default.MapListType == None) return; if (GameClass != None) { for (i=0; i GameClass; local int i; GameClass = class(DynamicLoadObject(GameType, class'Class')); for (i=0; i"$TempItem.Tag$""; } return OptionStr; } function String GenerateMapListOptions(String GameType, String MapListType) { local class GameClass; local String DefaultBaseClass, NextDefault, NextDesc, SelectedStr, OptionStr; local int NumDefaultClasses; GameClass = class(DynamicLoadObject(GameType, class'Class')); if(GameClass == None) return ""; DefaultBaseClass = String(GameClass.Default.MapListType); if(DefaultBaseClass == "") return ""; NextDefault = "Custom"; NextDesc = "Custom"; if(DynamicLoadObject(DefaultBaseClass, class'Class') == None) return ""; while( (NextDefault != "") && (NumDefaultClasses < 50) ) { if (MapListType ~= NextDefault) SelectedStr = " selected"; else SelectedStr = ""; OptionStr = OptionStr$""; Level.GetNextIntDesc(DefaultBaseClass, NumDefaultClasses++, NextDefault, NextDesc); } return OptionStr; } function String GenerateMapListSelect(ListItem MapList, optional string SelectedItem) { local ListItem TempItem; local String ResponseStr, SelectedStr; if (MapList == None) return ""; for (TempItem = MapList; TempItem != None; TempItem = TempItem.Next) { SelectedStr = ""; if (TempItem.Data ~= SelectedItem || TempItem.bJustMoved) SelectedStr = " selected"; ResponseStr = ResponseStr$""; } return ResponseStr; } //***************************************************************************** event Query(WebRequest Request, WebResponse Response) { // Check authentication: if ((AdminUsername != "" && Caps(Request.Username) != Caps(AdminUsername)) || (AdminPassword != "" && Caps(Request.Password) != Caps(AdminPassword))) { Response.FailAuthentication(AdminRealm); return; } //Response.Subst("BugAddress", "utbugs"$Level.EngineVersion$"@epicgames.com"); Response.Subst("BugAddress", "utpg@utpg.org"); // Match query function. checks URI and calls appropriate input/output function switch (Mid(Request.URI, 1)) { case "": case RootPage: QueryRoot(Request, Response); break; case MenuPage: QueryMenu(Request, Response); break; case CurrentPage: Response.Subst("Area", "Current"); QueryCurrent(Request, Response); break; case CurrentMenuPage: Response.Subst("Area", "Current"); QueryCurrentMenu(Request, Response); break; case CurrentPlayersPage: Response.Subst("Section", "Player List"); QueryCurrentPlayers(Request, Response); break; case CurrentGamePage: Response.Subst("Section", "Current Game"); QueryCurrentGame(Request, Response); break; case CurrentConsolePage: Response.Subst("Section", "Server Console"); QueryCurrentConsole(Request, Response); break; case CurrentConsoleLogPage: Response.Subst("Section", "Server Console"); QueryCurrentConsoleLog(Request, Response); break; case CurrentConsoleSendPage: Response.Subst("Section", "Server Console"); QueryCurrentConsoleSend(Request, Response); break; case CurrentMutatorsPage: Response.Subst("Section", "Mutators"); QueryCurrentMutators(Request, Response); break; case CurrentRestartPage: case DefaultsRestartPage: Response.Subst("Area", "Please Wait"); Response.Subst("Section", ""); QueryRestartPage(Request, Response); break; case DefaultsPage: Response.Subst("Area", "Defaults"); QueryDefaults(Request, Response); break; case DefaultsMenuPage: Response.Subst("Area", "Defaults"); QueryDefaultsMenu(Request, Response); break; case DefaultsMapsPage: Response.Subst("Area", "Defaults"); Response.Subst("Section", "Maps"); QueryDefaultsMaps(Request, Response); break; case DefaultsRulesPage: Response.Subst("Area", "Defaults"); Response.Subst("Section", "Rules"); QueryDefaultsRules(Request, Response); break; case DefaultsSettingsPage: Response.Subst("Area", "Defaults"); Response.Subst("Section", "Settings"); QueryDefaultsSettings(Request, Response); break; case DefaultsBotsPage: Response.Subst("Area", "Defaults"); Response.Subst("Section", "Bots"); QueryDefaultsBots(Request, Response); break; case DefaultsServerPage: Response.Subst("Area", "Defaults"); Response.Subst("Section", "Server"); QueryDefaultsServer(Request, Response); break; case DefaultsIPPolicyPage: Response.Subst("Area", "Defaults"); Response.Subst("Section", "IP Bans / Accepts"); QueryDefaultsIPPolicy(Request, Response); break; default: Response.SendText("ERROR: Page not found or enabled."); } } //***************************************************************************** function QueryRoot(WebRequest Request, WebResponse Response) { local String GroupPage; GroupPage = Request.GetVariable("Group", CurrentPage); Response.Subst("MenuURI", MenuPage$"?Group="$GroupPage); Response.Subst("MainURI", GroupPage); Response.IncludeUHTM("root.uhtm"); } function QueryMenu(WebRequest Request, WebResponse Response) { Response.Subst("CurrentBG", DefaultBG); Response.Subst("DefaultsBG", DefaultBG); switch(Request.GetVariable("Group", DefaultsPage)) { case CurrentPage: Response.Subst("CurrentBG", HighlightedBG); break; case DefaultsPage: Response.Subst("DefaultsBG", HighlightedBG); break; } // Set URIs Response.Subst("CurrentURI", RootPage$"?Group="$CurrentPage); Response.Subst("DefaultsURI", RootPage$"?Group="$DefaultsPage); Response.IncludeUHTM(MenuPage$".uhtm"); Response.ClearSubst(); } //***************************************************************************** function QueryCurrent(WebRequest Request, WebResponse Response) { local String Page; // if no page specified, use the default Page = Request.GetVariable("Page", CurrentGamePage); Response.Subst("IndexURI", CurrentMenuPage$"?Page="$Page); Response.Subst("MainURI", Page); Response.IncludeUHTM(CurrentPage$".uhtm"); Response.ClearSubst(); } function QueryCurrentMenu(WebRequest Request, WebResponse Response) { local String Page; Page = Request.GetVariable("Page", CurrentGamePage); // set background colors Response.Subst("DefaultBG", DefaultBG); // for unused tabs Response.Subst("PlayersBG", DefaultBG); Response.Subst("GameBG", DefaultBG); Response.Subst("ConsoleBG", DefaultBG); Response.Subst("MutatorsBG",DefaultBG); Response.Subst("RestartBG", DefaultBG); switch(Page) { case CurrentPlayersPage: Response.Subst("PlayersBG", HighlightedBG); break; case CurrentGamePage: Response.Subst("GameBG", HighlightedBG); break; case CurrentConsolePage: Response.Subst("ConsoleBG", HighlightedBG); break; case CurrentMutatorsPage: Response.Subst("MutatorsBG",HighlightedBG); break; case CurrentRestartPage: Response.Subst("RestartBG", HighlightedBG); break; } // Set URIs Response.Subst("PlayersURI", CurrentPage$"?Page="$CurrentPlayersPage); Response.Subst("GameURI", CurrentPage$"?Page="$CurrentGamePage); Response.Subst("ConsoleURI", CurrentPage$"?Page="$CurrentConsolePage); Response.Subst("MutatorsURI", CurrentPage$"?Page="$CurrentMutatorsPage); Response.Subst("RestartURI", CurrentPage$"?Page="$CurrentRestartPage); Response.IncludeUHTM(CurrentMenuPage$".uhtm"); Response.ClearSubst(); } function QueryCurrentPlayers(WebRequest Request, WebResponse Response) { local string Sort, PlayerListSubst, TempStr, S; local ListItem PlayerList, TempItem; local Pawn P; local int i, PawnCount, j, Minutes, Seconds; local string IP; if (Level.Game != None && DeathMatchPlus(Level.Game) != None && DeathMatchPlus(Level.Game).TimeLimit > 0.0) { Minutes = Max((Level.Game.GameReplicationInfo.RemainingTime / 60),0); Seconds = Level.Game.GameReplicationInfo.RemainingTime % 60; S = Level.Game.GameReplicationInfo.GameName@"in"@Level.Title@"("@Minutes$":"$PadLeft(Left(string(Seconds),2),2,"0")@"remaining )"; } else S = Level.Game.GameReplicationInfo.GameName@"in"@Level.Title; Response.Subst("Area", S); Sort = Request.GetVariable("Sort", "Name"); for (P=Level.PawnList; P!=None; P=P.NextPawn) { if( PlayerPawn(P) != None && P.PlayerReplicationInfo != None && NetConnection(PlayerPawn(P).Player) != None) { if(Request.GetVariable("BanPlayer"$string(P.PlayerReplicationInfo.PlayerID)) != "") { IP = PlayerPawn(P).GetPlayerNetworkAddress(); if(Level.Game.CheckIPPolicy(IP)) { IP = Left(IP, InStr(IP, ":")); Log("Adding IP Ban for: "$IP); for(j=0;j "; TempStr = " (Bot)"; } else { TempItem.Data = "
"; if (P.PlayerReplicationInfo.bIsSpectator) TempStr = " (Spectator)"; else TempStr = ""; } if(PlayerPawn(P) != None) { IP = PlayerPawn(P).GetPlayerNetworkAddress(); IP = Left(IP, InStr(IP, ":")); } else IP = ""; TempItem.Data = TempItem.Data$"
"$P.PlayerReplicationInfo.PlayerName$TempStr$"
"$P.PlayerReplicationInfo.TeamName$" 
"$P.PlayerReplicationInfo.Ping$"
"$int(P.PlayerReplicationInfo.Score)$"
"$IP$"
"; switch (Sort) { case "Name": TempItem.Tag = P.PlayerReplicationInfo.PlayerName; break; case "Team": TempItem.Tag = PadLeft(P.PlayerReplicationInfo.TeamName, 2, "0"); break; case "Ping": TempItem.Tag = PadLeft(String(P.PlayerReplicationInfo.Ping), 4, "0"); break; default: TempItem.Tag = PadLeft(String(int(P.PlayerReplicationInfo.Score)), 3, "0"); break; } if (PlayerList == None) PlayerList = TempItem; else PlayerList.AddSortedElement(PlayerList, TempItem); } } if (PawnCount > 0) { if (Sort ~= "Score") for (TempItem=PlayerList; TempItem!=None; TempItem=TempItem.Next) PlayerListSubst = TempItem.Data$PlayerListSubst; else for (TempItem=PlayerList; TempItem!=None; TempItem=TempItem.Next) PlayerListSubst = PlayerListSubst$TempItem.Data; } else PlayerListSubst = "** No Players Connected **"; Response.Subst("PlayerList", PlayerListSubst); Response.Subst("PostAction", CurrentPlayersPage); Response.Subst("Sort", Sort); Response.Subst("MinPlayers", String(DeathMatchPlus(Level.Game).MinPlayers)); Response.IncludeUHTM(CurrentPlayersPage$".uhtm"); } function QueryCurrentGame(WebRequest Request, WebResponse Response) { local ListItem ExcludeMaps, IncludeMaps; local class NewClass; local string NewGameType, S; local int Minutes, Seconds; if (Level.Game != None && DeathMatchPlus(Level.Game) != None && DeathMatchPlus(Level.Game).TimeLimit > 0.0) { Minutes = Max((Level.Game.GameReplicationInfo.RemainingTime / 60),0); Seconds = Level.Game.GameReplicationInfo.RemainingTime % 60; S = Level.Game.GameReplicationInfo.GameName@"in"@Level.Title@"("@Minutes$":"$PadLeft(Left(string(Seconds),2),2,"0")@"remaining )"; } else S = Level.Game.GameReplicationInfo.GameName@"in"@Level.Title; Response.Subst("Area", S); if (Request.GetVariable("SwitchGameTypeAndMap", "") != "") { Level.ServerTravel(Request.GetVariable("MapSelect")$"?game="$Request.GetVariable("GameTypeSelect")$"?mutator="$UsedMutators(), false); Response.Subst("Title", "Please Wait"); Response.Subst("Message", "The server is now switching to map '"$Request.GetVariable("MapSelect")$"' and game type '"$Request.GetVariable("GameTypeSelect")$"'. Please allow 10-15 seconds while the server changes levels."); Response.IncludeUHTM(MessageUHTM); } else if (Request.GetVariable("SwitchGameType", "") != "") { NewGameType = Request.GetVariable("GameTypeSelect"); NewClass = class(DynamicLoadObject(NewGameType, class'Class')); ReloadExcludeMaps(ExcludeMaps, NewGameType); ReloadIncludeMaps(ExcludeMaps, IncludeMaps, NewGameType); Response.Subst("GameTypeButton", ""); Response.Subst("MapButton", ""); Response.Subst("GameTypeSelect", NewClass.default.GameName$""); Response.Subst("MapSelect", GenerateMapListSelect(IncludeMaps)); Response.Subst("PostAction", CurrentGamePage); Response.IncludeUHTM(CurrentGamePage$".uhtm"); } else if (Request.GetVariable("SwitchMap", "") != "") { Level.ServerTravel(Request.GetVariable("MapSelect")$"?game="$Level.Game.Class$"?mutator="$UsedMutators(), false); Response.Subst("Title", "Please Wait"); Response.Subst("Message", "The server is now switching to map '"$Request.GetVariable("MapSelect")$"'. Please allow 10-15 seconds while the server changes levels."); Response.IncludeUHTM(MessageUHTM); } else { ReloadExcludeMaps(ExcludeMaps, String(Level.Game.Class)); ReloadIncludeMaps(ExcludeMaps, IncludeMaps, String(Level.Game.Class)); Response.Subst("GameTypeButton", ""); Response.Subst("MapButton", ""); Response.Subst("GameTypeSelect", ""); Response.Subst("MapSelect", GenerateMapListSelect(IncludeMaps, Left(string(Level), InStr(string(Level), "."))$".unr") ); Response.Subst("PostAction", CurrentGamePage); Response.IncludeUHTM(CurrentGamePage$".uhtm"); } } function QueryCurrentConsole(WebRequest Request, WebResponse Response) { local String SendStr, OutStr; SendStr = Request.GetVariable("SendText", ""); if (SendStr != "") { if (Left(SendStr, 4) ~= "say ") Spectator.BroadcastMessage("Admin: "$Mid(SendStr, 4)); else { OutStr = Level.ConsoleCommand(SendStr); if (OutStr != "") Spectator.AddMessage(None, OutStr, 'Console'); } } Response.Subst("LogURI", CurrentConsoleLogPage); Response.Subst("SayURI", CurrentConsoleSendPage); Response.IncludeUHTM(CurrentConsolePage$".uhtm"); } function QueryCurrentConsoleLog(WebRequest Request, WebResponse Response) { local ListItem TempItem; local String LogSubst, LogStr, S; local int i, Minutes, Seconds; if (Level.Game != None && DeathMatchPlus(Level.Game) != None && DeathMatchPlus(Level.Game).TimeLimit > 0.0) { Minutes = Max((Level.Game.GameReplicationInfo.RemainingTime / 60),0); Seconds = Level.Game.GameReplicationInfo.RemainingTime % 60; S = Level.Game.GameReplicationInfo.GameName@"in"@Level.Title@"("@Minutes$":"$PadLeft(Left(string(Seconds),2),2,"0")@"remaining )"; } else S = Level.Game.GameReplicationInfo.GameName@"in"@Level.Title; Response.Subst("Area", S); for (TempItem = Spectator.MessageList; TempItem != None; TempItem = TempItem.Next) LogSubst = LogSubst$"> "$TempItem.Data$"
"; Response.Subst("LogRefresh", WebServer.ServerURL$Path$"/"$CurrentConsoleLogPage$"#END"); Response.Subst("LogText", LogSubst); Response.IncludeUHTM(CurrentConsoleLogPage$".uhtm"); } function QueryCurrentConsoleSend(WebRequest Request, WebResponse Response) { Response.Subst("DefaultSendText", DefaultSendText); Response.Subst("PostAction", CurrentConsolePage); Response.IncludeUHTM(CurrentConsoleSendPage$".uhtm"); } function QueryRestartPage(WebRequest Request, WebResponse Response) { Level.ServerTravel(Left(string(Level), InStr(string(Level), "."))$".unr"$"?game="$Level.Game.Class$"?mutator="$UsedMutators(), false); Response.Subst("Title", "Please Wait"); Response.Subst("Message", "The server is now restarting the current map. Please allow 10-15 seconds while the server changes levels."); Response.IncludeUHTM(MessageUHTM); } function QueryCurrentMutators(WebRequest Request, WebResponse Response) { local ListItem TempItem; local int Count, i, Minutes, Seconds; local string S; if (Level.Game != None && DeathMatchPlus(Level.Game) != None && DeathMatchPlus(Level.Game).TimeLimit > 0.0) { Minutes = Max((Level.Game.GameReplicationInfo.RemainingTime / 60),0); Seconds = Level.Game.GameReplicationInfo.RemainingTime % 60; S = Level.Game.GameReplicationInfo.GameName@"in"@Level.Title@"("@Minutes$":"$PadLeft(Left(string(Seconds),2),2,"0")@"remaining )"; } else S = Level.Game.GameReplicationInfo.GameName@"in"@Level.Title; Response.Subst("Area", S); if (Request.GetVariable("AddMutator", "") != "") { Count = Request.GetVariableCount("ExcludeMutatorsSelect"); for (i=0; i 0) { Count = Request.GetVariableCount("IncludeMapsSelect"); for (i=0; i GameClass; Response.Subst("Section", "Rules"); GameType = Request.GetVariable("GameType", GameTypeList.Data); GameClass = class(DynamicLoadObject(GameType, class'Class')); MaxPlayers = Request.GetVariable("MaxPlayers", String(class(GameClass).Default.MaxPlayers)); MaxPlayers = String(max(int(MaxPlayers), 0)); class(GameClass).Default.MaxPlayers = int(MaxPlayers); Response.Subst("MaxPlayers", MaxPlayers); MaxSpectators = Request.GetVariable("MaxSpectators", String(class(GameClass).Default.MaxSpectators)); MaxSpectators = String(max(int(MaxSpectators), 0)); class(GameClass).Default.MaxSpectators = int(MaxSpectators); Response.Subst("MaxSpectators", MaxSpectators); WeaponsStay = String(class(GameClass).Default.bMultiWeaponStay); Tournament = String(class(GameClass).Default.bTournament); if( class(GameClass) != None ) PlayersBalanceTeams = String(class(GameClass).Default.bPlayersBalanceTeams); if( class(GameClass) == None ) ForceRespawn = String(class(GameClass).Default.bForceRespawn); if (Request.GetVariable("Apply", "") != "") { if( class(GameClass) != None ) { PlayersBalanceTeams = Request.GetVariable("PlayersBalanceTeams", "false"); class(GameClass).Default.bPlayersBalanceTeams = PlayersBalanceTeams ~= "true"; } if( class(GameClass) == None ) { ForceRespawn = Request.GetVariable("ForceRespawn", "false"); class(GameClass).Default.bForceRespawn = bool(ForceRespawn); } WeaponsStay = Request.GetVariable("WeaponsStay", "false"); class(GameClass).Default.bMultiWeaponStay = bool(WeaponsStay); Tournament = Request.GetVariable("Tournament", "false"); class(GameClass).Default.bTournament = bool(Tournament); } if (WeaponsStay ~= "true") { Response.Subst("WeaponsStay", " checked"); } if (Tournament ~= "true") { Response.Subst("Tournament", " checked"); } if( class(GameClass) == None ) { if (ForceRespawn ~= "true") ForceRespawn = " checked"; else ForceRespawn = ""; Response.Subst("ForceRespawnSubst", "Force Respawn"); } if( class(GameClass) != None ) { if (PlayersBalanceTeams ~= "true") PlayersBalanceTeams = " checked"; else PlayersBalanceTeams = ""; Response.Subst("BalanceSubst", "Force Balanced Teams"); } if (class(GameClass) != None && class(GameClass) == None) { if (class(GameClass) != None) { FragLimit = Request.GetVariable("FragLimit", String(class(GameClass).Default.GoalTeamScore)); FragLimit = String(max(int(FragLimit), 0)); class(GameClass).Default.GoalTeamScore = float(FragLimit); FragName = "Max Team Score"; } else { FragLimit = Request.GetVariable("FragLimit", String(class(GameClass).Default.FragLimit)); FragLimit = String(max(int(FragLimit), 0)); class(GameClass).Default.FragLimit = float(FragLimit); FragName = "Frag Limit"; } Response.Subst("FragSubst", ""$FragName$""); if(class(GameClass) == None) { TimeLimit = Request.GetVariable("TimeLimit", String(class(GameClass).Default.TimeLimit)); TimeLimit = String(max(int(TimeLimit), 0)); Response.Subst("TimeLimitSubst", "Time Limit"); class(GameClass).Default.TimeLimit = float(TimeLimit); } } if( class(GameClass) != None && !ClassIsChildOf( GameClass, class'CTFGame' ) && !ClassIsChildOf( GameClass, class'Assault' ) ) { MaxTeams = Request.GetVariable("MaxTeams", String(class(GameClass).Default.MaxTeams)); MaxTeams = String(max(int(MaxTeams), 0)); class(GameClass).Default.MaxTeams = Min(Max(int(MaxTeams), 2), 4); Response.Subst("TeamSubst", "Max Teams"); } if (class(GameClass) != None) { FriendlyFire = Request.GetVariable("FriendlyFire", String(class(GameClass).Default.FriendlyFireScale * 100)); FriendlyFire = String(min(max(int(FriendlyFire), 0), 100)); class(GameClass).Default.FriendlyFireScale = float(FriendlyFire)/100.0; Response.Subst("FriendlyFireSubst", "Friendly Fire: [0-100]%"); } Response.Subst("PostAction", DefaultsRulesPage); Response.Subst("GameType", GameType); Response.IncludeUHTM(DefaultsRulesPage$".uhtm"); Response.ClearSubst(); GameClass.Static.StaticSaveConfig(); } function QueryDefaultsSettings(WebRequest Request, WebResponse Response) { local String GameType, UseTranslocator; local class GameClass; local int GameStyle, GameSpeed, AirControl; GameType = Request.GetVariable("GameType", GameTypeList.Data); GameClass = class(DynamicLoadObject(GameType, class'Class')); if (class(GameClass).Default.bMegaSpeed == true) GameStyle=1; if (class(GameClass).Default.bHardCoreMode == true) GameStyle+=1; switch (Request.GetVariable("GameStyle", String(GameStyle))) { case "0": class(GameClass).Default.bMegaSpeed = false; class(GameClass).Default.bHardCoreMode = false; Response.Subst("Normal", " selected"); break; break; case "1": class(GameClass).Default.bMegaSpeed = false; class(GameClass).Default.bHardCoreMode = true; Response.Subst("HardCore", " selected"); break; case "2": class(GameClass).Default.bMegaSpeed = true; class(GameClass).Default.bHardCoreMode = true; Response.Subst("Turbo", " selected"); break; } GameSpeed = class(GameClass).Default.GameSpeed * 100.0; AirControl = class(GameClass).Default.AirControl * 100.0; UseTranslocator = String(class(GameClass).Default.bUseTranslocator); if (Request.GetVariable("Apply", "") != "") { GameSpeed = min(max(int(Request.GetVariable("GameSpeed", String(GameSpeed))), 10), 200); class(GameClass).Default.GameSpeed = GameSpeed / 100.0; AirControl = min(max(int(Request.GetVariable("AirControl", String(AirControl))), 0), 100); class(GameClass).Default.AirControl = AirControl / 100.0; UseTranslocator = Request.GetVariable("UseTranslocator", "false"); class(GameClass).Default.bUseTranslocator = bool(UseTranslocator); } Response.Subst("GameSpeed", String(GameSpeed)); Response.Subst("AirControl", String(AirControl)); if (UseTranslocator ~= "true") Response.Subst("UseTranslocator", " checked"); Response.Subst("PostAction", DefaultsSettingsPage); Response.Subst("GameType", GameType); Response.IncludeUHTM(DefaultsSettingsPage$".uhtm"); Response.ClearSubst(); GameClass.Static.StaticSaveConfig(); } function QueryDefaultsBots(WebRequest Request, WebResponse Response) { local String GameType, AutoAdjustSkill, RandomOrder, BalanceTeams, DumbDown; local class GameClass; local class BotConfig; local int BotDifficulty, MinPlayers; GameType = Request.GetVariable("GameType", GameTypeList.Data); GameClass = class(DynamicLoadObject(GameType, class'Class')); BotConfig = class(GameClass).Default.BotConfigType; if (Request.GetVariable("Apply", "") != "") { BotDifficulty = int(Request.GetVariable("BotDifficulty", String(BotDifficulty))); BotConfig.Default.Difficulty = BotDifficulty; MinPlayers = min(max(int(Request.GetVariable("MinPlayers", String(MinPlayers))), 0), 16); class(GameClass).Default.MinPlayers = MinPlayers; AutoAdjustSkill = Request.GetVariable("AutoAdjustSkill", "false"); BotConfig.Default.bAdjustSkill = bool(AutoAdjustSkill); RandomOrder = Request.GetVariable("RandomOrder", "false"); BotConfig.Default.bRandomOrder = bool(RandomOrder); if (class(GameClass) != None) { BalanceTeams = Request.GetVariable("BalanceTeams", "false"); class(GameClass).Default.bBalanceTeams = bool(BalanceTeams); if (class(GameClass) != None) { DumbDown = Request.GetVariable("DumbDown", "true"); class(GameClass).Default.bDumbDown = bool(Dumbdown); } } BotConfig.Static.StaticSaveConfig(); GameClass.Static.StaticSaveConfig(); } BotDifficulty = BotConfig.Default.Difficulty; MinPlayers = class(GameClass).Default.MinPlayers; AutoAdjustSkill = String(BotConfig.Default.bAdjustSkill); RandomOrder = String(BotConfig.Default.bRandomOrder); if (class(GameClass) != None) BalanceTeams = String(class(GameClass).Default.bBalanceTeams); if (class(GameClass) != None) DumbDown = String(class(GameClass).Default.bDumbDown); Response.Subst("BotDifficulty"$BotDifficulty, " selected"); Response.Subst("MinPlayers", String(MinPlayers)); if (AutoAdjustSkill ~= "true") Response.Subst("AutoAdjustSkill", " checked"); if (RandomOrder ~= "true") Response.Subst("RandomOrder", " checked"); if (class(GameClass) != None) { if (BalanceTeams ~= "true") BalanceTeams = " checked"; else BalanceTeams = ""; Response.Subst("BalanceSubst", "Bots Balance Teams"); if (class(GameClass) != None) { if (DumbDown ~= "false") DumbDown = " checked"; else DumbDown = ""; Response.Subst("DumbDownSubst", "Enhanced AI"); } } Response.Subst("PostAction", DefaultsBotsPage); Response.Subst("GameType", GameType); Response.IncludeUHTM(DefaultsBotsPage$".uhtm"); Response.ClearSubst(); } function QueryDefaultsServer(WebRequest Request, WebResponse Response) { local String ServerName, AdminName, AdminEmail, MOTDLine1, MOTDLine2, MOTDLine3, MOTDLine4, GamePassword, AdminPassword; local string LoginSeconds, MaxAttempts; local bool bDoUplink, bWorldLog, bAdminLogging; local int LoginAction; ServerName = class'Engine.GameReplicationInfo'.default.ServerName; AdminName = class'Engine.GameReplicationInfo'.default.AdminName; AdminEmail = class'Engine.GameReplicationInfo'.default.AdminEmail; MOTDLine1 = class'Engine.GameReplicationInfo'.default.MOTDLine1; MOTDLine2 = class'Engine.GameReplicationInfo'.default.MOTDLine2; MOTDLine3 = class'Engine.GameReplicationInfo'.default.MOTDLine3; MOTDLine4 = class'Engine.GameReplicationInfo'.default.MOTDLine4; LoginSeconds = string(Level.Game.default.LoginDelaySeconds); MaxAttempts = string(Level.Game.default.MaxLoginAttempts); GamePassword = Level.ConsoleCommand("get engine.gameinfo GamePassword"); AdminPassword = Level.ConsoleCommand("get engine.gameinfo AdminPassword"); LoginAction = int(Level.Game.ActionToTake); bAdminLogging = Level.Game.default.bLogAdminActions; bDoUplink = class'UdpServerUplink'.default.DoUplink; bWorldLog = Level.Game.Default.bWorldLog; if (Request.GetVariable("Apply", "") != "") { ServerName = Request.GetVariable("ServerName", ""); AdminName = Request.GetVariable("AdminName", ""); AdminEmail = Request.GetVariable("AdminEmail", ""); MOTDLine1 = Request.GetVariable("MOTDLine1", ""); MOTDLine2 = Request.GetVariable("MOTDLine2", ""); MOTDLine3 = Request.GetVariable("MOTDLine3", ""); MOTDLine4 = Request.GetVariable("MOTDLine4", ""); LoginSeconds = Request.GetVariable("LoginDelay", ""); MaxAttempts = Request.GetVariable("MaximumLogins", ""); bAdminLogging = bool(Request.GetVariable("LogAdmins", "")); bDoUplink = bool(Request.GetVariable("DoUplink", "false")); bWorldLog = bool(Request.GetVariable("WorldLog", "false")); GamePassword = Request.GetVariable("GamePassword", ""); AdminPassword = Request.GetVariable("AdminPassword", ""); LoginAction = int(Request.GetVariable("LoginReaction", string(LoginAction))); class'Engine.GameReplicationInfo'.Default.ServerName = ServerName; class'Engine.GameReplicationInfo'.Default.AdminName = AdminName; class'Engine.GameReplicationInfo'.Default.AdminEmail = AdminEmail; class'Engine.GameReplicationInfo'.Default.MOTDline1 = MOTDLine1; class'Engine.GameReplicationInfo'.Default.MOTDline2 = MOTDLine2; class'Engine.GameReplicationInfo'.Default.MOTDline3 = MOTDLine3; class'Engine.GameReplicationInfo'.Default.MOTDline4 = MOTDLine4; class'Engine.GameReplicationInfo'.Static.StaticSaveConfig(); class'UdpServerUplink'.default.DoUplink = bDoUplink; class'UdpServerUplink'.Static.StaticSaveConfig(); Level.Game.default.LoginDelaySeconds = float(LoginSeconds); Level.Game.default.MaxLoginAttempts = int(MaxAttempts); Level.Game.default.bLogAdminActions = bAdminLogging; if (Level.Game.default.ActionToTake != LoginAction) { switch (LoginAction) { case 0: Level.Game.default.ActionToTake = DO_Nothing; break; case 1: Level.Game.default.ActiontoTake = DO_Log; break; case 2: Level.Game.default.ActionToTake = DO_DisableLogin; break; case 3: Level.Game.default.ActionToTake = DO_KickPlayer; break; case 4: Level.Game.default.ActionToTake = DO_KickBanPlayer; break; } } Level.Game.Default.bWorldLog = bWorldLog; Level.Game.Static.StaticSaveConfig(); Level.ConsoleCommand("set engine.gameinfo GamePassword "$GamePassword); Level.ConsoleCommand("set engine.gameinfo AdminPassword "$AdminPassword); } Response.Subst("ServerName", ServerName); Response.Subst("AdminName", AdminName); Response.Subst("AdminEmail", AdminEmail); Response.Subst("MOTDLine1", MOTDLine1); Response.Subst("MOTDLine2", MOTDLine2); Response.Subst("MOTDLine3", MOTDLine3); Response.Subst("MOTDLine4", MOTDLine4); Response.Subst("GamePassword", GamePassword); Response.Subst("AdminPassword", AdminPassword); Response.Subst("LoginDelay", Left(LoginSeconds,4)); Response.Subst("MaximumLogins", MaxAttempts); Response.Subst("Reaction"$LoginAction, " selected"); if (bAdminLogging) Response.Subst("LogAdmins", " checked"); if (bDoUplink) Response.Subst("DoUplink", " checked"); if (bWorldLog) Response.Subst("WorldLog", " checked"); Response.Subst("PostAction", DefaultsServerPage); Response.IncludeUHTM(DefaultsServerPage$".uhtm"); } function QueryDefaultsIPPolicy(WebRequest Request, WebResponse Response) { local int i, j; if(Request.GetVariable("Update") != "") { i = int(Request.GetVariable("PolicyNo", "-1")); if(i == -1) for(i = 0; i 0) { for(i = i; (i Test=V *  AATest: AddSort 'A'  p => Test=V  Rw*ppppp => Tag=  Prev=V Next=V*  DDTest: AddSort 'D'  p => Test=V  Iw*ppppp => Tag=  Prev=V Next=V*  CCTest: AddSort 'C'  p => Test=V  @w*ppppp => Tag=  Prev=V Next=VTest: Delete 'C'  Cp => Test=V  w*ppppp => Tag=  Prev=V Next=VTest: Delete 'D'  Dp => Test=V  w*ppppp => Tag=  Prev=V Next=VQTest: Delete 'A'  Ap => Test=V  w*ppppp => Tag=  Prev=V Next=VTest: Delete 'B'  Bp => Test=V  Hw*ppppp => Tag=  Prev=V Next=V ^[`o4j|a- FFmYclass ListItem expands Object; var ListItem Next; var ListItem Prev; var String Tag; // sorted element var String Data; // saved data var bool bJustMoved; // if the map was just moved, keep it selected function AddElement(ListItem NewElement) { local ListItem TempItem; for (TempItem = self; TempItem.Next != None; TempItem = TempItem.Next); TempItem.Next = NewElement; NewElement.Prev = TempItem; NewElement.Next = None; } function AddSortedElement(out ListItem FirstElement, ListItem NewElement) { local ListItem TempItem; // find item which new should be inserted after TempItem = FirstElement; while (TempItem != None) { // if current is less or equal than new, but is at the end if (Caps(TempItem.Tag) <= Caps(NewElement.Tag) && TempItem.Next == None) { TempItem.Next = NewElement; NewElement.Prev = TempItem; NewElement.Next = None; break; } // else if current is greater than new else if (Caps(TempItem.Tag) > Caps(NewElement.Tag)) { // if current.prev == none, then make it the new first element if (TempItem.Prev == None) FirstElement = NewElement; else TempItem.Prev.Next = NewElement; NewElement.Prev = TempItem.Prev; NewElement.Next = TempItem; TempItem.Prev = NewElement; break; } TempItem = TempItem.Next; } } function ListItem FindItem(String SearchData) { local ListItem TempItem; for (TempItem = self; TempItem != None; TempItem = TempItem.Next) { if (TempItem.Data ~= SearchData) return TempItem; } return None; } function ListItem DeleteElement(out ListItem First, optional String SearchData) { local ListItem TempItem; for (TempItem = self; TempItem != None; TempItem = TempItem.Next) { if (TempItem.Data ~= SearchData || SearchData == "") { // if no prev, assume this is the first element if (TempItem == First || TempItem.Prev == None) { First = TempItem.Next; if (First != None) First.Prev = None; } else { // close the links around TempItem if (TempItem.Prev != None) TempItem.Prev.Next = TempItem.Next; if (TempItem.Next != None) TempItem.Next.Prev = TempItem.Prev; } TempItem.Prev = None; TempItem.Next = None; break; } } return TempItem; } function MoveElementUp(out ListItem First, ListItem MoveItem, out int Count) { local ListItem TempItem; local int TempCount; if (MoveItem != None) { for (TempCount = Count; TempCount > 0 && MoveItem.Prev != None; TempCount--) { TempItem = MoveItem.Prev; MoveItem.Prev = TempItem.Prev; if (MoveItem.Prev != None) MoveItem.Prev.Next = MoveItem; TempItem.Next = MoveItem.Next; if (TempItem.Next != None) TempItem.Next.Prev = TempItem; MoveItem.Next = TempItem; TempItem.Prev = MoveItem; if (TempItem == First) First = MoveItem; } Count = Count - TempCount; } } function MoveElementDown(out ListItem First, ListItem MoveItem, out int Count) { local ListItem TempItem; local int TempCount; if (MoveItem != None) { for (TempCount = Count; TempCount > 0 && MoveItem.Next != None; TempCount--) { TempItem = MoveItem.Next; MoveItem.Next = TempItem.Next; if (MoveItem.Next != None) MoveItem.Next.Prev = MoveItem; TempItem.Prev = MoveItem.Prev; if (TempItem.Prev != None) TempItem.Prev.Next = TempItem; MoveItem.Prev = TempItem; TempItem.Next = MoveItem; if (MoveItem == First) First = TempItem; } Count = Count - TempCount; } } function RunTest() { local ListItem Test, TempItem; Log("Test: Init 'B'"); Test = new(None) class'ListItem'; Test.Tag = "B"; Test.Data = "B"; Log(" => Test="$Test); TempItem = new(None) class'ListItem'; TempItem.Tag = "A"; TempItem.Data = "A"; Log("Test: AddSort 'A'"); Test.AddSortedElement(Test, TempItem); Log(" => Test="$Test); for (TempItem = Test; TempItem != None; TempItem = TempItem.Next) Log(" => Tag="$TempItem.Tag$" Prev="$TempItem.Prev$" Next="$TempItem.Next); TempItem = new(None) class'ListItem'; TempItem.Tag = "D"; TempItem.Data = "D"; Log("Test: AddSort 'D'"); Test.AddSortedElement(Test, TempItem); Log(" => Test="$Test); for (TempItem = Test; TempItem != None; TempItem = TempItem.Next) Log(" => Tag="$TempItem.Tag$" Prev="$TempItem.Prev$" Next="$TempItem.Next); TempItem = new(None) class'ListItem'; TempItem.Tag = "C"; TempItem.Data = "C"; Log("Test: AddSort 'C'"); Test.AddSortedElement(Test, TempItem); Log(" => Test="$Test); for (TempItem = Test; TempItem != None; TempItem = TempItem.Next) Log(" => Tag="$TempItem.Tag$" Prev="$TempItem.Prev$" Next="$TempItem.Next); Log(""); Log("Test: Delete 'C'"); Test.DeleteElement(Test, "C"); Log(" => Test="$Test); for (TempItem = Test; TempItem != None; TempItem = TempItem.Next) Log(" => Tag="$TempItem.Tag$" Prev="$TempItem.Prev$" Next="$TempItem.Next); Log("Test: Delete 'D'"); Test.DeleteElement(Test, "D"); Log(" => Test="$Test); for (TempItem = Test; TempItem != None; TempItem = TempItem.Next) Log(" => Tag="$TempItem.Tag$" Prev="$TempItem.Prev$" Next="$TempItem.Next); Log("Test: Delete 'A'"); Test.DeleteElement(Test, "A"); Log(" => Test="$Test); for (TempItem = Test; TempItem != None; TempItem = TempItem.Next) Log(" => Tag="$TempItem.Tag$" Prev="$TempItem.Prev$" Next="$TempItem.Next); Log("Test: Delete 'B'"); Test.DeleteElement(Test, "B"); Log(" => Test="$Test); for (TempItem = Test; TempItem != None; TempItem = TempItem.Next) Log(" => Tag="$TempItem.Tag$" Prev="$TempItem.Prev$" Next="$TempItem.Next); } FFFbFF^@FFd@FFn@FFQ@FFR@FF@FFkFFiFF!FFFFmFFlFFqFFF Z- Z2 Z YD YE YA Zt `M YB Yh YY YF Yx sG Ys `N YF sw Y` YJ YC Y{ Yv Y^ `O YK YP sC sF Yt Yp hu `F Yx `U pY `N Y{ Y@ Zq Yr `E hQ {M h{ hU ^I pr {[ YH hd `U Yr {e hz xH `V {Y Y| Y] x\ x] `n Y^ hf sl wn {o hb xJ ha wO {P hc {t sR hk `o Yo hs wg YG YH hj {W hw sc hQ {b {Z x xd xe x~ x} we `0 xC x@ ^m wa xA Yu xs xB wc `7 Yy `6 `4 Yu xz xh `O Yr sL hs YM `. sH xi sv hK hL xf p_ hQ Yf Yn hM^Hj[_vrmbAnvPn G_nVonH~n\kLo_|\oXkoTyoXHp9uWpDTfpDIupT[DqITq\vcqTZrqvArYQr"T`ruprZTrNvOsT:^s1GlsIG}sXMtT9\tFvkt Tzt\IJuTDXu IguXTvuqFvXTvEvbvXIrvSyAw&`QwYy`w9TpwFAwINx"I^xITmx1T}xvMyu]yTRlyr{yYvIzTKYzSvhz ZxzI|G{TWX{ vh{IIx{!vG|TW|T=f|TTu|ZYD} c] blQ{ vJIkZIliuw9IE;ST&vbEGqEuA\SOTB^\Om\N|1IKRZflCv{JvJBKY\Ti]y;qITAXT>gT?vT@ETFTIYc;lq o@ tOTJ^1nmy|TCJTLZ1ehImvvE DUvd&Yt bD [S\Ib>vrkB"RQHT`&Go+u@ xNR\ ekYyXI_Y dg+GvGvXXjhYzwVTE\@USzdNJr&lBXJPTI_1gn\O|@RKXqZXbiIxXpGXcVXke?TtIiD+vSxcXsqQ@IjNT]XwlXo{"XJXaZ"Yijy}HF {Y zhyw{FEUGdF {uEXCFTHS!zbTNqTQ@TPO E]Tpk;ayPTIPIYT;gTEuTTCTCRT<a }pVBpM\!{jHTxYQH?XVHxe>VsSQBBP>T_Oo1X} aLTZCAi9SyIXG TV1ge Xt?\CFTSQ"SbFts\PBNvQi`SJnF!P}YJM ~\TTkZBz hHnX&mgEYv?IFZIVVIeHIuPIE DUTId+XtXC!dRragpBX~BWNEX]JvlBL{TGK8yZ4yi4lx4aG&XW8lfuurDXS@ab@yrBYA wP@l_B\nTTCT \WTn#sIaTfq|W |f ItTkD>uo |~T,YMT0Tf&pzT"SITQ\TgmSTT ucT/KXTXcTusT)bhTvJTm@T#mF)hl)i{TtK)[)SNB6!`/^ATYP/_i/`x/\HBO"X4mzTY H>Wa |pB748ms>IATMQB42`T%A R;|SB*DbTYf!|uT]CT]`B z}B]wBPFfUT.V{T vQtG\u{T]JT!Ug`T||PJ|_)joubtT FDN|JlY&khTUSqhTOwaFT$tV'kJTouB~4}dT(x%aT~4nY`~4^ G 8Ae [[f ~4yYA XRz XQH XJW XNf "yu \yD >yS yb Kp L \LN "L\ "Kj \Ky >KH >LW