00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 class LadderGameRules extends GameRules
00011 config;
00012
00013 const LOGNAME = 'LadderGameRules';
00014
00015
00016 var ConfigMaster SAManager;
00017
00018
00019 var config bool bDirtyStart;
00020
00021
00022 struct Profile
00023 {
00024 var string ProfileName;
00025 var bool bActive;
00026 var bool bReload;
00027 };
00028
00029
00030 var protected config array<Profile> Profiles;
00031 var protected config int NumRemainingMatches;
00032
00033
00034 var array<ProfileConfigSet> LadderProfiles;
00035 var ProfileConfigSet CurrentProfile;
00036 var StringArray AllLadderProfiles;
00037 var StringArray ProfileMaps;
00038 var string ProfileMutators;
00039 var array<string> ProfileActors;
00040 var bool bWaitingToSwitch;
00041 var int Index;
00042
00043 var string LadderProfileClass;
00044 var string DefaultProfileName;
00045 var class<ProfileConfigSet> ProfileClass;
00046
00047 struct CommandLineParam { var string ParamName; var string Value; };
00048 var array<CommandLineParam> CommandLineOptions;
00049
00050
00051 var localized string ShutdownWhileTemporary;
00052 var localized string ShutdownWhilePermanent;
00053 var localized string ShutdownWhileWaiting;
00054 var localized string ShutdownRemainingMatches;
00055 var localized string ShutdownResumingTemporary;
00056 var localized string ShutdownResumingPermanent;
00057 var localized string ShutdownTrackingCorrupted;
00058
00059 var localized string EndOfGame;
00060 var localized string EndofGameIntercepting;
00061 var localized string EndofGameNoRemainingMatches;
00062 var localized string OverridingURL;
00063
00064
00065 var localized string BadProfileClass;
00066 var localized string CannotRemoveActive;
00067 var localized string PreviousProfileRemoved;
00068
00069
00070 var localized string EmptyMaplist;
00071 var localized string InvalidMaplist;
00072 var localized string CancellingProfile;
00073 var localized string BadIndex;
00074
00075
00076
00077
00078
00079
00080 var bool bRestartCalled;
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090 function bool AddBoolParam(string ParamName, optional bool DefaultValue, optional bool bAddIfNotExists);
00091 function bool AddSelectParam(string ParamName, array<string> VarOptions, optional bool bAddIfNotExists);
00092
00093 event Tick(float DeltaTime)
00094 {
00095 if (Level != None && Level.NextURL != "")
00096 {
00097 bDirtyStart = False;
00098 SaveConfig();
00099 Disable('Tick');
00100 }
00101 }
00102
00103 event PreBeginPlay()
00104 {
00105 ProfileClass = class<ProfileConfigSet>(DynamicLoadObject(LadderProfileClass, class'Class'));
00106 if (ProfileClass == None)
00107 {
00108 log(BadProfileClass@"'"$LadderProfileClass$"'",LOGNAME);
00109 Destroy();
00110 return;
00111 }
00112
00113
00114 AllLadderProfiles = new(None) class'SortedStringArray';
00115 ProfileMaps = new(None) class'StringArray';
00116 InitializeProfileArray();
00117
00118 Super.PreBeginPlay();
00119 }
00120
00121 event PostBeginPlay()
00122 {
00123 local int i, j, Matches;
00124
00125 i = 0 - 1;
00126 j = 0 - 1;
00127
00128 if (Level.Game.BaseMutator != None && ConfigMaster(Level.Game.BaseMutator.NextMutator) != None)
00129 SAManager = ConfigMaster(Level.Game.BaseMutator.NextMutator);
00130 Super.PostBeginPlay();
00131
00132 if (bDirtyStart)
00133 {
00134 i = FindPreviousProfile();
00135 j = FindActiveProfile();
00136 Matches = NumRemainingMatches;
00137 if (i >= 0)
00138 {
00139 if (j >= 0)
00140 {
00141 if ( Matches > 0 )
00142 {
00143 log(ShutdownWhileTemporary@"'"$Profiles[j].ProfileName$"'.",LOGNAME);
00144 log(ShutdownRemainingMatches$":"@NumRemainingMatches$"."@ShutdownResumingTemporary,LOGNAME);
00145 ApplyProfile( j, Matches );
00146 }
00147
00148 else
00149 {
00150 log(ShutdownWhileTemporary@"'"$Profiles[j].ProfileName$"'.",LOGNAME);
00151 log(ShutdownRemainingMatches$":"@NumRemainingMatches$"."@ShutdownResumingPermanent@"'"$Profiles[i].ProfileName$"'.",LOGNAME);
00152 ApplyProfile( i, 0);
00153 }
00154
00155 }
00156 else
00157 {
00158 log(ShutdownWhileWaiting,LOGNAME);
00159 if ( Matches > 0 )
00160 {
00161 ResetTrackingValues();
00162 ApplyProfile(i,Matches);
00163 }
00164 else
00165 {
00166 ResetTrackingValues();
00167 ApplyProfile(i,0);
00168 }
00169 }
00170 }
00171 else if (j >= 0)
00172 {
00173 log(ShutdownWhilePermanent@"'"$Profiles[j].ProfileName$"'."@ShutdownResumingPermanent@"'"$Profiles[j].ProfileName$"'.",LOGNAME);
00174 ApplyProfile( j, 0 );
00175 }
00176
00177 else if (Matches > 0)
00178 {
00179 NumRemainingMatches = 0;
00180 SaveConfig();
00181 }
00182 }
00183 else
00184 {
00185 bDirtyStart = True;
00186 SaveConfig();
00187 }
00188 }
00189
00190
00191
00192
00193 function bool HandleRestartGame()
00194 {
00195 local int i;
00196 local bool bHandleRestart;
00197
00198 if (bDirtyStart)
00199 {
00200 bDirtyStart = False;
00201 SaveConfig();
00202 }
00203
00204 if (!Level.Game.bChangeLevels || Level.Game.bAlreadyChanged)
00205 return Super.HandleRestartGame();
00206
00207 if (bRestartCalled)
00208 return Super.HandleRestartGame();
00209
00210 else bRestartCalled = True;
00211
00212 if ( bWaitingToSwitch )
00213 {
00214 i = FindPreviousProfile();
00215 if (i >= 0)
00216 {
00217 log(EndOfGame,LOGNAME);
00218 log(EndofGameIntercepting@"'"$Profiles[i].ProfileName$"'.",LOGNAME);
00219 ApplyProfile(i,NumRemainingMatches);
00220 bHandleRestart = True;
00221 }
00222 }
00223
00224 else if ( NumRemainingMatches > 0)
00225 {
00226 if (NumRemainingMatches == 1)
00227 {
00228
00229 i = FindPreviousProfile();
00230 if (i >= 0)
00231 {
00232 log(EndOfGame,LOGNAME);
00233 log(EndOfGameNoRemainingMatches,LOGNAME);
00234 log(EndOfGameIntercepting@"'"$Profiles[i].ProfileName$"'.",LOGNAME);
00235 ApplyProfile(i,0);
00236 bHandleRestart = true;
00237 }
00238 else
00239 {
00240 log(EndOfGame,LOGNAME);
00241 log(PreviousProfileRemoved,LOGNAME);
00242 }
00243 }
00244
00245 if ( !bHandleRestart )
00246 {
00247 NumRemainingMatches--;
00248 SaveConfig();
00249 }
00250 }
00251
00252
00253 return (Super.HandleRestartGame() || bHandleRestart);
00254 }
00255
00256
00257
00258
00259
00260
00261 function ApplyProfile(coerce int NewProfileIndex, int NumberOfMatches)
00262 {
00263 local int idx,i,j;
00264 local ProfileConfigSet TempPCS;
00265 local array<string> TempArr;
00266 local string GameType,ShortName,FirstMap,Tmp,TmpV;
00267
00268 idx = ActivateProfile(NewProfileIndex, NumberOfMatches > 0);
00269
00270 if (idx < 0)
00271 {
00272 Warn(CancellingProfile@"'"$Profiles[NewProfileIndex].ProfileName$"'"@"("$BadIndex$")");
00273 if (ActivateProfile(Index) < 0)
00274 ResetTrackingValues();
00275
00276 return;
00277 }
00278
00279 TempPCS = LadderProfiles[idx];
00280 class'Ladder.CommandLineParams'.default.bRejectPlayInfo = True;
00281 TempPCS.StartEdit();
00282 GameType = string(TempPCS.GetGameClass());
00283
00284
00285 ProfileMaps.Reset();
00286 TempArr = TempPCS.GetUsedMaps();
00287 if (TempArr.Length == 0)
00288 {
00289 Warn(CancellingProfile@"'"$Profiles[idx].ProfileName$"'"@"("$EmptyMaplist$")");
00290 if (Index == idx) DeactivateProfile(Index);
00291
00292 else if (ActivateProfile(Index, False) < 0)
00293 ResetTrackingValues();
00294
00295 TempPCS.EndEdit(False);
00296 return;
00297 }
00298
00299 NumRemainingMatches = NumberOfMatches;
00300 for (i=0;i<TempArr.Length;i++)
00301 ProfileMaps.Add(string(i),TempArr[i]);
00302
00303 FirstMap = ProfileMaps.getTag(0);
00304 UpdateDefaultMaps(GameType,ProfileMaps);
00305
00306
00307 ProfileMutators = "";
00308 ProfileMutators = UpdateMutatorString(TempPCS);
00309
00310
00311 ProfileActors = TempPCS.GetUsedServerActors();
00312 TempArr = SAManager.GetAllManagedActors();
00313 for (i = 0; i < TempArr.Length; i++)
00314 {
00315 Tmp = Left(TempArr[i],InStr(TempArr[i],","));
00316 for (j = 0; j < ProfileActors.Length; j++)
00317 {
00318 if (Tmp ~= ProfileActors[j])
00319 break;
00320
00321 }
00322
00323 if (j < ProfileActors.Length)
00324 EnableManagedActor(Tmp);
00325
00326 else DisableManagedActor(Tmp);
00327 }
00328
00329
00330 for (i=0;i<TempPCS.Count();i++)
00331 {
00332 Tmp = TempPCS.GetProfileParamName(i);
00333 TmpV = TempPCS.GetProfileParam(i);
00334 ShortName = GetItemName(Tmp);
00335
00336
00337
00338
00339 if (HasURLOption(ShortName))
00340 {
00341 log(OverridingURL@ShortName$".",LOGNAME);
00342 UpdateURL(ShortName, TmpV, false);
00343 }
00344
00345 else if (!TempPCS.SetNamedParam(Tmp, TmpV))
00346 {
00347 for (j = 0; j < CommandLineOptions.Length; j++)
00348 {
00349 if (Tmp ~= CommandLineOptions[j].ParamName && TmpV != "")
00350 UpdateURL(ShortName, TmpV, false);
00351 }
00352 }
00353 }
00354
00355 TempPCS.SavePI();
00356 TempPCS.EndEdit(False);
00357 if (bDirtyStart)
00358 {
00359 bDirtyStart = False;
00360 SaveConfig();
00361 }
00362
00363 Level.ServerTravel(FirstMap$"?Game="$GameType$"?Mutator="$ProfileMutators, False);
00364 }
00365
00366
00367 function bool WaitApplyProfile(coerce int NewProfileIndex, int NumberOfMatches)
00368 {
00369 local int i;
00370 local int CurrentActive;
00371
00372 CurrentActive = FindActiveProfile();
00373
00374 if ( NewProfileIndex == CurrentActive)
00375 return false;
00376
00377
00378 i = FindPreviousProfile();
00379 if (i >= 0) Profiles[i].bReload = False;
00380 if (CurrentActive >= 0) Profiles[CurrentActive].bActive = False;
00381 Profiles[NewProfileIndex].bReload = True;
00382 bWaitingToSwitch = True;
00383 NumRemainingMatches = NumberOfMatches;
00384 SaveConfig();
00385 return true;
00386 }
00387
00388
00389 function ProfileConfigSet AddProfile(string PCSName, optional string GameType)
00390 {
00391 local Profile TempP;
00392 local int i, NumProfiles;
00393
00394 NumProfiles = Profiles.Length;
00395 for (i = 0; i < NumProfiles; i++)
00396 if (Profiles[i].ProfileName ~= PCSName)
00397 return None;
00398
00399 TempP.ProfileName = PCSName;
00400 Profiles[Profiles.Length] = TempP;
00401
00402 LoadProfile(TempP,GameType);
00403 SaveConfig();
00404
00405 return LadderProfiles[NumProfiles];
00406 }
00407
00408
00409 function bool CopyProfile(int SourceProfileIndex, string NewProfileName)
00410 {
00411 local ProfileConfigSet PCS;
00412
00413 if (SourceProfileIndex < 0 || SourceProfileIndex >= Profiles.Length)
00414 return false;
00415
00416 if (LadderProfiles[SourceProfileIndex] == None)
00417 return false;
00418
00419 PCS = AddProfile(NewProfileName);
00420 if (PCS != None)
00421 {
00422 LadderProfiles[SourceProfileIndex].StartEdit();
00423 PCS.StartEdit();
00424 PCS.ReplaceWith(LadderProfiles[SourceProfileIndex]);
00425 PCS.EndEdit(True);
00426 LadderProfiles[SourceProfileIndex].EndEdit(False);
00427 return true;
00428 }
00429 return false;
00430 }
00431
00432
00433 function bool RemoveProfile(int idx)
00434 {
00435 local ProfileConfigSet LastPCS;
00436 local int LastIDX;
00437
00438 if (idx < 0 || idx >= LadderProfiles.Length)
00439 return false;
00440
00441 if (Profiles[idx].bActive)
00442 {
00443 log(CannotRemoveActive,LOGNAME);
00444 return false;
00445 }
00446
00447 LastIDX = LadderProfiles.Length - 1;
00448 LastPCS = LadderProfiles[LastIDX];
00449 LastPCS.StartEdit();
00450 if (idx < LastIDX)
00451 {
00452 Profiles[idx] = Profiles[LastIDX];
00453
00454 LadderProfiles[idx].StartEdit();
00455 LadderProfiles[idx].ReplaceWith(LastPCS);
00456 LadderProfiles[idx].EndEdit(True);
00457
00458 AllLadderProfiles.Remove(AllLadderProfiles.FindItemId(string(idx)));
00459 AllLadderProfiles.Add(string(idx),Profiles[LastIDX].ProfileName);
00460 }
00461
00462 LastPCS.Wipe();
00463 LastPCS.EndEdit(True);
00464 Profiles.Remove(LastIDX,1);
00465 LadderProfiles.Remove(LastIDX,1);
00466 AllLadderProfiles.Remove(AllLadderProfiles.FindItemId(string(LastIDX)));
00467 SaveConfig();
00468 return true;
00469 }
00470
00471
00472 function int FindActiveProfile()
00473 {
00474 local int i;
00475
00476 if (Index < -1)
00477 {
00478 for (i=0;i<Profiles.Length;i++)
00479 if (Profiles[i].bActive)
00480 Index = i;
00481
00482 if (Index < -1) Index++;
00483 }
00484
00485 return Index;
00486 }
00487
00488
00489 function int FindPreviousProfile()
00490 {
00491 local int i;
00492
00493 for (i=0;i<Profiles.Length;i++)
00494 if (Profiles[i].bReload)
00495 return i;
00496
00497 return -1;
00498 }
00499
00500
00501
00502
00503
00504
00505 function array<string> GetProfileMaps(optional string CurrentProfileItem)
00506 {
00507 local int j;
00508 local ProfileConfigSet PCS;
00509 local array<string> TempMaps;
00510
00511 if (CurrentProfileItem != "")
00512 {
00513 j = int(CurrentProfileItem);
00514 PCS = LadderProfiles[j];
00515 }
00516
00517 if (PCS == None && CurrentProfile!=None)
00518 PCS = CurrentProfile;
00519
00520 if (PCS != None)
00521 TempMaps = PCS.GetUsedMaps();
00522
00523 return TempMaps;
00524 }
00525
00526
00527 function array<string> GetProfileMutators(optional string CurrentProfileItem)
00528 {
00529 local int j;
00530 local ProfileConfigSet PCS;
00531 local array<string> TempString;
00532
00533 if (CurrentProfileItem != "")
00534 {
00535 j = int(CurrentProfileItem);
00536 PCS = LadderProfiles[j];
00537 }
00538
00539 if (PCS == None && CurrentProfile != None)
00540 PCS = CurrentProfile;
00541
00542
00543 if (PCS != none)
00544 TempString = PCS.GetUsedMutators();
00545
00546 return TempString;
00547 }
00548
00549 function array<string> GetProfileServerActors(optional string CurrentProfileItem)
00550 {
00551 local int j;
00552 local ProfileConfigSet PCS;
00553 local array<string> Temp;
00554
00555 if (CurrentProfileItem != "")
00556 {
00557 j = int(CurrentProfileItem);
00558 PCS = LadderProfiles[j];
00559 }
00560
00561 if (PCS == None && CurrentProfile != None)
00562 PCS = CurrentProfile;
00563
00564 if (PCS != None)
00565 Temp = PCS.GetUsedServerActors();
00566
00567 return Temp;
00568 }
00569
00570
00571
00572
00573
00574
00575
00576 protected function InitializeProfileArray()
00577 {
00578 local int i;
00579
00580 LadderProfiles.Length = 0;
00581
00582
00583 for (i = 0; i < Profiles.Length; i++)
00584 LoadProfile(Profiles[i]);
00585 }
00586
00587
00588 protected function LoadProfile(Profile NewProfile, optional string GameType)
00589 {
00590 local int i;
00591
00592 i = LadderProfiles.Length;
00593 LadderProfiles.Length = LadderProfiles.Length + 1;
00594
00595 LadderProfiles[i] = new(None,"Profile"$string(i)) ProfileClass;
00596
00597 if (LadderProfiles[i].GetGameClass() != None)
00598 {
00599 LadderProfiles[i].StartEdit();
00600 LadderProfiles[i].Wipe();
00601 LadderProfiles[i].EndEdit(True);
00602 }
00603
00604 if (GameType == "") LadderProfiles[i].Init(Level);
00605 else LadderProfiles[i].Init(Level,GameType);
00606
00607 AllLadderProfiles.Add(string(i), NewProfile.ProfileName);
00608 }
00609
00610 protected function int ActivateProfile(coerce int ProfileId, optional bool bStoreLast)
00611 {
00612 local int i,j;
00613
00614 if (ProfileId < 0 || ProfileId >= Profiles.Length)
00615 return -1;
00616
00617 i = FindActiveProfile();
00618
00619 if (i == ProfileId) return ProfileId;
00620 j = 0 - 1;
00621
00622 if (i >= 0) j = DeactivateProfile(i);
00623 if (j >= 0)
00624 {
00625 if (bStoreLast) Profiles[j].bReload = True;
00626 else Profiles[j].bReload = False;
00627 }
00628
00629 Profiles[ProfileId].bActive = True;
00630 Profiles[ProfileId].bReload = False;
00631 SaveConfig();
00632 return ProfileId;
00633 }
00634
00635 protected function int DeactivateProfile(coerce int j)
00636 {
00637 if (j < 0 || j > Profiles.Length)
00638 return -1;
00639
00640 Profiles[j].bActive = False;
00641 Index = default.Index;
00642 return j;
00643 }
00644
00645
00646 function UpdateDefaultMaps(String GameType, StringArray Maps)
00647 {
00648 local class<GameInfo> GameClass;
00649 local MapList List;
00650 local int i;
00651
00652 if (Maps == None)
00653 {
00654 Warn(InvalidMaplist);
00655 return;
00656 }
00657 GameClass = class<GameInfo>(DynamicLoadObject(GameType, class'Class'));
00658 if (GameClass != None && GameClass.Default.MapListType != "")
00659 {
00660 List = Level.Game.GetMapList(GameClass.Default.MapListType);
00661 if (List != None)
00662 {
00663 List.Maps.Length = 0;
00664 for (i=0; i<Maps.Count(); i++)
00665 List.Maps[i] = Maps.GetTag(i);
00666
00667 List.MapNum = 0;
00668 List.SaveConfig();
00669 List.Destroy();
00670 }
00671 }
00672 }
00673
00674 function EnableManagedActor(string ActorName)
00675 {
00676 local int i;
00677 local string S;
00678 local class<AutoLoader> A;
00679 local array<string> Arr;
00680
00681 if (SAManager == None) return;
00682
00683 for (i = 0; i < SAManager.LoaderClasses.Length; i++)
00684 {
00685 A = SAManager.LoaderClasses[i].AutoLoaderClass;
00686 if (A == None) continue;
00687
00688 Arr = A.static.GetManagedActors();
00689 while (Arr.Length > 0)
00690 {
00691 S = class'wUtils103.wArray'.static.ShiftS(Arr);
00692 if (ActorName ~= Left(S, InStr(S,",")))
00693 {
00694 A.static.EnableLoader(ActorName);
00695 return;
00696 }
00697 }
00698 }
00699 }
00700
00701 function DisableManagedActor(string ActorName)
00702 {
00703 local int i;
00704 local string S;
00705 local class<AutoLoader> A;
00706 local array<string> Arr;
00707
00708 if (SAManager == None) return;
00709
00710 for (i = 0; i < SAManager.LoaderClasses.Length; i++)
00711 {
00712 A = SAManager.LoaderClasses[i].AutoLoaderClass;
00713 if (A == None) continue;
00714
00715 Arr = A.static.GetManagedActors();
00716 while (Arr.Length > 0)
00717 {
00718 S = class'wUtils103.wArray'.static.ShiftS(Arr);
00719 if (ActorName ~= Left(S, InStr(S,",")))
00720 {
00721 A.static.DisableLoader(ActorName);
00722 return;
00723 }
00724 }
00725 }
00726 }
00727
00728
00729 function string UpdateMutatorString(ProfileConfigSet PCS)
00730 {
00731 local array<string> Mutators;
00732 local string MutatorString;
00733
00734 if (PCS == None)
00735 return "";
00736
00737 Mutators = PCS.GetUsedMutators();
00738 MutatorString = class'wUtils103.wArray'.static.Join(Mutators,",",True);
00739 return MutatorString;
00740 }
00741
00742
00743 final function bool HasURLOption(string ParamName)
00744 {
00745 local string Param, Value;
00746 local int i;
00747
00748 Param = ParamName;
00749 while (true)
00750 {
00751 i = Instr(Param, ".");
00752 if (i < 0)
00753 break;
00754
00755 Param = Mid(Param, i+1);
00756 }
00757
00758 Value = Level.GetUrlOption(Param);
00759 return Value != "";
00760 }
00761
00762 protected function ResetTrackingValues()
00763 {
00764 local int i;
00765 for (i=0;i<Profiles.Length;i++)
00766 {
00767 Profiles[i].bActive = False;
00768 Profiles[i].bReload = False;
00769 }
00770
00771 NumRemainingMatches = 0;
00772 SaveConfig();
00773 }
00774
00775 function int GetRemainingMatches()
00776 {
00777 return NumRemainingMatches;
00778 }
00779
00780 defaultproperties
00781 {
00782 Index=-2
00783 LadderProfileClass="Ladder.ProfileConfigSet"
00784 ShutdownWhileTemporary="Server was shutdown with active temporary profile"
00785 ShutdownWhilePermanent="Server was shutdown with active profile"
00786 ShutdownWhileWaiting="Server was shutdown while waiting to apply a profile. Now applying new profile."
00787 ShutdownRemainingMatches="Number of matches remaining for this profile"
00788 ShutdownResumingTemporary="Reactivating temporary profile with remaining number of matches."
00789 ShutdownResumingPermanent="Reactivating standard profile"
00790 ShutdownTrackingCorrupted="Profile tracking was corrupted. Resetting profile tracking values."
00791 EndOfGame="END OF GAME DETECTED."
00792 EndofGameIntercepting="Intercepting map change & activating profile"
00793 EndofGameNoRemainingMatches="Profile match limit reached. Reactivating previous profile."
00794 OverridingURL="Overriding command line value for parameter"
00795 BadProfileClass="Bad Profile Class"
00796 CannotRemoveActive="Removal of active profile not allowed! Please switch server to a different profile, then try again."
00797 PreviousProfileRemoved="Attempted to return server to previous profile, but no previous profile was found. Leaving server set to current profile."
00798 BadIndex="Invalid profile index"
00799 CancellingProfile="Cancelling activation of profile"
00800 EmptyMaplist="Profile maplist is empty"
00801 InvalidMaplist="Attempting to load profile with invalid maplist!"
00802 CommandLineOptions(0)=(ParamName="CommandLineParams.AdminUserName",Value="")
00803 CommandLineOptions(1)=(ParamName="CommandLineParams.AdminPassword",Value="")
00804 CommandLineOptions(2)=(ParamName="CommandLineParams.GameRules",Value="")
00805 CommandLineOptions(3)=(ParamName="CommandLineParams.DemoRec",Value="")
00806 CommandLineOptions(4)=(ParamName="CommandLineParams.bAutoNumBots",Value="")
00807 CommandLineOptions(5)=(ParamName="CommandLineParams.QuickStart",Value="")
00808 CommandLineOptions(6)=(ParamName="CommandLineParams.RedTeamAI",Value="UnrealGame.TeamAI")
00809 CommandLineOptions(7)=(ParamName="CommandLineParams.BlueTeamAI",Value="UnrealGame.TeamAI")
00810 CommandLineOptions(8)=(ParamName="CommandLineParams.RedTeamSymbol",Value="")
00811 CommandLineOptions(9)=(ParamName="CommandLineParams.BlueTeamSymbol",Value="")
00812 }