Legacy:LadderQuery
From Unreal Wiki, The Unreal Engine Documentation Site
//-----------------------------------------------------------
// Ladder.LadderQuery
// QueryHandler for webadmin interface
//-----------------------------------------------------------
class LadderQuery extends xWebQueryHandler
DependsOn(ProfileConfigSet)
config(System);
const LOGNAME = 'LadderQuery';
const EPICNUMBER = 85;
var LadderGameRules LadderRules;
// Profile Tracking Variables
var SessionMaster SMaster;
var ConfigMaster ConfigM;
var string EpicPackages[EPICNUMBER];
// Active Profile Variables
var StringArray ProfileMaps;
var ProfileExporter ExportMaster;
var ProfileConfigSet CurrentProfile;
var StringArray ProfileMutators;
var string DefaultProfileName;
// Physical page that will be served
var config string MasterPage; // This is main html page for Ladder
var config string SubFrame; // Manage sub-frame
var config string SubFrameMenu; // Sub-menu (GameType, Mutators, Maps, PlayInfo, Review)
var config string SubFrameContent;
// Include Files
var config string IncludeTable;
var config string IncludeSection;
var config string IncludeRows;
var config string IncludeCaptionButton;
var config string IncludeMapSelect;
var config string IncludeProfileName;
var config string IncludeGameType;
var config string IncludeCheckBox;
var config string IncludeSwitch;
// Virtual paths that will be requested from clients
var config string ProfileViewURI;
var config string ProfileEditURI;
var config string ProfileMenuURI;
var config string ProfileSwitchURI;
var config string ProfileManageURI;
var config string SubFrameURI; // accessed through manage link - linked to SubFrame page
var config string SubFrameMenuURI;
var config string SubMapsURI;
var config string SubSavedURI;
var config string SubRulesURI;
var config string SubReviewURI;
var config string SubGametypeURI;
var config string SubMutatorsURI;
var config string SubImportURI;
var config string SubExportURI;
// Localized Page Help texts
var localized string HelpViewProfile;
var localized string HelpEditProfile;
var localized string HelpSwitchProfile;
var localized string HelpManageProfile;
var localized string HelpImportProfile;
var localized string HelpExportProfile;
// Subpage help text
var localized string HelpGameType;
var localized string HelpMutators;
var localized string HelpMaps;
var localized string HelpPlayInfo;
var localized string HelpReview;
// Localized Menu Link Text
var localized string LinkEditProfile;
var localized string LinkViewProfile;
var localized string LinkSwitchProfile;
var localized string LinkManageProfile;
var localized string LinkImportProfile;
var localized string LinkExportProfile;
// for AddProfilePage/ManageProfilePage
var localized string TableTitle[9];
var localized string PageCaption[9];
var localized string ProfileButtonName[9];
var localized string ProfileButtonValue[9];
// Section Headers & Text
var localized string MapText;
var localized string ErrorText;
var localized string MutatorText;
var localized string RequiredText;
var localized string AvailableText;
var localized string UnlimitedText;
var localized string FollowingMaps;
var localized string AreAssignedText;
var localized string AreAvailableText;
var localized string FollowingMutators;
var localized string CommandLineOptionsTitle;
// Button Values
var localized string ButtonLoadProfile; // Label for "switch immediately" button
var localized string ButtonDeleteProfile;
var localized string ButtonPreviewProfile; // Label for previewing remote profile button
var localized string ButtonApplyImportProfile;
var localized string ButtonApplyExportProfile;
var localized string ButtonApplyProfileChanges;
// Input form labels
var localized string LabelCopyProfile;
var localized string LabelDeleteProfile;
var localized string LabelImportProfile;
var localized string LabelExportProfile;
var localized string LabelAddProfile;
var localized string LabelSelectActions;
var localized string LabelTextboxActions;
var localized string LabelPlayInfo;
var localized string LabelGeneralProfile;
var localized string LabelGameType;
var localized string LabelProfileName;
var localized string LabelAccessControl;
var localized string LabelChooseAction;
var localized string LabelManagement;
var localized string LabelInputDescription;
var localized string LabelMaxMaps;
var localized string LabelNumberGames;
var localized string LabelCheckAllMap;
var localized string LabelRequiredMaps;
var localized string LabelUncheckAllMap;
var localized string LabelChangeMaplist;
var localized string LabelCheckAllMutator;
var localized string LabelRequiredMutators;
var localized string LabelNumberMatchesLeft;
var localized string LabelUncheckAllMutator;
var localized string LabelDelayProfileChange;
var localized string LabelApplyImportProfile;
var localized string LabelApplyExportProfile;
var localized string LabelModifyProfile;
// Success Messages
var localized string SuccessText;
var localized string SuccessDeleteProfile;
var localized string SuccessExportProfile;
var localized string SuccessImportProfile;
var localized string SuccessImportProfileTitle;
var localized string SuccessCopyProfile;
var localized string SuccessSwitchProfile;
// Profile Errors
var localized string ErrorLoadingPlayInfoText[5];
var localized string ErrorGameRulesNotFound;
var localized string ErrorGameClassText;
var localized string ErrorGameClassTitle;
var localized string ErrorAccessControlText;
var localized string ErrorAccessControlTitle;
var localized string ErrorSameProfileName;
var localized string ErrorRemoteMutator;
var localized string ErrorRemoteServerActor;
var localized string ErrorSavingProfile;
var localized string ErrorDeletingProfile;
var localized string ErrorExportingProfile;
var localized string ErrorNoProfilesExist;
var localized string ErrorCopyFrom;
var localized string ErrorCopyNoName;
var localized string ErrorExcludeMapNotFound;
var localized string ErrorIncludeMapNotFound;
var localized string ErrorReplacingWebConnection;
var localized string ImportClassSpawnError;
var localized string ImportProfileFailText;
var localized string ImportProfileFailTitle;
// Import errors
var localized string ErrorBind;
var localized string ErrorBadURL;
var localized string ErrorServer;
var localized string ErrorResolve;
var localized string ErrorProfile;
var localized string ErrorTimeout;
var localized string ErrorNotFound;
var localized string ErrorForbidden;
var localized string ErrorBadRequest;
var localized string ErrorUnauthorized;
function bool Init()
{
local GameRules GR;
for (GR=Level.Game.GameRulesModifiers;GR!=None;GR=GR.NextGameRules)
if (LadderGameRules(GR) != None)
LadderRules = LadderGameRules(GR);
if (LadderRules == None)
{
Cleanup();
return false;
}
if (ConfigM == None && ConfigMaster(Level.Game.BaseMutator.NextMutator) != None)
ConfigM = ConfigMaster(Level.Game.BaseMutator.NextMutator);
GetCurrentConfigSet();
ExportMaster = new class'ProfileExporter';
DefaultProfileName = LadderRules.DefaultProfileName;
SMaster = new(None) class'SessionMaster';
ProfileMaps = new(None) class'SortedStringArray';
ProfileMutators = new(None) class'SortedStringArray';
Assert(Level.Game.AccessControl != None);
return true;
}
//////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////
// Session Manipulation Functions
//
// Load profile information into session object
function CreateSessionInfo(coerce int ProfileIndex, string SID, optional bool bIncludeNonActive, optional bool bSave, optional bool bQuiet)
{
local int i;
local Session CurS;
local string TempStr;
local array<string> TempArr;
local ProfileConfigSet TempPCS;
local array<ProfileConfigSet.ProfileMutator> AllPCSMutators;
local array<ProfileConfigSet.ProfileMap> AllPCSMaps;
local array<ProfileConfigSet.ProfileSA> AllPCSServerActors;
if (SID == "")
return;
CurS = SMaster.getSession(SID,true);
TempPCS = LadderRules.LadderProfiles[ProfileIndex];
TempPCS.StartEdit();
// General profile information
CurS.setValue("ProfileIndex", string(ProfileIndex), true);
CurS.setValue("ProfileName",LadderRules.Profiles[ProfileIndex].ProfileName,true);
CurS.setValue("GameType", string(TempPCS.GetGameClass()), True);
CurS.setValue("ACClass", TempPCS.GetAccessControl(), True);
CurS.setValue("MaxMaps", string(TempPCS.GetMaxMaps()), True);
AllPCSMutators = TempPCS.GetProfileMutators();
AllPCSMaps = TempPCS.GetProfileMaps();
AllPCSServerActors = TempPCS.GetProfileServerActors();
TempArr = LadderRules.GetProfileMutators(string(ProfileIndex));
TempStr = class'wUtils103.wArray'.static.Join(TempArr,",");
// Load profile mutator information
CurS.ClearMutators();
for (i=0;i<AllPCSMutators.Length;i++)
if (AllPCSMutators[i].bRequired || (InStr(TempStr,AllPCSMutators[i].MutatorName)!=-1) || bIncludeNonActive)
CurS.setMutator(AllPCSMutators[i].MutatorName,True,AllPCSMutators[i].bRequired);
TempArr = LadderRules.GetProfileMaps(string(ProfileIndex));
TempStr = class'wUtils103.wArray'.static.Join(TempArr,",");
// Load profile map information
CurS.ClearMaps();
for (i=0;i<AllPCSMaps.Length;i++)
if (AllPCSMaps[i].bRequired || (InStr(TempStr,AllPCSMaps[i].MapName)!=-1) || bIncludeNonActive)
CurS.setMap(AllPCSMaps[i].MapName,AllPCSMaps[i].MapListOrder,True,AllPCSMaps[i].bRequired);
TempArr = LadderRules.GetProfileServerActors(string(ProfileIndex));
TempStr = class'wUtils103.wArray'.static.Join(TempArr,",");
// Load ServerActor info
CurS.ClearServerActors();
for (i=0;i<AllPCSServerActors.Length;i++)
if (AllPCSServerActors[i].bRequired || InStr(TempStr,AllPCSServerActors[i].ActorClass)!=-1 || bIncludeNonActive)
CurS.setServerActor(AllPCSServerActors[i].ActorClass, True, AllPCSServerActors[i].bRequired);
// Load profile PlayInfo data
for (i=0;i<TempPCS.Count();i++)
CurS.setValue(TempPCS.GetProfileParamName(i),TempPCS.GetProfileParam(i),True);
TempPCS.EndEdit(bSave,bQuiet);
}
// Initialize session data for recently imported profile
function ProfileConfigSet CreateImportSessionInfo(Session CurS)
{
local int i;
local string TempStr, Tmp;
local PlayInfo TempPI;
local ProfileConfigSet TempPCS;
local class<Mutator> MutClass;
local class<GameInfo> GIClass;
local class<AccessControl> ACClass;
local class<Info> ServerActorClass;
local array<class<Info> > SAClass;
local array<class<Mutator> > MClass;
TempPCS = LadderRules.AddProfile(CurS.getValue("ProfileName"),CurS.getValue("GameType"));
if (TempPCS.StartEdit())
{
TempStr = CurS.getValue("GameType");
if (TempStr != "")
GIClass = class<GameInfo>(DynamicLoadObject(TempStr,class'Class'));
if (GIClass == None) return None;
TempStr = CurS.getValue("ACClass",Level.Game.AccessControlClass);
if (TempStr != "")
ACClass = class<AccessControl>(DynamicLoadObject(TempStr,class'Class'));
if (ACClass == None) return None;
TempPI = new(None) class'PlayInfo';
// Mutators
for (i=0;i<CurS.getMutatorLength();i++)
{
TempStr = CurS.getMutator(i);
MutClass = class<Mutator>(DynamicLoadObject(TempStr, class'Class'));
if (MutClass != None)
{
MClass[MClass.Length] = MutClass;
TempPCS.AddProfileMutator(TempStr,CurS.MutRequired(TempStr));
}
else log(ErrorRemoteMutator@TempStr,LOGNAME);
}
for (i=0;i<CurS.getSALength();i++)
{
TempStr = CurS.getServerActor(i);
ServerActorClass = class<Info>(DynamicLoadObject(TempStr,class'Class'));
if (ServerActorClass != None)
{
SAClass[SAClass.Length] = ServerActorClass;
TempPCS.AddProfileServerActor(TempStr,CurS.SARequired(TempStr));
}
else log(ErrorRemoteServerActor@TempStr,LOGNAME);
}
LoadThisPlayInfo(TempPI, GIClass, ACClass, MClass, SAClass);
// Maps
for (i=0;i<CurS.getMapLength();i++)
{
TempStr = CurS.getMap(i);
TempPCS.AddProfileMap(TempStr,CurS.MapRequired(TempStr));
}
// PlayInfo
for (i=0;i<TempPI.Settings.Length;i++)
{
TempStr = ""; Tmp="";
if (CurS.getIdValue(i,TempStr,Tmp) == -1)
break;
if ( !SettingIsAllowed(TempPI.Settings[i].SecLevel) ) continue;
if (!TempPCS.SetProfileNamedParam(TempPI.Settings[i].SettingName, CurS.getValue(TempPI.Settings[i].SettingName,TempPI.Settings[i].Value)))
TempPCS.SetProfileParam(TempPCS.Count(),TempPI.Settings[i].SettingName,CurS.getValue(TempPI.Settings[i].SettingName,TempPI.Settings[i].Value));
}
TempPCS.EndEdit(True);
return TempPCS;
}
else log(ErrorServer,LOGNAME);
return None;
}
// Clear session data and optionally create new session object
function string ResetSessionID(Session CurS, optional bool bDestroySession)
{
local string OldSID;
if (bDestroySession) SMaster.destroySession(CurS);
else CurS.ResetSession();
CurS = SMaster.getSession(OldSID,true);
return CurS.GetHash();
}
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
// Profile manipulation methods
//
function int LoadThisPlayInfo(PlayInfo PI, class<GameInfo> ThisGameInfo, class<AccessControl> ThisAccessControl, array<class<Mutator> > ThisMutator, array<class<Info> > ThisServerActor)
{
local int i;
local class<Mutator> M;
if (PI == None)
return 0;
PI.Clear();
if (ThisGameInfo == None)
return 1;
if (ThisAccessControl == None)
return 2;
if (ThisMutator.Length > 0)
for (i=0;i<ThisMutator.Length;i++)
if (ThisMutator[i] == None)
return 3;
if (ThisServerActor.Length > 0)
for (i=0;i<ThisServerActor.Length;i++)
if (ThisServerActor[i] == None)
return 4;
ThisGameInfo.static.FillPlayInfo(PI);
PI.PopClass();
if (ThisGameInfo.default.MutatorClass != "")
{
M = class<Mutator>(DynamicLoadObject(ThisGameInfo.default.MutatorClass,class'Class'));
if (M != None)
M.static.FillPlayInfo(PI);
}
ThisAccessControl.static.FillPlayInfo(PI);
PI.PopClass();
for (i = 0; i < ThisMutator.Length; i++)
{
ThisMutator[i].static.FillPlayInfo(PI);
PI.PopClass();
}
for (i = 0; i < ThisServerActor.Length; i++)
{
ThisServerActor[i].static.FillPlayInfo(PI);
PI.PopClass();
}
class'CommandLineParams'.static.FillPlayInfo(PI);
PI.PopClass();
return -1;
}
function ProfileConfigSet GetCurrentConfigSet()
{
local int i;
if (CurrentProfile == None)
{
i = LadderRules.FindActiveProfile();
if (i >= 0) CurrentProfile = LadderRules.LadderProfiles[i];
}
return CurrentProfile;
}
function int GetCurrentConfigIndex()
{
local int i;
if (CurrentProfile != None)
for (i = 0;i < LadderRules.LadderProfiles.Length;i++)
if (LadderRules.LadderProfiles[i] == CurrentProfile)
return i;
return LadderRules.FindActiveProfile();
}
// Returns an array of class names for mutators that this profile will use in the game
function array<string> LoadActiveProfileMutators(optional string CurrentProfileItem)
{
return LadderRules.GetProfileMutators(CurrentProfileItem);
}
function array<string> LoadActiveProfileServerActors(optional string CurrentProfileItem)
{
return LadderRules.GetProfileServerActors(CurrentProfileItem);
}
// Returns an array of map names that in the maplist for this profile
function array<string> LoadActiveProfileMaps(optional string CurrentProfileItem)
{
return LadderRules.GetProfileServerActors(CurrentProfileItem);
}
/*
function CreateFullMutatorList(out StringArray Mutators, out StringArray GroupsOnly)
{
local StringArray Grouped;
local int i,j,z;
local string GrpName;
local string thisgroup, nextgroup;
// This class provides a specialized sorting function
// since mutators may be grouped - mutators in the same groups
// are not allowed to be selected togther
Grouped = new(None) class'SortedStringArray';
// Create array sorted on GroupName...this allows to flag
// the mutator for a different .inc file
for (i = 0; i < Mutators.Count(); i++)
{
j = int(Mutators.GetItem(i));
// If the mutator author forgot to configure a group name for the mutator
if (AllMutators[j].GroupName == "")
GrpName = "Z" $ string (z++);
else GrpName = AllMutators[j].GroupName;
Grouped.Add(string(j),GrpName $ "." $ AllMutators[j].FriendlyName);
}
// Move all grouped mutators to GroupsOnly StringArray for sorting by friendly name
for (i=0;i<Grouped.Count();i++)
{
thisgroup = AllMutators[int(Grouped.GetItem(i))].GroupName;
nextgroup = "";
if (thisgroup=="")
continue;
if (i+1<Grouped.Count())
nextgroup = AllMutators[int(Grouped.GetItem(i+1))].GroupName;
if (thisgroup ~= nextgroup)
{
j=i;
while(nextgroup~=thisgroup && j<Grouped.Count())
{
GroupsOnly.MoveFromId(Grouped, Grouped.FindItemId(Grouped.GetItem(j)));
thisgroup = nextgroup;
if (j+1==Grouped.Count())
nextgroup="";
else nextgroup = AllMutators[int(Grouped.GetItem(j+1))].GroupName;
}
if (j<Grouped.Count())
GroupsOnly.MoveFromId(Grouped,Grouped.FindItemId(Grouped.GetItem(j)));
i=-1;
}
}
// Move all non-grouped mutators back to Mutators array
// for re-sorting by Friendly Name
Mutators.Reset();
for (i=0;i<Grouped.Count();i++)
{
j=int(Grouped.GetItem(i));
Mutators.Add(string(j),AllMutators[j].FriendlyName);
}
Grouped.Reset();
}
*/
//****************************************************************
//****************************************************************
// Helper functions
//
//****************************************************************
//**************************
// HTML Generation
//*************************
// Creates a listing of PlayInfo data
// Pass "defaults_row" in the 'IncludeFile' param to add the
// input form objects to the output
function string GeneratePlayInfoRows(WebRequest Req, WebResponse Res, string IncludeFile)
{
local int i,j,k,z;
local string TempStr, Data, Op, SID,
TempRow, HeadingRow, PlayInfoRows;
local Session CurS;
local PlayInfo TempPI;
local StringArray Info, InfoC, InfoS, InfoT;
local array<string> Options;
local class<Mutator> TempMut;
local class<Info> TempSA;
local class<GameInfo> GIClass;
local class<AccessControl> ACClass;
local array<class<Mutator> > MClass;
local array<class<Info> > SAClass;
SID = Req.GetVariable("SessionID");
CurS = SMaster.GetSession(SID);
TempStr = CurS.getValue("GameType");
if (TempStr != "")
GIClass = class<GameInfo>(DynamicLoadObject(TempStr,class'Class'));
if (GIClass == None)
{
ShowMessage(Res,ErrorGameClassTitle,ErrorGameClassText);
return "";
}
TempStr = CurS.getValue("ACClass",Level.Game.AccessControlClass);
if (TempStr != "")
ACClass = class<AccessControl>(DynamicLoadObject(TempStr,class'Class'));
if (ACClass == None)
{
ShowMessage(Res,ErrorAccessControlTitle,ErrorAccessControlText);
return "";
}
for (i=0;i<CurS.GetMutatorLength();i++)
{
TempStr = CurS.getMutator(i);
if (TempStr != "")
{
TempMut = class<Mutator>(DynamicLoadObject(TempStr,class'Class'));
if (TempMut != None)
MClass[MClass.Length] = TempMut;
}
}
for (i=0;i<CurS.getSALength();i++)
{
TempStr = CurS.getServerActor(i);
if (TempStr != "")
{
TempSA = class<Info>(DynamicLoadObject(TempStr,class'Class'));
if (TempSA != None)
SAClass[SAClass.Length] = TempSA;
}
}
// Initialize and fill PlayInfo
TempPI = new(None) class'PlayInfo';
LoadThisPlayInfo(TempPI, GIClass, ACClass, MClass, SAClass);
for (i=0;i<TempPI.Settings.Length;i++)
if (CurS.HasData(TempPI.Settings[i].SettingName))
TempPI.StoreSetting(i, CurS.getValue(TempPI.Settings[i].SettingName,TempPI.Settings[i].Value));
InfoC = new(None) class'SortedStringArray'; // Checkboxes
InfoS = new(None) class'SortedStringArray'; // Selects
InfoT = new(None) class'SortedStringArray'; // Textboxes
Info = new(None) class'SortedStringArray'; // Contains each unique ClassFrom value
// Want to allow admin to input values for each setting
if (IncludeFile ~= "defaults_row")
{
for (i=0;i<TempPI.Settings.Length;i++)
{
if (TempPI.Settings[i].RenderType~="Text")
{
// Hack for MOTD sorting
if (Left(TempPI.Settings[i].SettingName,Len(TempPI.Settings[i].SettingName) - 1) ~= "GameReplicationInfo.MOTDLine")
InfoT.Add(string(i), TempPI.Settings[i].SettingName);
else InfoT.Add(string(i),TempPI.Settings[i].DisplayName);
}
else if (TempPI.Settings[i].RenderType~="Check")
InfoC.Add(string(i),TempPI.Settings[i].DisplayName);
else if (TempPI.Settings[i].RenderType~="Select")
InfoS.Add(string(i),TempPI.Settings[i].DisplayName);
for (j=0;j<Info.Count();j++)
if (Info.GetTag(j) ~= string(TempPI.Settings[i].ClassFrom))
break;
if (j == Info.Count())
Info.Add(string(i), string(TempPI.Settings[i].ClassFrom));
}
for (k=0;k<Info.Count();k++)
{
TempRow = ""; HeadingRow = "";
Res.Subst("RowContent", "<td class=ttext colspan=\"3\">"$Info.GetTag(k)$"</td>");
HeadingRow = WebInclude(RowLeft);
for (i=0;i<InfoC.Count();i++)
{
TempStr = "";
j=int(InfoC.GetItem(i));
if (!SettingIsAllowed(TempPI.Settings[j].SecLevel) || (string(TempPI.Settings[j].ClassFrom)!=Info.GetTag(k)))
continue;
Res.Subst("Content", Checkbox(TempPI.Settings[j].SettingName, TempPI.Settings[j].Value ~= "True", TempPI.Settings[j].Data != ""));
TempStr = WebInclude(CellLeft);
Res.Subst("Content", "<span class=location title=\"Required Security Level\">"$TempPI.Settings[j].SecLevel$"</span>");
TempStr += WebInclude(CellLeft);
Res.Subst("Content", "<span class='location'>"$HtmlEncode(TempPI.Settings[j].DisplayName)$"</span>");
Res.Subst("RowContent", WebInclude(CellLeft) $ TempStr);
TempRow += WebInclude(RowLeft);
}
for (i=0;i<InfoT.Count();i++)
{
TempStr = "";
j = int(InfoT.GetItem(i));
if (!SettingIsAllowed(TempPI.Settings[j].SecLevel) || (string(TempPI.Settings[j].ClassFrom)!=Info.GetTag(k)))
continue;
Data = "8";
if (TempPI.Settings[j].Data != "")
{
Data = TempPI.Settings[j].Data;
Divide(TempPI.Settings[j].Data, ";", Data, Op);
TempPI.SplitStringToArray(Options, Op, ":");
}
Op = "";
if (Options.Length > 1)
Op = " ("$Options[0]$" - "$Options[1]$")";
Res.Subst("Content", Textbox(TempPI.Settings[j].SettingName, Data, 3 * int(Data), TempPI.Settings[j].Value) $ Op);
TempStr = WebInclude(CellLeft);
Res.Subst("Content", "<span class=location title=\"Required Security Level\">"$TempPI.Settings[j].SecLevel$"</span>");
TempStr += WebInclude(CellLeft);
Res.Subst("Content", "<span class='location'>"$HtmlEncode(TempPI.Settings[j].DisplayName)$"</span>");
Res.Subst("RowContent", WebInclude(CellLeft) $ TempStr);
TempRow += WebInclude(RowLeft);
}
for (i=0;i<InfoS.Count();i++)
{
Data = ""; TempStr = "";
j=int(InfoS.GetItem(i));
if (!SettingIsAllowed(TempPI.Settings[j].SecLevel) || (string(TempPI.Settings[j].ClassFrom)!=Info.GetTag(k)))
continue;
// Build a set of options from PID.Data
TempPI.SplitStringToArray(Options, TempPI.Settings[j].Data, ";");
for (z = 0; (z+1)<Options.Length; z += 2)
{
Data += ("<option value='"$Options[z]$"'");
If (TempPI.Settings[j].Value == Options[z])
Data @= "selected";
Data += (">"$HtmlEncode(Options[z+1])$"</option>");
}
Res.Subst("Content", Select(TempPI.Settings[j].SettingName, Data));
TempStr = WebInclude(CellLeft);
Res.Subst("Content", "<span class=location title=\"Required Security Level\">"$TempPI.Settings[j].SecLevel$"</span>");
TempStr += WebInclude(CellLeft);
Res.Subst("Content", "<span class='location'>"$HtmlEncode(TempPI.Settings[j].DisplayName)$"</span>");
Res.Subst("RowContent", WebInclude(CellLeft) $ TempStr);
TempRow += WebInclude(RowLeft);
}
if (TempRow!="")
PlayInfoRows += (HeadingRow$TempRow);
}
}
else // Displaying values only
{
for (i=0;i<TempPI.Settings.Length;i++)
{
if (Left(TempPI.Settings[i].SettingName,Len(TempPI.Settings[i].SettingName) - 1) ~= "GameReplicationInfo.MOTDLine")
InfoS.Add(string(i), TempPI.Settings[i].SettingName);
else InfoS.Add(string(i),TempPI.Settings[i].DisplayName);
for (j=0;j<Info.Count();j++)
if (Info.GetTag(j) ~= string(TempPI.Settings[i].ClassFrom))
break;
if (j == Info.Count())
Info.Add(string(i), string(TempPI.Settings[i].ClassFrom));
}
for (k=0;k<Info.Count();k++)
{
TempRow = "";
HeadingRow = "<tr><td class=ttext colspan=\"2\">"$Info.GetTag(k)$"</td></tr>";
for (i=0;i<InfoS.Count();i++)
{
j=int(InfoS.GetItem(i));
Data = "";
if (!SettingIsAllowed(TempPI.Settings[j].SecLevel) || (string(TempPI.Settings[j].ClassFrom)!=Info.GetTag(k)))
continue;
Res.Subst("SettingName", HtmlEncode(TempPI.Settings[j].DisplayName));
if (TempPI.Settings[j].Value ~= "true")
Data = "True";
else if (TempPI.Settings[j].Value ~= "false")
Data = "False";
else
{
if (TempPI.Settings[j].RenderType ~= "Select")
{
class'wUtils103.wString'.static.Split2(TempPI.Settings[j].Data, ";", Options);
for (z=0;(z+1)<Options.Length;z+=2)
{
if (TempPI.Settings[j].Value == Options[z])
{
Data = Options[z+1];
break;
}
}
}
else Data = TempPI.Settings[j].Value;
}
Res.Subst("SettingData", HtmlEncode(Data));
Res.Subst("Extra", "");
TempRow += WebInclude(IncludeFile);
}
if (TempRow!="")
PlayInfoRows += (HeadingRow$TempRow);
}
}
return PlayInfoRows;
}
// Creates the drop-down box containing profiles names
function String GenerateSwitchProfileOptions(optional string CurrentProfileItem)
{
local int i;
local string SelectedStr, OptionStr;
if (LadderRules.AllLadderProfiles.Count() == 0)
return "<option value=\"\">***"@NoneText@"***</option>";
for (i=0; i < LadderRules.AllLadderProfiles.Count(); i++)
{
// This item was the item passed in by CurrentProfileItem, so make it active
if (CurrentProfileItem ~= LadderRules.AllLadderProfiles.GetItem(i))
SelectedStr = " selected";
else SelectedStr = "";
OptionStr = OptionStr$"<option value=\""$LadderRules.AllLadderProfiles.GetItem(i)$"\""$SelectedStr$">"$LadderRules.AllLadderProfiles.GetTag(i)@"</option>";
}
return OptionStr;
}
function bool SettingIsAllowed(byte SettingSecLevel)
{
return SettingSecLevel <= CurAdmin.MaxSecLevel();
}
// Handles generation of the double map select boxes (Exclude & Include)
function String CreateMapListSelect(array<ProfileConfigSet.ProfileMap> AllPCSMaps, StringArray MapList, StringArray MovedMaps)
{
local int i,j;
local String ResponseStr, SelectedStr, Tmp;
if (MapList.Count() == 0)
return "<option value=\"\">***"@NoneText@"***</option>";
for (i = 0; i<MapList.Count(); i++)
{
// Index for map within AllPCSMaps
j = int(MapList.GetItem(i));
Tmp = AllPCSMaps[j].MapName;
SelectedStr = "";
if (MovedMaps != None && MovedMaps.FindItemId(string(j)) >= 0)
SelectedStr = " selected";
ResponseStr = ResponseStr$"<option value=\""$Tmp$"\""$SelectedStr$">"$Tmp$"</option>";
}
return ResponseStr;
}
//**********************
// Import / Export
//**********************
// Handles spacing for textboxes on export page
function int GetLongestURL()
{
local int i, Current, Largest;
for (i = 0; i < ExportMaster.Zips.Length; i++)
{
Current = Len(ExportMaster.Zips[i].ZipURL);
if (Current > Largest)
Largest = Current;
}
return Largest + 1;
}
// Handles filling in zip-location textboxes on export page
function string GetLocation(string Package)
{
local int i;
// Check if we're dealing with a map or a mutator
i = InStr(Package, ".");
// Dealing with a mutator - remove class name
if (i != -1)
Package = Left(Package, i);
return ExportMaster.FindZipLocation(Package);
}
// Handles saving zip file locations from export page
function SetLocation(string Package, string NewLocation)
{
local int i;
// Check if we're dealing with a map or a mutator
i = InStr(Package, ".");
// Dealing with a mutator - remove class name
if (i != -1)
Package = Left(Package, i);
if (NewLocation == "")
ExportMaster.DeleteZipLocation(Package);
else ExportMaster.AddZipLocation(Package, NewLocation);
}
// Utility function to remove strings from profile names before
// creating .txt for exported profile
function string RemoveStr(string Source,string mask)
{
local int i;
local string left,right;
i = InStr(Source,mask);
while (i != -1)
{
Divide(Source,mask,left,right);
Source = Left$Right;
i = InStr(Source,Mask);
}
return Source;
}
// Prevents entering a zip file location for any package
// that is already included with the game
function bool EpicPackage(string Package)
{
local int i;
// Check if we're dealing with a map or a mutator
i = InStr(Package, ".");
// Dealing with a mutator - remove class name
if (i != -1)
Package = Left(Package, i);
for (i = 0;i < EPICNUMBER; i++)
if (Package ~= EpicPackages[i])
return true;
return false;
}
function CheckSettingValue(string SettingData, out string NewValue)
{
local string sMaxLength, sMinMax, sMin, sMax;
local int iMaxLength, iMin, iMax, iValue;
local float fMin, fMax, fValue;
local bool bFloat;
if (SettingData == "")
return;
// This setting has no valid min/max (it is a password setting or something)
if (InStr(SettingData,";") < 0 )
{
// Allow only up to three times the configured max length
iMaxLength = 3 * int(SettingData);
if (Len(NewValue) > iMaxLength)
NewValue = Left(NewValue,iMaxLength);
return;
}
Divide(SettingData,";",sMaxLength,sMinMax); // Split the Max Length & MinMax Info
Divide(sMinMax,":",sMin,sMax); // Split the Min & Max info for casting
iMaxLength = int(sMaxLength);
if ( InStr(sMin,".") >= 0 || InStr(sMax,".") >= 0) // Are we dealing with floating point numbers?
{
bFloat = True;
fMin = float(sMin);
fMax = float(sMax);
}
else
{
iMin = int(sMin);
iMax = int(sMax);
}
// First check for length
if (Len(NewValue) > iMaxLength)
NewValue = Left(NewValue,iMaxLength);
if (bFloat)
{
fValue = float(NewValue);
fValue = FClamp(fValue,fMin,fMax);
NewValue = string(fValue);
}
else
{
iValue = int(NewValue);
iValue = Clamp(iValue,iMin,iMax);
NewValue = string(iValue);
}
}
//*****************************************************************************
//*****************************************************************************
// Query Methods
//
//
// Passes the SessionID variable to all pages in this query action
// if SessionID is not present in WebRequest, generates one
// (Helpful when dealing with frames)
function bool PreQuery(WebRequest Req, WebResponse Res)
{
local string SID;
SID = Req.GetVariable("SessionID");
if (SID == "")
{
SID = SMaster.getSession("xxxxx",true).GetHash();
Req.AddVariable("SessionID", SID);
}
Res.Subst("SessionID", SID);
return true;
}
function bool Query(WebRequest Request, WebResponse Response)
{
switch (Mid(Request.URI, 1))
{
case DefaultPage: if (!MapIsChanging()) QueryLadderFrame(Request, Response); return true;
case ProfileMenuURI: if (!MapIsChanging()) QueryLadderMenu(Request, Response); return true;
case ProfileViewURI: if (!MapIsChanging()) QueryLadderView(Request, Response); return true;
case ProfileEditURI: if (!MapIsChanging()) QueryLadderEdit(Request, Response); return true;
case ProfileSwitchURI: if (!MapIsChanging()) QueryLadderSwitch(Request, Response); return true;
case ProfileManageURI: if (!MapIsChanging()) QueryLadderManage(Request, Response); return true;
// Management subframes
case SubFrameURI: if (!MapIsChanging()) QuerySubFrame(Request, Response); return true;
case SubFrameMenuURI: if (!MapIsChanging()) QuerySubMenu(Request, Response); return true;
case SubGametypeURI: if (!MapIsChanging()) QuerySubGameType(Request, Response); return true;
case SubMapsURI: if (!MapIsChanging()) QuerySubMaps(Request, Response); return true;
case SubMutatorsURI: if (!MapIsChanging()) QuerySubMutators(Request, Response); return true;
case SubRulesURI: if (!MapIsChanging()) QuerySubRules(Request, Response); return true;
case SubReviewURI: if (!MapIsChanging()) QuerySubReview(Request, Response); return true;
case SubSavedURI: if (!MapIsChanging()) QuerySubSaved(Request, Response); return true;
case SubImportURI: if (!MapIsChanging()) QuerySubImport(Request, Response); return true;
case SubExportURI: if (!MapIsChanging()) QuerySubExport(Request, Response); return true;
}
// This query is looking for a page from another query handler
// or the map is changing
return false;
}
function QueryLadderFrame(WebRequest Req, WebResponse Res)
{
local String Page;
local string SID;
// if no page specified, use the default
Page = Req.GetVariable("Page", ProfileViewURI);
SID = Req.GetVariable("SessionID");
// Tell the menu page which page we're viewing (with the ?Page=),
// so that it can highlight the appropriate link
Res.Subst("IndexURI",ProfileMenuURI$"?Page="$Page$"?SessionID="$SID);
// Load the main page into the frameset
Res.Subst("MainURI", Page$"?SessionID="$SID);
ShowFrame(Res, DefaultPage);
}
function QuerySubFrame(WebRequest Req, WebResponse Res)
{
local string Page, SID, TempStr, Action;
local Session CurS;
SID = Req.GetVariable("SessionID");
CurS = SMaster.getSession(SID, true);
Action = Req.GetVariable("Actions","Add");
if (Action ~= "Modify")
{
TempStr = Req.GetVariable("ProfileNameSelect", "");
if (TempStr != "") CreateSessionInfo(TempStr,SID,True);
}
else if (Action ~= "Add")
{
TempStr = Req.GetVariable("TextInput");
if (TempStr != "") CurS.setValue("ProfileName",TempStr,True);
}
// if no page specified, use the default
Page = Req.GetVariable("Page", SubGameTypeURI);
CurS.setValue("CurrentPage", Page, True);
// Tell the SubMenu page which page we're viewing, so that it can highlight
// the appropriate link
Res.Subst("SubMenuURI", SubFrameMenuURI$"?SessionID="$SID);
// Load the main page into the frameset
Res.Subst("SubMainURI", Page$"?SessionID="$SID);
ShowFrame(Res, SubFrame);
}
function QueryLadderMenu(WebRequest Req, WebResponse Res)
{
local string SID;
SID = Req.GetVariable("SessionID");
/*
If ?SessionID= is appended to the link, PreQuery() will not generate
a new Session when this link is queried
*/
// Set URIs
if (CanPerform("Lv"))
Res.Subst("ViewProfiles", "<a href=\""$ProfileViewURI$"\" target=\"main\">"$LinkViewProfile$"</a><br />");
if (CanPerform("Le"))
Res.Subst("EditProfiles", "<a href=\""$ProfileEditURI$"\" target=\"main\">"$LinkEditProfile$"</a><br>");
if (CanPerform("Ls"))
Res.Subst("SwitchProfiles", "<a href=\""$ProfileSwitchURI$"\" target=\"main\">"$LinkSwitchProfile$"</a><br>");
if (CanPerform("Lm"))
Res.Subst("ManageProfiles", "<a href=\""$ProfileManageURI$"\" target=\"main\">"$LinkManageProfile$"</a><br>");
ShowPage(Res, ProfileMenuURI);
}
function QuerySubMenu(WebRequest Req, WebResponse Res)
{
// Highlight the current page
local string Highlighted, Background, SID;
local string GameLink, MutatorLink, MapLink, RuleLink, ReviewLink;
local string GameSpan, MutatorSpan, MapSpan, RuleSpan, ReviewSpan;
local string Page;
local Session CurS;
if (CanPerform("Lm"))
{
Highlighted = "<span class=\"blue\">";
Background = "<span class=\"red\">";
SID = Req.GetVariable("SessionID");
CurS = SMaster.getSession(SID, true);
// We are managing an existing profile
if (CurS.HasData("ProfileIndex"))
Res.Subst("Section", LabelModifyProfile);
else Res.Subst("Section", LabelAddProfile);
Page = CurS.getValue("CurrentPage",SubGametypeURI);
// Including ?SessionID= in link prevents PreQuery() from generating a new Session
GameLink = "<a href=\""$SubFrameURI$"?SessionID="$SID$"?Page="$SubGametypeURI$ "\" target=\"_parent\">";
MutatorLink = "<a href=\""$SubFrameURI$"?SessionID="$SID$"?Page="$SubMutatorsURI$ "\" target=\"_parent\">";
MapLink = "<a href=\""$SubFrameURI$"?SessionID="$SID$"?Page="$SubMapsURI$ "\" target=\"_parent\">";
RuleLink = "<a href=\""$SubFrameURI$"?SessionID="$SID$"?Page="$SubRulesURI$ "\" target=\"_parent\">";
ReviewLink = "<a href=\""$SubFrameURI$"?SessionID="$SID$"?Page="$SubReviewURI$ "\" target=\"_parent\">";
// Initially set all spans to the background color
GameSpan = Background;
MutatorSpan = Background;
MapSpan = Background;
RuleSpan = Background;
ReviewSpan = Background;
// Then set the appropriate span to the highlighted color
Res.Subst("SubTitle", CurS.GetValue("ProfileName"));
switch (Page)
{
case SubGametypeURI:
Curs.SetValue("ButtonName", ProfileButtonName[1],true);
Curs.SetValue("ButtonValue", ProfileButtonValue[1],true);
Res.Subst("PageHelp", HelpGameType);
GameSpan = Highlighted; break;
case SubMutatorsURI:
Curs.SetValue("ButtonName", ProfileButtonName[2],true);
Curs.SetValue("ButtonValue", ProfileButtonValue[2],true);
Res.Subst("PageHelp", HelpMutators);
MutatorSpan = Highlighted; break;
case SubMapsURI:
Curs.SetValue("ButtonName", ProfileButtonName[3],true);
Curs.SetValue("ButtonValue", ProfileButtonValue[3],true);
Res.Subst("PageHelp", HelpMaps);
Mapspan = Highlighted; break;
case SubRulesURI:
Curs.SetValue("ButtonName", ProfileButtonName[4],true);
Curs.SetValue("ButtonValue", ProfileButtonValue[4],true);
Res.Subst("PageHelp", HelpPlayInfo);
RuleSpan = Highlighted; break;
case SubReviewURI:
Curs.SetValue("ButtonName", ProfileButtonName[5],true);
Curs.SetValue("ButtonValue", ProfileButtonValue[5],true);
Res.Subst("PageHelp", HelpReview);
ReviewSpan = Highlighted; break;
}
GameLink = GameLink $ GameSpan $ TableTitle[1]$"</span></a>";
MutatorLink = MutatorLink $ MutatorSpan $ TableTitle[2]$"</span></a>";
MapLink = MapLink $ MapSpan $ TableTitle[3]$"</span></a>";
RuleLink = RuleLink $ RuleSpan $ TableTitle[4]$"</span></a>";
ReviewLink = ReviewLink $ ReviewSpan $ TableTitle[5]$"</span></a>";
Res.Subst("GameTypeLink", GameLink);
Res.Subst("MutatorsLink", MutatorLink);
Res.Subst("MapsLink", MapLink);
Res.Subst("RulesLink", RuleLink);
Res.Subst("ReviewLink", ReviewLink);
ShowPage(Res, SubFrameMenu);
}
else AccessDenied(Res);
}
function QueryLadderView(WebRequest Req, WebResponse Res)
{
local int i,j;
local Session CurS;
local string SID,
TempStr,
ViewRows,
NewProfile,
NewGameType;
local StringArray Mutators, GroupsOnly, ServerActors;
local class<GameInfo> GIClass;
local class<AccessControl> ACClass;
local class<Mutator> TempMut;
local class<Info> TempSA;
if (CanPerform("Lv"))
{
SID = Req.GetVariable("SessionID");
CurS = SMaster.getSession(SID,true);
if (CanPerform("Ls"))
{
if (Req.GetVariable("SetProfileName","")!="") // We would like to view a different profile
TempStr = Req.GetVariable("ProfileNameSelect", "");
If (TempStr == "") // Not selecting a new profile to view
{
// First, see if the current session is holding a profile
NewProfile = CurS.getValue("ProfileIndex");
if (NewProfile == "")
{
// See if a profile is currently loaded
j = GetCurrentConfigIndex();
if (j!=-1) // Found an active profile - this profile should be selected
NewProfile = string(j);
}
}
if (TempStr!="")
NewProfile = TempStr;
Res.Subst("ButtonName", "SetProfileName");
Res.Subst("ButtonValue", ButtonLoadProfile);
Res.Subst("PageCaption", "<select class=mini name='ProfileNameSelect'>"$GenerateSwitchProfileOptions(NewProfile)$"</select>");
}
// If admin doesn't have switch privileges, check for current profile
if (NewProfile == "")
{
NewProfile = CurS.getValue("ProfileIndex");
if (NewProfile == "")
{
j = GetCurrentConfigIndex();
if (j != -1)
NewProfile = string(j);
}
}
if (NewProfile != "" && LadderRules.AllLadderProfiles.Count() > 0)
{
CurS.setValue("ProfileIndex", NewProfile, True);
CreateSessionInfo(NewProfile,SID);
NewGameType = CurS.getValue("GameType");
if (NewGameType != "")
GIClass = class<GameInfo>(DynamicLoadObject(NewGameType,class'Class'));
if (GIClass==None)
{
ShowMessage(Res,ErrorGameClassTitle,ErrorGameClassText);
return;
}
TempStr = CurS.getValue("ACClass",Level.Game.AccessControlClass);
if (TempStr != "")
ACClass = class<AccessControl>(DynamicLoadObject(TempStr,class'Class'));
if (ACClass == None)
{
ShowMessage(Res,ErrorAccessControlTitle,ErrorAccessControlText);
return;
}
Mutators = new(None) class'SortedStringArray';
GroupsOnly = new(None) class'SortedStringArray';
ServerActors = new(None) class'SortedStringArray';
// Mutator Section
for (i=0;i<CurS.getMutatorLength();i++)
{
TempStr = CurS.getMutator(i);
for (j=0;j<AllMutators.Length;j++)
{
if (TempStr ~= AllMutators[j].ClassName)
{
TempMut = class<Mutator>(DynamicLoadObject(TempStr,class'Class'));
if (TempMut != None)
Mutators.Add(string(j), AllMutators[j].FriendlyName);
}
}
}
for (i=0;i<CurS.getSALength();i++)
{
TempStr = CurS.GetServerActor(i);
for (j=0;j<ConfigM.ManagedActors.Length;j++)
{
if (TempStr ~= string(ConfigM.ManagedActors[j].SAClass))
{
TempSA = class<Info>(DynamicLoadObject(TempStr,class'Class'));
if (TempSA != None)
ServerActors.Add(string(j),ConfigM.ManagedActors[j].SAName);
}
}
}
Res.Subst("SectionName", TableTitle[2]);
Res.Subst("SpecialInstructions", "");
ViewRows = ViewRows$WebInclude(IncludeSection);
for (i = 0; i<ServerActors.Count(); i++)
{
j = int(ServerActors.GetItem(i));
Res.Subst("SettingName", ServerActors.GetTag(i));
if (CurS.SARequired(string(ConfigM.ManagedActors[j].SAClass)))
Res.Subst("SettingData", RequiredText);
else Res.Subst("SettingData", " ");
ViewRows = ViewRows $ WebInclude(IncludeRows);
}
ViewRows = ViewRows $ "<tr><td colspan=\"2\"> </td></tr>";
for (i = 0; i<Mutators.Count(); i++)
{
j = int(Mutators.GetItem(i));
Res.Subst("SettingName", AllMutators[j].FriendlyName);
if (CurS.MutRequired(AllMutators[j].ClassName))
Res.Subst("SettingData", RequiredText);
else Res.Subst("SettingData", " ");
ViewRows = ViewRows$WebInclude(IncludeRows);
}
Res.Subst("SectionName", TableTitle[3]);
Res.Subst("SpecialInstructions", "");
ViewRows = ViewRows$WebInclude(IncludeSection);
Res.Subst("SettingName", LabelMaxMaps);
TempStr = CurS.getValue("MaxMaps");
if (TempStr == "0")
TempStr = UnlimitedText;
Res.Subst("SettingData", TempStr);
Res.Subst("Extra", "<tr><td colspan=\"2\"> </td></tr>");
ViewRows = ViewRows$WebInclude(IncludeRows);
for (i=0;i<CurS.getMapLength();i++)
{
TempStr = CurS.getMap(i);
Res.Subst("SettingName", TempStr);
Res.Subst("Extra", "");
if (CurS.MapRequired(TempStr))
Res.Subst("SettingData", RequiredText);
else Res.Subst("SettingData", "  ");
ViewRows = ViewRows$WebInclude(IncludeRows);
}
Res.Subst("SectionName", TableTitle[4]);
Res.Subst("SpecialInstructions", " ");
ViewRows = ViewRows $ WebInclude(IncludeSection);
ViewRows = ViewRows $ "<tr><td colspan=\"2\"> </td></tr>" $ GeneratePlayInfoRows(Req, Res, IncludeRows);
}
// We have no profile currently active
else
{
Res.Subst("SettingName", PageCaption[0]);
ViewRows = ViewRows $ WebInclude(IncludeRows);
}
TempStr = CurS.getValue("ProfileName", PageCaption[0]);
if (LadderRules.GetRemainingMatches() > 0 && TempStr == LadderRules.Profiles[GetCurrentConfigIndex()].ProfileName)
TempStr = TempStr @ LabelNumberMatchesLeft @ string(LadderRules.GetRemainingMatches());
Res.Subst("TableRows", ViewRows);
Res.Subst("LadderTable", WebInclude(IncludeCaptionButton)$WebInclude(IncludeTable));
Res.Subst("Section", LinkViewProfile);
Res.Subst("SubTitle", TempStr);
Res.Subst("PageHelp", HelpViewProfile);
Res.Subst("PostAction", ProfileViewURI$"?SessionID="$SID);
ShowPage(Res, MasterPage);
}
else AccessDenied(Res);
}
function QueryLadderEdit(WebRequest Req, WebResponse Res)
{
local Session CurS;
local bool bAllMuts;
local int i,j,k,z,
id,
Count,
MoveCount;
local string SID,
EditRows,
TempStr, Tmp, NewProfile, NewGameType,
lastgroup, thisgroup, nextgroup, EmptyRow;
local ProfileConfigSet TempPCS;
local array<string> TempMutes;
local class<GameInfo> GIClass;
local class<AccessControl> ACClass;
local array<ProfileConfigSet.ProfileMap> AllPCSMaps;
local array<ProfileConfigSet.ProfileMutator> AllPCSMutators;
local array<ProfileConfigSet.ProfileSA> AllPCSServerActors;
local StringArray
Mutators, GroupsOnly, Required, ServerActors, ReqSA,
RequiredMaps, IncludeMaps, ExcludeMaps, MovedMaps;
SID = Req.GetVariable("SessionID");
CurS = SMaster.getSession(SID,true);
if (CanPerform("Le"))
{
if (CanPerform("Ls"))
{
if (Req.GetVariable("SetProfileName","")!="") // We would like to view a different profile
TempStr = Req.GetVariable("ProfileNameSelect", "");
If (TempStr == "") // Not selecting a new profile to view
{
// First, see if the current session is holding a profile
NewProfile = CurS.getValue("ProfileIndex");
if (NewProfile == "")
{
// See if a profile is currently loaded
j = GetCurrentConfigIndex();
if (j!=-1) // Found an active profile - this profile should be selected
NewProfile = string(j);
}
}
if (TempStr!="")
NewProfile = TempStr;
Res.Subst("ButtonName", "SetProfileName");
Res.Subst("ButtonValue", ButtonLoadProfile);
Res.Subst("PageCaption", "<select class=mini name='ProfileNameSelect'>"$GenerateSwitchProfileOptions(NewProfile)$"</select>");
}
CurS.setValue("CurrentPage", ProfileEditURI, true);
CurS.setValue("ButtonName", "ApplyProfileChanges",true);
CurS.setValue("ButtonValue", ButtonApplyProfileChanges, true);
// If admin doesn't have switch privileges, check for current profile
if (NewProfile == "")
{
NewProfile = CurS.getValue("ProfileIndex");
if (NewProfile == "")
{
j = GetCurrentConfigIndex();
if (j != -1)
NewProfile = string(j);
}
}
CurS.setValue("ProfileIndex", NewProfile, True);
if (NewProfile != "" && LadderRules.AllLadderProfiles.Count() > 0)
{
ProfileMaps.Reset();
Required = new(None) class'SortedStringArray';
ReqSA = new(None) class'SortedStringArray';
Mutators = new(None) class'SortedStringArray';
MovedMaps = new(None) class'SortedStringArray';
GroupsOnly = new(None) class'SortedStringArray';
ServerActors = new(None) class'SortedStringArray';
IncludeMaps = new(None) class'SortedStringArray';
ExcludeMaps = new(None) class'SortedStringArray';
RequiredMaps = new(None) class'SortedStringArray';
CreateSessionInfo(NewProfile,SID);
TempPCS = LadderRules.LadderProfiles[int(NewProfile)];
TempPCS.StartEdit();
NewGameType = CurS.getValue("GameType");
GIClass = class<GameInfo>(DynamicLoadObject(NewGameType,class'Class'));
if (GIClass==None)
{
ShowMessage(Res,ErrorGameClassTitle,ErrorGameClassText);
return;
}
TempStr = CurS.getValue("ACClass", Level.Game.AccessControlClass);
if (TempStr != "")
ACClass = class<AccessControl>(DynamicLoadObject(TempStr,class'Class'));
AllPCSMutators = TempPCS.GetProfileMutators();
AllPCSMaps = TempPCS.GetProfileMaps();
AllPCSServerActors = TempPCS.GetProfileServerActors();
// Load Exclude Maps
for (i=0;i<AllPCSMaps.Length;i++)
{
ProfileMaps.Add(string(i), AllPCSMaps[i].MapName);
if (AllPCSMaps[i].bRequired)
{
RequiredMaps.Add(string(i),string(AllPCSMaps[i].MapListOrder));
IncludeMaps.Add(string(i),string(AllPCSMaps[i].MapListOrder));
}
else ExcludeMaps.Add(string(i),string(AllPCSMaps[i].MapListOrder));
}
for (i=0;i<CurS.GetMapLength();i++)
{
j = ExcludeMaps.FindItemId(ProfileMaps.GetItem(ProfileMaps.FindTagId(CurS.getMap(i))));
if (j >= 0) IncludeMaps.MoveFromId(ExcludeMaps, j);
}
if (Req.GetVariable("ApplyProfileChanges","")!="")
{
for (i=0;i<AllPCSMutators.Length;i++)
for (j=0;j<AllMutators.Length;j++)
if (AllPCSMutators[i].MutatorName ~= AllMutators[j].ClassName)
Mutators.Add(string(j),AllPCSMutators[i].MutatorName);
for (i=0;i<Mutators.Count();i++)
{
if ((Req.GetVariable(Mutators.GetTag(i),"")!="")||(Req.GetVariable(AllMutators[int(Mutators.GetItem(i))].GroupName)~=Mutators.GetTag(i)))
TempPCS.AddMutator(Mutators.GetTag(i));
else TempPCS.DelMutator(Mutators.GetTag(i));
}
for (i=0;i<AllPCSServerActors.Length;i++)
{
if (Req.GetVariable(AllPCSServerActors[i].ActorClass,"") != "")
TempPCS.AddServerActor(AllPCSServerActors[i].ActorClass);
else TempPCS.DelServerActor(AllPCSServerActors[i].ActorClass);
}
for (i=0;i<AllPCSMaps.Length;i++)
{
if (AllPCSMaps[i].bRequired) TempPCS.AddMap(AllPCSMaps[i].MapName,int(RequiredMaps.GetTag(RequiredMaps.FindItemId(string(i)))));
else if (IncludeMaps.FindItemId(string(i)) >= 0) TempPCS.AddMap(AllPCSMaps[i].MapName,int(IncludeMaps.GetTag(IncludeMaps.FindItemId(string(i)))));
else TempPCS.RemoveMap(AllPCSMaps[i].MapName);
}
CreateSessionInfo(NewProfile,SID,false,true);
}
else if (Req.GetVariable("AddMap", "") != "")
{
Count = Req.GetVariableCount("ExcludeMapsSelect");
for (i=0; i<Count; i++)
{
if (IncludeMaps.Count() >= TempPCS.MaxMaps && TempPCS.MaxMaps > 0)
break;
if (ExcludeMaps.Count() > 0)
{
id = IncludeMaps.MoveFromId(ExcludeMaps, ExcludeMaps.FindItemId(ProfileMaps.GetItem(ProfileMaps.FindTagId(Req.GetVariableNumber("ExcludeMapsSelect", i)))));
if (id >= 0)
{
TempPCS.AddMap(AllPCSMaps[int(IncludeMaps.getItem(id))].MapName,int(IncludeMaps.getTag(id)));
MovedMaps.CopyFromId(IncludeMaps, id);
}
else
Log(ErrorExcludeMapNotFound@Req.GetVariableNumber("ExcludeMapsSelect", i),LOGNAME);
}
}
for (i=0;i<IncludeMaps.Count();i++)
TempPCS.AddMap(AllPCSMaps[int(IncludeMaps.getItem(i))].MapName,i);
CreateSessionInfo(NewProfile,SID,false,true,True);
}
else if (Req.GetVariable("DelMap", "") != "" && Req.GetVariableCount("IncludeMapsSelect") > 0)
{
Count = Req.GetVariableCount("IncludeMapsSelect");
for (i=0; i<Count; i++)
{
if (RequiredMaps.FindItemId(ProfileMaps.GetItem(ProfileMaps.FindTagId(Req.GetVariableNumber("IncludeMapsSelect", i)))) < 0)
{
if (IncludeMaps.Count() > 0)
{
id = ExcludeMaps.MoveFromId(IncludeMaps, IncludeMaps.FindItemId(ProfileMaps.GetItem(ProfileMaps.FindTagId(Req.GetVariableNumber("IncludeMapsSelect", i)))));
if (id >= 0)
{
TempPCS.RemoveMap(AllPCSMaps[int(ExcludeMaps.GetItem(id))].MapName);
MovedMaps.CopyFromId(ExcludeMaps, id);
}
else
Log(ErrorIncludeMapNotFound@Req.GetVariableNumber("IncludeMapsSelect", i),LOGNAME);
}
}
}
CreateSessionInfo(NewProfile,SID,false,true,True);
}
else if (Req.GetVariable("AddAllMap", "") != "")
{
while (ExcludeMaps.Count() > 0 && (IncludeMaps.Count() < TempPCS.MaxMaps || TempPCS.MaxMaps == 0) )
{
id = IncludeMaps.MoveFromId(ExcludeMaps, ExcludeMaps.Count()-1);
if (id >= 0)
{
TempPCS.AddMap(AllPCSMaps[int(IncludeMaps.getItem(id))].MapName,int(IncludeMaps.getTag(id)));
MovedMaps.CopyFromId(IncludeMaps, id);
}
}
for (i=0;i<IncludeMaps.Count();i++)
TempPCS.AddMap(AllPCSMaps[int(IncludeMaps.getItem(i))].MapName,i);
CreateSessionInfo(NewProfile,SID,false,true,True);
}
else if (Req.GetVariable("DelAllMap", "") != "")
{
i = IncludeMaps.Count();
while (i > 0 && IncludeMaps.Count() > RequiredMaps.Count())
{
if (RequiredMaps.FindItemId(IncludeMaps.GetItem(i-1)) < 0)
{
id = ExcludeMaps.MoveFromId(IncludeMaps, i-1);
if (id >= 0)
{
TempPCS.RemoveMap(AllPCSMaps[int(ExcludeMaps.GetItem(id))].MapName);
MovedMaps.CopyFromId(ExcludeMaps, id);
}
}
i--;
}
CreateSessionInfo(NewProfile,SID,false,true,True);
}
else if (Req.GetVariable("MoveMap", "") != "")
{
MoveCount = int(Abs(float(Req.GetVariable("MoveMapCount"))));
if (MoveCount != 0)
{
Count = Req.GetVariableCount("IncludeMapsSelect");
// 1) Create a sorted MovedMaps list
for (i = 0; i<Count; i++)
MovedMaps.CopyFromId(IncludeMaps, IncludeMaps.FindItemId(ProfileMaps.GetItem(ProfileMaps.FindTagId(Req.GetVariableNumber("IncludeMapsSelect", i)))));
if (Req.GetVariable("MoveMap") ~= "Down")
{
// 2) Browse from Last to 0 until all maps are moved by count
// but stop moving them if hitting bottom
for (i = IncludeMaps.Count()-1; i >= 0; i--)
if (MovedMaps.FindItemId(IncludeMaps.GetItem(i)) >= 0)
IncludeMaps.ShiftStrict(i, MoveCount);
}
else
{
MoveCount = -MoveCount;
for (i = 0; i<IncludeMaps.Count(); i++)
if (MovedMaps.FindItemId(IncludeMaps.GetItem(i)) >= 0)
IncludeMaps.ShiftStrict(i, MoveCount);
}
}
for (i=0;i<IncludeMaps.Count();i++)
TempPCS.AddMap(AllPCSMaps[int(IncludeMaps.getItem(i))].MapName,i);
CreateSessionInfo(NewProfile,SID,false,true,True);
}
if (TempPCS.CanEdit())
TempPCS.StartEdit();
// Mutator Section
Mutators.Reset();
// Set active ServerActors
TempMutes = LoadActiveProfileServerActors(NewProfile);
TempStr = class'wUtils103.wArray'.static.Join(TempMutes,",");
bAllMuts = TempMutes.Length == ConfigM.ManagedActors.Length;
for (i=0;i<AllPCSServerActors.Length;i++)
{
for (j = 0; j < ConfigM.ManagedActors.Length; j++)
{
if (AllPCSServerActors[i].ActorClass ~= string(ConfigM.ManagedActors[j].SAClass))
{
if (AllPCSServerActors[i].bRequired)
ReqSA.Add(string(j), ConfigM.ManagedActors[j].SAName);
else ServerActors.Add(string(j),ConfigM.ManagedActors[j].SAName);
break;
}
}
}
TempMutes = LoadActiveProfileMutators(NewProfile);
TempStr = class'wUtils103.wArray'.static.Join(TempMutes,",");
// Set Available Mutators for this profile
bAllMuts = bAllMuts && AllPCSMutators.Length == AllMutators.Length;
for (i=0;i<AllPCSMutators.Length;i++)
{
for (j=0;j<AllMutators.Length;j++)
{
if (AllMutators[j].ClassName ~= AllPCSMutators[i].MutatorName)
{
if (AllPCSMutators[i].bRequired)
Required.Add(string(j),AllMutators[j].FriendlyName);
else
{
// Don't add available mutator if it belongs in the same group as a required mutator
for (k=0;k<Required.Count();k++)
if (AllMutators[int(Required.GetItem(k))].GroupName ~= AllMutators[j].GroupName)
break;
if (k==Required.Count())
Mutators.Add(string(j),AllPCSMutators[i].MutatorName);
}
break;
}
}
}
// BEGIN OUTPUT ////////////////////////////////////////////
/*
TempMutes is an array of active mutators, including required ones
AllPCSMutators is a ProfileMutator array, which includes a required flag
Need to generate a regular mutator selection list, but list all required
first, followed by the list of all other mutators which are available
*/
// MAPS
Res.Subst("SpanLength", "2");
Res.Subst("SpanContent", " ");
EmptyRow = "<tr>" $ WebInclude(CellColSpan) $ "</tr>";
Res.Subst("SectionName", TableTitle[3]);
TempStr = string(TempPCS.GetMaxMaps());
if (TempStr == "0") TempStr = "Unlimited";
Res.Subst("SpecialInstructions", LabelMaxMaps$":"@TempStr);
EditRows += WebInclude(IncludeSection);
j = RequiredMaps.Count();
if (j > 0)
{
EditRows = EditRows $ EmptyRow $ "<tr><td class=ttext>" $ RequiredText @ MapText $ "</td><td class=ttext>" $ FollowingMaps@AreAssignedText $ "</td></tr>";
i=0;
while (i<j)
{
Res.Subst("SettingName", AllPCSMaps[int(RequiredMaps.GetItem(i++))].MapName);
Res.Subst("SettingData", StringIf(i < j, AllPCSMaps[int(RequiredMaps.GetItem(i++))].MapName, ""));
Res.Subst("Extra", "");
EditRows += WebInclude(IncludeRows);
}
}
EditRows = EditRows $ EmptyRow $ "<tr><td class=ttext>" $ AvailableText@MapText $ "</td><td class=ttext>" $ LabelChangeMaplist $ "</td></tr>";
Res.Subst("ExcludeMapsOptions", CreateMapListSelect(AllPCSMaps, ExcludeMaps,MovedMaps));
Res.Subst("IncludeMapsOptions", CreateMapListSelect(AllPCSMaps, IncludeMaps,MovedMaps));
Res.Subst("SpanContent", WebInclude(IncludeMapSelect));
Res.Subst("RowContent", WebInclude(CellColSpan));
EditRows += WebInclude(RowLeft);
// MUTATORS
CreateFullMutatorList(Mutators,GroupsOnly);
Res.Subst("SectionName", TableTitle[2]);
Res.Subst("SpecialInstructions", "");
EditRows += WebInclude(IncludeSection);
if (ReqSA.Count() > 0 || Required.Count() > 0)
EditRows = EditRows $ EmptyRow $ "<tr><td class=ttext>" $ RequiredText@MutatorText $ "</td><td class=ttext>" $ FollowingMutators@AreAssignedText $ "</td></tr>";
// Include ServerActors first
for (i=0;i<ReqSA.Count();i++)
{
j = int(ReqSA.GetItem(i));
Res.Subst("SettingName", ReqSA.GetTag(i));
Res.Subst("SettingData", ConfigM.ManagedActors[j].SADescription);
Res.Subst("Extra", "");
EditRows += WebInclude(IncludeRows);
}
for (i=0;i<Required.Count();i++)
{
j=int(Required.GetItem(i));
Res.Subst("SettingName", AllMutators[j].FriendlyName);
Res.Subst("SettingData", AllMutators[j].Description);
Res.Subst("Extra", "");
EditRows += WebInclude(IncludeRows);
}
EditRows = EditRows $ EmptyRow $ "<tr><td class=ttext>" $ AvailableText@MutatorText $ "</td><td class=ttext>" $ FollowingMutators@AreAvailableText $ "</td></tr>";
for (i=0;i<GroupsOnly.Count();i++)
{
j=int(GroupsOnly.GetItem(i));
if (AllMutators[j].GroupName=="")
thisgroup="Z"$string(z++);
else thisgroup = AllMutators[j].GroupName;
if ( (i + 1) == GroupsOnly.Count())
nextgroup = "";
else
{
// Assign nextgroup to the next mutators group
k = int(GroupsOnly.GetItem(i + 1));
if (AllMutators[k].GroupName=="")
nextgroup="Z"$string(z);
else nextgroup = AllMutators[k].GroupName;
}
Res.Subst("GroupName", thisgroup);
Res.Subst("MutatorClass", AllMutators[j].ClassName);
Res.Subst("MutatorName", AllMutators[j].FriendlyName);
Res.Subst("MutatorDesc", AllMutators[j].Description);
if ((lastgroup != thisgroup) && (thisgroup == nextgroup)) // and the next mut is in the same group as this one
{
Res.Subst("Checked", " checked");
EditRows += WebInclude("current_mutators_group");
}
Res.Subst("Checked", StringIf(CurS.HasMutator(AllMutators[j].ClassName), " checked", ""));
EditRows += WebInclude("current_mutators_group_row");
lastgroup=thisgroup;
}
// Add ServerActors first
for (i = 0; i < ServerActors.Count(); i++)
{
TempStr = "";
j = int(ServerActors.GetItem(i));
Res.Subst("Content", Checkbox(string(ConfigM.ManagedActors[j].SAClass), CurS.HasServerActor(string(ConfigM.ManagedActors[j].SAClass))) $ " " $ ServerActors.GetTag(i));
TempStr = WebInclude(NowrapLeft);
Res.Subst("Content", ConfigM.ManagedActors[j].SADescription);
Res.Subst("RowContent", TempStr $ WebInclude(CellLeft));
EditRows += WebInclude(RowLeft);
}
for (i = 0; i<Mutators.Count(); i++)
{
TempStr = "";
j = int(Mutators.GetItem(i));
Res.Subst("Content", Checkbox(AllMutators[j].ClassName,CurS.HasMutator(AllMutators[j].ClassName)) $ " " $ AllMutators[j].FriendlyName);
TempStr += WebInclude(NowrapLeft);
Res.Subst("Content", AllMutators[j].Description);
Res.Subst("RowContent", TempStr $ WebInclude(CellLeft));
EditRows += WebInclude(RowLeft);
}
TempPCS.EndEdit(False);
}
// We have no profile currently active
else
{
Res.Subst("SettingName", PageCaption[0]);
EditRows += WebInclude(IncludeRows);
}
Res.Subst("TableRows", EditRows);
TempStr = "";
TempStr = WebInclude(IncludeCaptionButton)$Tmp$WebInclude(IncludeTable);
if (NewProfile != "")
{
Res.Subst("ButtonName", curS.getValue("ButtonName","ApplyProfileChanges"));
Res.Subst("ButtonValue", ButtonApplyProfileChanges);
Res.Subst("PageCaption", "");
TempStr += WebInclude(IncludeCaptionButton);
}
Tmp = CurS.getValue("ProfileName",PageCaption[0]);
if (LadderRules.GetRemainingMatches() > 0 && Tmp == LadderRules.Profiles[GetCurrentConfigIndex()].ProfileName)
Tmp = Tmp @ LabelNumberMatchesLeft @ string(LadderRules.GetRemainingMatches());
Res.Subst("LadderTable", TempStr);
Res.Subst("Section", LinkEditProfile);
Res.Subst("SubTitle", Tmp);
Res.Subst("PageHelp", HelpEditProfile);
Res.Subst("PostAction", ProfileEditURI$"?SessionID="$SID);
ShowPage(Res, MasterPage);
}
else AccessDenied(Res);
}
function QueryLadderSwitch(WebRequest Req, WebResponse Res)
{
local int j, NumMatches;
local bool bDelayChange, bSwitching;
local Session CurS;
local string SID,
TempStr, Tmp,
Checked;
SID = Req.GetVariable("SessionID");
CurS = SMaster.getSession(SID,true);
if (CanPerform("Ls"))
{
TempStr = Req.GetVariable("ProfileNameSelect", "");
Tmp = Req.GetVariable("SetNewProfile", "");
if (Tmp != "")
{
if (TempStr != "")
{
NumMatches = int(Req.GetVariable("NumMatches", "0"));
bDelayChange = Req.GetVariable("DelaySwitch","") != "";
if (bDelayChange)
{
if (LadderRules.WaitApplyProfile(TempStr, NumMatches))
{
CurS.setValue("ProfileIndex", TempStr, True);
bSwitching = True;
}
}
else
{
// We would like to switch immediately
LadderRules.ApplyProfile(TempStr, NumMatches);
MapIsChanging();
return;
}
}
else StatusError(Res, ErrorNoProfilesExist);
}
else if (LadderRules.Profiles.Length > 0)
{
j = GetCurrentConfigIndex();
if (j >= 0) TempStr = string(j);
}
bDelayChange = Req.GetVariable("DelaySwitch","") != "" || LadderRules.bWaitingToSwitch;
if (bDelayChange)
Checked = " checked";
else Checked = "";
Res.Subst("ProfileSelect", GenerateSwitchProfileOptions(TempStr));
Res.Subst("NumberGamesText", LabelNumberGames);
Res.Subst("TextName", "NumMatches");
Res.Subst("TextValue", string(NumMatches));
Res.Subst("TextSize", "3");
Res.Subst("TextLength", "3");
Res.Subst("SwitchButtonName", "SetNewProfile");
Res.Subst("SwitchButtonValue", ButtonLoadProfile);
Res.Subst("DelayCheckName", "DelaySwitch");
Res.Subst("Checked", Checked);
Res.Subst("DelayCheckLabel", LabelDelayProfileChange);
if (Tmp != "" && bSwitching)
StatusOK(Res, SuccessSwitchProfile);
Tmp = CurS.getValue("ProfileName", PageCaption[0]);
if (LadderRules.GetRemainingMatches() > 0 && Tmp == LadderRules.Profiles[GetCurrentConfigIndex()].ProfileName)
Tmp = Tmp @ LabelNumberMatchesLeft @ string(LadderRules.GetRemainingMatches());
Res.Subst("LadderTable", WebInclude(IncludeSwitch));
Res.Subst("Section", LinkSwitchProfile);
Res.Subst("SubTitle", Tmp);
Res.Subst("PageHelp", HelpSwitchProfile);
Res.Subst("PostAction", ProfileSwitchURI$"?SessionID="$SID);
ShowPage(Res, MasterPage);
}
else AccessDenied(Res);
}
function QuerySubImport(WebRequest Req, WebResponse Res)
{
local string SID;
local Session CurS;
local ProfileConfigSet TempPCS;
SID = Req.GetVariable("SessionID");
CurS = SMaster.getSession(SID,true);
if (CanPerform("Lm"))
{
// We've gotten our profile - want to integrate it into the server now
if (Req.GetVariable("ImportRemoteProfile","") != "")
{
TempPCS = CreateImportSessionInfo(CurS);
if (TempPCS == None)
{
ShowMessage(Res, ImportProfileFailTitle, ImportProfileFailText);
return;
}
ShowMessage(Res, SuccessImportProfileTitle, SuccessImportProfile);
return;
}
}
else AccessDenied(Res);
}
function RemoteImport(ProfileImporter ProfileConn)
{
local int i,j;
local Session CurS;
local string Tmp, TempStr,
ImportRows,
PackageLink,
NewGameType, CustomGameLocation,
NewAccessType, CustomAccessLocation,
ImportProfileHTML,
MapLocation, MutatorLocation, MutatorName;
local StringArray ImportMaps, ImportMutators;
local WebRequest Req;
local WebResponse Res;
Req = ProfileConn.QueryRequest;
Res = ProfileConn.QueryResponse;
if (Res == None)
{
ShowMessage(Res, ErrorText, ErrorTimeout);
return;
}
switch (ProfileConn.ImportResult)
{
case IMPORT_BadURL: ShowMessage(Res,ErrorText,ErrorBadURL); CleanupQuery(); return;
case IMPORT_ResolveError: ShowMessage(Res,ErrorText,ErrorResolve); CleanupQuery(); return;
case IMPORT_BindError: ShowMessage(Res,ErrorText,ErrorBind); CleanupQuery(); return;
case IMPORT_TimeOut: ShowMessage(Res,ErrorText,ErrorTimeout); CleanupQuery(); return;
case IMPORT_ServerError: ShowMessage(Res,ErrorText,ErrorServer); CleanupQuery(); return;
case IMPORT_BadRequest: ShowMessage(Res,ErrorText,ErrorBadRequest); CleanupQuery(); return;
case IMPORT_Unauthorized: ShowMessage(Res,ErrorText,ErrorUnauthorized); CleanupQuery(); return;
case IMPORT_Forbidden: ShowMessage(Res,ErrorText,ErrorForbidden); CleanupQuery(); return;
case IMPORT_NotFound: ShowMessage(Res,ErrorText,ErrorNotFound); CleanupQuery(); return;
case IMPORT_InvalidProfile: ShowMessage(Res,ErrorText,ErrorProfile); CleanupQuery(); return;
}
CurS = ProfileConn.ImportS;
ImportMaps = new(None) class'SortedStringArray';
ImportMutators = new(None) class'SortedStringArray';
// General Profile Info
Res.Subst("SectionName", LabelGeneralProfile);
Res.Subst("SpecialInstructions", "");
ImportRows += WebInclude(IncludeSection);
Res.Subst("SettingName", LabelProfileName);
Res.Subst("SettingData", CurS.getValue("ProfileName"));
Res.Subst("Extra","");
ImportRows += WebInclude(IncludeRows);
// Profile Gametype Class
NewGameType = CurS.getValue("GameType");
CustomGameLocation = CurS.getValue("CustomGameLoc");
if (CustomGameLocation != "")
PackageLink = "<a href=\""$CustomGameLocation$"\" target=\"_blank\">"$CurS.getValue("GameName")$"</a>";
else PackageLink = CurS.getValue("GameName");
Res.Subst("SettingName", LabelGameType);
Res.Subst("SettingData", PackageLink);
Res.Subst("Extra","");
ImportRows += WebInclude(IncludeRows);
// Profile access control class
NewAccessType = CurS.getValue("ACClass");
CustomAccessLocation = CurS.getValue("CustomACLoc");
if (CustomAccessLocation != "")
PackageLink = "<a href=\""$CustomAccessLocation$"\" target=\"_blank\">"$NewAccessType$"</a>";
else PackageLink = NewAccessType;
Res.Subst("SettingName", LabelAccessControl);
Res.Subst("SettingData", PackageLink);
Res.Subst("Extra","");
ImportRows += WebInclude(IncludeRows);
// Map Information
Res.Subst("SectionName", TableTitle[3]);
Res.Subst("SpecialInstructions", "");
ImportRows += WebInclude(IncludeSection);
for (i = 0; i < CurS.getMapLength(); i++)
ImportMaps.Add(string(i), string(CurS.MapOrder(i)));
for (i = 0; i < ImportMaps.Count(); i++)
{
TempStr = CurS.getMap( int(ImportMaps.getItem(i)) );
MapLocation = ProfileConn.FindRemoteZipLocation(TempStr,ProfileConn.ProfileServerAddress $ ProfileConn.RemoteProfilePath);
if (MapLocation != "") PackageLink = "<a href=\""$MapLocation$"\" target=\"_blank\">"$TempStr$"</a>";
else PackageLink = TempStr;
if (CurS.MapRequired( TempStr ))
TempStr = "<font color=\"red\">"$RequiredText$"</font>";
else TempStr = AvailableText;
Res.Subst("SettingName", TempStr);
Res.Subst("SettingData", PackageLink);
Res.Subst("Extra", "");
ImportRows = ImportRows $ WebInclude(IncludeRows);
}
// Mutator Information
Res.Subst("SectionName", TableTitle[2]);
Res.Subst("SpecialInstructions", "");
ImportRows += WebInclude(IncludeSection);
for (i = 0; i < CurS.getMutatorLength(); i++)
ImportMutators.Add(string(i), CurS.getMutator(i));
for (i = 0; i < ImportMutators.Count(); i++)
{
TempStr = CurS.getMutator( int(ImportMutators.getItem(i)) );
for (j=0;j<CurS.getDataLength();j++)
{
CurS.getIDValue(j,MutatorName,Tmp);
if (Tmp ~= TempStr) break;
}
MutatorLocation = ProfileConn.FindRemoteZipLocation(TempStr,ProfileConn.ProfileServerAddress $ ProfileConn.RemoteProfilePath);
PackageLink = StringIf(MutatorLocation != "", "<a href=\""$MutatorLocation$"\" target=\"_blank\">"$MutatorName$"</a>", MutatorName);
TempStr = Stringif(CurS.MutRequired(TempStr), "<font color=\"red\">"$RequiredText$"</font>", AvailableText);
Res.Subst("SettingName", TempStr);
Res.Subst("SettingData", PackageLink);
Res.Subst("Extra", "");
ImportRows += WebInclude(IncludeRows);
}
// PlayInfo Information
Res.Subst("SectionName", TableTitle[4]);
Res.Subst("SpecialInstructions", "");
ImportRows += WebInclude(IncludeSection);
ImportRows = ImportRows $"<tr><td colspan=\"2\"> </td></tr>"$ GeneratePlayInfoRows(Req,Res,IncludeRows);
// Build Subst's
Res.Subst("ButtonName", "ImportRemoteProfile");
Res.Subst("ButtonValue", ButtonApplyImportProfile);
Res.Subst("PageCaption", LabelApplyImportProfile);
ImportProfileHTML = WebInclude(IncludeCaptionButton);
Res.Subst("TableRows", ImportRows);
Res.Subst("LadderTable", WebInclude(IncludeTable) $ ImportProfileHTML);
Tmp = CurS.getValue("ProfileName", PageCaption[0]);
if (LadderRules.GetRemainingMatches() > 0 && Tmp == LadderRules.Profiles[GetCurrentConfigIndex()].ProfileName)
Tmp = Tmp @ LabelNumberMatchesLeft @ string(LadderRules.GetRemainingMatches());
Res.Subst("Section", LinkImportProfile);
Res.Subst("SubTitle", Tmp);
Res.Subst("PageHelp", HelpImportProfile);
Res.Subst("PostAction", SubImportURI$"?SessionID="$CurS.getHash());
ShowPage(Res, MasterPage);
CleanupQuery();
}
function QuerySubExport(WebRequest Req, WebResponse Res)
{
local int i,j;
local PlayInfo TempPI;
local FileLog EProfile;
local Session CurS;
local string SID, Logname,
TempStr, Tmp,
dataname, datavalue,
ProfileIndex, NewGameType,
ExportRows, Location;
local class<GameInfo> GIClass;
local class<AccessControl> ACClass;
local class<Mutator> TempMut;
local array<class<Mutator> > MClass;
local class<Info> TempSA;
local array<class<Info> > SAClass;
local StringArray Mutators,GroupsOnly;
if (CanPerform("Lm"))
{
SID = Req.GetVariable("SessionID");
CurS = SMaster.getSession(SID,true);
ProfileIndex = Req.GetVariable("ProfileNameSelect", CurS.getValue("ProfileIndex"));
CreateSessionInfo(ProfileIndex,SID,True);
Logname = CurS.getValue("Logname",Req.GetVariable("TextInput"));
if (Logname == "")
Logname = CurS.getValue("ProfileName");
CurS.setValue("Logname",Logname,True);
for (i=0;i<CurS.getMutatorLength();i++)
{
TempStr = CurS.getMutator(i);
if (EpicPackage(TempStr))
continue;
if (Req.GetVariable("Save"$TempStr,"") != "")
SetLocation(TempStr,Req.GetVariable(TempStr));
}
for (i=0;i<CurS.getMapLength();i++)
{
TempStr = CurS.getMap(i);
if (EpicPackage(TempStr))
continue;
if (Req.GetVariable("Save"$TempStr,"") != "")
SetLocation(TempStr,Req.GetVariable(TempStr));
}
NewGameType = CurS.getValue("GameType");
if (NewGameType != "")
GIClass = class<GameInfo>(DynamicLoadObject(NewGameType,class'Class'));
if (GIClass==None)
{
ShowMessage(Res,ErrorGameClassTitle,ErrorGameClassText);
return;
}
TempStr = CurS.getValue("ACClass", Level.Game.AccessControlClass);
if (TempStr != "")
ACClass = class<AccessControl>(DynamicLoadObject(TempStr,class'Class'));
if (ACClass == None)
{
ShowMessage(Res,ErrorAccessControlTitle,ErrorAccessControlText);
return;
}
if (Req.GetVariable("Export","")!="")
{
// Write file locations to .ini
EProfile = Level.Spawn(class'FileLog');
if (EProfile == None)
{
ShowMessage(Res, ErrorText, ErrorExportingProfile);
return;
}
EProfile.OpenLog(RemoveStr(CurS.getValue("Logname")," "));
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));
for (i=0;i<CurS.getMapLength();i++)
{
TempStr = CurS.getMap(i);
if (Req.GetVariable(TempStr,"") != "")
Location = Chr(21) $ Req.GetVariable(TempStr);
else Location = "";
EProfile.Logf("Map:"$TempStr$Chr(21)$CurS.MapOrder(i)$Chr(21)$CurS.MapRequired(TempStr)$Location);
}
for (i=0;i<CurS.getSALength();i++)
{
TempStr = CurS.getServerActor(i);
for (j=0;j<ConfigM.ManagedActors.Length;j++)
if (string(ConfigM.ManagedActors[j].SAClass) ~= TempStr)
DataName = ConfigM.ManagedActors[j].SAName;
if (Req.GetVariable(TempStr,"") != "")
Location = Chr(21) $ Req.GetVariable(TempStr);
else Location = "";
EProfile.Logf("Mutator:"$DataName$Chr(21)$TempStr$Chr(21)$CurS.SARequired(TempStr)$Location);
}
for (i=0;i<CurS.getMutatorLength();i++)
{
TempStr = CurS.getMutator(i);
for (j=0;j<AllMutators.Length;j++)
if (AllMutators[j].ClassName == TempStr)
DataName = AllMutators[j].FriendlyName;
if (Req.GetVariable(TempStr,"") != "")
Location = Chr(21) $ Req.GetVariable(TempStr);
else Location = "";
EProfile.Logf("Mutator:"$DataName$Chr(21)$TempStr$Chr(21)$CurS.MutRequired(TempStr)$Location);
}
i=0;
j=0;
while (i<CurS.getDataLength())
{
CurS.getIdValue(i,dataname,datavalue);
if (InStr(dataname,".") != -1)
EProfile.Logf("Data:"$DataName$Chr(21)$DataValue);
i++;
}
EProfile.Destroy();
ShowMessage(Res, SuccessText, SuccessExportProfile$RemoveStr(LogName," ")$".txt");
return;
}
// Mutator Section
Mutators = new(None) class'SortedStringArray';
GroupsOnly = new(None) class'SortedStringArray';
for (i=0;i<CurS.getMutatorLength();i++)
{
TempStr = CurS.getMutator(i);
for (j=0;j<AllMutators.Length;j++)
if (TempStr ~= AllMutators[j].ClassName)
Mutators.Add(string(j), AllMutators[j].FriendlyName);
TempMut = class<Mutator>(DynamicLoadObject(TempStr,class'Class'));
if (TempMut != None)
MClass[MClass.Length] = TempMut;
}
Res.Subst("SectionName", TableTitle[2]);
Res.Subst("SpecialInstructions", "");
ExportRows += WebInclude(IncludeSection);
for (i = 0; i<Mutators.Count(); i++)
{
j = int(Mutators.GetItem(i));
Res.Subst("SettingName", AllMutators[j].FriendlyName);
if (EpicPackage(AllMutators[j].ClassName))
Res.Subst("SettingData", "");
else Res.Subst("SettingData", Textbox(AllMutators[j].ClassName,Min(Max(GetLongestURL(),16),64),128,GetLocation(AllMutators[j].ClassName)) $ " " $ SubmitButton("Save"$AllMutators[j].ClassName,ProfileButtonName[0]));
Res.Subst("Extra", "");
ExportRows += WebInclude(IncludeRows);
}
for (i=0;i<CurS.getSALength();i++)
{
TempStr = CurS.getServerActor(i);
if (TempStr != "")
{
TempSA = class<Info>(DynamicLoadObject(TempStr,class'class'));
if (TempSA != None)
SAClass[SAClass.Length] = TempSA;
}
}
TempPI = new(None) class'PlayInfo';
LoadThisPlayInfo(TempPI, GIClass, ACClass, MClass, SAClass);
Res.Subst("SectionName", TableTitle[3]);
Res.Subst("SpecialInstructions", "");
ExportRows += WebInclude(IncludeSection);
Res.Subst("SettingName", LabelMaxMaps);
TempStr = CurS.getValue("MaxMaps");
if (TempStr == "0")
TempStr = UnlimitedText;
Res.Subst("SettingData", TempStr);
Res.Subst("Extra", "<tr><td colspan=\"2\"> </td></tr>");
ExportRows += WebInclude(IncludeRows);
// Map Section
for (i=0;i<CurS.getMapLength();i++)
{
TempStr = CurS.getMap(i);
Res.Subst("SettingName", TempStr);
Res.Subst("Extra", "");
if (EpicPackage(TempStr))
Res.Subst("SettingData", "");
else Res.Subst("SettingData", Textbox(TempStr,Min(Max(GetLongestURL(),16),64),128,GetLocation(TempStr)) $ " " $ SubmitButton("Save"$TempStr,ProfileButtonName[0]));
ExportRows += WebInclude(IncludeRows);
}
// PlayInfo section
Res.Subst("SectionName", TableTitle[4]);
Res.Subst("SpecialInstructions", " ");
ExportRows += WebInclude(IncludeSection);
ExportRows += ("<tr><td colspan=\"2\"> </td></tr>" $ GeneratePlayInfoRows(Req, Res, IncludeRows));
ExportRows += ("<tr><td colspan=\"2\"> </td></tr><tr><td colspan=\"2\">"$LabelApplyExportProfile$"</td></tr><tr><td colspan=\"2\">"$SubmitButton("Export",ButtonApplyExportProfile)$"</td></tr>");
Res.Subst("TableRows", ExportRows);
Res.Subst("LadderTable", WebInclude(IncludeTable));
Tmp = CurS.getValue("ProfileName", PageCaption[0]);
if (LadderRules.GetRemainingMatches() > 0 && Tmp == LadderRules.Profiles[GetCurrentConfigIndex()].ProfileName)
Tmp = Tmp @ LabelNumberMatchesLeft @ string(LadderRules.GetRemainingMatches());
Res.Subst("Section", LinkExportProfile);
Res.Subst("PageHelp", HelpExportProfile);
Res.Subst("SubTitle", Tmp);
Res.Subst("PostAction", SubExportURI$"?SessionID="$SID);
ShowPage(Res, MasterPage);
}
else AccessDenied(Res);
}
//****************************************************************
//****************************************************************
// Query subpages for Add & Manage Modules
//
//
// Page 0
function QueryLadderManage(WebRequest Req, WebResponse Res)
{
local string HeaderRows, ManagementRows,
TempStr, Tmp, SID;
local bool bAdd, bModify, bCopy, bDelete, bImport, bExport;
local Session CurS;
local ProfileImporter ProfileConn;
if (CanPerform("Lm"))
{
SID = Req.GetVariable("SessionID");
CurS = SMaster.getSession(SID, True);
// Submit button was pressed
if (Req.GetVariable(ProfileButtonName[0], "") != "")
{
switch (Req.GetVariable("Actions",""))
{
case "Add":
bAdd = True;
QuerySubFrame(Req, Res);
break;
case "Modify":
bModify = True;
TempStr = Req.GetVariable("ProfileNameSelect");
if (TempStr == "")
{
StatusError(Res, ErrorNoProfilesExist);
break;
}
QuerySubFrame(Req, Res);
return;
case "Copy":
bCopy = True;
Tmp = Req.GetVariable("ProfileNameSelect");
if (Tmp == "")
StatusError(Res, ErrorNoProfilesExist);
TempStr = Req.GetVariable("TextInput");
if (TempStr == "")
{
StatusError(Res, ErrorCopyNoName);
break;
}
if (LadderRules.CopyProfile(int(Tmp),TempStr))
StatusOK(Res,SuccessCopyProfile);
else StatusError(Res, ErrorCopyFrom);
break;
case "Delete":
bDelete = True;
TempStr = Req.GetVariable("ProfileNameSelect");
if (TempStr != "")
{
if (LadderRules.RemoveProfile(int(TempStr)))
StatusOK(Res, SuccessDeleteProfile);
else StatusError(Res, ErrorDeletingProfile);
}
else StatusError(Res, ErrorNoProfilesExist);
break;
case "Import":
bImport = True;
TempStr = Req.GetVariable("TextInput","");
if (!(Left(TempStr,7) ~= "http://"))
{
StatusError(Res, ErrorBadURL);
break;
}
// Spawn class to handle network interaction to receive remote profile
ProfileConn = Level.Spawn(Class'ProfileImporter');
If (ProfileConn == None)
{
ShowMessage(Res, ErrorText, ImportClassSpawnError);
return;
}
// Assign local connection objects to importer class
ProfileConn.QueryPage = Self;
ProfileConn.QueryRequest = Req;
ProfileConn.QueryResponse = Res;
// Setting bDelayCleanup prevents the connection from being closed
// when QueryProfileImport() returns to Query()
// Set this prior to initializing connection, to ensure correct behavior
Res.Connection.bDelayCleanup = True;
// Initialize connection to foreign host, pass Importer class a Session
// object to allow it to build a profile config set.
ProfileConn.Connect(TempStr, CurS);
return;
case "Export":
bExport = True;
TempStr = Req.GetVariable("ProfileNameSelect", "");
if (TempStr == "")
{
StatusError(Res, ErrorNoProfilesExist);
break;
}
QuerySubExport(Req,Res);
return;
default:
bModify = True;
}
}
// Output code -
// TODO: move to .inc file
HeaderRows = "<tr><td nowrap>"$LabelChooseAction$"</td><td nowrap>"$LabelInputDescription$"</td></tr>";
ManagementRows += ("<tr><td nowrap>"$RadioButton("Actions", "Add", bAdd)$LabelAddProfile$"<br>");
ManagementRows += (RadioButton("Actions", "Modify", bModify)$LabelModifyProfile$"</td>");
ManagementRows += ("<td><select class=mini name='ProfileNameSelect'>"$GenerateSwitchProfileOptions(TempStr)$"</select> "$LabelSelectActions$"</td></tr>");
ManagementRows += ("<tr><td nowrap>"$RadioButton("Actions", "Copy", bCopy)$LabelCopyProfile$"<br>");
ManagementRows += (RadioButton("Actions", "Delete", bDelete)$LabelDeleteProfile$"</td>");
ManagementRows += ("<td nowrap>"$Textbox("TextInput",64,128)$" "$LabelTextboxActions$"</td></tr>");
ManagementRows += ("<tr><td nowrap>"$RadioButton("Actions", "Import", bImport)$LabelImportProfile$"<br>");
ManagementRows += (RadioButton("Actions", "Export", bExport)$LabelExportProfile$"</td>");
ManagementRows += ("<td>"$SubmitButton(ProfileButtonName[0],ProfileButtonValue[0])$"</td></tr>");
Res.Subst("TableTitle", TableTitle[0]);
Res.Subst("HeaderRow", HeaderRows);
Res.Subst("TableRows",ManagementRows);
Tmp = CurS.getValue("ProfileName", PageCaption[0]);
if (LadderRules.GetRemainingMatches() > 0 && Tmp == LadderRules.Profiles[GetCurrentConfigIndex()].ProfileName)
Tmp @= (LabelNumberMatchesLeft @ string(LadderRules.GetRemainingMatches()));
Res.Subst("Section", LabelManagement);
Res.Subst("PageHelp", HelpManageProfile);
Res.Subst("SubTitle", Tmp);
Res.Subst("LadderTable", WebInclude(IncludeTable));
Res.Subst("PostAction", ProfileManageURI);
ShowPage(Res, MasterPage);
}
else AccessDenied(Res);
}
// Page 1
function QuerySubGameType(WebRequest Req, WebResponse Res)
{
local int i;
local string DataName, DataValue, SID, NewName, OldName;
local string GameTypeRows, OldGameType, CommandLineRows;
local string GameTypeTable, CommandLineTable, ApplyTable;
local Session CurS;
local LadderProfiles LadderMaster;
if (CanPerform("Lm"))
{
SID = Req.GetVariable("SessionID");
CurS = SMaster.getSession(SID, true);
if (Req.GetVariable(CurS.getValue("ButtonName",""),"")!="")
{
NewName = Req.GetVariable("NewProfile",DefaultProfileName);
OldName = CurS.getValue("ProfileName");
if ((OldName != "" && !(OldName ~= NewName)) || OldName == "")
{
for (i=0;i<LadderRules.Profiles.Length;i++)
{
if (NewName ~= LadderRules.Profiles[i].ProfileName)
{
StatusError(Res, ErrorSameProfileName);
NewName = DefaultProfileName;
break;
}
}
}
CurS.setValue("ProfileName", NewName, true);
CurS.setValue("GameType", Req.GetVariable("NewGameType"), True, OldGameType);
if (!(OldGameType ~= CurS.getValue("GameType")))
{
CurS.ClearMaps();
// Reset all stored PlayInfo information
for (i=0;i<CurS.getDataLength();i++)
{
CurS.getIDValue(i,DataName,DataValue);
if (InStr(DataName, ".") != -1)
{
CurS.delValue(DataName);
i--;
}
}
}
}
Res.Subst("NewProfileName", CurS.getValue("ProfileName", DefaultProfileName));
GameTypeRows = WebInclude(IncludeProfileName);
for (i=0;i<AGameType.Count();i++)
{
Res.Subst("GameTypeClass", AGameType.GetItem(i));
Res.Subst("GameTypeName", AGameType.GetTag(i));
Res.Subst("Selected", StringIf(CurS.getValue("GameType") ~= AGameType.GetItem(i), " checked", ""));
GameTypeRows += WebInclude(IncludeGameType);
}
// Fill in caption table values
Res.Subst("PageCaption", CurS.getValue("PageCaption", PageCaption[1]));
Res.Subst("ButtonName", CurS.getValue("ButtonName", ProfileButtonName[1]));
Res.Subst("ButtonValue", CurS.getValue("ButtonValue", ProfileButtonValue[1]));
Res.Subst("TableRows", GameTypeRows);
Res.Subst("LadderTable", WebInclude(IncludeTable)$WebInclude(IncludeCaptionButton));
Res.Subst("PostAction", CurS.GetValue("CurrentPage"));
ShowPage(Res, SubFrameContent);
}
else AccessDenied(Res);
}
// Page 2
function QuerySubMutators(WebRequest Req, WebResponse Res)
{
local int i,j;
local bool bAllMuts,
bClearMuts,
bChecked;
local string MutatorRows,
SID, TempStr;
local Session CurS;
local StringArray Mutators, ServerActors;
local class<Mutator> MutClass;
if (CanPerform("Lm"))
{
SID = Req.GetVariable("SessionID");
CurS = SMaster.getSession(SID, true);
if (Req.GetVariable(CurS.getValue("ButtonName",""),"")!="")
{
bAllMuts = Req.GetVariable("AllowAllMutators")!="";
bClearMuts = Req.GetVariable("ClearAllMutators")!="";
// CurS.ClearMutators();
for (i=0;i<ConfigM.ManagedActors.Length;i++)
{
TempStr = string(ConfigM.ManagedActors[i].SAClass);
if (bAllMuts || (!bClearMuts && Req.GetVariable(TempStr,"") != ""))
CurS.setServerActor(TempStr, True, CurS.SARequired(TempStr));
else CurS.delServerActor(TempStr);
}
for (i=0;i<AllMutators.Length;i++)
{
if (bAllMuts || (!bClearMuts && (Req.GetVariable(AllMutators[i].ClassName,"")!="" || Req.GetVariable(AllMutators[i].GroupName)~=AllMutators[i].ClassName)))
CurS.setMutator(AllMutators[i].ClassName,true,CurS.MutRequired(AllMutators[i].ClassName));
else if (Req.GetVariable(AllMutators[i].GroupName) ~= "None")
CurS.setMutator(AllMutators[i].GroupName,true);
else
{
CurS.delMutator(AllMutators[i].ClassName);
CurS.delMutator(AllMutators[i].GroupName);
}
}
}
Mutators = new(None) class'SortedStringArray';
ServerActors = new(None) class'SortedStringArray';
// GroupsOnly = new(None) class'SortedStringArray';
for (i = 0; i<AllMutators.Length; i++)
{
MutClass = class<Mutator>(DynamicLoadObject(AllMutators[i].ClassName, class'Class'));
if (MutClass != None)
Mutators.Add(string(i),AllMutators[i].FriendlyName);
}
for (i=0;i<ConfigM.ManagedActors.Length;i++)
if (ConfigM.ManagedActors[i].SAClass != None)
ServerActors.Add(string(i),ConfigM.ManagedActors[i].SAName);
// Uncomment this to allow mutators to be grouped according to MutatorGroup
/*
CreateFullMutatorList(Mutators,GroupsOnly);
for (i=0;i<CurS.GetMutatorLength();i++)
{
k = 0-1;
for (j=0;j<AllMutators.Length;j++)
if (CurS.GetMutator(i) ~= AllMutators[j].ClassName)
break;
if (j<AllMutators.Length) k = GroupsOnly.FindItemId(string(j));
if (k >= 0)
{
for (z=0;z<TempA.Length;z++)
{
if (TempA[z] ~= AllMutators[j].GroupName)
{
bAllMuts = True;
break;
}
}
if (!bAllMuts) TempA[TempA.Length] = AllMutators[j].GroupName;
}
if (bAllMuts)
break;
}
lastgroup = "";
thisgroup = "";
nextgroup = "";
MutatorRows="";
for (i=0;i<GroupsOnly.Count();i++)
{
j=int(GroupsOnly.GetItem(i));
if (AllMutators[j].GroupName=="")
thisgroup="Z"$string(z++);
else thisgroup = AllMutators[j].GroupName;
if ( (i + 1) == GroupsOnly.Count())
nextgroup = "";
else
{
// Assign nextgroup to the next mutators group
k = int(GroupsOnly.GetItem(i + 1));
if (AllMutators[k].GroupName=="")
nextgroup="Z"$string(z);
else nextgroup = AllMutators[k].GroupName;
}
Res.Subst("GroupName", thisgroup);
Res.Subst("MutatorClass", AllMutators[j].ClassName);
Res.Subst("MutatorName", AllMutators[j].FriendlyName);
Res.Subst("MutatorDesc", AllMutators[j].Description);
if ((lastgroup != thisgroup) && (thisgroup == nextgroup)) // and the next mut is in the same group as this one
{
if (bAllMuts||CurS.HasMutator(thisgroup)) Res.Subst("Checked", "checked");
MutatorRows = MutatorRows$WebInclude("current_mutators_group");
}
else
{
if (CurS.HasMutator(AllMutators[j].ClassName) && !bAllMuts) Res.Subst("Checked", "checked"); else Res.Subst("Checked", "");
MutatorRows = MutatorRows$WebInclude("current_mutators_group_row");
}
lastgroup=thisgroup;
}
*/
bAllMuts = True;
for (i = 0; i<ServerActors.Count(); i++)
{
TempStr = ""; bChecked = False;
j = int(ServerActors.GetItem(i));
if (CurS.HasServerActor(string(ConfigM.ManagedActors[j].SAClass)))
bChecked = True;
else if (bAllMuts) bAllMuts = False;
Res.Subst("Content", Checkbox(string(ConfigM.ManagedActors[j].SAClass),bChecked) $ " " $ ServerActors.GetTag(i));
TempStr = WebInclude(NowrapLeft);
Res.Subst("Content", ConfigM.ManagedActors[j].SADescription);
Res.Subst("RowContent", TempStr $ WebInclude(CellLeft));
MutatorRows += WebInclude(RowLeft);
}
for (i = 0; i<Mutators.Count(); i++)
{
TempStr = ""; bChecked = False;
j = int(Mutators.GetItem(i));
if (CurS.HasMutator(AllMutators[j].ClassName))
bChecked = True;
else if (bAllMuts) bAllMuts = False;
Res.Subst("Content", CheckBox(AllMutators[j].ClassName, bChecked) $ " " $ AllMutators[j].FriendlyName);
TempStr = WebInclude(NowrapLeft);
Res.Subst("Content", AllMutators[j].Description);
Res.Subst("RowContent", TempStr $ WebInclude(CellLeft));
MutatorRows += WebInclude(RowLeft);
}
if (bAllMuts)
Res.Subst("Content", Checkbox("ClearAllMutators", False)@LabelUncheckAllMutator);
else
Res.Subst("Content", Checkbox("AllowAllMutators", False)@LabelCheckAllMutator);
Res.Subst("SpanLength", "2");
Res.Subst("SpanContent", " ");
Res.Subst("RowContent", WebInclude(CellColSpan));
MutatorRows += WebInclude(RowLeft);
Res.Subst("RowContent", WebInclude(CellLeft));
MutatorRows += WebInclude(RowLeft);
Res.Subst("TableRows", MutatorRows);
// Fill in caption table values
Res.Subst("PageCaption", CurS.getValue("PageCaption", PageCaption[2]));
Res.Subst("ButtonName", CurS.getValue("ButtonName", ProfileButtonName[2]));
Res.Subst("ButtonValue", CurS.getValue("ButtonValue", ProfileButtonValue[2]));
Res.Subst("LadderTable", WebInclude(IncludeTable)$WebInclude(IncludeCaptionButton));
Res.Subst("PostAction", CurS.GetValue("CurrentPage"));
ShowPage(Res, SubFrameContent);
}
else AccessDenied(Res);
}
// Page3
function QuerySubMaps(WebRequest Req, WebResponse Res)
{
local int i;
local string SID,
MapRows,
TempStr, Temp,
CheckString;
local bool bAllMaps,
bClearMaps,
bChecked;
local Session CurS;
local StringArray SortedMaps;
local array<string> TempMaps;
local class<GameInfo> GIClass;
if (CanPerform("Lm"))
{
SID = Req.GetVariable("SessionID");
CurS = SMaster.getSession(SID);
TempStr = CurS.getValue("GameType");
if (TempStr != "")
GIClass = class<GameInfo>(DynamicLoadObject(TempStr,class'Class'));
if (GIClass == None)
{
ShowFramedMessage(Res,ErrorGameClassText,True);
return;
}
// Build a string array of maps valid for this gametype.
GIClass.static.LoadMapList(GIClass.default.MapPrefix, TempMaps);
if (Req.GetVariable(CurS.getValue("ButtonName",""),"")!="")
{
bAllMaps = Req.GetVariable("AllowAllMaps","")!="";
bClearMaps = Req.GetVariable("ClearAllMaps","")!="";
for (i=0;i<TempMaps.Length;i++)
if (bAllMaps || (!bClearMaps && Req.GetVariable(TempMaps[i])!=""))
CurS.setMap(TempMaps[i],0,True,CurS.MapRequired(TempMaps[i]));
else CurS.delMap(TempMaps[i]);
}
// Add the map name array to a sorted string array for sorting
SortedMaps = new(None) class'SortedStringArray';
for(i=0;i<TempMaps.Length;i++)
SortedMaps.Add(string(i),TempMaps[i]);
bAllMaps = True;
// Now build the map rows
for (i=0;i<SortedMaps.Count();i++)
{
Temp = ""; bChecked = False;
TempStr = SortedMaps.GetTag(i);
if (CurS.HasMap(TempStr))
bChecked = True;
else if (bAllMaps) bAllMaps = False;
Res.Subst("Content", Checkbox(TempStr, bChecked) $ " " $ TempStr);
Res.Subst("RowContent", WebInclude(CellLeft));
// Build string for javascript function
if (CheckString!="")
CheckString += "','";
CheckString += TempStr;
MapRows += WebInclude(RowLeft);
}
// Fill Javascript substs
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>");
Res.Subst("JCheck"," onClick=\"CheckMaps('AllowAllMaps','"$CheckString$"');return document.MM_returnValue\"");
Res.Subst("Checked","");
if (bAllMaps)
Res.Subst("Content", Checkbox("ClearAllMaps", False) @ LabelUncheckAllMap);
else Res.Subst("Content", Checkbox("AllowAllMaps", False) @ LabelCheckAllMap);
Res.Subst("SpanLength", "2");
Res.Subst("SpanContent", " ");
Res.Subst("RowContent", WebInclude(CellColSpan));
MapRows += WebInclude(RowLeft);
Res.Subst("RowContent", WebInclude(CellLeft));
MapRows += WebInclude(RowLeft);
// Set ladder_caption_table subst's
Res.Subst("PageCaption", CurS.getValue("PageCaption",PageCaption[3]));
Res.Subst("ButtonName", CurS.getValue("ButtonName", ProfileButtonName[3]));
Res.Subst("ButtonValue", CurS.getValue("ButtonValue", ProfileButtonValue[3]));
Res.Subst("TableRows", MapRows);
Res.Subst("LadderTable", WebInclude(IncludeTable)$WebInclude(IncludeCaptionButton));
Res.Subst("PostAction", CurS.getValue("CurrentPage"));
ShowPage(Res, SubFrameContent);
}
else AccessDenied(Res);
}
// Page 4
function QuerySubRules(WebRequest Req, WebResponse Res)
{
local int i;
local string TempStr,
SID;
local Session CurS;
local PlayInfo TempPI;
local class<Mutator> TempClass;
local class<GameInfo> GIClass;
local class<AccessControl> ACClass;
local array<class<Mutator> > MClass;
local class<Info> TempSA;
local array<class<Info> > SAClass;
if (CanPerform("Lm"))
{
SID = Req.GetVariable("SessionID");
CurS = SMaster.GetSession(SID);
TempStr = CurS.getValue("GameType");
if (TempStr != "")
GIClass = class<GameInfo>(DynamicLoadObject(TempStr,class'Class'));
if (GIClass == None)
{
ShowFramedMessage(Res,ErrorGameClassText,True);
return;
}
TempStr = CurS.getValue("ACClass", Level.Game.AccessControlClass);
if (TempStr != "")
ACClass = class<AccessControl>(DynamicLoadObject(TempStr,class'Class'));
if (ACClass == None)
{
ShowFramedMessage(Res,ErrorAccessControlText,True);
return;
}
if (Req.GetVariable(CurS.getValue("ButtonName",""),"")!="")
{
for (i=0;i<CurS.GetMutatorLength();i++)
{
TempStr = CurS.getMutator(i);
if (TempStr != "")
{
TempClass = class<Mutator>(DynamicLoadObject(TempStr,class'Class'));
if (TempClass != None)
MClass[MClass.Length] = TempClass;
}
}
TempPI = new(None) class'PlayInfo';
for (i=0;i<CurS.getSALength(); i++)
{
TempStr = CurS.getServerActor(i);
if (TempStr != "")
{
TempSA = class<Info>(DynamicLoadObject(TempStr,class'Class'));
if (TempSA != None)
SAClass[SAClass.Length] = TempSA;
}
}
LoadThisPlayInfo(TempPI, GIClass, ACClass, MClass, SAClass);
for (i=0;i<TempPI.Settings.Length;i++)
{
if (!SettingIsAllowed(TempPI.Settings[i].SecLevel)) continue;
TempStr = Req.GetVariable(TempPI.Settings[i].SettingName,TempPI.Settings[i].Value);
if (TempPI.Settings[i].RenderType == "Text")
CheckSettingValue(TempPI.Settings[i].Data, TempStr);
CurS.setValue(TempPI.Settings[i].SettingName,TempStr,true);
}
}
Res.Subst("TableRows", GeneratePlayInfoRows(Req, Res, "defaults_row"));
// Set ladder_caption_table subst's
Res.Subst("PageCaption", CurS.getValue("PageCaption",PageCaption[4]));
Res.Subst("ButtonName", CurS.getValue("ButtonName", ProfileButtonName[4]));
Res.Subst("ButtonValue", CurS.getValue("ButtonValue", ProfileButtonValue[4]));
Res.Subst("LadderTable", WebInclude(IncludeTable)$WebInclude(IncludeCaptionButton));
Res.Subst("PostAction", CurS.getValue("CurrentPage"));
ShowPage(Res, SubFrameContent);
}
else AccessDenied(Res);
}
// Page 5
function QuerySubReview(WebRequest Req, WebResponse Res)
{
local int i,j,k,z;
local string SID,
TempStr, TempSA,
ReviewRows,
thisgroup, lastgroup, nextgroup;
local Session CurS;
local StringArray Mutators, GroupsOnly;
local class<Mutator> TempClass;
local class<Info> TempSAClass;
local class<GameInfo> GIClass;
local class<AccessControl> ACClass;
local array<class<Mutator> > MClass;
if (CanPerform("Lm"))
{
SID = Req.GetVariable("SessionID");
CurS = SMaster.getSession(SID);
TempStr = CurS.getValue("GameType");
if (TempStr != "")
GIClass = class<GameInfo>(DynamicLoadObject(TempStr,class'Class'));
if (GIClass == None)
{
ShowFramedMessage(Res,ErrorGameClassText,True);
return;
}
TempStr = CurS.getValue("ACClass",Level.Game.AccessControlClass);
if (TempStr != "")
ACClass = class<AccessControl>(DynamicLoadObject(TempStr,class'Class'));
if (ACClass == None)
{
ShowFramedMessage(Res,ErrorAccessControlText,True);
return;
}
Mutators = new(None) class'SortedStringArray';
GroupsOnly = new(None) class'SortedStringArray';
for (i = 0; i<AllMutators.Length; i++)
{
if (CurS.HasMutator(AllMutators[i].ClassName)||CurS.HasMutator(AllMutators[i].GroupName))
{
TempClass = class<Mutator>(DynamicLoadObject(AllMutators[i].ClassName, class'Class'));
if (TempClass != None)
{
MClass[MClass.Length] = TempClass;
Mutators.Add(string(i),AllMutators[i].FriendlyName);
}
}
}
CreateFullMutatorList(Mutators,GroupsOnly);
lastgroup = ""; thisgroup = ""; nextgroup = "";
Res.Subst("SectionName", TableTitle[2]);
Res.Subst("SpecialInstructions", LabelRequiredMutators);
ReviewRows += WebInclude(IncludeSection);
for (i=0;i<GroupsOnly.Count();i++)
{
j=int(GroupsOnly.GetItem(i));
if (AllMutators[j].GroupName=="")
thisgroup="Z"$string(z++);
else thisgroup = AllMutators[j].GroupName;
if ( (i + 1) == GroupsOnly.Count())
nextgroup = "";
else
{
// Assign nextgroup to the next mutators group
k = int(GroupsOnly.GetItem(i + 1));
if (AllMutators[k].GroupName=="")
nextgroup="Z"$string(z);
else nextgroup = AllMutators[k].GroupName;
}
Res.Subst("GroupName", thisgroup);
Res.Subst("MutatorClass", AllMutators[j].ClassName);
Res.Subst("MutatorName", AllMutators[j].FriendlyName);
Res.Subst("MutatorDesc", AllMutators[j].Description);
if ((lastgroup != thisgroup) && (thisgroup == nextgroup)) // and the next mut is in the same group as this one
{
Res.Subst("Checked", " checked");
ReviewRows += WebInclude("current_mutators_group");
}
Res.Subst("Checked", StringIf(CurS.MutRequired(AllMutators[j].ClassName), " checked", ""));
ReviewRows += WebInclude("current_mutators_group_row");
lastgroup=thisgroup;
}
for (i = 0; i<Mutators.Count(); i++)
{
TempStr = "";
j = int(Mutators.GetItem(i));
Res.Subst("Content", CheckBox(AllMutators[j].ClassName, CurS.MutRequired(AllMutators[j].ClassName)) $ " " $ AllMutators[j].FriendlyName);
TempStr = WebInclude(NowrapLeft);
Res.Subst("Content", AllMutators[j].Description);
Res.Subst("RowContent", TempStr $ WebInclude(CellLeft));
ReviewRows += WebInclude(RowLeft);
}
Mutators.Reset();
for (i = 0; i < ConfigM.ManagedActors.Length; i++)
{
TempSA = string(ConfigM.ManagedActors[i].SAClass);
if (CurS.HasServerActor(TempSA))
{
TempSAClass = class<Info>(DynamicLoadObject(TempSA,class'Class'));
if (TempSAClass != None)
Mutators.Add(string(i),ConfigM.ManagedActors[i].SAName);
}
}
lastgroup = "";
Res.Subst("SpanLength", "2");
Res.Subst("SpanContent", " ");
Res.Subst("RowContent", WebInclude(CellColSpan));
lastgroup = WebInclude(RowLeft);
ReviewRows += lastgroup;
for (i=0;i<Mutators.Count();i++)
{
TempStr = "";
j = int(Mutators.GetItem(i));
Res.Subst("Content", Checkbox(string(ConfigM.ManagedActors[j].SAClass), CurS.SARequired(string(ConfigM.ManagedActors[j].SAClass))) $ " " $ Mutators.GetTag(i));
TempStr = WebInclude(NowrapLeft);
Res.Subst("Content", ConfigM.ManagedActors[j].SADescription);
Res.Subst("RowContent", TempStr $ WebInclude(CellLeft));
ReviewRows += WebInclude(RowLeft);
}
Res.Subst("SectionName", TableTitle[3]);
Res.Subst("SpecialInstructions", LabelRequiredMaps);
ReviewRows += WebInclude(IncludeSection);
Res.Subst("SettingName", LabelMaxMaps);
Res.Subst("SettingData", Textbox("MaxMaps", 3, 3, CurS.getValue("MaxMaps","3")));
Res.Subst("Extra", lastgroup);
ReviewRows += WebInclude(IncludeRows);
for (i=0;i<CurS.GetMapLength();i++)
{
Res.Subst("SettingName", CurS.getMap(i));
Res.Subst("Extra", "");
Res.Subst("SettingData", Checkbox(CurS.getMap(i), CurS.MapRequired(CurS.getMap(i))));
ReviewRows += WebInclude(IncludeRows);
}
Res.Subst("SectionName", TableTitle[4]);
Res.Subst("SpecialInstructions", LabelPlayInfo);
Res.Subst("Extra", lastgroup);
ReviewRows += WebInclude(IncludeSection);
ReviewRows += (lastgroup $ GeneratePlayInfoRows(Req, Res, IncludeRows));
Res.Subst("TableRows", ReviewRows);
// Set ladder_caption_table subst's
Res.Subst("PageCaption", CurS.getValue("PageCaption",PageCaption[5]));
Res.Subst("ButtonName", CurS.getValue("ButtonName", ProfileButtonName[5]));
Res.Subst("ButtonValue", CurS.getValue("ButtonValue", ProfileButtonValue[5]));
Res.Subst("LadderTable", WebInclude(IncludeTable)$WebInclude(IncludeCaptionButton));
Res.Subst("PostAction", SubSavedURI$"?SessionID="$SID);
Res.Subst("NewTarget", " target=\"_parent\"");
ShowPage(Res, SubFrameContent);
}
else AccessDenied(Res);
}
// Page 6
function QuerySubSaved(WebRequest Req, WebResponse Res)
{
local int i,k, x;
local string SID,
tmp, tmp1,
TempStr;
local Session CurS;
local PlayInfo TempPI;
local ProfileConfigSet TempPCS;
local array<string> TempArr;
local array<class<Mutator> > MClass;
local array<class<Info> > SAClass;
local class<Mutator> MutClass;
local class<GameInfo> GIClass;
local class<AccessControl> ACClass;
local class<Info> TempSA;
SID = Req.GetVariable("SessionID");
CurS = SMaster.getSession(SID);
if (CanPerform("Lm"))
{
TempStr = CurS.getValue("GameType");
if (TempStr != "")
GIClass = class<GameInfo>(DynamicLoadObject(TempStr,class'Class'));
if (GIClass == None)
{
ShowFramedMessage(Res,ErrorGameClassText,True);
return;
}
TempStr = CurS.getValue("ACClass",Level.Game.AccessControlClass);
if (TempStr != "")
ACClass = class<AccessControl>(DynamicLoadObject(TempStr,class'Class'));
if (ACClass == None)
{
ShowFramedMessage(Res,ErrorAccessControlText,True);
return;
}
TempPI = new(None) class'PlayInfo';
// We are managing an existing profile
if (CurS.hasData("ProfileIndex"))
{
k = int(CurS.getValue("ProfileIndex"));
TempPCS = LadderRules.LadderProfiles[k];
if (LadderRules.Profiles[k].ProfileName != CurS.getValue("ProfileName"))
{
LadderRules.Profiles[k].ProfileName = CurS.getValue("ProfileName");
LadderRules.AllLadderProfiles.Remove(LadderRules.AllLadderProfiles.FindItemId(string(k)));
LadderRules.AllLadderProfiles.Add(string(k),LadderRules.Profiles[k].ProfileName);
LadderRules.SaveConfig();
}
if (TempPCS.StartEdit())
{
TempPCS.SetGameType(CurS.getValue("GameType"));
TempPCS.EndEdit(False);
}
}
else TempPCS = LadderRules.AddProfile(CurS.getValue("ProfileName"), CurS.getValue("GameType"));
if (TempPCS.StartEdit())
{
for (i=0;i<AllMutators.Length;i++)
{
MutClass = class<Mutator>(DynamicLoadObject(AllMutators[i].ClassName,class'Class'));
if (MutClass != None)
{
if ((Req.GetVariable(AllMutators[i].ClassName,"")!="")||(Req.GetVariable(AllMutators[i].GroupName,"")~=AllMutators[i].ClassName))
CurS.setMutator(AllMutators[i].ClassName,true,true);
else CurS.setMutator(AllMutators[i].ClassName,false);
if (CurS.HasMutator(AllMutators[i].ClassName))
{
MClass[MClass.Length] = MutClass;
TempPCS.AddProfileMutator(AllMutators[i].ClassName,CurS.MutRequired(AllMutators[i].ClassName));
}
else TempPCS.DelProfileMutator(AllMutators[i].ClassName);
}
}
for (i=0;i<ConfigM.ManagedActors.Length;i++)
{
TempSA = ConfigM.ManagedActors[i].SAClass;
if (TempSA != None)
{
TempStr = string(ConfigM.ManagedActors[i].SAClass);
if (Req.GetVariable(TempStr,"") != "")
CurS.setServerActor(TempStr, True, True);
else CurS.setServerActor(TempStr, False);
if (CurS.HasServerActor(TempStr))
{
SAClass[SAClass.Length] = TempSA;
TempPCS.AddProfileServerActor(TempStr,CurS.SARequired(TempStr));
}
else TempPCS.DelProfileServerActor(TempStr);
}
}
x = LoadThisPlayInfo(TempPI, GIClass, ACClass, MClass, SAClass);
if (x >= 0)
{
ShowFramedMessage(Res, ErrorLoadingPlayInfoText[x],True);
return;
}
CurS.setValue("MaxMaps",Req.GetVariable("MaxMaps"),true);
TempPCS.MaxMaps = int(CurS.getValue("MaxMaps"));
GIClass.static.LoadMapList(GIClass.default.MapPrefix, TempArr);
for (i=0;i<TempArr.Length;i++)
{
if (Req.GetVariable(TempArr[i],"")!="")
CurS.setMap(TempArr[i],0,true,true);
else CurS.setMap(TempArr[i],0,false,false);
if (CurS.HasMap(TempArr[i]))
TempPCS.AddProfileMap(TempArr[i], CurS.MapRequired(TempArr[i]));
else TempPCS.DelProfileMap(TempArr[i]);
}
for (i=0;i<TempPI.Settings.Length;i++)
{
if (TempPI.Settings[i].SecLevel > CurAdmin.MaxSecLevel()) continue;
tmp = ""; tmp1="";
if (CurS.getIdValue(i,tmp,tmp1) == -1)
break;
if (!TempPCS.SetProfileNamedParam(TempPI.Settings[i].SettingName, CurS.getValue(TempPI.Settings[i].SettingName,TempPI.Settings[i].Value)))
TempPCS.SetProfileParam(TempPCS.Count(),TempPI.Settings[i].SettingName,CurS.getValue(TempPI.Settings[i].SettingName,TempPI.Settings[i].Value));
}
TempPCS.EndEdit(true);
}
else
{
StatusError(Res,ErrorSavingProfile);
QuerySubReview(Req, Res);
return;
}
Tmp = CurS.getValue("ProfileName", PageCaption[0]);
if (LadderRules.GetRemainingMatches() > 0 && Tmp == LadderRules.Profiles[GetCurrentConfigIndex()].ProfileName)
Tmp = Tmp @ LabelNumberMatchesLeft @ string(LadderRules.GetRemainingMatches());
Res.Subst("SubTitle", Tmp);
ShowMessage(Res, TableTitle[6], PageCaption[6]);
return;
}
else AccessDenied(Res);
}
defaultproperties
{
EpicPackages(0)="BR-Anubis"
EpicPackages(1)="BR-Bifrost"
EpicPackages(2)="BR-Disclosure"
EpicPackages(3)="BR-IceFields"
EpicPackages(4)="BR-Skyline"
EpicPackages(5)="BR-Slaughterhouse"
EpicPackages(6)="BR-TwinTombs"
EpicPackages(7)="CTF-Chrome"
EpicPackages(8)="CTF-Citadel"
EpicPackages(9)="CTF-December"
EpicPackages(10)="CTF-Face3"
EpicPackages(11)="CTF-Geothermal"
EpicPackages(12)="CTF-Lostfaith"
EpicPackages(13)="CTF-Magma"
EpicPackages(14)="CTF-Maul"
EpicPackages(15)="CTF-Orbital2"
EpicPackages(16)="DM-Antalus"
EpicPackages(17)="DM-Asbestos"
EpicPackages(18)="DM-Compressed"
EpicPackages(19)="DM-Curse3"
EpicPackages(20)="DM-Flux2"
EpicPackages(21)="DM-Gael"
EpicPackages(22)="DM-Inferno"
EpicPackages(23)="DM-Insidious"
EpicPackages(24)="DM-Leviathan"
EpicPackages(25)="DM-Oceanic"
EpicPackages(26)="DM-Phobos2"
EpicPackages(27)="DM-Plunge"
EpicPackages(28)="DM-Serpentine"
EpicPackages(29)="DM-TokaraForest"
EpicPackages(30)="DM-TrainingDay"
EpicPackages(31)="DOM-Core"
EpicPackages(32)="DOM-OutRigger"
EpicPackages(33)="DOM-Ruination"
EpicPackages(34)="DOM-ScorchedEarth"
EpicPackages(35)="DOM-SepukkuGorge"
EpicPackages(36)="DOM-Suntemple"
EpicPackages(37)="Entry"
EpicPackages(38)="NvidiaLogo"
EpicPackages(39)="TUT-BR"
EpicPackages(40)="TUT-CTF"
EpicPackages(41)="TUT-DM"
EpicPackages(42)="TUT-DOM"
EpicPackages(43)="UT2-intro"
EpicPackages(44)="VehicleDemo"
EpicPackages(45)="endgame"
EpicPackages(46)="Core"
EpicPackages(47)="Editor"
EpicPackages(48)="Engine"
EpicPackages(49)="Fire"
EpicPackages(50)="GamePlay"
EpicPackages(51)="IpDrv"
EpicPackages(52)="UWeb"
EpicPackages(53)="UnrealEd"
EpicPackages(54)="UnrealGame"
EpicPackages(55)="Vehicles"
EpicPackages(56)="XAdmin"
EpicPackages(57)="XEffects"
EpicPackages(58)="XGame"
EpicPackages(59)="XGame_rc"
EpicPackages(60)="XInterface"
EpicPackages(61)="XPickups"
EpicPackages(62)="XPickups_rc"
EpicPackages(63)="XWeapons"
EpicPackages(64)="XWeapons_rc"
EpicPackages(65)="XWebAdmin"
EpicPackages(66)="BR-DE-ElecFields"
EpicPackages(67)="CTF-DE-ElecFields"
EpicPackages(68)="CTF-DE-LavaGiant2"
EpicPackages(69)="DM-DE-Grendelkeep"
EpicPackages(70)="DM-DE-Ironic"
EpicPackages(71)="DM-DE-Osiris2"
EpicPackages(72)="BR-Canyon"
EpicPackages(73)="CTF-Avaris"
EpicPackages(74)="DM-1on1-Crash"
EpicPackages(75)="DM-1on1-Mixer"
EpicPackages(76)="DM-Icetomb"
EpicPackages(77)="DM-Injector"
EpicPackages(78)="DM-IronDeity"
EpicPackages(79)="DM-Rustatorium"
EpicPackages(80)="DOM-Junkyard"
EpicPackages(81)="SkaarjPack"
EpicPackages(82)="SkaarjPack_rc"
EpicPackages(83)="BonusPack"
EpicPackages(84)="OGGPlayer"
MasterPage="ladder"
SubFrame="ladder_frame"
SubFrameMenu="ladder_frame1"
SubFrameContent="ladder_frame2"
IncludeTable="ladder_table"
IncludeSection="ladder_section"
IncludeRows="ladder_rows"
IncludeCaptionButton="ladder_caption"
IncludeMapSelect="ladder_mapselect"
IncludeProfileName="ladder_name"
IncludeGameType="ladder_gametype"
IncludeCheckBox="ladder_checkrow"
IncludeSwitch="ladder_switch"
ProfileViewURI="ladder_view"
ProfileEditURI="ladder_edit"
ProfileMenuURI="ladder_menu"
ProfileSwitchURI="ladder_switch"
ProfileManageURI="ladder_manage"
SubFrameURI="profile_management"
SubFrameMenuURI="management_menu"
SubMapsURI="ladder_maps"
SubSavedURI="ladder_save"
SubRulesURI="ladder_rules"
SubReviewURI="ladder_review"
SubGametypeURI="management_game_type"
SubMutatorsURI="ladder_mutators"
SubImportURI="profile_import"
SubExportURI="profile_export"
LinkEditProfile="Edit Profiles"
LinkViewProfile="View Profiles"
LinkSwitchProfile="Switch Profiles"
LinkManageProfile="Manage Profiles"
LinkImportProfile="Import Profile"
LinkExportProfile="Export Profile"
TableTitle(0)="Profile Management Portal"
TableTitle(1)="Profile GameType"
TableTitle(2)="Profile Mutators"
TableTitle(3)="Profile Maps"
TableTitle(4)="Profile Settings"
TableTitle(5)="Review Profile"
TableTitle(6)="Profile Saved"
PageCaption(0)="No Profile Loaded"
PageCaption(1)="Select the gametype that will be associated with this profile."
PageCaption(2)="Select the mutators that will be available in this profile."
PageCaption(3)="Select the maps that will be available in this profile."
PageCaption(4)="Select the settings that will be associated with this profile."
PageCaption(5)="Review all settings for accuracy before saving to file."
PageCaption(6)="Settings were saved successfully!"
ProfileButtonName(0)="Save Location"
ProfileButtonName(1)="GameType"
ProfileButtonName(2)="Mutators"
ProfileButtonName(3)="Maps"
ProfileButtonName(4)="Rules"
ProfileButtonName(5)="Review"
ProfileButtonName(6)="Saved"
ProfileButtonValue(0)="Proceed"
ProfileButtonValue(1)="Set GameType"
ProfileButtonValue(2)="Set Mutators"
ProfileButtonValue(3)="Set Maps"
ProfileButtonValue(4)="Set Rules"
ProfileButtonValue(5)="Save Profile"
ProfileButtonValue(6)="Profile Saved"
MapText="Maps"
ErrorText="Error"
MutatorText="Mutators"
RequiredText="Required"
AvailableText="Available"
UnlimitedText="Unlimited"
FollowingMaps="The following maps"
AreAssignedText="are assigned to this profile and cannot be removed."
AreAvailableText="may be added to this profile."
FollowingMutators="The following mutators"
CommandLineOptionsTitle="Command Line Options"
ButtonLoadProfile="Load Profile"
ButtonDeleteProfile="Delete Profile"
ButtonPreviewProfile="Load Profile"
ButtonApplyImportProfile="Import Profile"
ButtonApplyExportProfile="Export Profile"
ButtonApplyProfileChanges="Apply Profile Changes"
LabelCopyProfile="Copy Profile"
LabelDeleteProfile="Delete Profile"
LabelImportProfile="Import Profile"
LabelExportProfile="Export Profile"
LabelAddProfile="Add Profile"
LabelSelectActions="(Copy, Modify, Delete, Export)"
LabelTextboxActions="(Add, Copy, Import)"
LabelPlayInfo="Profile Game Parameters"
LabelGeneralProfile="General Profile Information"
LabelGameType="Profile Game Type"
LabelProfileName="Profile Name"
LabelAccessControl="Profile Access Control"
LabelChooseAction="Choose action to perform:"
LabelManagement="Profile Management"
LabelInputDescription="Actions which require input from this field are listed on the right."
LabelMaxMaps="Maximum maps allowed in this profile's maplist"
LabelNumberGames="Number of matches (0 = unlimited)"
LabelCheckAllMap="Select all maps"
LabelRequiredMaps="Check each map that will be required (non-removable) for this profile."
LabelUncheckAllMap="Deselect all maps"
LabelChangeMaplist="Changes to the maplist are saved immediately."
LabelCheckAllMutator="Select all mutators"
LabelRequiredMutators="Check each mutator that will be required (non-removable) for this profile."
LabelNumberMatchesLeft="Matches Remaining:"
LabelUncheckAllMutator="Deselect all mutators"
LabelDelayProfileChange="Check to delay applying profile until end of current match."
LabelApplyImportProfile="Click Apply Import to make this profile available in your server's list of profiles."
LabelApplyExportProfile="Click Apply Export to save this profile to a .txt file."
LabelModifyProfile="Modify Profile"
SuccessText="Success"
SuccessDeleteProfile="Profile successfully deleted! It will no longer appear in your list of available profiles."
SuccessExportProfile="Profile exported successfully! Exported profile has been saved to the server's System folder as "
SuccessImportProfile="Profile imported successfully! The remote profile will now appear in your list of available profiles."
SuccessImportProfileTitle="Import Successful!"
SuccessCopyProfile="Profile copied successfully! Copied profile will now be available in your list of available profiles."
SuccessSwitchProfile="Profile successfully applied! Changes take effect at the end of the current match."
ErrorLoadingPlayInfoText(0)="Error while loading playinfo. LoadThisPlayInfo() received bad playinfo object!"
ErrorLoadingPlayInfoText(1)="Error while loading playinfo. LoadThisPlayInfo() could not load incoming game class!"
ErrorLoadingPlayInfoText(2)="Error while loading playinfo. LoadThisPlayInfo() could not load associated access control!"
ErrorLoadingPlayInfoText(3)="Error while loading playinfo. LoadThisPlayInfo() had exception while loading mutators!"
ErrorLoadingPlayInfoText(4)="Error while loading playinfo. LoadThisPlayInfo() had exception while loading server actors!"
ErrorGameClassText="No gametype was selected, or the files required by this gametype do not exist on this server."
ErrorGameClassTitle="Invalid GameType"
ErrorAccessControlText="Exception while loading access control. Please double check the AccessControlClass= line of the [Engine.GameInfo] section of your server's .ini file."
ErrorAccessControlTitle="Invalid Access Control"
ErrorSameProfileName="Another profile already exists with that name. Please select a different name!"
ErrorRemoteMutator="Error loading mutator from remote profile. Could not find mutator package:"
ErrorRemoteServerActor="Error loading ServerActor from remote profile. Could not find ServerActor package:"
ErrorSavingProfile="Exception while saving new profile! Please resubmit save request."
ErrorDeletingProfile="Error deleting profile! Please check server log for details."
ErrorExportingProfile="Error exporting profile! Export class could not be spawned!"
ErrorNoProfilesExist="No profiles exist! Could not perform selected action!"
ErrorCopyFrom="Error copying profile. No Profile Found!"
ErrorCopyNoName="You must specify a unique name for the new profile!"
ErrorExcludeMapNotFound="Error! Exclude map not found:"
ErrorIncludeMapNotFound="Error! Include map not found:"
ErrorReplacingWebConnection="Exception replacing WebServer.AcceptClass! (Very bad) Please send an email to Evolution containing your server's ini and log files."
ImportClassSpawnError="Exception occured spawning connection class. Please try again!"
ImportProfileFailText="Error while importing profile. Please ensure you have all the files necessary to load this remote profile."
ImportProfileFailTitle="Import Failed!"
ErrorBind="Failed to bind port! Please try again!"
ErrorBadURL="URL must start with 'http://' !"
ErrorServer="Unspecified error while importing profile!"
ErrorResolve="URL could not be resolved!"
ErrorProfile="Attempted to import a file that does not contain a profile!"
ErrorTimeout="Timed out while waiting for response from foreign host!"
ErrorNotFound="Profile does not exist on remote server!"
ErrorForbidden="Remote profile could not be imported: Forbidden"
ErrorBadRequest="Request could not be processed by remote server!"
ErrorUnauthorized="Remote profile could not be imported: Unauthorized"
DefaultPage="ladder_main"
Title="Ladder"
}