1
0
KF2-Dev-Scripts/Engine/Classes/CheatManager.uc
2020-12-13 18:01:13 +03:00

1430 lines
36 KiB
Ucode

//=============================================================================
// CheatManager
// Object within playercontroller that manages "cheat" commands
// only spawned in single player mode
// Copyright 1998-2013 Epic Games, Inc. All Rights Reserved.
//=============================================================================
class CheatManager extends Object within PlayerController
dependson(AppNotificationsBase)
native;
var localized string ViewingFrom;
var localized string OwnCamera;
/**
* Finds the nearest pawn of the given class (excluding the owner's pawn) and
* plays the specified FaceFX animation.
*/
exec function FXPlay(class<Pawn> aClass, string FXAnimPath)
{
local Pawn P, ClosestPawn;
local float ThisDistance, ClosestPawnDistance;
local string FxAnimGroup;
local string FxAnimName;
local int dotPos;
if ( WorldInfo.NetMode == NM_Standalone )
{
ClosestPawn = None;
ClosestPawnDistance = 10000000.0;
ForEach DynamicActors(class'Pawn', P)
{
if( ClassIsChildOf(P.class, aClass) && (P != PlayerController(Owner).Pawn) )
{
ThisDistance = VSize(P.Location - PlayerController(Owner).Pawn.Location);
if(ThisDistance < ClosestPawnDistance)
{
ClosestPawn = P;
ClosestPawnDistance = ThisDistance;
}
}
}
if( ClosestPawn.Mesh != none )
{
dotPos = InStr(FXAnimPath, ".");
if( dotPos != -1 )
{
FXAnimGroup = Left(FXAnimPath, dotPos);
FXAnimName = Right(FXAnimPath, Len(FXAnimPath) - dotPos - 1);
// WWISEMODIF_START, alessard, nov-28-2008, WwiseAudioIntegration
ClosestPawn.Mesh.PlayFaceFXAnim(None, FXAnimName, FXAnimGroup, none, none);
// WWISEMODIF_END
}
}
}
}
/**
* Finds the nearest pawn of the given class (excluding the owner's pawn) and
* stops any currently playing FaceFX animation.
*/
exec function FXStop(class<Pawn> aClass)
{
local Pawn P, ClosestPawn;
local float ThisDistance, ClosestPawnDistance;
if ( WorldInfo.NetMode == NM_StandAlone )
{
ClosestPawn = None;
ClosestPawnDistance = 10000000.0;
ForEach DynamicActors(class'Pawn', P)
{
if( ClassIsChildOf(P.class, aClass) && (P != PlayerController(Owner).Pawn) )
{
ThisDistance = VSize(P.Location - PlayerController(Owner).Pawn.Location);
if(ThisDistance < ClosestPawnDistance)
{
ClosestPawn = P;
ClosestPawnDistance = ThisDistance;
}
}
}
if( ClosestPawn.Mesh != none )
{
ClosestPawn.Mesh.StopFaceFXAnim();
}
}
}
exec function DebugAI(optional coerce name Category);
exec function EditAIByTrace()
{
local Vector CamLoc;
local Rotator CamRot;
local Vector HitLocation, HitNormal;
local Pawn HitPawn;
local Controller C;
GetPlayerViewPoint( CamLoc, CamRot );
HitPawn = Pawn(Trace( HitLocation, HitNormal, CamLoc + Vector(CamRot) * 10000, CamLoc, TRUE, vect(10,10,10) ));
if( HitPawn != None )
{
C = HitPawn.Controller;
if( C == None && HitPawn.DrivenVehicle != None )
{
C = HitPawn.DrivenVehicle.Controller;
}
if( C != None )
{
ConsoleCommand( "EDITACTOR NAME="$C.Name, TRUE );
}
}
}
/** Dumps the pause state of the game */
exec function DebugPause()
{
WorldInfo.Game.DebugPause();
}
exec function ListDynamicActors()
{
`if(`notdefined(FINAL_RELEASE))
local Actor A;
local int i;
ForEach DynamicActors(class'Actor',A)
{
i++;
`log(i@A);
}
`log("Num dynamic actors: "$i);
`endif
}
exec function FreezeFrame(float delay)
{
WorldInfo.Game.SetPause(Outer,Outer.CanUnpause);
WorldInfo.PauseDelay = WorldInfo.TimeSeconds + delay;
}
exec function WriteToLog( string Param )
{
`log("NOW! "$Param);
}
exec function KillViewedActor()
{
if ( ViewTarget != None )
{
if ( (Pawn(ViewTarget) != None) && (Pawn(ViewTarget).Controller != None) )
Pawn(ViewTarget).Controller.Destroy();
ViewTarget.Destroy();
SetViewTarget(None);
}
}
/* Teleport()
Teleport to surface player is looking at
*/
exec function Teleport()
{
local Actor HitActor;
local vector HitNormal, HitLocation;
local vector ViewLocation;
local rotator ViewRotation;
GetPlayerViewPoint( ViewLocation, ViewRotation );
HitActor = Trace(HitLocation, HitNormal, ViewLocation + 1000000 * vector(ViewRotation), ViewLocation, true);
if ( HitActor != None)
HitLocation += HitNormal * 4.0;
ViewTarget.SetLocation( HitLocation );
}
/*
Scale the player's size to be F * default size
*/
exec function ChangeSize( float F )
{
Pawn.CylinderComponent.SetCylinderSize( Pawn.Default.CylinderComponent.CollisionRadius * F, Pawn.Default.CylinderComponent.CollisionHeight * F );
Pawn.SetDrawScale(F);
Pawn.SetLocation(Pawn.Location);
}
/* Stop interpolation
*/
exec function EndPath()
{
}
exec function Amphibious()
{
Pawn.UnderwaterTime = +999999.0;
}
exec function Fly()
{
if ( (Pawn != None) && Pawn.CheatFly() )
{
ClientMessage("You feel much lighter");
bCheatFlying = true;
Outer.GotoState('PlayerFlying');
}
}
exec function Walk()
{
bCheatFlying = false;
if (Pawn != None && Pawn.CheatWalk())
{
Restart(false);
}
}
exec function Ghost()
{
if ( (Pawn != None) && Pawn.CheatGhost() )
{
bCheatFlying = true;
Outer.GotoState('PlayerFlying');
}
else
{
bCollideWorld = false;
}
ClientMessage("You feel ethereal");
}
/* AllAmmo
Sets maximum ammo on all weapons
*/
exec function AllAmmo();
exec function God()
{
if ( bGodMode )
{
bGodMode = false;
ClientMessage("God mode off");
return;
}
bGodMode = true;
ClientMessage("God Mode on");
}
exec function Slomo( float T )
{
WorldInfo.Game.SetGameSpeed(T);
}
exec function SetJumpZ( float F )
{
Pawn.JumpZ = F;
}
exec function SetGravity( float F )
{
WorldInfo.WorldGravityZ = F;
}
exec function SetSpeed( float F )
{
Pawn.GroundSpeed = Pawn.Default.GroundSpeed * f;
Pawn.WaterSpeed = Pawn.Default.WaterSpeed * f;
}
exec function KillAll(class<actor> aClass)
{
local Actor A;
`if(`notdefined(FINAL_RELEASE))
local PlayerController PC;
foreach WorldInfo.AllControllers(class'PlayerController', PC)
{
PC.ClientMessage("Killed all "$string(aClass));
}
`endif
if ( ClassIsChildOf(aClass, class'Pawn') )
{
KillAllPawns(class<Pawn>(aClass));
return;
}
ForEach DynamicActors(class 'Actor', A)
if ( ClassIsChildOf(A.class, aClass) )
A.Destroy();
}
// Kill non-player pawns and their controllers
function KillAllPawns(class<Pawn> aClass)
{
local Pawn P;
ForEach DynamicActors(class'Pawn', P)
if ( ClassIsChildOf(P.Class, aClass)
&& !P.IsPlayerPawn() )
{
if ( P.Controller != None )
P.Controller.Destroy();
P.Destroy();
}
}
exec function KillPawns()
{
KillAllPawns(class'Pawn');
}
/**
* Possess a pawn of the requested class
*/
exec function Avatar( name ClassName )
{
local Pawn P, TargetPawn, FirstPawn, OldPawn;
local bool bPickNextPawn;
Foreach DynamicActors(class'Pawn', P)
{
if( P == Pawn )
{
bPickNextPawn = TRUE;
}
else if( P.IsA(ClassName) )
{
if( FirstPawn == None )
{
FirstPawn = P;
}
if( bPickNextPawn )
{
TargetPawn = P;
break;
}
}
}
// if we went through the list without choosing a pawn, pick first available choice (loop)
if( TargetPawn == None )
{
TargetPawn = FirstPawn;
}
if( TargetPawn != None )
{
// detach TargetPawn from its controller and kill its controller.
TargetPawn.DetachFromController( TRUE );
// detach player from current pawn and possess targetpawn
if( Pawn != None )
{
OldPawn = Pawn;
Pawn.DetachFromController();
}
Possess(TargetPawn, FALSE);
// Spawn default controller for our ex-pawn (AI)
if( OldPawn != None )
{
OldPawn.SpawnDefaultController();
}
}
else
{
`log("Avatar: Couldn't find any Pawn to possess of class '" $ ClassName $ "'");
}
}
exec function Summon( string ClassName )
{
local class<actor> NewClass;
local vector SpawnLoc;
`log( "Fabricate " $ ClassName );
NewClass = class<actor>( DynamicLoadObject( ClassName, class'Class' ) );
if( NewClass!=None )
{
if ( Pawn != None )
SpawnLoc = Pawn.Location;
else
SpawnLoc = Location;
Spawn( NewClass,,,SpawnLoc + 72 * Vector(Rotation) + vect(0,0,1) * 15 );
}
}
/**
* Give a specified weapon to the Pawn.
* If weapon is not carried by player, then it is created.
* Weapon given is returned as the function's return parmater.
*/
exec function Weapon GiveWeapon( String WeaponClassStr )
{
Local Weapon Weap;
local class<Weapon> WeaponClass;
WeaponClass = class<Weapon>(DynamicLoadObject(WeaponClassStr, class'Class'));
Weap = Weapon(Pawn.FindInventoryType(WeaponClass));
if( Weap != None )
{
return Weap;
}
return Weapon(Pawn.CreateInventory( WeaponClass ));
}
exec function PlayersOnly()
{
if (WorldInfo.bPlayersOnly || WorldInfo.bPlayersOnlyPending)
{
WorldInfo.bPlayersOnly = false;
WorldInfo.bPlayersOnlyPending = false;
}
else
{
WorldInfo.bPlayersOnlyPending = !WorldInfo.bPlayersOnlyPending;
// WorldInfo.bPlayersOnly is set after next tick of UWorld::Tick
}
}
exec function SuspendAI()
{
WorldInfo.bSuspendAI = !WorldInfo.bSuspendAI;
}
/** Util for fracturing meshes within an area of the player. */
exec function DestroyFractures(optional float Radius)
{
local FracturedStaticMeshActor FracActor;
if(Radius == 0.0)
{
Radius = 256.0;
}
foreach CollidingActors(class'FracturedStaticMeshActor', FracActor, Radius, Pawn.Location, TRUE)
{
if(FracActor.Physics == PHYS_None)
{
// Make sure the impacted fractured mesh is visually relevant
FracActor.BreakOffPartsInRadius(Pawn.Location, Radius, 500.0, TRUE);
}
}
}
/** Util for ensuring at least one piece is broken of each FSM in level */
exec function FractureAllMeshes()
{
local FracturedStaticMeshActor FracActor;
foreach AllActors(class'FracturedStaticMeshActor', FracActor)
{
FracActor.HideOneFragment();
}
}
/** This will break all Fractured meshes in the map in a way to maximize memory usage **/
exec function FractureAllMeshesToMaximizeMemoryUsage()
{
local FracturedStaticMeshActor FracActor;
foreach AllActors(class'FracturedStaticMeshActor', FracActor)
{
FracActor.HideFragmentsToMaximizeMemoryUsage();
}
}
// ***********************************************************
// Navigation Aids (for testing)
// remember spot for path testing (display path using ShowDebug)
exec function RememberSpot()
{
if ( Pawn != None )
SetDestinationPosition( Pawn.Location );
else
SetDestinationPosition( Location );
}
// ***********************************************************
// Changing viewtarget
exec function ViewSelf(optional bool bQuiet)
{
Outer.ResetCameraMode();
if ( Pawn != None )
SetViewTarget(Pawn);
else
SetViewtarget(outer);
if (!bQuiet )
ClientMessage(OwnCamera, 'Event');
FixFOV();
}
exec function ViewPlayer( string S )
{
local Controller P;
foreach WorldInfo.AllControllers(class'Controller', P)
{
if ( P.bIsPlayer && (P.PlayerReplicationInfo.PlayerName ~= S ) )
{
break;
}
}
if ( P.Pawn != None )
{
ClientMessage(ViewingFrom@P.PlayerReplicationInfo.PlayerName, 'Event');
SetViewTarget(P.Pawn);
}
}
exec function ViewActor( name ActorName)
{
local Actor A;
ForEach AllActors(class'Actor', A)
if ( A.Name == ActorName )
{
SetViewTarget(A);
SetCameraMode('ThirdPerson');
return;
}
}
exec function ViewBot()
{
local actor first;
local bool bFound;
local AIController C;
foreach WorldInfo.AllControllers(class'AIController', C)
{
if (C.Pawn != None && C.PlayerReplicationInfo != None)
{
if (bFound || first == None)
{
first = C;
if (bFound)
{
break;
}
}
if (C.PlayerReplicationInfo == RealViewTarget)
{
bFound = true;
}
}
}
if ( first != None )
{
`log("view "$first);
SetViewTarget(first);
SetCameraMode( 'ThirdPerson' );
FixFOV();
}
else
ViewSelf(true);
}
exec function ViewClass( class<actor> aClass )
{
local actor other, first;
local bool bFound;
first = None;
ForEach AllActors( aClass, other )
{
if ( bFound || (first == None) )
{
first = other;
if ( bFound )
break;
}
if ( other == ViewTarget )
bFound = true;
}
if ( first != None )
{
if ( Pawn(first) != None )
ClientMessage(ViewingFrom@First.GetHumanReadableName(), 'Event');
else
ClientMessage(ViewingFrom@first, 'Event');
SetViewTarget(first);
FixFOV();
}
else
ViewSelf(false);
}
exec function Loaded()
{
if( WorldInfo.Netmode!=NM_Standalone )
return;
AllWeapons();
AllAmmo();
}
/* AllWeapons
Give player all available weapons
*/
exec function AllWeapons()
{
// subclass me
}
/** streaming level debugging */
function SetLevelStreamingStatus(name PackageName, bool bShouldBeLoaded, bool bShouldBeVisible)
{
local PlayerController PC;
local int i;
if (PackageName != 'All')
{
foreach WorldInfo.AllControllers(class'PlayerController', PC)
{
PC.ClientUpdateLevelStreamingStatus(PackageName, bShouldBeLoaded, bShouldBeVisible, FALSE );
}
}
else
{
foreach WorldInfo.AllControllers(class'PlayerController', PC)
{
for (i = 0; i < WorldInfo.StreamingLevels.length; i++)
{
PC.ClientUpdateLevelStreamingStatus(WorldInfo.StreamingLevels[i].PackageName, bShouldBeLoaded, bShouldBeVisible, FALSE );
}
}
}
}
exec function StreamLevelIn(name PackageName)
{
SetLevelStreamingStatus(PackageName, true, true);
}
exec function OnlyLoadLevel(name PackageName)
{
SetLevelStreamingStatus(PackageName, true, false);
}
exec function StreamLevelOut(name PackageName)
{
SetLevelStreamingStatus(PackageName, false, false);
}
exec function TestLevel()
{
local Actor A, Found;
local bool bFoundErrors;
ForEach AllActors(class'Actor', A)
{
bFoundErrors = bFoundErrors || A.CheckForErrors();
if ( bFoundErrors && (Found == None) )
Found = A;
}
if ( bFoundErrors )
{
`log("Found problem with "$Found);
assert(false);
}
}
`if(`notdefined(FINAL_RELEASE))
/**
* Logs the current session state for the game type and online layer
*/
exec function DumpOnlineSessionState()
{
local int PlayerIndex;
if (WorldInfo.NetMode != NM_Client)
{
`Log("");
`Log("GameInfo state");
`Log("-------------------------------------------------------------");
`Log("");
// Log game info data
`Log("Class: "$WorldInfo.Game.Class.Name);
// Log player count information
`Log(" MaxPlayersAllowed: "$WorldInfo.Game.MaxPlayersAllowed);
`Log(" MaxPlayers: "$WorldInfo.Game.MaxPlayers);
`Log(" NumPlayers: "$WorldInfo.Game.NumPlayers);
`Log(" MaxSpectatorsAllowed: "$WorldInfo.Game.MaxSpectatorsAllowed);
`Log(" MaxSpectators: "$WorldInfo.Game.MaxSpectators);
`Log(" NumSpectators: "$WorldInfo.Game.NumSpectators);
`Log(" NumBots: "$WorldInfo.Game.NumBots);
`Log(" bUseSeamlessTravel: "$WorldInfo.Game.bUseSeamlessTravel);
`Log(" bRequiresPushToTalk: "$WorldInfo.Game.bRequiresPushToTalk);
`Log(" bHasNetworkError: "$WorldInfo.Game.bHasNetworkError);
`Log(" OnlineGameSettingsClass: "$WorldInfo.Game.OnlineGameSettingsClass);
`Log(" OnlineStatsWriteClass: "$WorldInfo.Game.OnlineStatsWriteClass);
`Log(" bUsingArbitration: "$WorldInfo.Game.bUsingArbitration);
if (WorldInfo.Game.bUsingArbitration)
{
`Log(" bHasArbitratedHandshakeBegun: "$WorldInfo.Game.bHasArbitratedHandshakeBegun);
`Log(" bNeedsEndGameHandshake: "$WorldInfo.Game.bNeedsEndGameHandshake);
`Log(" bIsEndGameHandshakeComplete: "$WorldInfo.Game.bIsEndGameHandshakeComplete);
`Log(" bHasEndGameHandshakeBegun: "$WorldInfo.Game.bHasEndGameHandshakeBegun);
`Log(" ArbitrationHandshakeTimeout: "$WorldInfo.Game.ArbitrationHandshakeTimeout);
`Log(" Number of pending arbitration PCs: "$WorldInfo.Game.PendingArbitrationPCs.Length);
// List who we are waiting of for arbitration
for (PlayerIndex = 0; PlayerIndex < WorldInfo.Game.PendingArbitrationPCs.Length; PlayerIndex++)
{
`Log(" Player: "$WorldInfo.Game.PendingArbitrationPCs[PlayerIndex].PlayerReplicationInfo.PlayerName$" PC ("$WorldInfo.Game.PendingArbitrationPCs[PlayerIndex].Name$")");
}
`Log(" Number of arbitration PCs: "$WorldInfo.Game.ArbitrationPCs.Length);
// List all of the players that have completed arbitration
for (PlayerIndex = 0; PlayerIndex < WorldInfo.Game.ArbitrationPCs.Length; PlayerIndex++)
{
`Log(" Player: "$WorldInfo.Game.ArbitrationPCs[PlayerIndex].PlayerReplicationInfo.PlayerName$" PC ("$WorldInfo.Game.ArbitrationPCs[PlayerIndex].Name$")");
}
}
}
// Log PRI player info
DebugLogPRIs();
// Log the online session state
if (OnlineSub != None)
{
OnlineSub.DumpSessionState();
}
}
`endif
/**
* Changes the OS specific logging level
*
* @param DebugLevel the new debug level to use
*/
exec function SetOnlineDebugLevel(int DebugLevel)
{
if (OnlineSub != None)
{
OnlineSub.SetDebugSpewLevel(DebugLevel);
}
}
/**
* tries to path from the player's current position to the position the player is looking at
*
*/
exec function TestNavMeshPath(optional bool bDrawPath=TRUE)
{
local actor HitActor;
local vector HitLoc,HitNorm, Start, End;
local rotator Rot;
if(NavigationHandle == none)
{
NavigationHandle = new(outer) class'NavigationHandle';
}
GetPlayerViewPoint(Start,Rot);
End = Start + vector(rot) * 10000;
HitActor = Trace(HitLoc,HitNorm,End,Start,false);
if(HitActor != none)
{
class'NavmeshPath_Toward'.static.TowardPoint(NavigationHandle,HitLoc);
class'NavMeshGoal_At'.static.AtLocation(NavigationHandle,HitLoc);
NavigationHandle.bDebugConstraintsAndGoalEvals=true;
NavigationHandle.bUltraVerbosePathDebugging=TRUE;
if(NavigationHandle.FindPath())
{
DrawDebugLine(HitLoc,Start,0,255,0,TRUE);
DrawDebugCoordinateSystem(HitLoc,rot(0,0,0),25.f,TRUE);
if(bDrawPath)
{
NavigationHandle.DrawPathCache(,true);
}
}
else
{
DrawDebugLine(HitLoc,Start,255,0,0,TRUE);
DrawDebugCoordinateSystem(HitLoc,rot(0,0,0),25.f,TRUE);
DrawDebugBox(Pawn.Location,Pawn.GetCollisionExtent(),255,0,0,TRUE);
}
}
}
exec function TestPylonConnectivity()
{
local Pylon Py;
foreach AllActors(class'Pylon',Py)
{
PY.VerifyTopLevelConnections();
}
}
exec function VerbosePathDebug()
{
local vector HitLoc,HitNorm, Start, End;
local rotator Rot;
local Pawn P;
GetPlayerViewPoint(Start,Rot);
End = Start + vector(rot) * 10000;
foreach TraceActors(class'Pawn',P,HitLoc,HitNorm,End,Start,vect(1,1,1))
{
Pawn.MessagePlayer("Verbosepathdebug trace hit"@P);
if(P != none && P.Controller != none)
{
P.Controller.NavigationHandle.bUltraVerbosePathDebugging=!P.Controller.NavigationHandle.bUltraVerbosePathDebugging;
}
}
}
/** This is not an actor, so we need a stand in for PostBeginPlay */
function InitCheatManager();
/**
* This will have all PlaySound function calls emit a warnf so you can see that name of
* the soundcue being played.
**/
exec native function LogPlaySoundCalls( bool bShouldLog );
/**
* This will have all ActivateSystem function calls emit a warnf so you can see that name of
* the particlesystem being played.
**/
exec native function LogParticleActivateSystemCalls( bool bShouldLog );
/**
* debug command, verifies that all path objects and path obstacls are valid
* (E.G.) that they haven't been deleted, but left registered
*/
exec native function VerifyNavMeshObjects();
/**
* debug command, will draw all edges that are not supported for the passed pawn class
*/
exec native function DrawUnsupportingEdges(coerce string PawnClassName);
/**
* enables a timer to do periodic navmesh verification
*/
exec function NavMeshVerification(float interval=0.5)
{
if(interval < 0)
{
ClearTimer(nameof(VerifyNavMeshObjects),outer);
}
else
{
SetTimer(interval,true,nameof(VerifyNavMeshObjects),outer);
}
}
/**
* debug command, prints all navmesh pathobject edges
*/
exec native function PrintAllPathObjectEdges();
/**
* debug command, prints all active navmesh obstaces
*/
exec native function PrintNavMeshObstacles();
/**
* debug command, verifies all cover references
*/
exec native function VerifyNavMeshCoverRefs();
/**
* toggles AI logging
*/
exec function ToggleAILogging()
{
local Engine Eng;
Eng = class'Engine'.static.GetEngine();
if(Pawn != none)
{
if( Eng.bDisableAILogging )
{
Pawn.MessagePlayer("OK! AI logging is now ON");
}
else
{
Pawn.MessagePlayer("OK! AI logging is now OFF");
}
}
Eng.bDisableAILogging = !Eng.bDisableAILogging;
}
exec function DebugIniLocPatcher()
{
if (OnlineSub != None &&
OnlineSub.Patcher != None)
{
OnlineSub.Patcher.DownloadFiles();
}
}
exec function DebugDownloadTitleFile(string Filename, optional bool bFromCache)
{
if (OnlineSub != None)
{
if (bFromCache)
{
if (OnlineSub.TitleFileCacheInterface != None)
{
`Log(`location @ "starting file load for"@Filename);
OnlineSub.TitleFileCacheInterface.AddLoadTitleFileCompleteDelegate(OnLoadComplete);
OnlineSub.TitleFileCacheInterface.LoadTitleFile(Filename);
}
else
{
`Log(`location @ "OnlineTitleFileCacheInterface not supported");
}
}
else
{
if (OnlineSub.TitleFileInterface != None)
{
`Log(`location @ "starting file download request for"@Filename);
OnlineSub.TitleFileInterface.AddReadTitleFileCompleteDelegate(OnDownloadComplete);
OnlineSub.TitleFileInterface.ReadTitleFile(Filename);
}
else
{
`Log(`location @ "OnlineTitleFileInterface not supported");
}
}
}
}
function OnDownloadComplete(bool bWasSuccessful,string Filename)
{
OnlineSub.TitleFileInterface.ClearReadTitleFileCompleteDelegate(OnDownloadComplete);
`Log(`location @ "download completed"
@"bWasSuccessful="$bWasSuccessful
@"FileName="$Filename);
if (bWasSuccessful)
{
DebugSaveTitleFile(Filename);
}
}
function OnLoadComplete(bool bWasSuccessful,string FileName)
{
OnlineSub.TitleFileCacheInterface.ClearLoadTitleFileCompleteDelegate(OnLoadComplete);
`Log(`location @ "load completed"
@"bWasSuccessful="$bWasSuccessful
@"FileName="$Filename);
DebugDownloadTitleFile(FileName,false);
}
exec function DebugSaveTitleFile(string Filename)
{
local array<byte> FileContents;
if (OnlineSub != None)
{
if (OnlineSub.TitleFileInterface != None)
{
if (OnlineSub.TitleFileInterface.GetTitleFileContents(Filename, FileContents))
{
`Log(`location @ "found file in download cache. using file contents from download cache:"@Filename);
}
else
{
`Log(`location @ "couldn't find file in download cache:"@Filename);
}
}
else
{
`Log(`location @ "OnlineTitleFileInterface not supported");
}
if (OnlineSub.TitleFileCacheInterface != None)
{
`Log(`location @ "starting file save for"@Filename);
OnlineSub.TitleFileCacheInterface.AddSaveTitleFileCompleteDelegate(OnSaveComplete);
OnlineSub.TitleFileCacheInterface.SaveTitleFile(Filename, "TestName.ini", FileContents);
}
else
{
`Log(`location @ "OnlineTitleFileCacheInterface not supported");
}
}
}
function OnSaveComplete(bool bWasSuccessful,string FileName)
{
OnlineSub.TitleFileCacheInterface.ClearSaveTitleFileCompleteDelegate(OnSaveComplete);
`Log(`location @ "save completed"
@"bWasSuccessful="$bWasSuccessful
@"FileName="$Filename);
}
exec function DebugDeleteTitleFiles()
{
if (OnlineSub != None)
{
if (OnlineSub.TitleFileCacheInterface != None)
{
`Log(`location @ "deleting all title files in cache dir");
if (OnlineSub.TitleFileCacheInterface.DeleteTitleFiles(0))
{
`Log(`location @ "delete succeeded");
}
else
{
`Log(`location @ "cant delete. file ops in progress");
}
}
else
{
`Log(`location @ "OnlineTitleFileCacheInterface not supported");
}
}
}
exec function DebugEmsDownload()
{
if (OnlineSub != None &&
OnlineSub.Patcher != None)
{
OnlineSub.Patcher.DownloadFiles();
}
}
/**
* debug command which prints out stats about memory usage by covernodes
*/
exec native function DumpCoverStats();
exec function DrawLocation(vector Loc)
{
DrawDebugCoordinateSystem(Loc,rot(0,0,0),50.f,TRUE);
}
exec function DrawLocationXYZ(float X, Float Y, float Z)
{
local vector DrawSpot;
DrawSpot.X = X;
DrawSpot.y = y;
DrawSpot.z = z;
DrawDebugCoordinateSystem(DrawSpot,rot(0,0,0),150.f,TRUE);
}
/**
* Debug exec for scheduling a push notification
*
* @param MessageBody string to display in message box of notification
* @param SecondsFromNow seconds to elapse before triggering the notification
*/
exec function DebugNotification(string MessageBody, int SecondsFromNow)
{
local AppNotificationsBase AppNotification;
local NotificationInfo NotificationInfo;
local NotificationMessageInfo MessageInfo;
AppNotification = class'PlatformInterfaceBase'.static.GetAppNotificationsInterface();
if (AppNotification != None)
{
NotificationInfo.BadgeNumber = 1;
NotificationInfo.MessageBody = MessageBody;
MessageInfo.Key = "test key 1";
MessageInfo.Value = "test val 1";
NotificationInfo.MessageInfo.AddItem(MessageInfo);
MessageInfo.Key = "test key 2";
MessageInfo.Value = "test val 2";
NotificationInfo.MessageInfo.AddItem(MessageInfo);
`log(`location@""
@" MessageBody="$MessageBody
@" SecondsFromNow="$SecondsFromNow);
AppNotification.OnReceivedLocalNotification = OnReceivedLocalNotificationDebug;
AppNotification.ScheduleLocalNotification(NotificationInfo,SecondsFromNow);
}
}
/**
* Debug params from a local notification that was processed
*/
private function OnReceivedLocalNotificationDebug(const out NotificationInfo Notification, bool bWasAppActive)
{
`log(`location@"bWasAppActive="$bWasAppActive);
class'PlatformInterfaceBase'.static.GetAppNotificationsInterface().DebugLogNotification(Notification);
}
exec function DebugQueryUserFiles(string UserId)
{
if (OnlineSub != None &&
OnlineSub.UserCloudInterface != None)
{
OnlineSub.UserCloudInterface.AddEnumerateUserFileCompleteDelegate(OnEnumerateUserFilesComplete);
OnlineSub.UserCloudInterface.EnumerateUserFiles(UserId);
}
}
private function OnEnumerateUserFilesComplete(bool bWasSuccessful,string UserId)
{
OnlineSub.UserCloudInterface.ClearEnumerateUserFileCompleteDelegate(OnEnumerateUserFilesComplete);
ConsoleCommand("obj dump" @OnlineSub.UserCloudInterface.Name);
`log(`location@""
$" bWasSuccessful="$bWasSuccessful
$" UserId="$UserId);
}
exec function DebugWriteUserFile(string UserId, string FileName)
{
local int Idx;
local array<byte> FileContents;
if (OnlineSub != None &&
OnlineSub.UserCloudInterface != None)
{
for (Idx=0; Idx < 1000; Idx++)
{
FileContents[Idx]=Idx;
}
OnlineSub.UserCloudInterface.AddWriteUserFileCompleteDelegate(OnWriteUserFileComplete);
OnlineSub.UserCloudInterface.WriteUserFile(UserId,FileName,FileContents);
}
}
private function OnWriteUserFileComplete(bool bWasSuccessful,string UserId,string FileName)
{
OnlineSub.UserCloudInterface.ClearWriteUserFileCompleteDelegate(OnWriteUserFileComplete);
ConsoleCommand("obj dump" @OnlineSub.UserCloudInterface.Name);
`log(`location@""
$" bWasSuccessful="$bWasSuccessful
$" UserId="$UserId
$" FileName="$FileName);
}
exec function DebugReadUserFile(string UserId, string FileName)
{
if (OnlineSub != None &&
OnlineSub.UserCloudInterface != None)
{
OnlineSub.UserCloudInterface.AddReadUserFileCompleteDelegate(OnReadUserFileComplete);
OnlineSub.UserCloudInterface.ReadUserFile(UserId,FileName);
}
}
private function OnReadUserFileComplete(bool bWasSuccessful,string UserId,string FileName)
{
local array<byte> FileContents;
OnlineSub.UserCloudInterface.ClearReadUserFileCompleteDelegate(OnReadUserFileComplete);
OnlineSub.UserCloudInterface.GetFileContents(UserId,FileName,FileContents);
ConsoleCommand("obj dump" @OnlineSub.UserCloudInterface.Name);
`log(`location@""
$" bWasSuccessful="$bWasSuccessful
$" UserId="$UserId
$" FileName="$FileName
$" FileContents="$FileContents.Length);
}
exec function DebugDeleteUserFile(string UserId, string FileName)
{
if (OnlineSub != None &&
OnlineSub.UserCloudInterface != None)
{
OnlineSub.UserCloudInterface.AddDeleteUserFileCompleteDelegate(OnDeleteUserFileComplete);
OnlineSub.UserCloudInterface.DeleteUserFile(UserId,FileName,true,true);
}
}
private function OnDeleteUserFileComplete(bool bWasSuccessful,string UserId,string FileName)
{
OnlineSub.UserCloudInterface.ClearDeleteUserFileCompleteDelegate(OnDeleteUserFileComplete);
ConsoleCommand("obj dump" @OnlineSub.UserCloudInterface.Name);
`log(`location@""
$" bWasSuccessful="$bWasSuccessful
$" UserId="$UserId
$" FileName="$FileName);
}
defaultproperties
{
}
/**
* Simple function to illustrate the use of the HttpRequest system.
*/
exec function TestHttp(string Verb, string Payload, string URL, optional bool bSendParallelRequest)
{
local HttpRequestInterface R;
// create the request instance using the factory (which handles
// determining the proper type to create based on config).
R = class'HttpFactory'.static.CreateRequest();
// always set a delegate instance to handle the response.
R.OnProcessRequestComplete = OnRequestComplete;
`log("Created request");
// you can make many requests from one request object.
R.SetURL(URL);
// Default verb is GET
if (Len(Verb) > 0)
{
R.SetVerb(Verb);
}
else
{
`log("No Verb given, using the defaults.");
}
// Default Payload is empty
if (Len(Payload) > 0)
{
R.SetContentAsString(Payload);
}
else
{
`log("No payload given.");
}
`log("Creating request for URL:"@URL);
// there is currently no way to distinguish keys that are empty from keys that aren't there.
`log("Key1 ="@R.GetURLParameter("Key1"));
`log("Key2 ="@R.GetURLParameter("Key2"));
`log("Key3NoValue ="@R.GetURLParameter("Key3NoValue"));
`log("NonexistentKey ="@R.GetURLParameter("NonexistentKey"));
// A header will not necessarily be present if you don't set one. Platform implementations
// may add things like Content-Length when you send the request, but won't necessarily
// be available in the Header.
`log("NonExistentHeader ="@R.GetHeader("NonExistentHeader"));
`log("CustomHeaderName ="@R.GetHeader("CustomHeaderName"));
`log("ContentType ="@R.GetContentType());
`log("ContentLength ="@R.GetContentLength());
`log("URL ="@R.GetURL());
`log("Verb ="@R.GetVerb());
// multiple ProcessRequest calls can be made from the same instance if desired.
if (!R.ProcessRequest())
{
`log("ProcessRequest failed. Unsuppress DevHttpRequest to see more details.");
}
else
{
`log("Request sent");
}
// send off a parallel request for testing.
if (bSendParallelRequest)
{
if (!class'HttpFactory'.static.CreateRequest()
.SetURL("http://www.epicgames.com")
.SetVerb("GET")
.SetHeader("Test", "Value")
.SetProcessRequestCompleteDelegate(OnRequestComplete)
.ProcessRequest())
{
`log("ProcessRequest for parallel request failed. Unsuppress DevHttpRequest to see more details.");
}
else
{
`log("Parallel Request sent");
}
}
}
/** Delegate to use for HttpResponses. */
function OnRequestComplete(HttpRequestInterface OriginalRequest, HttpResponseInterface Response, bool bDidSucceed)
{
local array<String> Headers;
local String Header;
local String Payload;
local int PayloadIndex;
`log("Got response!!!!!!! Succeeded="@bDidSucceed);
`log("URL="@OriginalRequest.GetURL());
// if we didn't succeed, we can't really trust the payload, so you should always really check this.
if (Response != None)
{
`log("ResponseURL="@Response.GetURL());
`log("Response Code="@Response.GetResponseCode());
Headers = Response.GetHeaders();
foreach Headers(Header)
{
`log("Header:"@Header);
}
// GetContentAsString will make a copy of the payload to add the NULL terminator,
// then copy it again to convert it to TCHAR, so this could be fairly inefficient.
// This call also assumes the payload is UTF8 right now, as truly determining the encoding
// is content-type dependent.
// You also can't trust the content-length as you don't always get one. You should instead
// always trust the length of the content payload you receive.
Payload = Response.GetContentAsString();
if (Len(Payload) > 1024)
{
PayloadIndex = 0;
`log("Payload:");
while (PayloadIndex < Len(Payload))
{
`log(" "@Mid(Payload, PayloadIndex, 1024));
PayloadIndex = PayloadIndex + 1024;
}
}
else
{
`log("Payload:"@Payload);
}
}
}
/**
* Debug function to send an arbitrary analytics event.
*/
exec function SendAnalyticsEvent(string EventName, optional string AttributeName, optional string AttributeValue)
{
local AnalyticEventsBase Analytics;
Analytics = class'PlatformInterfaceBase'.static.GetAnalyticEventsInterface();
if (Len(AttributeName) > 0)
{
Analytics.LogStringEventParam(EventName, AttributeName, AttributeValue, false);
}
else
{
Analytics.LogStringEvent(EventName, false);
}
}
/**
* Debug function to test analytic user events
*/
exec function SendAnalyticsUserAttributeEvent(string AttributeName, string AttributeValue)
{
class'PlatformInterfaceBase'.static.GetAnalyticEventsInterface().LogUserAttributeUpdate(AttributeName, AttributeValue);
}
/**
* Debug function to test analytic events
*/
exec function SendAnalyticsItemPurchaseEvent(string ItemId, string Currency, int PerItemCost, int ItemQuantity)
{
class'PlatformInterfaceBase'.static.GetAnalyticEventsInterface().LogItemPurchaseEvent(ItemId, Currency, PerItemCost, ItemQuantity);
}
/**
* Debug function to test analytic events
*/
exec function SendAnalyticsCurrencyPurchaseEvent(string GameCurrencyType, int GameCurrencyAmount, string RealCurrencyType, float RealMoneyCost, string PaymentProvider)
{
class'PlatformInterfaceBase'.static.GetAnalyticEventsInterface().LogCurrencyPurchaseEvent(GameCurrencyType, GameCurrencyAmount, RealCurrencyType, RealMoneyCost, PaymentProvider);
}
/**
* Debug function to test analytic events
*/
exec function SendAnalyticsCurrencyGivenEvent(string GameCurrencyType, int GameCurrencyAmount)
{
class'PlatformInterfaceBase'.static.GetAnalyticEventsInterface().LogCurrencyGivenEvent(GameCurrencyType, GameCurrencyAmount);
}
/**
* Debug function to test analytic events
*/
exec function SendAnalyticsCachedEvents()
{
class'PlatformInterfaceBase'.static.GetAnalyticEventsInterface().SendCachedEvents();
}
/**
* Debug function to test analytic events
*/
exec function SetAnalyticsUserId(string UserId)
{
class'PlatformInterfaceBase'.static.GetAnalyticEventsInterface().SetUserId(UserId);
`log("Analytics UserId set to:"@UserId);
}
/**
* Debug function to test analytic events
*/
exec native function GetAnalyticsUserId();
/**
* Debug function to test analytic events
*/
exec function AnalyticsStartSession()
{
class'PlatformInterfaceBase'.static.GetAnalyticEventsInterface().StartSession();
}
/**
* Debug function to test analytic events
*/
exec function AnalyticsEndSession()
{
class'PlatformInterfaceBase'.static.GetAnalyticEventsInterface().EndSession();
}