1611 lines
47 KiB
Ucode
1611 lines
47 KiB
Ucode
/**
|
|
* Query Handler for changing the default settings. It will try to find settings
|
|
* handles for all gametypes and mutators. Custom gametypes have to implement a
|
|
* subclass of the Settings class as name it: <GameTypeClass>Settings.
|
|
* for example the gametype: FooBarQuuxGame has a settings class
|
|
* FooBarQuuxGameSettings. See "UTTeamGameSettings" for an example implementation.
|
|
*
|
|
* Copyright 2008 Epic Games, Inc. All Rights Reserved
|
|
* Copyright (C) 2011,2014 Tripwire Interactive LLC
|
|
*
|
|
* @author Michiel 'elmuerte' Hendriks
|
|
*/
|
|
class QHDefaults extends Object implements(IQueryHandler) config(WebAdmin)
|
|
dependson(WebAdminUtils);
|
|
|
|
`include(WebAdmin.uci)
|
|
|
|
struct ClassSettingsMapping
|
|
{
|
|
var string className;
|
|
var string settingsClass;
|
|
};
|
|
/**
|
|
* Mapping for classname to settings class. Will be used to resolve classnames
|
|
* for Settings classes that provide configuration possibilities for gametypes/
|
|
* mutators when it can not be automatically found.
|
|
*/
|
|
var config array<ClassSettingsMapping> SettingsClasses;
|
|
|
|
struct HasSettingsClass
|
|
{
|
|
var string className;
|
|
var bool hasSettings;
|
|
};
|
|
var config array<HasSettingsClass> HasSettingsCache;
|
|
|
|
struct ClassSettingsCacheEntry
|
|
{
|
|
var string cls;
|
|
var class<WebAdminSettings> settingsCls;
|
|
};
|
|
var array<ClassSettingsCacheEntry> classSettingsCache;
|
|
|
|
struct SettingsInstance
|
|
{
|
|
var class<WebAdminSettings> cls;
|
|
var WebAdminSettings instance;
|
|
};
|
|
var array<SettingsInstance> settingsInstances;
|
|
|
|
/**
|
|
* Settings class used for the general, server wide, settings
|
|
*/
|
|
var config string GeneralSettingsClass, WelcomeSettingsClass;
|
|
|
|
var WebAdmin webadmin;
|
|
|
|
var SettingsRenderer settingsRenderer;
|
|
|
|
var SettingsMagic settingsMagic;
|
|
|
|
//!localized
|
|
var localized string menuPolicy, menuPolicyDesc, menuBannedId, menuBannedIdDesc,
|
|
menuBannedHash, menuBannedHashDesc, menuSession, menuSessionDesc, menuSettings,
|
|
menuGeneral, menuGeneralDesc, menuPassword, menuPasswordDesc, menuGametypes,
|
|
menuGametypesDesc, menuMutators, menuMutatorsDesc, menuMapCycles, menuMapCyclesDesc,
|
|
menuMLAddition, menuMLAdditionDesc, msgSettingsCacheDesc, msgRemovedPolicy,
|
|
msgNoValidIpMask, msgInvalidPolicy, msgAddedPolicy, msdUpdatedPolicy,
|
|
msgNoValidId, msgAddedBanId, msgNoValidHash, msgBannedHash, msgRemovedSessionBan,
|
|
msgSettingsSaved, msgCantSaveSettings, msgCantLoadSettings, msgGamePWError,
|
|
msgGamePWSaved, msgAdminPWError, msgAdminPWSaved, msgAdminPWEmpty,
|
|
msgMapCycleSaved, msgCantLoadGT, msgImportedMapList, msgInvalidMaplist,
|
|
Untitled, msgCantFindMapCycle, msgCycleDeleted, msgCycleSaved, msgCycleActivated,
|
|
menuServerActors, menuServerActorsDesc, msgServerActorsSaved, msgServerActorsSavedWarn,
|
|
menuWelcome, menuWelcomeDesc, menuIpMask, menuIpMaskDesc,
|
|
msgSessionBansNoROAC, msgMapCycleActivated, msgMapCycleDeleted, msgNewMapCycle,
|
|
mapList, activeTag, msgBansImported, msgBansImporting, msgSessionBansNoBans;
|
|
|
|
function init(WebAdmin webapp)
|
|
{
|
|
if (Len(GeneralSettingsClass) == 0)
|
|
{
|
|
GeneralSettingsClass = class.getPackageName()$".GeneralSettings";
|
|
SaveConfig();
|
|
}
|
|
if (Len(WelcomeSettingsClass) == 0)
|
|
{
|
|
WelcomeSettingsClass = class.getPackageName()$".WelcomeSettings";
|
|
SaveConfig();
|
|
}
|
|
webadmin = webapp;
|
|
}
|
|
|
|
function cleanup()
|
|
{
|
|
local int i;
|
|
if (settingsMagic != none)
|
|
{
|
|
settingsMagic.cleanup();
|
|
}
|
|
settingsMagic = none;
|
|
webadmin = none;
|
|
if (settingsRenderer != none)
|
|
{
|
|
settingsRenderer.modifiers.Length = 0;
|
|
settingsRenderer.cleanup();
|
|
}
|
|
settingsRenderer = none;
|
|
for (i = 0; i < settingsInstances.length; i++)
|
|
{
|
|
if (IAdvWebAdminSettings(settingsInstances[i].instance) != none)
|
|
{
|
|
IAdvWebAdminSettings(settingsInstances[i].instance).cleanupSettings();
|
|
}
|
|
else if (settingsInstances[i].instance != none)
|
|
{
|
|
settingsInstances[i].instance.cleanupSettings();
|
|
}
|
|
}
|
|
settingsInstances.Length = 0;
|
|
}
|
|
|
|
function bool producesXhtml()
|
|
{
|
|
return true;
|
|
}
|
|
|
|
function bool handleQuery(WebAdminQuery q)
|
|
{
|
|
switch (q.request.URI)
|
|
{
|
|
case "/policy":
|
|
q.response.Redirect(WebAdmin.Path$"/policy/passwords");
|
|
return true;
|
|
case "/policy/ip":
|
|
handleIPPolicy(q);
|
|
return true;
|
|
case "/policy/bans":
|
|
handleBans(q);
|
|
return true;
|
|
case "/policy/bans+export":
|
|
handleBansExport(q);
|
|
return true;
|
|
case "/policy/bans+import":
|
|
handleBansImport(q);
|
|
return true;
|
|
`if(`WITH_BANCDHASH)
|
|
case "/policy/hashbans":
|
|
handleHashBans(q);
|
|
return true;
|
|
`endif
|
|
`if(`WITH_SESSION_BAN)
|
|
case "/policy/session":
|
|
handleSessionBans(q);
|
|
return true;
|
|
`endif
|
|
case "/settings":
|
|
q.response.Redirect(WebAdmin.Path$"/settings/general");
|
|
return true;
|
|
case "/settings/general":
|
|
handleSettingsGeneral(q);
|
|
return true;
|
|
case "/policy/passwords":
|
|
handleSettingsPasswords(q);
|
|
return true;
|
|
`if(`WITH_WELCOME_SETTINGS)
|
|
case "/settings/welcome":
|
|
handleSettingsWelcome(q);
|
|
return true;
|
|
`endif
|
|
case "/settings/gametypes":
|
|
handleSettingsGametypes(q);
|
|
return true;
|
|
case "/settings/mutators":
|
|
handleSettingsMutators(q);
|
|
return true;
|
|
case "/settings/maplist":
|
|
handleMapList(q);
|
|
return true;
|
|
case "/system/settingscache":
|
|
handleRebuildSettingsCache(q);
|
|
return true;
|
|
case "/settings/serveractors":
|
|
handleServerActors(q);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
function bool unhandledQuery(WebAdminQuery q);
|
|
|
|
function decoratePage(WebAdminQuery q);
|
|
|
|
function registerMenuItems(WebAdminMenu menu)
|
|
{
|
|
menu.addMenu("/policy", menuPolicy, self, menuPolicyDesc, -70);
|
|
menu.addMenu("/policy/passwords", menuPassword, self, menuPasswordDesc, -100);
|
|
menu.addMenu("/policy/bans", menuBannedId, self, menuBannedIdDesc, -80);
|
|
menu.addMenu("/policy/bans+export", "", self);
|
|
menu.addMenu("/policy/bans+import", "", self);
|
|
`if(`WITH_BANCDHASH)
|
|
menu.addMenu("/policy/hashbans", menuBannedHash, self, menuBannedHashDesc);
|
|
`endif
|
|
`if(`WITH_SESSION_BAN)
|
|
menu.addMenu("/policy/session", menuSession, self, menuSessionDesc, -90);
|
|
`endif
|
|
menu.addMenu("/policy/ip", menuIpMask, self, menuIpMaskDesc, -50);
|
|
menu.addMenu("/settings", menuSettings, self, "", -50);
|
|
menu.addMenu("/settings/general", menuGeneral, self, menuGeneralDesc, -10);
|
|
`if(`WITH_WELCOME_SETTINGS)
|
|
menu.addMenu("/settings/welcome", menuWelcome, self, menuWelcomeDesc);
|
|
`endif
|
|
menu.addMenu("/settings/gametypes", menuGametypes, self, menuGametypesDesc);
|
|
`if(`WITH_MUTATORS)
|
|
menu.addMenu("/settings/mutators", menuMutators, self, menuMutatorsDesc);
|
|
`endif
|
|
menu.addMenu("/settings/maplist", menuMapCycles, self, menuMapCyclesDesc);
|
|
menu.addMenu("/settings/serveractors", menuServerActors, self, menuServerActorsDesc);
|
|
menu.addMenu("/system/settingscache", "", self, msgSettingsCacheDesc);
|
|
}
|
|
|
|
function handleIPPolicy(WebAdminQuery q)
|
|
{
|
|
local string policies;
|
|
local string policy, action;
|
|
local array<string> parts;
|
|
local int i, idx;
|
|
|
|
action = q.request.getVariable("action");
|
|
if (action != "")
|
|
{
|
|
idx = -1;
|
|
if (action ~= "modify")
|
|
{
|
|
if (q.request.getVariable("delete") != "")
|
|
{
|
|
idx = int(q.request.getVariable("delete"));
|
|
action = "delete";
|
|
}
|
|
else if (q.request.getVariable("update") != "")
|
|
{
|
|
idx = int(q.request.getVariable("update"));
|
|
action = "update";
|
|
}
|
|
}
|
|
|
|
//`Log("Action = "$action);
|
|
if (action ~= "delete")
|
|
{
|
|
if (idx > -1 && idx < webadmin.worldinfo.game.accesscontrol.IPPolicies.length)
|
|
{
|
|
policy = webadmin.worldinfo.game.accesscontrol.IPPolicies[idx];
|
|
webadmin.worldinfo.game.accesscontrol.IPPolicies.Remove(idx, 1);
|
|
webadmin.worldinfo.game.accesscontrol.SaveConfig();
|
|
webadmin.addMessage(q, msgRemovedPolicy@policy);
|
|
}
|
|
}
|
|
else {
|
|
policy = q.request.getVariable("ipmask");
|
|
policy -= " ";
|
|
ParseStringIntoArray(policy, parts, ".", false);
|
|
for (i = 0; i < parts.length; i++)
|
|
{
|
|
if (parts[i] == "*")
|
|
{
|
|
continue;
|
|
}
|
|
if (parts[i] != string(int(parts[i])) || int(parts[i]) > 255 || int(parts[i]) < 0 )
|
|
{
|
|
webadmin.addMessage(q, repl(msgNoValidIpMask, "%s", "<code>"$policy$"</code>"), MT_error);
|
|
break;
|
|
}
|
|
}
|
|
if (parts.length > 4 || parts.length < 1)
|
|
{
|
|
webadmin.addMessage(q, repl(msgNoValidIpMask, "%s", "<code>"$policy$"</code>"), MT_error);
|
|
i = -1;
|
|
}
|
|
if (i == parts.length)
|
|
{
|
|
if (q.request.getVariable("policy") == "")
|
|
{
|
|
webadmin.addMessage(q, msgInvalidPolicy, MT_error);
|
|
}
|
|
else {
|
|
policy = q.request.getVariable("policy")$","$policy;
|
|
if (idx == -1)
|
|
{
|
|
webadmin.worldinfo.game.accesscontrol.IPPolicies.AddItem(policy);
|
|
webadmin.addMessage(q, msgAddedPolicy@policy);
|
|
}
|
|
else {
|
|
if (idx < -1 || idx > webadmin.worldinfo.game.accesscontrol.IPPolicies.length)
|
|
{
|
|
idx = webadmin.worldinfo.game.accesscontrol.IPPolicies.length;
|
|
}
|
|
webadmin.worldinfo.game.accesscontrol.IPPolicies[idx] = policy;
|
|
webadmin.addMessage(q, msdUpdatedPolicy@policy);
|
|
}
|
|
webadmin.worldinfo.game.accesscontrol.SaveConfig();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
for (i = 0; i < webadmin.worldinfo.game.accesscontrol.IPPolicies.length; i++)
|
|
{
|
|
q.response.subst("policy.id", ""$i);
|
|
policy = webadmin.worldinfo.game.accesscontrol.IPPolicies[i];
|
|
idx = InStr(policy, ",");
|
|
if (idx == INDEX_NONE) idx = InStr(policy, ";");
|
|
q.response.subst("policy.ipmask", `HTMLEscape(Mid(policy, idx+1)));
|
|
q.response.subst("policy.policy", `HTMLEscape(Left(policy, idx)));
|
|
q.response.subst("policy.selected."$Caps(Left(policy, idx)), "selected=\"selected\"");
|
|
policies $= webadmin.include(q, "policy_row.inc");
|
|
q.response.subst("policy.selected."$Caps(Left(policy, idx)), "");
|
|
}
|
|
|
|
q.response.subst("policies", policies);
|
|
webadmin.sendPage(q, "policy.html");
|
|
}
|
|
|
|
function handleBans(WebAdminQuery q)
|
|
{
|
|
local string bans, action;
|
|
local int i;
|
|
`if(`WITH_BANNEDINFO)
|
|
local BannedInfo NewBanInfo;
|
|
`endif
|
|
local UniqueNetId unid;
|
|
local OnlineSubsystem steamworks;
|
|
|
|
steamworks = class'GameEngine'.static.GetOnlineSubsystem();
|
|
|
|
action = q.request.getVariable("action");
|
|
if (action ~= "delete")
|
|
{
|
|
action = q.request.getVariable("banid");
|
|
i = InStr(action, "plainid:");
|
|
if (i == INDEX_NONE)
|
|
{
|
|
`if(`WITH_BANNEDINFO)
|
|
i = int(action);
|
|
if (i >= 0 && i < webadmin.worldinfo.game.accesscontrol.BannedPlayerInfo.Length)
|
|
{
|
|
webadmin.worldinfo.game.accesscontrol.BannedPlayerInfo.Remove(i, 1);
|
|
webadmin.worldinfo.game.accesscontrol.SaveConfig();
|
|
}
|
|
`endif
|
|
}
|
|
else {
|
|
i = int(Mid(action, 8));
|
|
if (i >= 0 && i < webadmin.worldinfo.game.accesscontrol.BannedIDs.Length)
|
|
{
|
|
webadmin.worldinfo.game.accesscontrol.BannedIDs.Remove(i, 1);
|
|
webadmin.worldinfo.game.accesscontrol.SaveConfig();
|
|
}
|
|
}
|
|
}
|
|
else if (action ~= "add")
|
|
{
|
|
action = q.request.getVariable("uniqueid");
|
|
action -= " ";
|
|
if (action != "")
|
|
{
|
|
class'OnlineSubsystem'.static.StringToUniqueNetId(action, unid);
|
|
}
|
|
else if (steamworks != none)
|
|
{
|
|
action = q.request.getVariable("steamint64");
|
|
action -= " ";
|
|
steamworks.Int64ToUniqueNetId(action, unid);
|
|
}
|
|
|
|
if (class'WebAdminUtils'.static.UniqueNetIdToString(unid) == "")
|
|
{
|
|
webadmin.addMessage(q, repl(msgNoValidId, "%s", "<code>"$action$"</code>"), MT_error);
|
|
}
|
|
else {
|
|
for (i = 0; i < webadmin.worldinfo.game.accesscontrol.BannedIDs.length; ++i)
|
|
{
|
|
if (webadmin.worldinfo.game.accesscontrol.BannedIDs[i] == unid)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (i == webadmin.worldinfo.game.accesscontrol.BannedIDs.length)
|
|
{
|
|
webadmin.worldinfo.game.accesscontrol.BannedIDs.addItem(unid);
|
|
webadmin.worldinfo.game.accesscontrol.SaveConfig();
|
|
webadmin.addMessage(q, msgAddedBanId@class'WebAdminUtils'.static.UniqueNetIdToString(unid));
|
|
}
|
|
}
|
|
}
|
|
|
|
`if(`WITH_BANNEDINFO)
|
|
for (i = 0; i < webadmin.worldinfo.game.accesscontrol.BannedPlayerInfo.Length; i++)
|
|
{
|
|
q.response.subst("ban.banid", ""$i);
|
|
unid = webadmin.worldinfo.game.accesscontrol.BannedPlayerInfo[i].BannedID;
|
|
q.response.subst("ban.uniqueid", class'OnlineSubsystem'.static.UniqueNetIdToString(unid));
|
|
q.response.subst("ban.playername", `HTMLEscape(webadmin.worldinfo.game.accesscontrol.BannedPlayerInfo[i].PlayerName));
|
|
q.response.subst("ban.timestamp", `HTMLEscape(webadmin.worldinfo.game.accesscontrol.BannedPlayerInfo[i].TimeStamp));
|
|
bans $= webadmin.include(q, "policy_bans_row.inc");
|
|
}
|
|
`endif
|
|
|
|
for (i = 0; i < webadmin.worldinfo.game.accesscontrol.BannedIDs.Length; i++)
|
|
{
|
|
q.response.subst("ban.banid", "plainid:"$i);
|
|
unid = webadmin.worldinfo.game.accesscontrol.BannedIDs[i];
|
|
q.response.subst("ban.uniqueid", class'OnlineSubsystem'.static.UniqueNetIdToString(unid));
|
|
if (steamworks != none)
|
|
{
|
|
q.response.subst("ban.steamid", steamworks.UniqueNetIdToInt64(unid));
|
|
action = steamworks.UniqueNetIdToPlayerName(unid);
|
|
q.response.subst("ban.steamname", `HTMLEscape(action));
|
|
}
|
|
else {
|
|
q.response.subst("ban.steamid", "");
|
|
q.response.subst("ban.steamname", "");
|
|
}
|
|
q.response.subst("ban.playername", "");
|
|
q.response.subst("ban.timestamp", "");
|
|
bans $= webadmin.include(q, "policy_bans_row.inc");
|
|
}
|
|
|
|
if (len(bans) == 0)
|
|
{
|
|
bans = webadmin.include(q, "policy_bans_empty.inc");
|
|
}
|
|
|
|
q.response.subst("bans", bans);
|
|
webadmin.sendPage(q, "policy_bans.html");
|
|
}
|
|
|
|
function handleBansExport(WebAdminQuery q)
|
|
{
|
|
local JsonObject result, bans, banJson;
|
|
local OnlineSubsystem steamworks;
|
|
local int i;
|
|
local int year,month,dayofweek,day,hour,minute,second,msec;
|
|
|
|
GetSystemTime(year,month,dayofweek,day,hour,minute,second,msec);
|
|
|
|
result = new class'JsonObject';
|
|
result.SetStringValue("serverName", webadmin.WorldInfo.Game.GameReplicationInfo.ServerName);
|
|
result.SetStringValue("timestamp", class'WebAdminUtils'.static.iso8601datetime(year,month,day,hour,minute,second,msec));
|
|
|
|
steamworks = class'GameEngine'.static.GetOnlineSubsystem();
|
|
|
|
bans = new class'JSonObject';
|
|
result.SetObject("bans", bans);
|
|
for (i = 0; i < webadmin.WorldInfo.Game.accesscontrol.BannedIDs.Length; ++i)
|
|
{
|
|
banJson = createBanJson(i, steamworks);
|
|
if (banJson != none)
|
|
{
|
|
bans.ObjectArray.addItem(banJson);
|
|
}
|
|
}
|
|
|
|
q.response.AddHeader("Content-Type: application/json");
|
|
q.response.AddHeader("Content-Disposition: attachment; filename=\"server-bans.json\"");
|
|
q.response.SendText(class'JsonObject'.static.EncodeJson(result));
|
|
}
|
|
|
|
function handleBansImport(WebAdminQuery q)
|
|
{
|
|
local string action;
|
|
local BanImporter banImporter;
|
|
local int cnt;
|
|
|
|
action = q.request.getVariable("action");
|
|
if (action ~= "import")
|
|
{
|
|
banImporter = new class 'BanImporter';
|
|
banImporter.importFrom(q.request.getVariable("importurl"));
|
|
q.session.putObject("BanImporter", banImporter);
|
|
}
|
|
else {
|
|
banImporter = BanImporter(q.session.getObject("BanImporter"));
|
|
}
|
|
|
|
if (banImporter == none) {
|
|
q.response.Redirect(WebAdmin.Path$"/policy/bans");
|
|
return;
|
|
}
|
|
|
|
q.response.subst("importer.status", banImporter.status);
|
|
q.response.subst("importer.statusMessage", banImporter.getStatusStr());
|
|
q.response.subst("importer.url", banImporter.importFromUrl);
|
|
|
|
if (banImporter.status == IS_ERROR) {
|
|
webadmin.addMessage(q, banImporter.errorMessage, MT_ERROR);
|
|
q.session.removeObject("BanImporter");
|
|
}
|
|
else if (banImporter.status == IS_DONE) {
|
|
cnt = banImporter.applyBansTo(webadmin.WorldInfo.Game.AccessControl,
|
|
class'GameEngine'.static.GetOnlineSubsystem());
|
|
webadmin.addMessage(q, repl(msgBansImported, "%i", cnt));
|
|
q.session.removeObject("BanImporter");
|
|
webadmin.WorldInfo.Game.AccessControl.SaveConfig();
|
|
}
|
|
|
|
webadmin.sendPage(q, "policy_bans_importing.html");
|
|
}
|
|
|
|
function JsonObject createBanJson(int idx, OnlineSubsystem steamworks)
|
|
{
|
|
local JsonObject result;
|
|
local AccessControl ac;
|
|
local UniqueNetId unid;
|
|
|
|
ac = webadmin.WorldInfo.Game.accesscontrol;
|
|
if (ac.BannedIDs.Length < idx+1 || idx < 0)
|
|
{
|
|
return none;
|
|
}
|
|
unid = ac.BannedIDs[idx];
|
|
|
|
result = new class'JsonObject';
|
|
result.SetStringValue("uniqueNetId", class'OnlineSubsystem'.static.UniqueNetIdToString(unid));
|
|
if (steamworks != none)
|
|
{
|
|
result.SetStringValue("steamId64", steamworks.UniqueNetIdToInt64(unid));
|
|
result.SetStringValue("steamName", steamworks.UniqueNetIdToPlayerName(unid));
|
|
}
|
|
return result;
|
|
}
|
|
|
|
`if(`WITH_BANCDHASH)
|
|
function handleHashBans(WebAdminQuery q)
|
|
{
|
|
local string bans, action;
|
|
local int i;
|
|
local BannedHashInfo NewBanInfo;
|
|
|
|
action = q.request.getVariable("action");
|
|
if (action ~= "delete")
|
|
{
|
|
i = int(q.request.getVariable("banid"));
|
|
if (i > -1 && i < webadmin.worldinfo.game.accesscontrol.BannedHashes.Length)
|
|
{
|
|
webadmin.worldinfo.game.accesscontrol.BannedHashes.Remove(i, 1);
|
|
webadmin.worldinfo.game.accesscontrol.SaveConfig();
|
|
}
|
|
}
|
|
else if (action ~= "add")
|
|
{
|
|
action = q.request.getVariable("hashresponse");
|
|
action -= " ";
|
|
if (action == "0")
|
|
{
|
|
webadmin.addMessage(q, repl(msgNoValidHash, "%s", "<code>"$action$"</code>"), MT_error);
|
|
}
|
|
else {
|
|
NewBanInfo.BannedHash = action;
|
|
NewBanInfo.playername = q.request.getVariable("playername");
|
|
webadmin.worldinfo.game.accesscontrol.BannedHashes.AddItem(NewBanInfo);
|
|
webadmin.worldinfo.game.accesscontrol.SaveConfig();
|
|
webadmin.addMessage(q, msgBannedHash@action);
|
|
}
|
|
}
|
|
|
|
for (i = 0; i < webadmin.worldinfo.game.accesscontrol.BannedHashes.Length; i++)
|
|
{
|
|
q.response.subst("ban.banid", ""$i);
|
|
q.response.subst("ban.hash", webadmin.worldinfo.game.accesscontrol.BannedHashes[i].BannedHash);
|
|
q.response.subst("ban.playername", `HTMLEscape(webadmin.worldinfo.game.accesscontrol.BannedHashes[i].PlayerName));
|
|
bans $= webadmin.include(q, "policy_hashbans_row.inc");
|
|
}
|
|
|
|
q.response.subst("bans", bans);
|
|
webadmin.sendPage(q, "policy_hashbans.html");
|
|
}
|
|
`endif
|
|
|
|
`if(`WITH_SESSION_BAN)
|
|
function handleSessionBans(WebAdminQuery q)
|
|
{
|
|
local `{AccessControl} roac;
|
|
local UniqueNetId unid, empty;
|
|
local string bans;
|
|
local int i;
|
|
local OnlineSubsystem steamworks;
|
|
|
|
roac = `{AccessControl} (webadmin.worldinfo.game.accesscontrol);
|
|
steamworks = class'GameEngine'.static.GetOnlineSubsystem();
|
|
|
|
if (roac != none && q.request.getVariable("action") ~= "revoke")
|
|
{
|
|
i = int(q.request.getVariable("banid", "-1"));
|
|
if (i > -1 && i < roac.SessionBannedIDs.length)
|
|
{
|
|
unid = roac.SessionBannedIDs[i];
|
|
roac.SessionBannedIDs.remove(i, 1);
|
|
webadmin.addMessage(q, repl(msgRemovedSessionBan, "%1", class'OnlineSubsystem'.static.UniqueNetIdToString(unid)));
|
|
}
|
|
}
|
|
|
|
if (roac != none)
|
|
{
|
|
for (i = 0; i < roac.SessionBannedIDs.Length; i++)
|
|
{
|
|
q.response.subst("ban.banid", i);
|
|
unid = roac.SessionBannedIDs[i];
|
|
if (empty == unid)
|
|
{
|
|
q.response.subst("ban.uniqueid", "");
|
|
q.response.subst("ban.uniqueid.visible", "display: none");
|
|
}
|
|
else {
|
|
q.response.subst("ban.uniqueid", class'OnlineSubsystem'.static.UniqueNetIdToString(unid));
|
|
`if(`WITH_BANNEDINFO)
|
|
if (webadmin.worldinfo.game.accesscontrol.BannedPlayerInfo.find('BannedID', unid) != INDEX_NONE)
|
|
{
|
|
q.response.subst("ban.uniqueid.visible", "display: none");
|
|
}
|
|
else {
|
|
`endif
|
|
q.response.subst("ban.uniqueid.visible", "");
|
|
`if(`WITH_BANNEDINFO)
|
|
}
|
|
`endif
|
|
}
|
|
|
|
if (steamworks != none)
|
|
{
|
|
q.response.subst("ban.steamname", `HTMLEscape(steamworks.UniqueNetIdToPlayerName(unid)));
|
|
q.response.subst("ban.steamid", steamworks.UniqueNetIdToInt64(unid));
|
|
}
|
|
else {
|
|
q.response.subst("ban.steamname", "");
|
|
q.response.subst("ban.steamid", "");
|
|
}
|
|
|
|
bans $= webadmin.include(q, "policy_session_row.inc");
|
|
}
|
|
if (roac.SessionBannedIDs.Length == 0)
|
|
{
|
|
q.response.subst("sessionban.empty", msgSessionBansNoBans);
|
|
bans = webadmin.include(q, "policy_session_empty.inc");
|
|
}
|
|
}
|
|
else {
|
|
`log("Current AccessControl class: "$webadmin.worldinfo.game.accesscontrol.class$" ; Expecting subclass of: `{AccessControl}",,'WebAdmin');
|
|
q.response.subst("sessionban.empty", msgSessionBansNoROAC);
|
|
bans = webadmin.include(q, "policy_session_empty.inc");
|
|
}
|
|
q.response.subst("bans", bans);
|
|
webadmin.sendPage(q, "policy_session.html");
|
|
}
|
|
`endif
|
|
|
|
function handleRebuildSettingsCache(WebAdminQuery q)
|
|
{
|
|
local array<DCEGameInfo> gts;
|
|
local int i;
|
|
|
|
if (q.request.getVariable("action") ~= "rebuild")
|
|
{
|
|
HasSettingsCache.length = 0;
|
|
gts = webadmin.dataStoreCache.getGameTypes();
|
|
for (i = 0; i < gts.length; i++)
|
|
{
|
|
HasSettings(gts[i].ClassName);
|
|
}
|
|
webadmin.dataStoreCache.loadMutators();
|
|
for (i = 0; i < webadmin.dataStoreCache.mutators.length; i++)
|
|
{
|
|
HasSettings(webadmin.dataStoreCache.mutators[i].ClassName);
|
|
}
|
|
webadmin.addMessage(q, "Settings cache has been rebuild.");
|
|
}
|
|
|
|
webadmin.addMessage(q, "<form action=\""$WebAdmin.Path$q.Request.URI$"\" method=\"post\">"
|
|
$"<p>Only rebuild the settings cache when the server is empty. It is strongly adviced to restart the game after rebuilding has been completed.</p>"
|
|
$"<p><button type=\"submit\" name=\"action\" value=\"rebuild\">Rebuild cache</button></p></form>", MT_Warning);
|
|
|
|
q.response.Subst("page.title", "Rebuild Settings Cache");
|
|
webadmin.sendPage(q, "message.html");
|
|
}
|
|
|
|
function bool HasSettings(string forClass)
|
|
{
|
|
local int i;
|
|
i = HasSettingsCache.find('classname', locs(forClass));
|
|
if (i != INDEX_NONE)
|
|
{
|
|
return HasSettingsCache[i].hasSettings;
|
|
}
|
|
i = HasSettingsCache.length;
|
|
HasSettingsCache.length = i+1;
|
|
HasSettingsCache[i].className = locs(forClass);
|
|
HasSettingsCache[i].hasSettings = getSettingsClassFqn(forClass, true) != none;
|
|
SaveConfig();
|
|
return HasSettingsCache[i].hasSettings;
|
|
}
|
|
|
|
/**
|
|
* Get the settings class by the fully qualified name
|
|
*/
|
|
function class<WebAdminSettings> getSettingsClassFqn(string forClass, optional bool bSilent=false)
|
|
{
|
|
local int idx;
|
|
local class<WebAdminSettings> result;
|
|
if (len(forClass) == 0) return none;
|
|
|
|
idx = classSettingsCache.find('cls', Locs(forClass));
|
|
if (idx != INDEX_NONE)
|
|
{
|
|
return classSettingsCache[idx].settingsCls;
|
|
}
|
|
idx = InStr(forClass, ".");
|
|
if (idx == INDEX_NONE)
|
|
{
|
|
result = getSettingsClass("", forClass, bSilent);
|
|
}
|
|
else {
|
|
result = getSettingsClass(Left(forClass, idx), Mid(forClass, idx+1), bSilent);
|
|
}
|
|
if (result != none)
|
|
{
|
|
idx = HasSettingsCache.find('classname', locs(forClass));
|
|
if (idx != INDEX_NONE)
|
|
{
|
|
HasSettingsCache[idx].hasSettings = true;
|
|
SaveConfig();
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Find the settings class. package name could be empty
|
|
*/
|
|
function class<WebAdminSettings> getSettingsClass(string pkgName, string clsName, optional bool bSilent=false)
|
|
{
|
|
local string className, settingsClass;
|
|
local class<WebAdminSettings> result;
|
|
local int idx;
|
|
local ClassSettingsCacheEntry cacheEntry;
|
|
|
|
if (len(clsName) == 0) return none;
|
|
|
|
idx = classSettingsCache.find('cls', Locs(pkgName$"."$clsName));
|
|
if (idx != INDEX_NONE)
|
|
{
|
|
return classSettingsCache[idx].settingsCls;
|
|
}
|
|
|
|
cacheEntry.cls = Locs(pkgName$"."$clsName);
|
|
|
|
idx = settingsClasses.find('className', clsName);
|
|
if (idx == INDEX_NONE)
|
|
{
|
|
className = cacheEntry.cls;
|
|
idx = settingsClasses.find('className', className);
|
|
}
|
|
if (idx != INDEX_NONE)
|
|
{
|
|
result = class<WebAdminSettings>(DynamicLoadObject(settingsClasses[idx].settingsClass, class'class'));
|
|
if (result == none)
|
|
{
|
|
`Log("Unable to load settings class "$settingsClasses[idx].settingsClass$" for the class "$settingsClasses[idx].className,,'WebAdmin');
|
|
}
|
|
else {
|
|
cacheEntry.settingsCls = result;
|
|
classSettingsCache.addItem(cacheEntry);
|
|
return result;
|
|
}
|
|
}
|
|
// try to find it automatically
|
|
settingsClass = rewriteSettingsClassname(pkgName, clsName);
|
|
|
|
result = class<WebAdminSettings>(DynamicLoadObject(settingsClass, class'class', true));
|
|
if (result != none)
|
|
{
|
|
cacheEntry.settingsCls = result;
|
|
classSettingsCache.addItem(cacheEntry);
|
|
return result;
|
|
}
|
|
// not in the same package, try the find the object (only works when it was loaded)
|
|
result = class<WebAdminSettings>(FindObject(clsName$"Settings", class'class'));
|
|
if (result == none)
|
|
{
|
|
if (!bSilent)
|
|
{
|
|
`Log("Settings class "$settingsClass$" for class "$pkgName$"."$clsName$" not found (auto detection).",,'WebAdmin');
|
|
}
|
|
}
|
|
// even cache a none result
|
|
cacheEntry.settingsCls = result;
|
|
classSettingsCache.addItem(cacheEntry);
|
|
return result;
|
|
}
|
|
|
|
function string rewriteSettingsClassname(string pkgName, string clsName)
|
|
{
|
|
return pkgName$"."$clsName$"Settings";
|
|
}
|
|
|
|
/**
|
|
* Try to find the settings class for the provided class
|
|
*/
|
|
function class<WebAdminSettings> getSettingsClassByClass(class forClass, optional bool bSilent=false)
|
|
{
|
|
return getSettingsClass(string(forClass.getPackageName()), string(forClass.name), bSilent);
|
|
}
|
|
|
|
function WebAdminSettings getSettingsInstance(class<WebAdminSettings> cls)
|
|
{
|
|
local WebAdminSettings instance;
|
|
local int idx;
|
|
idx = settingsInstances.find('cls', cls);
|
|
if (idx == INDEX_NONE)
|
|
{
|
|
instance = new cls;
|
|
idx = settingsInstances.length;
|
|
settingsInstances.Length = idx+1;
|
|
settingsInstances[idx].cls = cls;
|
|
settingsInstances[idx].instance = instance;
|
|
if (IAdvWebAdminSettings(instance) != none)
|
|
{
|
|
IAdvWebAdminSettings(instance).advInitSettings(webadmin.WorldInfo, webadmin.dataStoreCache);
|
|
}
|
|
else {
|
|
instance.initSettings();
|
|
}
|
|
}
|
|
return settingsInstances[idx].instance;
|
|
}
|
|
|
|
function SettingsRenderer getSettingsRenderer()
|
|
{
|
|
if (settingsRenderer == none)
|
|
{
|
|
settingsRenderer = new class'SettingsRenderer';
|
|
settingsRenderer.init(webadmin.path);
|
|
}
|
|
return settingsRenderer;
|
|
}
|
|
|
|
function handleSettingsGametypes(WebAdminQuery q)
|
|
{
|
|
local string currentGameType, substvar, tmp;
|
|
local DCEGameInfo editGametype, gametype;
|
|
local int idx;
|
|
local class<WebAdminSettings> settingsClass;
|
|
local class<GameInfo> gi;
|
|
local WebAdminSettings settings;
|
|
local ISettingsPrivileges privs;
|
|
local bool liveAdjust, settingsSaved;
|
|
|
|
currentGameType = q.request.getVariable("gametype");
|
|
if (currentGameType == "")
|
|
{
|
|
currentGameType = string(webadmin.WorldInfo.Game.class);
|
|
}
|
|
webadmin.dataStoreCache.loadGameTypes();
|
|
idx = webadmin.dataStoreCache.resolveGameType(currentGameType);
|
|
if (idx > INDEX_NONE)
|
|
{
|
|
editGametype = webadmin.dataStoreCache.gametypes[idx];
|
|
currentGameType = editGametype.data.ClassName;
|
|
}
|
|
else {
|
|
editGametype = none;
|
|
currentGameType = "";
|
|
}
|
|
|
|
substvar = "";
|
|
foreach webadmin.dataStoreCache.gametypes(gametype)
|
|
{
|
|
if (!q.user.canPerform(webadmin.getAuthURL(q.request.uri$"/"$gametype.data.ClassName)))
|
|
{
|
|
continue;
|
|
}
|
|
tmp = "";
|
|
if (!HasSettings(gametype.data.ClassName))
|
|
{
|
|
//continue;
|
|
tmp = " ¹";
|
|
}
|
|
q.response.subst("gametype.gamemode", `HTMLEscape(gametype.data.ClassName));
|
|
q.response.subst("gametype.friendlyname", `HTMLEscape(gametype.FriendlyName)$tmp);
|
|
//q.response.subst("gametype.defaultmap", `HTMLEscape(gametype.data.DefaultMap));
|
|
q.response.subst("gametype.description", `HTMLEscape(gametype.Description));
|
|
if (currentGameType ~= gametype.data.ClassName)
|
|
{
|
|
q.response.subst("editgametype.name", `HTMLEscape(gametype.FriendlyName)$tmp);
|
|
q.response.subst("editgametype.class", `HTMLEscape(gametype.data.ClassName));
|
|
q.response.subst("gametype.selected", "selected=\"selected\"");
|
|
}
|
|
else {
|
|
q.response.subst("gametype.selected", "");
|
|
}
|
|
substvar $= webadmin.include(q, "current_change_gametype.inc");
|
|
}
|
|
q.response.subst("gametypes", substvar);
|
|
|
|
if ((editGametype != none) && len(editGametype.data.ClassName) > 0 && q.user.canPerform("webadmin://"$q.request.uri$"/"$editGametype.data.ClassName))
|
|
{
|
|
gi = class<GameInfo>(DynamicLoadObject(editGametype.data.ClassName, class'class'));
|
|
if (gi != none)
|
|
{
|
|
settingsClass = getSettingsClassFqn(editGametype.data.ClassName);
|
|
}
|
|
if (settingsClass != none)
|
|
{
|
|
settings = getSettingsInstance(settingsClass);
|
|
}
|
|
if (settings == none)
|
|
{
|
|
if (settingsMagic == none)
|
|
{
|
|
settingsMagic = new class'SettingsMagic';
|
|
}
|
|
settings = settingsMagic.find(gi);
|
|
}
|
|
}
|
|
|
|
if (settings != none)
|
|
{
|
|
getSettingsRenderer();
|
|
|
|
if (q.request.getVariable("action") ~= "save" || q.request.getVariable("action") ~= "save settings")
|
|
{
|
|
liveAdjust = q.request.getVariable("liveAdjust", "0") == "1";
|
|
|
|
if (!liveAdjust) {
|
|
settings.setCurrentGameInfo(none);
|
|
}
|
|
if (IAdvWebAdminSettings(settings) != none)
|
|
{
|
|
if (IAdvWebAdminSettings(settings).advSaveSettings(q.request, webadmin.getMessagesObject(q)))
|
|
{
|
|
webadmin.addMessage(q, msgSettingsSaved);
|
|
}
|
|
}
|
|
else {
|
|
applySettings(settings, q.request);
|
|
settingsRenderer.ensureSettingValues(settings);
|
|
settings.saveSettings();
|
|
webadmin.addMessage(q, msgSettingsSaved);
|
|
}
|
|
|
|
settingsSaved = true;
|
|
}
|
|
else {
|
|
liveAdjust = true;
|
|
}
|
|
|
|
if (liveAdjust) {
|
|
settings.setCurrentGameInfo(webadmin.WorldInfo.Game);
|
|
}
|
|
|
|
privs = q.user.getSettingsPrivileges();
|
|
if (privs != none)
|
|
{
|
|
privs.setBasePrivilegeUri(webadmin.getAuthURL(q.request.uri$"/"$editGametype.data.ClassName));
|
|
}
|
|
|
|
if (!settingsSaved) {
|
|
settingsRenderer.ensureSettingValues(settings);
|
|
}
|
|
|
|
if (IAdvWebAdminSettings(settings) != none)
|
|
{
|
|
settingsRenderer.initEx(settings, q.response);
|
|
IAdvWebAdminSettings(settings).advRenderSettings(q.response, settingsRenderer,, privs);
|
|
}
|
|
else {
|
|
settingsRenderer.render(settings, q.response,, privs);
|
|
}
|
|
}
|
|
else if (editGametype != none) {
|
|
webadmin.addMessage(q, msgCantSaveSettings, MT_Warning);
|
|
}
|
|
|
|
if (KFGameInfoSettings(settings) == none || KFGameInfoSettings(settings).gameinfo == none)
|
|
{
|
|
q.response.subst("liveAdjustStyle", "style=\"display: none;\"");
|
|
}
|
|
|
|
if (liveAdjust) {
|
|
q.response.subst("liveAdjustChecked", "checked=\"checked\"");
|
|
}
|
|
else {
|
|
q.response.subst("liveAdjustChecked", "");
|
|
}
|
|
|
|
webadmin.sendPage(q, "default_settings_gametypes.html");
|
|
}
|
|
|
|
/**
|
|
* Apply the settings received from the response to the settings instance
|
|
*/
|
|
static function applySettings(WebAdminSettings settings, WebRequest request, optional string prefix = "settings_")
|
|
{
|
|
local int i, idx;
|
|
local name sname;
|
|
local string val;
|
|
|
|
for (i = 0; i < settings.LocalizedSettingsMappings.Length; i++)
|
|
{
|
|
idx = settings.LocalizedSettingsMappings[i].Id;
|
|
sname = settings.GetStringSettingName(idx);
|
|
if (request.GetVariableCount(prefix$sname) > 0)
|
|
{
|
|
val = request.GetVariable(prefix$sname);
|
|
settings.SetStringSettingValue(idx, int(val), false);
|
|
}
|
|
}
|
|
for (i = 0; i < settings.PropertyMappings.Length; i++)
|
|
{
|
|
idx = settings.PropertyMappings[i].Id;
|
|
sname = settings.GetPropertyName(idx);
|
|
if (request.GetVariableCount(prefix$sname) > 0)
|
|
{
|
|
val = request.GetVariable(prefix$sname);
|
|
settings.SetPropertyFromStringByName(sname, val);
|
|
}
|
|
}
|
|
}
|
|
|
|
function handleSettingsGeneral(WebAdminQuery q)
|
|
{
|
|
local class<WebAdminSettings> settingsClass;
|
|
local WebAdminSettings settings;
|
|
local float Difficulty;
|
|
local int Length;
|
|
local bool bNoLiveAdjust;
|
|
local KFGameInfo KFGI;
|
|
|
|
settingsClass = class<WebAdminSettings>(DynamicLoadObject( GeneralSettingsClass, class'class' ));
|
|
if( settingsClass != none )
|
|
{
|
|
settings = getSettingsInstance( settingsClass );
|
|
}
|
|
|
|
if( settings != none )
|
|
{
|
|
if( q.request.getVariable( "action" ) ~= "save" || q.request.getVariable( "action" ) ~= "save settings" )
|
|
{
|
|
KFGI = KFGameInfo(webadmin.WorldInfo.Game);
|
|
Difficulty = float(q.request.getVariable( "settings_GameDifficulty" ));
|
|
Length = int(q.request.getVariable( "settings_GameLength" ));
|
|
if( KFGI != none && (KFGI.GameDifficulty != Difficulty || KFGI.GameLength != Length) )
|
|
{
|
|
bNoLiveAdjust = true;
|
|
}
|
|
}
|
|
|
|
genericSettingsHandler( q, settings, bNoLiveAdjust );
|
|
}
|
|
else
|
|
{
|
|
`Log("Failed to load the general settings class "$GeneralSettingsClass,,'WebAdmin');
|
|
webadmin.addMessage( q, msgCantLoadSettings, MT_Warning );
|
|
}
|
|
|
|
webadmin.sendPage( q, "default_settings_general.html" );
|
|
}
|
|
|
|
function bool genericSettingsHandler( WebAdminQuery q, WebAdminSettings settings, optional bool bNoLiveAdjust=false )
|
|
{
|
|
local ISettingsPrivileges privs;
|
|
local bool settingsSaved, liveAdjust;
|
|
|
|
settingsSaved = false;
|
|
|
|
if (q.request.getVariable("action") ~= "save" || q.request.getVariable("action") ~= "save settings")
|
|
{
|
|
liveAdjust = bNoLiveAdjust ? false : q.request.getVariable("liveAdjust", "0") == "1";
|
|
if (!liveAdjust) {
|
|
settings.setCurrentGameInfo(none);
|
|
}
|
|
|
|
if (IAdvWebAdminSettings(settings) != none)
|
|
{
|
|
if (IAdvWebAdminSettings(settings).advSaveSettings(q.request, webadmin.getMessagesObject(q)))
|
|
{
|
|
webadmin.addMessage(q, msgSettingsSaved);
|
|
}
|
|
}
|
|
else {
|
|
applySettings(settings, q.request);
|
|
settingsRenderer.ensureSettingValues(settings);
|
|
settings.saveSettings();
|
|
webadmin.addMessage(q, msgSettingsSaved);
|
|
}
|
|
|
|
settingsSaved = true;
|
|
}
|
|
else {
|
|
liveAdjust = true;
|
|
}
|
|
|
|
getSettingsRenderer();
|
|
|
|
if (liveAdjust) {
|
|
settings.setCurrentGameInfo(WebAdmin.WorldInfo.Game);
|
|
}
|
|
|
|
if (!settingsSaved)
|
|
{
|
|
settingsRenderer.ensureSettingValues(settings);
|
|
}
|
|
|
|
privs = q.user.getSettingsPrivileges();
|
|
if (privs != none)
|
|
{
|
|
privs.setBasePrivilegeUri(webadmin.getAuthURL(q.request.uri));
|
|
}
|
|
|
|
if (IAdvWebAdminSettings(settings) != none)
|
|
{
|
|
settingsRenderer.initEx(settings, q.response);
|
|
IAdvWebAdminSettings(settings).advRenderSettings(q.response, settingsRenderer,, privs);
|
|
}
|
|
else {
|
|
settingsRenderer.render(settings, q.response,, privs);
|
|
}
|
|
|
|
if (liveAdjust) {
|
|
q.response.subst("liveAdjustChecked", "checked=\"checked\"");
|
|
}
|
|
else {
|
|
q.response.subst("liveAdjustChecked", "");
|
|
}
|
|
|
|
return settingsSaved;
|
|
}
|
|
|
|
function handleSettingsWelcome(WebAdminQuery q)
|
|
{
|
|
local class<WebAdminSettings> settingsClass;
|
|
local WebAdminSettings settings;
|
|
|
|
settingsClass = class<WebAdminSettings>(DynamicLoadObject(WelcomeSettingsClass, class'class'));
|
|
if (settingsClass != none)
|
|
{
|
|
settings = getSettingsInstance(settingsClass);
|
|
}
|
|
|
|
if (settings != none)
|
|
{
|
|
genericSettingsHandler(q, settings);
|
|
}
|
|
else {
|
|
`Log("Failed to load the welcome page settings class "$WelcomeSettingsClass,,'WebAdmin');
|
|
webadmin.addMessage(q, msgCantLoadSettings, MT_Warning);
|
|
}
|
|
|
|
webadmin.sendPage(q, "default_settings_welcome.html");
|
|
}
|
|
|
|
function handleSettingsPasswords(WebAdminQuery q)
|
|
{
|
|
local string action, pw1, pw2;
|
|
action = q.request.getVariable("action");
|
|
if (action ~= "gamepassword")
|
|
{
|
|
pw1 = q.request.getVariable("gamepw1");
|
|
pw2 = q.request.getVariable("gamepw2");
|
|
if (pw1 != pw2)
|
|
{
|
|
webadmin.addMessage(q, msgGamePWError, MT_Error);
|
|
}
|
|
else {
|
|
webadmin.WorldInfo.Game.AccessControl.SetGamePassword(pw1);
|
|
webadmin.WorldInfo.Game.AccessControl.SaveConfig();
|
|
webadmin.addMessage(q, msgGamePWSaved);
|
|
}
|
|
}
|
|
else if (action ~= "adminpassword")
|
|
{
|
|
pw1 = q.request.getVariable("adminpw1");
|
|
pw2 = q.request.getVariable("adminpw2");
|
|
if (pw1 != pw2)
|
|
{
|
|
webadmin.addMessage(q, msgAdminPWError, MT_Error);
|
|
}
|
|
else if (len(pw1) == 0)
|
|
{
|
|
webadmin.addMessage(q, msgAdminPWEmpty, MT_Error);
|
|
}
|
|
else {
|
|
webadmin.WorldInfo.Game.AccessControl.SetAdminPassword(pw1);
|
|
webadmin.WorldInfo.Game.AccessControl.SaveConfig();
|
|
webadmin.addMessage(q, msgAdminPWSaved);
|
|
}
|
|
}
|
|
q.response.subst("has.gamepassword", `HTMLEscape(webadmin.WorldInfo.Game.AccessControl.RequiresPassword()));
|
|
webadmin.sendPage(q, "default_settings_password.html");
|
|
}
|
|
|
|
function handleSettingsMutators(WebAdminQuery q)
|
|
{
|
|
local DCEMutator mutator, editMutator;
|
|
local string currentMutator, substvar;
|
|
local class<Mutator> mut;
|
|
local class<WebAdminSettings> settingsClass;
|
|
local WebAdminSettings settings;
|
|
local int idx;
|
|
local ISettingsPrivileges privs;
|
|
|
|
currentMutator = q.request.getVariable("mutator");
|
|
webadmin.dataStoreCache.loadMutators();
|
|
for (idx = 0; idx < webadmin.dataStoreCache.mutators.length; idx++)
|
|
{
|
|
if (webadmin.dataStoreCache.mutators[idx].ClassName ~= currentMutator)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
if (idx >= webadmin.dataStoreCache.mutators.length) idx = INDEX_NONE;
|
|
if (idx > INDEX_NONE)
|
|
{
|
|
editMutator = webadmin.dataStoreCache.mutators[idx];
|
|
currentMutator = editMutator.ClassName;
|
|
}
|
|
else {
|
|
editMutator = none;
|
|
currentMutator = "";
|
|
}
|
|
|
|
substvar = "";
|
|
foreach webadmin.dataStoreCache.mutators(mutator)
|
|
{
|
|
if (!HasSettings(mutator.ClassName))
|
|
{
|
|
continue;
|
|
}
|
|
if (!q.user.canPerform("webadmin://"$q.request.uri$"/"$mutator.ClassName))
|
|
{
|
|
continue;
|
|
}
|
|
q.response.subst("mutator.classname", `HTMLEscape(mutator.ClassName));
|
|
q.response.subst("mutator.friendlyname", `HTMLEscape(mutator.FriendlyName));
|
|
q.response.subst("mutator.description", `HTMLEscape(mutator.Description));
|
|
|
|
if (currentMutator ~= mutator.ClassName)
|
|
{
|
|
q.response.subst("editmutator.name", `HTMLEscape(mutator.FriendlyName));
|
|
q.response.subst("editmutator.class", `HTMLEscape(mutator.ClassName));
|
|
q.response.subst("editmutator.description", `HTMLEscape(mutator.Description));
|
|
q.response.subst("mutator.selected", "selected=\"selected\"");
|
|
}
|
|
else {
|
|
q.response.subst("mutator.selected", "");
|
|
}
|
|
substvar $= webadmin.include(q, "default_settings_mutators_select.inc");
|
|
}
|
|
q.response.subst("mutators", substvar);
|
|
|
|
if ((editMutator != none) && len(editMutator.ClassName) > 0 && q.user.canPerform("webadmin://"$q.request.uri$"/"$editMutator.ClassName))
|
|
{
|
|
mut = class<Mutator>(DynamicLoadObject(editMutator.ClassName, class'class'));
|
|
if (mut != none)
|
|
{
|
|
settingsClass = getSettingsClassFqn(editMutator.ClassName);
|
|
}
|
|
if (settingsClass != none)
|
|
{
|
|
settings = getSettingsInstance(settingsClass);
|
|
}
|
|
}
|
|
|
|
if (settings != none)
|
|
{
|
|
if (q.request.getVariable("action") ~= "save" || q.request.getVariable("action") ~= "save settings")
|
|
{
|
|
if (IAdvWebAdminSettings(settings) != none)
|
|
{
|
|
if (IAdvWebAdminSettings(settings).advSaveSettings(q.request, webadmin.getMessagesObject(q)))
|
|
{
|
|
webadmin.addMessage(q, msgSettingsSaved);
|
|
}
|
|
}
|
|
else {
|
|
applySettings(settings, q.request);
|
|
settings.saveSettings();
|
|
webadmin.addMessage(q, msgSettingsSaved);
|
|
}
|
|
}
|
|
|
|
getSettingsRenderer();
|
|
|
|
privs = q.user.getSettingsPrivileges();
|
|
if (privs != none)
|
|
{
|
|
privs.setBasePrivilegeUri(q.request.uri);
|
|
}
|
|
|
|
if (IAdvWebAdminSettings(settings) != none)
|
|
{
|
|
settingsRenderer.initEx(settings, q.response);
|
|
IAdvWebAdminSettings(settings).advRenderSettings(q.response, settingsRenderer,, privs);
|
|
}
|
|
else {
|
|
settingsRenderer.render(settings, q.response,, privs);
|
|
}
|
|
q.response.subst("settings", webadmin.include(q, "default_settings_mutators.inc"));
|
|
}
|
|
else if (editMutator != none) {
|
|
webadmin.addMessage(q, msgCantLoadSettings, MT_Warning);
|
|
}
|
|
|
|
webadmin.sendPage(q, "default_settings_mutators.html");
|
|
}
|
|
|
|
function handleMapList(WebAdminQuery q)
|
|
{
|
|
local string currentGameType, substvar;
|
|
local DCEGameInfo editGametype, gametype;
|
|
local int idx, i, maplistidx, activeidx;
|
|
local GameMapCycle cycle;
|
|
local array<GameMapCycle> cycles;
|
|
local array<DCEMapInfo> allMaps;
|
|
local array<string> postcycle;
|
|
|
|
// get the maplist cycle index
|
|
maplistidx = int(q.request.getVariable("maplistidx", "-2"));
|
|
if (maplistidx == -2)
|
|
{
|
|
if (`{GameInfo} (webadmin.WorldInfo.Game) != none)
|
|
{
|
|
maplistidx = `{GameInfo} (webadmin.WorldInfo.Game).ActiveMapCycle;
|
|
}
|
|
}
|
|
|
|
// get the maplist cycle
|
|
if (`{GameInfo} (webadmin.WorldInfo.Game) != none)
|
|
{
|
|
cycles = `{GameInfo} (webadmin.WorldInfo.Game).GameMapCycles;
|
|
}
|
|
else {
|
|
cycles = class'`{GameInfo}'.default.GameMapCycles;
|
|
}
|
|
maplistidx = min(maplistidx, cycles.length-1);
|
|
if (maplistidx >= 0)
|
|
{
|
|
cycle = cycles[maplistidx];
|
|
}
|
|
|
|
if (`{GameInfo} (webadmin.WorldInfo.Game) != none)
|
|
{
|
|
activeidx = `{GameInfo} (webadmin.WorldInfo.Game).ActiveMapCycle;
|
|
}
|
|
else {
|
|
activeidx = class'`{GameInfo}'.default.ActiveMapCycle;
|
|
}
|
|
|
|
if (activeidx == maplistidx || maplistidx < 0) {
|
|
q.response.subst("mlactive", "disabled=\"disabled\"");
|
|
}
|
|
else {
|
|
q.response.subst("mlactive", "");
|
|
}
|
|
|
|
// gametype to list the maps for
|
|
currentGameType = q.request.getVariable("gametype");
|
|
if (currentGameType == "")
|
|
{
|
|
// get gametype based on first map
|
|
if (cycle.Maps.Length > 0)
|
|
{
|
|
postcycle = webadmin.dataStoreCache.getGametypesByMap(cycle.Maps[0]);
|
|
if (postcycle.Length > 0)
|
|
{
|
|
currentGameType = postcycle[0];
|
|
}
|
|
}
|
|
|
|
if (currentGameType == "")
|
|
{
|
|
currentGameType = string(webadmin.WorldInfo.Game.class);
|
|
}
|
|
}
|
|
|
|
webadmin.dataStoreCache.loadGameTypes();
|
|
idx = webadmin.dataStoreCache.resolveGameType(currentGameType);
|
|
if (idx > INDEX_NONE)
|
|
{
|
|
editGametype = webadmin.dataStoreCache.gametypes[idx];
|
|
currentGameType = editGametype.data.ClassName;
|
|
}
|
|
else {
|
|
editGametype = none;
|
|
currentGameType = "";
|
|
}
|
|
|
|
// create gametype selection list
|
|
substvar = "";
|
|
foreach webadmin.dataStoreCache.gametypes(gametype)
|
|
{
|
|
q.response.subst("gametype.gamemode", `HTMLEscape(gametype.data.ClassName));
|
|
q.response.subst("gametype.friendlyname", `HTMLEscape(gametype.FriendlyName));
|
|
//q.response.subst("gametype.defaultmap", `HTMLEscape(gametype.data.DefaultMap));
|
|
q.response.subst("gametype.description", `HTMLEscape(gametype.Description));
|
|
if (currentGameType ~= gametype.data.ClassName)
|
|
{
|
|
q.response.subst("editgametype.name", `HTMLEscape(gametype.FriendlyName));
|
|
q.response.subst("editgametype.class", `HTMLEscape(gametype.data.ClassName));
|
|
q.response.subst("gametype.selected", "selected=\"selected\"");
|
|
}
|
|
else {
|
|
q.response.subst("gametype.selected", "");
|
|
}
|
|
substvar $= webadmin.include(q, "current_change_gametype.inc");
|
|
}
|
|
q.response.subst("gametypes", substvar);
|
|
|
|
if ((editGametype != none) && len(editGametype.data.ClassName) > 0)
|
|
{
|
|
allMaps = webadmin.dataStoreCache.getMaps(editGametype.data.ClassName);
|
|
}
|
|
|
|
if (len(q.request.getVariable("mapcycle")) > 0)
|
|
{
|
|
ParseStringIntoArray(q.request.getVariable("mapcycle"), postcycle, chr(10), true);
|
|
cycle.Maps.length = 0;
|
|
//cycle.RoundLimits.length = 0;
|
|
for (i = 0; i < postcycle.length; i++)
|
|
{
|
|
substvar = `Trim(postcycle[i]);
|
|
if (len(substvar) > 0)
|
|
{
|
|
//idx = InStr(substvar, "?");
|
|
//if (idx != INDEX_NONE)
|
|
//{
|
|
//tmp = mid(substvar, idx);
|
|
//idx = class'GameInfo'.static.GetIntOption(tmp, "RoundLimit", 0);
|
|
//substvar = class'WebAdminUtils'.static.removeUrlOption(substvar, "RoundLimit");
|
|
//}
|
|
//else {
|
|
// idx = 0;
|
|
//}
|
|
cycle.Maps[cycle.Maps.length] = substvar;
|
|
//cycle.RoundLimits[cycle.Maps.length-1] = idx;
|
|
}
|
|
}
|
|
|
|
if (len(q.request.getVariable("activate")) > 0)
|
|
{
|
|
if (maplistidx >= 0 && maplistidx < cycles.length)
|
|
{
|
|
class'`{GameInfo}'.default.ActiveMapCycle = maplistidx;
|
|
class'`{GameInfo}'.static.StaticSaveConfig();
|
|
if (`{GameInfo} (webadmin.WorldInfo.Game) != none)
|
|
{
|
|
`{GameInfo} (webadmin.WorldInfo.Game).ActiveMapCycle = class'`{GameInfo}'.default.ActiveMapCycle;
|
|
}
|
|
q.response.subst("mlactive", "disabled=\"disabled\"");
|
|
webadmin.addMessage(q, repl(msgMapCycleActivated, "%i", string(maplistidx+1)));
|
|
activeidx = maplistidx;
|
|
}
|
|
}
|
|
else if (len(q.request.getVariable("delete")) > 0)
|
|
{
|
|
if (maplistidx >= 0 && maplistidx < cycles.length)
|
|
{
|
|
cycles.Remove(maplistidx, 1);
|
|
class'`{GameInfo}'.default.GameMapCycles = cycles;
|
|
class'`{GameInfo}'.static.StaticSaveConfig();
|
|
if (`{GameInfo} (webadmin.WorldInfo.Game) != none)
|
|
{
|
|
`{GameInfo} (webadmin.WorldInfo.Game).GameMapCycles = class'`{GameInfo}'.default.GameMapCycles;
|
|
}
|
|
webadmin.addMessage(q, msgMapCycleDeleted);
|
|
q.response.subst("mlactive", "disabled=\"disabled\"");
|
|
maplistidx = -1;
|
|
cycle.Maps.Length = 0;
|
|
//cycle.RoundLimits.Length = 0;
|
|
}
|
|
}
|
|
else if (len(q.request.getVariable("action")) > 0)
|
|
{
|
|
if (maplistidx == INDEX_NONE) maplistidx = cycles.length;
|
|
cycles[maplistidx] = cycle;
|
|
class'`{GameInfo}'.default.GameMapCycles = cycles;
|
|
class'`{GameInfo}'.static.StaticSaveConfig();
|
|
if (`{GameInfo} (webadmin.WorldInfo.Game) != none)
|
|
{
|
|
`{GameInfo} (webadmin.WorldInfo.Game).GameMapCycles = class'`{GameInfo}'.default.GameMapCycles;
|
|
}
|
|
webadmin.addMessage(q, msgMapCycleSaved);
|
|
// can now be activated
|
|
if (activeidx == maplistidx || maplistidx < 0) {
|
|
q.response.subst("mlactive", "disabled=\"disabled\"");
|
|
}
|
|
else {
|
|
q.response.subst("mlactive", "");
|
|
}
|
|
}
|
|
}
|
|
|
|
if (maplistidx > -1)
|
|
{
|
|
q.response.subst("mldeletable", "");
|
|
}
|
|
else {
|
|
q.response.subst("mldeletable", "disabled=\"disabled\"");
|
|
}
|
|
|
|
// create maplist selection list
|
|
q.response.subst("maplistidx", string(maplistidx));
|
|
q.response.subst("editmaplist.friendlyname", `HTMLEscape(msgNewMapCycle));
|
|
substvar = "";
|
|
for (idx = 0; idx < cycles.length; ++idx)
|
|
{
|
|
// TODO: localize
|
|
q.response.subst("maplist.friendlyname", `HTMLEscape(repl(mapList, "%i", (idx+1))$(activeidx == idx?" "$activeTag:"")));
|
|
q.response.subst("maplist.index", string(idx));
|
|
if (maplistidx == idx)
|
|
{
|
|
q.response.subst("maplist.selected", "selected=\"selected\"");
|
|
q.response.subst("editmaplist.friendlyname", `HTMLEscape("Map cycle #"$(idx+1)));
|
|
}
|
|
else {
|
|
q.response.subst("maplist.selected", "");
|
|
}
|
|
substvar $= webadmin.include(q, "default_maplist_select.inc");
|
|
}
|
|
q.response.subst("maplists", substvar);
|
|
|
|
substvar = "";
|
|
for (i = 0; i < allMaps.length; i++)
|
|
{
|
|
if (i > 0) substvar $= chr(10);
|
|
substvar $= allMaps[i].data.MapName;
|
|
}
|
|
q.response.subst("allmaps.plain", `HTMLEscape(substvar));
|
|
|
|
substvar = "";
|
|
for (i = 0; i < cycle.Maps.length; i++)
|
|
{
|
|
if (i > 0) substvar $= chr(10);
|
|
substvar $= cycle.Maps[i];
|
|
//if (cycle.RoundLimits.length > i)
|
|
//{
|
|
// if (cycle.RoundLimits[i] > 0)
|
|
// {
|
|
// substvar $= "?RoundLimit="$cycle.RoundLimits[i];
|
|
// }
|
|
//}
|
|
}
|
|
q.response.subst("cycle.plain", `HTMLEscape(substvar));
|
|
|
|
q.response.subst("maplist_editor", webadmin.include(q, "default_maplist_editor.inc"));
|
|
|
|
webadmin.sendPage(q, "default_maplist.html");
|
|
}
|
|
|
|
function handleServerActors(WebAdminQuery q)
|
|
{
|
|
local string tmp;
|
|
local array<string> tmpa;
|
|
local int i;
|
|
local GameEngine gameengine;
|
|
local bool foundWebAdmin;
|
|
|
|
if (q.request.getVariable("action") ~= "save")
|
|
{
|
|
ParseStringIntoArray(q.request.getVariable("serveractors"), tmpa, chr(10), true);
|
|
class'KFGameEngine'.default.ServerActors.length = 0;
|
|
foundWebAdmin = false;
|
|
for (i = 0; i < tmpa.length; i++)
|
|
{
|
|
tmp = `Trim(tmpa[i]);
|
|
if (len(tmp) > 0)
|
|
{
|
|
if (tmp ~= "IpDrv.WebServer") foundWebAdmin = true;
|
|
class'KFGameEngine'.default.ServerActors.addItem(tmp);
|
|
}
|
|
}
|
|
if (!foundWebAdmin)
|
|
{
|
|
class'KFGameEngine'.default.ServerActors.addItem("IpDrv.WebServer");
|
|
`Log("Force added WebServer to server actors list",,'WebAdmin');
|
|
}
|
|
class'KFGameEngine'.static.StaticSaveConfig();
|
|
gameengine = GameEngine(FindObject("Transient.GameEngine_0", class'KFGameEngine'));
|
|
if (gameengine != none)
|
|
{
|
|
gameengine.ServerActors = class'KFGameEngine'.default.ServerActors;
|
|
webadmin.addMessage(q, msgServerActorsSaved);
|
|
}
|
|
else {
|
|
webadmin.addMessage(q, msgServerActorsSavedWarn, MT_Warning);
|
|
}
|
|
}
|
|
|
|
tmp = "";
|
|
for (i = 0; i < class'KFGameEngine'.default.ServerActors.length; i++)
|
|
{
|
|
if (i > 0) tmp $= chr(10);
|
|
tmp $= class'KFGameEngine'.default.ServerActors[i];
|
|
}
|
|
q.response.subst("serveractors", tmp);
|
|
webadmin.sendPage(q, "default_serveractors.html");
|
|
}
|
|
|
|
defaultproperties
|
|
{
|
|
}
|