I search for solutions in this order: Past Code, Unreal Source, Wiki, BUF, groups.yahoo, google, screaming at monitor. – RegularX

Legacy:LadderQuery

From Unreal Wiki, The Unreal Engine Documentation Site
Revision as of 17:31, 19 March 2003 by Evolution (Talk) (Updating for 1.5)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search
  1. //-----------------------------------------------------------
  2. //  Ladder.LadderQuery
  3. //  QueryHandler for webadmin interface
  4. //-----------------------------------------------------------
  5. class LadderQuery extends xWebQueryHandler
  6. 	DependsOn(ProfileConfigSet)
  7. 	config(System);
  8.  
  9. const LOGNAME		= 'LadderQuery';
  10. const EPICNUMBER    = 85;
  11.  
  12. var LadderGameRules LadderRules;
  13.  
  14. // Profile Tracking Variables
  15. var SessionMaster 			SMaster;
  16. var ConfigMaster			ConfigM;
  17. var string 					EpicPackages[EPICNUMBER];
  18.  
  19. // Active Profile Variables
  20. var StringArray 		ProfileMaps;
  21. var ProfileExporter		ExportMaster;
  22. var ProfileConfigSet 	CurrentProfile;
  23. var StringArray 		ProfileMutators;
  24.  
  25. var string				DefaultProfileName;
  26.  
  27. // Physical page that will be served
  28. var config string		MasterPage;	// This is main html page for Ladder
  29. var config string		SubFrame;	// Manage sub-frame
  30. var config string		SubFrameMenu;	// Sub-menu (GameType, Mutators, Maps, PlayInfo, Review)
  31. var config string		SubFrameContent;
  32.  
  33.  
  34. // Include Files
  35. var config string		IncludeTable;
  36. var config string		IncludeSection;
  37. var config string		IncludeRows;
  38. var config string		IncludeCaptionButton;
  39. var config string		IncludeMapSelect;
  40. var config string		IncludeProfileName;
  41. var config string		IncludeGameType;
  42. var config string		IncludeCheckBox;
  43. var config string		IncludeSwitch;
  44.  
  45. // Virtual paths that will be requested from clients
  46. var config string 		ProfileViewURI;
  47. var config string 		ProfileEditURI;
  48. var config string 		ProfileMenuURI;
  49. var config string 		ProfileSwitchURI;
  50. var config string		ProfileManageURI;
  51.  
  52. var config string		SubFrameURI;	// accessed through manage link - linked to SubFrame page
  53. var config string		SubFrameMenuURI;
  54. var config string 		SubMapsURI;
  55. var config string 		SubSavedURI;
  56. var config string 		SubRulesURI;
  57. var config string 		SubReviewURI;
  58. var config string 		SubGametypeURI;
  59. var config string 		SubMutatorsURI;
  60. var config string		SubImportURI;
  61. var config string		SubExportURI;
  62.  
  63. // Localized Page Help texts
  64. var localized string 	HelpViewProfile;
  65. var localized string 	HelpEditProfile;
  66. var localized string 	HelpSwitchProfile;
  67. var localized string 	HelpManageProfile;
  68. var localized string 	HelpImportProfile;
  69. var localized string 	HelpExportProfile;
  70. // Subpage help text
  71. var localized string	HelpGameType;
  72. var localized string	HelpMutators;
  73. var localized string	HelpMaps;
  74. var localized string	HelpPlayInfo;
  75. var localized string	HelpReview;
  76.  
  77. // Localized Menu Link Text
  78. var localized string 	LinkEditProfile;
  79. var localized string 	LinkViewProfile;
  80. var localized string 	LinkSwitchProfile;
  81. var localized string 	LinkManageProfile;
  82. var localized string 	LinkImportProfile;
  83. var localized string 	LinkExportProfile;
  84.  
  85. // for AddProfilePage/ManageProfilePage
  86. var localized string 	TableTitle[9];
  87. var localized string 	PageCaption[9];
  88. var localized string 	ProfileButtonName[9];
  89. var localized string 	ProfileButtonValue[9];
  90.  
  91. // Section Headers & Text
  92. var localized string	MapText;
  93. var localized string	ErrorText;
  94. var localized string	MutatorText;
  95. var localized string 	RequiredText;
  96. var localized string	AvailableText;
  97. var localized string	UnlimitedText;
  98. var localized string	FollowingMaps;
  99. var localized string	AreAssignedText;
  100. var localized string	AreAvailableText;
  101. var localized string	FollowingMutators;
  102. var localized string	CommandLineOptionsTitle;
  103.  
  104. // Button Values
  105. var localized string 	ButtonLoadProfile;			// Label for "switch immediately" button
  106. var localized string	ButtonDeleteProfile;
  107. var localized string	ButtonPreviewProfile;		// Label for previewing remote profile button
  108. var localized string	ButtonApplyImportProfile;
  109. var localized string	ButtonApplyExportProfile;
  110. var localized string	ButtonApplyProfileChanges;
  111.  
  112. // Input form labels
  113. var localized string	LabelCopyProfile;
  114. var localized string	LabelDeleteProfile;
  115. var localized string	LabelImportProfile;
  116. var localized string	LabelExportProfile;
  117. var localized string	LabelAddProfile;
  118. var localized string	LabelSelectActions;
  119. var localized string	LabelTextboxActions;
  120.  
  121. var localized string	LabelPlayInfo;
  122. var localized string	LabelGeneralProfile;
  123. var localized string	LabelGameType;
  124. var localized string	LabelProfileName;
  125. var localized string	LabelAccessControl;
  126. var localized string	LabelChooseAction;
  127. var localized string	LabelManagement;
  128. var localized string	LabelInputDescription;
  129.  
  130. var localized string 	LabelMaxMaps;
  131. var localized string 	LabelNumberGames;
  132. var localized string	LabelCheckAllMap;
  133. var localized string	LabelRequiredMaps;
  134. var localized string	LabelUncheckAllMap;
  135. var localized string 	LabelChangeMaplist;
  136. var localized string	LabelCheckAllMutator;
  137. var localized string	LabelRequiredMutators;
  138. var localized string	LabelNumberMatchesLeft;
  139. var localized string	LabelUncheckAllMutator;
  140. var localized string	LabelDelayProfileChange;
  141. var localized string	LabelApplyImportProfile;
  142. var localized string	LabelApplyExportProfile;
  143. var localized string	LabelModifyProfile;
  144.  
  145. // Success Messages
  146. var localized string	SuccessText;
  147. var localized string	SuccessDeleteProfile;
  148. var localized string	SuccessExportProfile;
  149. var localized string	SuccessImportProfile;
  150. var localized string	SuccessImportProfileTitle;
  151. var localized string	SuccessCopyProfile;
  152. var localized string	SuccessSwitchProfile;
  153.  
  154. // Profile Errors
  155. var localized string	ErrorLoadingPlayInfoText[5];
  156. var localized string	ErrorGameRulesNotFound;
  157. var localized string	ErrorGameClassText;
  158. var localized string	ErrorGameClassTitle;
  159. var localized string	ErrorAccessControlText;
  160. var localized string	ErrorAccessControlTitle;
  161. var localized string 	ErrorSameProfileName;
  162. var localized string	ErrorRemoteMutator;
  163. var localized string	ErrorRemoteServerActor;
  164. var localized string	ErrorSavingProfile;
  165. var localized string	ErrorDeletingProfile;
  166. var localized string	ErrorExportingProfile;
  167. var localized string	ErrorNoProfilesExist;
  168. var localized string	ErrorCopyFrom;
  169. var localized string	ErrorCopyNoName;
  170. var localized string	ErrorExcludeMapNotFound;
  171. var localized string	ErrorIncludeMapNotFound;
  172. var localized string	ErrorReplacingWebConnection;
  173. var localized string	ImportClassSpawnError;
  174. var localized string	ImportProfileFailText;
  175. var localized string	ImportProfileFailTitle;
  176.  
  177. // Import errors
  178. var localized string	ErrorBind;
  179. var localized string	ErrorBadURL;
  180. var localized string	ErrorServer;
  181. var localized string	ErrorResolve;
  182. var localized string	ErrorProfile;
  183. var localized string	ErrorTimeout;
  184. var localized string	ErrorNotFound;
  185. var localized string	ErrorForbidden;
  186. var localized string	ErrorBadRequest;
  187. var localized string	ErrorUnauthorized;
  188.  
  189. function bool Init()
  190. {
  191. 	local GameRules GR;
  192.  
  193. 	for (GR=Level.Game.GameRulesModifiers;GR!=None;GR=GR.NextGameRules)
  194. 		if (LadderGameRules(GR) != None)
  195. 			LadderRules = LadderGameRules(GR);
  196.  
  197. 	if (LadderRules == None)
  198. 	{
  199. 		Cleanup();
  200. 		return false;
  201. 	}
  202.  
  203. 	if (ConfigM == None && ConfigMaster(Level.Game.BaseMutator.NextMutator) != None)
  204. 		ConfigM = ConfigMaster(Level.Game.BaseMutator.NextMutator);
  205.  
  206. 	GetCurrentConfigSet();
  207. 	ExportMaster 			= new class'ProfileExporter';
  208. 	DefaultProfileName 		= LadderRules.DefaultProfileName;
  209.  
  210. 	SMaster 				= new(None) class'SessionMaster';
  211. 	ProfileMaps 			= new(None) class'SortedStringArray';
  212. 	ProfileMutators 		= new(None) class'SortedStringArray';
  213.  
  214. 	Assert(Level.Game.AccessControl != None);
  215. 	return true;
  216. }
  217.  
  218. //////////////////////////////////////////////////////////////
  219. //////////////////////////////////////////////////////////////
  220. // Session Manipulation Functions
  221. //
  222.  
  223. // Load profile information into session object
  224. function CreateSessionInfo(coerce int ProfileIndex, string SID, optional bool bIncludeNonActive, optional bool bSave, optional bool bQuiet)
  225. {
  226.     local int 										i;
  227.     local Session 									CurS;
  228.     local string 									TempStr;
  229.     local array<string> 							TempArr;
  230.     local ProfileConfigSet 							TempPCS;
  231.     local array<ProfileConfigSet.ProfileMutator> 	AllPCSMutators;
  232.     local array<ProfileConfigSet.ProfileMap> 		AllPCSMaps;
  233.     local array<ProfileConfigSet.ProfileSA> AllPCSServerActors;
  234.  
  235.     if (SID == "")
  236.         return;
  237.  
  238.     CurS = SMaster.getSession(SID,true);
  239. 	TempPCS = LadderRules.LadderProfiles[ProfileIndex];
  240. 	TempPCS.StartEdit();
  241.  
  242. // General profile information
  243.     CurS.setValue("ProfileIndex", string(ProfileIndex), true);
  244. 	CurS.setValue("ProfileName",LadderRules.Profiles[ProfileIndex].ProfileName,true);
  245. 	CurS.setValue("GameType", string(TempPCS.GetGameClass()), True);
  246. 	CurS.setValue("ACClass", TempPCS.GetAccessControl(), True);
  247. 	CurS.setValue("MaxMaps", string(TempPCS.GetMaxMaps()), True);
  248.  
  249. 	AllPCSMutators = TempPCS.GetProfileMutators();
  250. 	AllPCSMaps = TempPCS.GetProfileMaps();
  251. 	AllPCSServerActors = TempPCS.GetProfileServerActors();
  252.  
  253.     TempArr = LadderRules.GetProfileMutators(string(ProfileIndex));
  254.     TempStr = class'wUtils103.wArray'.static.Join(TempArr,",");
  255.  
  256. // Load profile mutator information
  257.     CurS.ClearMutators();
  258. 	for (i=0;i<AllPCSMutators.Length;i++)
  259. 	   if (AllPCSMutators[i].bRequired || (InStr(TempStr,AllPCSMutators[i].MutatorName)!=-1) || bIncludeNonActive)
  260. 	       CurS.setMutator(AllPCSMutators[i].MutatorName,True,AllPCSMutators[i].bRequired);
  261.  
  262.     TempArr = LadderRules.GetProfileMaps(string(ProfileIndex));
  263.     TempStr = class'wUtils103.wArray'.static.Join(TempArr,",");
  264.  
  265. // Load profile map information
  266.     CurS.ClearMaps();
  267. 	for (i=0;i<AllPCSMaps.Length;i++)
  268. 	   if (AllPCSMaps[i].bRequired || (InStr(TempStr,AllPCSMaps[i].MapName)!=-1) || bIncludeNonActive)
  269.     	   CurS.setMap(AllPCSMaps[i].MapName,AllPCSMaps[i].MapListOrder,True,AllPCSMaps[i].bRequired);
  270.  
  271. 	TempArr = LadderRules.GetProfileServerActors(string(ProfileIndex));
  272. 	TempStr = class'wUtils103.wArray'.static.Join(TempArr,",");
  273.  
  274. // Load ServerActor info
  275. 	CurS.ClearServerActors();
  276. 	for (i=0;i<AllPCSServerActors.Length;i++)
  277. 		if (AllPCSServerActors[i].bRequired || InStr(TempStr,AllPCSServerActors[i].ActorClass)!=-1 || bIncludeNonActive)
  278. 			CurS.setServerActor(AllPCSServerActors[i].ActorClass, True, AllPCSServerActors[i].bRequired);
  279.  
  280. // Load profile PlayInfo data
  281. 	for (i=0;i<TempPCS.Count();i++)
  282.         CurS.setValue(TempPCS.GetProfileParamName(i),TempPCS.GetProfileParam(i),True);
  283.  
  284.     TempPCS.EndEdit(bSave,bQuiet);
  285. }
  286.  
  287. // Initialize session data for recently imported profile
  288. function ProfileConfigSet CreateImportSessionInfo(Session CurS)
  289. {
  290. 	local int						i;
  291. 	local string 					TempStr, Tmp;
  292. 	local PlayInfo					TempPI;
  293. 	local ProfileConfigSet 			TempPCS;
  294.  
  295. 	local class<Mutator>			Mut${1}< ${3} >
  296. 	local class<GameInfo> 			GI${1}< ${3} >
  297. 	local class<AccessControl> 		AC${1}< ${3} >
  298. 	local class<Info>				ServerActor${1}< ${3} >
  299. 	local array<class<Info> >		SA${1}< ${3} >
  300. 	local array<class<Mutator> > 	M${1}< ${3} >
  301.  
  302. 	TempPCS = LadderRules.AddProfile(CurS.getValue("ProfileName"),CurS.getValue("GameType"));
  303. 	if (TempPCS.StartEdit())
  304. 	{
  305. 		TempStr = CurS.getValue("GameType");
  306. 		if (TempStr != "")
  307. 			GIClass = class<GameInfo>(DynamicLoadObject(TempStr,class'Class'));
  308. 		if (GIClass == None) return None;
  309.  
  310. 		TempStr = CurS.getValue("ACClass",Level.Game.AccessControlClass);
  311. 		if (TempStr != "")
  312. 			ACClass = class<AccessControl>(DynamicLoadObject(TempStr,class'Class'));
  313. 		if (ACClass == None) return None;
  314.  
  315. 		TempPI = new(None) class'PlayInfo';
  316.  
  317. // Mutators
  318. 		for (i=0;i<CurS.getMutatorLength();i++)
  319. 		{
  320. 			TempStr = CurS.getMutator(i);
  321. 			MutClass = class<Mutator>(DynamicLoadObject(TempStr, class'Class'));
  322. 			if (MutClass != None)
  323. 			{
  324. 				MClass[MClass.Length] = Mut${1}< ${3} >
  325. 				TempPCS.AddProfileMutator(TempStr,CurS.MutRequired(TempStr));
  326. 			}
  327.  
  328. 			else log(ErrorRemoteMutator@TempStr,LOGNAME);
  329. 		}
  330.  
  331. 		for (i=0;i<CurS.getSALength();i++)
  332. 		{
  333. 			TempStr = CurS.getServerActor(i);
  334. 			ServerActorClass = class<Info>(DynamicLoadObject(TempStr,class'Class'));
  335. 			if (ServerActorClass != None)
  336. 			{
  337. 				SAClass[SAClass.Length] = ServerActor${1}< ${3} >
  338. 				TempPCS.AddProfileServerActor(TempStr,CurS.SARequired(TempStr));
  339. 			}
  340. 			else log(ErrorRemoteServerActor@TempStr,LOGNAME);
  341. 		}
  342.  
  343. 		LoadThisPlayInfo(TempPI, GIClass, ACClass, MClass, SAClass);
  344.  
  345. // Maps
  346. 		for (i=0;i<CurS.getMapLength();i++)
  347. 		{
  348. 			TempStr = CurS.getMap(i);
  349. 			TempPCS.AddProfileMap(TempStr,CurS.MapRequired(TempStr));
  350. 		}
  351.  
  352. // PlayInfo
  353. 		for (i=0;i<TempPI.Settings.Length;i++)
  354. 		{
  355. 			TempStr = ""; Tmp="";
  356. 			if (CurS.getIdValue(i,TempStr,Tmp) == -1)
  357. 				break;
  358. 			if ( !SettingIsAllowed(TempPI.Settings[i].SecLevel) ) continue;
  359. 			if (!TempPCS.SetProfileNamedParam(TempPI.Settings[i].SettingName, CurS.getValue(TempPI.Settings[i].SettingName,TempPI.Settings[i].Value)))
  360. 				TempPCS.SetProfileParam(TempPCS.Count(),TempPI.Settings[i].SettingName,CurS.getValue(TempPI.Settings[i].SettingName,TempPI.Settings[i].Value));
  361. 		}
  362.  
  363. 		TempPCS.EndEdit(True);
  364. 		return TempPCS;
  365. 	}
  366.  
  367. 	else log(ErrorServer,LOGNAME);
  368.  
  369. 	return None;
  370. }
  371.  
  372. // Clear session data and optionally create new session object
  373. function string ResetSessionID(Session CurS, optional bool bDestroySession)
  374. {
  375. 	local string OldSID;
  376.  
  377. 	if (bDestroySession) SMaster.destroySession(CurS);
  378. 	else CurS.ResetSession();
  379.  
  380. 	CurS = SMaster.getSession(OldSID,true);
  381. 	return CurS.GetHash();
  382. }
  383.  
  384.  
  385. ////////////////////////////////////////////////////////////
  386. ////////////////////////////////////////////////////////////
  387. // Profile manipulation methods
  388. //
  389.  
  390. function int LoadThisPlayInfo(PlayInfo PI, class<GameInfo> ThisGameInfo, class<AccessControl> ThisAccessControl, array<class<Mutator> > ThisMutator, array<class<Info> > ThisServerActor)
  391. {
  392. 	local int i;
  393. 	local class<Mutator> M;
  394.  
  395. 	if (PI == None)
  396. 		return 0;
  397. 	PI.Clear();
  398.  
  399. 	if (ThisGameInfo == None)
  400. 		return 1;
  401.  
  402. 	if (ThisAccessControl == None)
  403. 		return 2;
  404.  
  405. 	if (ThisMutator.Length > 0)
  406. 		for (i=0;i<ThisMutator.Length;i++)
  407. 			if (ThisMutator[i] == None)
  408. 				return 3;
  409.  
  410. 	if (ThisServerActor.Length > 0)
  411. 		for (i=0;i<ThisServerActor.Length;i++)
  412. 			if (ThisServerActor[i] == None)
  413. 				return 4;
  414.  
  415. 	ThisGameInfo.static.FillPlayInfo(PI);
  416. 	PI.PopClass();
  417.  
  418. 	if (ThisGameInfo.default.MutatorClass != "")
  419. 	{
  420. 		M = class<Mutator>(DynamicLoadObject(ThisGameInfo.default.MutatorClass,class'Class'));
  421. 		if (M != None)
  422. 			M.static.FillPlayInfo(PI);
  423. 	}
  424.  
  425. 	ThisAccessControl.static.FillPlayInfo(PI);
  426. 	PI.PopClass();
  427.  
  428. 	for (i = 0; i < ThisMutator.Length; i++)
  429. 	{
  430. 		ThisMutator[i].static.FillPlayInfo(PI);
  431. 		PI.PopClass();
  432. 	}
  433.  
  434. 	for (i = 0; i < ThisServerActor.Length; i++)
  435. 	{
  436. 		ThisServerActor[i].static.FillPlayInfo(PI);
  437. 		PI.PopClass();
  438. 	}
  439.  
  440. 	class'CommandLineParams'.static.FillPlayInfo(PI);
  441. 	PI.PopClass();
  442.  
  443. 	return -1;
  444. }
  445.  
  446. function ProfileConfigSet GetCurrentConfigSet()
  447. {
  448. 	local int i;
  449.  
  450. 	if (CurrentProfile == None)
  451. 	{
  452. 		i = LadderRules.FindActiveProfile();
  453. 		if (i >= 0)	CurrentProfile = LadderRules.LadderProfiles[i];
  454. 	}
  455.  
  456. 	return CurrentProfile;
  457. }
  458.  
  459. function int GetCurrentConfigIndex()
  460. {
  461. 	local int i;
  462.  
  463. 	if (CurrentProfile != None)
  464. 		for (i = 0;i < LadderRules.LadderProfiles.Length;i++)
  465. 			if (LadderRules.LadderProfiles[i] == CurrentProfile)
  466. 				return i;
  467.  
  468. 	return LadderRules.FindActiveProfile();
  469. }
  470.  
  471. // Returns an array of class names for mutators that this profile will use in the game
  472. function array<string> LoadActiveProfileMutators(optional string CurrentProfileItem)
  473. {
  474. 	return LadderRules.GetProfileMutators(CurrentProfileItem);
  475. }
  476.  
  477. function array<string> LoadActiveProfileServerActors(optional string CurrentProfileItem)
  478. {
  479. 	return LadderRules.GetProfileServerActors(CurrentProfileItem);
  480. }
  481.  
  482. // Returns an array of map names that in the maplist for this profile
  483. function array<string> LoadActiveProfileMaps(optional string CurrentProfileItem)
  484. {
  485. 	return LadderRules.GetProfileServerActors(CurrentProfileItem);
  486. }
  487. /*
  488. function CreateFullMutatorList(out StringArray Mutators, out StringArray GroupsOnly)
  489. {
  490. 	local StringArray Grouped;
  491. 	local int i,j,z;
  492. 	local string GrpName;
  493. 	local string thisgroup, nextgroup;
  494.  
  495. // This class provides a specialized sorting function
  496. // since mutators may be grouped - mutators in the same groups
  497. // are not allowed to be selected togther
  498.  
  499. 	Grouped = new(None) class'SortedStringArray';
  500.  
  501. // Create array sorted on GroupName...this allows to flag
  502. // the mutator for a different .inc file
  503. 	for (i = 0; i < Mutators.Count(); i++)
  504. 	{
  505. 		j = int(Mutators.GetItem(i));
  506.  
  507. // If the mutator author forgot to configure a group name for the mutator
  508. 		if (AllMutators[j].GroupName == "")
  509. 			GrpName = "Z" $ string (z++);
  510. 		else GrpName = AllMutators[j].GroupName;
  511.  
  512. 		Grouped.Add(string(j),GrpName $ "." $ AllMutators[j].FriendlyName);
  513. 	}
  514.  
  515. // Move all grouped mutators to GroupsOnly StringArray for sorting by friendly name
  516. 	for (i=0;i<Grouped.Count();i++)
  517. 	{
  518. 		thisgroup = AllMutators[int(Grouped.GetItem(i))].GroupName;
  519. 		nextgroup = "";
  520.  
  521. 		if (thisgroup=="")
  522. 			continue;
  523. 		if (i+1<Grouped.Count())
  524. 			nextgroup = AllMutators[int(Grouped.GetItem(i+1))].GroupName;
  525.  
  526. 		if (thisgroup ~= nextgroup)
  527. 		{
  528. 			j=i;
  529. 			while(nextgroup~=thisgroup && j<Grouped.Count())
  530. 			{
  531. 				GroupsOnly.MoveFromId(Grouped, Grouped.FindItemId(Grouped.GetItem(j)));
  532. 				thisgroup = nextgroup;
  533. 				if (j+1==Grouped.Count())
  534. 					nextgroup="";
  535. 				else nextgroup = AllMutators[int(Grouped.GetItem(j+1))].GroupName;
  536. 			}
  537. 			if (j<Grouped.Count())
  538. 				GroupsOnly.MoveFromId(Grouped,Grouped.FindItemId(Grouped.GetItem(j)));
  539. 			i=-1;
  540. 		}
  541. 	}
  542.  
  543. // Move all non-grouped mutators back to Mutators array
  544. // for re-sorting by Friendly Name
  545. 	Mutators.Reset();
  546. 	for (i=0;i<Grouped.Count();i++)
  547. 	{
  548. 		j=int(Grouped.GetItem(i));
  549. 		Mutators.Add(string(j),AllMutators[j].FriendlyName);
  550. 	}
  551. 	Grouped.Reset();
  552. }
  553. */
  554. //****************************************************************
  555. //****************************************************************
  556. // Helper functions
  557. //
  558. //****************************************************************
  559. //**************************
  560. // HTML Generation
  561. //*************************
  562.  
  563. // Creates a listing of PlayInfo data
  564. // Pass "defaults_row" in the 'IncludeFile' param to add the
  565. // input form objects to the output
  566.  
  567. function string GeneratePlayInfoRows(WebRequest Req, WebResponse Res, string IncludeFile)
  568. {
  569. 	local int i,j,k,z;
  570. 	local string 	TempStr, Data, Op, SID,
  571. 					TempRow, HeadingRow, PlayInfoRows;
  572.  
  573. 	local Session 		CurS;
  574. 	local PlayInfo 		TempPI;
  575. 	local StringArray 	Info, InfoC, InfoS, InfoT;
  576.  
  577. 	local array<string> 		Options;
  578. 	local class<Mutator> 		TempMut;
  579. 	local class<Info>			TempSA;
  580. 	local class<GameInfo> 		GI${1}< ${3} >
  581. 	local class<AccessControl> 	AC${1}< ${3} >
  582. 	local array<class<Mutator> > M${1}< ${3} >
  583. 	local array<class<Info> >	SA${1}< ${3} >
  584.  
  585. 	SID = Req.GetVariable("SessionID");
  586. 	CurS = SMaster.GetSession(SID);
  587.  
  588. 	TempStr = CurS.getValue("GameType");
  589. 	if (TempStr != "")
  590. 		GIClass = class<GameInfo>(DynamicLoadObject(TempStr,class'Class'));
  591. 	if (GIClass == None)
  592. 	{
  593. 		ShowMessage(Res,ErrorGameClassTitle,ErrorGameClassText);
  594. 		return "";
  595. 	}
  596.  
  597. 	TempStr = CurS.getValue("ACClass",Level.Game.AccessControlClass);
  598. 	if (TempStr != "")
  599. 		ACClass = class<AccessControl>(DynamicLoadObject(TempStr,class'Class'));
  600. 	if (ACClass == None)
  601. 	{
  602. 		ShowMessage(Res,ErrorAccessControlTitle,ErrorAccessControlText);
  603. 		return "";
  604. 	}
  605.  
  606. 	for (i=0;i<CurS.GetMutatorLength();i++)
  607. 	{
  608. 		TempStr = CurS.getMutator(i);
  609. 		if (TempStr != "")
  610. 		{
  611. 			TempMut = class<Mutator>(DynamicLoadObject(TempStr,class'Class'));
  612. 			if (TempMut != None)
  613. 				MClass[MClass.Length] = TempMut;
  614. 		}
  615. 	}
  616.  
  617. 	for (i=0;i<CurS.getSALength();i++)
  618. 	{
  619. 		TempStr = CurS.getServerActor(i);
  620. 		if (TempStr != "")
  621. 		{
  622. 			TempSA = class<Info>(DynamicLoadObject(TempStr,class'Class'));
  623. 			if (TempSA != None)
  624. 				SAClass[SAClass.Length] = TempSA;
  625. 		}
  626. 	}
  627.  
  628. 	// Initialize and fill PlayInfo
  629. 	TempPI = new(None) class'PlayInfo';
  630. 	LoadThisPlayInfo(TempPI, GIClass, ACClass, MClass, SAClass);
  631.  
  632. 	for (i=0;i<TempPI.Settings.Length;i++)
  633. 		if (CurS.HasData(TempPI.Settings[i].SettingName))
  634. 			TempPI.StoreSetting(i, CurS.getValue(TempPI.Settings[i].SettingName,TempPI.Settings[i].Value));
  635.  
  636. 	InfoC = new(None) class'SortedStringArray';	// Checkboxes
  637. 	InfoS = new(None) class'SortedStringArray';	// Selects
  638. 	InfoT = new(None) class'SortedStringArray';	// Textboxes
  639. 	Info  = new(None) class'SortedStringArray';	// Contains each unique ClassFrom value
  640.  
  641. 	// Want to allow admin to input values for each setting
  642. 	if (IncludeFile ~= "defaults_row")
  643. 	{
  644. 		for (i=0;i<TempPI.Settings.Length;i++)
  645. 		{
  646. 			if (TempPI.Settings[i].RenderType~="Text")
  647. 			{
  648. 				// Hack for MOTD sorting
  649. 				if (Left(TempPI.Settings[i].SettingName,Len(TempPI.Settings[i].SettingName) - 1) ~= "GameReplicationInfo.MOTDLine")
  650. 					InfoT.Add(string(i), TempPI.Settings[i].SettingName);
  651. 				else InfoT.Add(string(i),TempPI.Settings[i].DisplayName);
  652. 			}
  653.  
  654. 			else if (TempPI.Settings[i].RenderType~="Check")
  655. 				InfoC.Add(string(i),TempPI.Settings[i].DisplayName);
  656.  
  657. 			else if (TempPI.Settings[i].RenderType~="Select")
  658. 				InfoS.Add(string(i),TempPI.Settings[i].DisplayName);
  659.  
  660. 			for (j=0;j<Info.Count();j++)
  661. 				if (Info.GetTag(j) ~= string(TempPI.Settings[i].ClassFrom))
  662. 					break;
  663.  
  664. 			if (j == Info.Count())
  665. 				Info.Add(string(i), string(TempPI.Settings[i].ClassFrom));
  666. 		}
  667.  
  668. 		for (k=0;k<Info.Count();k++)
  669. 		{
  670. 			TempRow = ""; HeadingRow = "";
  671. 			Res.Subst("RowContent", "<td class=ttext colspan=\"3\">"$Info.GetTag(k)$"</td>");
  672. 			HeadingRow = WebInclude(RowLeft);
  673.  
  674. 			for (i=0;i<InfoC.Count();i++)
  675. 			{
  676. 				TempStr = "";
  677. 				j=int(InfoC.GetItem(i));
  678. 				if (!SettingIsAllowed(TempPI.Settings[j].SecLevel) || (string(TempPI.Settings[j].ClassFrom)!=Info.GetTag(k)))
  679. 					continue;
  680.  
  681. 				Res.Subst("Content", Checkbox(TempPI.Settings[j].SettingName, TempPI.Settings[j].Value ~= "True", TempPI.Settings[j].Data != ""));
  682. 				TempStr = WebInclude(CellLeft);
  683.  
  684. 				Res.Subst("Content", "<span class=location title=\"Required Security Level\">"$TempPI.Settings[j].SecLevel$"</span>");
  685. 				TempStr += WebInclude(CellLeft);
  686.  
  687. 				Res.Subst("Content", "<span class='location'>"$HtmlEncode(TempPI.Settings[j].DisplayName)$"</span>");
  688. 				Res.Subst("RowContent", WebInclude(CellLeft) $ TempStr);
  689. 				TempRow += WebInclude(RowLeft);
  690. 			}
  691.  
  692. 			for (i=0;i<InfoT.Count();i++)
  693. 			{
  694. 				TempStr = "";
  695. 				j = int(InfoT.GetItem(i));
  696. 				if (!SettingIsAllowed(TempPI.Settings[j].SecLevel) || (string(TempPI.Settings[j].ClassFrom)!=Info.GetTag(k)))
  697. 					continue;
  698.  
  699. 				Data = "8";
  700. 				if (TempPI.Settings[j].Data != "")
  701. 				{
  702. 					Data = TempPI.Settings[j].Data;
  703. 					Divide(TempPI.Settings[j].Data, ";", Data, Op);
  704. 					TempPI.SplitStringToArray(Options, Op, ":");
  705. 				}
  706.  
  707. 				Op = "";
  708. 				if (Options.Length > 1)
  709. 					Op = " ("$Options[0]$" - "$Options[1]$")";
  710.  
  711. 				Res.Subst("Content", Textbox(TempPI.Settings[j].SettingName, Data, 3 * int(Data), TempPI.Settings[j].Value) $ Op);
  712. 				TempStr = WebInclude(CellLeft);
  713.  
  714. 				Res.Subst("Content", "<span class=location title=\"Required Security Level\">"$TempPI.Settings[j].SecLevel$"</span>");
  715. 				TempStr += WebInclude(CellLeft);
  716.  
  717. 				Res.Subst("Content", "<span class='location'>"$HtmlEncode(TempPI.Settings[j].DisplayName)$"</span>");
  718. 				Res.Subst("RowContent", WebInclude(CellLeft) $ TempStr);
  719. 				TempRow += WebInclude(RowLeft);
  720. 			}
  721.  
  722. 			for (i=0;i<InfoS.Count();i++)
  723. 			{
  724. 				Data = ""; TempStr = "";
  725. 				j=int(InfoS.GetItem(i));
  726. 				if (!SettingIsAllowed(TempPI.Settings[j].SecLevel) || (string(TempPI.Settings[j].ClassFrom)!=Info.GetTag(k)))
  727. 					continue;
  728. 				// Build a set of options from PID.Data
  729. 				TempPI.SplitStringToArray(Options, TempPI.Settings[j].Data, ";");
  730. 				for (z = 0; (z+1)<Options.Length; z += 2)
  731. 				{
  732. 					Data += ("<option value='"$Options[z]$"'");
  733. 					If (TempPI.Settings[j].Value == Options[z])
  734. 						Data @= "selected";
  735. 					Data += (">"$HtmlEncode(Options[z+1])$"</option>");
  736. 				}
  737.  
  738. 				Res.Subst("Content", Select(TempPI.Settings[j].SettingName, Data));
  739. 				TempStr = WebInclude(CellLeft);
  740.  
  741. 				Res.Subst("Content", "<span class=location title=\"Required Security Level\">"$TempPI.Settings[j].SecLevel$"</span>");
  742. 				TempStr += WebInclude(CellLeft);
  743.  
  744. 				Res.Subst("Content", "<span class='location'>"$HtmlEncode(TempPI.Settings[j].DisplayName)$"</span>");
  745. 				Res.Subst("RowContent", WebInclude(CellLeft) $ TempStr);
  746. 				TempRow += WebInclude(RowLeft);
  747. 			}
  748.  
  749. 			if (TempRow!="")
  750. 				PlayInfoRows += (HeadingRow$TempRow);
  751. 		}
  752. 	}
  753. 	else	// Displaying values only
  754. 	{
  755. 		for (i=0;i<TempPI.Settings.Length;i++)
  756. 		{
  757. 			if (Left(TempPI.Settings[i].SettingName,Len(TempPI.Settings[i].SettingName) - 1) ~= "GameReplicationInfo.MOTDLine")
  758. 				InfoS.Add(string(i), TempPI.Settings[i].SettingName);
  759. 			else InfoS.Add(string(i),TempPI.Settings[i].DisplayName);
  760.  
  761. 			for (j=0;j<Info.Count();j++)
  762. 				if (Info.GetTag(j) ~= string(TempPI.Settings[i].ClassFrom))
  763. 					break;
  764. 			if (j == Info.Count())
  765. 				Info.Add(string(i), string(TempPI.Settings[i].ClassFrom));
  766. 		}
  767.  
  768. 		for (k=0;k<Info.Count();k++)
  769. 		{
  770. 			TempRow = "";
  771. 			HeadingRow = "<tr><td class=ttext colspan=\"2\">"$Info.GetTag(k)$"</td></tr>";
  772. 			for (i=0;i<InfoS.Count();i++)
  773. 			{
  774. 				j=int(InfoS.GetItem(i));
  775. 				Data = "";
  776.  
  777. 				if (!SettingIsAllowed(TempPI.Settings[j].SecLevel) || (string(TempPI.Settings[j].ClassFrom)!=Info.GetTag(k)))
  778. 					continue;
  779.  
  780. 				Res.Subst("SettingName", HtmlEncode(TempPI.Settings[j].DisplayName));
  781.  
  782. 				if (TempPI.Settings[j].Value ~= "true")
  783. 					Data = "True";
  784.  
  785. 				else if (TempPI.Settings[j].Value ~= "false")
  786. 					Data = "False";
  787.  
  788. 				else
  789. 				{
  790. 					if (TempPI.Settings[j].RenderType ~= "Select")
  791. 					{
  792. 						class'wUtils103.wString'.static.Split2(TempPI.Settings[j].Data, ";", Options);
  793. 						for (z=0;(z+1)<Options.Length;z+=2)
  794. 						{
  795. 							if (TempPI.Settings[j].Value == Options[z])
  796. 							{
  797. 								Data = Options[z+1];
  798. 								break;
  799. 							}
  800. 						}
  801. 					}
  802. 					else Data = TempPI.Settings[j].Value;
  803. 				}
  804.  
  805. 				Res.Subst("SettingData", HtmlEncode(Data));
  806. 				Res.Subst("Extra", "");
  807. 				TempRow += WebInclude(IncludeFile);
  808. 			}
  809.  
  810. 			if (TempRow!="")
  811. 				PlayInfoRows += (HeadingRow$TempRow);
  812. 		}
  813. 	}
  814. 	return PlayInfoRows;
  815. }
  816.  
  817. // Creates the drop-down box containing profiles names
  818. function String GenerateSwitchProfileOptions(optional string CurrentProfileItem)
  819. {
  820. 	local int i;
  821. 	local string SelectedStr, OptionStr;
  822.  
  823. 	if (LadderRules.AllLadderProfiles.Count() == 0)
  824. 		return "<option value=\"\">***"@NoneText@"***</option>";
  825.  
  826. 	for (i=0; i < LadderRules.AllLadderProfiles.Count(); i++)
  827. 	{
  828. 	// This item was the item passed in by CurrentProfileItem, so make it active
  829. 		if (CurrentProfileItem ~= LadderRules.AllLadderProfiles.GetItem(i))
  830. 			SelectedStr = " selected";
  831. 		else SelectedStr = "";
  832.  
  833. 		OptionStr = OptionStr$"<option value=\""$LadderRules.AllLadderProfiles.GetItem(i)$"\""$SelectedStr$">"$LadderRules.AllLadderProfiles.GetTag(i)@"</option>";
  834. 	}
  835. 	return OptionStr;
  836. }
  837.  
  838. function bool SettingIsAllowed(byte SettingSecLevel)
  839. {
  840. 	return SettingSecLevel <= CurAdmin.MaxSecLevel();
  841. }
  842.  
  843. // Handles generation of the double map select boxes (Exclude & Include)
  844. function String CreateMapListSelect(array<ProfileConfigSet.ProfileMap> AllPCSMaps, StringArray MapList, StringArray MovedMaps)
  845. {
  846. 	local int i,j;
  847. 	local String ResponseStr, SelectedStr, Tmp;
  848.  
  849. 	if (MapList.Count() == 0)
  850. 		return "<option value=\"\">***"@NoneText@"***</option>";
  851.  
  852. 	for (i = 0; i<MapList.Count(); i++)
  853. 	{
  854. 	// Index for map within AllPCSMaps
  855. 		j = int(MapList.GetItem(i));
  856.  
  857. 		Tmp = AllPCSMaps[j].MapName;
  858. 		SelectedStr = "";
  859. 		if (MovedMaps != None && MovedMaps.FindItemId(string(j)) >= 0)
  860. 			SelectedStr = " selected";
  861. 		ResponseStr = ResponseStr$"<option value=\""$Tmp$"\""$SelectedStr$">"$Tmp$"</option>";
  862. 	}
  863.  
  864. 	return ResponseStr;
  865. }
  866.  
  867. //**********************
  868. // Import / Export
  869. //**********************
  870.  
  871. // Handles spacing for textboxes on export page
  872. function int GetLongestURL()
  873. {
  874. 	local int i, Current, Largest;
  875.  
  876. 	for (i = 0; i < ExportMaster.Zips.Length; i++)
  877. 	{
  878. 		Current = Len(ExportMaster.Zips[i].ZipURL);
  879. 		if (Current > Largest)
  880. 			Largest = Current;
  881. 	}
  882.  
  883. 	return Largest + 1;
  884. }
  885.  
  886. // Handles filling in zip-location textboxes on export page
  887. function string GetLocation(string Package)
  888. {
  889. 	local int i;
  890.  
  891. 	// Check if we're dealing with a map or a mutator
  892. 	i = InStr(Package, ".");
  893.  
  894. 	// Dealing with a mutator - remove class name
  895. 	if (i != -1)
  896. 		Package = Left(Package, i);
  897.  
  898. 	return ExportMaster.FindZipLocation(Package);
  899. }
  900.  
  901. // Handles saving zip file locations from export page
  902. function SetLocation(string Package, string NewLocation)
  903. {
  904. 	local int i;
  905.  
  906. 	// Check if we're dealing with a map or a mutator
  907. 	i = InStr(Package, ".");
  908.  
  909. 	// Dealing with a mutator - remove class name
  910. 	if (i != -1)
  911. 		Package = Left(Package, i);
  912.  
  913. 	if (NewLocation == "")
  914. 		ExportMaster.DeleteZipLocation(Package);
  915. 	else ExportMaster.AddZipLocation(Package, NewLocation);
  916. }
  917.  
  918. // Utility function to remove strings from profile names before
  919. // creating .txt for exported profile
  920. function string RemoveStr(string Source,string mask)
  921. {
  922. 	local int i;
  923. 	local string left,right;
  924.  
  925. 	i = InStr(Source,mask);
  926. 	while (i != -1)
  927. 	{
  928. 		Divide(Source,mask,left,right);
  929. 		Source = Left$Right;
  930. 		i = InStr(Source,Mask);
  931. 	}
  932.  
  933. 	return Source;
  934. }
  935.  
  936. // Prevents entering a zip file location for any package
  937. // that is already included with the game
  938. function bool EpicPackage(string Package)
  939. {
  940. 	local int i;
  941.  
  942. 	// Check if we're dealing with a map or a mutator
  943. 	i = InStr(Package, ".");
  944.  
  945. 	// Dealing with a mutator - remove class name
  946. 	if (i != -1)
  947. 		Package = Left(Package, i);
  948.  
  949. 	for (i = 0;i < EPICNUMBER; i++)
  950. 		if (Package ~= EpicPackages[i])
  951. 			return true;
  952. 	return false;
  953. }
  954.  
  955. function CheckSettingValue(string SettingData, out string NewValue)
  956. {
  957. 	local string sMaxLength, sMinMax, sMin, sMax;
  958. 	local int iMaxLength, iMin, iMax, iValue;
  959. 	local float fMin, fMax, fValue;
  960. 	local bool bFloat;
  961.  
  962. 	if (SettingData == "")
  963. 		return;
  964.  
  965. // This setting has no valid min/max (it is a password setting or something)
  966. 	if (InStr(SettingData,";") < 0 )
  967. 	{
  968. 		// Allow only up to three times the configured max length
  969. 		iMaxLength = 3 * int(SettingData);
  970. 		if (Len(NewValue) > iMaxLength)
  971. 			NewValue = Left(NewValue,iMaxLength);
  972. 		return;
  973. 	}
  974.  
  975. 	Divide(SettingData,";",sMaxLength,sMinMax);	// Split the Max Length & MinMax Info
  976. 	Divide(sMinMax,":",sMin,sMax);				// Split the Min & Max info for casting
  977. 	iMaxLength = int(sMaxLength);
  978. 	if ( InStr(sMin,".") >= 0 || InStr(sMax,".") >= 0)	// Are we dealing with floating point numbers?
  979. 	{
  980. 		bFloat = True;
  981. 		fMin = float(sMin);
  982. 		fMax = float(sMax);
  983. 	}
  984.  
  985. 	else
  986. 	{
  987. 		iMin = int(sMin);
  988. 		iMax = int(sMax);
  989. 	}
  990.  
  991. 	// First check for length
  992. 	if (Len(NewValue) > iMaxLength)
  993. 		NewValue = Left(NewValue,iMaxLength);
  994.  
  995. 	if (bFloat)
  996. 	{
  997. 		fValue = float(NewValue);
  998. 		fValue = FClamp(fValue,fMin,fMax);
  999. 		NewValue = string(fValue);
  1000. 	}
  1001. 	else
  1002. 	{
  1003. 		iValue = int(NewValue);
  1004. 		iValue = Clamp(iValue,iMin,iMax);
  1005. 		NewValue = string(iValue);
  1006. 	}
  1007. }
  1008. //*****************************************************************************
  1009. //*****************************************************************************
  1010. // Query Methods
  1011. //
  1012. //
  1013.  
  1014. // Passes the SessionID variable to all pages in this query action
  1015. // if SessionID is not present in WebRequest, generates one
  1016. // (Helpful when dealing with frames)
  1017. function bool PreQuery(WebRequest Req, WebResponse Res)
  1018. {
  1019. 	local string SID;
  1020.  
  1021. 	SID = Req.GetVariable("SessionID");
  1022. 	if (SID == "")
  1023. 	{
  1024. 		SID = SMaster.getSession("xxxxx",true).GetHash();
  1025. 		Req.AddVariable("SessionID", SID);
  1026. 	}
  1027. 	Res.Subst("SessionID", SID);
  1028. 	return true;
  1029. }
  1030.  
  1031. function bool Query(WebRequest Request, WebResponse Response)
  1032. {
  1033. 	switch (Mid(Request.URI, 1))
  1034. 	{
  1035. 	case DefaultPage: 		if (!MapIsChanging()) QueryLadderFrame(Request, Response);		return true;
  1036. 	case ProfileMenuURI:	if (!MapIsChanging()) QueryLadderMenu(Request, Response);		return true;
  1037. 	case ProfileViewURI:	if (!MapIsChanging()) QueryLadderView(Request, Response);		return true;
  1038. 	case ProfileEditURI: 	if (!MapIsChanging()) QueryLadderEdit(Request, Response);		return true;
  1039. 	case ProfileSwitchURI:	if (!MapIsChanging()) QueryLadderSwitch(Request, Response);		return true;
  1040. 	case ProfileManageURI:	if (!MapIsChanging()) QueryLadderManage(Request, Response);		return true;
  1041.  
  1042. // Management subframes
  1043. 	case SubFrameURI: 		if (!MapIsChanging()) QuerySubFrame(Request, Response);			return true;
  1044. 	case SubFrameMenuURI: 	if (!MapIsChanging()) QuerySubMenu(Request, Response);			return true;
  1045. 	case SubGametypeURI:	if (!MapIsChanging()) QuerySubGameType(Request, Response);		return true;
  1046. 	case SubMapsURI:		if (!MapIsChanging()) QuerySubMaps(Request, Response);			return true;
  1047. 	case SubMutatorsURI:	if (!MapIsChanging()) QuerySubMutators(Request, Response);		return true;
  1048. 	case SubRulesURI:		if (!MapIsChanging()) QuerySubRules(Request, Response);			return true;
  1049. 	case SubReviewURI:		if (!MapIsChanging()) QuerySubReview(Request, Response);		return true;
  1050. 	case SubSavedURI:		if (!MapIsChanging()) QuerySubSaved(Request, Response);			return true;
  1051. 	case SubImportURI: 		if (!MapIsChanging()) QuerySubImport(Request, Response);		return true;
  1052. 	case SubExportURI: 		if (!MapIsChanging()) QuerySubExport(Request, Response);		return true;
  1053. 	}
  1054. // This query is looking for a page from another query handler
  1055. // or the map is changing
  1056. 	return false;
  1057. }
  1058.  
  1059. function QueryLadderFrame(WebRequest Req, WebResponse Res)
  1060. {
  1061. 	local String Page;
  1062. 	local string SID;
  1063.  
  1064. // if no page specified, use the default
  1065. 	Page = Req.GetVariable("Page", ProfileViewURI);
  1066. 	SID = Req.GetVariable("SessionID");
  1067.  
  1068. // Tell the menu page which page we're viewing (with the ?Page=),
  1069. // so that it can highlight the appropriate link
  1070. 	Res.Subst("IndexURI",ProfileMenuURI$"?Page="$Page$"?SessionID="$SID);
  1071.  
  1072. // Load the main page into the frameset
  1073. 	Res.Subst("MainURI", Page$"?SessionID="$SID);
  1074.  
  1075. 	ShowFrame(Res, DefaultPage);
  1076. }
  1077.  
  1078. function QuerySubFrame(WebRequest Req, WebResponse Res)
  1079. {
  1080. 	local string Page, SID, TempStr, Action;
  1081. 	local Session CurS;
  1082.  
  1083. 	SID = Req.GetVariable("SessionID");
  1084. 	CurS = SMaster.getSession(SID, true);
  1085.  
  1086. 	Action = Req.GetVariable("Actions","Add");
  1087.  
  1088. 	if (Action ~= "Modify")
  1089. 	{
  1090. 		TempStr = Req.GetVariable("ProfileNameSelect", "");
  1091. 		if (TempStr != "") CreateSessionInfo(TempStr,SID,True);
  1092. 	}
  1093.  
  1094. 	else if (Action ~= "Add")
  1095. 	{
  1096. 		TempStr = Req.GetVariable("TextInput");
  1097. 		if (TempStr != "") CurS.setValue("ProfileName",TempStr,True);
  1098. 	}
  1099.  
  1100. // if no page specified, use the default
  1101. 	Page = Req.GetVariable("Page", SubGameTypeURI);
  1102. 	CurS.setValue("CurrentPage", Page, True);
  1103.  
  1104. // Tell the SubMenu page which page we're viewing, so that it can highlight
  1105. // the appropriate link
  1106. 	Res.Subst("SubMenuURI", SubFrameMenuURI$"?SessionID="$SID);
  1107.  
  1108. // Load the main page into the frameset
  1109. 	Res.Subst("SubMainURI", Page$"?SessionID="$SID);
  1110. 	ShowFrame(Res, SubFrame);
  1111. }
  1112.  
  1113. function QueryLadderMenu(WebRequest Req, WebResponse Res)
  1114. {
  1115. 	local string SID;
  1116.  
  1117. 	SID = Req.GetVariable("SessionID");
  1118. /*
  1119. If ?SessionID= is appended to the link, PreQuery() will not generate
  1120. a new Session when this link is queried
  1121. */
  1122. 	// Set URIs
  1123. 	if (CanPerform("Lv"))
  1124. 		Res.Subst("ViewProfiles", "<a href=\""$ProfileViewURI$"\" target=\"main\">"$LinkViewProfile$"</a><br />");
  1125.  
  1126. 	if (CanPerform("Le"))
  1127. 		Res.Subst("EditProfiles", "<a href=\""$ProfileEditURI$"\" target=\"main\">"$LinkEditProfile$"</a><br>");
  1128.  
  1129. 	if (CanPerform("Ls"))
  1130. 		Res.Subst("SwitchProfiles", "<a href=\""$ProfileSwitchURI$"\" target=\"main\">"$LinkSwitchProfile$"</a><br>");
  1131.  
  1132. 	if (CanPerform("Lm"))
  1133. 		Res.Subst("ManageProfiles", "<a href=\""$ProfileManageURI$"\" target=\"main\">"$LinkManageProfile$"</a><br>");
  1134.  
  1135. 	ShowPage(Res, ProfileMenuURI);
  1136. }
  1137.  
  1138. function QuerySubMenu(WebRequest Req, WebResponse Res)
  1139. {
  1140. // Highlight the current page
  1141. 	local string Highlighted, Background, SID;
  1142. 	local string GameLink, MutatorLink, MapLink, RuleLink, ReviewLink;
  1143. 	local string GameSpan, MutatorSpan, MapSpan, RuleSpan, ReviewSpan;
  1144.  
  1145. 	local string Page;
  1146. 	local Session CurS;
  1147.  
  1148. 	if (CanPerform("Lm"))
  1149. 	{
  1150. 		Highlighted = "<span class=\"blue\">";
  1151. 		Background = "<span class=\"red\">";
  1152. 		SID = Req.GetVariable("SessionID");
  1153. 		CurS = SMaster.getSession(SID, true);
  1154.  
  1155. 		// We are managing an existing profile
  1156. 		if (CurS.HasData("ProfileIndex"))
  1157. 	    	Res.Subst("Section", LabelModifyProfile);
  1158.  
  1159. 		else Res.Subst("Section", LabelAddProfile);
  1160.  
  1161. 		Page = CurS.getValue("CurrentPage",SubGametypeURI);
  1162.  
  1163. 	// Including ?SessionID= in link prevents PreQuery() from generating a new Session
  1164. 		GameLink = 		"<a href=\""$SubFrameURI$"?SessionID="$SID$"?Page="$SubGametypeURI$	"\" target=\"_parent\">";
  1165. 		MutatorLink = 	"<a href=\""$SubFrameURI$"?SessionID="$SID$"?Page="$SubMutatorsURI$	"\" target=\"_parent\">";
  1166. 		MapLink = 		"<a href=\""$SubFrameURI$"?SessionID="$SID$"?Page="$SubMapsURI$		"\" target=\"_parent\">";
  1167. 		RuleLink = 		"<a href=\""$SubFrameURI$"?SessionID="$SID$"?Page="$SubRulesURI$	"\" target=\"_parent\">";
  1168. 		ReviewLink = 	"<a href=\""$SubFrameURI$"?SessionID="$SID$"?Page="$SubReviewURI$	"\" target=\"_parent\">";
  1169.  
  1170. 	// Initially set all spans to the background color
  1171. 		GameSpan 	= Background;
  1172. 		MutatorSpan = Background;
  1173. 		MapSpan 	= Background;
  1174. 		RuleSpan 	= Background;
  1175. 		ReviewSpan 	= Background;
  1176.  
  1177. 		// Then set the appropriate span to the highlighted color
  1178. 		Res.Subst("SubTitle", CurS.GetValue("ProfileName"));
  1179. 		switch (Page)
  1180. 		{
  1181. 			case SubGametypeURI:
  1182. 				Curs.SetValue("ButtonName",		ProfileButtonName[1],true);
  1183. 				Curs.SetValue("ButtonValue", 	ProfileButtonValue[1],true);
  1184.  
  1185. 				Res.Subst("PageHelp", HelpGameType);
  1186. 				GameSpan = Highlighted; break;
  1187.  
  1188. 			case SubMutatorsURI:
  1189. 				Curs.SetValue("ButtonName", 	ProfileButtonName[2],true);
  1190. 				Curs.SetValue("ButtonValue", 	ProfileButtonValue[2],true);
  1191.  
  1192. 				Res.Subst("PageHelp", HelpMutators);
  1193. 				MutatorSpan = Highlighted; break;
  1194.  
  1195. 			case SubMapsURI:
  1196. 				Curs.SetValue("ButtonName", 	ProfileButtonName[3],true);
  1197. 				Curs.SetValue("ButtonValue", 	ProfileButtonValue[3],true);
  1198.  
  1199. 				Res.Subst("PageHelp", HelpMaps);
  1200. 				Mapspan = Highlighted; break;
  1201.  
  1202. 			case SubRulesURI:
  1203. 				Curs.SetValue("ButtonName", 	ProfileButtonName[4],true);
  1204. 				Curs.SetValue("ButtonValue", 	ProfileButtonValue[4],true);
  1205.  
  1206. 				Res.Subst("PageHelp", HelpPlayInfo);
  1207. 				RuleSpan = Highlighted; break;
  1208.  
  1209. 			case SubReviewURI:
  1210. 				Curs.SetValue("ButtonName", 	ProfileButtonName[5],true);
  1211. 				Curs.SetValue("ButtonValue", 	ProfileButtonValue[5],true);
  1212.  
  1213. 				Res.Subst("PageHelp", HelpReview);
  1214. 				ReviewSpan = Highlighted; break;
  1215. 		}
  1216.  
  1217. 		GameLink 	= GameLink 		$ GameSpan 		$ TableTitle[1]$"</span></a>";
  1218. 		MutatorLink = MutatorLink 	$ MutatorSpan 	$ TableTitle[2]$"</span></a>";
  1219. 		MapLink 	= MapLink 		$ MapSpan 		$ TableTitle[3]$"</span></a>";
  1220. 		RuleLink 	= RuleLink 		$ RuleSpan 		$ TableTitle[4]$"</span></a>";
  1221. 		ReviewLink 	= ReviewLink 	$ ReviewSpan 	$ TableTitle[5]$"</span></a>";
  1222.  
  1223. 		Res.Subst("GameTypeLink", 	GameLink);
  1224. 		Res.Subst("MutatorsLink", 	MutatorLink);
  1225. 		Res.Subst("MapsLink", 		MapLink);
  1226. 		Res.Subst("RulesLink", 		RuleLink);
  1227. 		Res.Subst("ReviewLink", 	ReviewLink);
  1228.  
  1229. 		ShowPage(Res, SubFrameMenu);
  1230. 	}
  1231.  
  1232. 	else AccessDenied(Res);
  1233. }
  1234.  
  1235. function QueryLadderView(WebRequest Req, WebResponse Res)
  1236. {
  1237. 	local int i,j;
  1238. 	local Session 	CurS;
  1239. 	local string	SID,
  1240. 					TempStr,
  1241. 					ViewRows,
  1242. 					NewProfile,
  1243. 					NewGameType;
  1244.  
  1245. 	local StringArray 			Mutators, GroupsOnly, ServerActors;
  1246. 	local class<GameInfo> 		GI${1}< ${3} >
  1247. 	local class<AccessControl> 	AC${1}< ${3} >
  1248. 	local class<Mutator>		TempMut;
  1249. 	local class<Info>			TempSA;
  1250.  
  1251.  
  1252. 	if (CanPerform("Lv"))
  1253. 	{
  1254. 		SID = Req.GetVariable("SessionID");
  1255. 		CurS = SMaster.getSession(SID,true);
  1256.  
  1257. 		if (CanPerform("Ls"))
  1258. 		{
  1259.  
  1260. 			if (Req.GetVariable("SetProfileName","")!="") // We would like to view a different profile
  1261. 				TempStr = Req.GetVariable("ProfileNameSelect", "");
  1262.  
  1263. 			If (TempStr == "")	// Not selecting a new profile to view
  1264. 			{
  1265. 			// First, see if the current session is holding a profile
  1266. 				NewProfile = CurS.getValue("ProfileIndex");
  1267. 				if (NewProfile == "")
  1268. 				{
  1269. 				// See if a profile is currently loaded
  1270. 					j = GetCurrentConfigIndex();
  1271. 					if (j!=-1)		// Found an active profile - this profile should be selected
  1272. 						NewProfile = string(j);
  1273. 				}
  1274. 			}
  1275.  
  1276. 			if (TempStr!="")
  1277. 				NewProfile = TempStr;
  1278.  
  1279. 			Res.Subst("ButtonName", "SetProfileName");
  1280. 			Res.Subst("ButtonValue", ButtonLoadProfile);
  1281. 			Res.Subst("PageCaption", "<select class=mini name='ProfileNameSelect'>"$GenerateSwitchProfileOptions(NewProfile)$"</select>");
  1282. 		}
  1283.  
  1284. 	// If admin doesn't have switch privileges, check for current profile
  1285. 		if (NewProfile == "")
  1286. 		{
  1287. 			NewProfile = CurS.getValue("ProfileIndex");
  1288. 			if (NewProfile == "")
  1289. 			{
  1290. 				j = GetCurrentConfigIndex();
  1291. 				if (j != -1)
  1292. 					NewProfile = string(j);
  1293. 			}
  1294. 		}
  1295.  
  1296. 		if (NewProfile != "" && LadderRules.AllLadderProfiles.Count() > 0)
  1297. 		{
  1298. 			CurS.setValue("ProfileIndex", NewProfile, True);
  1299.             CreateSessionInfo(NewProfile,SID);
  1300. 			NewGameType = CurS.getValue("GameType");
  1301.  
  1302. 			if (NewGameType != "")
  1303. 				GIClass = class<GameInfo>(DynamicLoadObject(NewGameType,class'Class'));
  1304. 			if (GIClass==None)
  1305. 			{
  1306. 				ShowMessage(Res,ErrorGameClassTitle,ErrorGameClassText);
  1307. 				return;
  1308. 			}
  1309.  
  1310. 			TempStr = CurS.getValue("ACClass",Level.Game.AccessControlClass);
  1311. 			if (TempStr != "")
  1312. 				ACClass = class<AccessControl>(DynamicLoadObject(TempStr,class'Class'));
  1313. 			if (ACClass == None)
  1314. 			{
  1315. 				ShowMessage(Res,ErrorAccessControlTitle,ErrorAccessControlText);
  1316. 				return;
  1317. 			}
  1318.  
  1319. 			Mutators = new(None) class'SortedStringArray';
  1320. 			GroupsOnly = new(None) class'SortedStringArray';
  1321. 			ServerActors = new(None) class'SortedStringArray';
  1322. 		// Mutator Section
  1323. 			for (i=0;i<CurS.getMutatorLength();i++)
  1324. 			{
  1325. 			    TempStr = CurS.getMutator(i);
  1326.                 for (j=0;j<AllMutators.Length;j++)
  1327. 				{
  1328. 					if (TempStr ~= AllMutators[j].ClassName)
  1329. 					{
  1330. 						TempMut = class<Mutator>(DynamicLoadObject(TempStr,class'Class'));
  1331. 						if (TempMut != None)
  1332. 							Mutators.Add(string(j), AllMutators[j].FriendlyName);
  1333. 					}
  1334. 				}
  1335. 			}
  1336.  
  1337. 			for (i=0;i<CurS.getSALength();i++)
  1338. 			{
  1339. 				TempStr = CurS.GetServerActor(i);
  1340. 				for (j=0;j<ConfigM.ManagedActors.Length;j++)
  1341. 				{
  1342. 					if (TempStr ~= string(ConfigM.ManagedActors[j].SAClass))
  1343. 					{
  1344. 						TempSA = class<Info>(DynamicLoadObject(TempStr,class'Class'));
  1345. 						if (TempSA != None)
  1346. 							ServerActors.Add(string(j),ConfigM.ManagedActors[j].SAName);
  1347. 					}
  1348. 				}
  1349. 			}
  1350.  
  1351. 			Res.Subst("SectionName", TableTitle[2]);
  1352. 			Res.Subst("SpecialInstructions", "");
  1353. 			ViewRows = ViewRows$WebInclude(IncludeSection);
  1354.  
  1355. 			for (i = 0; i<ServerActors.Count(); i++)
  1356. 			{
  1357. 				j = int(ServerActors.GetItem(i));
  1358. 				Res.Subst("SettingName", ServerActors.GetTag(i));
  1359. 				if (CurS.SARequired(string(ConfigM.ManagedActors[j].SAClass)))
  1360. 					Res.Subst("SettingData", RequiredText);
  1361. 				else Res.Subst("SettingData", "&nbsp;&nbsp;");
  1362. 				ViewRows = ViewRows $ WebInclude(IncludeRows);
  1363. 			}
  1364. 			ViewRows = ViewRows $ "<tr><td colspan=\"2\">&nbsp;&nbsp;</td></tr>";
  1365. 			for (i = 0; i<Mutators.Count(); i++)
  1366. 			{
  1367. 				j = int(Mutators.GetItem(i));
  1368. 				Res.Subst("SettingName", AllMutators[j].FriendlyName);
  1369. 				if (CurS.MutRequired(AllMutators[j].ClassName))
  1370. 					Res.Subst("SettingData", RequiredText);
  1371. 				else Res.Subst("SettingData", "&nbsp;&nbsp;");
  1372. 				ViewRows = ViewRows$WebInclude(IncludeRows);
  1373. 			}
  1374.  
  1375. 			Res.Subst("SectionName", TableTitle[3]);
  1376. 			Res.Subst("SpecialInstructions", "");
  1377. 			ViewRows = ViewRows$WebInclude(IncludeSection);
  1378.  
  1379. 			Res.Subst("SettingName", LabelMaxMaps);
  1380. 			TempStr = CurS.getValue("MaxMaps");
  1381. 			if (TempStr == "0")
  1382. 				TempStr = UnlimitedText;
  1383. 			Res.Subst("SettingData", TempStr);
  1384. 			Res.Subst("Extra", "<tr><td colspan=\"2\">&nbsp;&nbsp;</td></tr>");
  1385. 			ViewRows = ViewRows$WebInclude(IncludeRows);
  1386. 			for (i=0;i<CurS.getMapLength();i++)
  1387. 			{
  1388.                 TempStr = CurS.getMap(i);
  1389.                 Res.Subst("SettingName", TempStr);
  1390. 				Res.Subst("Extra", "");
  1391. 				if (CurS.MapRequired(TempStr))
  1392. 					Res.Subst("SettingData", RequiredText);
  1393. 				else Res.Subst("SettingData", "&nbsp;&nbsp");
  1394.  
  1395. 				ViewRows = ViewRows$WebInclude(IncludeRows);
  1396. 			}
  1397.  
  1398. 			Res.Subst("SectionName", TableTitle[4]);
  1399. 			Res.Subst("SpecialInstructions", "&nbsp;&nbsp;");
  1400. 			ViewRows = ViewRows $ WebInclude(IncludeSection);
  1401. 			ViewRows = ViewRows $ "<tr><td colspan=\"2\">&nbsp;</td></tr>" $ GeneratePlayInfoRows(Req, Res, IncludeRows);
  1402. 		}
  1403.  
  1404. 	// We have no profile currently active
  1405. 		else
  1406. 		{
  1407. 			Res.Subst("SettingName", PageCaption[0]);
  1408. 			ViewRows = ViewRows $ WebInclude(IncludeRows);
  1409. 		}
  1410.  
  1411. 		TempStr = CurS.getValue("ProfileName", PageCaption[0]);
  1412. 		if (LadderRules.GetRemainingMatches() > 0 && TempStr == LadderRules.Profiles[GetCurrentConfigIndex()].ProfileName)
  1413. 			TempStr = TempStr @ LabelNumberMatchesLeft @ string(LadderRules.GetRemainingMatches());
  1414.  
  1415. 		Res.Subst("TableRows", ViewRows);
  1416. 		Res.Subst("LadderTable", WebInclude(IncludeCaptionButton)$WebInclude(IncludeTable));
  1417. 		Res.Subst("Section", LinkViewProfile);
  1418. 		Res.Subst("SubTitle", TempStr);
  1419. 		Res.Subst("PageHelp", HelpViewProfile);
  1420. 		Res.Subst("PostAction", ProfileViewURI$"?SessionID="$SID);
  1421.  
  1422. 		ShowPage(Res, MasterPage);
  1423. 	}
  1424.  
  1425. 	else AccessDenied(Res);
  1426. }
  1427.  
  1428. function QueryLadderEdit(WebRequest Req, WebResponse Res)
  1429. {
  1430. 	local Session CurS;
  1431. 	local bool 	bAllMuts;
  1432. 	local int 	i,j,k,z,
  1433. 				id,
  1434. 				Count,
  1435. 				MoveCount;
  1436.  
  1437. 	local string	SID,
  1438. 					EditRows,
  1439. 					TempStr, Tmp, NewProfile, NewGameType,
  1440. 					lastgroup, thisgroup, nextgroup, EmptyRow;
  1441.  
  1442. 	local ProfileConfigSet 		TempPCS;
  1443. 	local array<string> 		TempMutes;
  1444. 	local class<GameInfo> 		GI${1}< ${3} >
  1445. 	local class<AccessControl> 	AC${1}< ${3} >
  1446. 	local array<ProfileConfigSet.ProfileMap> 		AllPCSMaps;
  1447. 	local array<ProfileConfigSet.ProfileMutator> 	AllPCSMutators;
  1448. 	local array<ProfileConfigSet.ProfileSA>			AllPCSServerActors;
  1449. 	local StringArray
  1450. 				Mutators, GroupsOnly, Required, ServerActors, ReqSA,
  1451. 				RequiredMaps, IncludeMaps, ExcludeMaps, MovedMaps;
  1452.  
  1453. 	SID = Req.GetVariable("SessionID");
  1454. 	CurS = SMaster.getSession(SID,true);
  1455. 	if (CanPerform("Le"))
  1456. 	{
  1457. 		if (CanPerform("Ls"))
  1458. 		{
  1459. 			if (Req.GetVariable("SetProfileName","")!="") // We would like to view a different profile
  1460. 				TempStr = Req.GetVariable("ProfileNameSelect", "");
  1461.  
  1462. 			If (TempStr == "")	// Not selecting a new profile to view
  1463. 			{
  1464. 			// First, see if the current session is holding a profile
  1465. 				NewProfile = CurS.getValue("ProfileIndex");
  1466.  
  1467. 				if (NewProfile == "")
  1468. 				{
  1469. 				// See if a profile is currently loaded
  1470. 					j = GetCurrentConfigIndex();
  1471. 					if (j!=-1)		// Found an active profile - this profile should be selected
  1472. 						NewProfile = string(j);
  1473. 				}
  1474.  
  1475. 			}
  1476.  
  1477. 			if (TempStr!="")
  1478. 				NewProfile = TempStr;
  1479.  
  1480. 			Res.Subst("ButtonName", "SetProfileName");
  1481. 			Res.Subst("ButtonValue", ButtonLoadProfile);
  1482. 			Res.Subst("PageCaption", "<select class=mini name='ProfileNameSelect'>"$GenerateSwitchProfileOptions(NewProfile)$"</select>");
  1483. 		}
  1484. 		CurS.setValue("CurrentPage", ProfileEditURI, true);
  1485. 		CurS.setValue("ButtonName", "ApplyProfileChanges",true);
  1486. 		CurS.setValue("ButtonValue", ButtonApplyProfileChanges, true);
  1487.  
  1488. // If admin doesn't have switch privileges, check for current profile
  1489. 		if (NewProfile == "")
  1490. 		{
  1491. 			NewProfile = CurS.getValue("ProfileIndex");
  1492. 			if (NewProfile == "")
  1493. 			{
  1494. 				j = GetCurrentConfigIndex();
  1495. 				if (j != -1)
  1496. 					NewProfile = string(j);
  1497. 			}
  1498. 		}
  1499.  
  1500. 		CurS.setValue("ProfileIndex", NewProfile, True);
  1501. 		if (NewProfile != "" && LadderRules.AllLadderProfiles.Count() > 0)
  1502. 		{
  1503. 			ProfileMaps.Reset();
  1504. 			Required = new(None) 		class'SortedStringArray';
  1505. 			ReqSA	= new(None)			class'SortedStringArray';
  1506. 			Mutators = new(None) 		class'SortedStringArray';
  1507. 			MovedMaps = new(None) 		class'SortedStringArray';
  1508. 			GroupsOnly = new(None) 		class'SortedStringArray';
  1509. 			ServerActors = new(None)	class'SortedStringArray';
  1510. 			IncludeMaps = new(None) 	class'SortedStringArray';
  1511. 			ExcludeMaps = new(None) 	class'SortedStringArray';
  1512. 			RequiredMaps = new(None) 	class'SortedStringArray';
  1513.  
  1514.             CreateSessionInfo(NewProfile,SID);
  1515. 			TempPCS = LadderRules.LadderProfiles[int(NewProfile)];
  1516. 			TempPCS.StartEdit();
  1517.  
  1518. 			NewGameType = CurS.getValue("GameType");
  1519. 			GIClass = class<GameInfo>(DynamicLoadObject(NewGameType,class'Class'));
  1520. 			if (GIClass==None)
  1521. 			{
  1522. 				ShowMessage(Res,ErrorGameClassTitle,ErrorGameClassText);
  1523. 				return;
  1524. 			}
  1525.  
  1526. 			TempStr = CurS.getValue("ACClass", Level.Game.AccessControlClass);
  1527. 			if (TempStr != "")
  1528. 				ACClass = class<AccessControl>(DynamicLoadObject(TempStr,class'Class'));
  1529. 			AllPCSMutators = TempPCS.GetProfileMutators();
  1530. 			AllPCSMaps = TempPCS.GetProfileMaps();
  1531. 			AllPCSServerActors = TempPCS.GetProfileServerActors();
  1532.  
  1533. 	// Load Exclude Maps
  1534. 			for (i=0;i<AllPCSMaps.Length;i++)
  1535. 			{
  1536. 				ProfileMaps.Add(string(i), AllPCSMaps[i].MapName);
  1537. 				if (AllPCSMaps[i].bRequired)
  1538. 				{
  1539. 					RequiredMaps.Add(string(i),string(AllPCSMaps[i].MapListOrder));
  1540. 					IncludeMaps.Add(string(i),string(AllPCSMaps[i].MapListOrder));
  1541. 				}
  1542.  
  1543. 				else ExcludeMaps.Add(string(i),string(AllPCSMaps[i].MapListOrder));
  1544. 			}
  1545.  
  1546. 			for (i=0;i<CurS.GetMapLength();i++)
  1547. 			{
  1548. 				j = ExcludeMaps.FindItemId(ProfileMaps.GetItem(ProfileMaps.FindTagId(CurS.getMap(i))));
  1549. 				if (j >= 0) IncludeMaps.MoveFromId(ExcludeMaps, j);
  1550. 			}
  1551.  
  1552. 			if (Req.GetVariable("ApplyProfileChanges","")!="")
  1553. 			{
  1554. 				for (i=0;i<AllPCSMutators.Length;i++)
  1555. 					for (j=0;j<AllMutators.Length;j++)
  1556. 						if (AllPCSMutators[i].MutatorName ~= AllMutators[j].ClassName)
  1557. 							Mutators.Add(string(j),AllPCSMutators[i].MutatorName);
  1558.  
  1559. 				for (i=0;i<Mutators.Count();i++)
  1560. 				{
  1561. 					if ((Req.GetVariable(Mutators.GetTag(i),"")!="")||(Req.GetVariable(AllMutators[int(Mutators.GetItem(i))].GroupName)~=Mutators.GetTag(i)))
  1562. 						TempPCS.AddMutator(Mutators.GetTag(i));
  1563. 					else TempPCS.DelMutator(Mutators.GetTag(i));
  1564. 				}
  1565.  
  1566. 				for (i=0;i<AllPCSServerActors.Length;i++)
  1567. 				{
  1568. 					if (Req.GetVariable(AllPCSServerActors[i].ActorClass,"") != "")
  1569. 						TempPCS.AddServerActor(AllPCSServerActors[i].ActorClass);
  1570. 					else TempPCS.DelServerActor(AllPCSServerActors[i].ActorClass);
  1571. 				}
  1572.  
  1573. 				for (i=0;i<AllPCSMaps.Length;i++)
  1574. 				{
  1575. 					if (AllPCSMaps[i].bRequired) TempPCS.AddMap(AllPCSMaps[i].MapName,int(RequiredMaps.GetTag(RequiredMaps.FindItemId(string(i)))));
  1576. 					else if (IncludeMaps.FindItemId(string(i)) >= 0) TempPCS.AddMap(AllPCSMaps[i].MapName,int(IncludeMaps.GetTag(IncludeMaps.FindItemId(string(i)))));
  1577. 					else TempPCS.RemoveMap(AllPCSMaps[i].MapName);
  1578. 				}
  1579.  
  1580.                 CreateSessionInfo(NewProfile,SID,false,true);
  1581. 			}
  1582. 			else if (Req.GetVariable("AddMap", "") != "")
  1583. 			{
  1584. 				Count = Req.GetVariableCount("ExcludeMapsSelect");
  1585. 				for (i=0; i<Count; i++)
  1586. 				{
  1587. 					if (IncludeMaps.Count() >= TempPCS.MaxMaps && TempPCS.MaxMaps > 0)
  1588. 						break;
  1589. 					if (ExcludeMaps.Count() > 0)
  1590. 					{
  1591. 						id = IncludeMaps.MoveFromId(ExcludeMaps, ExcludeMaps.FindItemId(ProfileMaps.GetItem(ProfileMaps.FindTagId(Req.GetVariableNumber("ExcludeMapsSelect", i)))));
  1592. 						if (id >= 0)
  1593. 						{
  1594. 							TempPCS.AddMap(AllPCSMaps[int(IncludeMaps.getItem(id))].MapName,int(IncludeMaps.getTag(id)));
  1595. 							MovedMaps.CopyFromId(IncludeMaps, id);
  1596. 						}
  1597. 						else
  1598. 							Log(ErrorExcludeMapNotFound@Req.GetVariableNumber("ExcludeMapsSelect", i),LOGNAME);
  1599. 					}
  1600. 				}
  1601. 				for (i=0;i<IncludeMaps.Count();i++)
  1602. 					TempPCS.AddMap(AllPCSMaps[int(IncludeMaps.getItem(i))].MapName,i);
  1603.  
  1604.                 CreateSessionInfo(NewProfile,SID,false,true,True);
  1605. 			}
  1606.  
  1607. 			else if (Req.GetVariable("DelMap", "") != "" && Req.GetVariableCount("IncludeMapsSelect") > 0)
  1608. 			{
  1609. 				Count = Req.GetVariableCount("IncludeMapsSelect");
  1610. 				for (i=0; i<Count; i++)
  1611. 				{
  1612. 					if (RequiredMaps.FindItemId(ProfileMaps.GetItem(ProfileMaps.FindTagId(Req.GetVariableNumber("IncludeMapsSelect", i)))) < 0)
  1613. 					{
  1614. 						if (IncludeMaps.Count() > 0)
  1615. 						{
  1616. 							id = ExcludeMaps.MoveFromId(IncludeMaps, IncludeMaps.FindItemId(ProfileMaps.GetItem(ProfileMaps.FindTagId(Req.GetVariableNumber("IncludeMapsSelect", i)))));
  1617. 							if (id >= 0)
  1618. 							{
  1619. 								TempPCS.RemoveMap(AllPCSMaps[int(ExcludeMaps.GetItem(id))].MapName);
  1620. 								MovedMaps.CopyFromId(ExcludeMaps, id);
  1621. 							}
  1622. 							else
  1623. 								Log(ErrorIncludeMapNotFound@Req.GetVariableNumber("IncludeMapsSelect", i),LOGNAME);
  1624. 						}
  1625. 					}
  1626. 				}
  1627.                 CreateSessionInfo(NewProfile,SID,false,true,True);
  1628. 			}
  1629. 			else if (Req.GetVariable("AddAllMap", "") != "")
  1630. 			{
  1631. 				while (ExcludeMaps.Count() > 0 && (IncludeMaps.Count() < TempPCS.MaxMaps || TempPCS.MaxMaps == 0) )
  1632. 				{
  1633. 					id = IncludeMaps.MoveFromId(ExcludeMaps, ExcludeMaps.Count()-1);
  1634. 					if (id >= 0)
  1635. 					{
  1636. 						TempPCS.AddMap(AllPCSMaps[int(IncludeMaps.getItem(id))].MapName,int(IncludeMaps.getTag(id)));
  1637. 						MovedMaps.CopyFromId(IncludeMaps, id);
  1638. 					}
  1639. 				}
  1640. 				for (i=0;i<IncludeMaps.Count();i++)
  1641. 					TempPCS.AddMap(AllPCSMaps[int(IncludeMaps.getItem(i))].MapName,i);
  1642.                CreateSessionInfo(NewProfile,SID,false,true,True);
  1643. 			}
  1644. 			else if (Req.GetVariable("DelAllMap", "") != "")
  1645. 			{
  1646. 				i = IncludeMaps.Count();
  1647. 				while (i > 0 && IncludeMaps.Count() > RequiredMaps.Count())
  1648. 				{
  1649. 					if (RequiredMaps.FindItemId(IncludeMaps.GetItem(i-1)) < 0)
  1650. 					{
  1651. 						id =  ExcludeMaps.MoveFromId(IncludeMaps, i-1);
  1652. 						if (id >= 0)
  1653. 						{
  1654. 							TempPCS.RemoveMap(AllPCSMaps[int(ExcludeMaps.GetItem(id))].MapName);
  1655. 							MovedMaps.CopyFromId(ExcludeMaps, id);
  1656. 						}
  1657. 					}
  1658. 					i--;
  1659. 				}
  1660.                 CreateSessionInfo(NewProfile,SID,false,true,True);
  1661. 			}
  1662. 			else if (Req.GetVariable("MoveMap", "") != "")
  1663. 			{
  1664. 				MoveCount = int(Abs(float(Req.GetVariable("MoveMapCount"))));
  1665. 				if (MoveCount != 0)
  1666. 				{
  1667. 					Count = Req.GetVariableCount("IncludeMapsSelect");
  1668.  
  1669. 					// 1) Create a sorted MovedMaps list
  1670. 					for (i = 0; i<Count; i++)
  1671. 						MovedMaps.CopyFromId(IncludeMaps, IncludeMaps.FindItemId(ProfileMaps.GetItem(ProfileMaps.FindTagId(Req.GetVariableNumber("IncludeMapsSelect", i)))));
  1672.  
  1673. 					if (Req.GetVariable("MoveMap") ~= "Down")
  1674. 					{
  1675. 						// 2) Browse from Last to 0 until all maps are moved by count
  1676. 						//    but stop moving them if hitting bottom
  1677. 						for (i = IncludeMaps.Count()-1; i >= 0; i--)
  1678. 							if (MovedMaps.FindItemId(IncludeMaps.GetItem(i)) >= 0)
  1679. 								IncludeMaps.ShiftStrict(i, MoveCount);
  1680. 					}
  1681. 					else
  1682. 					{
  1683. 						MoveCount = -MoveCount;
  1684. 						for (i = 0; i<IncludeMaps.Count(); i++)
  1685. 							if (MovedMaps.FindItemId(IncludeMaps.GetItem(i)) >= 0)
  1686. 								IncludeMaps.ShiftStrict(i, MoveCount);
  1687. 					}
  1688. 				}
  1689.  
  1690. 				for (i=0;i<IncludeMaps.Count();i++)
  1691. 					TempPCS.AddMap(AllPCSMaps[int(IncludeMaps.getItem(i))].MapName,i);
  1692.  
  1693.                 CreateSessionInfo(NewProfile,SID,false,true,True);
  1694. 			}
  1695.  
  1696. 			if (TempPCS.CanEdit())
  1697. 				TempPCS.StartEdit();
  1698. // Mutator Section
  1699. 			Mutators.Reset();
  1700. 	// Set active ServerActors
  1701. 			TempMutes = LoadActiveProfileServerActors(NewProfile);
  1702. 			TempStr = class'wUtils103.wArray'.static.Join(TempMutes,",");
  1703.  
  1704. 			bAllMuts = TempMutes.Length == ConfigM.ManagedActors.Length;
  1705.  
  1706. 			for (i=0;i<AllPCSServerActors.Length;i++)
  1707. 			{
  1708. 				for (j = 0; j < ConfigM.ManagedActors.Length; j++)
  1709. 				{
  1710. 					if (AllPCSServerActors[i].ActorClass ~= string(ConfigM.ManagedActors[j].SAClass))
  1711. 					{
  1712. 						if (AllPCSServerActors[i].bRequired)
  1713. 							ReqSA.Add(string(j), ConfigM.ManagedActors[j].SAName);
  1714. 						else ServerActors.Add(string(j),ConfigM.ManagedActors[j].SAName);
  1715. 						break;
  1716. 					}
  1717. 				}
  1718. 			}
  1719. 			TempMutes = LoadActiveProfileMutators(NewProfile);
  1720. 			TempStr = class'wUtils103.wArray'.static.Join(TempMutes,",");
  1721. 		// Set Available Mutators for this profile
  1722. 			bAllMuts = bAllMuts && AllPCSMutators.Length == AllMutators.Length;
  1723. 			for (i=0;i<AllPCSMutators.Length;i++)
  1724. 			{
  1725. 				for (j=0;j<AllMutators.Length;j++)
  1726. 				{
  1727. 					if (AllMutators[j].ClassName ~= AllPCSMutators[i].MutatorName)
  1728. 					{
  1729. 						if (AllPCSMutators[i].bRequired)
  1730. 							Required.Add(string(j),AllMutators[j].FriendlyName);
  1731. 						else
  1732. 						{
  1733. 					// Don't add available mutator if it belongs in the same group as a required mutator
  1734. 							for (k=0;k<Required.Count();k++)
  1735. 								if (AllMutators[int(Required.GetItem(k))].GroupName ~= AllMutators[j].GroupName)
  1736. 									break;
  1737. 							if (k==Required.Count())
  1738. 								Mutators.Add(string(j),AllPCSMutators[i].MutatorName);
  1739. 						}
  1740. 						break;
  1741. 					}
  1742. 				}
  1743. 			}
  1744. // BEGIN OUTPUT ////////////////////////////////////////////
  1745. /*
  1746. 	TempMutes is an array of active mutators, including required ones
  1747. 	AllPCSMutators is a ProfileMutator array, which includes a required flag
  1748.  
  1749. 	Need to generate a regular mutator selection list, but list all required
  1750. 	first, followed by the list of all other mutators which are available
  1751. */
  1752. // MAPS
  1753. 			Res.Subst("SpanLength", "2");
  1754. 			Res.Subst("SpanContent", "&nbsp;&nbsp;");
  1755. 			EmptyRow = "<tr>" $ WebInclude(CellColSpan) $ "</tr>";
  1756.  
  1757. 			Res.Subst("SectionName", TableTitle[3]);
  1758. 			TempStr = string(TempPCS.GetMaxMaps());
  1759. 			if (TempStr == "0") TempStr = "Unlimited";
  1760. 			Res.Subst("SpecialInstructions", LabelMaxMaps$":"@TempStr);
  1761. 			EditRows += WebInclude(IncludeSection);
  1762.  
  1763. 			j = RequiredMaps.Count();
  1764. 			if (j > 0)
  1765. 			{
  1766. 				EditRows = EditRows $ EmptyRow $ "<tr><td class=ttext>" $ RequiredText @ MapText $ "</td><td class=ttext>" $ FollowingMaps@AreAssignedText $ "</td></tr>";
  1767. 				i=0;
  1768. 				while (i<j)
  1769. 				{
  1770. 					Res.Subst("SettingName", AllPCSMaps[int(RequiredMaps.GetItem(i++))].MapName);
  1771. 					Res.Subst("SettingData", StringIf(i < j, AllPCSMaps[int(RequiredMaps.GetItem(i++))].MapName, ""));
  1772.  
  1773. 					Res.Subst("Extra", "");
  1774. 					EditRows += WebInclude(IncludeRows);
  1775. 				}
  1776. 			}
  1777.  
  1778. 			EditRows = EditRows $ EmptyRow $ "<tr><td class=ttext>" $ AvailableText@MapText $ "</td><td class=ttext>" $ LabelChangeMaplist $ "</td></tr>";
  1779.  
  1780. 			Res.Subst("ExcludeMapsOptions", CreateMapListSelect(AllPCSMaps, ExcludeMaps,MovedMaps));
  1781. 			Res.Subst("IncludeMapsOptions", CreateMapListSelect(AllPCSMaps, IncludeMaps,MovedMaps));
  1782. 			Res.Subst("SpanContent", WebInclude(IncludeMapSelect));
  1783. 			Res.Subst("RowContent", WebInclude(CellColSpan));
  1784. 			EditRows += WebInclude(RowLeft);
  1785.  
  1786. // MUTATORS
  1787. 			CreateFullMutatorList(Mutators,GroupsOnly);
  1788. 			Res.Subst("SectionName", TableTitle[2]);
  1789. 			Res.Subst("SpecialInstructions", "");
  1790. 			EditRows += WebInclude(IncludeSection);
  1791.  
  1792. 			if (ReqSA.Count() > 0 || Required.Count() > 0)
  1793. 				EditRows = EditRows $ EmptyRow $ "<tr><td class=ttext>" $ RequiredText@MutatorText $ "</td><td class=ttext>" $ FollowingMutators@AreAssignedText $ "</td></tr>";
  1794. // Include ServerActors first
  1795. 			for (i=0;i<ReqSA.Count();i++)
  1796. 			{
  1797. 				j = int(ReqSA.GetItem(i));
  1798. 				Res.Subst("SettingName", ReqSA.GetTag(i));
  1799. 				Res.Subst("SettingData", ConfigM.ManagedActors[j].SADescription);
  1800. 				Res.Subst("Extra", "");
  1801.  
  1802. 				EditRows += WebInclude(IncludeRows);
  1803. 			}
  1804.  
  1805. 			for (i=0;i<Required.Count();i++)
  1806. 			{
  1807. 				j=int(Required.GetItem(i));
  1808. 				Res.Subst("SettingName", AllMutators[j].FriendlyName);
  1809. 				Res.Subst("SettingData", AllMutators[j].Description);
  1810. 				Res.Subst("Extra", "");
  1811.  
  1812. 				EditRows += WebInclude(IncludeRows);
  1813. 			}
  1814.  
  1815. 			EditRows = EditRows $ EmptyRow $ "<tr><td class=ttext>" $ AvailableText@MutatorText $ "</td><td class=ttext>" $ FollowingMutators@AreAvailableText $ "</td></tr>";
  1816. 			for (i=0;i<GroupsOnly.Count();i++)
  1817. 			{
  1818. 				j=int(GroupsOnly.GetItem(i));
  1819. 				if (AllMutators[j].GroupName=="")
  1820. 					thisgroup="Z"$string(z++);
  1821. 				else thisgroup = AllMutators[j].GroupName;
  1822. 				if ( (i + 1) == GroupsOnly.Count())
  1823. 					nextgroup = "";
  1824. 				else
  1825. 				{
  1826. 				// Assign nextgroup to the next mutators group
  1827. 					k = int(GroupsOnly.GetItem(i + 1));
  1828. 					if (AllMutators[k].GroupName=="")
  1829. 						nextgroup="Z"$string(z);
  1830. 					else nextgroup = AllMutators[k].GroupName;
  1831. 				}
  1832.  
  1833. 				Res.Subst("GroupName", thisgroup);
  1834. 				Res.Subst("MutatorClass", AllMutators[j].ClassName);
  1835. 				Res.Subst("MutatorName", AllMutators[j].FriendlyName);
  1836. 				Res.Subst("MutatorDesc", AllMutators[j].Description);
  1837.  
  1838. 				if ((lastgroup != thisgroup) && (thisgroup == nextgroup)) // and the next mut is in the same group as this one
  1839. 				{
  1840. 					Res.Subst("Checked", " checked");
  1841. 					EditRows += WebInclude("current_mutators_group");
  1842. 				}
  1843.  
  1844. 				Res.Subst("Checked", StringIf(CurS.HasMutator(AllMutators[j].ClassName), " checked", ""));
  1845. 				EditRows += WebInclude("current_mutators_group_row");
  1846.  
  1847. 				lastgroup=thisgroup;
  1848. 			}
  1849. // Add ServerActors first
  1850. 			for (i = 0; i < ServerActors.Count(); i++)
  1851. 			{
  1852. 				TempStr = "";
  1853. 				j = int(ServerActors.GetItem(i));
  1854.  
  1855. 				Res.Subst("Content", Checkbox(string(ConfigM.ManagedActors[j].SAClass), CurS.HasServerActor(string(ConfigM.ManagedActors[j].SAClass))) $ "&nbsp;" $ ServerActors.GetTag(i));
  1856. 				TempStr = WebInclude(NowrapLeft);
  1857. 				Res.Subst("Content", ConfigM.ManagedActors[j].SADescription);
  1858. 				Res.Subst("RowContent", TempStr $ WebInclude(CellLeft));
  1859. 				EditRows += WebInclude(RowLeft);
  1860. 			}
  1861.  
  1862. 			for (i = 0; i<Mutators.Count(); i++)
  1863. 			{
  1864. 				TempStr = "";
  1865. 				j = int(Mutators.GetItem(i));
  1866.  
  1867. 				Res.Subst("Content", Checkbox(AllMutators[j].ClassName,CurS.HasMutator(AllMutators[j].ClassName)) $ "&nbsp;" $ AllMutators[j].FriendlyName);
  1868. 				TempStr += WebInclude(NowrapLeft);
  1869. 				Res.Subst("Content", AllMutators[j].Description);
  1870. 				Res.Subst("RowContent", TempStr $ WebInclude(CellLeft));
  1871. 				EditRows += WebInclude(RowLeft);
  1872. 			}
  1873. 			TempPCS.EndEdit(False);
  1874. 		}
  1875. 	// We have no profile currently active
  1876. 		else
  1877. 		{
  1878. 			Res.Subst("SettingName", PageCaption[0]);
  1879. 			EditRows += WebInclude(IncludeRows);
  1880. 		}
  1881. 		Res.Subst("TableRows", EditRows);
  1882. 		TempStr = "";
  1883. 		TempStr = WebInclude(IncludeCaptionButton)$Tmp$WebInclude(IncludeTable);
  1884.  
  1885. 		if (NewProfile != "")
  1886. 		{
  1887. 			Res.Subst("ButtonName", curS.getValue("ButtonName","ApplyProfileChanges"));
  1888. 			Res.Subst("ButtonValue", ButtonApplyProfileChanges);
  1889. 			Res.Subst("PageCaption", "");
  1890. 			TempStr += WebInclude(IncludeCaptionButton);
  1891. 		}
  1892.  
  1893. 		Tmp = CurS.getValue("ProfileName",PageCaption[0]);
  1894. 		if (LadderRules.GetRemainingMatches() > 0 && Tmp == LadderRules.Profiles[GetCurrentConfigIndex()].ProfileName)
  1895. 			Tmp = Tmp @ LabelNumberMatchesLeft @ string(LadderRules.GetRemainingMatches());
  1896.  
  1897. 		Res.Subst("LadderTable", 	TempStr);
  1898. 		Res.Subst("Section",	 	LinkEditProfile);
  1899. 		Res.Subst("SubTitle", 		Tmp);
  1900. 		Res.Subst("PageHelp", 		HelpEditProfile);
  1901. 		Res.Subst("PostAction", 	ProfileEditURI$"?SessionID="$SID);
  1902. 		ShowPage(Res, MasterPage);
  1903. 	}
  1904.  
  1905. 	else AccessDenied(Res);
  1906. }
  1907.  
  1908. function QueryLadderSwitch(WebRequest Req, WebResponse Res)
  1909. {
  1910. 	local int 		j, NumMatches;
  1911. 	local bool		bDelayChange, bSwitching;
  1912. 	local Session 	CurS;
  1913. 	local string 	SID,
  1914. 					TempStr, Tmp,
  1915. 					Checked;
  1916.  
  1917. 	SID = Req.GetVariable("SessionID");
  1918. 	CurS = SMaster.getSession(SID,true);
  1919.  
  1920. 	if (CanPerform("Ls"))
  1921. 	{
  1922. 		TempStr = Req.GetVariable("ProfileNameSelect", "");
  1923. 		Tmp = Req.GetVariable("SetNewProfile", "");
  1924. 		if (Tmp != "")
  1925. 		{
  1926. 			if (TempStr != "")
  1927. 			{
  1928. 				NumMatches = int(Req.GetVariable("NumMatches", "0"));
  1929. 				bDelayChange = Req.GetVariable("DelaySwitch","") != "";
  1930. 				if (bDelayChange)
  1931. 				{
  1932. 					if (LadderRules.WaitApplyProfile(TempStr, NumMatches))
  1933. 					{
  1934. 						CurS.setValue("ProfileIndex", TempStr, True);
  1935. 						bSwitching = True;
  1936. 					}
  1937. 				}
  1938. 				else
  1939. 				{
  1940. 				// We would like to switch immediately
  1941. 					LadderRules.ApplyProfile(TempStr, NumMatches);
  1942. 					MapIsChanging();
  1943. 					return;
  1944. 				}
  1945. 			}
  1946. 			else StatusError(Res, ErrorNoProfilesExist);
  1947. 		}
  1948.  
  1949. 		else if (LadderRules.Profiles.Length > 0)
  1950. 		{
  1951. 			j = GetCurrentConfigIndex();
  1952. 			if (j >= 0) TempStr = string(j);
  1953. 		}
  1954.  
  1955. 		bDelayChange = Req.GetVariable("DelaySwitch","") != "" || LadderRules.bWaitingToSwitch;
  1956. 		if (bDelayChange)
  1957. 			Checked = " checked";
  1958. 		else Checked = "";
  1959.  
  1960. 		Res.Subst("ProfileSelect", 		GenerateSwitchProfileOptions(TempStr));
  1961. 		Res.Subst("NumberGamesText", 	LabelNumberGames);
  1962. 		Res.Subst("TextName", 			"NumMatches");
  1963. 		Res.Subst("TextValue", 			string(NumMatches));
  1964. 		Res.Subst("TextSize", 			"3");
  1965. 		Res.Subst("TextLength", 		"3");
  1966. 		Res.Subst("SwitchButtonName", 	"SetNewProfile");
  1967. 		Res.Subst("SwitchButtonValue", 	ButtonLoadProfile);
  1968. 		Res.Subst("DelayCheckName", 	"DelaySwitch");
  1969. 		Res.Subst("Checked", 			Checked);
  1970. 		Res.Subst("DelayCheckLabel", 	LabelDelayProfileChange);
  1971.  
  1972. 		if (Tmp != "" && bSwitching)
  1973. 			StatusOK(Res, SuccessSwitchProfile);
  1974.  
  1975. 		Tmp = CurS.getValue("ProfileName", PageCaption[0]);
  1976. 		if (LadderRules.GetRemainingMatches() > 0 && Tmp == LadderRules.Profiles[GetCurrentConfigIndex()].ProfileName)
  1977. 			Tmp = Tmp @ LabelNumberMatchesLeft @ string(LadderRules.GetRemainingMatches());
  1978.  
  1979. 		Res.Subst("LadderTable", 	WebInclude(IncludeSwitch));
  1980. 		Res.Subst("Section", 		LinkSwitchProfile);
  1981. 		Res.Subst("SubTitle", 		Tmp);
  1982. 		Res.Subst("PageHelp", 		HelpSwitchProfile);
  1983. 		Res.Subst("PostAction", 	ProfileSwitchURI$"?SessionID="$SID);
  1984.  
  1985. 		ShowPage(Res, MasterPage);
  1986. 	}
  1987. 	else AccessDenied(Res);
  1988. }
  1989.  
  1990. function QuerySubImport(WebRequest Req, WebResponse Res)
  1991. {
  1992. 	local string 					SID;
  1993. 	local Session 					CurS;
  1994. 	local ProfileConfigSet 			TempPCS;
  1995.  
  1996. 	SID = Req.GetVariable("SessionID");
  1997. 	CurS = SMaster.getSession(SID,true);
  1998. 	if (CanPerform("Lm"))
  1999. 	{
  2000. 	// We've gotten our profile - want to integrate it into the server now
  2001. 		if (Req.GetVariable("ImportRemoteProfile","") != "")
  2002. 		{
  2003. 			TempPCS = CreateImportSessionInfo(CurS);
  2004. 			if (TempPCS == None)
  2005. 			{
  2006. 				ShowMessage(Res, ImportProfileFailTitle, ImportProfileFailText);
  2007. 				return;
  2008. 			}
  2009. 			ShowMessage(Res, SuccessImportProfileTitle, SuccessImportProfile);
  2010. 			return;
  2011. 		}
  2012. 	}
  2013.  
  2014. 	else AccessDenied(Res);
  2015. }
  2016.  
  2017. function RemoteImport(ProfileImporter ProfileConn)
  2018. {
  2019. 	local int i,j;
  2020. 	local Session 	CurS;
  2021. 	local string 	Tmp, TempStr,
  2022. 					ImportRows,
  2023. 					PackageLink,
  2024. 					NewGameType, CustomGameLocation,
  2025. 					NewAccessType, CustomAccessLocation,
  2026. 					ImportProfileHTML,
  2027. 					MapLocation, MutatorLocation, MutatorName;
  2028. 	local StringArray ImportMaps, ImportMutators;
  2029.  
  2030. 	local WebRequest 		Req;
  2031. 	local WebResponse 		Res;
  2032.  
  2033. 	Req = ProfileConn.QueryRequest;
  2034. 	Res = ProfileConn.QueryResponse;
  2035.  
  2036. 	if (Res == None)
  2037. 	{
  2038. 		ShowMessage(Res, ErrorText, ErrorTimeout);
  2039. 		return;
  2040. 	}
  2041.  
  2042. 	switch (ProfileConn.ImportResult)
  2043. 	{
  2044. 	case IMPORT_BadURL: 		ShowMessage(Res,ErrorText,ErrorBadURL); 		CleanupQuery();	return;
  2045. 	case IMPORT_ResolveError: 	ShowMessage(Res,ErrorText,ErrorResolve); 		CleanupQuery();	return;
  2046. 	case IMPORT_BindError:		ShowMessage(Res,ErrorText,ErrorBind); 			CleanupQuery();	return;
  2047. 	case IMPORT_TimeOut:		ShowMessage(Res,ErrorText,ErrorTimeout);		CleanupQuery();	return;
  2048. 	case IMPORT_ServerError:	ShowMessage(Res,ErrorText,ErrorServer); 		CleanupQuery();	return;
  2049. 	case IMPORT_BadRequest:		ShowMessage(Res,ErrorText,ErrorBadRequest); 	CleanupQuery();	return;
  2050. 	case IMPORT_Unauthorized:	ShowMessage(Res,ErrorText,ErrorUnauthorized);	CleanupQuery();	return;
  2051. 	case IMPORT_Forbidden:		ShowMessage(Res,ErrorText,ErrorForbidden);		CleanupQuery();	return;
  2052. 	case IMPORT_NotFound:		ShowMessage(Res,ErrorText,ErrorNotFound); 		CleanupQuery();	return;
  2053. 	case IMPORT_InvalidProfile:	ShowMessage(Res,ErrorText,ErrorProfile);		CleanupQuery();	return;
  2054. 	}
  2055.  
  2056. 	CurS = ProfileConn.ImportS;
  2057. 	ImportMaps = new(None) class'SortedStringArray';
  2058. 	ImportMutators = new(None) class'SortedStringArray';
  2059.  
  2060. // General Profile Info
  2061. 	Res.Subst("SectionName", LabelGeneralProfile);
  2062. 	Res.Subst("SpecialInstructions", "");
  2063. 	ImportRows += WebInclude(IncludeSection);
  2064.  
  2065. 	Res.Subst("SettingName", LabelProfileName);
  2066. 	Res.Subst("SettingData", CurS.getValue("ProfileName"));
  2067. 	Res.Subst("Extra","");
  2068. 	ImportRows += WebInclude(IncludeRows);
  2069.  
  2070. // Profile Gametype Class
  2071. 	NewGameType = CurS.getValue("GameType");
  2072. 	CustomGameLocation = CurS.getValue("CustomGameLoc");
  2073.  
  2074. 	if (CustomGameLocation != "")
  2075. 		PackageLink = "<a href=\""$CustomGameLocation$"\" target=\"_blank\">"$CurS.getValue("GameName")$"</a>";
  2076. 	else PackageLink = CurS.getValue("GameName");
  2077.  
  2078. 	Res.Subst("SettingName", LabelGameType);
  2079. 	Res.Subst("SettingData", PackageLink);
  2080. 	Res.Subst("Extra","");
  2081. 	ImportRows += WebInclude(IncludeRows);
  2082.  
  2083. // Profile access control class
  2084. 	NewAccessType = CurS.getValue("ACClass");
  2085. 	CustomAccessLocation = CurS.getValue("CustomACLoc");
  2086.  
  2087. 	if (CustomAccessLocation != "")
  2088. 		PackageLink = "<a href=\""$CustomAccessLocation$"\" target=\"_blank\">"$NewAccessType$"</a>";
  2089. 	else PackageLink = NewAccessType;
  2090.  
  2091. 	Res.Subst("SettingName", LabelAccessControl);
  2092. 	Res.Subst("SettingData", PackageLink);
  2093. 	Res.Subst("Extra","");
  2094. 	ImportRows += WebInclude(IncludeRows);
  2095.  
  2096. // Map Information
  2097.  
  2098. 	Res.Subst("SectionName", TableTitle[3]);
  2099. 	Res.Subst("SpecialInstructions", "");
  2100. 	ImportRows += WebInclude(IncludeSection);
  2101.  
  2102. 	for (i = 0; i < CurS.getMapLength(); i++)
  2103. 		ImportMaps.Add(string(i), string(CurS.MapOrder(i)));
  2104.  
  2105. 	for (i = 0; i < ImportMaps.Count(); i++)
  2106. 	{
  2107. 		TempStr = CurS.getMap( int(ImportMaps.getItem(i)) );
  2108. 		MapLocation = ProfileConn.FindRemoteZipLocation(TempStr,ProfileConn.ProfileServerAddress $ ProfileConn.RemoteProfilePath);
  2109. 		if (MapLocation != "") PackageLink = "<a href=\""$MapLocation$"\" target=\"_blank\">"$TempStr$"</a>";
  2110. 		else PackageLink = TempStr;
  2111.  
  2112. 		if (CurS.MapRequired( TempStr ))
  2113. 			TempStr = "<font color=\"red\">"$RequiredText$"</font>";
  2114. 		else TempStr = AvailableText;
  2115.  
  2116. 		Res.Subst("SettingName", TempStr);
  2117. 		Res.Subst("SettingData", PackageLink);
  2118. 		Res.Subst("Extra", "");
  2119. 		ImportRows = ImportRows $ WebInclude(IncludeRows);
  2120. 	}
  2121.  
  2122. // Mutator Information
  2123. 	Res.Subst("SectionName", TableTitle[2]);
  2124. 	Res.Subst("SpecialInstructions", "");
  2125. 	ImportRows += WebInclude(IncludeSection);
  2126.  
  2127. 	for (i = 0; i < CurS.getMutatorLength(); i++)
  2128. 		ImportMutators.Add(string(i), CurS.getMutator(i));
  2129.  
  2130. 	for (i = 0; i < ImportMutators.Count(); i++)
  2131. 	{
  2132. 		TempStr = CurS.getMutator( int(ImportMutators.getItem(i)) );
  2133. 		for (j=0;j<CurS.getDataLength();j++)
  2134. 		{
  2135. 			CurS.getIDValue(j,MutatorName,Tmp);
  2136. 			if (Tmp ~= TempStr) break;
  2137. 		}
  2138.  
  2139. 		MutatorLocation = ProfileConn.FindRemoteZipLocation(TempStr,ProfileConn.ProfileServerAddress $ ProfileConn.RemoteProfilePath);
  2140. 		PackageLink = StringIf(MutatorLocation != "", "<a href=\""$MutatorLocation$"\" target=\"_blank\">"$MutatorName$"</a>", MutatorName);
  2141. 		TempStr = Stringif(CurS.MutRequired(TempStr), "<font color=\"red\">"$RequiredText$"</font>", AvailableText);
  2142.  
  2143. 		Res.Subst("SettingName", TempStr);
  2144. 		Res.Subst("SettingData", PackageLink);
  2145. 		Res.Subst("Extra", "");
  2146. 		ImportRows += WebInclude(IncludeRows);
  2147. 	}
  2148.  
  2149. // PlayInfo Information
  2150. 	Res.Subst("SectionName", TableTitle[4]);
  2151. 	Res.Subst("SpecialInstructions", "");
  2152. 	ImportRows += WebInclude(IncludeSection);
  2153. 	ImportRows = ImportRows $"<tr><td colspan=\"2\">&nbsp;</td></tr>"$ GeneratePlayInfoRows(Req,Res,IncludeRows);
  2154.  
  2155. // Build Subst's
  2156. 	Res.Subst("ButtonName", "ImportRemoteProfile");
  2157. 	Res.Subst("ButtonValue", ButtonApplyImportProfile);
  2158. 	Res.Subst("PageCaption", LabelApplyImportProfile);
  2159. 	ImportProfileHTML = WebInclude(IncludeCaptionButton);
  2160.  
  2161. 	Res.Subst("TableRows", ImportRows);
  2162. 	Res.Subst("LadderTable", WebInclude(IncludeTable) $ ImportProfileHTML);
  2163.  
  2164. 	Tmp = CurS.getValue("ProfileName", PageCaption[0]);
  2165. 	if (LadderRules.GetRemainingMatches() > 0 && Tmp == LadderRules.Profiles[GetCurrentConfigIndex()].ProfileName)
  2166. 		Tmp = Tmp @ LabelNumberMatchesLeft @ string(LadderRules.GetRemainingMatches());
  2167.  
  2168. 	Res.Subst("Section", LinkImportProfile);
  2169. 	Res.Subst("SubTitle", Tmp);
  2170. 	Res.Subst("PageHelp", HelpImportProfile);
  2171. 	Res.Subst("PostAction", SubImportURI$"?SessionID="$CurS.getHash());
  2172. 	ShowPage(Res, MasterPage);
  2173. 	CleanupQuery();
  2174. }
  2175.  
  2176. function QuerySubExport(WebRequest Req, WebResponse Res)
  2177. {
  2178. 	local int i,j;
  2179. 	local PlayInfo 	TempPI;
  2180. 	local FileLog 	EProfile;
  2181. 	local Session 	CurS;
  2182. 	local string 	SID, Logname,
  2183. 					TempStr, Tmp,
  2184. 					dataname, datavalue,
  2185. 					ProfileIndex, NewGameType,
  2186. 					ExportRows, Location;
  2187.  
  2188. 	local class<GameInfo> 		GI${1}< ${3} >
  2189. 	local class<AccessControl> 	AC${1}< ${3} >
  2190. 	local class<Mutator>		TempMut;
  2191. 	local array<class<Mutator> > M${1}< ${3} >
  2192. 	local class<Info>			TempSA;
  2193. 	local array<class<Info> >	SA${1}< ${3} >
  2194. 	local StringArray Mutators,GroupsOnly;
  2195.  
  2196.  
  2197. 	if (CanPerform("Lm"))
  2198. 	{
  2199. 		SID = Req.GetVariable("SessionID");
  2200. 		CurS = SMaster.getSession(SID,true);
  2201. 		ProfileIndex = Req.GetVariable("ProfileNameSelect", CurS.getValue("ProfileIndex"));
  2202.  
  2203.         CreateSessionInfo(ProfileIndex,SID,True);
  2204. 		Logname = CurS.getValue("Logname",Req.GetVariable("TextInput"));
  2205. 		if (Logname == "")
  2206. 			Logname = CurS.getValue("ProfileName");
  2207.  
  2208. 		CurS.setValue("Logname",Logname,True);
  2209. 		for (i=0;i<CurS.getMutatorLength();i++)
  2210. 		{
  2211. 			TempStr = CurS.getMutator(i);
  2212. 			if (EpicPackage(TempStr))
  2213. 				continue;
  2214. 			if (Req.GetVariable("Save"$TempStr,"") != "")
  2215. 				SetLocation(TempStr,Req.GetVariable(TempStr));
  2216. 		}
  2217.  
  2218. 		for (i=0;i<CurS.getMapLength();i++)
  2219. 		{
  2220. 			TempStr = CurS.getMap(i);
  2221. 			if (EpicPackage(TempStr))
  2222. 				continue;
  2223. 			if (Req.GetVariable("Save"$TempStr,"") != "")
  2224. 				SetLocation(TempStr,Req.GetVariable(TempStr));
  2225. 		}
  2226.  
  2227. 		NewGameType = CurS.getValue("GameType");
  2228. 		if (NewGameType != "")
  2229. 			GIClass = class<GameInfo>(DynamicLoadObject(NewGameType,class'Class'));
  2230. 		if (GIClass==None)
  2231. 		{
  2232. 			ShowMessage(Res,ErrorGameClassTitle,ErrorGameClassText);
  2233. 			return;
  2234. 		}
  2235.  
  2236. 		TempStr = CurS.getValue("ACClass", Level.Game.AccessControlClass);
  2237. 		if (TempStr != "")
  2238. 			ACClass = class<AccessControl>(DynamicLoadObject(TempStr,class'Class'));
  2239. 		if (ACClass == None)
  2240. 		{
  2241. 			ShowMessage(Res,ErrorAccessControlTitle,ErrorAccessControlText);
  2242. 			return;
  2243. 		}
  2244.  
  2245. 		if (Req.GetVariable("Export","")!="")
  2246. 		{
  2247. 		// Write file locations to .ini
  2248. 			EProfile = Level.Spawn(class'FileLog');
  2249. 			if (EProfile == None)
  2250. 			{
  2251. 				ShowMessage(Res, ErrorText, ErrorExportingProfile);
  2252. 				return;
  2253. 			}
  2254.  
  2255. 			EProfile.OpenLog(RemoveStr(CurS.getValue("Logname")," "));
  2256. 			EProfile.Logf("Profile:"$CurS.getValue("ProfileName")$Chr(21)$CurS.getValue("GameType")$Chr(21)$CurS.getValue("MaxMaps")$Chr(21)$GIClass.default.GameName$Chr(21)$string(ACClass));
  2257.  
  2258. 			for (i=0;i<CurS.getMapLength();i++)
  2259. 			{
  2260. 				TempStr = CurS.getMap(i);
  2261.  
  2262. 				if (Req.GetVariable(TempStr,"") != "")
  2263. 					Location = Chr(21) $ Req.GetVariable(TempStr);
  2264. 				else Location = "";
  2265.  
  2266. 				EProfile.Logf("Map:"$TempStr$Chr(21)$CurS.MapOrder(i)$Chr(21)$CurS.MapRequired(TempStr)$Location);
  2267. 			}
  2268.  
  2269. 			for (i=0;i<CurS.getSALength();i++)
  2270. 			{
  2271. 				TempStr = CurS.getServerActor(i);
  2272. 				for (j=0;j<ConfigM.ManagedActors.Length;j++)
  2273. 					if (string(ConfigM.ManagedActors[j].SAClass) ~= TempStr)
  2274. 						DataName = ConfigM.ManagedActors[j].SAName;
  2275.  
  2276. 				if (Req.GetVariable(TempStr,"") != "")
  2277. 					Location = Chr(21) $ Req.GetVariable(TempStr);
  2278. 				else Location = "";
  2279.  
  2280. 				EProfile.Logf("Mutator:"$DataName$Chr(21)$TempStr$Chr(21)$CurS.SARequired(TempStr)$Location);
  2281. 			}
  2282.  
  2283. 			for (i=0;i<CurS.getMutatorLength();i++)
  2284. 			{
  2285. 				TempStr = CurS.getMutator(i);
  2286. 				for (j=0;j<AllMutators.Length;j++)
  2287. 					if (AllMutators[j].ClassName == TempStr)
  2288. 						DataName = AllMutators[j].FriendlyName;
  2289.  
  2290. 				if (Req.GetVariable(TempStr,"") != "")
  2291. 					Location = Chr(21) $ Req.GetVariable(TempStr);
  2292. 				else Location = "";
  2293.  
  2294. 				EProfile.Logf("Mutator:"$DataName$Chr(21)$TempStr$Chr(21)$CurS.MutRequired(TempStr)$Location);
  2295. 			}
  2296.  
  2297. 			i=0;
  2298. 			j=0;
  2299. 			while (i<CurS.getDataLength())
  2300. 			{
  2301. 				CurS.getIdValue(i,dataname,datavalue);
  2302. 				if (InStr(dataname,".") != -1)
  2303. 					EProfile.Logf("Data:"$DataName$Chr(21)$DataValue);
  2304. 				i++;
  2305. 			}
  2306. 			EProfile.Destroy();
  2307. 			ShowMessage(Res, SuccessText, SuccessExportProfile$RemoveStr(LogName," ")$".txt");
  2308. 			return;
  2309. 		}
  2310.  
  2311.  
  2312. 	// Mutator Section
  2313. 		Mutators = new(None) class'SortedStringArray';
  2314. 		GroupsOnly = new(None) class'SortedStringArray';
  2315. 		for (i=0;i<CurS.getMutatorLength();i++)
  2316. 		{
  2317. 		    TempStr = CurS.getMutator(i);
  2318.             for (j=0;j<AllMutators.Length;j++)
  2319. 				if (TempStr ~= AllMutators[j].ClassName)
  2320. 					Mutators.Add(string(j), AllMutators[j].FriendlyName);
  2321. 			TempMut = class<Mutator>(DynamicLoadObject(TempStr,class'Class'));
  2322. 			if (TempMut != None)
  2323. 				MClass[MClass.Length] = TempMut;
  2324. 		}
  2325.  
  2326. 		Res.Subst("SectionName", TableTitle[2]);
  2327. 		Res.Subst("SpecialInstructions", "");
  2328. 		ExportRows += WebInclude(IncludeSection);
  2329.  
  2330. 		for (i = 0; i<Mutators.Count(); i++)
  2331. 		{
  2332. 			j = int(Mutators.GetItem(i));
  2333.  
  2334. 			Res.Subst("SettingName", AllMutators[j].FriendlyName);
  2335. 			if (EpicPackage(AllMutators[j].ClassName))
  2336. 				Res.Subst("SettingData", "");
  2337. 			else Res.Subst("SettingData", Textbox(AllMutators[j].ClassName,Min(Max(GetLongestURL(),16),64),128,GetLocation(AllMutators[j].ClassName)) $ "&nbsp;&nbsp;" $ SubmitButton("Save"$AllMutators[j].ClassName,ProfileButtonName[0]));
  2338.  
  2339. 			Res.Subst("Extra", "");
  2340. 			ExportRows += WebInclude(IncludeRows);
  2341. 		}
  2342.  
  2343. 		for (i=0;i<CurS.getSALength();i++)
  2344. 		{
  2345. 			TempStr = CurS.getServerActor(i);
  2346. 			if (TempStr != "")
  2347. 			{
  2348. 				TempSA = class<Info>(DynamicLoadObject(TempStr,class'class'));
  2349. 				if (TempSA != None)
  2350. 					SAClass[SAClass.Length] = TempSA;
  2351. 			}
  2352. 		}
  2353.  
  2354. 		TempPI = new(None) class'PlayInfo';
  2355. 		LoadThisPlayInfo(TempPI, GIClass, ACClass, MClass, SAClass);
  2356.  
  2357. 		Res.Subst("SectionName", TableTitle[3]);
  2358. 		Res.Subst("SpecialInstructions", "");
  2359. 		ExportRows += WebInclude(IncludeSection);
  2360.  
  2361. 		Res.Subst("SettingName", LabelMaxMaps);
  2362. 		TempStr = CurS.getValue("MaxMaps");
  2363. 		if (TempStr == "0")
  2364. 			TempStr = UnlimitedText;
  2365. 		Res.Subst("SettingData", TempStr);
  2366. 		Res.Subst("Extra", "<tr><td colspan=\"2\">&nbsp;&nbsp;</td></tr>");
  2367. 		ExportRows += WebInclude(IncludeRows);
  2368.  
  2369. // Map Section
  2370. 		for (i=0;i<CurS.getMapLength();i++)
  2371. 		{
  2372.             TempStr = CurS.getMap(i);
  2373.             Res.Subst("SettingName", TempStr);
  2374. 			Res.Subst("Extra", "");
  2375. 			if (EpicPackage(TempStr))
  2376. 				Res.Subst("SettingData", "");
  2377. 			else Res.Subst("SettingData", Textbox(TempStr,Min(Max(GetLongestURL(),16),64),128,GetLocation(TempStr)) $ "&nbsp;&nbsp;" $ SubmitButton("Save"$TempStr,ProfileButtonName[0]));
  2378.  
  2379. 			ExportRows += WebInclude(IncludeRows);
  2380. 		}
  2381.  
  2382. // PlayInfo section
  2383. 		Res.Subst("SectionName", TableTitle[4]);
  2384. 		Res.Subst("SpecialInstructions", "&nbsp;&nbsp;");
  2385. 		ExportRows += WebInclude(IncludeSection);
  2386. 		ExportRows += ("<tr><td colspan=\"2\">&nbsp;</td></tr>" $ GeneratePlayInfoRows(Req, Res, IncludeRows));
  2387. 		ExportRows += ("<tr><td colspan=\"2\">&nbsp;</td></tr><tr><td colspan=\"2\">"$LabelApplyExportProfile$"</td></tr><tr><td colspan=\"2\">"$SubmitButton("Export",ButtonApplyExportProfile)$"</td></tr>");
  2388.  
  2389. 		Res.Subst("TableRows", ExportRows);
  2390. 		Res.Subst("LadderTable", WebInclude(IncludeTable));
  2391.  
  2392. 		Tmp = CurS.getValue("ProfileName", PageCaption[0]);
  2393. 		if (LadderRules.GetRemainingMatches() > 0 && Tmp == LadderRules.Profiles[GetCurrentConfigIndex()].ProfileName)
  2394. 			Tmp = Tmp @ LabelNumberMatchesLeft @ string(LadderRules.GetRemainingMatches());
  2395.  
  2396. 		Res.Subst("Section", LinkExportProfile);
  2397. 		Res.Subst("PageHelp", HelpExportProfile);
  2398. 		Res.Subst("SubTitle", Tmp);
  2399. 		Res.Subst("PostAction", SubExportURI$"?SessionID="$SID);
  2400. 		ShowPage(Res, MasterPage);
  2401. 	}
  2402.  
  2403. 	else AccessDenied(Res);
  2404. }
  2405.  
  2406. //****************************************************************
  2407. //****************************************************************
  2408. // Query subpages for Add & Manage Modules
  2409. //
  2410. //
  2411.  
  2412. // Page 0
  2413. function QueryLadderManage(WebRequest Req, WebResponse Res)
  2414. {
  2415. 	local string 	HeaderRows, ManagementRows,
  2416. 					TempStr, Tmp, SID;
  2417. 	local bool		bAdd, bModify, bCopy, bDelete, bImport, bExport;
  2418. 	local Session 	CurS;
  2419. 	local ProfileImporter ProfileConn;
  2420.  
  2421. 	if (CanPerform("Lm"))
  2422. 	{
  2423. 		SID = Req.GetVariable("SessionID");
  2424. 		CurS = SMaster.getSession(SID, True);
  2425.  
  2426. 		// Submit button was pressed
  2427. 		if (Req.GetVariable(ProfileButtonName[0], "") != "")
  2428. 		{
  2429. 			switch (Req.GetVariable("Actions",""))
  2430. 			{
  2431. 				case "Add":
  2432. 					bAdd = True;
  2433. 					QuerySubFrame(Req, Res);
  2434. 					break;
  2435.  
  2436. 				case "Modify":
  2437. 					bModify = True;
  2438. 					TempStr = Req.GetVariable("ProfileNameSelect");
  2439. 					if (TempStr == "")
  2440. 					{
  2441. 						StatusError(Res, ErrorNoProfilesExist);
  2442. 						break;
  2443. 					}
  2444. 					QuerySubFrame(Req, Res);
  2445. 					return;
  2446.  
  2447. 				case "Copy":
  2448. 					bCopy = True;
  2449. 					Tmp = Req.GetVariable("ProfileNameSelect");
  2450. 					if (Tmp == "")
  2451. 						StatusError(Res, ErrorNoProfilesExist);
  2452.  
  2453. 					TempStr = Req.GetVariable("TextInput");
  2454. 					if (TempStr == "")
  2455. 					{
  2456. 						StatusError(Res, ErrorCopyNoName);
  2457. 						break;
  2458. 					}
  2459.  
  2460. 					if (LadderRules.CopyProfile(int(Tmp),TempStr))
  2461. 						StatusOK(Res,SuccessCopyProfile);
  2462. 					else StatusError(Res, ErrorCopyFrom);
  2463. 					break;
  2464.  
  2465. 				case "Delete":
  2466. 					bDelete = True;
  2467. 					TempStr = Req.GetVariable("ProfileNameSelect");
  2468. 					if (TempStr != "")
  2469. 					{
  2470. 						if (LadderRules.RemoveProfile(int(TempStr)))
  2471. 							StatusOK(Res, SuccessDeleteProfile);
  2472. 						else StatusError(Res, ErrorDeletingProfile);
  2473. 					}
  2474. 					else StatusError(Res, ErrorNoProfilesExist);
  2475. 					break;
  2476.  
  2477. 				case "Import":
  2478. 					bImport = True;
  2479. 					TempStr = Req.GetVariable("TextInput","");
  2480. 					if (!(Left(TempStr,7) ~= "http://"))
  2481. 					{
  2482. 						StatusError(Res, ErrorBadURL);
  2483. 						break;
  2484. 					}
  2485.  
  2486. 				// Spawn class to handle network interaction to receive remote profile
  2487. 					ProfileConn = Level.Spawn(Class'ProfileImporter');
  2488. 					If (ProfileConn == None)
  2489. 					{
  2490. 						ShowMessage(Res, ErrorText, ImportClassSpawnError);
  2491. 						return;
  2492. 					}
  2493.  
  2494. 				// Assign local connection objects to importer class
  2495. 					ProfileConn.QueryPage = Self;
  2496. 					ProfileConn.QueryRequest = Req;
  2497. 					ProfileConn.QueryResponse = Res;
  2498.  
  2499. 				// Setting bDelayCleanup prevents the connection from being closed
  2500. 				// when QueryProfileImport() returns to Query()
  2501. 				// Set this prior to initializing connection, to ensure correct behavior
  2502. 					Res.Connection.bDelayCleanup = True;
  2503.  
  2504. 				// Initialize connection to foreign host, pass Importer class a Session
  2505. 				// object to allow it to build a profile config set.
  2506. 					ProfileConn.Connect(TempStr, CurS);
  2507. 					return;
  2508.  
  2509. 				case "Export":
  2510. 					bExport = True;
  2511. 					TempStr = Req.GetVariable("ProfileNameSelect", "");
  2512. 					if (TempStr == "")
  2513. 					{
  2514. 						StatusError(Res, ErrorNoProfilesExist);
  2515. 						break;
  2516. 					}
  2517. 					QuerySubExport(Req,Res);
  2518. 					return;
  2519.  
  2520. 				default:
  2521. 					bModify = True;
  2522. 			}
  2523. 		}
  2524.  
  2525. 	// Output code -
  2526. 	// TODO: move to .inc file
  2527. 		HeaderRows = "<tr><td nowrap>"$LabelChooseAction$"</td><td nowrap>"$LabelInputDescription$"</td></tr>";
  2528. 	    ManagementRows += ("<tr><td nowrap>"$RadioButton("Actions", "Add", bAdd)$LabelAddProfile$"<br>");
  2529. 		ManagementRows += (RadioButton("Actions", "Modify", bModify)$LabelModifyProfile$"</td>");
  2530. 		ManagementRows += ("<td><select class=mini name='ProfileNameSelect'>"$GenerateSwitchProfileOptions(TempStr)$"</select>&nbsp;"$LabelSelectActions$"</td></tr>");
  2531. 		ManagementRows += ("<tr><td nowrap>"$RadioButton("Actions", "Copy", bCopy)$LabelCopyProfile$"<br>");
  2532. 		ManagementRows += (RadioButton("Actions", "Delete", bDelete)$LabelDeleteProfile$"</td>");
  2533. 		ManagementRows += ("<td nowrap>"$Textbox("TextInput",64,128)$"&nbsp;"$LabelTextboxActions$"</td></tr>");
  2534. 		ManagementRows += ("<tr><td nowrap>"$RadioButton("Actions", "Import", bImport)$LabelImportProfile$"<br>");
  2535. 		ManagementRows += (RadioButton("Actions", "Export", bExport)$LabelExportProfile$"</td>");
  2536. 		ManagementRows += ("<td>"$SubmitButton(ProfileButtonName[0],ProfileButtonValue[0])$"</td></tr>");
  2537.  
  2538. 		Res.Subst("TableTitle", TableTitle[0]);
  2539. 		Res.Subst("HeaderRow", HeaderRows);
  2540. 		Res.Subst("TableRows",ManagementRows);
  2541.  
  2542. 		Tmp = CurS.getValue("ProfileName", PageCaption[0]);
  2543. 		if (LadderRules.GetRemainingMatches() > 0 && Tmp == LadderRules.Profiles[GetCurrentConfigIndex()].ProfileName)
  2544. 			Tmp @= (LabelNumberMatchesLeft @ string(LadderRules.GetRemainingMatches()));
  2545.  
  2546. 		Res.Subst("Section", LabelManagement);
  2547. 		Res.Subst("PageHelp", HelpManageProfile);
  2548. 		Res.Subst("SubTitle", Tmp);
  2549. 		Res.Subst("LadderTable", WebInclude(IncludeTable));
  2550. 		Res.Subst("PostAction", ProfileManageURI);
  2551. 		ShowPage(Res, MasterPage);
  2552. 	}
  2553.  
  2554. 	else AccessDenied(Res);
  2555. }
  2556.  
  2557. // Page 1
  2558. function QuerySubGameType(WebRequest Req, WebResponse Res)
  2559. {
  2560. 	local int i;
  2561. 	local string DataName, DataValue, SID, NewName, OldName;
  2562. 	local string GameTypeRows, OldGameType, CommandLineRows;
  2563. 	local string GameTypeTable, CommandLineTable, ApplyTable;
  2564. 	local Session CurS;
  2565. 	local LadderProfiles LadderMaster;
  2566.  
  2567.  
  2568. 	if (CanPerform("Lm"))
  2569. 	{
  2570. 		SID = Req.GetVariable("SessionID");
  2571. 		CurS = SMaster.getSession(SID, true);
  2572.  
  2573.         if (Req.GetVariable(CurS.getValue("ButtonName",""),"")!="")
  2574.     	{
  2575.     		NewName = Req.GetVariable("NewProfile",DefaultProfileName);
  2576.     		OldName = CurS.getValue("ProfileName");
  2577.     		if ((OldName != "" && !(OldName ~= NewName)) || OldName == "")
  2578.     		{
  2579. 	    		for (i=0;i<LadderRules.Profiles.Length;i++)
  2580. 	    		{
  2581. 	    			if (NewName ~= LadderRules.Profiles[i].ProfileName)
  2582. 	    			{
  2583. 	    				StatusError(Res, ErrorSameProfileName);
  2584. 	    				NewName = DefaultProfileName;
  2585. 	    				break;
  2586. 	    			}
  2587. 	    		}
  2588. 	    	}
  2589. 			CurS.setValue("ProfileName", NewName, true);
  2590. 			CurS.setValue("GameType", Req.GetVariable("NewGameType"), True, OldGameType);
  2591. 			if (!(OldGameType ~= CurS.getValue("GameType")))
  2592. 			{
  2593. 				CurS.ClearMaps();
  2594. 			// Reset all stored PlayInfo information
  2595. 				for (i=0;i<CurS.getDataLength();i++)
  2596. 				{
  2597. 					CurS.getIDValue(i,DataName,DataValue);
  2598. 					if (InStr(DataName, ".") != -1)
  2599. 					{
  2600. 						CurS.delValue(DataName);
  2601. 						i--;
  2602. 					}
  2603. 				}
  2604. 			}
  2605. 		}
  2606.  
  2607. 		Res.Subst("NewProfileName", CurS.getValue("ProfileName", DefaultProfileName));
  2608. 		GameTypeRows = WebInclude(IncludeProfileName);
  2609.  
  2610. 		for (i=0;i<AGameType.Count();i++)
  2611. 		{
  2612. 			Res.Subst("GameTypeClass", 	AGameType.GetItem(i));
  2613. 			Res.Subst("GameTypeName", 	AGameType.GetTag(i));
  2614. 			Res.Subst("Selected", 		StringIf(CurS.getValue("GameType") ~= AGameType.GetItem(i), " checked", ""));
  2615. 			GameTypeRows += WebInclude(IncludeGameType);
  2616. 		}
  2617.  
  2618. 	// Fill in caption table values
  2619. 		Res.Subst("PageCaption", 	CurS.getValue("PageCaption", PageCaption[1]));
  2620. 		Res.Subst("ButtonName", 	CurS.getValue("ButtonName", ProfileButtonName[1]));
  2621. 		Res.Subst("ButtonValue", 	CurS.getValue("ButtonValue", ProfileButtonValue[1]));
  2622.  
  2623.   		Res.Subst("TableRows", 		GameTypeRows);
  2624. 		Res.Subst("LadderTable", 	WebInclude(IncludeTable)$WebInclude(IncludeCaptionButton));
  2625. 		Res.Subst("PostAction", 	CurS.GetValue("CurrentPage"));
  2626. 		ShowPage(Res, SubFrameContent);
  2627. 	}
  2628.  
  2629. 	else AccessDenied(Res);
  2630. }
  2631.  
  2632. // Page 2
  2633. function QuerySubMutators(WebRequest Req, WebResponse Res)
  2634. {
  2635. 	local int i,j;
  2636. 	local bool 		bAllMuts,
  2637. 					bClearMuts,
  2638. 					bChecked;
  2639. 	local string 	MutatorRows,
  2640. 					SID, TempStr;
  2641.  
  2642. 	local Session CurS;
  2643. 	local StringArray Mutators, ServerActors;
  2644. 	local class<Mutator> Mut${1}< ${3} >
  2645.  
  2646.  
  2647. 	if (CanPerform("Lm"))
  2648. 	{
  2649. 		SID = Req.GetVariable("SessionID");
  2650. 		CurS = SMaster.getSession(SID, true);
  2651.  
  2652. 		if (Req.GetVariable(CurS.getValue("ButtonName",""),"")!="")
  2653. 		{
  2654. 			bAllMuts = Req.GetVariable("AllowAllMutators")!="";
  2655. 			bClearMuts = Req.GetVariable("ClearAllMutators")!="";
  2656. //			CurS.ClearMutators();
  2657.  
  2658. 			for (i=0;i<ConfigM.ManagedActors.Length;i++)
  2659. 			{
  2660. 				TempStr = string(ConfigM.ManagedActors[i].SAClass);
  2661. 				if (bAllMuts || (!bClearMuts && Req.GetVariable(TempStr,"") != ""))
  2662. 					CurS.setServerActor(TempStr, True, CurS.SARequired(TempStr));
  2663. 				else CurS.delServerActor(TempStr);
  2664. 			}
  2665.  
  2666. 			for (i=0;i<AllMutators.Length;i++)
  2667. 			{
  2668. 				if (bAllMuts || (!bClearMuts && (Req.GetVariable(AllMutators[i].ClassName,"")!="" || Req.GetVariable(AllMutators[i].GroupName)~=AllMutators[i].ClassName)))
  2669. 					CurS.setMutator(AllMutators[i].ClassName,true,CurS.MutRequired(AllMutators[i].ClassName));
  2670. 				else if (Req.GetVariable(AllMutators[i].GroupName) ~= "None")
  2671. 					CurS.setMutator(AllMutators[i].GroupName,true);
  2672. 				else
  2673. 				{
  2674. 					CurS.delMutator(AllMutators[i].ClassName);
  2675. 					CurS.delMutator(AllMutators[i].GroupName);
  2676. 				}
  2677. 			}
  2678. 		}
  2679.  
  2680. 		Mutators = new(None) class'SortedStringArray';
  2681. 		ServerActors = new(None) class'SortedStringArray';
  2682. //		GroupsOnly = new(None) class'SortedStringArray';
  2683. 		for (i = 0; i<AllMutators.Length; i++)
  2684. 		{
  2685. 			MutClass = class<Mutator>(DynamicLoadObject(AllMutators[i].ClassName, class'Class'));
  2686. 			if (MutClass != None)
  2687. 				Mutators.Add(string(i),AllMutators[i].FriendlyName);
  2688. 		}
  2689.  
  2690. 		for (i=0;i<ConfigM.ManagedActors.Length;i++)
  2691. 			if (ConfigM.ManagedActors[i].SAClass != None)
  2692. 				ServerActors.Add(string(i),ConfigM.ManagedActors[i].SAName);
  2693.  
  2694. // Uncomment this to allow mutators to be grouped according to MutatorGroup
  2695. /*
  2696. 		CreateFullMutatorList(Mutators,GroupsOnly);
  2697.  
  2698. 		for (i=0;i<CurS.GetMutatorLength();i++)
  2699. 		{
  2700. 			k = 0-1;
  2701. 			for (j=0;j<AllMutators.Length;j++)
  2702. 				if (CurS.GetMutator(i) ~= AllMutators[j].ClassName)
  2703. 					break;
  2704. 			if (j<AllMutators.Length) k = GroupsOnly.FindItemId(string(j));
  2705. 			if (k >= 0)
  2706. 			{
  2707. 				for (z=0;z<TempA.Length;z++)
  2708. 				{
  2709. 					if (TempA[z] ~= AllMutators[j].GroupName)
  2710. 					{
  2711. 						bAllMuts = True;
  2712. 						break;
  2713. 					}
  2714. 				}
  2715.  
  2716. 				if (!bAllMuts) TempA[TempA.Length] = AllMutators[j].GroupName;
  2717. 			}
  2718. 			if (bAllMuts)
  2719.        			break;
  2720. 		}
  2721.  
  2722. 		lastgroup = "";
  2723. 		thisgroup = "";
  2724. 		nextgroup = "";
  2725. 		MutatorRows="";
  2726.  
  2727. 		for (i=0;i<GroupsOnly.Count();i++)
  2728. 		{
  2729. 			j=int(GroupsOnly.GetItem(i));
  2730. 			if (AllMutators[j].GroupName=="")
  2731. 				thisgroup="Z"$string(z++);
  2732. 			else thisgroup = AllMutators[j].GroupName;
  2733. 			if ( (i + 1) == GroupsOnly.Count())
  2734. 				nextgroup = "";
  2735. 			else
  2736. 			{
  2737. 			// Assign nextgroup to the next mutators group
  2738. 				k = int(GroupsOnly.GetItem(i + 1));
  2739. 				if (AllMutators[k].GroupName=="")
  2740. 					nextgroup="Z"$string(z);
  2741. 				else nextgroup = AllMutators[k].GroupName;
  2742. 			}
  2743.  
  2744. 			Res.Subst("GroupName", thisgroup);
  2745. 			Res.Subst("MutatorClass", AllMutators[j].ClassName);
  2746. 			Res.Subst("MutatorName", AllMutators[j].FriendlyName);
  2747. 			Res.Subst("MutatorDesc", AllMutators[j].Description);
  2748.  
  2749. 			if ((lastgroup != thisgroup) && (thisgroup == nextgroup)) // and the next mut is in the same group as this one
  2750. 			{
  2751. 				if (bAllMuts||CurS.HasMutator(thisgroup)) Res.Subst("Checked", "checked");
  2752. 				MutatorRows = MutatorRows$WebInclude("current_mutators_group");
  2753. 			}
  2754. 			else
  2755. 			{
  2756. 				if (CurS.HasMutator(AllMutators[j].ClassName) && !bAllMuts) Res.Subst("Checked", "checked"); else Res.Subst("Checked", "");
  2757. 				MutatorRows = MutatorRows$WebInclude("current_mutators_group_row");
  2758. 			}
  2759.  
  2760. 			lastgroup=thisgroup;
  2761. 		}
  2762. */
  2763. 		bAllMuts = True;
  2764. 		for (i = 0; i<ServerActors.Count(); i++)
  2765. 		{
  2766. 			TempStr = ""; bChecked = False;
  2767. 			j = int(ServerActors.GetItem(i));
  2768.  
  2769. 			if (CurS.HasServerActor(string(ConfigM.ManagedActors[j].SAClass)))
  2770. 				bChecked = True;
  2771. 			else if (bAllMuts) bAllMuts = False;
  2772.  
  2773. 			Res.Subst("Content", Checkbox(string(ConfigM.ManagedActors[j].SAClass),bChecked) $ "&nbsp;" $ ServerActors.GetTag(i));
  2774. 			TempStr = WebInclude(NowrapLeft);
  2775. 			Res.Subst("Content", ConfigM.ManagedActors[j].SADescription);
  2776. 			Res.Subst("RowContent", TempStr $ WebInclude(CellLeft));
  2777.  
  2778. 			MutatorRows += WebInclude(RowLeft);
  2779. 		}
  2780.  
  2781. 		for (i = 0; i<Mutators.Count(); i++)
  2782. 		{
  2783. 			TempStr = ""; bChecked = False;
  2784. 			j = int(Mutators.GetItem(i));
  2785.  
  2786. 			if (CurS.HasMutator(AllMutators[j].ClassName))
  2787. 				bChecked = True;
  2788. 			else if (bAllMuts) bAllMuts = False;
  2789.  
  2790. 			Res.Subst("Content", CheckBox(AllMutators[j].ClassName, bChecked) $ "&nbsp;" $ AllMutators[j].FriendlyName);
  2791. 			TempStr = WebInclude(NowrapLeft);
  2792. 			Res.Subst("Content", AllMutators[j].Description);
  2793. 			Res.Subst("RowContent", TempStr $ WebInclude(CellLeft));
  2794.  
  2795. 			MutatorRows += WebInclude(RowLeft);
  2796. 		}
  2797.  
  2798. 		if (bAllMuts)
  2799. 			Res.Subst("Content", Checkbox("ClearAllMutators", False)@LabelUncheckAllMutator);
  2800. 		else
  2801. 			Res.Subst("Content", Checkbox("AllowAllMutators", False)@LabelCheckAllMutator);
  2802. 		Res.Subst("SpanLength", "2");
  2803. 		Res.Subst("SpanContent", "&nbsp;&nbsp;");
  2804. 		Res.Subst("RowContent", WebInclude(CellColSpan));
  2805. 		MutatorRows += WebInclude(RowLeft);
  2806.  
  2807. 		Res.Subst("RowContent", WebInclude(CellLeft));
  2808. 		MutatorRows += WebInclude(RowLeft);
  2809.  
  2810. 		Res.Subst("TableRows", MutatorRows);
  2811. 	// Fill in caption table values
  2812. 		Res.Subst("PageCaption", 	CurS.getValue("PageCaption", PageCaption[2]));
  2813. 		Res.Subst("ButtonName", 	CurS.getValue("ButtonName", ProfileButtonName[2]));
  2814. 		Res.Subst("ButtonValue", 	CurS.getValue("ButtonValue", ProfileButtonValue[2]));
  2815.  
  2816. 		Res.Subst("LadderTable", 	WebInclude(IncludeTable)$WebInclude(IncludeCaptionButton));
  2817. 		Res.Subst("PostAction", 	CurS.GetValue("CurrentPage"));
  2818. 		ShowPage(Res, SubFrameContent);
  2819. 	}
  2820.  
  2821. 	else AccessDenied(Res);
  2822. }
  2823.  
  2824. // Page3
  2825. function QuerySubMaps(WebRequest Req, WebResponse Res)
  2826. {
  2827. 	local int i;
  2828. 	local string 	SID,
  2829. 					MapRows,
  2830. 					TempStr, Temp,
  2831. 					CheckString;
  2832. 	local bool 		bAllMaps,
  2833. 					bClearMaps,
  2834. 					bChecked;
  2835.  
  2836. 	local Session CurS;
  2837. 	local StringArray SortedMaps;
  2838. 	local array<string> TempMaps;
  2839. 	local class<GameInfo> GI${1}< ${3} >
  2840.  
  2841.  
  2842. 	if (CanPerform("Lm"))
  2843. 	{
  2844. 		SID = Req.GetVariable("SessionID");
  2845. 		CurS = SMaster.getSession(SID);
  2846.  
  2847. 		TempStr = CurS.getValue("GameType");
  2848. 		if (TempStr != "")
  2849. 			GIClass = class<GameInfo>(DynamicLoadObject(TempStr,class'Class'));
  2850. 		if (GIClass == None)
  2851. 		{
  2852. 			ShowFramedMessage(Res,ErrorGameClassText,True);
  2853. 			return;
  2854. 		}
  2855. 		// Build a string array of maps valid for this gametype.
  2856. 		GIClass.static.LoadMapList(GIClass.default.MapPrefix, TempMaps);
  2857.  
  2858. 		if (Req.GetVariable(CurS.getValue("ButtonName",""),"")!="")
  2859. 		{
  2860. 			bAllMaps = Req.GetVariable("AllowAllMaps","")!="";
  2861. 			bClearMaps = Req.GetVariable("ClearAllMaps","")!="";
  2862.  
  2863. 			for (i=0;i<TempMaps.Length;i++)
  2864. 				if (bAllMaps || (!bClearMaps && Req.GetVariable(TempMaps[i])!=""))
  2865. 					CurS.setMap(TempMaps[i],0,True,CurS.MapRequired(TempMaps[i]));
  2866. 				else CurS.delMap(TempMaps[i]);
  2867. 		}
  2868. 		// Add the map name array to a sorted string array for sorting
  2869. 		SortedMaps = new(None) class'SortedStringArray';
  2870. 		for(i=0;i<TempMaps.Length;i++)
  2871. 			SortedMaps.Add(string(i),TempMaps[i]);
  2872.  
  2873. 		bAllMaps = True;
  2874. 		// Now build the map rows
  2875. 		for (i=0;i<SortedMaps.Count();i++)
  2876. 		{
  2877. 			Temp = ""; bChecked = False;
  2878. 			TempStr = SortedMaps.GetTag(i);
  2879. 			if (CurS.HasMap(TempStr))
  2880. 				bChecked = True;
  2881. 			else if (bAllMaps) bAllMaps = False;
  2882.  
  2883. 			Res.Subst("Content", Checkbox(TempStr, bChecked) $ "&nbsp;" $ TempStr);
  2884. 			Res.Subst("RowContent", WebInclude(CellLeft));
  2885. 		// Build string for javascript function
  2886. 			if (CheckString!="")
  2887. 				CheckString += "','";
  2888. 			CheckString += TempStr;
  2889.  
  2890. 			MapRows += WebInclude(RowLeft);
  2891. 		}
  2892.  
  2893. 	// Fill Javascript substs
  2894. 		Res.Subst("JavaScripts","<script language=\"JavaScript\" type=\"text/JavaScript\">function MM_findObj(n,d){var p,i,x;if(!d)d=document;if((p=n.indexOf(\"?\"))>0&&parent.frames.length){d=parent.frames[n.substring(p+1)].document;n=n.substring(0,p);}if(!(x=d[n])&&d.all)x=d.all[n];for(i=0;!x&&i<d.forms.length;i++)x=d.forms[i][n];for(i=0;!x&&d.layers&&i<d.layers.length;i++)x=MM_findObj(n,d.layers[i].document);if(!x&&d.getElementById)x=d.getElementById(n);return x;}function CheckMaps(){var maps=CheckMaps.arguments;var MapChecked=false;for(var i=0;i<maps.length;i++){var myObj=MM_findObj(maps[i]);if(myObj.checked==true){MapChecked=true}}if(MapChecked==false){alert('You must check at least one map to continue!')}document.MM_returnValue=(MapChecked);}</script>");
  2895. 		Res.Subst("JCheck"," onClick=\"CheckMaps('AllowAllMaps','"$CheckString$"');return document.MM_returnValue\"");
  2896. 		Res.Subst("Checked","");
  2897.  
  2898. 		if (bAllMaps)
  2899. 			Res.Subst("Content", Checkbox("ClearAllMaps", False) @ LabelUncheckAllMap);
  2900. 		else Res.Subst("Content", Checkbox("AllowAllMaps", False) @ LabelCheckAllMap);
  2901.  
  2902. 		Res.Subst("SpanLength", "2");
  2903. 		Res.Subst("SpanContent", "&nbsp;&nbsp;");
  2904. 		Res.Subst("RowContent", WebInclude(CellColSpan));
  2905. 		MapRows += WebInclude(RowLeft);
  2906.  
  2907. 		Res.Subst("RowContent", WebInclude(CellLeft));
  2908. 		MapRows += WebInclude(RowLeft);
  2909.  
  2910. 		// Set ladder_caption_table subst's
  2911. 		Res.Subst("PageCaption", 	CurS.getValue("PageCaption",PageCaption[3]));
  2912. 		Res.Subst("ButtonName", 	CurS.getValue("ButtonName", ProfileButtonName[3]));
  2913. 		Res.Subst("ButtonValue", 	CurS.getValue("ButtonValue", ProfileButtonValue[3]));
  2914.  
  2915. 		Res.Subst("TableRows", MapRows);
  2916.  
  2917. 		Res.Subst("LadderTable", 	WebInclude(IncludeTable)$WebInclude(IncludeCaptionButton));
  2918. 		Res.Subst("PostAction", 	CurS.getValue("CurrentPage"));
  2919. 		ShowPage(Res, SubFrameContent);
  2920. 	}
  2921.  
  2922. 	else AccessDenied(Res);
  2923. }
  2924.  
  2925. // Page 4
  2926. function QuerySubRules(WebRequest Req, WebResponse Res)
  2927. {
  2928. 	local int i;
  2929. 	local string 	TempStr,
  2930. 					SID;
  2931. 	local Session 	CurS;
  2932. 	local PlayInfo 	TempPI;
  2933. 	local class<Mutator> 		Temp${1}< ${3} >
  2934. 	local class<GameInfo> 		GI${1}< ${3} >
  2935. 	local class<AccessControl> 	AC${1}< ${3} >
  2936. 	local array<class<Mutator> > M${1}< ${3} >
  2937. 	local class<Info>			TempSA;
  2938. 	local array<class<Info> >	SA${1}< ${3} >
  2939.  
  2940. 	if (CanPerform("Lm"))
  2941. 	{
  2942. 		SID = Req.GetVariable("SessionID");
  2943. 		CurS = SMaster.GetSession(SID);
  2944.  
  2945. 		TempStr = CurS.getValue("GameType");
  2946. 		if (TempStr != "")
  2947. 			GIClass = class<GameInfo>(DynamicLoadObject(TempStr,class'Class'));
  2948. 		if (GIClass == None)
  2949. 		{
  2950. 			ShowFramedMessage(Res,ErrorGameClassText,True);
  2951. 			return;
  2952. 		}
  2953.  
  2954. 		TempStr = CurS.getValue("ACClass", Level.Game.AccessControlClass);
  2955. 		if (TempStr != "")
  2956. 			ACClass = class<AccessControl>(DynamicLoadObject(TempStr,class'Class'));
  2957. 		if (ACClass == None)
  2958. 		{
  2959. 			ShowFramedMessage(Res,ErrorAccessControlText,True);
  2960. 			return;
  2961. 		}
  2962.  
  2963. 		if (Req.GetVariable(CurS.getValue("ButtonName",""),"")!="")
  2964. 		{
  2965. 			for (i=0;i<CurS.GetMutatorLength();i++)
  2966. 			{
  2967. 				TempStr = CurS.getMutator(i);
  2968. 				if (TempStr != "")
  2969. 				{
  2970. 					TempClass = class<Mutator>(DynamicLoadObject(TempStr,class'Class'));
  2971. 					if (TempClass != None)
  2972. 						MClass[MClass.Length] = Temp${1}< ${3} >
  2973. 				}
  2974. 			}
  2975.  
  2976. 			TempPI = new(None) class'PlayInfo';
  2977. 			for (i=0;i<CurS.getSALength(); i++)
  2978. 			{
  2979. 				TempStr = CurS.getServerActor(i);
  2980. 				if (TempStr != "")
  2981. 				{
  2982. 					TempSA = class<Info>(DynamicLoadObject(TempStr,class'Class'));
  2983. 					if (TempSA != None)
  2984. 						SAClass[SAClass.Length] = TempSA;
  2985. 				}
  2986. 			}
  2987.  
  2988. 			LoadThisPlayInfo(TempPI, GIClass, ACClass, MClass, SAClass);
  2989. 			for (i=0;i<TempPI.Settings.Length;i++)
  2990. 			{
  2991. 				if (!SettingIsAllowed(TempPI.Settings[i].SecLevel)) continue;
  2992. 				TempStr = Req.GetVariable(TempPI.Settings[i].SettingName,TempPI.Settings[i].Value);
  2993.  
  2994. 				if (TempPI.Settings[i].RenderType == "Text")
  2995. 					CheckSettingValue(TempPI.Settings[i].Data, TempStr);
  2996.  
  2997. 				CurS.setValue(TempPI.Settings[i].SettingName,TempStr,true);
  2998. 			}
  2999. 		}
  3000.  
  3001. 		Res.Subst("TableRows",		GeneratePlayInfoRows(Req, Res, "defaults_row"));
  3002.  
  3003. 		// Set ladder_caption_table subst's
  3004. 		Res.Subst("PageCaption", 	CurS.getValue("PageCaption",PageCaption[4]));
  3005. 		Res.Subst("ButtonName", 	CurS.getValue("ButtonName", ProfileButtonName[4]));
  3006. 		Res.Subst("ButtonValue", 	CurS.getValue("ButtonValue", ProfileButtonValue[4]));
  3007.  
  3008. 		Res.Subst("LadderTable", 	WebInclude(IncludeTable)$WebInclude(IncludeCaptionButton));
  3009. 		Res.Subst("PostAction", 	CurS.getValue("CurrentPage"));
  3010. 		ShowPage(Res, SubFrameContent);
  3011. 	}
  3012.  
  3013. 	else AccessDenied(Res);
  3014. }
  3015.  
  3016. // Page 5
  3017. function QuerySubReview(WebRequest Req, WebResponse Res)
  3018. {
  3019. 	local int i,j,k,z;
  3020. 	local string 	SID,
  3021. 					TempStr, TempSA,
  3022. 					ReviewRows,
  3023. 					thisgroup, lastgroup, nextgroup;
  3024.  
  3025. 	local Session CurS;
  3026. 	local StringArray Mutators, GroupsOnly;
  3027. 	local class<Mutator> 		Temp${1}< ${3} >
  3028. 	local class<Info>			TempSA${1}< ${3} >
  3029. 	local class<GameInfo> 		GI${1}< ${3} >
  3030. 	local class<AccessControl> 	AC${1}< ${3} >
  3031. 	local array<class<Mutator> > M${1}< ${3} >
  3032.  
  3033. 	if (CanPerform("Lm"))
  3034. 	{
  3035. 		SID = Req.GetVariable("SessionID");
  3036. 		CurS = SMaster.getSession(SID);
  3037.  
  3038. 		TempStr = CurS.getValue("GameType");
  3039. 		if (TempStr != "")
  3040. 			GIClass = class<GameInfo>(DynamicLoadObject(TempStr,class'Class'));
  3041. 		if (GIClass == None)
  3042. 		{
  3043. 			ShowFramedMessage(Res,ErrorGameClassText,True);
  3044. 			return;
  3045. 		}
  3046.  
  3047. 		TempStr = CurS.getValue("ACClass",Level.Game.AccessControlClass);
  3048. 		if (TempStr != "")
  3049. 			ACClass = class<AccessControl>(DynamicLoadObject(TempStr,class'Class'));
  3050. 		if (ACClass == None)
  3051. 		{
  3052. 			ShowFramedMessage(Res,ErrorAccessControlText,True);
  3053. 			return;
  3054. 		}
  3055.  
  3056. 		Mutators = new(None) class'SortedStringArray';
  3057. 		GroupsOnly = new(None) class'SortedStringArray';
  3058. 		for (i = 0; i<AllMutators.Length; i++)
  3059. 		{
  3060. 			if (CurS.HasMutator(AllMutators[i].ClassName)||CurS.HasMutator(AllMutators[i].GroupName))
  3061. 			{
  3062. 				TempClass = class<Mutator>(DynamicLoadObject(AllMutators[i].ClassName, class'Class'));
  3063. 				if (TempClass != None)
  3064. 				{
  3065. 					MClass[MClass.Length] = Temp${1}< ${3} >
  3066. 					Mutators.Add(string(i),AllMutators[i].FriendlyName);
  3067. 				}
  3068. 			}
  3069. 		}
  3070.  
  3071. 		CreateFullMutatorList(Mutators,GroupsOnly);
  3072. 		lastgroup = ""; thisgroup = ""; nextgroup = "";
  3073.  
  3074. 		Res.Subst("SectionName", TableTitle[2]);
  3075. 		Res.Subst("SpecialInstructions", LabelRequiredMutators);
  3076. 		ReviewRows += WebInclude(IncludeSection);
  3077.  
  3078. 		for (i=0;i<GroupsOnly.Count();i++)
  3079. 		{
  3080. 			j=int(GroupsOnly.GetItem(i));
  3081.  
  3082. 			if (AllMutators[j].GroupName=="")
  3083. 				thisgroup="Z"$string(z++);
  3084. 			else thisgroup = AllMutators[j].GroupName;
  3085.  
  3086. 			if ( (i + 1) == GroupsOnly.Count())
  3087. 				nextgroup = "";
  3088. 			else
  3089. 			{
  3090. 			// Assign nextgroup to the next mutators group
  3091. 				k = int(GroupsOnly.GetItem(i + 1));
  3092. 				if (AllMutators[k].GroupName=="")
  3093. 					nextgroup="Z"$string(z);
  3094. 				else nextgroup = AllMutators[k].GroupName;
  3095. 			}
  3096.  
  3097. 			Res.Subst("GroupName", thisgroup);
  3098. 			Res.Subst("MutatorClass", AllMutators[j].ClassName);
  3099. 			Res.Subst("MutatorName", AllMutators[j].FriendlyName);
  3100. 			Res.Subst("MutatorDesc", AllMutators[j].Description);
  3101.  
  3102. 			if ((lastgroup != thisgroup) && (thisgroup == nextgroup)) // and the next mut is in the same group as this one
  3103. 			{
  3104.                 Res.Subst("Checked", " checked");
  3105. 				ReviewRows += WebInclude("current_mutators_group");
  3106. 			}
  3107.  
  3108. 			Res.Subst("Checked", StringIf(CurS.MutRequired(AllMutators[j].ClassName), " checked", ""));
  3109. 			ReviewRows += WebInclude("current_mutators_group_row");
  3110.  
  3111. 			lastgroup=thisgroup;
  3112. 		}
  3113.  
  3114. 		for (i = 0; i<Mutators.Count(); i++)
  3115. 		{
  3116. 			TempStr = "";
  3117. 			j = int(Mutators.GetItem(i));
  3118.  
  3119. 			Res.Subst("Content", CheckBox(AllMutators[j].ClassName, CurS.MutRequired(AllMutators[j].ClassName)) $ "&nbsp;" $ AllMutators[j].FriendlyName);
  3120. 			TempStr = WebInclude(NowrapLeft);
  3121. 			Res.Subst("Content", AllMutators[j].Description);
  3122. 			Res.Subst("RowContent", TempStr $ WebInclude(CellLeft));
  3123.  
  3124. 			ReviewRows += WebInclude(RowLeft);
  3125. 		}
  3126.  
  3127. 		Mutators.Reset();
  3128. 		for (i = 0; i < ConfigM.ManagedActors.Length; i++)
  3129. 		{
  3130. 			TempSA = string(ConfigM.ManagedActors[i].SAClass);
  3131. 			if (CurS.HasServerActor(TempSA))
  3132. 			{
  3133. 				TempSAClass = class<Info>(DynamicLoadObject(TempSA,class'Class'));
  3134. 				if (TempSAClass != None)
  3135. 					Mutators.Add(string(i),ConfigM.ManagedActors[i].SAName);
  3136. 			}
  3137. 		}
  3138. 		lastgroup = "";
  3139. 		Res.Subst("SpanLength", "2");
  3140. 		Res.Subst("SpanContent", "&nbsp;&nbsp;");
  3141. 		Res.Subst("RowContent", WebInclude(CellColSpan));
  3142. 		lastgroup = WebInclude(RowLeft);
  3143. 		ReviewRows += lastgroup;
  3144.  
  3145. 		for (i=0;i<Mutators.Count();i++)
  3146. 		{
  3147. 			TempStr = "";
  3148. 			j = int(Mutators.GetItem(i));
  3149.  
  3150. 			Res.Subst("Content", Checkbox(string(ConfigM.ManagedActors[j].SAClass), CurS.SARequired(string(ConfigM.ManagedActors[j].SAClass))) $ "&nbsp;" $ Mutators.GetTag(i));
  3151. 			TempStr = WebInclude(NowrapLeft);
  3152. 			Res.Subst("Content", ConfigM.ManagedActors[j].SADescription);
  3153. 			Res.Subst("RowContent", TempStr $ WebInclude(CellLeft));
  3154. 			ReviewRows += WebInclude(RowLeft);
  3155. 		}
  3156.  
  3157. 		Res.Subst("SectionName", TableTitle[3]);
  3158. 		Res.Subst("SpecialInstructions", LabelRequiredMaps);
  3159. 		ReviewRows += WebInclude(IncludeSection);
  3160.  
  3161. 		Res.Subst("SettingName", LabelMaxMaps);
  3162. 		Res.Subst("SettingData", Textbox("MaxMaps", 3, 3, CurS.getValue("MaxMaps","3")));
  3163. 		Res.Subst("Extra", lastgroup);
  3164. 		ReviewRows += WebInclude(IncludeRows);
  3165. 		for (i=0;i<CurS.GetMapLength();i++)
  3166. 		{
  3167. 			Res.Subst("SettingName", CurS.getMap(i));
  3168. 			Res.Subst("Extra", "");
  3169. 			Res.Subst("SettingData", Checkbox(CurS.getMap(i), CurS.MapRequired(CurS.getMap(i))));
  3170.  
  3171. 			ReviewRows += WebInclude(IncludeRows);
  3172. 		}
  3173.  
  3174. 		Res.Subst("SectionName", TableTitle[4]);
  3175. 		Res.Subst("SpecialInstructions", LabelPlayInfo);
  3176. 		Res.Subst("Extra", lastgroup);
  3177. 		ReviewRows += WebInclude(IncludeSection);
  3178.  
  3179. 		ReviewRows += (lastgroup $ GeneratePlayInfoRows(Req, Res, IncludeRows));
  3180. 		Res.Subst("TableRows", ReviewRows);
  3181.  
  3182. 	// Set ladder_caption_table subst's
  3183. 		Res.Subst("PageCaption", 	CurS.getValue("PageCaption",PageCaption[5]));
  3184. 		Res.Subst("ButtonName", 	CurS.getValue("ButtonName", ProfileButtonName[5]));
  3185. 		Res.Subst("ButtonValue", 	CurS.getValue("ButtonValue", ProfileButtonValue[5]));
  3186.  
  3187. 		Res.Subst("LadderTable", 	WebInclude(IncludeTable)$WebInclude(IncludeCaptionButton));
  3188. 		Res.Subst("PostAction", 	SubSavedURI$"?SessionID="$SID);
  3189. 		Res.Subst("NewTarget",		" target=\"_parent\"");
  3190. 		ShowPage(Res, SubFrameContent);
  3191. 	}
  3192.  
  3193. 	else AccessDenied(Res);
  3194. }
  3195.  
  3196. // Page 6
  3197. function QuerySubSaved(WebRequest Req, WebResponse Res)
  3198. {
  3199. 	local int i,k, x;
  3200. 	local string 	SID,
  3201. 					tmp, tmp1,
  3202. 					TempStr;
  3203. 	local Session 				CurS;
  3204. 	local PlayInfo 				TempPI;
  3205. 	local ProfileConfigSet 		TempPCS;
  3206. 	local array<string> 		TempArr;
  3207. 	local array<class<Mutator> > M${1}< ${3} >
  3208. 	local array<class<Info> >	SA${1}< ${3} >
  3209.  
  3210. 	local class<Mutator> 		Mut${1}< ${3} >
  3211. 	local class<GameInfo> 		GI${1}< ${3} >
  3212. 	local class<AccessControl> 	AC${1}< ${3} >
  3213. 	local class<Info>			TempSA;
  3214.  
  3215.  
  3216. 	SID = Req.GetVariable("SessionID");
  3217. 	CurS = SMaster.getSession(SID);
  3218. 	if (CanPerform("Lm"))
  3219. 	{
  3220. 		TempStr = CurS.getValue("GameType");
  3221. 		if (TempStr != "")
  3222. 			GIClass = class<GameInfo>(DynamicLoadObject(TempStr,class'Class'));
  3223. 		if (GIClass == None)
  3224. 		{
  3225. 			ShowFramedMessage(Res,ErrorGameClassText,True);
  3226. 			return;
  3227. 		}
  3228.  
  3229. 		TempStr = CurS.getValue("ACClass",Level.Game.AccessControlClass);
  3230. 		if (TempStr != "")
  3231. 			ACClass = class<AccessControl>(DynamicLoadObject(TempStr,class'Class'));
  3232. 		if (ACClass == None)
  3233. 		{
  3234. 			ShowFramedMessage(Res,ErrorAccessControlText,True);
  3235. 			return;
  3236. 		}
  3237. 		TempPI = new(None) class'PlayInfo';
  3238.  
  3239. 		// We are managing an existing profile
  3240. 		if (CurS.hasData("ProfileIndex"))
  3241.         {
  3242.             k = int(CurS.getValue("ProfileIndex"));
  3243.             TempPCS = LadderRules.LadderProfiles[k];
  3244.             if (LadderRules.Profiles[k].ProfileName != CurS.getValue("ProfileName"))
  3245. 			{
  3246. 				LadderRules.Profiles[k].ProfileName = CurS.getValue("ProfileName");
  3247. 				LadderRules.AllLadderProfiles.Remove(LadderRules.AllLadderProfiles.FindItemId(string(k)));
  3248. 				LadderRules.AllLadderProfiles.Add(string(k),LadderRules.Profiles[k].ProfileName);
  3249. 				LadderRules.SaveConfig();
  3250. 			}
  3251.  
  3252. 			if (TempPCS.StartEdit())
  3253. 			{
  3254. 				TempPCS.SetGameType(CurS.getValue("GameType"));
  3255. 				TempPCS.EndEdit(False);
  3256. 			}
  3257.         }
  3258.  
  3259. 		else TempPCS = LadderRules.AddProfile(CurS.getValue("ProfileName"), CurS.getValue("GameType"));
  3260.  
  3261.         if (TempPCS.StartEdit())
  3262. 		{
  3263. 			for (i=0;i<AllMutators.Length;i++)
  3264. 			{
  3265. 				MutClass = class<Mutator>(DynamicLoadObject(AllMutators[i].ClassName,class'Class'));
  3266. 				if (MutClass != None)
  3267. 				{
  3268. 					if ((Req.GetVariable(AllMutators[i].ClassName,"")!="")||(Req.GetVariable(AllMutators[i].GroupName,"")~=AllMutators[i].ClassName))
  3269. 						CurS.setMutator(AllMutators[i].ClassName,true,true);
  3270. 					else CurS.setMutator(AllMutators[i].ClassName,false);
  3271.  
  3272. 					if (CurS.HasMutator(AllMutators[i].ClassName))
  3273. 					{
  3274. 						MClass[MClass.Length] = Mut${1}< ${3} >
  3275. 						TempPCS.AddProfileMutator(AllMutators[i].ClassName,CurS.MutRequired(AllMutators[i].ClassName));
  3276. 					}
  3277. 					else TempPCS.DelProfileMutator(AllMutators[i].ClassName);
  3278. 				}
  3279. 			}
  3280.  
  3281. 			for (i=0;i<ConfigM.ManagedActors.Length;i++)
  3282. 			{
  3283. 				TempSA = ConfigM.ManagedActors[i].SA${1}< ${3} >
  3284. 				if (TempSA != None)
  3285. 				{
  3286. 					TempStr = string(ConfigM.ManagedActors[i].SAClass);
  3287. 					if (Req.GetVariable(TempStr,"") != "")
  3288. 						CurS.setServerActor(TempStr, True, True);
  3289. 					else CurS.setServerActor(TempStr, False);
  3290.  
  3291. 					if (CurS.HasServerActor(TempStr))
  3292. 					{
  3293. 						SAClass[SAClass.Length] = TempSA;
  3294. 						TempPCS.AddProfileServerActor(TempStr,CurS.SARequired(TempStr));
  3295. 					}
  3296. 					else TempPCS.DelProfileServerActor(TempStr);
  3297. 				}
  3298. 			}
  3299.  
  3300. 			x = LoadThisPlayInfo(TempPI, GIClass, ACClass, MClass, SAClass);
  3301. 			if (x >= 0)
  3302. 			{
  3303. 				ShowFramedMessage(Res, ErrorLoadingPlayInfoText[x],True);
  3304. 				return;
  3305. 			}
  3306. 			CurS.setValue("MaxMaps",Req.GetVariable("MaxMaps"),true);
  3307. 			TempPCS.MaxMaps = int(CurS.getValue("MaxMaps"));
  3308.  
  3309. 			GIClass.static.LoadMapList(GIClass.default.MapPrefix, TempArr);
  3310. 			for (i=0;i<TempArr.Length;i++)
  3311. 			{
  3312. 				if (Req.GetVariable(TempArr[i],"")!="")
  3313. 					CurS.setMap(TempArr[i],0,true,true);
  3314. 				else CurS.setMap(TempArr[i],0,false,false);
  3315.  
  3316. 				if (CurS.HasMap(TempArr[i]))
  3317. 					TempPCS.AddProfileMap(TempArr[i], CurS.MapRequired(TempArr[i]));
  3318. 				else TempPCS.DelProfileMap(TempArr[i]);
  3319. 			}
  3320.  
  3321. 			for (i=0;i<TempPI.Settings.Length;i++)
  3322. 			{
  3323. 				if (TempPI.Settings[i].SecLevel > CurAdmin.MaxSecLevel()) continue;
  3324. 				tmp = ""; tmp1="";
  3325. 				if (CurS.getIdValue(i,tmp,tmp1) == -1)
  3326. 					break;
  3327. 				if (!TempPCS.SetProfileNamedParam(TempPI.Settings[i].SettingName, CurS.getValue(TempPI.Settings[i].SettingName,TempPI.Settings[i].Value)))
  3328. 					TempPCS.SetProfileParam(TempPCS.Count(),TempPI.Settings[i].SettingName,CurS.getValue(TempPI.Settings[i].SettingName,TempPI.Settings[i].Value));
  3329. 			}
  3330.  
  3331. 			TempPCS.EndEdit(true);
  3332. 		}
  3333.  
  3334. 		else
  3335. 		{
  3336. 			StatusError(Res,ErrorSavingProfile);
  3337. 			QuerySubReview(Req, Res);
  3338. 			return;
  3339. 		}
  3340. 		Tmp = CurS.getValue("ProfileName", PageCaption[0]);
  3341. 		if (LadderRules.GetRemainingMatches() > 0 && Tmp == LadderRules.Profiles[GetCurrentConfigIndex()].ProfileName)
  3342. 			Tmp = Tmp @ LabelNumberMatchesLeft @ string(LadderRules.GetRemainingMatches());
  3343. 		Res.Subst("SubTitle", Tmp);
  3344. 		ShowMessage(Res, TableTitle[6], PageCaption[6]);
  3345. 		return;
  3346. 	}
  3347.  
  3348. 	else AccessDenied(Res);
  3349. }
  3350.  
  3351. defaultproperties
  3352. {
  3353.      EpicPackages(0)="BR-Anubis"
  3354.      EpicPackages(1)="BR-Bifrost"
  3355.      EpicPackages(2)="BR-Disclosure"
  3356.      EpicPackages(3)="BR-IceFields"
  3357.      EpicPackages(4)="BR-Skyline"
  3358.      EpicPackages(5)="BR-Slaughterhouse"
  3359.      EpicPackages(6)="BR-TwinTombs"
  3360.      EpicPackages(7)="CTF-Chrome"
  3361.      EpicPackages(8)="CTF-Citadel"
  3362.      EpicPackages(9)="CTF-December"
  3363.      EpicPackages(10)="CTF-Face3"
  3364.      EpicPackages(11)="CTF-Geothermal"
  3365.      EpicPackages(12)="CTF-Lostfaith"
  3366.      EpicPackages(13)="CTF-Magma"
  3367.      EpicPackages(14)="CTF-Maul"
  3368.      EpicPackages(15)="CTF-Orbital2"
  3369.      EpicPackages(16)="DM-Antalus"
  3370.      EpicPackages(17)="DM-Asbestos"
  3371.      EpicPackages(18)="DM-Compressed"
  3372.      EpicPackages(19)="DM-Curse3"
  3373.      EpicPackages(20)="DM-Flux2"
  3374.      EpicPackages(21)="DM-Gael"
  3375.      EpicPackages(22)="DM-Inferno"
  3376.      EpicPackages(23)="DM-Insidious"
  3377.      EpicPackages(24)="DM-Leviathan"
  3378.      EpicPackages(25)="DM-Oceanic"
  3379.      EpicPackages(26)="DM-Phobos2"
  3380.      EpicPackages(27)="DM-Plunge"
  3381.      EpicPackages(28)="DM-Serpentine"
  3382.      EpicPackages(29)="DM-TokaraForest"
  3383.      EpicPackages(30)="DM-TrainingDay"
  3384.      EpicPackages(31)="DOM-Core"
  3385.      EpicPackages(32)="DOM-OutRigger"
  3386.      EpicPackages(33)="DOM-Ruination"
  3387.      EpicPackages(34)="DOM-ScorchedEarth"
  3388.      EpicPackages(35)="DOM-SepukkuGorge"
  3389.      EpicPackages(36)="DOM-Suntemple"
  3390.      EpicPackages(37)="Entry"
  3391.      EpicPackages(38)="NvidiaLogo"
  3392.      EpicPackages(39)="TUT-BR"
  3393.      EpicPackages(40)="TUT-CTF"
  3394.      EpicPackages(41)="TUT-DM"
  3395.      EpicPackages(42)="TUT-DOM"
  3396.      EpicPackages(43)="UT2-intro"
  3397.      EpicPackages(44)="VehicleDemo"
  3398.      EpicPackages(45)="endgame"
  3399.      EpicPackages(46)="Core"
  3400.      EpicPackages(47)="Editor"
  3401.      EpicPackages(48)="Engine"
  3402.      EpicPackages(49)="Fire"
  3403.      EpicPackages(50)="GamePlay"
  3404.      EpicPackages(51)="IpDrv"
  3405.      EpicPackages(52)="UWeb"
  3406.      EpicPackages(53)="UnrealEd"
  3407.      EpicPackages(54)="UnrealGame"
  3408.      EpicPackages(55)="Vehicles"
  3409.      EpicPackages(56)="XAdmin"
  3410.      EpicPackages(57)="XEffects"
  3411.      EpicPackages(58)="XGame"
  3412.      EpicPackages(59)="XGame_rc"
  3413.      EpicPackages(60)="XInterface"
  3414.      EpicPackages(61)="XPickups"
  3415.      EpicPackages(62)="XPickups_rc"
  3416.      EpicPackages(63)="XWeapons"
  3417.      EpicPackages(64)="XWeapons_rc"
  3418.      EpicPackages(65)="XWebAdmin"
  3419.      EpicPackages(66)="BR-DE-ElecFields"
  3420.      EpicPackages(67)="CTF-DE-ElecFields"
  3421.      EpicPackages(68)="CTF-DE-LavaGiant2"
  3422.      EpicPackages(69)="DM-DE-Grendelkeep"
  3423.      EpicPackages(70)="DM-DE-Ironic"
  3424.      EpicPackages(71)="DM-DE-Osiris2"
  3425.      EpicPackages(72)="BR-Canyon"
  3426.      EpicPackages(73)="CTF-Avaris"
  3427.      EpicPackages(74)="DM-1on1-Crash"
  3428.      EpicPackages(75)="DM-1on1-Mixer"
  3429.      EpicPackages(76)="DM-Icetomb"
  3430.      EpicPackages(77)="DM-Injector"
  3431.      EpicPackages(78)="DM-IronDeity"
  3432.      EpicPackages(79)="DM-Rustatorium"
  3433.      EpicPackages(80)="DOM-Junkyard"
  3434.      EpicPackages(81)="SkaarjPack"
  3435.      EpicPackages(82)="SkaarjPack_rc"
  3436.      EpicPackages(83)="BonusPack"
  3437.      EpicPackages(84)="OGGPlayer"
  3438.      MasterPage="ladder"
  3439.      SubFrame="ladder_frame"
  3440.      SubFrameMenu="ladder_frame1"
  3441.      SubFrameContent="ladder_frame2"
  3442.      IncludeTable="ladder_table"
  3443.      IncludeSection="ladder_section"
  3444.      IncludeRows="ladder_rows"
  3445.      IncludeCaptionButton="ladder_caption"
  3446.      IncludeMapSelect="ladder_mapselect"
  3447.      IncludeProfileName="ladder_name"
  3448.      IncludeGameType="ladder_gametype"
  3449.      IncludeCheckBox="ladder_checkrow"
  3450.      IncludeSwitch="ladder_switch"
  3451.      ProfileViewURI="ladder_view"
  3452.      ProfileEditURI="ladder_edit"
  3453.      ProfileMenuURI="ladder_menu"
  3454.      ProfileSwitchURI="ladder_switch"
  3455.      ProfileManageURI="ladder_manage"
  3456.      SubFrameURI="profile_management"
  3457.      SubFrameMenuURI="management_menu"
  3458.      SubMapsURI="ladder_maps"
  3459.      SubSavedURI="ladder_save"
  3460.      SubRulesURI="ladder_rules"
  3461.      SubReviewURI="ladder_review"
  3462.      SubGametypeURI="management_game_type"
  3463.      SubMutatorsURI="ladder_mutators"
  3464.      SubImportURI="profile_import"
  3465.      SubExportURI="profile_export"
  3466.      LinkEditProfile="Edit Profiles"
  3467.      LinkViewProfile="View Profiles"
  3468.      LinkSwitchProfile="Switch Profiles"
  3469.      LinkManageProfile="Manage Profiles"
  3470.      LinkImportProfile="Import Profile"
  3471.      LinkExportProfile="Export Profile"
  3472.      TableTitle(0)="Profile Management Portal"
  3473.      TableTitle(1)="Profile GameType"
  3474.      TableTitle(2)="Profile Mutators"
  3475.      TableTitle(3)="Profile Maps"
  3476.      TableTitle(4)="Profile Settings"
  3477.      TableTitle(5)="Review Profile"
  3478.      TableTitle(6)="Profile Saved"
  3479.      PageCaption(0)="No Profile Loaded"
  3480.      PageCaption(1)="Select the gametype that will be associated with this profile."
  3481.      PageCaption(2)="Select the mutators that will be available in this profile."
  3482.      PageCaption(3)="Select the maps that will be available in this profile."
  3483.      PageCaption(4)="Select the settings that will be associated with this profile."
  3484.      PageCaption(5)="Review all settings for accuracy before saving to file."
  3485.      PageCaption(6)="Settings were saved successfully!"
  3486.      ProfileButtonName(0)="Save Location"
  3487.      ProfileButtonName(1)="GameType"
  3488.      ProfileButtonName(2)="Mutators"
  3489.      ProfileButtonName(3)="Maps"
  3490.      ProfileButtonName(4)="Rules"
  3491.      ProfileButtonName(5)="Review"
  3492.      ProfileButtonName(6)="Saved"
  3493.      ProfileButtonValue(0)="Proceed"
  3494.      ProfileButtonValue(1)="Set GameType"
  3495.      ProfileButtonValue(2)="Set Mutators"
  3496.      ProfileButtonValue(3)="Set Maps"
  3497.      ProfileButtonValue(4)="Set Rules"
  3498.      ProfileButtonValue(5)="Save Profile"
  3499.      ProfileButtonValue(6)="Profile Saved"
  3500.      MapText="Maps"
  3501.      ErrorText="Error"
  3502.      MutatorText="Mutators"
  3503.      RequiredText="Required"
  3504.      AvailableText="Available"
  3505.      UnlimitedText="Unlimited"
  3506.      FollowingMaps="The following maps"
  3507.      AreAssignedText="are assigned to this profile and cannot be removed."
  3508.      AreAvailableText="may be added to this profile."
  3509.      FollowingMutators="The following mutators"
  3510.      CommandLineOptionsTitle="Command Line Options"
  3511.      ButtonLoadProfile="Load Profile"
  3512.      ButtonDeleteProfile="Delete Profile"
  3513.      ButtonPreviewProfile="Load Profile"
  3514.      ButtonApplyImportProfile="Import Profile"
  3515.      ButtonApplyExportProfile="Export Profile"
  3516.      ButtonApplyProfileChanges="Apply Profile Changes"
  3517.      LabelCopyProfile="Copy Profile"
  3518.      LabelDeleteProfile="Delete Profile"
  3519.      LabelImportProfile="Import Profile"
  3520.      LabelExportProfile="Export Profile"
  3521.      LabelAddProfile="Add Profile"
  3522.      LabelSelectActions="(Copy, Modify, Delete, Export)"
  3523.      LabelTextboxActions="(Add, Copy, Import)"
  3524.      LabelPlayInfo="Profile Game Parameters"
  3525.      LabelGeneralProfile="General Profile Information"
  3526.      LabelGameType="Profile Game Type"
  3527.      LabelProfileName="Profile Name"
  3528.      LabelAccessControl="Profile Access Control"
  3529.      LabelChooseAction="Choose action to perform:"
  3530.      LabelManagement="Profile Management"
  3531.      LabelInputDescription="Actions which require input from this field are listed on the right."
  3532.      LabelMaxMaps="Maximum maps allowed in this profile's maplist"
  3533.      LabelNumberGames="Number of matches (0 = unlimited)"
  3534.      LabelCheckAllMap="Select all maps"
  3535.      LabelRequiredMaps="Check each map that will be required (non-removable) for this profile."
  3536.      LabelUncheckAllMap="Deselect all maps"
  3537.      LabelChangeMaplist="Changes to the maplist are saved immediately."
  3538.      LabelCheckAllMutator="Select all mutators"
  3539.      LabelRequiredMutators="Check each mutator that will be required (non-removable) for this profile."
  3540.      LabelNumberMatchesLeft="Matches Remaining:"
  3541.      LabelUncheckAllMutator="Deselect all mutators"
  3542.      LabelDelayProfileChange="Check to delay applying profile until end of current match."
  3543.      LabelApplyImportProfile="Click Apply Import to make this profile available in your server's list of profiles."
  3544.      LabelApplyExportProfile="Click Apply Export to save this profile to a .txt file."
  3545.      LabelModifyProfile="Modify Profile"
  3546.      SuccessText="Success"
  3547.      SuccessDeleteProfile="Profile successfully deleted!  It will no longer appear in your list of available profiles."
  3548.      SuccessExportProfile="Profile exported successfully!  Exported profile has been saved to the server's System folder as "
  3549.      SuccessImportProfile="Profile imported successfully! The remote profile will now appear in your list of available profiles."
  3550.      SuccessImportProfileTitle="Import Successful!"
  3551.      SuccessCopyProfile="Profile copied successfully! Copied profile will now be available in your list of available profiles."
  3552.      SuccessSwitchProfile="Profile successfully applied! Changes take effect at the end of the current match."
  3553.      ErrorLoadingPlayInfoText(0)="Error while loading playinfo.  LoadThisPlayInfo() received bad playinfo object!"
  3554.      ErrorLoadingPlayInfoText(1)="Error while loading playinfo.  LoadThisPlayInfo() could not load incoming game class!"
  3555.      ErrorLoadingPlayInfoText(2)="Error while loading playinfo.  LoadThisPlayInfo() could not load associated access control!"
  3556.      ErrorLoadingPlayInfoText(3)="Error while loading playinfo.  LoadThisPlayInfo() had exception while loading mutators!"
  3557.      ErrorLoadingPlayInfoText(4)="Error while loading playinfo.  LoadThisPlayInfo() had exception while loading server actors!"
  3558.      ErrorGameClassText="No gametype was selected, or the files required by this gametype do not exist on this server."
  3559.      ErrorGameClassTitle="Invalid GameType"
  3560.      ErrorAccessControlText="Exception while loading access control.  Please double check the AccessControlClass= line of the [Engine.GameInfo] section of your server's .ini file."
  3561.      ErrorAccessControlTitle="Invalid Access Control"
  3562.      ErrorSameProfileName="Another profile already exists with that name. Please select a different name!"
  3563.      ErrorRemoteMutator="Error loading mutator from remote profile. Could not find mutator package:"
  3564.      ErrorRemoteServerActor="Error loading ServerActor from remote profile.  Could not find ServerActor package:"
  3565.      ErrorSavingProfile="Exception while saving new profile! Please resubmit save request."
  3566.      ErrorDeletingProfile="Error deleting profile!  Please check server log for details."
  3567.      ErrorExportingProfile="Error exporting profile! Export class could not be spawned!"
  3568.      ErrorNoProfilesExist="No profiles exist! Could not perform selected action!"
  3569.      ErrorCopyFrom="Error copying profile.  No Profile Found!"
  3570.      ErrorCopyNoName="You must specify a unique name for the new profile!"
  3571.      ErrorExcludeMapNotFound="Error! Exclude map not found:"
  3572.      ErrorIncludeMapNotFound="Error! Include map not found:"
  3573.      ErrorReplacingWebConnection="Exception replacing WebServer.AcceptClass! (Very bad) Please send an email to Evolution containing your server's ini and log files."
  3574.      ImportClassSpawnError="Exception occured spawning connection class.  Please try again!"
  3575.      ImportProfileFailText="Error while importing profile.  Please ensure you have all the files necessary to load this remote profile."
  3576.      ImportProfileFailTitle="Import Failed!"
  3577.      ErrorBind="Failed to bind port! Please try again!"
  3578.      ErrorBadURL="URL must start with 'http://' !"
  3579.      ErrorServer="Unspecified error while importing profile!"
  3580.      ErrorResolve="URL could not be resolved!"
  3581.      ErrorProfile="Attempted to import a file that does not contain a profile!"
  3582.      ErrorTimeout="Timed out while waiting for response from foreign host!"
  3583.      ErrorNotFound="Profile does not exist on remote server!"
  3584.      ErrorForbidden="Remote profile could not be imported: Forbidden"
  3585.      ErrorBadRequest="Request could not be processed by remote server!"
  3586.      ErrorUnauthorized="Remote profile could not be imported: Unauthorized"
  3587.      DefaultPage="ladder_main"
  3588.      Title="Ladder"
  3589. }