mirror of
https://github.com/Milxnor/Project-Reboot-3.0.git
synced 2026-01-13 02:42:22 +01:00
respawn toggle
toggling respawn, auto parachute height changer changer, fixed issue with characterparts, fixed lategame on s8, added cheat commands
This commit is contained in:
@@ -197,6 +197,12 @@ void UAbilitySystemComponent::InternalServerTryActivateAbilityHook(UAbilitySyste
|
|||||||
|
|
||||||
FGameplayAbilitySpecHandle UAbilitySystemComponent::GiveAbilityEasy(UClass* AbilityClass, UObject* SourceObject, bool bDoNotRegive)
|
FGameplayAbilitySpecHandle UAbilitySystemComponent::GiveAbilityEasy(UClass* AbilityClass, UObject* SourceObject, bool bDoNotRegive)
|
||||||
{
|
{
|
||||||
|
if (!AbilityClass)
|
||||||
|
{
|
||||||
|
LOG_WARN(LogAbilities, "Invalid AbilityClass passed into GiveAbilityEasy!");
|
||||||
|
return FGameplayAbilitySpecHandle();
|
||||||
|
}
|
||||||
|
|
||||||
// LOG_INFO(LogDev, "Making spec!");
|
// LOG_INFO(LogDev, "Making spec!");
|
||||||
|
|
||||||
auto DefaultAbility = AbilityClass->CreateDefaultObject();
|
auto DefaultAbility = AbilityClass->CreateDefaultObject();
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ struct FVehicleClassDetails
|
|||||||
{
|
{
|
||||||
static UStruct* GetStruct()
|
static UStruct* GetStruct()
|
||||||
{
|
{
|
||||||
static auto Struct = FindObject<UStruct>("/Script/FortniteGame.VehicleClassDetails");
|
static auto Struct = FindObject<UStruct>(L"/Script/FortniteGame.VehicleClassDetails");
|
||||||
return Struct;
|
return Struct;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
#include "vehicles.h"
|
#include "vehicles.h"
|
||||||
#include "globals.h"
|
#include "globals.h"
|
||||||
#include "events.h"
|
#include "events.h"
|
||||||
|
#include "FortPlaylistAthena.h"
|
||||||
#include "reboot.h"
|
#include "reboot.h"
|
||||||
#include "ai.h"
|
#include "ai.h"
|
||||||
#include "Map.h"
|
#include "Map.h"
|
||||||
@@ -35,11 +36,11 @@
|
|||||||
#include "gui.h"
|
#include "gui.h"
|
||||||
#include <random>
|
#include <random>
|
||||||
|
|
||||||
static UFortPlaylist* GetPlaylistToUse()
|
static UFortPlaylistAthena* GetPlaylistToUse()
|
||||||
{
|
{
|
||||||
// LOG_DEBUG(LogDev, "PlaylistName: {}", PlaylistName);
|
// LOG_DEBUG(LogDev, "PlaylistName: {}", PlaylistName);
|
||||||
|
|
||||||
auto Playlist = FindObject<UFortPlaylist>(PlaylistName);
|
auto Playlist = FindObject<UFortPlaylistAthena>(PlaylistName);
|
||||||
|
|
||||||
if (Globals::bGoingToPlayEvent)
|
if (Globals::bGoingToPlayEvent)
|
||||||
{
|
{
|
||||||
@@ -62,7 +63,7 @@ static UFortPlaylist* GetPlaylistToUse()
|
|||||||
// SET OVERRIDE PLAYLIST DOWN HERE
|
// SET OVERRIDE PLAYLIST DOWN HERE
|
||||||
|
|
||||||
if (Globals::bCreative)
|
if (Globals::bCreative)
|
||||||
Playlist = FindObject<UFortPlaylist>(L"/Game/Athena/Playlists/Creative/Playlist_PlaygroundV2.Playlist_PlaygroundV2");
|
Playlist = FindObject<UFortPlaylistAthena>(L"/Game/Athena/Playlists/Creative/Playlist_PlaygroundV2.Playlist_PlaygroundV2");
|
||||||
|
|
||||||
return Playlist;
|
return Playlist;
|
||||||
}
|
}
|
||||||
@@ -922,6 +923,10 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game
|
|||||||
|
|
||||||
int AFortGameModeAthena::Athena_PickTeamHook(AFortGameModeAthena* GameMode, uint8 preferredTeam, AActor* Controller)
|
int AFortGameModeAthena::Athena_PickTeamHook(AFortGameModeAthena* GameMode, uint8 preferredTeam, AActor* Controller)
|
||||||
{
|
{
|
||||||
|
#if 0
|
||||||
|
static int bruh = 3;
|
||||||
|
return bruh++;
|
||||||
|
#endif
|
||||||
bool bIsBot = false;
|
bool bIsBot = false;
|
||||||
|
|
||||||
auto PlayerState = ((APlayerController*)Controller)->GetPlayerState();
|
auto PlayerState = ((APlayerController*)Controller)->GetPlayerState();
|
||||||
|
|||||||
@@ -152,20 +152,20 @@ TScriptInterface<UFortSafeZoneInterface> AFortGameStateAthena::GetSafeZoneInterf
|
|||||||
return ScriptInterface;
|
return ScriptInterface;
|
||||||
}
|
}
|
||||||
|
|
||||||
UFortPlaylist*& AFortGameStateAthena::GetCurrentPlaylist()
|
UFortPlaylistAthena*& AFortGameStateAthena::GetCurrentPlaylist()
|
||||||
{
|
{
|
||||||
static auto CurrentPlaylistInfoOffset = GetOffset("CurrentPlaylistInfo", false);
|
static auto CurrentPlaylistInfoOffset = GetOffset("CurrentPlaylistInfo", false);
|
||||||
|
|
||||||
if (CurrentPlaylistInfoOffset == -1)
|
if (CurrentPlaylistInfoOffset == -1)
|
||||||
{
|
{
|
||||||
static auto CurrentPlaylistDataOffset = GetOffset("CurrentPlaylistData");
|
static auto CurrentPlaylistDataOffset = GetOffset("CurrentPlaylistData");
|
||||||
return Get<UFortPlaylist*>(CurrentPlaylistDataOffset);
|
return (Get<UFortPlaylistAthena*>(CurrentPlaylistDataOffset));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto CurrentPlaylistInfo = this->GetPtr<FFastArraySerializer>(CurrentPlaylistInfoOffset);
|
auto CurrentPlaylistInfo = this->GetPtr<FFastArraySerializer>(CurrentPlaylistInfoOffset);
|
||||||
|
|
||||||
static auto BasePlaylistOffset = FindOffsetStruct("/Script/FortniteGame.PlaylistPropertyArray", "BasePlaylist");
|
static auto BasePlaylistOffset = FindOffsetStruct("/Script/FortniteGame.PlaylistPropertyArray", "BasePlaylist");
|
||||||
return *(UFortPlaylist**)(__int64(CurrentPlaylistInfo) + BasePlaylistOffset);
|
return (*(UFortPlaylistAthena**)(__int64(CurrentPlaylistInfo) + BasePlaylistOffset));
|
||||||
}
|
}
|
||||||
|
|
||||||
int AFortGameStateAthena::GetAircraftIndex(AFortPlayerState* PlayerState)
|
int AFortGameStateAthena::GetAircraftIndex(AFortPlayerState* PlayerState)
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include "GameState.h"
|
#include "GameState.h"
|
||||||
#include "FortPlayerStateAthena.h"
|
#include "FortPlayerStateAthena.h"
|
||||||
#include "FortPlaylist.h"
|
#include "FortPlaylistAthena.h"
|
||||||
#include "BuildingStructuralSupportSystem.h"
|
#include "BuildingStructuralSupportSystem.h"
|
||||||
#include "ScriptInterface.h"
|
#include "ScriptInterface.h"
|
||||||
#include "Interface.h"
|
#include "Interface.h"
|
||||||
@@ -149,7 +149,7 @@ public:
|
|||||||
return Get<EAthenaGamePhaseStep>(GamePhaseStepOffset);
|
return Get<EAthenaGamePhaseStep>(GamePhaseStepOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
UFortPlaylist*& GetCurrentPlaylist();
|
UFortPlaylistAthena*& GetCurrentPlaylist();
|
||||||
TScriptInterface<UFortSafeZoneInterface> GetSafeZoneInterface();
|
TScriptInterface<UFortSafeZoneInterface> GetSafeZoneInterface();
|
||||||
|
|
||||||
void AddPlayerStateToGameMemberInfo(class AFortPlayerStateAthena* PlayerState);
|
void AddPlayerStateToGameMemberInfo(class AFortPlayerStateAthena* PlayerState);
|
||||||
|
|||||||
@@ -699,6 +699,7 @@ void AFortPlayerController::ServerAttemptAircraftJumpHook(AFortPlayerController*
|
|||||||
{
|
{
|
||||||
static auto StormEffectClass = FindObject<UClass>(L"/Game/Athena/SafeZone/GE_OutsideSafeZoneDamage.GE_OutsideSafeZoneDamage_C");
|
static auto StormEffectClass = FindObject<UClass>(L"/Game/Athena/SafeZone/GE_OutsideSafeZoneDamage.GE_OutsideSafeZoneDamage_C");
|
||||||
auto PlayerState = PlayerController->GetPlayerStateAthena();
|
auto PlayerState = PlayerController->GetPlayerStateAthena();
|
||||||
|
|
||||||
PlayerState->GetAbilitySystemComponent()->RemoveActiveGameplayEffectBySourceEffect(StormEffectClass, 1, PlayerState->GetAbilitySystemComponent());
|
PlayerState->GetAbilitySystemComponent()->RemoveActiveGameplayEffectBySourceEffect(StormEffectClass, 1, PlayerState->GetAbilitySystemComponent());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1324,6 +1325,10 @@ void AFortPlayerController::ClientOnPawnDiedHook(AFortPlayerController* PlayerCo
|
|||||||
int MaxHealth = 100;
|
int MaxHealth = 100;
|
||||||
int MaxShield = 100;
|
int MaxShield = 100;
|
||||||
int AmountGiven = 0;
|
int AmountGiven = 0;
|
||||||
|
/*
|
||||||
|
int ShieldGiven = 0;
|
||||||
|
int HealthGiven = 0;
|
||||||
|
*/
|
||||||
|
|
||||||
if ((MaxHealth - Health) > 0)
|
if ((MaxHealth - Health) > 0)
|
||||||
{
|
{
|
||||||
@@ -1343,6 +1348,11 @@ void AFortPlayerController::ClientOnPawnDiedHook(AFortPlayerController* PlayerCo
|
|||||||
AmountGiven += AmountToGive;
|
AmountGiven += AmountToGive;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (AmountGiven > 0)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
27
Project Reboot 3.0/FortPlaylistAthena.h
Normal file
27
Project Reboot 3.0/FortPlaylistAthena.h
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "FortPlaylist.h"
|
||||||
|
|
||||||
|
enum class EAthenaRespawnType : uint8_t
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
InfiniteRespawn = 1,
|
||||||
|
InfiniteRespawnExceptStorm = 2,
|
||||||
|
EAthenaRespawnType_MAX = 3
|
||||||
|
};
|
||||||
|
|
||||||
|
class UFortPlaylistAthena : public UFortPlaylist
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
EAthenaRespawnType& GetRespawnType()
|
||||||
|
{
|
||||||
|
static auto RespawnTypeOffset = GetOffset("RespawnType");
|
||||||
|
return Get<EAthenaRespawnType>(RespawnTypeOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
static UClass* StaticClass()
|
||||||
|
{
|
||||||
|
static auto Class = FindObject<UClass>(L"/Script/FortniteGame.FortPlaylistAthena");
|
||||||
|
return Class;
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -189,9 +189,11 @@
|
|||||||
<ClCompile Include="calendar.h" />
|
<ClCompile Include="calendar.h" />
|
||||||
<ClCompile Include="CheatManager.cpp" />
|
<ClCompile Include="CheatManager.cpp" />
|
||||||
<ClCompile Include="Class.cpp" />
|
<ClCompile Include="Class.cpp" />
|
||||||
|
<ClCompile Include="commands.cpp" />
|
||||||
<ClCompile Include="Controller.cpp" />
|
<ClCompile Include="Controller.cpp" />
|
||||||
<ClCompile Include="DataChannel.cpp" />
|
<ClCompile Include="DataChannel.cpp" />
|
||||||
<ClCompile Include="DataTableFunctionLibrary.cpp" />
|
<ClCompile Include="DataTableFunctionLibrary.cpp" />
|
||||||
|
<ClCompile Include="extra.cpp" />
|
||||||
<ClCompile Include="dllmain.cpp" />
|
<ClCompile Include="dllmain.cpp" />
|
||||||
<ClCompile Include="EngineTypes.cpp" />
|
<ClCompile Include="EngineTypes.cpp" />
|
||||||
<ClCompile Include="finder.cpp" />
|
<ClCompile Include="finder.cpp" />
|
||||||
@@ -376,6 +378,7 @@
|
|||||||
<ClInclude Include="FortPlayerState.h" />
|
<ClInclude Include="FortPlayerState.h" />
|
||||||
<ClInclude Include="FortPlayerStateAthena.h" />
|
<ClInclude Include="FortPlayerStateAthena.h" />
|
||||||
<ClInclude Include="FortPlaylist.h" />
|
<ClInclude Include="FortPlaylist.h" />
|
||||||
|
<ClInclude Include="FortPlaylistAthena.h" />
|
||||||
<ClInclude Include="FortPlaysetItemDefinition.h" />
|
<ClInclude Include="FortPlaysetItemDefinition.h" />
|
||||||
<ClInclude Include="FortQuickBars.h" />
|
<ClInclude Include="FortQuickBars.h" />
|
||||||
<ClInclude Include="FortResourceItemDefinition.h" />
|
<ClInclude Include="FortResourceItemDefinition.h" />
|
||||||
|
|||||||
@@ -298,6 +298,12 @@
|
|||||||
<ClCompile Include="objectviewer.cpp">
|
<ClCompile Include="objectviewer.cpp">
|
||||||
<Filter>Reboot\Private</Filter>
|
<Filter>Reboot\Private</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="commands.cpp">
|
||||||
|
<Filter>Reboot\Private</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="extra.cpp">
|
||||||
|
<Filter>Reboot\Private</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="log.h" />
|
<ClInclude Include="log.h" />
|
||||||
@@ -951,6 +957,9 @@
|
|||||||
<ClInclude Include="AthenaPlayerMatchReport.h">
|
<ClInclude Include="AthenaPlayerMatchReport.h">
|
||||||
<Filter>FortniteGame\Source\FortniteGame\Public\Stats</Filter>
|
<Filter>FortniteGame\Source\FortniteGame\Public\Stats</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="FortPlaylistAthena.h">
|
||||||
|
<Filter>FortniteGame\Source\FortniteGame\Public</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Filter Include="Engine">
|
<Filter Include="Engine">
|
||||||
|
|||||||
952
Project Reboot 3.0/commands.cpp
Normal file
952
Project Reboot 3.0/commands.cpp
Normal file
@@ -0,0 +1,952 @@
|
|||||||
|
#include "commands.h"
|
||||||
|
|
||||||
|
void ServerCheatHook(AFortPlayerControllerAthena* PlayerController, FString Msg)
|
||||||
|
{
|
||||||
|
if (!Msg.Data.Data || Msg.Data.Num() <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
auto PlayerState = Cast<AFortPlayerStateAthena>(PlayerController->GetPlayerState());
|
||||||
|
|
||||||
|
// std::cout << "aa!\n";
|
||||||
|
|
||||||
|
if (!PlayerState || !IsOperator(PlayerState, PlayerController))
|
||||||
|
return;
|
||||||
|
|
||||||
|
std::vector<std::string> Arguments;
|
||||||
|
auto OldMsg = Msg.ToString();
|
||||||
|
|
||||||
|
auto ReceivingController = PlayerController; // for now
|
||||||
|
auto ReceivingPlayerState = PlayerState; // for now
|
||||||
|
|
||||||
|
auto firstBackslash = OldMsg.find_first_of("\\");
|
||||||
|
auto lastBackslash = OldMsg.find_last_of("\\");
|
||||||
|
|
||||||
|
static auto World_NetDriverOffset = GetWorld()->GetOffset("NetDriver");
|
||||||
|
auto WorldNetDriver = GetWorld()->Get<UNetDriver*>(World_NetDriverOffset);
|
||||||
|
auto& ClientConnections = WorldNetDriver->GetClientConnections();
|
||||||
|
|
||||||
|
if (firstBackslash != std::string::npos && lastBackslash != std::string::npos)
|
||||||
|
{
|
||||||
|
if (firstBackslash != lastBackslash)
|
||||||
|
{
|
||||||
|
std::string player = OldMsg;
|
||||||
|
|
||||||
|
player = player.substr(firstBackslash + 1, lastBackslash - firstBackslash - 1);
|
||||||
|
|
||||||
|
for (int i = 0; i < ClientConnections.Num(); ++i)
|
||||||
|
{
|
||||||
|
static auto PlayerControllerOffset = ClientConnections.at(i)->GetOffset("PlayerController");
|
||||||
|
auto CurrentPlayerController = Cast<AFortPlayerControllerAthena>(ClientConnections.at(i)->Get(PlayerControllerOffset));
|
||||||
|
|
||||||
|
if (!CurrentPlayerController)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
auto CurrentPlayerState = Cast<AFortPlayerStateAthena>(CurrentPlayerController->GetPlayerState());
|
||||||
|
|
||||||
|
if (!CurrentPlayerState)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
FString PlayerName = CurrentPlayerState->GetPlayerName();
|
||||||
|
|
||||||
|
if (PlayerName.ToString() == player) // hopefully we arent on adifferent thread
|
||||||
|
{
|
||||||
|
ReceivingController = CurrentPlayerController;
|
||||||
|
ReceivingPlayerState = CurrentPlayerState;
|
||||||
|
PlayerName.Free();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
PlayerName.Free();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// SendMessageToConsole(PlayerController, L"Warning: You have a backslash but no ending backslash, was this by mistake? Executing on you.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ReceivingController || !ReceivingPlayerState)
|
||||||
|
{
|
||||||
|
SendMessageToConsole(PlayerController, L"Unable to find player!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto Message = Msg.ToString();
|
||||||
|
|
||||||
|
size_t start = Message.find('\\');
|
||||||
|
|
||||||
|
while (start != std::string::npos) // remove the playername
|
||||||
|
{
|
||||||
|
size_t end = Message.find('\\', start + 1);
|
||||||
|
|
||||||
|
if (end == std::string::npos)
|
||||||
|
break;
|
||||||
|
|
||||||
|
Message.replace(start, end - start + 2, "");
|
||||||
|
start = Message.find('\\');
|
||||||
|
}
|
||||||
|
|
||||||
|
int zz = 0;
|
||||||
|
|
||||||
|
// std::cout << "Message Before: " << Message << '\n';
|
||||||
|
|
||||||
|
while (Message.find(" ") != std::string::npos)
|
||||||
|
{
|
||||||
|
auto arg = Message.substr(0, Message.find(' '));
|
||||||
|
Arguments.push_back(arg);
|
||||||
|
// std::cout << std::format("[{}] {}\n", zz, arg);
|
||||||
|
Message.erase(0, Message.find(' ') + 1);
|
||||||
|
zz++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if (zz == 0)
|
||||||
|
{
|
||||||
|
Arguments.push_back(Message);
|
||||||
|
// std::cout << std::format("[{}] {}\n", zz, Message);
|
||||||
|
zz++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// std::cout << "Message After: " << Message << '\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
auto NumArgs = Arguments.size() == 0 ? 0 : Arguments.size() - 1;
|
||||||
|
|
||||||
|
// std::cout << "NumArgs: " << NumArgs << '\n';
|
||||||
|
|
||||||
|
// return;
|
||||||
|
|
||||||
|
bool bSendHelpMessage = false;
|
||||||
|
|
||||||
|
if (Arguments.size() >= 1)
|
||||||
|
{
|
||||||
|
auto& Command = Arguments[0];
|
||||||
|
std::transform(Command.begin(), Command.end(), Command.begin(), ::tolower);
|
||||||
|
|
||||||
|
if (Command == "giveitem")
|
||||||
|
{
|
||||||
|
if (NumArgs < 1)
|
||||||
|
{
|
||||||
|
SendMessageToConsole(PlayerController, L"Please provide a WID!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto WorldInventory = ReceivingController->GetWorldInventory();
|
||||||
|
|
||||||
|
if (!WorldInventory)
|
||||||
|
{
|
||||||
|
SendMessageToConsole(PlayerController, L"No world inventory!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto& weaponName = Arguments[1];
|
||||||
|
int count = 1;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (NumArgs >= 2)
|
||||||
|
count = std::stoi(Arguments[2]);
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// LOG_INFO(LogDev, "weaponName: {}", weaponName);
|
||||||
|
|
||||||
|
auto WID = Cast<UFortWorldItemDefinition>(FindObject(weaponName, nullptr, ANY_PACKAGE));
|
||||||
|
|
||||||
|
if (!WID)
|
||||||
|
{
|
||||||
|
SendMessageToConsole(PlayerController, L"Invalid WID!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool bShouldUpdate = false;
|
||||||
|
WorldInventory->AddItem(WID, &bShouldUpdate, count);
|
||||||
|
|
||||||
|
if (bShouldUpdate)
|
||||||
|
WorldInventory->Update();
|
||||||
|
|
||||||
|
SendMessageToConsole(PlayerController, L"Granted item!");
|
||||||
|
}
|
||||||
|
else if (Command == "printsimulatelootdrops")
|
||||||
|
{
|
||||||
|
if (NumArgs < 1)
|
||||||
|
{
|
||||||
|
SendMessageToConsole(PlayerController, L"Please provide a LootTierGroup!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto& lootTierGroup = Arguments[1];
|
||||||
|
|
||||||
|
auto LootDrops = PickLootDrops(UKismetStringLibrary::Conv_StringToName(std::wstring(lootTierGroup.begin(), lootTierGroup.end()).c_str()), -1, true);
|
||||||
|
|
||||||
|
for (int i = 0; i < LootDrops.size(); ++i)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
SendMessageToConsole(PlayerController, L"Printed!");
|
||||||
|
}
|
||||||
|
/* else if (Command == "debugattributes")
|
||||||
|
{
|
||||||
|
auto AbilitySystemComponent = ReceivingPlayerState->GetAbilitySystemComponent();
|
||||||
|
|
||||||
|
if (!AbilitySystemComponent)
|
||||||
|
{
|
||||||
|
SendMessageToConsole(PlayerController, L"No AbilitySystemComponent!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SendMessageToConsole(PlayerController, (L"AbilitySystemComponent->GetSpawnedAttributes().Num(): " + std::to_wstring(AbilitySystemComponent->GetSpawnedAttributes().Num())).c_str());
|
||||||
|
|
||||||
|
for (int i = 0; i < AbilitySystemComponent->GetSpawnedAttributes().Num(); ++i)
|
||||||
|
{
|
||||||
|
auto CurrentAttributePathName = AbilitySystemComponent->GetSpawnedAttributes().at(i)->GetPathName();
|
||||||
|
SendMessageToConsole(PlayerController, (L"SpawnedAttribute Name: " + std::wstring(CurrentAttributePathName.begin(), CurrentAttributePathName.end())).c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (Command == "debugcurrentitem")
|
||||||
|
{
|
||||||
|
auto Pawn = ReceivingController->GetMyFortPawn();
|
||||||
|
|
||||||
|
if (!Pawn)
|
||||||
|
{
|
||||||
|
SendMessageToConsole(PlayerController, L"No pawn!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto CurrentWeapon = Pawn->GetCurrentWeapon();
|
||||||
|
|
||||||
|
if (!CurrentWeapon)
|
||||||
|
{
|
||||||
|
SendMessageToConsole(PlayerController, L"No CurrentWeapon!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto WorldInventory = ReceivingController->GetWorldInventory();
|
||||||
|
|
||||||
|
if (!CurrentWeapon)
|
||||||
|
{
|
||||||
|
SendMessageToConsole(PlayerController, L"No WorldInventory!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto ItemInstance = WorldInventory->FindItemInstance(CurrentWeapon->GetItemEntryGuid());
|
||||||
|
auto ReplicatedEntry = WorldInventory->FindReplicatedEntry(CurrentWeapon->GetItemEntryGuid());
|
||||||
|
|
||||||
|
if (!ItemInstance)
|
||||||
|
{
|
||||||
|
SendMessageToConsole(PlayerController, L"Failed to find ItemInstance!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ReplicatedEntry)
|
||||||
|
{
|
||||||
|
SendMessageToConsole(PlayerController, L"Failed to find ReplicatedEntry!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SendMessageToConsole(PlayerController, (L"ReplicatedEntry->GetGenericAttributeValues().Num(): " + std::to_wstring(ReplicatedEntry->GetGenericAttributeValues().Num())).c_str());
|
||||||
|
SendMessageToConsole(PlayerController, (L"ReplicatedEntry->GetStateValues().Num(): " + std::to_wstring(ReplicatedEntry->GetStateValues().Num())).c_str());
|
||||||
|
|
||||||
|
for (int i = 0; i < ReplicatedEntry->GetStateValues().Num(); ++i)
|
||||||
|
{
|
||||||
|
SendMessageToConsole(PlayerController, (L"[{}] StateValue Type: "
|
||||||
|
+ std::to_wstring((int)ReplicatedEntry->GetStateValues().at(i, FFortItemEntryStateValue::GetStructSize()).GetStateType())).c_str()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} */
|
||||||
|
else if (Command == "op")
|
||||||
|
{
|
||||||
|
if (ReceivingController == PlayerController)
|
||||||
|
{
|
||||||
|
SendMessageToConsole(PlayerController, L"You can't op yourself!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsOp(ReceivingController))
|
||||||
|
{
|
||||||
|
SendMessageToConsole(PlayerController, L"Player is already operator!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Op(ReceivingController);
|
||||||
|
SendMessageToConsole(PlayerController, L"Granted operator to player!");
|
||||||
|
}
|
||||||
|
else if (Command == "deop")
|
||||||
|
{
|
||||||
|
if (!IsOp(ReceivingController))
|
||||||
|
{
|
||||||
|
SendMessageToConsole(PlayerController, L"Player is not operator!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Deop(ReceivingController);
|
||||||
|
SendMessageToConsole(PlayerController, L"Removed operator from player!");
|
||||||
|
}
|
||||||
|
else if (Command == "setpickaxe")
|
||||||
|
{
|
||||||
|
if (NumArgs < 1)
|
||||||
|
{
|
||||||
|
SendMessageToConsole(PlayerController, L"Please provide a pickaxe!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Fortnite_Version < 3) // Idk why but emptyslot kicks the player because of the validate.
|
||||||
|
{
|
||||||
|
SendMessageToConsole(PlayerController, L"Not supported on this version!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto WorldInventory = ReceivingController->GetWorldInventory();
|
||||||
|
|
||||||
|
if (!WorldInventory)
|
||||||
|
{
|
||||||
|
SendMessageToConsole(PlayerController, L"No world inventory!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto& pickaxeName = Arguments[1];
|
||||||
|
static auto AthenaPickaxeItemDefinitionClass = FindObject<UClass>(L"/Script/FortniteGame.AthenaPickaxeItemDefinition");
|
||||||
|
|
||||||
|
auto Pickaxe1 = FindObject(pickaxeName + "." + pickaxeName, nullptr, ANY_PACKAGE);
|
||||||
|
|
||||||
|
UFortWeaponMeleeItemDefinition* NewPickaxeItemDefinition = nullptr;
|
||||||
|
|
||||||
|
if (Pickaxe1)
|
||||||
|
{
|
||||||
|
if (Pickaxe1->IsA(AthenaPickaxeItemDefinitionClass))
|
||||||
|
{
|
||||||
|
static auto WeaponDefinitionOffset = Pickaxe1->GetOffset("WeaponDefinition");
|
||||||
|
NewPickaxeItemDefinition = Pickaxe1->Get<UFortWeaponMeleeItemDefinition*>(WeaponDefinitionOffset);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
NewPickaxeItemDefinition = Cast<UFortWeaponMeleeItemDefinition>(Pickaxe1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!NewPickaxeItemDefinition)
|
||||||
|
{
|
||||||
|
SendMessageToConsole(PlayerController, L"Invalid pickaxe item definition!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto PickaxeInstance = WorldInventory->GetPickaxeInstance();
|
||||||
|
|
||||||
|
if (PickaxeInstance)
|
||||||
|
{
|
||||||
|
WorldInventory->RemoveItem(PickaxeInstance->GetItemEntry()->GetItemGuid(), nullptr, PickaxeInstance->GetItemEntry()->GetCount(), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
WorldInventory->AddItem(NewPickaxeItemDefinition, nullptr, 1);
|
||||||
|
WorldInventory->Update();
|
||||||
|
|
||||||
|
SendMessageToConsole(PlayerController, L"Successfully set pickaxe!");
|
||||||
|
}
|
||||||
|
else if (Command == "load")
|
||||||
|
{
|
||||||
|
if (!Globals::bCreative)
|
||||||
|
{
|
||||||
|
SendMessageToConsole(PlayerController, L"It is not creative!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static auto CreativePlotLinkedVolumeOffset = ReceivingController->GetOffset("CreativePlotLinkedVolume", false);
|
||||||
|
auto Volume = CreativePlotLinkedVolumeOffset == -1 ? nullptr : ReceivingController->GetCreativePlotLinkedVolume();
|
||||||
|
|
||||||
|
if (Arguments.size() <= 1)
|
||||||
|
{
|
||||||
|
SendMessageToConsole(PlayerController, L"Please provide a filename!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string FileName = "islandSave";
|
||||||
|
|
||||||
|
try { FileName = Arguments[1]; }
|
||||||
|
catch (...) {}
|
||||||
|
|
||||||
|
float X{ -1 }, Y{ -1 }, Z{ -1 };
|
||||||
|
|
||||||
|
if (Arguments.size() >= 4)
|
||||||
|
{
|
||||||
|
try { X = std::stof(Arguments[2]); }
|
||||||
|
catch (...) {}
|
||||||
|
try { Y = std::stof(Arguments[3]); }
|
||||||
|
catch (...) {}
|
||||||
|
try { Z = std::stof(Arguments[4]); }
|
||||||
|
catch (...) {}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!Volume)
|
||||||
|
{
|
||||||
|
SendMessageToConsole(PlayerController, L"They do not have an island!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (X != -1 && Y != -1 && Z != -1) // omg what if they want to spawn it at -1 -1 -1!!!
|
||||||
|
Builder::LoadSave(FileName, FVector(X, Y, Z), FRotator());
|
||||||
|
else
|
||||||
|
Builder::LoadSave(FileName, Volume);
|
||||||
|
|
||||||
|
SendMessageToConsole(PlayerController, L"Loaded!");
|
||||||
|
}
|
||||||
|
else if (Command == "spawnpickup")
|
||||||
|
{
|
||||||
|
if (NumArgs < 1)
|
||||||
|
{
|
||||||
|
SendMessageToConsole(PlayerController, L"Please provide a WID!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto Pawn = ReceivingController->GetMyFortPawn();
|
||||||
|
|
||||||
|
if (!Pawn)
|
||||||
|
{
|
||||||
|
SendMessageToConsole(PlayerController, L"No pawn!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto& weaponName = Arguments[1];
|
||||||
|
int count = 1;
|
||||||
|
int amount = 1;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (NumArgs >= 2)
|
||||||
|
count = std::stoi(Arguments[2]);
|
||||||
|
if (NumArgs >= 3)
|
||||||
|
amount = std::stoi(Arguments[3]);
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr int Max = 100;
|
||||||
|
|
||||||
|
if (amount > Max)
|
||||||
|
{
|
||||||
|
SendMessageToConsole(PlayerController, (std::wstring(L"You went over the limit! Only spawning ") + std::to_wstring(Max) + L".").c_str());
|
||||||
|
amount = Max;
|
||||||
|
}
|
||||||
|
|
||||||
|
// LOG_INFO(LogDev, "weaponName: {}", weaponName);
|
||||||
|
|
||||||
|
auto WID = Cast<UFortWorldItemDefinition>(FindObject(weaponName, nullptr, ANY_PACKAGE));
|
||||||
|
|
||||||
|
if (!WID)
|
||||||
|
{
|
||||||
|
SendMessageToConsole(PlayerController, L"Invalid WID!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto Location = Pawn->GetActorLocation();
|
||||||
|
|
||||||
|
auto GameState = Cast<AFortGameStateAthena>(GetWorld()->GetGameState());
|
||||||
|
|
||||||
|
PickupCreateData CreateData;
|
||||||
|
CreateData.ItemEntry = FFortItemEntry::MakeItemEntry(WID, count, -1, MAX_DURABILITY, WID->GetFinalLevel(GameState->GetWorldLevel()));
|
||||||
|
CreateData.SpawnLocation = Location;
|
||||||
|
CreateData.bShouldFreeItemEntryWhenDeconstructed = true;
|
||||||
|
|
||||||
|
for (int i = 0; i < amount; i++)
|
||||||
|
{
|
||||||
|
AFortPickup::SpawnPickup(CreateData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (Command == "listplayers")
|
||||||
|
{
|
||||||
|
std::string PlayerNames;
|
||||||
|
|
||||||
|
for (int i = 0; i < ClientConnections.Num(); i++)
|
||||||
|
{
|
||||||
|
static auto PlayerControllerOffset = ClientConnections.at(i)->GetOffset("PlayerController");
|
||||||
|
auto CurrentPlayerController = Cast<AFortPlayerControllerAthena>(ClientConnections.at(i)->Get(PlayerControllerOffset));
|
||||||
|
|
||||||
|
if (!CurrentPlayerController)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
auto CurrentPlayerState = Cast<AFortPlayerStateAthena>(CurrentPlayerController->GetPlayerState());
|
||||||
|
|
||||||
|
if (!CurrentPlayerState->IsValidLowLevel())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
PlayerNames += "\"" + CurrentPlayerState->GetPlayerName().ToString() + "\" ";
|
||||||
|
}
|
||||||
|
|
||||||
|
SendMessageToConsole(PlayerController, std::wstring(PlayerNames.begin(), PlayerNames.end()).c_str());
|
||||||
|
}
|
||||||
|
else if (Command == "launch")
|
||||||
|
{
|
||||||
|
if (Arguments.size() <= 3)
|
||||||
|
{
|
||||||
|
SendMessageToConsole(PlayerController, L"Please provide X, Y, and Z!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
float X{}, Y{}, Z{};
|
||||||
|
|
||||||
|
try { X = std::stof(Arguments[1]); }
|
||||||
|
catch (...) {}
|
||||||
|
try { Y = std::stof(Arguments[2]); }
|
||||||
|
catch (...) {}
|
||||||
|
try { Z = std::stof(Arguments[3]); }
|
||||||
|
catch (...) {}
|
||||||
|
|
||||||
|
auto Pawn = ReceivingController->GetMyFortPawn();
|
||||||
|
|
||||||
|
if (!Pawn)
|
||||||
|
{
|
||||||
|
SendMessageToConsole(PlayerController, L"No pawn to teleport!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static auto LaunchCharacterFn = FindObject<UFunction>(L"/Script/Engine.Character.LaunchCharacter");
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
FVector LaunchVelocity; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||||
|
bool bXYOverride; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||||
|
bool bZOverride; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
||||||
|
} ACharacter_LaunchCharacter_Params{ FVector(X, Y, Z), false, false };
|
||||||
|
Pawn->ProcessEvent(LaunchCharacterFn, &ACharacter_LaunchCharacter_Params);
|
||||||
|
|
||||||
|
SendMessageToConsole(PlayerController, L"Launched character!");
|
||||||
|
}
|
||||||
|
else if (Command == "setshield")
|
||||||
|
{
|
||||||
|
auto Pawn = ReceivingController->GetMyFortPawn();
|
||||||
|
|
||||||
|
if (!Pawn)
|
||||||
|
{
|
||||||
|
SendMessageToConsole(PlayerController, L"No pawn!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
float Shield = 0.f;
|
||||||
|
|
||||||
|
if (NumArgs >= 1)
|
||||||
|
{
|
||||||
|
try { Shield = std::stof(Arguments[1]); }
|
||||||
|
catch (...) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
Pawn->SetShield(Shield);
|
||||||
|
SendMessageToConsole(PlayerController, L"Set shield!\n");
|
||||||
|
}
|
||||||
|
else if (Command == "god")
|
||||||
|
{
|
||||||
|
auto Pawn = ReceivingController->GetMyFortPawn();
|
||||||
|
|
||||||
|
if (!Pawn)
|
||||||
|
{
|
||||||
|
SendMessageToConsole(PlayerController, L"No pawn!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Pawn->SetCanBeDamaged(!Pawn->CanBeDamaged());
|
||||||
|
SendMessageToConsole(PlayerController, std::wstring(L"God set to " + std::to_wstring(!(bool)Pawn->CanBeDamaged())).c_str());
|
||||||
|
}
|
||||||
|
else if (Command == "applycid")
|
||||||
|
{
|
||||||
|
auto PlayerState = Cast<AFortPlayerState>(ReceivingController->GetPlayerState());
|
||||||
|
|
||||||
|
if (!PlayerState) // ???
|
||||||
|
{
|
||||||
|
SendMessageToConsole(PlayerController, L"No playerstate!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto Pawn = Cast<AFortPlayerPawn>(ReceivingController->GetMyFortPawn());
|
||||||
|
|
||||||
|
std::string CIDStr = Arguments[1];
|
||||||
|
auto CIDDef = FindObject(CIDStr, nullptr, ANY_PACKAGE);
|
||||||
|
// auto CIDDef = UObject::FindObject<UAthenaCharacterItemDefinition>(CIDStr);
|
||||||
|
|
||||||
|
if (!CIDDef)
|
||||||
|
{
|
||||||
|
SendMessageToConsole(PlayerController, L"Invalid character item definition!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_INFO(LogDev, "Applying {}", CIDDef->GetFullName());
|
||||||
|
|
||||||
|
if (!ApplyCID(Pawn, CIDDef))
|
||||||
|
{
|
||||||
|
SendMessageToConsole(PlayerController, L"Failed while applying skin! Please check the server log.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SendMessageToConsole(PlayerController, L"Applied CID!");
|
||||||
|
}
|
||||||
|
else if (Command == "suicide")
|
||||||
|
{
|
||||||
|
static auto ServerSuicideFn = FindObject<UFunction>("/Script/FortniteGame.FortPlayerController.ServerSuicide");
|
||||||
|
ReceivingController->ProcessEvent(ServerSuicideFn);
|
||||||
|
}
|
||||||
|
else if (Command == "summon")
|
||||||
|
{
|
||||||
|
if (Arguments.size() <= 1)
|
||||||
|
{
|
||||||
|
SendMessageToConsole(PlayerController, L"Please provide a class!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto& ClassName = Arguments[1];
|
||||||
|
|
||||||
|
/* if (ClassName.contains("/Script/"))
|
||||||
|
{
|
||||||
|
SendMessageToConsole(PlayerController, L"For now, we don't allow non-blueprint classes.\n");
|
||||||
|
return;
|
||||||
|
} */
|
||||||
|
|
||||||
|
auto Pawn = ReceivingController->GetPawn();
|
||||||
|
|
||||||
|
if (!Pawn)
|
||||||
|
{
|
||||||
|
SendMessageToConsole(PlayerController, L"No pawn to spawn class at!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Count = 1;
|
||||||
|
|
||||||
|
if (Arguments.size() >= 3)
|
||||||
|
{
|
||||||
|
try { Count = std::stod(Arguments[2]); }
|
||||||
|
catch (...) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr int Max = 100;
|
||||||
|
|
||||||
|
if (Count > Max)
|
||||||
|
{
|
||||||
|
SendMessageToConsole(PlayerController, (std::wstring(L"You went over the limit! Only spawning ") + std::to_wstring(Max) + L".").c_str());
|
||||||
|
Count = Max;
|
||||||
|
}
|
||||||
|
|
||||||
|
static auto BGAClass = FindObject<UClass>(L"/Script/Engine.BlueprintGeneratedClass");
|
||||||
|
static auto ClassClass = FindObject<UClass>(L"/Script/CoreUObject.Class");
|
||||||
|
auto ClassObj = ClassName.contains("/Script/") ? FindObject<UClass>(ClassName, ClassClass) : LoadObject<UClass>(ClassName, BGAClass); // scuffy
|
||||||
|
|
||||||
|
if (ClassObj)
|
||||||
|
{
|
||||||
|
int AmountSpawned = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < Count; i++)
|
||||||
|
{
|
||||||
|
auto Loc = Pawn->GetActorLocation();
|
||||||
|
Loc.Z += 1000;
|
||||||
|
auto NewActor = GetWorld()->SpawnActor<AActor>(ClassObj, Loc, FQuat(), FVector(1, 1, 1));
|
||||||
|
|
||||||
|
if (!NewActor)
|
||||||
|
{
|
||||||
|
SendMessageToConsole(PlayerController, L"Failed to spawn an actor!");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AmountSpawned++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SendMessageToConsole(PlayerController, L"Summoned!");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SendMessageToConsole(PlayerController, L"Not a valid class!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (Command == "spawnbottest")
|
||||||
|
{
|
||||||
|
// /Game/Athena/AI/MANG/BotData/
|
||||||
|
|
||||||
|
if (NumArgs < 1)
|
||||||
|
{
|
||||||
|
SendMessageToConsole(PlayerController, L"Please provide a customization object!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto Pawn = ReceivingController->GetPawn();
|
||||||
|
|
||||||
|
if (!Pawn)
|
||||||
|
{
|
||||||
|
SendMessageToConsole(PlayerController, L"No pawn to spawn bot at!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto CustomizationData = LoadObject<UFortAthenaAIBotCustomizationData>(Arguments[1], UFortAthenaAIBotCustomizationData::StaticClass());
|
||||||
|
|
||||||
|
if (!CustomizationData)
|
||||||
|
{
|
||||||
|
SendMessageToConsole(PlayerController, L"Invalid CustomizationData!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto NewPawn = SpawnAIFromCustomizationData(Pawn->GetActorLocation(), CustomizationData);
|
||||||
|
|
||||||
|
if (NewPawn)
|
||||||
|
{
|
||||||
|
SendMessageToConsole(PlayerController, L"Spawned!");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SendMessageToConsole(PlayerController, L"Failed to spawn!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (Command == "spawnbot")
|
||||||
|
{
|
||||||
|
auto Pawn = ReceivingController->GetPawn();
|
||||||
|
|
||||||
|
if (!Pawn)
|
||||||
|
{
|
||||||
|
SendMessageToConsole(PlayerController, L"No pawn to spawn bot at!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Count = 1;
|
||||||
|
|
||||||
|
if (Arguments.size() >= 2)
|
||||||
|
{
|
||||||
|
try { Count = std::stod(Arguments[1]); }
|
||||||
|
catch (...) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr int Max = 99;
|
||||||
|
|
||||||
|
if (Count > Max)
|
||||||
|
{
|
||||||
|
SendMessageToConsole(PlayerController, (std::wstring(L"You went over the limit! Only spawning ") + std::to_wstring(Max) + L".").c_str());
|
||||||
|
Count = Max;
|
||||||
|
}
|
||||||
|
|
||||||
|
int AmountSpawned = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < Count; i++)
|
||||||
|
{
|
||||||
|
FActorSpawnParameters SpawnParameters{};
|
||||||
|
// SpawnParameters.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AdjustIfPossibleButAlwaysSpawn;
|
||||||
|
|
||||||
|
auto Loc = Pawn->GetActorLocation();
|
||||||
|
Loc.Z += 1000;
|
||||||
|
|
||||||
|
FTransform Transform;
|
||||||
|
Transform.Translation = Loc;
|
||||||
|
Transform.Scale3D = FVector(1, 1, 1);
|
||||||
|
|
||||||
|
auto NewActor = Bots::SpawnBot(Transform);
|
||||||
|
|
||||||
|
if (!NewActor)
|
||||||
|
{
|
||||||
|
SendMessageToConsole(PlayerController, L"Failed to spawn an actor!");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AmountSpawned++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SendMessageToConsole(PlayerController, L"Summoned!");
|
||||||
|
}
|
||||||
|
else if (Command == "sethealth")
|
||||||
|
{
|
||||||
|
auto Pawn = ReceivingController->GetMyFortPawn();
|
||||||
|
|
||||||
|
if (!Pawn)
|
||||||
|
{
|
||||||
|
SendMessageToConsole(PlayerController, L"No pawn!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
float Health = 100.f;
|
||||||
|
|
||||||
|
try { Health = std::stof(Arguments[1]); }
|
||||||
|
catch (...) {}
|
||||||
|
|
||||||
|
Pawn->SetHealth(Health);
|
||||||
|
SendMessageToConsole(PlayerController, L"Set health!\n");
|
||||||
|
}
|
||||||
|
else if (Command == "pausesafezone")
|
||||||
|
{
|
||||||
|
auto GameState = Cast<AFortGameStateAthena>(GetWorld()->GetGameState());
|
||||||
|
auto GameMode = Cast<AFortGameModeAthena>(GetWorld()->GetGameMode());
|
||||||
|
|
||||||
|
UKismetSystemLibrary::ExecuteConsoleCommand(GetWorld(), L"pausesafezone", nullptr);
|
||||||
|
// GameMode->PauseSafeZone(GameState->IsSafeZonePaused() == 0);
|
||||||
|
}
|
||||||
|
else if (Command == "teleport" || Command == "tp")
|
||||||
|
{
|
||||||
|
auto CheatManager = ReceivingController->SpawnCheatManager(UCheatManager::StaticClass());
|
||||||
|
|
||||||
|
if (!CheatManager)
|
||||||
|
{
|
||||||
|
SendMessageToConsole(PlayerController, L"Failed to spawn player's cheat manager!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
CheatManager->Teleport();
|
||||||
|
CheatManager = nullptr;
|
||||||
|
SendMessageToConsole(PlayerController, L"Teleported!");
|
||||||
|
}
|
||||||
|
else if (Command == "wipequickbar" || Command == "wipequickbars")
|
||||||
|
{
|
||||||
|
bool bWipePrimary = false;
|
||||||
|
bool bWipeSecondary = false;
|
||||||
|
bool bCheckShouldBeDropped = true;
|
||||||
|
|
||||||
|
bool bWipeSingularQuickbar = Command != "wipequickbars";
|
||||||
|
|
||||||
|
if (bWipeSingularQuickbar)
|
||||||
|
{
|
||||||
|
if (Arguments.size() <= 1)
|
||||||
|
{
|
||||||
|
SendMessageToConsole(PlayerController, L"Please provide \"primary\" or \"secondary\"!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string quickbarType = Arguments[1];
|
||||||
|
std::transform(quickbarType.begin(), quickbarType.end(), quickbarType.begin(), ::tolower);
|
||||||
|
|
||||||
|
if (quickbarType == "primary") bWipePrimary = true;
|
||||||
|
if (quickbarType == "secondary") bWipeSecondary = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bWipePrimary = true;
|
||||||
|
bWipeSecondary = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!bWipePrimary && !bWipeSecondary)
|
||||||
|
{
|
||||||
|
SendMessageToConsole(PlayerController, L"Please provide \"primary\" or \"secondary\"!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Arguments.size() > 1 + bWipeSingularQuickbar)
|
||||||
|
{
|
||||||
|
std::string bypassCanBeDropped = Arguments[1 + bWipeSingularQuickbar];
|
||||||
|
std::transform(bypassCanBeDropped.begin(), bypassCanBeDropped.end(), bypassCanBeDropped.begin(), ::tolower);
|
||||||
|
|
||||||
|
if (bypassCanBeDropped == "true") bCheckShouldBeDropped = true;
|
||||||
|
else if (bypassCanBeDropped == "false") bCheckShouldBeDropped = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto WorldInventory = ReceivingController->GetWorldInventory();
|
||||||
|
|
||||||
|
if (!WorldInventory)
|
||||||
|
{
|
||||||
|
SendMessageToConsole(PlayerController, L"Player does not have a WorldInventory!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static auto FortEditToolItemDefinitionClass = FindObject<UClass>(L"/Script/FortniteGame.FortEditToolItemDefinition");
|
||||||
|
static auto FortBuildingItemDefinitionClass = FindObject<UClass>(L"/Script/FortniteGame.FortBuildingItemDefinition");
|
||||||
|
|
||||||
|
std::vector<std::pair<FGuid, int>> GuidsAndCountsToRemove;
|
||||||
|
const auto& ItemInstances = WorldInventory->GetItemList().GetItemInstances();
|
||||||
|
auto PickaxeInstance = WorldInventory->GetPickaxeInstance();
|
||||||
|
|
||||||
|
for (int i = 0; i < ItemInstances.Num(); ++i)
|
||||||
|
{
|
||||||
|
auto ItemInstance = ItemInstances.at(i);
|
||||||
|
const auto ItemDefinition = Cast<UFortWorldItemDefinition>(ItemInstance->GetItemEntry()->GetItemDefinition());
|
||||||
|
|
||||||
|
if (bCheckShouldBeDropped
|
||||||
|
? ItemDefinition->CanBeDropped()
|
||||||
|
: !ItemDefinition->IsA(FortBuildingItemDefinitionClass)
|
||||||
|
&& !ItemDefinition->IsA(FortEditToolItemDefinitionClass)
|
||||||
|
&& ItemInstance != PickaxeInstance
|
||||||
|
)
|
||||||
|
{
|
||||||
|
bool IsPrimary = IsPrimaryQuickbar(ItemDefinition);
|
||||||
|
|
||||||
|
if ((bWipePrimary && IsPrimary) || (bWipeSecondary && !IsPrimary))
|
||||||
|
{
|
||||||
|
GuidsAndCountsToRemove.push_back({ ItemInstance->GetItemEntry()->GetItemGuid(), ItemInstance->GetItemEntry()->GetCount() });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& [Guid, Count] : GuidsAndCountsToRemove)
|
||||||
|
{
|
||||||
|
WorldInventory->RemoveItem(Guid, nullptr, Count, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
WorldInventory->Update();
|
||||||
|
|
||||||
|
SendMessageToConsole(PlayerController, L"Cleared!\n");
|
||||||
|
}
|
||||||
|
else if (Command == "destroytarget")
|
||||||
|
{
|
||||||
|
auto CheatManager = ReceivingController->SpawnCheatManager(UCheatManager::StaticClass());
|
||||||
|
|
||||||
|
if (!CheatManager)
|
||||||
|
{
|
||||||
|
SendMessageToConsole(PlayerController, L"Failed to spawn player's cheat manager!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
CheatManager->DestroyTarget();
|
||||||
|
CheatManager = nullptr;
|
||||||
|
SendMessageToConsole(PlayerController, L"Destroyed target!");
|
||||||
|
}
|
||||||
|
else if (Command == "bugitgo")
|
||||||
|
{
|
||||||
|
if (Arguments.size() <= 3)
|
||||||
|
{
|
||||||
|
SendMessageToConsole(PlayerController, L"Please provide X, Y, and Z!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
float X{}, Y{}, Z{};
|
||||||
|
|
||||||
|
try { X = std::stof(Arguments[1]); }
|
||||||
|
catch (...) {}
|
||||||
|
try { Y = std::stof(Arguments[2]); }
|
||||||
|
catch (...) {}
|
||||||
|
try { Z = std::stof(Arguments[3]); }
|
||||||
|
catch (...) {}
|
||||||
|
|
||||||
|
auto Pawn = Cast<APawn>(ReceivingController->GetPawn());
|
||||||
|
|
||||||
|
if (!Pawn)
|
||||||
|
{
|
||||||
|
SendMessageToConsole(PlayerController, L"No pawn to teleport!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Pawn->TeleportTo(FVector(X, Y, Z), Pawn->GetActorRotation());
|
||||||
|
SendMessageToConsole(PlayerController, L"Teleported!");
|
||||||
|
}
|
||||||
|
else { bSendHelpMessage = true; };
|
||||||
|
}
|
||||||
|
else { bSendHelpMessage = true; };
|
||||||
|
|
||||||
|
if (bSendHelpMessage)
|
||||||
|
{
|
||||||
|
FString HelpMessage = LR"(
|
||||||
|
cheat giveitem <ShortWID> <Count=1> - Gives a weapon to the executing player, if inventory is full drops a pickup on the player.
|
||||||
|
cheat summon <BlueprintClassPathName> <Count=1> - Summons the specified blueprint class at the executing player's location. Note: There is a limit on the count.
|
||||||
|
cheat bugitgo <X> <Y> <Z> - Teleport to a location.
|
||||||
|
cheat launch <X> <Y> <Z> - Launches a player.
|
||||||
|
cheat listplayers - Gives you all players names.
|
||||||
|
cheat pausesafezone - Pauses the zone.
|
||||||
|
cheat sethealth <Health=100.f> - Sets executing player's health.
|
||||||
|
cheat setshield <Shield=0.f> - Sets executing player's shield.
|
||||||
|
cheat applycid <CIDShortName> - Sets a player's character.
|
||||||
|
cheat spawnpickup <ShortWID> <ItemCount=1> <PickupCount=1> - Spawns a pickup at specified player.
|
||||||
|
cheat teleport/tp - Teleports to what the player is looking at.
|
||||||
|
cheat spawnbot <Amount=1> - Spawns a bot at the player (experimental).
|
||||||
|
cheat setpickaxe <PickaxeID> - Set player's pickaxe. Can be either the PID or WID
|
||||||
|
cheat destroytarget - Destroys the actor that the player is looking at.
|
||||||
|
cheat wipequickbar <Primary|Secondary> <RemoveUndroppables=false> - Wipes the specified quickbar (parameters is not case sensitive).
|
||||||
|
cheat wipequickbars <RemoveUndroppables=false> - Wipes primary and secondary quickbar of targeted player (parameter is not case sensitive).
|
||||||
|
cheat suicide - Makes targeted player suicide.
|
||||||
|
|
||||||
|
If you want to execute a command on a certain player, surround their name (case sensitive) with \, and put the param with their name anywhere. Example: cheat sethealth \Milxnor\ 100
|
||||||
|
)";
|
||||||
|
|
||||||
|
SendMessageToConsole(PlayerController, HelpMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -13,7 +13,7 @@
|
|||||||
#include "ai.h"
|
#include "ai.h"
|
||||||
#include "moderation.h"
|
#include "moderation.h"
|
||||||
|
|
||||||
bool IsOperator(APlayerState* PlayerState, AFortPlayerController* PlayerController)
|
inline bool IsOperator(APlayerState* PlayerState, AFortPlayerController* PlayerController)
|
||||||
{
|
{
|
||||||
auto& IP = PlayerState->GetSavedNetworkAddress();
|
auto& IP = PlayerState->GetSavedNetworkAddress();
|
||||||
auto IPStr = IP.ToString();
|
auto IPStr = IP.ToString();
|
||||||
@@ -47,857 +47,4 @@ inline void SendMessageToConsole(AFortPlayerController* PlayerController, const
|
|||||||
// LOG_INFO(LogDev, "{}", brah);
|
// LOG_INFO(LogDev, "{}", brah);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ServerCheatHook(AFortPlayerControllerAthena* PlayerController, FString Msg)
|
void ServerCheatHook(AFortPlayerControllerAthena* PlayerController, FString Msg);
|
||||||
{
|
|
||||||
if (!Msg.Data.Data || Msg.Data.Num() <= 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
auto PlayerState = Cast<AFortPlayerStateAthena>(PlayerController->GetPlayerState());
|
|
||||||
|
|
||||||
// std::cout << "aa!\n";
|
|
||||||
|
|
||||||
if (!PlayerState || !IsOperator(PlayerState, PlayerController))
|
|
||||||
return;
|
|
||||||
|
|
||||||
std::vector<std::string> Arguments;
|
|
||||||
auto OldMsg = Msg.ToString();
|
|
||||||
|
|
||||||
auto ReceivingController = PlayerController; // for now
|
|
||||||
auto ReceivingPlayerState = PlayerState; // for now
|
|
||||||
|
|
||||||
auto firstBackslash = OldMsg.find_first_of("\\");
|
|
||||||
auto lastBackslash = OldMsg.find_last_of("\\");
|
|
||||||
|
|
||||||
static auto World_NetDriverOffset = GetWorld()->GetOffset("NetDriver");
|
|
||||||
auto WorldNetDriver = GetWorld()->Get<UNetDriver*>(World_NetDriverOffset);
|
|
||||||
auto& ClientConnections = WorldNetDriver->GetClientConnections();
|
|
||||||
|
|
||||||
if (firstBackslash != std::string::npos && lastBackslash != std::string::npos)
|
|
||||||
{
|
|
||||||
if (firstBackslash != lastBackslash)
|
|
||||||
{
|
|
||||||
std::string player = OldMsg;
|
|
||||||
|
|
||||||
player = player.substr(firstBackslash + 1, lastBackslash - firstBackslash - 1);
|
|
||||||
|
|
||||||
for (int i = 0; i < ClientConnections.Num(); ++i)
|
|
||||||
{
|
|
||||||
static auto PlayerControllerOffset = ClientConnections.at(i)->GetOffset("PlayerController");
|
|
||||||
auto CurrentPlayerController = Cast<AFortPlayerControllerAthena>(ClientConnections.at(i)->Get(PlayerControllerOffset));
|
|
||||||
|
|
||||||
if (!CurrentPlayerController)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
auto CurrentPlayerState = Cast<AFortPlayerStateAthena>(CurrentPlayerController->GetPlayerState());
|
|
||||||
|
|
||||||
if (!CurrentPlayerState)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
FString PlayerName = CurrentPlayerState->GetPlayerName();
|
|
||||||
|
|
||||||
if (PlayerName.ToString() == player) // hopefully we arent on adifferent thread
|
|
||||||
{
|
|
||||||
ReceivingController = CurrentPlayerController;
|
|
||||||
ReceivingPlayerState = CurrentPlayerState;
|
|
||||||
PlayerName.Free();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
PlayerName.Free();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// SendMessageToConsole(PlayerController, L"Warning: You have a backslash but no ending backslash, was this by mistake? Executing on you.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ReceivingController || !ReceivingPlayerState)
|
|
||||||
{
|
|
||||||
SendMessageToConsole(PlayerController, L"Unable to find player!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
auto Message = Msg.ToString();
|
|
||||||
|
|
||||||
size_t start = Message.find('\\');
|
|
||||||
|
|
||||||
while (start != std::string::npos) // remove the playername
|
|
||||||
{
|
|
||||||
size_t end = Message.find('\\', start + 1);
|
|
||||||
|
|
||||||
if (end == std::string::npos)
|
|
||||||
break;
|
|
||||||
|
|
||||||
Message.replace(start, end - start + 2, "");
|
|
||||||
start = Message.find('\\');
|
|
||||||
}
|
|
||||||
|
|
||||||
int zz = 0;
|
|
||||||
|
|
||||||
// std::cout << "Message Before: " << Message << '\n';
|
|
||||||
|
|
||||||
while (Message.find(" ") != std::string::npos)
|
|
||||||
{
|
|
||||||
auto arg = Message.substr(0, Message.find(' '));
|
|
||||||
Arguments.push_back(arg);
|
|
||||||
// std::cout << std::format("[{}] {}\n", zz, arg);
|
|
||||||
Message.erase(0, Message.find(' ') + 1);
|
|
||||||
zz++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if (zz == 0)
|
|
||||||
{
|
|
||||||
Arguments.push_back(Message);
|
|
||||||
// std::cout << std::format("[{}] {}\n", zz, Message);
|
|
||||||
zz++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// std::cout << "Message After: " << Message << '\n';
|
|
||||||
}
|
|
||||||
|
|
||||||
auto NumArgs = Arguments.size() == 0 ? 0 : Arguments.size() - 1;
|
|
||||||
|
|
||||||
// std::cout << "NumArgs: " << NumArgs << '\n';
|
|
||||||
|
|
||||||
// return;
|
|
||||||
|
|
||||||
bool bSendHelpMessage = false;
|
|
||||||
|
|
||||||
if (Arguments.size() >= 1)
|
|
||||||
{
|
|
||||||
auto& Command = Arguments[0];
|
|
||||||
std::transform(Command.begin(), Command.end(), Command.begin(), ::tolower);
|
|
||||||
|
|
||||||
if (Command == "giveitem")
|
|
||||||
{
|
|
||||||
if (NumArgs < 1)
|
|
||||||
{
|
|
||||||
SendMessageToConsole(PlayerController, L"Please provide a WID!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto WorldInventory = ReceivingController->GetWorldInventory();
|
|
||||||
|
|
||||||
if (!WorldInventory)
|
|
||||||
{
|
|
||||||
SendMessageToConsole(PlayerController, L"No world inventory!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto& weaponName = Arguments[1];
|
|
||||||
int count = 1;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (NumArgs >= 2)
|
|
||||||
count = std::stoi(Arguments[2]);
|
|
||||||
}
|
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// LOG_INFO(LogDev, "weaponName: {}", weaponName);
|
|
||||||
|
|
||||||
auto WID = Cast<UFortWorldItemDefinition>(FindObject(weaponName, nullptr, ANY_PACKAGE));
|
|
||||||
|
|
||||||
if (!WID)
|
|
||||||
{
|
|
||||||
SendMessageToConsole(PlayerController, L"Invalid WID!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool bShouldUpdate = false;
|
|
||||||
WorldInventory->AddItem(WID, &bShouldUpdate, count);
|
|
||||||
|
|
||||||
if (bShouldUpdate)
|
|
||||||
WorldInventory->Update();
|
|
||||||
|
|
||||||
SendMessageToConsole(PlayerController, L"Granted item!");
|
|
||||||
}
|
|
||||||
else if (Command == "printsimulatelootdrops")
|
|
||||||
{
|
|
||||||
if (NumArgs < 1)
|
|
||||||
{
|
|
||||||
SendMessageToConsole(PlayerController, L"Please provide a LootTierGroup!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto& lootTierGroup = Arguments[1];
|
|
||||||
|
|
||||||
auto LootDrops = PickLootDrops(UKismetStringLibrary::Conv_StringToName(std::wstring(lootTierGroup.begin(), lootTierGroup.end()).c_str()), -1, true);
|
|
||||||
|
|
||||||
for (int i = 0; i < LootDrops.size(); ++i)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
SendMessageToConsole(PlayerController, L"Printed!");
|
|
||||||
}
|
|
||||||
/* else if (Command == "debugattributes")
|
|
||||||
{
|
|
||||||
auto AbilitySystemComponent = ReceivingPlayerState->GetAbilitySystemComponent();
|
|
||||||
|
|
||||||
if (!AbilitySystemComponent)
|
|
||||||
{
|
|
||||||
SendMessageToConsole(PlayerController, L"No AbilitySystemComponent!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
SendMessageToConsole(PlayerController, (L"AbilitySystemComponent->GetSpawnedAttributes().Num(): " + std::to_wstring(AbilitySystemComponent->GetSpawnedAttributes().Num())).c_str());
|
|
||||||
|
|
||||||
for (int i = 0; i < AbilitySystemComponent->GetSpawnedAttributes().Num(); ++i)
|
|
||||||
{
|
|
||||||
auto CurrentAttributePathName = AbilitySystemComponent->GetSpawnedAttributes().at(i)->GetPathName();
|
|
||||||
SendMessageToConsole(PlayerController, (L"SpawnedAttribute Name: " + std::wstring(CurrentAttributePathName.begin(), CurrentAttributePathName.end())).c_str());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (Command == "debugcurrentitem")
|
|
||||||
{
|
|
||||||
auto Pawn = ReceivingController->GetMyFortPawn();
|
|
||||||
|
|
||||||
if (!Pawn)
|
|
||||||
{
|
|
||||||
SendMessageToConsole(PlayerController, L"No pawn!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto CurrentWeapon = Pawn->GetCurrentWeapon();
|
|
||||||
|
|
||||||
if (!CurrentWeapon)
|
|
||||||
{
|
|
||||||
SendMessageToConsole(PlayerController, L"No CurrentWeapon!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto WorldInventory = ReceivingController->GetWorldInventory();
|
|
||||||
|
|
||||||
if (!CurrentWeapon)
|
|
||||||
{
|
|
||||||
SendMessageToConsole(PlayerController, L"No WorldInventory!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto ItemInstance = WorldInventory->FindItemInstance(CurrentWeapon->GetItemEntryGuid());
|
|
||||||
auto ReplicatedEntry = WorldInventory->FindReplicatedEntry(CurrentWeapon->GetItemEntryGuid());
|
|
||||||
|
|
||||||
if (!ItemInstance)
|
|
||||||
{
|
|
||||||
SendMessageToConsole(PlayerController, L"Failed to find ItemInstance!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ReplicatedEntry)
|
|
||||||
{
|
|
||||||
SendMessageToConsole(PlayerController, L"Failed to find ReplicatedEntry!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
SendMessageToConsole(PlayerController, (L"ReplicatedEntry->GetGenericAttributeValues().Num(): " + std::to_wstring(ReplicatedEntry->GetGenericAttributeValues().Num())).c_str());
|
|
||||||
SendMessageToConsole(PlayerController, (L"ReplicatedEntry->GetStateValues().Num(): " + std::to_wstring(ReplicatedEntry->GetStateValues().Num())).c_str());
|
|
||||||
|
|
||||||
for (int i = 0; i < ReplicatedEntry->GetStateValues().Num(); ++i)
|
|
||||||
{
|
|
||||||
SendMessageToConsole(PlayerController, (L"[{}] StateValue Type: "
|
|
||||||
+ std::to_wstring((int)ReplicatedEntry->GetStateValues().at(i, FFortItemEntryStateValue::GetStructSize()).GetStateType())).c_str()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} */
|
|
||||||
else if (Command == "op")
|
|
||||||
{
|
|
||||||
if (ReceivingController == PlayerController)
|
|
||||||
{
|
|
||||||
SendMessageToConsole(PlayerController, L"You can't op yourself!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IsOp(ReceivingController))
|
|
||||||
{
|
|
||||||
SendMessageToConsole(PlayerController, L"Player is already operator!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Op(ReceivingController);
|
|
||||||
SendMessageToConsole(PlayerController, L"Granted operator to player!");
|
|
||||||
}
|
|
||||||
else if (Command == "deop")
|
|
||||||
{
|
|
||||||
if (!IsOp(ReceivingController))
|
|
||||||
{
|
|
||||||
SendMessageToConsole(PlayerController, L"Player is not operator!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Deop(ReceivingController);
|
|
||||||
SendMessageToConsole(PlayerController, L"Removed operator from player!");
|
|
||||||
}
|
|
||||||
else if (Command == "setpickaxe")
|
|
||||||
{
|
|
||||||
if (NumArgs < 1)
|
|
||||||
{
|
|
||||||
SendMessageToConsole(PlayerController, L"Please provide a pickaxe!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Fortnite_Version < 3) // Idk why but emptyslot kicks the player because of the validate.
|
|
||||||
{
|
|
||||||
SendMessageToConsole(PlayerController, L"Not supported on this version!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto WorldInventory = ReceivingController->GetWorldInventory();
|
|
||||||
|
|
||||||
if (!WorldInventory)
|
|
||||||
{
|
|
||||||
SendMessageToConsole(PlayerController, L"No world inventory!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto& pickaxeName = Arguments[1];
|
|
||||||
static auto AthenaPickaxeItemDefinitionClass = FindObject<UClass>("/Script/FortniteGame.AthenaPickaxeItemDefinition");
|
|
||||||
|
|
||||||
auto Pickaxe1 = FindObject(pickaxeName + "." + pickaxeName, nullptr, ANY_PACKAGE);
|
|
||||||
|
|
||||||
UFortWeaponMeleeItemDefinition* NewPickaxeItemDefinition = nullptr;
|
|
||||||
|
|
||||||
if (Pickaxe1)
|
|
||||||
{
|
|
||||||
if (Pickaxe1->IsA(AthenaPickaxeItemDefinitionClass))
|
|
||||||
{
|
|
||||||
static auto WeaponDefinitionOffset = Pickaxe1->GetOffset("WeaponDefinition");
|
|
||||||
NewPickaxeItemDefinition = Pickaxe1->Get<UFortWeaponMeleeItemDefinition*>(WeaponDefinitionOffset);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
NewPickaxeItemDefinition = Cast<UFortWeaponMeleeItemDefinition>(Pickaxe1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!NewPickaxeItemDefinition)
|
|
||||||
{
|
|
||||||
SendMessageToConsole(PlayerController, L"Invalid pickaxe item definition!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto PickaxeInstance = WorldInventory->GetPickaxeInstance();
|
|
||||||
|
|
||||||
if (PickaxeInstance)
|
|
||||||
{
|
|
||||||
WorldInventory->RemoveItem(PickaxeInstance->GetItemEntry()->GetItemGuid(), nullptr, PickaxeInstance->GetItemEntry()->GetCount(), true);
|
|
||||||
}
|
|
||||||
|
|
||||||
WorldInventory->AddItem(NewPickaxeItemDefinition, nullptr, 1);
|
|
||||||
WorldInventory->Update();
|
|
||||||
|
|
||||||
SendMessageToConsole(PlayerController, L"Successfully set pickaxe!");
|
|
||||||
}
|
|
||||||
else if (Command == "load")
|
|
||||||
{
|
|
||||||
if (!Globals::bCreative)
|
|
||||||
{
|
|
||||||
SendMessageToConsole(PlayerController, L"It is not creative!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
static auto CreativePlotLinkedVolumeOffset = ReceivingController->GetOffset("CreativePlotLinkedVolume", false);
|
|
||||||
auto Volume = CreativePlotLinkedVolumeOffset == -1 ? nullptr : ReceivingController->GetCreativePlotLinkedVolume();
|
|
||||||
|
|
||||||
if (Arguments.size() <= 1)
|
|
||||||
{
|
|
||||||
SendMessageToConsole(PlayerController, L"Please provide a filename!\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string FileName = "islandSave";
|
|
||||||
|
|
||||||
try { FileName = Arguments[1]; }
|
|
||||||
catch (...) {}
|
|
||||||
|
|
||||||
float X{ -1 }, Y{ -1 }, Z{ -1 };
|
|
||||||
|
|
||||||
if (Arguments.size() >= 4)
|
|
||||||
{
|
|
||||||
try { X = std::stof(Arguments[2]); }
|
|
||||||
catch (...) {}
|
|
||||||
try { Y = std::stof(Arguments[3]); }
|
|
||||||
catch (...) {}
|
|
||||||
try { Z = std::stof(Arguments[4]); }
|
|
||||||
catch (...) {}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!Volume)
|
|
||||||
{
|
|
||||||
SendMessageToConsole(PlayerController, L"They do not have an island!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (X != -1 && Y != -1 && Z != -1) // omg what if they want to spawn it at -1 -1 -1!!!
|
|
||||||
Builder::LoadSave(FileName, FVector(X, Y, Z), FRotator());
|
|
||||||
else
|
|
||||||
Builder::LoadSave(FileName, Volume);
|
|
||||||
|
|
||||||
SendMessageToConsole(PlayerController, L"Loaded!");
|
|
||||||
}
|
|
||||||
else if (Command == "spawnpickup")
|
|
||||||
{
|
|
||||||
if (NumArgs < 1)
|
|
||||||
{
|
|
||||||
SendMessageToConsole(PlayerController, L"Please provide a WID!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto Pawn = ReceivingController->GetMyFortPawn();
|
|
||||||
|
|
||||||
if (!Pawn)
|
|
||||||
{
|
|
||||||
SendMessageToConsole(PlayerController, L"No pawn!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto& weaponName = Arguments[1];
|
|
||||||
int count = 1;
|
|
||||||
int amount = 1;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (NumArgs >= 2)
|
|
||||||
count = std::stoi(Arguments[2]);
|
|
||||||
if (NumArgs >= 3)
|
|
||||||
amount = std::stoi(Arguments[3]);
|
|
||||||
}
|
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr int Max = 100;
|
|
||||||
|
|
||||||
if (amount > Max)
|
|
||||||
{
|
|
||||||
SendMessageToConsole(PlayerController, (std::wstring(L"You went over the limit! Only spawning ") + std::to_wstring(Max) + L".").c_str());
|
|
||||||
amount = Max;
|
|
||||||
}
|
|
||||||
|
|
||||||
// LOG_INFO(LogDev, "weaponName: {}", weaponName);
|
|
||||||
|
|
||||||
auto WID = Cast<UFortWorldItemDefinition>(FindObject(weaponName, nullptr, ANY_PACKAGE));
|
|
||||||
|
|
||||||
if (!WID)
|
|
||||||
{
|
|
||||||
SendMessageToConsole(PlayerController, L"Invalid WID!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto Location = Pawn->GetActorLocation();
|
|
||||||
|
|
||||||
auto GameState = Cast<AFortGameStateAthena>(GetWorld()->GetGameState());
|
|
||||||
|
|
||||||
PickupCreateData CreateData;
|
|
||||||
CreateData.ItemEntry = FFortItemEntry::MakeItemEntry(WID, count, -1, MAX_DURABILITY, WID->GetFinalLevel(GameState->GetWorldLevel()));
|
|
||||||
CreateData.SpawnLocation = Location;
|
|
||||||
CreateData.bShouldFreeItemEntryWhenDeconstructed = true;
|
|
||||||
|
|
||||||
for (int i = 0; i < amount; i++)
|
|
||||||
{
|
|
||||||
AFortPickup::SpawnPickup(CreateData);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (Command == "listplayers")
|
|
||||||
{
|
|
||||||
std::string PlayerNames;
|
|
||||||
|
|
||||||
for (int i = 0; i < ClientConnections.Num(); i++)
|
|
||||||
{
|
|
||||||
static auto PlayerControllerOffset = ClientConnections.at(i)->GetOffset("PlayerController");
|
|
||||||
auto CurrentPlayerController = Cast<AFortPlayerControllerAthena>(ClientConnections.at(i)->Get(PlayerControllerOffset));
|
|
||||||
|
|
||||||
if (!CurrentPlayerController)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
auto CurrentPlayerState = Cast<AFortPlayerStateAthena>(CurrentPlayerController->GetPlayerState());
|
|
||||||
|
|
||||||
if (!CurrentPlayerState->IsValidLowLevel())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
PlayerNames += "\"" + CurrentPlayerState->GetPlayerName().ToString() + "\" ";
|
|
||||||
}
|
|
||||||
|
|
||||||
SendMessageToConsole(PlayerController, std::wstring(PlayerNames.begin(), PlayerNames.end()).c_str());
|
|
||||||
}
|
|
||||||
else if (Command == "launch")
|
|
||||||
{
|
|
||||||
if (Arguments.size() <= 3)
|
|
||||||
{
|
|
||||||
SendMessageToConsole(PlayerController, L"Please provide X, Y, and Z!\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
float X{}, Y{}, Z{};
|
|
||||||
|
|
||||||
try { X = std::stof(Arguments[1]); }
|
|
||||||
catch (...) {}
|
|
||||||
try { Y = std::stof(Arguments[2]); }
|
|
||||||
catch (...) {}
|
|
||||||
try { Z = std::stof(Arguments[3]); }
|
|
||||||
catch (...) {}
|
|
||||||
|
|
||||||
auto Pawn = ReceivingController->GetMyFortPawn();
|
|
||||||
|
|
||||||
if (!Pawn)
|
|
||||||
{
|
|
||||||
SendMessageToConsole(PlayerController, L"No pawn to teleport!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
static auto LaunchCharacterFn = FindObject<UFunction>(L"/Script/Engine.Character.LaunchCharacter");
|
|
||||||
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
FVector LaunchVelocity; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
|
||||||
bool bXYOverride; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
|
||||||
bool bZOverride; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)
|
|
||||||
} ACharacter_LaunchCharacter_Params{ FVector(X, Y, Z), false, false};
|
|
||||||
Pawn->ProcessEvent(LaunchCharacterFn, &ACharacter_LaunchCharacter_Params);
|
|
||||||
|
|
||||||
SendMessageToConsole(PlayerController, L"Launched character!");
|
|
||||||
}
|
|
||||||
else if (Command == "setshield")
|
|
||||||
{
|
|
||||||
auto Pawn = ReceivingController->GetMyFortPawn();
|
|
||||||
|
|
||||||
if (!Pawn)
|
|
||||||
{
|
|
||||||
SendMessageToConsole(PlayerController, L"No pawn!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
float Shield = 0.f;
|
|
||||||
|
|
||||||
if (NumArgs >= 1)
|
|
||||||
{
|
|
||||||
try { Shield = std::stof(Arguments[1]); }
|
|
||||||
catch (...) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
Pawn->SetShield(Shield);
|
|
||||||
SendMessageToConsole(PlayerController, L"Set shield!\n");
|
|
||||||
}
|
|
||||||
else if (Command == "god")
|
|
||||||
{
|
|
||||||
auto Pawn = ReceivingController->GetMyFortPawn();
|
|
||||||
|
|
||||||
if (!Pawn)
|
|
||||||
{
|
|
||||||
SendMessageToConsole(PlayerController, L"No pawn!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Pawn->SetCanBeDamaged(!Pawn->CanBeDamaged());
|
|
||||||
SendMessageToConsole(PlayerController, std::wstring(L"God set to " + std::to_wstring(!(bool)Pawn->CanBeDamaged())).c_str());
|
|
||||||
}
|
|
||||||
else if (Command == "applycid")
|
|
||||||
{
|
|
||||||
auto PlayerState = Cast<AFortPlayerState>(ReceivingController->GetPlayerState());
|
|
||||||
|
|
||||||
if (!PlayerState) // ???
|
|
||||||
{
|
|
||||||
SendMessageToConsole(PlayerController, L"No playerstate!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto Pawn = Cast<AFortPlayerPawn>(ReceivingController->GetMyFortPawn());
|
|
||||||
|
|
||||||
std::string CIDStr = Arguments[1];
|
|
||||||
auto CIDDef = FindObject(CIDStr, nullptr, ANY_PACKAGE);
|
|
||||||
// auto CIDDef = UObject::FindObject<UAthenaCharacterItemDefinition>(CIDStr);
|
|
||||||
|
|
||||||
if (!CIDDef)
|
|
||||||
{
|
|
||||||
SendMessageToConsole(PlayerController, L"Invalid character item definition!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
LOG_INFO(LogDev, "Applying {}", CIDDef->GetFullName());
|
|
||||||
|
|
||||||
if (!ApplyCID(Pawn, CIDDef))
|
|
||||||
{
|
|
||||||
SendMessageToConsole(PlayerController, L"Failed while applying skin! Please check the server log.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
SendMessageToConsole(PlayerController, L"Applied CID!");
|
|
||||||
}
|
|
||||||
else if (Command == "summon")
|
|
||||||
{
|
|
||||||
if (Arguments.size() <= 1)
|
|
||||||
{
|
|
||||||
SendMessageToConsole(PlayerController, L"Please provide a class!\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto& ClassName = Arguments[1];
|
|
||||||
|
|
||||||
/* if (ClassName.contains("/Script/"))
|
|
||||||
{
|
|
||||||
SendMessageToConsole(PlayerController, L"For now, we don't allow non-blueprint classes.\n");
|
|
||||||
return;
|
|
||||||
} */
|
|
||||||
|
|
||||||
auto Pawn = ReceivingController->GetPawn();
|
|
||||||
|
|
||||||
if (!Pawn)
|
|
||||||
{
|
|
||||||
SendMessageToConsole(PlayerController, L"No pawn to spawn class at!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int Count = 1;
|
|
||||||
|
|
||||||
if (Arguments.size() >= 3)
|
|
||||||
{
|
|
||||||
try { Count = std::stod(Arguments[2]); }
|
|
||||||
catch (...) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr int Max = 100;
|
|
||||||
|
|
||||||
if (Count > Max)
|
|
||||||
{
|
|
||||||
SendMessageToConsole(PlayerController, (std::wstring(L"You went over the limit! Only spawning ") + std::to_wstring(Max) + L".").c_str());
|
|
||||||
Count = Max;
|
|
||||||
}
|
|
||||||
|
|
||||||
static auto BGAClass = FindObject<UClass>(L"/Script/Engine.BlueprintGeneratedClass");
|
|
||||||
static auto ClassClass = FindObject<UClass>(L"/Script/CoreUObject.Class");
|
|
||||||
auto ClassObj = ClassName.contains("/Script/") ? FindObject<UClass>(ClassName, ClassClass) : LoadObject<UClass>(ClassName, BGAClass); // scuffy
|
|
||||||
|
|
||||||
if (ClassObj)
|
|
||||||
{
|
|
||||||
int AmountSpawned = 0;
|
|
||||||
|
|
||||||
for (int i = 0; i < Count; i++)
|
|
||||||
{
|
|
||||||
auto Loc = Pawn->GetActorLocation();
|
|
||||||
Loc.Z += 1000;
|
|
||||||
auto NewActor = GetWorld()->SpawnActor<AActor>(ClassObj, Loc, FQuat(), FVector(1, 1, 1));
|
|
||||||
|
|
||||||
if (!NewActor)
|
|
||||||
{
|
|
||||||
SendMessageToConsole(PlayerController, L"Failed to spawn an actor!");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
AmountSpawned++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SendMessageToConsole(PlayerController, L"Summoned!");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SendMessageToConsole(PlayerController, L"Not a valid class!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (Command == "spawnbottest")
|
|
||||||
{
|
|
||||||
// /Game/Athena/AI/MANG/BotData/
|
|
||||||
|
|
||||||
if (NumArgs < 1)
|
|
||||||
{
|
|
||||||
SendMessageToConsole(PlayerController, L"Please provide a customization object!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto Pawn = ReceivingController->GetPawn();
|
|
||||||
|
|
||||||
if (!Pawn)
|
|
||||||
{
|
|
||||||
SendMessageToConsole(PlayerController, L"No pawn to spawn bot at!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto CustomizationData = LoadObject<UFortAthenaAIBotCustomizationData>(Arguments[1], UFortAthenaAIBotCustomizationData::StaticClass());
|
|
||||||
|
|
||||||
if (!CustomizationData)
|
|
||||||
{
|
|
||||||
SendMessageToConsole(PlayerController, L"Invalid CustomizationData!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto NewPawn = SpawnAIFromCustomizationData(Pawn->GetActorLocation(), CustomizationData);
|
|
||||||
|
|
||||||
if (NewPawn)
|
|
||||||
{
|
|
||||||
SendMessageToConsole(PlayerController, L"Spawned!");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SendMessageToConsole(PlayerController, L"Failed to spawn!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (Command == "spawnbot")
|
|
||||||
{
|
|
||||||
auto Pawn = ReceivingController->GetPawn();
|
|
||||||
|
|
||||||
if (!Pawn)
|
|
||||||
{
|
|
||||||
SendMessageToConsole(PlayerController, L"No pawn to spawn bot at!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int Count = 1;
|
|
||||||
|
|
||||||
if (Arguments.size() >= 2)
|
|
||||||
{
|
|
||||||
try { Count = std::stod(Arguments[1]); }
|
|
||||||
catch (...) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr int Max = 99;
|
|
||||||
|
|
||||||
if (Count > Max)
|
|
||||||
{
|
|
||||||
SendMessageToConsole(PlayerController, (std::wstring(L"You went over the limit! Only spawning ") + std::to_wstring(Max) + L".").c_str());
|
|
||||||
Count = Max;
|
|
||||||
}
|
|
||||||
|
|
||||||
int AmountSpawned = 0;
|
|
||||||
|
|
||||||
for (int i = 0; i < Count; i++)
|
|
||||||
{
|
|
||||||
FActorSpawnParameters SpawnParameters{};
|
|
||||||
// SpawnParameters.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AdjustIfPossibleButAlwaysSpawn;
|
|
||||||
|
|
||||||
auto Loc = Pawn->GetActorLocation();
|
|
||||||
Loc.Z += 1000;
|
|
||||||
|
|
||||||
FTransform Transform;
|
|
||||||
Transform.Translation = Loc;
|
|
||||||
Transform.Scale3D = FVector(1, 1, 1);
|
|
||||||
|
|
||||||
auto NewActor = Bots::SpawnBot(Transform);
|
|
||||||
|
|
||||||
if (!NewActor)
|
|
||||||
{
|
|
||||||
SendMessageToConsole(PlayerController, L"Failed to spawn an actor!");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
AmountSpawned++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SendMessageToConsole(PlayerController, L"Summoned!");
|
|
||||||
}
|
|
||||||
else if (Command == "sethealth")
|
|
||||||
{
|
|
||||||
auto Pawn = ReceivingController->GetMyFortPawn();
|
|
||||||
|
|
||||||
if (!Pawn)
|
|
||||||
{
|
|
||||||
SendMessageToConsole(PlayerController, L"No pawn!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
float Health = 100.f;
|
|
||||||
|
|
||||||
try { Health = std::stof(Arguments[1]); }
|
|
||||||
catch (...) {}
|
|
||||||
|
|
||||||
Pawn->SetHealth(Health);
|
|
||||||
SendMessageToConsole(PlayerController, L"Set health!\n");
|
|
||||||
}
|
|
||||||
else if (Command == "pausesafezone")
|
|
||||||
{
|
|
||||||
auto GameState = Cast<AFortGameStateAthena>(GetWorld()->GetGameState());
|
|
||||||
auto GameMode = Cast<AFortGameModeAthena>(GetWorld()->GetGameMode());
|
|
||||||
|
|
||||||
UKismetSystemLibrary::ExecuteConsoleCommand(GetWorld(), L"pausesafezone", nullptr);
|
|
||||||
// GameMode->PauseSafeZone(GameState->IsSafeZonePaused() == 0);
|
|
||||||
}
|
|
||||||
else if (Command == "teleport")
|
|
||||||
{
|
|
||||||
auto CheatManager = ReceivingController->SpawnCheatManager(UCheatManager::StaticClass());
|
|
||||||
|
|
||||||
if (!CheatManager)
|
|
||||||
{
|
|
||||||
SendMessageToConsole(PlayerController, L"Failed to spawn player's cheat manager!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
CheatManager->Teleport();
|
|
||||||
CheatManager = nullptr;
|
|
||||||
SendMessageToConsole(PlayerController, L"Teleported!");
|
|
||||||
}
|
|
||||||
else if (Command == "destroytarget")
|
|
||||||
{
|
|
||||||
auto CheatManager = ReceivingController->SpawnCheatManager(UCheatManager::StaticClass());
|
|
||||||
|
|
||||||
if (!CheatManager)
|
|
||||||
{
|
|
||||||
SendMessageToConsole(PlayerController, L"Failed to spawn player's cheat manager!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
CheatManager->DestroyTarget();
|
|
||||||
CheatManager = nullptr;
|
|
||||||
SendMessageToConsole(PlayerController, L"Destroyed target!");
|
|
||||||
}
|
|
||||||
else if (Command == "bugitgo")
|
|
||||||
{
|
|
||||||
if (Arguments.size() <= 3)
|
|
||||||
{
|
|
||||||
SendMessageToConsole(PlayerController, L"Please provide X, Y, and Z!\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
float X{}, Y{}, Z{};
|
|
||||||
|
|
||||||
try { X = std::stof(Arguments[1]); }
|
|
||||||
catch (...) {}
|
|
||||||
try { Y = std::stof(Arguments[2]); }
|
|
||||||
catch (...) {}
|
|
||||||
try { Z = std::stof(Arguments[3]); }
|
|
||||||
catch (...) {}
|
|
||||||
|
|
||||||
auto Pawn = Cast<APawn>(ReceivingController->GetPawn());
|
|
||||||
|
|
||||||
if (!Pawn)
|
|
||||||
{
|
|
||||||
SendMessageToConsole(PlayerController, L"No pawn to teleport!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Pawn->TeleportTo(FVector(X, Y, Z), Pawn->GetActorRotation());
|
|
||||||
SendMessageToConsole(PlayerController, L"Teleported!");
|
|
||||||
}
|
|
||||||
else { bSendHelpMessage = true; };
|
|
||||||
}
|
|
||||||
else { bSendHelpMessage = true; };
|
|
||||||
|
|
||||||
if (bSendHelpMessage)
|
|
||||||
{
|
|
||||||
FString HelpMessage = LR"(
|
|
||||||
cheat giveitem <ShortWID> <Count=1> - Gives a weapon to the executing player, if inventory is full drops a pickup on the player.
|
|
||||||
cheat summon <BlueprintClassPathName> <Count=1> - Summons the specified blueprint class at the executing player's location. Note: There is a limit on the count.
|
|
||||||
cheat bugitgo <X> <Y> <Z> - Teleport to a location.
|
|
||||||
cheat launch <X> <Y> <Z> - Launches a player.
|
|
||||||
cheat listplayers - Gives you all players names.
|
|
||||||
cheat pausesafezone - Pauses the zone.
|
|
||||||
cheat sethealth <Health=100.f> - Sets executing player's health.
|
|
||||||
cheat setshield <Shield=0.f> - Sets executing player's shield.
|
|
||||||
cheat applycid <CIDShortName> - Sets a player's character.
|
|
||||||
cheat spawnpickup <ShortWID> <ItemCount=1> <PickupCount=1> - Spawns a pickup at specified player.
|
|
||||||
cheat teleport - Teleports to what the player is looking at.
|
|
||||||
cheat spawnbot <Amount=1> - Spawns a bot at the player (experimental).
|
|
||||||
cheat setpickaxe <PickaxeID> - Set player's pickaxe.
|
|
||||||
cheat destroytarget - Destroys the actor that the player is looking at.
|
|
||||||
|
|
||||||
If you want to execute a command on a certain player, surround their name (case sensitive) with \, and put the param anywhere. Example: cheat sethealth \Milxnor\ 100
|
|
||||||
)";
|
|
||||||
|
|
||||||
SendMessageToConsole(PlayerController, HelpMessage);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -10,151 +10,7 @@
|
|||||||
|
|
||||||
static inline void (*SetZoneToIndexOriginal)(AFortGameModeAthena* GameModeAthena, int OverridePhaseMaybeIDFK);
|
static inline void (*SetZoneToIndexOriginal)(AFortGameModeAthena* GameModeAthena, int OverridePhaseMaybeIDFK);
|
||||||
|
|
||||||
static inline void SetZoneToIndexHook(AFortGameModeAthena* GameModeAthena, int OverridePhaseMaybeIDFK)
|
void SetZoneToIndexHook(AFortGameModeAthena* GameModeAthena, int OverridePhaseMaybeIDFK);
|
||||||
{
|
|
||||||
static auto ZoneDurationsOffset = Fortnite_Version >= 15 && Fortnite_Version < 18 ? 0x258
|
|
||||||
: std::floor(Fortnite_Version) >= 18 ? 0x248
|
|
||||||
: 0x1F8; // S13-S14
|
|
||||||
|
|
||||||
static auto GameMode_SafeZonePhaseOffset = GameModeAthena->GetOffset("SafeZonePhase");
|
|
||||||
auto GameState = Cast<AFortGameStateAthena>(GameModeAthena->GetGameState());
|
|
||||||
|
|
||||||
if (!GameState)
|
|
||||||
return SetZoneToIndexOriginal(GameModeAthena, OverridePhaseMaybeIDFK);
|
|
||||||
|
|
||||||
auto SafeZoneIndicator = GameModeAthena->GetSafeZoneIndicator();
|
|
||||||
|
|
||||||
static auto GameState_SafeZonePhaseOffset = GameState->GetOffset("SafeZonePhase");
|
|
||||||
|
|
||||||
static int NewLateGameSafeZonePhase = 2;
|
|
||||||
|
|
||||||
LOG_INFO(LogDev, "NewLateGameSafeZonePhase: {}", NewLateGameSafeZonePhase);
|
|
||||||
|
|
||||||
if (Fortnite_Version < 13)
|
|
||||||
{
|
|
||||||
if (Globals::bLateGame.load())
|
|
||||||
{
|
|
||||||
GameModeAthena->Get<int>(GameMode_SafeZonePhaseOffset) = NewLateGameSafeZonePhase;
|
|
||||||
GameState->Get<int>(GameState_SafeZonePhaseOffset) = NewLateGameSafeZonePhase;
|
|
||||||
SetZoneToIndexOriginal(GameModeAthena, OverridePhaseMaybeIDFK);
|
|
||||||
|
|
||||||
if (NewLateGameSafeZonePhase == 2 || NewLateGameSafeZonePhase == 3)
|
|
||||||
{
|
|
||||||
if (SafeZoneIndicator)
|
|
||||||
SafeZoneIndicator->SkipShrinkSafeZone();
|
|
||||||
else
|
|
||||||
LOG_WARN(LogZone, "Invalid SafeZoneIndicator!");
|
|
||||||
}
|
|
||||||
|
|
||||||
NewLateGameSafeZonePhase++;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
return SetZoneToIndexOriginal(GameModeAthena, OverridePhaseMaybeIDFK);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!SafeZoneIndicator)
|
|
||||||
{
|
|
||||||
LOG_WARN(LogZone, "Invalid SafeZoneIndicator!");
|
|
||||||
return SetZoneToIndexOriginal(GameModeAthena, OverridePhaseMaybeIDFK);
|
|
||||||
}
|
|
||||||
|
|
||||||
static auto SafeZoneFinishShrinkTimeOffset = SafeZoneIndicator->GetOffset("SafeZoneFinishShrinkTime");
|
|
||||||
static auto SafeZoneStartShrinkTimeOffset = SafeZoneIndicator->GetOffset("SafeZoneStartShrinkTime");
|
|
||||||
static auto RadiusOffset = SafeZoneIndicator->GetOffset("Radius");
|
|
||||||
|
|
||||||
static auto SafeZonePhaseOffset = GameModeAthena->GetOffset("SafeZonePhase");
|
|
||||||
|
|
||||||
static auto MapInfoOffset = GameState->GetOffset("MapInfo");
|
|
||||||
auto MapInfo = GameState->Get<AActor*>(MapInfoOffset);
|
|
||||||
|
|
||||||
if (!MapInfo)
|
|
||||||
{
|
|
||||||
LOG_WARN(LogZone, "Invalid MapInfo!")
|
|
||||||
return SetZoneToIndexOriginal(GameModeAthena, OverridePhaseMaybeIDFK);
|
|
||||||
}
|
|
||||||
|
|
||||||
static auto SafeZoneDefinitionOffset = MapInfo->GetOffset("SafeZoneDefinition");
|
|
||||||
auto SafeZoneDefinition = MapInfo->GetPtr<__int64>(SafeZoneDefinitionOffset);
|
|
||||||
|
|
||||||
LOG_INFO(LogDev, "SafeZoneDefinitionOffset: 0x{:x}", SafeZoneDefinitionOffset);
|
|
||||||
|
|
||||||
static auto ZoneHoldDurationsOffset = ZoneDurationsOffset - 0x10; // fr
|
|
||||||
|
|
||||||
auto& ZoneDurations = *(TArray<float>*)(__int64(SafeZoneDefinition) + ZoneDurationsOffset);
|
|
||||||
auto& ZoneHoldDurations = *(TArray<float>*)(__int64(SafeZoneDefinition) + ZoneHoldDurationsOffset);
|
|
||||||
|
|
||||||
static bool bFilledDurations = false;
|
|
||||||
|
|
||||||
if (!bFilledDurations)
|
|
||||||
{
|
|
||||||
bFilledDurations = true;
|
|
||||||
|
|
||||||
auto CurrentPlaylist = GameState->GetCurrentPlaylist();
|
|
||||||
UCurveTable* FortGameData = nullptr;
|
|
||||||
|
|
||||||
static auto GameDataOffset = CurrentPlaylist->GetOffset("GameData");
|
|
||||||
FortGameData = CurrentPlaylist ? CurrentPlaylist->Get<TSoftObjectPtr<UCurveTable>>(GameDataOffset).Get() : nullptr;
|
|
||||||
|
|
||||||
if (!FortGameData)
|
|
||||||
FortGameData = FindObject<UCurveTable>(L"/Game/Balance/AthenaGameData.AthenaGameData");
|
|
||||||
|
|
||||||
auto ShrinkTimeFName = UKismetStringLibrary::Conv_StringToName(L"Default.SafeZone.ShrinkTime");
|
|
||||||
auto HoldTimeFName = UKismetStringLibrary::Conv_StringToName(L"Default.SafeZone.WaitTime");
|
|
||||||
|
|
||||||
for (int i = 0; i < ZoneDurations.Num(); i++)
|
|
||||||
{
|
|
||||||
ZoneDurations.at(i) = FortGameData->GetValueOfKey(FortGameData->GetKey(ShrinkTimeFName, i));
|
|
||||||
}
|
|
||||||
for (int i = 0; i < ZoneHoldDurations.Num(); i++)
|
|
||||||
{
|
|
||||||
ZoneHoldDurations.at(i) = FortGameData->GetValueOfKey(FortGameData->GetKey(HoldTimeFName, i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LOG_INFO(LogZone, "SafeZonePhase: {}", GameModeAthena->Get<int>(SafeZonePhaseOffset));
|
|
||||||
LOG_INFO(LogZone, "OverridePhaseMaybeIDFK: {}", OverridePhaseMaybeIDFK);
|
|
||||||
LOG_INFO(LogZone, "TimeSeconds: {}", UGameplayStatics::GetTimeSeconds(GetWorld()));
|
|
||||||
|
|
||||||
if (Globals::bLateGame.load())
|
|
||||||
{
|
|
||||||
GameModeAthena->Get<int>(GameMode_SafeZonePhaseOffset) = NewLateGameSafeZonePhase;
|
|
||||||
GameState->Get<int>(GameState_SafeZonePhaseOffset) = NewLateGameSafeZonePhase;
|
|
||||||
SetZoneToIndexOriginal(GameModeAthena, OverridePhaseMaybeIDFK);
|
|
||||||
NewLateGameSafeZonePhase++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SetZoneToIndexOriginal(GameModeAthena, OverridePhaseMaybeIDFK);
|
|
||||||
}
|
|
||||||
|
|
||||||
LOG_INFO(LogZone, "SafeZonePhase After: {}", GameModeAthena->Get<int>(SafeZonePhaseOffset));
|
|
||||||
|
|
||||||
float ZoneHoldDuration = 0;
|
|
||||||
|
|
||||||
if (GameModeAthena->Get<int>(SafeZonePhaseOffset) >= 0 && GameModeAthena->Get<int>(SafeZonePhaseOffset) < ZoneHoldDurations.Num())
|
|
||||||
ZoneHoldDuration = ZoneHoldDurations.at(GameModeAthena->Get<int>(SafeZonePhaseOffset));
|
|
||||||
|
|
||||||
SafeZoneIndicator->Get<float>(SafeZoneStartShrinkTimeOffset) = GameState->GetServerWorldTimeSeconds() + ZoneHoldDuration;
|
|
||||||
|
|
||||||
float ZoneDuration = 0;
|
|
||||||
|
|
||||||
if (GameModeAthena->Get<int>(SafeZonePhaseOffset) >= 0 && GameModeAthena->Get<int>(SafeZonePhaseOffset) < ZoneDurations.Num())
|
|
||||||
ZoneDuration = ZoneDurations.at(GameModeAthena->Get<int>(SafeZonePhaseOffset));
|
|
||||||
|
|
||||||
LOG_INFO(LogZone, "ZoneDuration: {}", ZoneDuration);
|
|
||||||
LOG_INFO(LogZone, "Duration: {}", SafeZoneIndicator->Get<float>(RadiusOffset));
|
|
||||||
|
|
||||||
SafeZoneIndicator->Get<float>(SafeZoneFinishShrinkTimeOffset) = SafeZoneIndicator->Get<float>(SafeZoneStartShrinkTimeOffset) + ZoneDuration;
|
|
||||||
|
|
||||||
if (NewLateGameSafeZonePhase == 3 || NewLateGameSafeZonePhase == 4)
|
|
||||||
{
|
|
||||||
if (SafeZoneIndicator)
|
|
||||||
SafeZoneIndicator->SkipShrinkSafeZone();
|
|
||||||
else
|
|
||||||
LOG_WARN(LogZone, "Invalid SafeZoneIndicator!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void ProcessEventHook(UObject* Object, UFunction* Function, void* Parameters)
|
static inline void ProcessEventHook(UObject* Object, UFunction* Function, void* Parameters)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -374,7 +374,6 @@ DWORD WINAPI Main(LPVOID)
|
|||||||
Offsets::Print();
|
Offsets::Print();
|
||||||
|
|
||||||
Addresses::FindAll();
|
Addresses::FindAll();
|
||||||
// Addresses::Print();
|
|
||||||
Addresses::Init();
|
Addresses::Init();
|
||||||
Addresses::Print();
|
Addresses::Print();
|
||||||
|
|
||||||
@@ -387,7 +386,13 @@ DWORD WINAPI Main(LPVOID)
|
|||||||
#ifdef ABOVE_S20
|
#ifdef ABOVE_S20
|
||||||
if (Fortnite_Version < 20)
|
if (Fortnite_Version < 20)
|
||||||
{
|
{
|
||||||
MessageBoxA(0, "Please undefined ABOVE_S20", "Project Reboot 3.0", MB_ICONERROR);
|
MessageBoxA(0, "Please undefine ABOVE_S20", "Project Reboot 3.0", MB_ICONERROR);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if (Fortnite_Version > 20)
|
||||||
|
{
|
||||||
|
MessageBoxA(0, "Please define ABOVE_S20", "Project Reboot 3.0", MB_ICONERROR);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -457,9 +462,6 @@ DWORD WINAPI Main(LPVOID)
|
|||||||
|
|
||||||
Hooking::MinHook::Hook((PVOID)Addresses::ActorGetNetMode, (PVOID)GetNetModeHook2, nullptr);
|
Hooking::MinHook::Hook((PVOID)Addresses::ActorGetNetMode, (PVOID)GetNetModeHook2, nullptr);
|
||||||
|
|
||||||
// LOG_INFO(LogDev, "FindGIsServer: 0x{:x}", FindGIsServer() - __int64(GetModuleHandleW(0)));
|
|
||||||
// LOG_INFO(LogDev, "FindGIsClient: 0x{:x}", FindGIsClient() - __int64(GetModuleHandleW(0)));
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
Hooking::MinHook::Hook(FindObject<ABuildingFoundation>(L"/Script/FortniteGame.Default__BuildingFoundation"),
|
Hooking::MinHook::Hook(FindObject<ABuildingFoundation>(L"/Script/FortniteGame.Default__BuildingFoundation"),
|
||||||
@@ -587,11 +589,12 @@ DWORD WINAPI Main(LPVOID)
|
|||||||
{
|
{
|
||||||
auto matchmaking = Memcury::Scanner::FindPattern("83 BD ? ? ? ? 01 7F 18 49 8D 4D D8 48 8B D6 E8 ? ? ? ? 48", false).Get();
|
auto matchmaking = Memcury::Scanner::FindPattern("83 BD ? ? ? ? 01 7F 18 49 8D 4D D8 48 8B D6 E8 ? ? ? ? 48", false).Get();
|
||||||
|
|
||||||
matchmaking = matchmaking ? matchmaking : Memcury::Scanner::FindPattern("83 7D 88 01 7F 0D 48 8B CE E8", false).Get();
|
if (!matchmaking)
|
||||||
|
matchmaking = Memcury::Scanner::FindPattern("83 7D 88 01 7F 0D 48 8B CE E8", false).Get();
|
||||||
|
// if (!matchmaking)
|
||||||
|
// matchmaking = Memcury::Scanner::FindPattern("83 BD ? ? ? ? ? 7F 18 49 8D 4D D8 48 8B D7 E8").Get(); // 4.20
|
||||||
|
|
||||||
bool bMatchmakingSupported = false;
|
bool bMatchmakingSupported = matchmaking && Engine_Version >= 420;
|
||||||
|
|
||||||
bMatchmakingSupported = matchmaking && Engine_Version >= 420;
|
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
|
|
||||||
if (bMatchmakingSupported) // now check if it leads to the right place and where the jg is at
|
if (bMatchmakingSupported) // now check if it leads to the right place and where the jg is at
|
||||||
@@ -605,7 +608,7 @@ DWORD WINAPI Main(LPVOID)
|
|||||||
|
|
||||||
// std::cout << std::format("[{}] 0x{:x}\n", i, (int)*byte);
|
// std::cout << std::format("[{}] 0x{:x}\n", i, (int)*byte);
|
||||||
|
|
||||||
if (*byte == 0x7F)
|
if (*byte == 0x7F) // jump if greater
|
||||||
{
|
{
|
||||||
bMatchmakingSupported = true;
|
bMatchmakingSupported = true;
|
||||||
idx = i;
|
idx = i;
|
||||||
@@ -626,7 +629,7 @@ DWORD WINAPI Main(LPVOID)
|
|||||||
|
|
||||||
std::cout << "before byte: " << (int)*before << '\n';
|
std::cout << "before byte: " << (int)*before << '\n';
|
||||||
|
|
||||||
*before = 0x74;
|
*before = 0x74; // jump if zero
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
#include "Object.h"
|
#include "Object.h"
|
||||||
#include "reboot.h"
|
#include "reboot.h"
|
||||||
#include "GameplayStatics.h"
|
#include "GameplayStatics.h"
|
||||||
#include "FortPlaylist.h"
|
#include "FortPlaylistAthena.h"
|
||||||
|
|
||||||
struct Event
|
struct Event
|
||||||
{
|
{
|
||||||
@@ -450,12 +450,12 @@ static inline std::vector<Event> Events =
|
|||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline UFortPlaylist* GetEventPlaylist()
|
static inline UFortPlaylistAthena* GetEventPlaylist()
|
||||||
{
|
{
|
||||||
for (auto& CurrentEvent : Events)
|
for (auto& CurrentEvent : Events)
|
||||||
{
|
{
|
||||||
if (CurrentEvent.Version == Fortnite_Version)
|
if (CurrentEvent.Version == Fortnite_Version)
|
||||||
return FindObject<UFortPlaylist>(CurrentEvent.PlaylistName, nullptr, ANY_PACKAGE);
|
return FindObject<UFortPlaylistAthena>(CurrentEvent.PlaylistName, nullptr, ANY_PACKAGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|||||||
175
Project Reboot 3.0/extra.cpp
Normal file
175
Project Reboot 3.0/extra.cpp
Normal file
@@ -0,0 +1,175 @@
|
|||||||
|
#include "die.h"
|
||||||
|
|
||||||
|
#include "gui.h"
|
||||||
|
|
||||||
|
void SetZoneToIndexHook(AFortGameModeAthena* GameModeAthena, int OverridePhaseMaybeIDFK)
|
||||||
|
{
|
||||||
|
static auto ZoneDurationsOffset = Fortnite_Version >= 15 && Fortnite_Version < 18 ? 0x258
|
||||||
|
: std::floor(Fortnite_Version) >= 18 ? 0x248
|
||||||
|
: 0x1F8; // S13-S14
|
||||||
|
|
||||||
|
static auto GameMode_SafeZonePhaseOffset = GameModeAthena->GetOffset("SafeZonePhase");
|
||||||
|
auto GameState = Cast<AFortGameStateAthena>(GameModeAthena->GetGameState());
|
||||||
|
|
||||||
|
if (!GameState)
|
||||||
|
return SetZoneToIndexOriginal(GameModeAthena, OverridePhaseMaybeIDFK);
|
||||||
|
|
||||||
|
auto SafeZoneIndicator = GameModeAthena->GetSafeZoneIndicator();
|
||||||
|
|
||||||
|
static auto GameState_SafeZonePhaseOffset = GameState->GetOffset("SafeZonePhase");
|
||||||
|
|
||||||
|
static int NewLateGameSafeZonePhase = 2;
|
||||||
|
|
||||||
|
LOG_INFO(LogDev, "NewLateGameSafeZonePhase: {}", NewLateGameSafeZonePhase);
|
||||||
|
|
||||||
|
static bool bReversing = false;
|
||||||
|
|
||||||
|
if (Fortnite_Version < 13)
|
||||||
|
{
|
||||||
|
if (Globals::bLateGame.load())
|
||||||
|
{
|
||||||
|
GameModeAthena->Get<int>(GameMode_SafeZonePhaseOffset) = NewLateGameSafeZonePhase;
|
||||||
|
GameState->Get<int>(GameState_SafeZonePhaseOffset) = NewLateGameSafeZonePhase;
|
||||||
|
SetZoneToIndexOriginal(GameModeAthena, OverridePhaseMaybeIDFK);
|
||||||
|
|
||||||
|
if (NewLateGameSafeZonePhase == 5)
|
||||||
|
{
|
||||||
|
bReversing = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NewLateGameSafeZonePhase == 2 || NewLateGameSafeZonePhase == 3)
|
||||||
|
{
|
||||||
|
if (SafeZoneIndicator)
|
||||||
|
SafeZoneIndicator->SkipShrinkSafeZone();
|
||||||
|
else
|
||||||
|
LOG_WARN(LogZone, "Invalid SafeZoneIndicator!");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NewLateGameSafeZonePhase >= 7) // This means instead of going to the 8th phase its gonna go down.
|
||||||
|
{
|
||||||
|
bReversing = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bReversing && bEnableReverseZone) NewLateGameSafeZonePhase--;
|
||||||
|
else NewLateGameSafeZonePhase++;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SetZoneToIndexOriginal(GameModeAthena, OverridePhaseMaybeIDFK);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!SafeZoneIndicator)
|
||||||
|
{
|
||||||
|
LOG_WARN(LogZone, "Invalid SafeZoneIndicator!");
|
||||||
|
return SetZoneToIndexOriginal(GameModeAthena, OverridePhaseMaybeIDFK);
|
||||||
|
}
|
||||||
|
|
||||||
|
static auto SafeZoneFinishShrinkTimeOffset = SafeZoneIndicator->GetOffset("SafeZoneFinishShrinkTime");
|
||||||
|
static auto SafeZoneStartShrinkTimeOffset = SafeZoneIndicator->GetOffset("SafeZoneStartShrinkTime");
|
||||||
|
static auto RadiusOffset = SafeZoneIndicator->GetOffset("Radius");
|
||||||
|
|
||||||
|
static auto SafeZonePhaseOffset = GameModeAthena->GetOffset("SafeZonePhase");
|
||||||
|
|
||||||
|
static auto MapInfoOffset = GameState->GetOffset("MapInfo");
|
||||||
|
auto MapInfo = GameState->Get<AActor*>(MapInfoOffset);
|
||||||
|
|
||||||
|
if (!MapInfo)
|
||||||
|
{
|
||||||
|
LOG_WARN(LogZone, "Invalid MapInfo!")
|
||||||
|
return SetZoneToIndexOriginal(GameModeAthena, OverridePhaseMaybeIDFK);
|
||||||
|
}
|
||||||
|
|
||||||
|
static auto SafeZoneDefinitionOffset = MapInfo->GetOffset("SafeZoneDefinition");
|
||||||
|
auto SafeZoneDefinition = MapInfo->GetPtr<__int64>(SafeZoneDefinitionOffset);
|
||||||
|
|
||||||
|
LOG_INFO(LogDev, "SafeZoneDefinitionOffset: 0x{:x}", SafeZoneDefinitionOffset);
|
||||||
|
|
||||||
|
static auto ZoneHoldDurationsOffset = ZoneDurationsOffset - 0x10; // fr
|
||||||
|
|
||||||
|
auto& ZoneDurations = *(TArray<float>*)(__int64(SafeZoneDefinition) + ZoneDurationsOffset);
|
||||||
|
auto& ZoneHoldDurations = *(TArray<float>*)(__int64(SafeZoneDefinition) + ZoneHoldDurationsOffset);
|
||||||
|
|
||||||
|
static bool bFilledDurations = false;
|
||||||
|
|
||||||
|
if (!bFilledDurations)
|
||||||
|
{
|
||||||
|
bFilledDurations = true;
|
||||||
|
|
||||||
|
auto CurrentPlaylist = GameState->GetCurrentPlaylist();
|
||||||
|
UCurveTable* FortGameData = nullptr;
|
||||||
|
|
||||||
|
static auto GameDataOffset = CurrentPlaylist->GetOffset("GameData");
|
||||||
|
FortGameData = CurrentPlaylist ? CurrentPlaylist->Get<TSoftObjectPtr<UCurveTable>>(GameDataOffset).Get() : nullptr;
|
||||||
|
|
||||||
|
if (!FortGameData)
|
||||||
|
FortGameData = FindObject<UCurveTable>(L"/Game/Balance/AthenaGameData.AthenaGameData");
|
||||||
|
|
||||||
|
auto ShrinkTimeFName = UKismetStringLibrary::Conv_StringToName(L"Default.SafeZone.ShrinkTime");
|
||||||
|
auto HoldTimeFName = UKismetStringLibrary::Conv_StringToName(L"Default.SafeZone.WaitTime");
|
||||||
|
|
||||||
|
for (int i = 0; i < ZoneDurations.Num(); i++)
|
||||||
|
{
|
||||||
|
ZoneDurations.at(i) = FortGameData->GetValueOfKey(FortGameData->GetKey(ShrinkTimeFName, i));
|
||||||
|
}
|
||||||
|
for (int i = 0; i < ZoneHoldDurations.Num(); i++)
|
||||||
|
{
|
||||||
|
ZoneHoldDurations.at(i) = FortGameData->GetValueOfKey(FortGameData->GetKey(HoldTimeFName, i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_INFO(LogZone, "SafeZonePhase: {}", GameModeAthena->Get<int>(SafeZonePhaseOffset));
|
||||||
|
LOG_INFO(LogZone, "OverridePhaseMaybeIDFK: {}", OverridePhaseMaybeIDFK);
|
||||||
|
LOG_INFO(LogZone, "TimeSeconds: {}", UGameplayStatics::GetTimeSeconds(GetWorld()));
|
||||||
|
|
||||||
|
if (Globals::bLateGame.load())
|
||||||
|
{
|
||||||
|
GameModeAthena->Get<int>(GameMode_SafeZonePhaseOffset) = NewLateGameSafeZonePhase;
|
||||||
|
GameState->Get<int>(GameState_SafeZonePhaseOffset) = NewLateGameSafeZonePhase;
|
||||||
|
SetZoneToIndexOriginal(GameModeAthena, OverridePhaseMaybeIDFK);
|
||||||
|
|
||||||
|
if (NewLateGameSafeZonePhase == 5)
|
||||||
|
{
|
||||||
|
bReversing = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NewLateGameSafeZonePhase >= 7) // This means instead of going to the 8th phase its gonna go down.
|
||||||
|
{
|
||||||
|
bReversing = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bReversing && bEnableReverseZone) NewLateGameSafeZonePhase--;
|
||||||
|
else NewLateGameSafeZonePhase++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SetZoneToIndexOriginal(GameModeAthena, OverridePhaseMaybeIDFK);
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_INFO(LogZone, "SafeZonePhase After: {}", GameModeAthena->Get<int>(SafeZonePhaseOffset));
|
||||||
|
|
||||||
|
float ZoneHoldDuration = 0;
|
||||||
|
|
||||||
|
if (GameModeAthena->Get<int>(SafeZonePhaseOffset) >= 0 && GameModeAthena->Get<int>(SafeZonePhaseOffset) < ZoneHoldDurations.Num())
|
||||||
|
ZoneHoldDuration = ZoneHoldDurations.at(GameModeAthena->Get<int>(SafeZonePhaseOffset));
|
||||||
|
|
||||||
|
SafeZoneIndicator->Get<float>(SafeZoneStartShrinkTimeOffset) = GameState->GetServerWorldTimeSeconds() + ZoneHoldDuration;
|
||||||
|
|
||||||
|
float ZoneDuration = 0;
|
||||||
|
|
||||||
|
if (GameModeAthena->Get<int>(SafeZonePhaseOffset) >= 0 && GameModeAthena->Get<int>(SafeZonePhaseOffset) < ZoneDurations.Num())
|
||||||
|
ZoneDuration = ZoneDurations.at(GameModeAthena->Get<int>(SafeZonePhaseOffset));
|
||||||
|
|
||||||
|
LOG_INFO(LogZone, "ZoneDuration: {}", ZoneDuration);
|
||||||
|
LOG_INFO(LogZone, "Duration: {}", SafeZoneIndicator->Get<float>(RadiusOffset));
|
||||||
|
|
||||||
|
SafeZoneIndicator->Get<float>(SafeZoneFinishShrinkTimeOffset) = SafeZoneIndicator->Get<float>(SafeZoneStartShrinkTimeOffset) + ZoneDuration;
|
||||||
|
|
||||||
|
if (NewLateGameSafeZonePhase == 3 || NewLateGameSafeZonePhase == 4)
|
||||||
|
{
|
||||||
|
if (SafeZoneIndicator)
|
||||||
|
SafeZoneIndicator->SkipShrinkSafeZone();
|
||||||
|
else
|
||||||
|
LOG_WARN(LogZone, "Invalid SafeZoneIndicator!");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -867,6 +867,8 @@ static inline uint64 FindSetZoneToIndex() // actually StartNewSafeZonePhase
|
|||||||
return Memcury::Scanner::FindPattern("E8 ? ? ? ? EB 31 80 B9 ? ? ? ? ?").RelativeOffset(1).Get(); // 3.5
|
return Memcury::Scanner::FindPattern("E8 ? ? ? ? EB 31 80 B9 ? ? ? ? ?").RelativeOffset(1).Get(); // 3.5
|
||||||
if (Engine_Version == 422)
|
if (Engine_Version == 422)
|
||||||
return Memcury::Scanner::FindPattern("E9 ? ? ? ? 48 8B C1 40 38 B9").RelativeOffset(1).Get(); // 7.40
|
return Memcury::Scanner::FindPattern("E9 ? ? ? ? 48 8B C1 40 38 B9").RelativeOffset(1).Get(); // 7.40
|
||||||
|
if (Engine_Version == 423)
|
||||||
|
return Memcury::Scanner::FindPattern("89 54 24 10 48 89 4C 24 ? 53 56 57 41 56 41 57 48 81 EC ? ? ? ? 4C 8B B9").Get(); // 8.51
|
||||||
|
|
||||||
auto Addr = Memcury::Scanner::FindStringRef(L"FortGameModeAthena: No MegaStorm on SafeZone[%d]. GridCellThickness is less than 1.0.", true, 0, Engine_Version >= 427).Get();
|
auto Addr = Memcury::Scanner::FindStringRef(L"FortGameModeAthena: No MegaStorm on SafeZone[%d]. GridCellThickness is less than 1.0.", true, 0, Engine_Version >= 427).Get();
|
||||||
// return FindBytes(Addr, { 0x40, 0x55 }, 30000, 0, true);
|
// return FindBytes(Addr, { 0x40, 0x55 }, 30000, 0, true);
|
||||||
|
|||||||
@@ -63,6 +63,7 @@
|
|||||||
#define LOADOUT_PLAYERTAB 4
|
#define LOADOUT_PLAYERTAB 4
|
||||||
#define FUN_PLAYERTAB 5
|
#define FUN_PLAYERTAB 5
|
||||||
|
|
||||||
|
extern inline bool bEnableReverseZone = false;
|
||||||
extern inline int AmountOfPlayersWhenBusStart = 0;
|
extern inline int AmountOfPlayersWhenBusStart = 0;
|
||||||
extern inline bool bHandleDeath = true;
|
extern inline bool bHandleDeath = true;
|
||||||
extern inline bool bUseCustomMap = false;
|
extern inline bool bUseCustomMap = false;
|
||||||
@@ -700,23 +701,6 @@ static inline void MainUI()
|
|||||||
UKismetSystemLibrary::ExecuteConsoleCommand(GetWorld(), cmd, nullptr);
|
UKismetSystemLibrary::ExecuteConsoleCommand(GetWorld(), cmd, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto GameState = Cast<AFortGameStateAthena>(GetWorld()->GetGameState());
|
|
||||||
|
|
||||||
if (GameState)
|
|
||||||
{
|
|
||||||
static auto DefaultGliderRedeployCanRedeployOffset = FindOffsetStruct("/Script/FortniteGame.FortGameStateAthena", "DefaultGliderRedeployCanRedeploy", false);
|
|
||||||
|
|
||||||
if (DefaultGliderRedeployCanRedeployOffset != -1)
|
|
||||||
{
|
|
||||||
bool EnableGliderRedeploy = (bool)GameState->Get<float>(DefaultGliderRedeployCanRedeployOffset);
|
|
||||||
|
|
||||||
if (ImGui::Checkbox("Enable Glider Redeploy", &EnableGliderRedeploy))
|
|
||||||
{
|
|
||||||
GameState->Get<float>(DefaultGliderRedeployCanRedeployOffset) = EnableGliderRedeploy;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* if (ImGui::Button("Spawn BGAs"))
|
/* if (ImGui::Button("Spawn BGAs"))
|
||||||
{
|
{
|
||||||
SpawnBGAs();
|
SpawnBGAs();
|
||||||
@@ -1119,10 +1103,45 @@ static inline void MainUI()
|
|||||||
LOG_WARN(LogUI, "Invalid Item Definition!");
|
LOG_WARN(LogUI, "Invalid Item Definition!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto GameState = Cast<AFortGameStateAthena>(GetWorld()->GetGameState());
|
||||||
|
|
||||||
|
if (GameState)
|
||||||
|
{
|
||||||
|
static auto DefaultGliderRedeployCanRedeployOffset = FindOffsetStruct("/Script/FortniteGame.FortGameStateAthena", "DefaultGliderRedeployCanRedeploy", false);
|
||||||
|
static auto DefaultParachuteDeployTraceForGroundDistanceOffset = GameState->GetOffset("DefaultParachuteDeployTraceForGroundDistance", false);
|
||||||
|
|
||||||
|
if (DefaultParachuteDeployTraceForGroundDistanceOffset != -1)
|
||||||
|
{
|
||||||
|
ImGui::InputFloat("Automatic Parachute Pullout Distance", GameState->GetPtr<float>(DefaultParachuteDeployTraceForGroundDistanceOffset));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DefaultGliderRedeployCanRedeployOffset != -1)
|
||||||
|
{
|
||||||
|
bool EnableGliderRedeploy = (bool)GameState->Get<float>(DefaultGliderRedeployCanRedeployOffset);
|
||||||
|
|
||||||
|
if (ImGui::Checkbox("Enable Glider Redeploy", &EnableGliderRedeploy))
|
||||||
|
{
|
||||||
|
GameState->Get<float>(DefaultGliderRedeployCanRedeployOffset) = EnableGliderRedeploy;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GET_PLAYLIST(GameState);
|
||||||
|
|
||||||
|
if (CurrentPlaylist)
|
||||||
|
{
|
||||||
|
bool bRespawning = CurrentPlaylist->GetRespawnType() == EAthenaRespawnType::InfiniteRespawn || CurrentPlaylist->GetRespawnType() == EAthenaRespawnType::InfiniteRespawnExceptStorm;
|
||||||
|
|
||||||
|
if (ImGui::Checkbox("Respawning", &bRespawning))
|
||||||
|
{
|
||||||
|
CurrentPlaylist->GetRespawnType() = (EAthenaRespawnType)bRespawning;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (Tab == LATEGAME_TAB)
|
else if (Tab == LATEGAME_TAB)
|
||||||
{
|
{
|
||||||
|
ImGui::Checkbox("Enable Reverse Zone (EXPERIMENTAL)", &bEnableReverseZone);
|
||||||
}
|
}
|
||||||
else if (Tab == DEVELOPER_TAB)
|
else if (Tab == DEVELOPER_TAB)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
#include "json.hpp"
|
#include "json.hpp"
|
||||||
|
|
||||||
bool IsBanned(APlayerController* PlayerController)
|
inline bool IsBanned(APlayerController* PlayerController)
|
||||||
{
|
{
|
||||||
std::ifstream input_file(("banned-ips.json"));
|
std::ifstream input_file(("banned-ips.json"));
|
||||||
std::string line;
|
std::string line;
|
||||||
@@ -33,13 +33,13 @@ bool IsBanned(APlayerController* PlayerController)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GetFilePath()
|
inline std::string GetFilePath()
|
||||||
{
|
{
|
||||||
std::string str = "banned-ips.json";
|
std::string str = "banned-ips.json";
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Ban(APlayerController* PlayerController, const std::string& Name = "")
|
inline void Ban(APlayerController* PlayerController, const std::string& Name = "")
|
||||||
{
|
{
|
||||||
std::ofstream stream(("banned-ips.json"), std::ios::app);
|
std::ofstream stream(("banned-ips.json"), std::ios::app);
|
||||||
|
|
||||||
@@ -62,7 +62,7 @@ void Ban(APlayerController* PlayerController, const std::string& Name = "")
|
|||||||
// KickPlayer(PlayerController, L"You have been banned!");
|
// KickPlayer(PlayerController, L"You have been banned!");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Unban(APlayerController* PlayerController)
|
inline void Unban(APlayerController* PlayerController)
|
||||||
{
|
{
|
||||||
std::ifstream input_file(("banned-ips.json"));
|
std::ifstream input_file(("banned-ips.json"));
|
||||||
|
|
||||||
@@ -101,7 +101,7 @@ void Unban(APlayerController* PlayerController)
|
|||||||
// return ipToRemove != 1;
|
// return ipToRemove != 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Op(APlayerController* PlayerController)
|
inline void Op(APlayerController* PlayerController)
|
||||||
{
|
{
|
||||||
std::ofstream stream(("op-ips.json"), std::ios::app);
|
std::ofstream stream(("op-ips.json"), std::ios::app);
|
||||||
|
|
||||||
@@ -123,7 +123,7 @@ void Op(APlayerController* PlayerController)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Deop(APlayerController* PlayerController)
|
inline void Deop(APlayerController* PlayerController)
|
||||||
{
|
{
|
||||||
std::ifstream input_file(("op-ips.json"));
|
std::ifstream input_file(("op-ips.json"));
|
||||||
|
|
||||||
@@ -163,7 +163,7 @@ void Deop(APlayerController* PlayerController)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool IsOp(APlayerController* PlayerController)
|
inline bool IsOp(APlayerController* PlayerController)
|
||||||
{
|
{
|
||||||
std::ifstream input_file(("op-ips.json"));
|
std::ifstream input_file(("op-ips.json"));
|
||||||
std::string line;
|
std::string line;
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ void ObjectViewer::DumpContentsToFile(UObject* Object, const std::string& FileNa
|
|||||||
auto PropertyClass = *(UClass**)(__int64(Property) + Offsets::PropertyClass);
|
auto PropertyClass = *(UClass**)(__int64(Property) + Offsets::PropertyClass);
|
||||||
|
|
||||||
if (PropertyClass->IsValidLowLevel())
|
if (PropertyClass->IsValidLowLevel())
|
||||||
log(std::format("{} Object: {}\n", PropertyName, PropertyClass->GetPathName()));
|
log(std::format("{} Object: {}\n", PropertyName, PropertyClass->GetFullName()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
Reference in New Issue
Block a user