Added base ServerExt and ServerExtMut
This commit is contained in:
74580
ServerExtMut/Classes/CtryDatabase.uc
Normal file
74580
ServerExtMut/Classes/CtryDatabase.uc
Normal file
File diff suppressed because it is too large
Load Diff
246
ServerExtMut/Classes/ExtPlayerStat.uc
Normal file
246
ServerExtMut/Classes/ExtPlayerStat.uc
Normal file
@ -0,0 +1,246 @@
|
||||
// Byte serialization, written by Marco.
|
||||
Class ExtPlayerStat extends Object implements(ExtSaveDataBase);
|
||||
|
||||
var int ArVersion,SaveNum;
|
||||
var transient int BufferOffset,BufferSize;
|
||||
var transient array<int> EOFStack;
|
||||
var array<byte> Buffer;
|
||||
var array<string> StrMap;
|
||||
const CurrentSaveVer=1;
|
||||
|
||||
final function bool LoadStatFile( PlayerController Other )
|
||||
{
|
||||
local string S;
|
||||
|
||||
FlushData();
|
||||
S = class'ServerExtMut'.Static.GetStatFile(Other.PlayerReplicationInfo.UniqueId);
|
||||
if( Class'Engine'.Static.BasicLoadObject(Self,S,false,CurrentSaveVer) )
|
||||
{
|
||||
BufferSize = Buffer.Length;
|
||||
return true;
|
||||
}
|
||||
BufferSize = 0;
|
||||
Buffer.Length = 0;
|
||||
return false;
|
||||
}
|
||||
final function SaveStatFile( PlayerController Other )
|
||||
{
|
||||
local string S;
|
||||
|
||||
S = class'ServerExtMut'.Static.GetStatFile(Other.PlayerReplicationInfo.UniqueId);
|
||||
Class'Engine'.Static.BasicSaveObject(Self,S,false,CurrentSaveVer);
|
||||
}
|
||||
|
||||
function SaveInt( int Value, optional byte MaxVal )
|
||||
{
|
||||
++MaxVal;
|
||||
if( (BufferOffset+MaxVal)>Buffer.Length )
|
||||
{
|
||||
Buffer.Length = (BufferOffset+MaxVal);
|
||||
BufferSize = Buffer.Length;
|
||||
}
|
||||
Buffer[BufferOffset++] = Value & 255;
|
||||
if( MaxVal>1 )
|
||||
{
|
||||
Buffer[BufferOffset++] = (Value >> 8) & 255;
|
||||
if( MaxVal>2 )
|
||||
{
|
||||
Buffer[BufferOffset++] = (Value >> 16) & 255;
|
||||
if( MaxVal>3 )
|
||||
Buffer[BufferOffset++] = (Value >> 24) & 255;
|
||||
}
|
||||
}
|
||||
}
|
||||
function int ReadInt( optional byte MaxVal )
|
||||
{
|
||||
local int Res;
|
||||
|
||||
++MaxVal;
|
||||
if( (BufferOffset+MaxVal)>BufferSize )
|
||||
return 0;
|
||||
|
||||
Res = Buffer[BufferOffset++];
|
||||
if( MaxVal>1 )
|
||||
{
|
||||
Res = Res | (Buffer[BufferOffset++] << 8);
|
||||
if( MaxVal>2 )
|
||||
{
|
||||
Res = Res | (Buffer[BufferOffset++] << 16);
|
||||
if( MaxVal>3 )
|
||||
Res = Res | (Buffer[BufferOffset++] << 24);
|
||||
}
|
||||
}
|
||||
return Res;
|
||||
}
|
||||
function SaveStr( string S )
|
||||
{
|
||||
local int i;
|
||||
|
||||
if( S=="" )
|
||||
{
|
||||
SaveInt(0,1);
|
||||
return;
|
||||
}
|
||||
S = Left(S,255);
|
||||
i = StrMap.Find(S);
|
||||
if( i==-1 )
|
||||
{
|
||||
i = StrMap.Length;
|
||||
StrMap[StrMap.Length] = S;
|
||||
}
|
||||
SaveInt((i+1),1);
|
||||
}
|
||||
function string ReadStr()
|
||||
{
|
||||
local int i;
|
||||
|
||||
i = ReadInt(1);
|
||||
if( i==0 || i>StrMap.Length )
|
||||
return "";
|
||||
return StrMap[i-1];
|
||||
}
|
||||
|
||||
function int TellOffset()
|
||||
{
|
||||
return BufferOffset;
|
||||
}
|
||||
function SeekOffset( int Offset )
|
||||
{
|
||||
BufferOffset = Clamp(Offset,0,BufferSize);
|
||||
}
|
||||
function int TotalSize()
|
||||
{
|
||||
return BufferSize;
|
||||
}
|
||||
function ToEnd()
|
||||
{
|
||||
BufferOffset = BufferSize;
|
||||
}
|
||||
function ToStart()
|
||||
{
|
||||
BufferOffset = 0;
|
||||
}
|
||||
function bool AtEnd()
|
||||
{
|
||||
return (BufferOffset>=BufferSize);
|
||||
}
|
||||
function SkipBytes( int Count )
|
||||
{
|
||||
BufferOffset = Clamp(BufferOffset+Count,0,BufferSize);
|
||||
}
|
||||
|
||||
function FlushData()
|
||||
{
|
||||
ArVersion = 0;
|
||||
SaveNum = 0;
|
||||
BufferOffset = 0;
|
||||
BufferSize = 0;
|
||||
Buffer.Length = 0;
|
||||
EOFStack.Length = 0;
|
||||
StrMap.Length = 0;
|
||||
}
|
||||
|
||||
final function DebugData()
|
||||
{
|
||||
local string S,SS;
|
||||
local array<byte> B;
|
||||
local int i;
|
||||
|
||||
GetData(B);
|
||||
`Log("DEBUG DATA: Data size: "$B.Length);
|
||||
for( i=0; i<B.Length; ++i )
|
||||
{
|
||||
S $= Chr(Max(B[i],1));
|
||||
SS $= "."$B[i];
|
||||
}
|
||||
`Log("DEBUG DATA: "$S);
|
||||
`Log("DEBUG DATA: "$SS);
|
||||
}
|
||||
|
||||
function GetData( out array<byte> Res )
|
||||
{
|
||||
local int i,l,o,j;
|
||||
|
||||
Res = Buffer;
|
||||
Res.Insert(0,1);
|
||||
Res[0] = ArVersion;
|
||||
|
||||
// Add string map to start.
|
||||
// Write string map length.
|
||||
Res.Insert(1,2);
|
||||
l = StrMap.Length;
|
||||
Res[1] = l & 255;
|
||||
Res[2] = (l >> 8) & 255;
|
||||
o = 3;
|
||||
|
||||
// write each entry.
|
||||
for( i=0; i<StrMap.Length; ++i )
|
||||
{
|
||||
l = Len(StrMap[i]);
|
||||
Res.Insert(o,l+1);
|
||||
Res[o++] = l;
|
||||
for( j=0; j<l; ++j )
|
||||
Res[o++] = Asc(Mid(StrMap[i],j,1));
|
||||
}
|
||||
}
|
||||
function SetData( out array<byte> S )
|
||||
{
|
||||
local int i,o,l,j;
|
||||
|
||||
ArVersion = S[0];
|
||||
Buffer = S;
|
||||
|
||||
// read string map length.
|
||||
StrMap.Length = Buffer[1] | (Buffer[2] << 8);
|
||||
o = 3;
|
||||
|
||||
// read each string map entry.
|
||||
for( i=0; i<StrMap.Length; ++i )
|
||||
{
|
||||
l = Buffer[o++];
|
||||
StrMap[i] = "";
|
||||
for( j=0; j<l; ++j )
|
||||
StrMap[i] $= Chr(Buffer[o++]);
|
||||
}
|
||||
Buffer.Remove(0,o);
|
||||
|
||||
BufferSize = Buffer.Length;
|
||||
}
|
||||
|
||||
function int GetArVer()
|
||||
{
|
||||
return ArVersion;
|
||||
}
|
||||
function SetArVer( int Ver )
|
||||
{
|
||||
ArVersion = Ver;
|
||||
}
|
||||
|
||||
function PushEOFLimit( int EndOffset )
|
||||
{
|
||||
EOFStack.AddItem(BufferSize);
|
||||
BufferSize = EndOffset;
|
||||
}
|
||||
function PopEOFLimit()
|
||||
{
|
||||
if( EOFStack.Length==0 )
|
||||
{
|
||||
`Log(Self@"WARNING: Tried to pop one EoF stack down too far!!!");
|
||||
return; // Whoops, error.
|
||||
}
|
||||
BufferSize = EOFStack[EOFStack.Length-1];
|
||||
EOFStack.Length = EOFStack.Length-1;
|
||||
}
|
||||
|
||||
function int GetSaveVersion()
|
||||
{
|
||||
return SaveNum;
|
||||
}
|
||||
function SetSaveVersion( int Num )
|
||||
{
|
||||
SaveNum = Num;
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
}
|
106
ServerExtMut/Classes/ExtStatList.uc
Normal file
106
ServerExtMut/Classes/ExtStatList.uc
Normal file
@ -0,0 +1,106 @@
|
||||
Class ExtStatList extends Object
|
||||
config(ServerExtStats)
|
||||
abstract;
|
||||
|
||||
struct FTopPlayers
|
||||
{
|
||||
var config string N,Id;
|
||||
var config int V;
|
||||
};
|
||||
var config array<FTopPlayers> TopPlaytimes,TopKills,TopExp;
|
||||
|
||||
static final function SetTopPlayers( ExtPlayerController Other )
|
||||
{
|
||||
local ExtPerkManager PM;
|
||||
local bool bDirty;
|
||||
|
||||
PM = Other.ActivePerkManager;
|
||||
|
||||
bDirty = CheckBestTrack(Other.PlayerReplicationInfo,PM.TotalPlayTime,Default.TopPlaytimes);
|
||||
bDirty = CheckBestTrack(Other.PlayerReplicationInfo,PM.TotalKills,Default.TopKills) || bDirty;
|
||||
bDirty = CheckBestTrack(Other.PlayerReplicationInfo,PM.TotalEXP,Default.TopExp) || bDirty;
|
||||
if( bDirty )
|
||||
StaticSaveConfig();
|
||||
}
|
||||
static final function bool CheckBestTrack( PlayerReplicationInfo PRI, int Value, out array<FTopPlayers> V )
|
||||
{
|
||||
local string S;
|
||||
local int i,l;
|
||||
|
||||
S = class'OnlineSubsystem'.Static.UniqueNetIdToString(PRI.UniqueId);
|
||||
|
||||
l = class'ServerExtMut'.Default.MaxTopPlayers;
|
||||
if( V.Length>l ) // See if list has overflown incase an admin has changed the max stats value.
|
||||
V.Length = l;
|
||||
|
||||
i = V.Find('ID',S); // First see if we have an entry from before.
|
||||
if( i>=0 )
|
||||
{
|
||||
if( V[i].V==Value ) // Stat unchanged.
|
||||
{
|
||||
if( V[i].N!=PRI.PlayerName ) // Name has changed, update that.
|
||||
{
|
||||
V[i].N = PRI.PlayerName;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Remove entry and insert it back in list only if rank changed.
|
||||
if( (i>0 && V[i-1].V<Value) || (i<(V.Length-1) && V[i+1].V>Value) )
|
||||
V.Remove(i,1);
|
||||
else // No change in rank.
|
||||
{
|
||||
if( V[i].N!=PRI.PlayerName ) // Name has changed, update that.
|
||||
{
|
||||
V[i].N = PRI.PlayerName;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
for( i=0; i<l; ++i )
|
||||
{
|
||||
if( i==V.Length || V[i].V<Value ) // At final entry, or has higher value then this ranked player.
|
||||
{
|
||||
V.Insert(i,1);
|
||||
V[i].N = PRI.PlayerName;
|
||||
V[i].V = Value;
|
||||
V[i].ID = S;
|
||||
if( V.Length>l ) // See if list has overflown.
|
||||
V.Length = l;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static final function bool GetStat( ExtPlayerController PC, byte ListNum, int StatIndex )
|
||||
{
|
||||
local UniqueNetId ID;
|
||||
|
||||
switch( ListNum )
|
||||
{
|
||||
case 0:
|
||||
if( StatIndex>=Default.TopPlaytimes.Length )
|
||||
return false;
|
||||
class'OnlineSubsystem'.Static.StringToUniqueNetId(Default.TopPlaytimes[StatIndex].ID,ID);
|
||||
PC.ClientGetStat(ListNum,false,Default.TopPlaytimes[StatIndex].N,ID,Default.TopPlaytimes[StatIndex].V);
|
||||
return true;
|
||||
case 1:
|
||||
if( StatIndex>=Default.TopKills.Length )
|
||||
return false;
|
||||
class'OnlineSubsystem'.Static.StringToUniqueNetId(Default.TopKills[StatIndex].ID,ID);
|
||||
PC.ClientGetStat(ListNum,false,Default.TopKills[StatIndex].N,ID,Default.TopKills[StatIndex].V);
|
||||
return true;
|
||||
case 2:
|
||||
if( StatIndex>=Default.TopExp.Length )
|
||||
return false;
|
||||
class'OnlineSubsystem'.Static.StringToUniqueNetId(Default.TopExp[StatIndex].ID,ID);
|
||||
PC.ClientGetStat(ListNum,false,Default.TopExp[StatIndex].N,ID,Default.TopExp[StatIndex].V);
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
281
ServerExtMut/Classes/ExtWebApp.uc
Normal file
281
ServerExtMut/Classes/ExtWebApp.uc
Normal file
@ -0,0 +1,281 @@
|
||||
Class ExtWebApp extends Object implements(IQueryHandler);
|
||||
|
||||
var WebAdmin webadmin;
|
||||
var string ExtWebURL;
|
||||
var int EditPageIndex;
|
||||
var ExtWebAdmin_UI ExtAdminUI;
|
||||
var ServerExtMut MyMutator;
|
||||
|
||||
function cleanup()
|
||||
{
|
||||
webadmin = None;
|
||||
MyMutator = None;
|
||||
if( ExtAdminUI!=None )
|
||||
{
|
||||
ExtAdminUI.Cleanup();
|
||||
ExtAdminUI = None;
|
||||
}
|
||||
}
|
||||
function init(WebAdmin webapp)
|
||||
{
|
||||
webadmin = webapp;
|
||||
}
|
||||
function registerMenuItems(WebAdminMenu menu)
|
||||
{
|
||||
menu.addMenu(ExtWebURL, "ExtServer Mod", self, "Modify settings of Extended Server Mod.", -44);
|
||||
}
|
||||
function bool handleQuery(WebAdminQuery q)
|
||||
{
|
||||
switch (q.request.URI)
|
||||
{
|
||||
case ExtWebURL:
|
||||
handleExtMod(q);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
final function IncludeFile( WebAdminQuery q, string file )
|
||||
{
|
||||
local string S;
|
||||
|
||||
if( webadmin.HTMLSubDirectory!="" )
|
||||
{
|
||||
S = webadmin.Path $ "/" $ webadmin.HTMLSubDirectory $ "/" $ file;
|
||||
if ( q.response.FileExists(S) )
|
||||
{
|
||||
q.response.IncludeUHTM(S);
|
||||
return;
|
||||
}
|
||||
}
|
||||
q.response.IncludeUHTM(webadmin.Path $ "/" $ file);
|
||||
}
|
||||
final function SendHeader( WebAdminQuery q, string Title )
|
||||
{
|
||||
local IQueryHandler handler;
|
||||
|
||||
q.response.Subst("page.title", Title);
|
||||
q.response.Subst("page.description", "");
|
||||
foreach webadmin.handlers(handler)
|
||||
{
|
||||
handler.decoratePage(q);
|
||||
}
|
||||
q.response.Subst("messages", webadmin.renderMessages(q));
|
||||
if (q.session.getString("privilege.log") != "")
|
||||
{
|
||||
q.response.Subst("privilege.log", webadmin.renderPrivilegeLog(q));
|
||||
}
|
||||
IncludeFile(q,"header.inc");
|
||||
q.response.SendText("<div id=\"content\"><h2>"$Title$"</h2></div><div class=\"section\">");
|
||||
}
|
||||
final function SendFooter( WebAdminQuery q )
|
||||
{
|
||||
IncludeFile(q,"navigation.inc");
|
||||
IncludeFile(q,"footer.inc");
|
||||
q.response.ClearSubst();
|
||||
}
|
||||
|
||||
final function AddConfigEditbox( WebAdminQuery q, string InfoStr, string CurVal, int MaxLen, string ResponseVar, string Tooltip, optional bool bSkipTrail )
|
||||
{
|
||||
local string S;
|
||||
|
||||
S = "<TR><TD><abbr title=\""$Tooltip$"\">"$InfoStr$":</abbr></TD><TD><input class=\"textbox\" class=\"text\" name=\""$ResponseVar$"\" value=\""$CurVal$"\"></TD>";
|
||||
if( !bSkipTrail )
|
||||
S $= "</TR>";
|
||||
q.response.SendText(S);
|
||||
}
|
||||
final function AddConfigCheckbox( WebAdminQuery q, string InfoStr, bool bCur, string ResponseVar, string Tooltip )
|
||||
{
|
||||
local string S;
|
||||
|
||||
S = bCur ? " checked" : "";
|
||||
S = "<TR><TD><abbr title=\""$Tooltip$"\">"$InfoStr$":</abbr></TD><TD><input type=\"checkbox\" name=\""$ResponseVar$"\" value=\"1\" "$S$"></TD></TR>";
|
||||
q.response.SendText(S);
|
||||
}
|
||||
final function AddConfigTextbox( WebAdminQuery q, string InfoStr, string CurVal, int Rows, string ResponseVar, string Tooltip )
|
||||
{
|
||||
local string S;
|
||||
|
||||
S = "<TR><TD><abbr title=\""$Tooltip$"\">"$InfoStr$":</abbr></TD><TD>";
|
||||
S $= "<textarea name=\""$ResponseVar$"\" rows=\""$Rows$"\" cols=\"80\">"$CurVal$"</textarea></TD></TR>";
|
||||
q.response.SendText(S);
|
||||
}
|
||||
|
||||
function handleExtMod(WebAdminQuery q)
|
||||
{
|
||||
local int i,j,z;
|
||||
local string S;
|
||||
local delegate<ExtWebAdmin_UI.OnGetValue> GetV;
|
||||
local delegate<ExtWebAdmin_UI.OnSetValue> SetV;
|
||||
local bool bEditArray;
|
||||
|
||||
if( ExtAdminUI==None )
|
||||
{
|
||||
ExtAdminUI = new (None) class'ExtWebAdmin_UI';
|
||||
MyMutator.InitWebAdmin(ExtAdminUI);
|
||||
}
|
||||
|
||||
// First check if user is trying to get to another page.
|
||||
S = q.request.getVariable("GoToPage");
|
||||
if( S!="" )
|
||||
{
|
||||
if( S=="Main Menu" )
|
||||
EditPageIndex = -1;
|
||||
else EditPageIndex = ExtAdminUI.ConfigList.Find('PageName',S);
|
||||
}
|
||||
|
||||
if( EditPageIndex<0 || EditPageIndex>=ExtAdminUI.ConfigList.Length )
|
||||
{
|
||||
// Show main links page.
|
||||
SendHeader(q,"Ext Server Links page");
|
||||
q.response.SendText("<table id=\"settings\" class=\"grid\"><thead><tr><th>Links</th></tr></thead><tbody>");
|
||||
for( i=0; i<ExtAdminUI.ConfigList.Length; ++i )
|
||||
q.response.SendText("<tr><td><form action=\""$webadmin.Path$ExtWebURL$"\"><input class=\"button\" name=\"GoToPage\" type=\"submit\" value=\""$ExtAdminUI.ConfigList[i].PageName$"\"></form></td></tr>");
|
||||
q.response.SendText("</tbody></table></div></div></body></html>");
|
||||
}
|
||||
else
|
||||
{
|
||||
S = q.request.getVariable("edit"$EditPageIndex);
|
||||
bEditArray = false;
|
||||
if( S=="Submit" )
|
||||
{
|
||||
// Read setting values.
|
||||
for( i=0; i<ExtAdminUI.ConfigList[EditPageIndex].Configs.Length; ++i )
|
||||
{
|
||||
S = q.request.getVariable("PR"$i,"#NULL");
|
||||
if( S!="#NULL" )
|
||||
{
|
||||
SetV = ExtAdminUI.ConfigList[EditPageIndex].SetValue;
|
||||
SetV(ExtAdminUI.ConfigList[EditPageIndex].Configs[i].PropName,0,S);
|
||||
}
|
||||
else if( ExtAdminUI.ConfigList[EditPageIndex].Configs[i].PropType==1 ) // Checkboxes return nothing if unchecked.
|
||||
{
|
||||
SetV = ExtAdminUI.ConfigList[EditPageIndex].SetValue;
|
||||
SetV(ExtAdminUI.ConfigList[EditPageIndex].Configs[i].PropName,0,"0");
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( Left(S,5)=="Edit " )
|
||||
{
|
||||
i = ExtAdminUI.ConfigList[EditPageIndex].Configs.Find('UIName',Mid(S,5));
|
||||
if( i!=-1 && ExtAdminUI.ConfigList[EditPageIndex].Configs[i].NumElements==-1 ) // Check if valid.
|
||||
{
|
||||
// Edit dynamic array.
|
||||
bEditArray = true;
|
||||
}
|
||||
}
|
||||
else if( Left(S,7)=="Submit " )
|
||||
{
|
||||
i = ExtAdminUI.ConfigList[EditPageIndex].Configs.Find('UIName',Mid(S,7));
|
||||
if( i!=-1 && ExtAdminUI.ConfigList[EditPageIndex].Configs[i].NumElements==-1 ) // Check if valid.
|
||||
{
|
||||
// Submitted dynamic array values.
|
||||
GetV = ExtAdminUI.ConfigList[EditPageIndex].GetValue;
|
||||
SetV = ExtAdminUI.ConfigList[EditPageIndex].SetValue;
|
||||
z = int(GetV(ExtAdminUI.ConfigList[EditPageIndex].Configs[i].PropName,-1));
|
||||
|
||||
for( j=z; j>=0; --j )
|
||||
{
|
||||
if( q.request.getVariable("DEL"$j)=="1" )
|
||||
SetV(ExtAdminUI.ConfigList[EditPageIndex].Configs[i].PropName,j,"#DELETE");
|
||||
else
|
||||
{
|
||||
S = q.request.getVariable("PR"$j,"New Line");
|
||||
if( S!="New Line" )
|
||||
SetV(ExtAdminUI.ConfigList[EditPageIndex].Configs[i].PropName,j,S);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Show settings page
|
||||
SendHeader(q,ExtAdminUI.ConfigList[EditPageIndex].PageName$" ("$PathName(ExtAdminUI.ConfigList[EditPageIndex].ObjClass)$")");
|
||||
q.response.SendText("<form method=\"post\" action=\""$webadmin.Path$ExtWebURL$"\"><table id=\"settings\" class=\"grid\">");
|
||||
|
||||
if( bEditArray )
|
||||
{
|
||||
q.response.SendText("<table id=\"settings\" class=\"grid\"><thead><tr><th><abbr title=\""$ExtAdminUI.ConfigList[EditPageIndex].Configs[i].UIDesc$"\">Edit Array "$ExtAdminUI.ConfigList[EditPageIndex].Configs[i].UIName$"</abbr></th><th></th><th>Delete Line</th></tr></thead><tbody>");
|
||||
|
||||
GetV = ExtAdminUI.ConfigList[EditPageIndex].GetValue;
|
||||
z = int(GetV(ExtAdminUI.ConfigList[EditPageIndex].Configs[i].PropName,-1));
|
||||
|
||||
for( j=0; j<=z; ++j )
|
||||
{
|
||||
if( j<z )
|
||||
S = GetV(ExtAdminUI.ConfigList[EditPageIndex].Configs[i].PropName,j);
|
||||
else S = "New Line";
|
||||
switch( ExtAdminUI.ConfigList[EditPageIndex].Configs[i].PropType )
|
||||
{
|
||||
case 0: // int
|
||||
AddConfigEditbox(q,"["$j$"]",S,8,"PR"$j,"",true);
|
||||
if( j<z )
|
||||
q.response.SendText("<TD><input type=\"checkbox\" name=\"DEL"$j$"\" value=\"1\" "$S$"></TD></TR>");
|
||||
else q.response.SendText("<TD></TD></TR>");
|
||||
break;
|
||||
case 2: // string
|
||||
AddConfigEditbox(q,"["$j$"]",S,80,"PR"$j,"",true);
|
||||
if( j<z )
|
||||
q.response.SendText("<TD><input type=\"checkbox\" name=\"DEL"$j$"\" value=\"1\" "$S$"></TD></TR>");
|
||||
else q.response.SendText("<TD></TD></TR>");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
q.response.SendText("<tr><td></td><td><input class=\"button\" type=\"submit\" name=\"edit"$EditPageIndex$"\" value=\"Submit "$ExtAdminUI.ConfigList[EditPageIndex].Configs[i].UIName$"\"></td></tr></form>");
|
||||
}
|
||||
else
|
||||
{
|
||||
q.response.SendText("<table id=\"settings\" class=\"grid\"><thead><tr><th>Settings</th></tr></thead><tbody>");
|
||||
for( i=0; i<ExtAdminUI.ConfigList[EditPageIndex].Configs.Length; ++i )
|
||||
{
|
||||
if( ExtAdminUI.ConfigList[EditPageIndex].Configs[i].NumElements==-1 ) // Dynamic array.
|
||||
{
|
||||
GetV = ExtAdminUI.ConfigList[EditPageIndex].GetValue;
|
||||
j = int(GetV(ExtAdminUI.ConfigList[EditPageIndex].Configs[i].PropName,-1));
|
||||
q.response.SendText("<TR><TD><abbr title=\""$ExtAdminUI.ConfigList[EditPageIndex].Configs[i].UIDesc$"\">"$ExtAdminUI.ConfigList[EditPageIndex].Configs[i].UIName$"["$j$"]:</abbr></TD><TD><input class=\"button\" type=\"submit\" name=\"edit"$EditPageIndex$"\" value=\"Edit "$ExtAdminUI.ConfigList[EditPageIndex].Configs[i].UIName$"\"></TD></TR>");
|
||||
}
|
||||
else
|
||||
{
|
||||
GetV = ExtAdminUI.ConfigList[EditPageIndex].GetValue;
|
||||
S = GetV(ExtAdminUI.ConfigList[EditPageIndex].Configs[i].PropName,0);
|
||||
switch( ExtAdminUI.ConfigList[EditPageIndex].Configs[i].PropType )
|
||||
{
|
||||
case 0: // Int
|
||||
AddConfigEditbox(q,ExtAdminUI.ConfigList[EditPageIndex].Configs[i].UIName,S,8,"PR"$i,ExtAdminUI.ConfigList[EditPageIndex].Configs[i].UIDesc);
|
||||
break;
|
||||
case 1: // Bool
|
||||
AddConfigCheckbox(q,ExtAdminUI.ConfigList[EditPageIndex].Configs[i].UIName,bool(S),"PR"$i,ExtAdminUI.ConfigList[EditPageIndex].Configs[i].UIDesc);
|
||||
break;
|
||||
case 2: // String
|
||||
AddConfigEditbox(q,ExtAdminUI.ConfigList[EditPageIndex].Configs[i].UIName,S,80,"PR"$i,ExtAdminUI.ConfigList[EditPageIndex].Configs[i].UIDesc);
|
||||
break;
|
||||
case 3: // Text field
|
||||
AddConfigTextbox(q,ExtAdminUI.ConfigList[EditPageIndex].Configs[i].UIName,S,25,"PR"$i,ExtAdminUI.ConfigList[EditPageIndex].Configs[i].UIDesc);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Submit button
|
||||
q.response.SendText("<tr><td></td><td><input class=\"button\" type=\"submit\" name=\"edit"$EditPageIndex$"\" value=\"Submit\"></td></tr></form>");
|
||||
}
|
||||
|
||||
// Return to main menu button.
|
||||
q.response.SendText("<tr><td><form action=\""$webadmin.Path$ExtWebURL$"\"><input class=\"button\" name=\"GoToPage\" type=\"submit\" value=\"Main Menu\"></form></td></tr>");
|
||||
q.response.SendText("</tbody></table></div></div></body></html>");
|
||||
}
|
||||
SendFooter(q);
|
||||
}
|
||||
|
||||
function bool producesXhtml()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
function bool unhandledQuery(WebAdminQuery q);
|
||||
function decoratePage(WebAdminQuery q);
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
ExtWebURL="/settings/ExtServerMod"
|
||||
EditPageIndex=-1
|
||||
}
|
43
ServerExtMut/Classes/ExtXMLOutput.uc
Normal file
43
ServerExtMut/Classes/ExtXMLOutput.uc
Normal file
@ -0,0 +1,43 @@
|
||||
Class ExtXMLOutput extends FileWriter implements(ExtStatWriter);
|
||||
|
||||
var transient string Intendent;
|
||||
var transient array<string> StackedSect;
|
||||
|
||||
event PreBeginPlay();
|
||||
|
||||
final function DumpXML( ExtPerkManager M )
|
||||
{
|
||||
OpenFile(class'OnlineSubsystem'.Static.UniqueNetIdToString(M.PRIOwner.UniqueId),FWFT_Stats,".xml",false);
|
||||
M.OutputXML(Self);
|
||||
CloseFile();
|
||||
ResetFile();
|
||||
}
|
||||
|
||||
function WriteValue( string Key, string Value )
|
||||
{
|
||||
Logf(Intendent$"<"$Key$">"$Value$"</"$Key$">");
|
||||
}
|
||||
function StartIntendent( string Section, optional string Key, optional string Value )
|
||||
{
|
||||
if( Key!="" )
|
||||
Logf(Intendent$"-<"$Section$" "$Key$"=\""$Value$"\">");
|
||||
else Logf(Intendent$"-<"$Section$">");
|
||||
Intendent $= Chr(9);
|
||||
StackedSect.AddItem(Section);
|
||||
}
|
||||
function EndIntendent()
|
||||
{
|
||||
Intendent = Left(Intendent,Len(Intendent)-1);
|
||||
Logf(Intendent$"</"$StackedSect[StackedSect.Length-1]$">");
|
||||
StackedSect.Remove(StackedSect.Length-1,1);
|
||||
}
|
||||
function ResetFile()
|
||||
{
|
||||
Intendent = "";
|
||||
StackedSect.Length = 0;
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
bFlushEachWrite=false
|
||||
}
|
1543
ServerExtMut/Classes/ServerExtMut.uc
Normal file
1543
ServerExtMut/Classes/ServerExtMut.uc
Normal file
File diff suppressed because it is too large
Load Diff
4
ServerExtMut/Classes/ServerExtMut.upkg
Normal file
4
ServerExtMut/Classes/ServerExtMut.upkg
Normal file
@ -0,0 +1,4 @@
|
||||
[Flags]
|
||||
AllowDownload=False
|
||||
ClientOptional=False
|
||||
ServerSideOnly=True
|
2
ServerExtMut/Classes/desktop.ini
Normal file
2
ServerExtMut/Classes/desktop.ini
Normal file
@ -0,0 +1,2 @@
|
||||
[.ShellClassInfo]
|
||||
IconResource=C:\Users\Carte\AppData\Roaming\Insync\App\res\shared-folder-vista-7.ico,0
|
57
ServerExtMut/Classes/xMapVoteHistory.uc
Normal file
57
ServerExtMut/Classes/xMapVoteHistory.uc
Normal file
@ -0,0 +1,57 @@
|
||||
Class xMapVoteHistory extends Object
|
||||
config(xMapVoteHistory);
|
||||
|
||||
var config array<string> M;
|
||||
struct FMapInfoEntry
|
||||
{
|
||||
var config int U,D,S,N;
|
||||
var config string T;
|
||||
};
|
||||
var config array<FMapInfoEntry> N;
|
||||
|
||||
static final function int GetMapHistory( string MapName, string MapTitle )
|
||||
{
|
||||
local int i;
|
||||
|
||||
MapName = Caps(MapName);
|
||||
i = Default.M.Find(MapName);
|
||||
if( i==-1 )
|
||||
{
|
||||
i = Default.M.Length;
|
||||
Default.M.Length = i+1;
|
||||
Default.M[i] = MapName;
|
||||
Default.N.Length = i+1;
|
||||
}
|
||||
if( !(MapTitle~=MapName) && MapTitle!=Class'WorldInfo'.Default.Title && MapTitle!="" )
|
||||
Default.N[i].T = MapTitle;
|
||||
return i;
|
||||
}
|
||||
static final function GetHistory( int i, out int UpVotes, out int DownVotes, out int Seq, out int NumP, out string Title )
|
||||
{
|
||||
UpVotes = Default.N[i].U;
|
||||
DownVotes = Default.N[i].D;
|
||||
Seq = Default.N[i].S;
|
||||
NumP = Default.N[i].N;
|
||||
Title = Default.N[i].T;
|
||||
}
|
||||
|
||||
static final function UpdateMapHistory( int iWon )
|
||||
{
|
||||
local int i;
|
||||
|
||||
for( i=(Default.M.Length-1); i>=0; --i )
|
||||
{
|
||||
if( i==iWon )
|
||||
{
|
||||
++Default.N[i].N;
|
||||
Default.N[i].S = 0;
|
||||
}
|
||||
else ++Default.N[i].S;
|
||||
}
|
||||
}
|
||||
static final function AddMapKarma( int i, bool bUp )
|
||||
{
|
||||
if( bUp )
|
||||
++Default.N[i].U;
|
||||
else ++Default.N[i].D;
|
||||
}
|
37
ServerExtMut/Classes/xVoteBroadcast.uc
Normal file
37
ServerExtMut/Classes/xVoteBroadcast.uc
Normal file
@ -0,0 +1,37 @@
|
||||
class xVoteBroadcast extends BroadcastHandler;
|
||||
|
||||
var BroadcastHandler NextBroadcaster;
|
||||
var xVotingHandler Handler;
|
||||
|
||||
function UpdateSentText()
|
||||
{
|
||||
NextBroadcaster.UpdateSentText();
|
||||
}
|
||||
|
||||
function Broadcast( Actor Sender, coerce string Msg, optional name Type )
|
||||
{
|
||||
if( (Type=='Say' || Type=='TeamSay') && Left(Msg,1)=="!" && PlayerController(Sender)!=None )
|
||||
Handler.ParseCommand(Mid(Msg,1),PlayerController(Sender));
|
||||
NextBroadcaster.Broadcast(Sender,Msg,Type);
|
||||
}
|
||||
|
||||
function BroadcastTeam( Controller Sender, coerce string Msg, optional name Type )
|
||||
{
|
||||
if( (Type=='Say' || Type=='TeamSay') && Left(Msg,1)=="!" && PlayerController(Sender)!=None )
|
||||
Handler.ParseCommand(Mid(Msg,1),PlayerController(Sender));
|
||||
NextBroadcaster.BroadcastTeam(Sender,Msg,Type);
|
||||
}
|
||||
|
||||
function AllowBroadcastLocalized( actor Sender, class<LocalMessage> Message, optional int Switch, optional PlayerReplicationInfo RelatedPRI_1, optional PlayerReplicationInfo RelatedPRI_2, optional Object OptionalObject )
|
||||
{
|
||||
NextBroadcaster.AllowBroadcastLocalized(Sender,Message,Switch,RelatedPRI_1,RelatedPRI_2,OptionalObject);
|
||||
}
|
||||
|
||||
event AllowBroadcastLocalizedTeam( int TeamIndex, actor Sender, class<LocalMessage> Message, optional int Switch, optional PlayerReplicationInfo RelatedPRI_1, optional PlayerReplicationInfo RelatedPRI_2, optional Object OptionalObject )
|
||||
{
|
||||
NextBroadcaster.AllowBroadcastLocalizedTeam(TeamIndex,Sender,Message,Switch,RelatedPRI_1,RelatedPRI_2,OptionalObject);
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
}
|
198
ServerExtMut/Classes/xVoteWebApp.uc
Normal file
198
ServerExtMut/Classes/xVoteWebApp.uc
Normal file
@ -0,0 +1,198 @@
|
||||
Class xVoteWebApp extends Object implements(IQueryHandler);
|
||||
|
||||
var WebAdmin webadmin;
|
||||
var string MapVoterURL;
|
||||
var int EditSettingLine;
|
||||
|
||||
function cleanup()
|
||||
{
|
||||
webadmin = None;
|
||||
}
|
||||
function init(WebAdmin webapp)
|
||||
{
|
||||
webadmin = webapp;
|
||||
}
|
||||
function registerMenuItems(WebAdminMenu menu)
|
||||
{
|
||||
menu.addMenu(MapVoterURL, "X - Mapvote", self, "Modify settings of mapvote.", -88);
|
||||
}
|
||||
function bool handleQuery(WebAdminQuery q)
|
||||
{
|
||||
switch (q.request.URI)
|
||||
{
|
||||
case MapVoterURL:
|
||||
handleMapVotes(q);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
final function IncludeFile( WebAdminQuery q, string file )
|
||||
{
|
||||
local string S;
|
||||
|
||||
if( webadmin.HTMLSubDirectory!="" )
|
||||
{
|
||||
S = webadmin.Path $ "/" $ webadmin.HTMLSubDirectory $ "/" $ file;
|
||||
if ( q.response.FileExists(S) )
|
||||
{
|
||||
q.response.IncludeUHTM(S);
|
||||
return;
|
||||
}
|
||||
}
|
||||
q.response.IncludeUHTM(webadmin.Path $ "/" $ file);
|
||||
}
|
||||
final function SendHeader( WebAdminQuery q, string Title )
|
||||
{
|
||||
local IQueryHandler handler;
|
||||
|
||||
q.response.Subst("page.title", Title);
|
||||
q.response.Subst("page.description", "");
|
||||
foreach webadmin.handlers(handler)
|
||||
{
|
||||
handler.decoratePage(q);
|
||||
}
|
||||
q.response.Subst("messages", webadmin.renderMessages(q));
|
||||
if (q.session.getString("privilege.log") != "")
|
||||
{
|
||||
q.response.Subst("privilege.log", webadmin.renderPrivilegeLog(q));
|
||||
}
|
||||
IncludeFile(q,"header.inc");
|
||||
q.response.SendText("<div id=\"content\"><h2>"$Title$"</h2></div><div class=\"section\">");
|
||||
}
|
||||
final function SendFooter( WebAdminQuery q )
|
||||
{
|
||||
IncludeFile(q,"navigation.inc");
|
||||
IncludeFile(q,"footer.inc");
|
||||
q.response.ClearSubst();
|
||||
}
|
||||
|
||||
final function AddConfigEditbox( WebAdminQuery q, string InfoStr, string CurVal, int MaxLen, string ResponseVar, string Tooltip, optional bool bNoTR )
|
||||
{
|
||||
local string S;
|
||||
|
||||
S = "<abbr title=\""$Tooltip$"\"><TD>"$InfoStr$":</TD><TD><input class=\"textbox\" class=\"text\" name=\""$ResponseVar$"\" size=\""$Min(100,MaxLen)$"\" value=\""$CurVal$"\" maxlength=\""$MaxLen$"\"></TD></abbr>";
|
||||
if( !bNoTR )
|
||||
S = "<TR>"$S$"</TR>";
|
||||
q.response.SendText(S);
|
||||
}
|
||||
final function AddInLineEditbox( WebAdminQuery q, string CurVal, int MaxLen, string ResponseVar, string Tooltip )
|
||||
{
|
||||
q.response.SendText("<abbr title=\""$Tooltip$"\"><TD><input class=\"textbox\" class=\"text\" name=\""$ResponseVar$"\" size=\""$Min(100,MaxLen)$"\" value=\""$CurVal$"\" maxlength=\""$MaxLen$"\"></TD></abbr>");
|
||||
}
|
||||
function handleMapVotes(WebAdminQuery q)
|
||||
{
|
||||
local int i;
|
||||
local string S;
|
||||
|
||||
S = q.request.getVariable("edit");
|
||||
if( S=="Submit" )
|
||||
{
|
||||
class'xVotingHandler'.Default.VoteTime = int(q.request.getVariable("VT",string(class'xVotingHandler'.Default.VoteTime)));
|
||||
class'xVotingHandler'.Default.MidGameVotePct = float(q.request.getVariable("MV",string(class'xVotingHandler'.Default.MidGameVotePct)));
|
||||
class'xVotingHandler'.Default.MapWinPct = float(q.request.getVariable("VP",string(class'xVotingHandler'.Default.MapWinPct)));
|
||||
class'xVotingHandler'.Default.MapChangeDelay = float(q.request.getVariable("SD",string(class'xVotingHandler'.Default.MapChangeDelay)));
|
||||
class'xVotingHandler'.Default.MaxMapsOnList = int(q.request.getVariable("MXP",string(class'xVotingHandler'.Default.MaxMapsOnList)));
|
||||
class'xVotingHandler'.Static.StaticSaveConfig();
|
||||
EditSettingLine = -1;
|
||||
}
|
||||
else if( S=="New" )
|
||||
{
|
||||
i = class'xVotingHandler'.Default.GameModes.Length;
|
||||
class'xVotingHandler'.Default.GameModes.Length = i+1;
|
||||
class'xVotingHandler'.Default.GameModes[i].GameName = "Killing Floor";
|
||||
class'xVotingHandler'.Default.GameModes[i].GameShortName = "KF";
|
||||
class'xVotingHandler'.Default.GameModes[i].GameClass = "KFGameContent.KFGameInfo_Survival";
|
||||
EditSettingLine = i;
|
||||
class'xVotingHandler'.Static.StaticSaveConfig();
|
||||
}
|
||||
else if( S=="Save" )
|
||||
{
|
||||
if( EditSettingLine>=0 && EditSettingLine<class'xVotingHandler'.Default.GameModes.Length )
|
||||
{
|
||||
i = EditSettingLine;
|
||||
class'xVotingHandler'.Default.GameModes[i].GameName = q.request.getVariable("GN",class'xVotingHandler'.Default.GameModes[i].GameName);
|
||||
class'xVotingHandler'.Default.GameModes[i].GameShortName = q.request.getVariable("GS",class'xVotingHandler'.Default.GameModes[i].GameName);
|
||||
class'xVotingHandler'.Default.GameModes[i].GameClass = q.request.getVariable("GC",class'xVotingHandler'.Default.GameModes[i].GameName);
|
||||
class'xVotingHandler'.Default.GameModes[i].Mutators = q.request.getVariable("MM",class'xVotingHandler'.Default.GameModes[i].GameName);
|
||||
class'xVotingHandler'.Default.GameModes[i].Options = q.request.getVariable("OP",class'xVotingHandler'.Default.GameModes[i].GameName);
|
||||
class'xVotingHandler'.Default.GameModes[i].Prefix = q.request.getVariable("PF",class'xVotingHandler'.Default.GameModes[i].GameName);
|
||||
class'xVotingHandler'.Static.StaticSaveConfig();
|
||||
}
|
||||
EditSettingLine = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
for( i=0; i<class'xVotingHandler'.Default.GameModes.Length; ++i )
|
||||
{
|
||||
S = q.request.getVariable("edit"$i);
|
||||
if( S=="Delete" )
|
||||
{
|
||||
class'xVotingHandler'.Default.GameModes.Remove(i,1);
|
||||
class'xVotingHandler'.Static.StaticSaveConfig();
|
||||
EditSettingLine = -1;
|
||||
break;
|
||||
}
|
||||
else if( S=="Edit" )
|
||||
{
|
||||
EditSettingLine = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SendHeader(q,"X - Mapvote");
|
||||
q.response.SendText("<form method=\"post\" action=\""$webadmin.Path$MapVoterURL$"\"><table id=\"settings\" class=\"grid\">");
|
||||
q.response.SendText("<thead><tr><th colspan=2>Mapvote settings</th></tr></thead><tbody>");
|
||||
AddConfigEditbox(q,"Mapvote time",string(class'xVotingHandler'.Default.VoteTime),8,"VT","Time in seconds people have to cast mapvote");
|
||||
AddConfigEditbox(q,"Mid-Game vote pct",string(class'xVotingHandler'.Default.MidGameVotePct),12,"MV","Number of people in percent needs to vote to make game initiate mid-game mapvote");
|
||||
AddConfigEditbox(q,"Map win vote pct",string(class'xVotingHandler'.Default.MapWinPct),12,"VP","Number of people in percent needs to vote for same map for mapvote instantly switch to it");
|
||||
AddConfigEditbox(q,"Map switch delay",string(class'xVotingHandler'.Default.MapChangeDelay),12,"SD","Time in seconds delay after a mapvote has passed, when server actually switches map");
|
||||
AddConfigEditbox(q,"Max Maps On List",string(class'xVotingHandler'.Default.MaxMapsOnList),8,"MXP","Maximum maps that should show on mapvote GUI before starting to remove random ones (0 = no limit)");
|
||||
q.response.SendText("<tr><td></td><td><input class=\"button\" type=\"submit\" name=\"edit\" value=\"Submit\"></td></tr>");
|
||||
q.response.SendText("</tbody></table></form>");
|
||||
q.response.SendText("<form method=\"post\" action=\""$webadmin.Path$MapVoterURL$"\"><table id=\"settings\" class=\"grid\">");
|
||||
q.response.SendText("<thead><tr><th colspan=7>Mapvote game modes</th></tr></thead><tbody>");
|
||||
q.response.SendText("<tr><th>Game Name</th><th>Game Short Name</th><th>Game Class</th><th>Mutators</th><th>Options</th><th>Map Prefix</th><th></th></tr>");
|
||||
for( i=0; i<class'xVotingHandler'.Default.GameModes.Length; ++i )
|
||||
{
|
||||
if( EditSettingLine==i )
|
||||
{
|
||||
q.response.SendText("<tr>",false);
|
||||
AddInLineEditbox(q,class'xVotingHandler'.Default.GameModes[i].GameName,48,"GN","Game type long display name");
|
||||
AddInLineEditbox(q,class'xVotingHandler'.Default.GameModes[i].GameShortName,12,"GS","Game type short display name");
|
||||
AddInLineEditbox(q,class'xVotingHandler'.Default.GameModes[i].GameClass,38,"GC","Game type class name to run");
|
||||
AddInLineEditbox(q,class'xVotingHandler'.Default.GameModes[i].Mutators,120,"MM","List of mutators to run along with this game option (separated with commas)");
|
||||
AddInLineEditbox(q,class'xVotingHandler'.Default.GameModes[i].Options,100,"OP","List of options to run along with this game option (separated with question mark)");
|
||||
AddInLineEditbox(q,class'xVotingHandler'.Default.GameModes[i].Prefix,16,"PF","Maps prefix to filter out maps not wanted for this game mode");
|
||||
q.response.SendText("</td><td><input class=\"button\" type=\"submit\" name=\"edit\" value=\"Save\"><input class=\"button\" type=\"submit\" name=\"edit"$i$"\" value=\"Delete\"></td></tr>");
|
||||
}
|
||||
else
|
||||
{
|
||||
q.response.SendText("<tr><td>"$class'xVotingHandler'.Default.GameModes[i].GameName$
|
||||
"</td><td>"$class'xVotingHandler'.Default.GameModes[i].GameShortName$
|
||||
"</td><td>"$class'xVotingHandler'.Default.GameModes[i].GameClass$
|
||||
"</td><td>"$class'xVotingHandler'.Default.GameModes[i].Mutators$
|
||||
"</td><td>"$class'xVotingHandler'.Default.GameModes[i].Options$
|
||||
"</td><td>"$class'xVotingHandler'.Default.GameModes[i].Prefix$
|
||||
"</td><td><input class=\"button\" type=\"submit\" name=\"edit"$i$"\" value=\"Edit\"><input class=\"button\" type=\"submit\" name=\"edit"$i$"\" value=\"Delete\"></td></tr>");
|
||||
}
|
||||
}
|
||||
q.response.SendText("<tr><td><input class=\"button\" type=\"submit\" name=\"edit\" value=\"New\"></td></tr>");
|
||||
q.response.SendText("</tbody></table></form>");
|
||||
q.response.SendText("</div></body></html>");
|
||||
SendFooter(q);
|
||||
}
|
||||
|
||||
function bool producesXhtml()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
function bool unhandledQuery(WebAdminQuery q);
|
||||
function decoratePage(WebAdminQuery q);
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
MapVoterURL="/settings/xMapVoter"
|
||||
EditSettingLine=-1
|
||||
}
|
558
ServerExtMut/Classes/xVotingHandler.uc
Normal file
558
ServerExtMut/Classes/xVotingHandler.uc
Normal file
@ -0,0 +1,558 @@
|
||||
Class xVotingHandler extends xVotingHandlerBase
|
||||
config(xMapVote);
|
||||
|
||||
struct FGameModeOption
|
||||
{
|
||||
var config string GameName,GameShortName,GameClass,Mutators,Options,Prefix;
|
||||
};
|
||||
var config array<FGameModeOption> GameModes;
|
||||
var config int LastVotedGameInfo,VoteTime,MaxMapsOnList;
|
||||
var config float MidGameVotePct,MapWinPct,MapChangeDelay;
|
||||
var config bool bNoWebAdmin;
|
||||
|
||||
var class<Mutator> BaseMutator;
|
||||
|
||||
var array<SoundCue> AnnouncerCues;
|
||||
var array<FMapEntry> Maps;
|
||||
var array<FVotedMaps> ActiveVotes;
|
||||
var array<xVotingReplication> ActiveVoters;
|
||||
var int iCurrentHistory,VoteTimeLeft,ShowMenuDelay;
|
||||
var string PendingMapURL;
|
||||
var KFGameReplicationInfo KF;
|
||||
var bool bMapvoteHasEnded,bMapVoteTimer,bHistorySaved;
|
||||
|
||||
function PostBeginPlay()
|
||||
{
|
||||
local int i,j,z,n,UpV,DownV,Seq,NumPl;
|
||||
local string S,MapFile;
|
||||
|
||||
if( WorldInfo.Game.BaseMutator==None )
|
||||
WorldInfo.Game.BaseMutator = Self;
|
||||
else WorldInfo.Game.BaseMutator.AddMutator(Self);
|
||||
|
||||
if( bDeleteMe ) // This was a duplicate instance of the mutator.
|
||||
return;
|
||||
|
||||
MapFile = string(WorldInfo.GetPackageName());
|
||||
iCurrentHistory = class'xMapVoteHistory'.Static.GetMapHistory(MapFile,WorldInfo.Title);
|
||||
if( LastVotedGameInfo<0 || LastVotedGameInfo>=GameModes.Length )
|
||||
LastVotedGameInfo = 0;
|
||||
|
||||
if( MapChangeDelay==0 )
|
||||
MapChangeDelay = 3;
|
||||
if( GameModes.Length==0 ) // None specified, so use current settings.
|
||||
{
|
||||
GameModes.Length = 1;
|
||||
GameModes[0].GameName = "Killing Floor";
|
||||
GameModes[0].GameShortName = "KF";
|
||||
GameModes[0].GameClass = PathName(WorldInfo.Game.Class);
|
||||
GameModes[0].Mutators = "";
|
||||
GameModes[0].Prefix = "";
|
||||
MidGameVotePct = 0.51;
|
||||
MapWinPct = 0.75;
|
||||
VoteTime = 35;
|
||||
SaveConfig();
|
||||
}
|
||||
|
||||
// Build maplist.
|
||||
z = 0;
|
||||
for( i=(Class'KFGameInfo'.Default.GameMapCycles.Length-1); i>=0; --i )
|
||||
{
|
||||
for( j=(Class'KFGameInfo'.Default.GameMapCycles[i].Maps.Length-1); j>=0; --j )
|
||||
{
|
||||
if( MaxMapsOnList>0 && Class'KFGameInfo'.Default.GameMapCycles[i].Maps[j]~=MapFile ) // If we limit the maps count, remove current map.
|
||||
continue;
|
||||
Maps.Length = z+1;
|
||||
Maps[z].MapName = Class'KFGameInfo'.Default.GameMapCycles[i].Maps[j];
|
||||
n = class'xMapVoteHistory'.Static.GetMapHistory(Maps[z].MapName,"");
|
||||
class'xMapVoteHistory'.Static.GetHistory(n,UpV,DownV,Seq,NumPl,S);
|
||||
Maps[z].UpVotes = UpV;
|
||||
Maps[z].DownVotes = DownV;
|
||||
Maps[z].Sequence = Seq;
|
||||
Maps[z].NumPlays = NumPl;
|
||||
Maps[z].History = n;
|
||||
Maps[z].MapTitle = S;
|
||||
++z;
|
||||
}
|
||||
}
|
||||
|
||||
if( MaxMapsOnList>0 )
|
||||
{
|
||||
// Remove random maps from list.
|
||||
while( Maps.Length>MaxMapsOnList )
|
||||
Maps.Remove(Rand(Maps.Length),1);
|
||||
}
|
||||
|
||||
SetTimer(0.15,false,'SetupBroadcast');
|
||||
SetTimer(1,true,'CheckEndGameEnded');
|
||||
}
|
||||
function AddMutator(Mutator M)
|
||||
{
|
||||
if( M!=Self ) // Make sure we don't get added twice.
|
||||
{
|
||||
if( M.Class==Class )
|
||||
M.Destroy();
|
||||
else Super.AddMutator(M);
|
||||
}
|
||||
}
|
||||
|
||||
function SetupBroadcast()
|
||||
{
|
||||
local xVoteBroadcast B;
|
||||
local WebServer W;
|
||||
local WebAdmin A;
|
||||
local xVoteWebApp xW;
|
||||
local byte i;
|
||||
|
||||
B = Spawn(class'xVoteBroadcast');
|
||||
B.Handler = Self;
|
||||
B.NextBroadcaster = WorldInfo.Game.BroadcastHandler;
|
||||
WorldInfo.Game.BroadcastHandler = B;
|
||||
if( !bNoWebAdmin )
|
||||
{
|
||||
foreach AllActors(class'WebServer',W)
|
||||
break;
|
||||
if( W!=None )
|
||||
{
|
||||
for( i=0; (i<10 && A==None); ++i )
|
||||
A = WebAdmin(W.ApplicationObjects[i]);
|
||||
if( A!=None )
|
||||
{
|
||||
xW = new (None) class'xVoteWebApp';
|
||||
A.addQueryHandler(xW);
|
||||
}
|
||||
else `Log("X-VoteWebAdmin ERROR: No valid WebAdmin application found!");
|
||||
}
|
||||
else `Log("X-VoteWebAdmin ERROR: No WebServer object found!");
|
||||
}
|
||||
}
|
||||
final function AddVote( int Count, int MapIndex, int GameIndex )
|
||||
{
|
||||
local int i,j;
|
||||
|
||||
if( bMapvoteHasEnded )
|
||||
return;
|
||||
for( i=0; i<ActiveVotes.Length; ++i )
|
||||
if( ActiveVotes[i].GameIndex==GameIndex && ActiveVotes[i].MapIndex==MapIndex )
|
||||
{
|
||||
ActiveVotes[i].NumVotes += Count;
|
||||
for( j=(ActiveVoters.Length-1); j>=0; --j )
|
||||
ActiveVoters[j].ClientReceiveVote(GameIndex,MapIndex,ActiveVotes[i].NumVotes);
|
||||
if( ActiveVotes[i].NumVotes<=0 )
|
||||
{
|
||||
for( j=(ActiveVoters.Length-1); j>=0; --j )
|
||||
if( ActiveVoters[j].DownloadStage==2 && ActiveVoters[j].DownloadIndex>=i && ActiveVoters[j].DownloadIndex>0 ) // Make sure client doesn't skip a download at this point.
|
||||
--ActiveVoters[j].DownloadIndex;
|
||||
ActiveVotes.Remove(i,1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if( Count<=0 )
|
||||
return;
|
||||
ActiveVotes.Length = i+1;
|
||||
ActiveVotes[i].GameIndex = GameIndex;
|
||||
ActiveVotes[i].MapIndex = MapIndex;
|
||||
ActiveVotes[i].NumVotes = Count;
|
||||
for( j=(ActiveVoters.Length-1); j>=0; --j )
|
||||
ActiveVoters[j].ClientReceiveVote(GameIndex,MapIndex,Count);
|
||||
}
|
||||
final function LogoutPlayer( PlayerController PC )
|
||||
{
|
||||
local int i;
|
||||
|
||||
for( i=(ActiveVoters.Length-1); i>=0; --i )
|
||||
if( ActiveVoters[i].PlayerOwner==PC )
|
||||
{
|
||||
ActiveVoters[i].Destroy();
|
||||
break;
|
||||
}
|
||||
}
|
||||
final function LoginPlayer( PlayerController PC )
|
||||
{
|
||||
local xVotingReplication R;
|
||||
local int i;
|
||||
|
||||
for( i=(ActiveVoters.Length-1); i>=0; --i )
|
||||
if( ActiveVoters[i].PlayerOwner==PC )
|
||||
return;
|
||||
R = Spawn(class'xVotingReplication',PC);
|
||||
R.VoteHandler = Self;
|
||||
ActiveVoters.AddItem(R);
|
||||
}
|
||||
|
||||
function NotifyLogout(Controller Exiting)
|
||||
{
|
||||
if( PlayerController(Exiting)!=None )
|
||||
LogoutPlayer(PlayerController(Exiting));
|
||||
if ( NextMutator != None )
|
||||
NextMutator.NotifyLogout(Exiting);
|
||||
}
|
||||
function NotifyLogin(Controller NewPlayer)
|
||||
{
|
||||
if( PlayerController(NewPlayer)!=None )
|
||||
LoginPlayer(PlayerController(NewPlayer));
|
||||
if ( NextMutator != None )
|
||||
NextMutator.NotifyLogin(NewPlayer);
|
||||
}
|
||||
|
||||
function ClientDownloadInfo( xVotingReplication V )
|
||||
{
|
||||
if( bMapvoteHasEnded )
|
||||
{
|
||||
V.DownloadStage = 255;
|
||||
return;
|
||||
}
|
||||
|
||||
switch( V.DownloadStage )
|
||||
{
|
||||
case 0: // Game modes.
|
||||
if( V.DownloadIndex>=GameModes.Length )
|
||||
break;
|
||||
V.ClientReceiveGame(V.DownloadIndex,GameModes[V.DownloadIndex].GameName,GameModes[V.DownloadIndex].GameShortName,GameModes[V.DownloadIndex].Prefix);
|
||||
++V.DownloadIndex;
|
||||
return;
|
||||
case 1: // Maplist.
|
||||
if( V.DownloadIndex>=Maps.Length )
|
||||
break;
|
||||
if( Maps[V.DownloadIndex].MapTitle=="" )
|
||||
V.ClientReceiveMap(V.DownloadIndex,Maps[V.DownloadIndex].MapName,Maps[V.DownloadIndex].UpVotes,Maps[V.DownloadIndex].DownVotes,Maps[V.DownloadIndex].Sequence,Maps[V.DownloadIndex].NumPlays);
|
||||
else V.ClientReceiveMap(V.DownloadIndex,Maps[V.DownloadIndex].MapName,Maps[V.DownloadIndex].UpVotes,Maps[V.DownloadIndex].DownVotes,Maps[V.DownloadIndex].Sequence,Maps[V.DownloadIndex].NumPlays,Maps[V.DownloadIndex].MapTitle);
|
||||
++V.DownloadIndex;
|
||||
return;
|
||||
case 2: // Current votes.
|
||||
if( V.DownloadIndex>=ActiveVotes.Length )
|
||||
break;
|
||||
V.ClientReceiveVote(ActiveVotes[V.DownloadIndex].GameIndex,ActiveVotes[V.DownloadIndex].MapIndex,ActiveVotes[V.DownloadIndex].NumVotes);
|
||||
++V.DownloadIndex;
|
||||
return;
|
||||
default:
|
||||
V.ClientReady(LastVotedGameInfo);
|
||||
V.DownloadStage = 255;
|
||||
return;
|
||||
}
|
||||
++V.DownloadStage;
|
||||
V.DownloadIndex = 0;
|
||||
}
|
||||
function ClientCastVote( xVotingReplication V, int GameIndex, int MapIndex, bool bAdminForce )
|
||||
{
|
||||
local int i;
|
||||
|
||||
if( bMapvoteHasEnded )
|
||||
return;
|
||||
|
||||
if( bAdminForce && V.PlayerOwner.PlayerReplicationInfo.bAdmin )
|
||||
{
|
||||
SwitchToLevel(GameIndex,MapIndex,true);
|
||||
return;
|
||||
}
|
||||
if( !Class'xUI_MapVote'.Static.BelongsToPrefix(Maps[MapIndex].MapName,GameModes[GameIndex].Prefix) )
|
||||
{
|
||||
V.PlayerOwner.ClientMessage("Error: Can't vote that map (wrong Prefix to that game mode)!");
|
||||
return;
|
||||
}
|
||||
if( V.CurrentVote[0]>=0 )
|
||||
AddVote(-1,V.CurrentVote[1],V.CurrentVote[0]);
|
||||
V.CurrentVote[0] = GameIndex;
|
||||
V.CurrentVote[1] = MapIndex;
|
||||
AddVote(1,MapIndex,GameIndex);
|
||||
for( i=(ActiveVoters.Length-1); i>=0; --i )
|
||||
ActiveVoters[i].ClientNotifyVote(V.PlayerOwner.PlayerReplicationInfo,GameIndex,MapIndex);
|
||||
TallyVotes();
|
||||
}
|
||||
function ClientRankMap( xVotingReplication V, bool bUp )
|
||||
{
|
||||
class'xMapVoteHistory'.Static.AddMapKarma(iCurrentHistory,bUp);
|
||||
}
|
||||
function ClientDisconnect( xVotingReplication V )
|
||||
{
|
||||
ActiveVoters.RemoveItem(V);
|
||||
if( V.CurrentVote[0]>=0 )
|
||||
AddVote(-1,V.CurrentVote[1],V.CurrentVote[0]);
|
||||
TallyVotes();
|
||||
}
|
||||
|
||||
final function float GetPctOf( int Nom, int Denom )
|
||||
{
|
||||
local float R;
|
||||
|
||||
R = float(Nom) / float(Denom);
|
||||
return R;
|
||||
}
|
||||
final function TallyVotes( optional bool bForce )
|
||||
{
|
||||
local int i,NumVotees,c,j;
|
||||
local array<int> Candidates;
|
||||
|
||||
if( bMapvoteHasEnded )
|
||||
return;
|
||||
|
||||
NumVotees = ActiveVoters.Length;
|
||||
c = 0;
|
||||
|
||||
if( bForce )
|
||||
{
|
||||
// First check for highest result.
|
||||
for( i=(ActiveVotes.Length-1); i>=0; --i )
|
||||
c = Max(c,ActiveVotes[i].NumVotes);
|
||||
|
||||
if( c>0 )
|
||||
{
|
||||
// Then check how many votes for the best.
|
||||
for( i=(ActiveVotes.Length-1); i>=0; --i )
|
||||
if( ActiveVotes[i].NumVotes==c )
|
||||
Candidates.AddItem(i);
|
||||
|
||||
// Finally pick a random winner from the best.
|
||||
c = Candidates[Rand(Candidates.Length)];
|
||||
|
||||
if( NumVotees>=4 && ActiveVotes.Length==1 ) // If more then 4 voters and everyone voted same map?!!! Give the mapvote some orgy.
|
||||
{
|
||||
for( j=(ActiveVoters.Length-1); j>=0; --j )
|
||||
ActiveVoters[j].PlayerOwner.ClientPlaySound(AnnouncerCues[13]);
|
||||
}
|
||||
SwitchToLevel(ActiveVotes[c].GameIndex,ActiveVotes[c].MapIndex,false);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Pick a random map to win.
|
||||
c = Rand(Maps.Length);
|
||||
|
||||
// Pick a random gametype to win along with it.
|
||||
for( i=(GameModes.Length-1); i>=0; --i )
|
||||
if( Class'xUI_MapVote'.Static.BelongsToPrefix(Maps[c].MapName,GameModes[i].Prefix) )
|
||||
Candidates.AddItem(i);
|
||||
|
||||
if( Candidates.Length==0 ) // Odd, a map without gametype...
|
||||
i = Rand(GameModes.Length);
|
||||
else i = Candidates[Rand(Candidates.Length)];
|
||||
|
||||
SwitchToLevel(i,c,false);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Check for insta-win vote.
|
||||
for( i=(ActiveVotes.Length-1); i>=0; --i )
|
||||
{
|
||||
c+=ActiveVotes[i].NumVotes;
|
||||
if( GetPctOf(ActiveVotes[i].NumVotes,NumVotees)>=MapWinPct )
|
||||
{
|
||||
if( NumVotees>=4 && ActiveVotes.Length==1 ) // If more then 4 voters and everyone voted same map?!!! Give the mapvote some orgy.
|
||||
{
|
||||
for( j=(ActiveVoters.Length-1); j>=0; --j )
|
||||
ActiveVoters[j].PlayerOwner.ClientPlaySound(AnnouncerCues[13]);
|
||||
}
|
||||
SwitchToLevel(ActiveVotes[i].GameIndex,ActiveVotes[i].MapIndex,false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Check for mid-game voting timer.
|
||||
if( !bMapVoteTimer && NumVotees>0 && GetPctOf(c,NumVotees)>=MidGameVotePct )
|
||||
StartMidGameVote(true);
|
||||
}
|
||||
final function StartMidGameVote( bool bMidGame )
|
||||
{
|
||||
local int i;
|
||||
|
||||
if( bMapVoteTimer || bMapvoteHasEnded )
|
||||
return;
|
||||
bMapVoteTimer = true;
|
||||
if( bMidGame )
|
||||
{
|
||||
for( i=(ActiveVoters.Length-1); i>=0; --i )
|
||||
ActiveVoters[i].ClientNotifyVoteTime(0);
|
||||
}
|
||||
ShowMenuDelay = 5;
|
||||
VoteTimeLeft = Max(VoteTime,10);
|
||||
SetTimer(1,true);
|
||||
}
|
||||
function CheckEndGameEnded()
|
||||
{
|
||||
if( KF==None )
|
||||
{
|
||||
KF = KFGameReplicationInfo(WorldInfo.GRI);
|
||||
if( KF==None )
|
||||
return;
|
||||
}
|
||||
if( KF.bMatchIsOver ) // HACK, since KFGameInfo_Survival doesn't properly notify mutators of this!
|
||||
{
|
||||
if( !bMapVoteTimer )
|
||||
StartMidGameVote(false);
|
||||
ClearTimer('CheckEndGameEnded');
|
||||
WorldInfo.Game.ClearTimer('ShowPostGameMenu');
|
||||
}
|
||||
}
|
||||
function bool HandleRestartGame()
|
||||
{
|
||||
if( !bMapVoteTimer )
|
||||
StartMidGameVote(false);
|
||||
return true;
|
||||
}
|
||||
function Timer()
|
||||
{
|
||||
local int i;
|
||||
local SoundCue FX;
|
||||
|
||||
if( bMapvoteHasEnded )
|
||||
{
|
||||
if( WorldInfo.NextSwitchCountdown<=0.f ) // Mapswitch failed, force to random other map.
|
||||
{
|
||||
ActiveVotes.Length = 0;
|
||||
bMapvoteHasEnded = false;
|
||||
TallyVotes(true);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if( ShowMenuDelay>0 && --ShowMenuDelay==0 )
|
||||
{
|
||||
for( i=(ActiveVoters.Length-1); i>=0; --i )
|
||||
ActiveVoters[i].ClientOpenMapvote(true);
|
||||
}
|
||||
--VoteTimeLeft;
|
||||
if( VoteTimeLeft==0 )
|
||||
{
|
||||
TallyVotes(true);
|
||||
}
|
||||
else if( VoteTimeLeft<=10 || VoteTimeLeft==20 || VoteTimeLeft==30 || VoteTimeLeft==60 )
|
||||
{
|
||||
FX = None;
|
||||
if( VoteTimeLeft<=10 )
|
||||
FX = AnnouncerCues[VoteTimeLeft-1];
|
||||
else if( VoteTimeLeft==20 )
|
||||
FX = AnnouncerCues[10];
|
||||
else if( VoteTimeLeft==30 )
|
||||
FX = AnnouncerCues[11];
|
||||
else if( VoteTimeLeft==60 )
|
||||
FX = AnnouncerCues[12];
|
||||
for( i=(ActiveVoters.Length-1); i>=0; --i )
|
||||
{
|
||||
ActiveVoters[i].ClientNotifyVoteTime(VoteTimeLeft);
|
||||
if( FX!=None )
|
||||
ActiveVoters[i].PlayerOwner.ClientPlaySound(FX);
|
||||
}
|
||||
}
|
||||
}
|
||||
final function SwitchToLevel( int GameIndex, int MapIndex, bool bAdminForce )
|
||||
{
|
||||
local int i;
|
||||
local string S;
|
||||
|
||||
if( bMapvoteHasEnded )
|
||||
return;
|
||||
|
||||
Default.LastVotedGameInfo = GameIndex;
|
||||
Class.Static.StaticSaveConfig();
|
||||
bMapvoteHasEnded = true;
|
||||
if( !bAdminForce && !bHistorySaved )
|
||||
{
|
||||
class'xMapVoteHistory'.Static.UpdateMapHistory(Maps[MapIndex].History);
|
||||
class'xMapVoteHistory'.Static.StaticSaveConfig();
|
||||
bHistorySaved = true;
|
||||
}
|
||||
|
||||
S = Maps[MapIndex].MapName$" ("$GameModes[GameIndex].GameName$")";
|
||||
for( i=(ActiveVoters.Length-1); i>=0; --i )
|
||||
{
|
||||
KFPlayerController(ActiveVoters[i].PlayerOwner).ShowConnectionProgressPopup(PMT_AdminMessage,"Switching to level:",S);
|
||||
ActiveVoters[i].ClientNotifyVoteWin(GameIndex,MapIndex,bAdminForce);
|
||||
}
|
||||
|
||||
PendingMapURL = Maps[MapIndex].MapName$"?Game="$GameModes[GameIndex].GameClass$"?Mutator="$PathName(BaseMutator);
|
||||
if( GameModes[GameIndex].Mutators!="" )
|
||||
PendingMapURL $= ","$GameModes[GameIndex].Mutators;
|
||||
if( GameModes[GameIndex].Options!="" )
|
||||
PendingMapURL $= "?"$GameModes[GameIndex].Options;
|
||||
`Log("MapVote: Switch map to "$PendingMapURL);
|
||||
SetTimer(FMax(MapChangeDelay,0.1),false,'PendingSwitch');
|
||||
}
|
||||
function PendingSwitch()
|
||||
{
|
||||
WorldInfo.ServerTravel(PendingMapURL,false);
|
||||
SetTimer(1,true);
|
||||
}
|
||||
|
||||
final function ParseCommand( string Cmd, PlayerController PC )
|
||||
{
|
||||
if( Cmd~="Help" )
|
||||
{
|
||||
PC.ClientMessage("MapVote commands:");
|
||||
PC.ClientMessage("!MapVote - Show mapvote menu");
|
||||
PC.ClientMessage("!AddMap <Mapname> - Add map to mapvote");
|
||||
PC.ClientMessage("!RemoveMap <Mapname> - Remove map from mapvote");
|
||||
}
|
||||
else if( Cmd~="MapVote" )
|
||||
ShowMapVote(PC);
|
||||
else if( !PC.PlayerReplicationInfo.bAdmin && !PC.IsA('MessagingSpectator') )
|
||||
return;
|
||||
else if( Left(Cmd,7)~="AddMap " )
|
||||
{
|
||||
Cmd = Mid(Cmd,7);
|
||||
PC.ClientMessage("Added map '"$Cmd$"'!");
|
||||
AddMap(Cmd);
|
||||
}
|
||||
else if( Left(Cmd,10)~="RemoveMap " )
|
||||
{
|
||||
Cmd = Mid(Cmd,10);
|
||||
if( RemoveMap(Cmd) )
|
||||
PC.ClientMessage("Removed map '"$Cmd$"'!");
|
||||
else PC.ClientMessage("Map '"$Cmd$"' not found!");
|
||||
}
|
||||
}
|
||||
function ShowMapVote( PlayerController PC )
|
||||
{
|
||||
local int i;
|
||||
|
||||
if( bMapvoteHasEnded )
|
||||
return;
|
||||
for( i=(ActiveVoters.Length-1); i>=0; --i )
|
||||
if( ActiveVoters[i].PlayerOwner==PC )
|
||||
{
|
||||
ActiveVoters[i].ClientOpenMapvote(false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
final function AddMap( string M )
|
||||
{
|
||||
if( Class'KFGameInfo'.Default.GameMapCycles.Length==0 )
|
||||
Class'KFGameInfo'.Default.GameMapCycles.Length = 1;
|
||||
Class'KFGameInfo'.Default.GameMapCycles[0].Maps.AddItem(M);
|
||||
Class'KFGameInfo'.Static.StaticSaveConfig();
|
||||
}
|
||||
final function bool RemoveMap( string M )
|
||||
{
|
||||
local int i,j;
|
||||
|
||||
for( i=(Class'KFGameInfo'.Default.GameMapCycles.Length-1); i>=0; --i )
|
||||
{
|
||||
for( j=(Class'KFGameInfo'.Default.GameMapCycles[i].Maps.Length-1); j>=0; --j )
|
||||
{
|
||||
if( Class'KFGameInfo'.Default.GameMapCycles[i].Maps[j]~=M )
|
||||
{
|
||||
Class'KFGameInfo'.Default.GameMapCycles[i].Maps.Remove(j,1);
|
||||
Class'KFGameInfo'.Static.StaticSaveConfig();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
BaseMutator=Class'xVotingHandler'
|
||||
AnnouncerCues.Add(SoundCue'xVoteAnnouncer.VX_one_Cue')
|
||||
AnnouncerCues.Add(SoundCue'xVoteAnnouncer.VX_two_Cue')
|
||||
AnnouncerCues.Add(SoundCue'xVoteAnnouncer.VX_three_Cue')
|
||||
AnnouncerCues.Add(SoundCue'xVoteAnnouncer.VX_four_Cue')
|
||||
AnnouncerCues.Add(SoundCue'xVoteAnnouncer.VX_five_Cue')
|
||||
AnnouncerCues.Add(SoundCue'xVoteAnnouncer.VX_six_Cue')
|
||||
AnnouncerCues.Add(SoundCue'xVoteAnnouncer.VX_seven_Cue')
|
||||
AnnouncerCues.Add(SoundCue'xVoteAnnouncer.VX_eight_Cue')
|
||||
AnnouncerCues.Add(SoundCue'xVoteAnnouncer.VX_nine_Cue')
|
||||
AnnouncerCues.Add(SoundCue'xVoteAnnouncer.VX_ten_Cue')
|
||||
AnnouncerCues.Add(SoundCue'xVoteAnnouncer.VX_20_seconds_Cue')
|
||||
AnnouncerCues.Add(SoundCue'xVoteAnnouncer.VX_30_seconds_Cue')
|
||||
AnnouncerCues.Add(SoundCue'xVoteAnnouncer.VX_1_minute_Cue')
|
||||
AnnouncerCues.Add(SoundCue'xVoteAnnouncer.VX_HolyShit_Cue')
|
||||
}
|
Reference in New Issue
Block a user