//============================================================================= // 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 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 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 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(aClass)); return; } ForEach DynamicActors(class 'Actor', A) if ( ClassIsChildOf(A.class, aClass) ) A.Destroy(); } // Kill non-player pawns and their controllers function KillAllPawns(class 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 NewClass; local vector SpawnLoc; `log( "Fabricate " $ ClassName ); NewClass = class( 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 WeaponClass; WeaponClass = class(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 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 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 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 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 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(); }