Files
UT99-Mod-ChaChaRESTStats/Sources/Classes/ChaChaRESTStats.uc
2023-04-20 16:02:48 +02:00

462 lines
12 KiB
Ucode

class ChaChaRESTStats expands WebApplication;
var() class<UTServerAdminSpectator> SpectatorType;
var UTServerAdminSpectator Spectator;
var ListItem IncludeMutators;
var ListItem ExcludeMutators;
/* Usage:
[UWeb.WebServer]
Applications[X]=ChaChaRESTStats.ChaChaRESTStats
ApplicationPaths[X]=/api/v1
bEnabled=True
http://server.ip.address/api/v1/current_game
*/
event Init()
{
Super.Init();
if (SpectatorType != None)
Spectator = Level.Spawn(SpectatorType);
else
Spectator = Level.Spawn(class'UTServerAdminSpectator');
// won't change as long as the server is up
LoadMutators();
}
function LoadMutators()
{
local int NumMutatorClasses;
local string NextMutator, NextDesc;
local listitem TempItem;
local Mutator M;
local int k;
ExcludeMutators = None;
Level.GetNextIntDesc("Engine.Mutator", 0, NextMutator, NextDesc);
while( (NextMutator != "") && (NumMutatorClasses < 1024) )
{
TempItem = new(None) class'ListItem';
k = InStr(NextDesc, ",");
if (k == -1)
TempItem.Tag = NextDesc;
else
TempItem.Tag = Left(NextDesc, k);
TempItem.Data = NextMutator;
if (ExcludeMutators == None)
ExcludeMutators = TempItem;
else
ExcludeMutators.AddSortedElement(ExcludeMutators, TempItem);
NumMutatorClasses++;
Level.GetNextIntDesc("Engine.Mutator", NumMutatorClasses, NextMutator, NextDesc);
}
IncludeMutators = None;
for ( M=Level.Game.BaseMutator.NextMutator ; M!=None ; M=M.NextMutator )
{
TempItem = ExcludeMutators.DeleteElement(ExcludeMutators, String(M.Class));
if (TempItem != None)
{
if (IncludeMutators == None)
IncludeMutators = TempItem;
else
IncludeMutators.AddElement(TempItem);
}
else
log("Unknown Mutator in use: "$String(M.Class));
}
}
event Query(WebRequest Request, WebResponse Response)
{
local string tmp;
//local int i;
/* Kept in case auth needed
if(Request.Username != "test" || Request.Password != "test")
{
Response.FailAuthentication("HelloWeb");
return;
}
*/
Response.SendStandardHeaders("application/json",False);
Response.bSentText=True; //avoid header to be re-sent
switch(Request.URI)
{
case "/map_list":
Response.SendText(EncloseJSON(QueryMapList()));
break;
case "/current_all":
tmp=QueryCurrentGame();
tmp$=",";
tmp$=QueryCurrentPlayers();
Response.SendText(EncloseJSON(tmp));
break;
case "/current_game":
Response.SendText(EncloseJSON(QueryCurrentGame()));
break;
case "/current_players":
Response.SendText(EncloseJSON(QueryCurrentPlayers()));
break;
case "/default_all":
tmp=QueryDefaultsSettings();
tmp$=",";
tmp$=QueryDefaultsRules();
tmp$=",";
tmp$=QueryDefaultsServer();
Response.SendText(EncloseJSON(tmp));
break;
case "/defaults_settings":
Response.SendText(EncloseJSON(QueryDefaultsSettings()));
break;
case "/defaults_rules":
Response.SendText(EncloseJSON(QueryDefaultsRules()));
break;
case "/defaults_server":
Response.SendText(EncloseJSON(QueryDefaultsServer()));
break;
default:
Response.SendText("ERROR: Page not found or enabled.");
break;
}
}
function string EncloseJSON(String _input)
{
return "{"$_input$"}";
}
function string RenderJSONBool(string KeyName, bool KeyValue)
{
if( KeyValue )
{
return "\""$KeyName$"\":\"true\"";
}
else
{
return "\""$KeyName$"\":\"false\"";
}
}
function string RenderJSONBoolString(string KeyName, string KeyValue)
{
return RenderJSONBool(KeyName,KeyValue ~= "true");
}
function string QueryDefaultsServer()
{
local String tmp;
tmp$="\"ServerName\":\""$class'Engine.GameReplicationInfo'.default.ServerName$"\",";
tmp$="\"AdminName\":\""$class'Engine.GameReplicationInfo'.default.AdminName$"\",";
tmp$="\"AdminEmail\":\""$class'Engine.GameReplicationInfo'.default.AdminEmail$"\",";
tmp$="\"MOTDLine1\":\""$class'Engine.GameReplicationInfo'.default.MOTDLine1$"\",";
tmp$="\"MOTDLine2\":\""$class'Engine.GameReplicationInfo'.default.MOTDLine2$"\",";
tmp$="\"MOTDLine3\":\""$class'Engine.GameReplicationInfo'.default.MOTDLine3$"\",";
tmp$="\"MOTDLine4\":\""$class'Engine.GameReplicationInfo'.default.MOTDLine4$"\",";
tmp$=RenderJSONBool("bWorldLog",Level.Game.Default.bWorldLog);
return tmp;
}
function string QueryDefaultsRules()
{
local float FriendlyFireScale;
local class<GameInfo> GameClass;
local String tmp;
GameClass = Level.Game.Class;
tmp$="\"MaxPlayers\":"$class<DeathMatchPlus>(GameClass).Default.MaxPlayers$",";
tmp$="\"MaxSpectators\":"$class<DeathMatchPlus>(GameClass).Default.MaxSpectators$",";
//tmp$="\"bMultiWeaponStay\":"$class<DeathMatchPlus>(GameClass).Default.bMultiWeaponStay$",";
tmp$=RenderJSONBool("bMultiWeaponStay",class<DeathMatchPlus>(GameClass).Default.bMultiWeaponStay)$",";
//tmp$="\"bTournament\":"$class<DeathMatchPlus>(GameClass).Default.bTournament;
tmp$=RenderJSONBool("bTournament",class<DeathMatchPlus>(GameClass).Default.bTournament);
if( class<TeamGamePlus>(GameClass) != None )
{
//tmp$=",\"bPlayersBalanceTeams\":"$class<TeamGamePlus>(GameClass).Default.bPlayersBalanceTeams;
tmp$=","$RenderJSONBool("bPlayersBalanceTeams",class<TeamGamePlus>(GameClass).Default.bPlayersBalanceTeams);
}
if( class<LastManStanding>(GameClass) == None )
{
//tmp$=",\"bForceRespawn\":"$class<DeathMatchPlus>(GameClass).Default.bForceRespawn;
tmp$=","$RenderJSONBool("bForceRespawn",class<DeathMatchPlus>(GameClass).Default.bForceRespawn);
}
if (class<DeathMatchPlus>(GameClass) != None && class<Assault>(GameClass) == None)
{
if (class<TeamGamePlus>(GameClass) != None)
{
tmp$=",\"GoalTeamScore\":"$class<TeamGamePlus>(GameClass).Default.GoalTeamScore;
}
else
{
tmp$=",\"FragLimit\":"$class<DeathMatchPlus>(GameClass).Default.FragLimit;
}
if(class<LastManStanding>(GameClass) == None)
{
tmp$=",\"TimeLimit\":"$class<DeathMatchPlus>(GameClass).Default.TimeLimit;
}
}
if( class<TeamGamePlus>(GameClass) != None &&
!ClassIsChildOf( GameClass, class'CTFGame' ) &&
!ClassIsChildOf( GameClass, class'Assault' ) )
{
tmp$=",\"MaxTeams\":"$class<TeamGamePlus>(GameClass).Default.MaxTeams;
}
if (class<TeamGamePlus>(GameClass) != None)
{
FriendlyFireScale = class<TeamGamePlus>(GameClass).Default.FriendlyFireScale * 100;
tmp$=",\"FriendlyFireScale\":"$FriendlyFireScale;
}
return tmp;
}
function string QueryDefaultsSettings()
{
local class<GameInfo> GameClass;
local int GameStyle;
local float GameSpeed, AirControl;
local String tmp;
GameClass = Level.Game.Class;
if (class<DeathMatchPlus>(GameClass).Default.bMegaSpeed == true)
GameStyle=1;
if (class<DeathMatchPlus>(GameClass).Default.bHardCoreMode == true)
GameStyle+=1;
switch (GameStyle) {
case 0:
tmp$="\"GameStyle\":\"Normal\",";
break;
case 1:
tmp$="\"GameStyle\":\"HardCore\",";
break;
case 2:
tmp$="\"GameStyle\":\"Turbo\",";
break;
default:
tmp$="\"GameStyle\":\"Normal\",";
break;
}
GameSpeed = class<DeathMatchPlus>(GameClass).Default.GameSpeed * 100.0;
tmp$="\"GameSpeed\":"$GameSpeed$",";
AirControl = class<DeathMatchPlus>(GameClass).Default.AirControl * 100.0;
tmp$="\"AirControl\":"$AirControl$",";
//tmp$="\"UseTranslocator\":"$class<DeathMatchPlus>(GameClass).Default.bUseTranslocator;
tmp$=RenderJSONBool("bUseTranslocator",class<DeathMatchPlus>(GameClass).Default.bUseTranslocator);
return tmp;
}
function string QueryMapList()
{
local string tmp;
local ListItem ExcludeMaps, IncludeMaps;
ReloadExcludeMaps(ExcludeMaps, String(Level.Game.Class));
ReloadIncludeMaps(ExcludeMaps, IncludeMaps, String(Level.Game.Class));
tmp$=RenderDataList("Maplist",IncludeMaps);
return tmp;
}
function string QueryCurrentGame()
{
local string tmp,LevelFullName,LevelName;
local int k;
tmp$="\"GameName\":\""$Level.Game.GameReplicationInfo.GameName$"\",";
tmp$="\"GameClass\":\""$String(Level.Game.Class)$"\",";
tmp$="\"LevelTitle\":\""$Level.Title$"\",";
LevelFullName=String(Level);
k = InStr(LevelFullName, ".");
LevelName = Left(LevelFullName, k);
tmp$="\"Level\":\""$LevelName$"\",";
if (Level.Game != None && DeathMatchPlus(Level.Game) != None &&
DeathMatchPlus(Level.Game).TimeLimit > 0.0)
{
tmp$="\"TimeLimit\":"$DeathMatchPlus(Level.Game).TimeLimit$",";
}
tmp$=RenderDataList("Mutators",IncludeMutators);
return tmp;
}
function string QueryCurrentPlayers()
{
local string tmp;
local Pawn P;
local string IP;
local bool bFirst;
tmp$="\"player_list\":[";
bFirst=True;
for (P=Level.PawnList; P!=None; P=P.NextPawn) {
if (P.bIsPlayer
&& !P.bDeleteMe
&& UTServerAdminSpectator(P) == None
&& P.PlayerReplicationInfo != None)
{
if(!bFirst)
tmp$=",";
bFirst=False;
tmp$="{";
tmp$="\"PlayerName\":\""$P.PlayerReplicationInfo.PlayerName$"\",";
tmp$="\"Ping\":"$max(P.PlayerReplicationInfo.Ping, 0)$",";
tmp$="\"Score\":"$P.PlayerReplicationInfo.Score$",";
if (P.PlayerReplicationInfo.bIsABot)
{
tmp$="\"bIsABot\":true,";
tmp$="\"bIsSpectator\":false,";
}
else
{
tmp$="\"bIsABot\":false,";
if (P.PlayerReplicationInfo.bIsSpectator)
{
tmp$="\"bIsSpectator\":true,";
}
else
{
tmp$="\"bIsSpectator\":false,";
}
}
IP = "";
if ( PlayerPawn(P) != None )
{
IP = PlayerPawn(P).GetPlayerNetworkAddress();
IP = class'InternetInfo'.static.StripPort(IP);
}
tmp$="\"IP\":\""$IP$"\"";
tmp$="}";
}
}
tmp$="]";
return tmp;
}
function string RenderDataList(String name,ListItem _list)
{
local string tmp;
local ListItem TempItem;
local bool bFirst;
tmp$="\""$name$"\":[";
bFirst = true;
for (TempItem = _list; TempItem != None; TempItem = TempItem.Next) {
if(!bFirst)
tmp$=",";
tmp$="\""$TempItem.Data$"\"";
bFirst=false;
}
tmp$="]";
return tmp;
}
function ReloadExcludeMaps(out ListItem ExcludeMaps, String GameType)
{
local class<GameInfo> GameClass;
local string FirstMap, NextMap, TestMap;
local ListItem TempItem;
GameClass = class<GameInfo>(DynamicLoadObject(GameType, class'Class'));
ExcludeMaps = None;
if(GameClass.Default.MapPrefix == "")
return;
FirstMap = Level.GetMapName(GameClass.Default.MapPrefix, "", 0);
NextMap = FirstMap;
while (!(FirstMap ~= TestMap) && FirstMap != "")
{
if(!(Left(NextMap, Len(NextMap) - 4) ~= (GameClass.Default.MapPrefix$"-tutorial")))
{
// Add the map.
TempItem = new(None) class'ListItem';
TempItem.Data = NextMap;
if(Right(NextMap, 4) ~= ".unr")
TempItem.Tag = Left(NextMap, Len(NextMap) - 4);
else
TempItem.Tag = NextMap;
if (ExcludeMaps == None)
ExcludeMaps = TempItem;
else
{
// Maplists returned by GetMapName get sorted in C++ as of the Unreal Tournament 469 patch
//ExcludeMaps.AddSortedElement(ExcludeMaps, TempItem);
ExcludeMaps.AddElement(TempItem);
}
}
NextMap = Level.GetMapName(GameClass.Default.MapPrefix, NextMap, 1);
TestMap = NextMap;
}
}
function ReloadIncludeMaps(out ListItem ExcludeMaps, out ListItem IncludeMaps, String GameType)
{
local class<GameInfo> GameClass;
local ListItem TempItem;
local int i;
GameClass = class<GameInfo>(DynamicLoadObject(GameType, class'Class'));
if(GameClass.Default.MapListType == None)
return;
if (GameClass != None)
{
for (i=0; i<ArrayCount(GameClass.Default.MapListType.Default.Maps) && GameClass.Default.MapListType.Default.Maps[i] != ""; i++)
{
// Add the map.
TempItem = ExcludeMaps.DeleteElement(ExcludeMaps, GameClass.Default.MapListType.Default.Maps[i]);
if (TempItem == None)
{
TempItem = new(None) class'ListItem';
TempItem.Data = GameClass.Default.MapListType.Default.Maps[i];
if(Right(TempItem.Data, 4) ~= ".unr")
TempItem.Tag = Left(TempItem.Data, Len(TempItem.Data) - 4);
else
TempItem.Tag = TempItem.Data;
}
else
{
if (IncludeMaps == None)
IncludeMaps = TempItem;
else
IncludeMaps.AddElement(TempItem);
}
}
}
}
defaultproperties
{
SpectatorType=Class'utserveradmin.UTServerAdminSpectator'
Spectator=None
}