From 0ca1350d92308fecc31c1b4e6eb6cbd7d882c041 Mon Sep 17 00:00:00 2001 From: Milxnor Date: Fri, 23 Jun 2023 15:00:53 -0400 Subject: [PATCH] respawn toggle toggling respawn, auto parachute height changer changer, fixed issue with characterparts, fixed lategame on s8, added cheat commands --- .../AbilitySystemComponent_Abilities.cpp | 6 + Project Reboot 3.0/FortAthenaMapInfo.h | 2 +- Project Reboot 3.0/FortGameModeAthena.cpp | 11 +- Project Reboot 3.0/FortGameStateAthena.cpp | 6 +- Project Reboot 3.0/FortGameStateAthena.h | 4 +- Project Reboot 3.0/FortPlayerController.cpp | 10 + Project Reboot 3.0/FortPlaylistAthena.h | 27 + Project Reboot 3.0/Project Reboot 3.0.vcxproj | 3 + .../Project Reboot 3.0.vcxproj.filters | 9 + Project Reboot 3.0/commands.cpp | 952 ++++++++++++++++++ Project Reboot 3.0/commands.h | 859 +--------------- Project Reboot 3.0/die.h | 146 +-- Project Reboot 3.0/dllmain.cpp | 25 +- Project Reboot 3.0/events.h | 6 +- Project Reboot 3.0/extra.cpp | 175 ++++ Project Reboot 3.0/finder.h | 2 + Project Reboot 3.0/gui.h | 55 +- Project Reboot 3.0/moderation.h | 14 +- Project Reboot 3.0/objectviewer.cpp | 2 +- 19 files changed, 1264 insertions(+), 1050 deletions(-) create mode 100644 Project Reboot 3.0/FortPlaylistAthena.h create mode 100644 Project Reboot 3.0/commands.cpp create mode 100644 Project Reboot 3.0/extra.cpp diff --git a/Project Reboot 3.0/AbilitySystemComponent_Abilities.cpp b/Project Reboot 3.0/AbilitySystemComponent_Abilities.cpp index 8c0b630..f7d1442 100644 --- a/Project Reboot 3.0/AbilitySystemComponent_Abilities.cpp +++ b/Project Reboot 3.0/AbilitySystemComponent_Abilities.cpp @@ -197,6 +197,12 @@ void UAbilitySystemComponent::InternalServerTryActivateAbilityHook(UAbilitySyste 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!"); auto DefaultAbility = AbilityClass->CreateDefaultObject(); diff --git a/Project Reboot 3.0/FortAthenaMapInfo.h b/Project Reboot 3.0/FortAthenaMapInfo.h index 81fc72c..10b8773 100644 --- a/Project Reboot 3.0/FortAthenaMapInfo.h +++ b/Project Reboot 3.0/FortAthenaMapInfo.h @@ -55,7 +55,7 @@ struct FVehicleClassDetails { static UStruct* GetStruct() { - static auto Struct = FindObject("/Script/FortniteGame.VehicleClassDetails"); + static auto Struct = FindObject(L"/Script/FortniteGame.VehicleClassDetails"); return Struct; } diff --git a/Project Reboot 3.0/FortGameModeAthena.cpp b/Project Reboot 3.0/FortGameModeAthena.cpp index e3ed7cf..404c9e3 100644 --- a/Project Reboot 3.0/FortGameModeAthena.cpp +++ b/Project Reboot 3.0/FortGameModeAthena.cpp @@ -24,6 +24,7 @@ #include "vehicles.h" #include "globals.h" #include "events.h" +#include "FortPlaylistAthena.h" #include "reboot.h" #include "ai.h" #include "Map.h" @@ -35,11 +36,11 @@ #include "gui.h" #include -static UFortPlaylist* GetPlaylistToUse() +static UFortPlaylistAthena* GetPlaylistToUse() { // LOG_DEBUG(LogDev, "PlaylistName: {}", PlaylistName); - auto Playlist = FindObject(PlaylistName); + auto Playlist = FindObject(PlaylistName); if (Globals::bGoingToPlayEvent) { @@ -62,7 +63,7 @@ static UFortPlaylist* GetPlaylistToUse() // SET OVERRIDE PLAYLIST DOWN HERE if (Globals::bCreative) - Playlist = FindObject(L"/Game/Athena/Playlists/Creative/Playlist_PlaygroundV2.Playlist_PlaygroundV2"); + Playlist = FindObject(L"/Game/Athena/Playlists/Creative/Playlist_PlaygroundV2.Playlist_PlaygroundV2"); return Playlist; } @@ -922,6 +923,10 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game int AFortGameModeAthena::Athena_PickTeamHook(AFortGameModeAthena* GameMode, uint8 preferredTeam, AActor* Controller) { +#if 0 + static int bruh = 3; + return bruh++; +#endif bool bIsBot = false; auto PlayerState = ((APlayerController*)Controller)->GetPlayerState(); diff --git a/Project Reboot 3.0/FortGameStateAthena.cpp b/Project Reboot 3.0/FortGameStateAthena.cpp index 7fab3eb..be75c24 100644 --- a/Project Reboot 3.0/FortGameStateAthena.cpp +++ b/Project Reboot 3.0/FortGameStateAthena.cpp @@ -152,20 +152,20 @@ TScriptInterface AFortGameStateAthena::GetSafeZoneInterf return ScriptInterface; } -UFortPlaylist*& AFortGameStateAthena::GetCurrentPlaylist() +UFortPlaylistAthena*& AFortGameStateAthena::GetCurrentPlaylist() { static auto CurrentPlaylistInfoOffset = GetOffset("CurrentPlaylistInfo", false); if (CurrentPlaylistInfoOffset == -1) { static auto CurrentPlaylistDataOffset = GetOffset("CurrentPlaylistData"); - return Get(CurrentPlaylistDataOffset); + return (Get(CurrentPlaylistDataOffset)); } auto CurrentPlaylistInfo = this->GetPtr(CurrentPlaylistInfoOffset); static auto BasePlaylistOffset = FindOffsetStruct("/Script/FortniteGame.PlaylistPropertyArray", "BasePlaylist"); - return *(UFortPlaylist**)(__int64(CurrentPlaylistInfo) + BasePlaylistOffset); + return (*(UFortPlaylistAthena**)(__int64(CurrentPlaylistInfo) + BasePlaylistOffset)); } int AFortGameStateAthena::GetAircraftIndex(AFortPlayerState* PlayerState) diff --git a/Project Reboot 3.0/FortGameStateAthena.h b/Project Reboot 3.0/FortGameStateAthena.h index d3f2e5a..4915ab1 100644 --- a/Project Reboot 3.0/FortGameStateAthena.h +++ b/Project Reboot 3.0/FortGameStateAthena.h @@ -2,7 +2,7 @@ #include "GameState.h" #include "FortPlayerStateAthena.h" -#include "FortPlaylist.h" +#include "FortPlaylistAthena.h" #include "BuildingStructuralSupportSystem.h" #include "ScriptInterface.h" #include "Interface.h" @@ -149,7 +149,7 @@ public: return Get(GamePhaseStepOffset); } - UFortPlaylist*& GetCurrentPlaylist(); + UFortPlaylistAthena*& GetCurrentPlaylist(); TScriptInterface GetSafeZoneInterface(); void AddPlayerStateToGameMemberInfo(class AFortPlayerStateAthena* PlayerState); diff --git a/Project Reboot 3.0/FortPlayerController.cpp b/Project Reboot 3.0/FortPlayerController.cpp index 35f8ce2..c521089 100644 --- a/Project Reboot 3.0/FortPlayerController.cpp +++ b/Project Reboot 3.0/FortPlayerController.cpp @@ -699,6 +699,7 @@ void AFortPlayerController::ServerAttemptAircraftJumpHook(AFortPlayerController* { static auto StormEffectClass = FindObject(L"/Game/Athena/SafeZone/GE_OutsideSafeZoneDamage.GE_OutsideSafeZoneDamage_C"); auto PlayerState = PlayerController->GetPlayerStateAthena(); + PlayerState->GetAbilitySystemComponent()->RemoveActiveGameplayEffectBySourceEffect(StormEffectClass, 1, PlayerState->GetAbilitySystemComponent()); } @@ -1324,6 +1325,10 @@ void AFortPlayerController::ClientOnPawnDiedHook(AFortPlayerController* PlayerCo int MaxHealth = 100; int MaxShield = 100; int AmountGiven = 0; + /* + int ShieldGiven = 0; + int HealthGiven = 0; + */ if ((MaxHealth - Health) > 0) { @@ -1343,6 +1348,11 @@ void AFortPlayerController::ClientOnPawnDiedHook(AFortPlayerController* PlayerCo AmountGiven += AmountToGive; } } + + if (AmountGiven > 0) + { + + } } } } diff --git a/Project Reboot 3.0/FortPlaylistAthena.h b/Project Reboot 3.0/FortPlaylistAthena.h new file mode 100644 index 0000000..994d957 --- /dev/null +++ b/Project Reboot 3.0/FortPlaylistAthena.h @@ -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(RespawnTypeOffset); + } + + static UClass* StaticClass() + { + static auto Class = FindObject(L"/Script/FortniteGame.FortPlaylistAthena"); + return Class; + } +}; \ No newline at end of file diff --git a/Project Reboot 3.0/Project Reboot 3.0.vcxproj b/Project Reboot 3.0/Project Reboot 3.0.vcxproj index 608a689..422c1cb 100644 --- a/Project Reboot 3.0/Project Reboot 3.0.vcxproj +++ b/Project Reboot 3.0/Project Reboot 3.0.vcxproj @@ -189,9 +189,11 @@ + + @@ -376,6 +378,7 @@ + diff --git a/Project Reboot 3.0/Project Reboot 3.0.vcxproj.filters b/Project Reboot 3.0/Project Reboot 3.0.vcxproj.filters index 5f83562..62285ea 100644 --- a/Project Reboot 3.0/Project Reboot 3.0.vcxproj.filters +++ b/Project Reboot 3.0/Project Reboot 3.0.vcxproj.filters @@ -298,6 +298,12 @@ Reboot\Private + + Reboot\Private + + + Reboot\Private + @@ -951,6 +957,9 @@ FortniteGame\Source\FortniteGame\Public\Stats + + FortniteGame\Source\FortniteGame\Public + diff --git a/Project Reboot 3.0/commands.cpp b/Project Reboot 3.0/commands.cpp new file mode 100644 index 0000000..89f6fed --- /dev/null +++ b/Project Reboot 3.0/commands.cpp @@ -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(PlayerController->GetPlayerState()); + + // std::cout << "aa!\n"; + + if (!PlayerState || !IsOperator(PlayerState, PlayerController)) + return; + + std::vector 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(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(ClientConnections.at(i)->Get(PlayerControllerOffset)); + + if (!CurrentPlayerController) + continue; + + auto CurrentPlayerState = Cast(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(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(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(WeaponDefinitionOffset); + } + else + { + NewPickaxeItemDefinition = Cast(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(FindObject(weaponName, nullptr, ANY_PACKAGE)); + + if (!WID) + { + SendMessageToConsole(PlayerController, L"Invalid WID!"); + return; + } + + auto Location = Pawn->GetActorLocation(); + + auto GameState = Cast(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(ClientConnections.at(i)->Get(PlayerControllerOffset)); + + if (!CurrentPlayerController) + continue; + + auto CurrentPlayerState = Cast(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(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(ReceivingController->GetPlayerState()); + + if (!PlayerState) // ??? + { + SendMessageToConsole(PlayerController, L"No playerstate!"); + return; + } + + auto Pawn = Cast(ReceivingController->GetMyFortPawn()); + + std::string CIDStr = Arguments[1]; + auto CIDDef = FindObject(CIDStr, nullptr, ANY_PACKAGE); + // auto CIDDef = UObject::FindObject(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("/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(L"/Script/Engine.BlueprintGeneratedClass"); + static auto ClassClass = FindObject(L"/Script/CoreUObject.Class"); + auto ClassObj = ClassName.contains("/Script/") ? FindObject(ClassName, ClassClass) : LoadObject(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(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(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(GetWorld()->GetGameState()); + auto GameMode = Cast(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(L"/Script/FortniteGame.FortEditToolItemDefinition"); + static auto FortBuildingItemDefinitionClass = FindObject(L"/Script/FortniteGame.FortBuildingItemDefinition"); + + std::vector> 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(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(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 - Gives a weapon to the executing player, if inventory is full drops a pickup on the player. +cheat summon - Summons the specified blueprint class at the executing player's location. Note: There is a limit on the count. +cheat bugitgo - Teleport to a location. +cheat launch - Launches a player. +cheat listplayers - Gives you all players names. +cheat pausesafezone - Pauses the zone. +cheat sethealth - Sets executing player's health. +cheat setshield - Sets executing player's shield. +cheat applycid - Sets a player's character. +cheat spawnpickup - Spawns a pickup at specified player. +cheat teleport/tp - Teleports to what the player is looking at. +cheat spawnbot - Spawns a bot at the player (experimental). +cheat setpickaxe - Set player's pickaxe. Can be either the PID or WID +cheat destroytarget - Destroys the actor that the player is looking at. +cheat wipequickbar - Wipes the specified quickbar (parameters is not case sensitive). +cheat wipequickbars - 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); + } +} \ No newline at end of file diff --git a/Project Reboot 3.0/commands.h b/Project Reboot 3.0/commands.h index 3b0663e..936166b 100644 --- a/Project Reboot 3.0/commands.h +++ b/Project Reboot 3.0/commands.h @@ -13,7 +13,7 @@ #include "ai.h" #include "moderation.h" -bool IsOperator(APlayerState* PlayerState, AFortPlayerController* PlayerController) +inline bool IsOperator(APlayerState* PlayerState, AFortPlayerController* PlayerController) { auto& IP = PlayerState->GetSavedNetworkAddress(); auto IPStr = IP.ToString(); @@ -34,7 +34,7 @@ inline void SendMessageToConsole(AFortPlayerController* PlayerController, const FName TypeName = FName(); // auto set to "Event" static auto ClientMessageFn = FindObject(L"/Script/Engine.PlayerController.ClientMessage"); - struct + struct { FString S; // (Parm, ZeroConstructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) FName Type; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) @@ -47,857 +47,4 @@ inline void SendMessageToConsole(AFortPlayerController* PlayerController, const // LOG_INFO(LogDev, "{}", brah); } -void ServerCheatHook(AFortPlayerControllerAthena* PlayerController, FString Msg) -{ - if (!Msg.Data.Data || Msg.Data.Num() <= 0) - return; - - auto PlayerState = Cast(PlayerController->GetPlayerState()); - - // std::cout << "aa!\n"; - - if (!PlayerState || !IsOperator(PlayerState, PlayerController)) - return; - - std::vector 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(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(ClientConnections.at(i)->Get(PlayerControllerOffset)); - - if (!CurrentPlayerController) - continue; - - auto CurrentPlayerState = Cast(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(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("/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(WeaponDefinitionOffset); - } - else - { - NewPickaxeItemDefinition = Cast(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(FindObject(weaponName, nullptr, ANY_PACKAGE)); - - if (!WID) - { - SendMessageToConsole(PlayerController, L"Invalid WID!"); - return; - } - - auto Location = Pawn->GetActorLocation(); - - auto GameState = Cast(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(ClientConnections.at(i)->Get(PlayerControllerOffset)); - - if (!CurrentPlayerController) - continue; - - auto CurrentPlayerState = Cast(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(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(ReceivingController->GetPlayerState()); - - if (!PlayerState) // ??? - { - SendMessageToConsole(PlayerController, L"No playerstate!"); - return; - } - - auto Pawn = Cast(ReceivingController->GetMyFortPawn()); - - std::string CIDStr = Arguments[1]; - auto CIDDef = FindObject(CIDStr, nullptr, ANY_PACKAGE); - // auto CIDDef = UObject::FindObject(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(L"/Script/Engine.BlueprintGeneratedClass"); - static auto ClassClass = FindObject(L"/Script/CoreUObject.Class"); - auto ClassObj = ClassName.contains("/Script/") ? FindObject(ClassName, ClassClass) : LoadObject(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(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(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(GetWorld()->GetGameState()); - auto GameMode = Cast(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(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 - Gives a weapon to the executing player, if inventory is full drops a pickup on the player. -cheat summon - Summons the specified blueprint class at the executing player's location. Note: There is a limit on the count. -cheat bugitgo - Teleport to a location. -cheat launch - Launches a player. -cheat listplayers - Gives you all players names. -cheat pausesafezone - Pauses the zone. -cheat sethealth - Sets executing player's health. -cheat setshield - Sets executing player's shield. -cheat applycid - Sets a player's character. -cheat spawnpickup - Spawns a pickup at specified player. -cheat teleport - Teleports to what the player is looking at. -cheat spawnbot - Spawns a bot at the player (experimental). -cheat setpickaxe - 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); - } -} \ No newline at end of file +void ServerCheatHook(AFortPlayerControllerAthena* PlayerController, FString Msg); \ No newline at end of file diff --git a/Project Reboot 3.0/die.h b/Project Reboot 3.0/die.h index d7a3bb3..570dd33 100644 --- a/Project Reboot 3.0/die.h +++ b/Project Reboot 3.0/die.h @@ -10,151 +10,7 @@ static inline void (*SetZoneToIndexOriginal)(AFortGameModeAthena* GameModeAthena, int OverridePhaseMaybeIDFK); -static inline 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(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(GameMode_SafeZonePhaseOffset) = NewLateGameSafeZonePhase; - GameState->Get(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(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*)(__int64(SafeZoneDefinition) + ZoneDurationsOffset); - auto& ZoneHoldDurations = *(TArray*)(__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>(GameDataOffset).Get() : nullptr; - - if (!FortGameData) - FortGameData = FindObject(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(SafeZonePhaseOffset)); - LOG_INFO(LogZone, "OverridePhaseMaybeIDFK: {}", OverridePhaseMaybeIDFK); - LOG_INFO(LogZone, "TimeSeconds: {}", UGameplayStatics::GetTimeSeconds(GetWorld())); - - if (Globals::bLateGame.load()) - { - GameModeAthena->Get(GameMode_SafeZonePhaseOffset) = NewLateGameSafeZonePhase; - GameState->Get(GameState_SafeZonePhaseOffset) = NewLateGameSafeZonePhase; - SetZoneToIndexOriginal(GameModeAthena, OverridePhaseMaybeIDFK); - NewLateGameSafeZonePhase++; - } - else - { - SetZoneToIndexOriginal(GameModeAthena, OverridePhaseMaybeIDFK); - } - - LOG_INFO(LogZone, "SafeZonePhase After: {}", GameModeAthena->Get(SafeZonePhaseOffset)); - - float ZoneHoldDuration = 0; - - if (GameModeAthena->Get(SafeZonePhaseOffset) >= 0 && GameModeAthena->Get(SafeZonePhaseOffset) < ZoneHoldDurations.Num()) - ZoneHoldDuration = ZoneHoldDurations.at(GameModeAthena->Get(SafeZonePhaseOffset)); - - SafeZoneIndicator->Get(SafeZoneStartShrinkTimeOffset) = GameState->GetServerWorldTimeSeconds() + ZoneHoldDuration; - - float ZoneDuration = 0; - - if (GameModeAthena->Get(SafeZonePhaseOffset) >= 0 && GameModeAthena->Get(SafeZonePhaseOffset) < ZoneDurations.Num()) - ZoneDuration = ZoneDurations.at(GameModeAthena->Get(SafeZonePhaseOffset)); - - LOG_INFO(LogZone, "ZoneDuration: {}", ZoneDuration); - LOG_INFO(LogZone, "Duration: {}", SafeZoneIndicator->Get(RadiusOffset)); - - SafeZoneIndicator->Get(SafeZoneFinishShrinkTimeOffset) = SafeZoneIndicator->Get(SafeZoneStartShrinkTimeOffset) + ZoneDuration; - - if (NewLateGameSafeZonePhase == 3 || NewLateGameSafeZonePhase == 4) - { - if (SafeZoneIndicator) - SafeZoneIndicator->SkipShrinkSafeZone(); - else - LOG_WARN(LogZone, "Invalid SafeZoneIndicator!"); - } -} +void SetZoneToIndexHook(AFortGameModeAthena* GameModeAthena, int OverridePhaseMaybeIDFK); static inline void ProcessEventHook(UObject* Object, UFunction* Function, void* Parameters) { diff --git a/Project Reboot 3.0/dllmain.cpp b/Project Reboot 3.0/dllmain.cpp index 6104c9f..ab527d9 100644 --- a/Project Reboot 3.0/dllmain.cpp +++ b/Project Reboot 3.0/dllmain.cpp @@ -374,7 +374,6 @@ DWORD WINAPI Main(LPVOID) Offsets::Print(); Addresses::FindAll(); - // Addresses::Print(); Addresses::Init(); Addresses::Print(); @@ -387,7 +386,13 @@ DWORD WINAPI Main(LPVOID) #ifdef ABOVE_S20 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; } #endif @@ -457,9 +462,6 @@ DWORD WINAPI Main(LPVOID) 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(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(); - 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; - - bMatchmakingSupported = matchmaking && Engine_Version >= 420; + bool bMatchmakingSupported = matchmaking && Engine_Version >= 420; int idx = 0; 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); - if (*byte == 0x7F) + if (*byte == 0x7F) // jump if greater { bMatchmakingSupported = true; idx = i; @@ -626,7 +629,7 @@ DWORD WINAPI Main(LPVOID) std::cout << "before byte: " << (int)*before << '\n'; - *before = 0x74; + *before = 0x74; // jump if zero } } diff --git a/Project Reboot 3.0/events.h b/Project Reboot 3.0/events.h index 0e3716e..0068514 100644 --- a/Project Reboot 3.0/events.h +++ b/Project Reboot 3.0/events.h @@ -5,7 +5,7 @@ #include "Object.h" #include "reboot.h" #include "GameplayStatics.h" -#include "FortPlaylist.h" +#include "FortPlaylistAthena.h" struct Event { @@ -450,12 +450,12 @@ static inline std::vector Events = ) }; -static inline UFortPlaylist* GetEventPlaylist() +static inline UFortPlaylistAthena* GetEventPlaylist() { for (auto& CurrentEvent : Events) { if (CurrentEvent.Version == Fortnite_Version) - return FindObject(CurrentEvent.PlaylistName, nullptr, ANY_PACKAGE); + return FindObject(CurrentEvent.PlaylistName, nullptr, ANY_PACKAGE); } return nullptr; diff --git a/Project Reboot 3.0/extra.cpp b/Project Reboot 3.0/extra.cpp new file mode 100644 index 0000000..0f8a52a --- /dev/null +++ b/Project Reboot 3.0/extra.cpp @@ -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(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(GameMode_SafeZonePhaseOffset) = NewLateGameSafeZonePhase; + GameState->Get(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(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*)(__int64(SafeZoneDefinition) + ZoneDurationsOffset); + auto& ZoneHoldDurations = *(TArray*)(__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>(GameDataOffset).Get() : nullptr; + + if (!FortGameData) + FortGameData = FindObject(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(SafeZonePhaseOffset)); + LOG_INFO(LogZone, "OverridePhaseMaybeIDFK: {}", OverridePhaseMaybeIDFK); + LOG_INFO(LogZone, "TimeSeconds: {}", UGameplayStatics::GetTimeSeconds(GetWorld())); + + if (Globals::bLateGame.load()) + { + GameModeAthena->Get(GameMode_SafeZonePhaseOffset) = NewLateGameSafeZonePhase; + GameState->Get(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(SafeZonePhaseOffset)); + + float ZoneHoldDuration = 0; + + if (GameModeAthena->Get(SafeZonePhaseOffset) >= 0 && GameModeAthena->Get(SafeZonePhaseOffset) < ZoneHoldDurations.Num()) + ZoneHoldDuration = ZoneHoldDurations.at(GameModeAthena->Get(SafeZonePhaseOffset)); + + SafeZoneIndicator->Get(SafeZoneStartShrinkTimeOffset) = GameState->GetServerWorldTimeSeconds() + ZoneHoldDuration; + + float ZoneDuration = 0; + + if (GameModeAthena->Get(SafeZonePhaseOffset) >= 0 && GameModeAthena->Get(SafeZonePhaseOffset) < ZoneDurations.Num()) + ZoneDuration = ZoneDurations.at(GameModeAthena->Get(SafeZonePhaseOffset)); + + LOG_INFO(LogZone, "ZoneDuration: {}", ZoneDuration); + LOG_INFO(LogZone, "Duration: {}", SafeZoneIndicator->Get(RadiusOffset)); + + SafeZoneIndicator->Get(SafeZoneFinishShrinkTimeOffset) = SafeZoneIndicator->Get(SafeZoneStartShrinkTimeOffset) + ZoneDuration; + + if (NewLateGameSafeZonePhase == 3 || NewLateGameSafeZonePhase == 4) + { + if (SafeZoneIndicator) + SafeZoneIndicator->SkipShrinkSafeZone(); + else + LOG_WARN(LogZone, "Invalid SafeZoneIndicator!"); + } +} \ No newline at end of file diff --git a/Project Reboot 3.0/finder.h b/Project Reboot 3.0/finder.h index 2b31019..f763a30 100644 --- a/Project Reboot 3.0/finder.h +++ b/Project Reboot 3.0/finder.h @@ -867,6 +867,8 @@ static inline uint64 FindSetZoneToIndex() // actually StartNewSafeZonePhase return Memcury::Scanner::FindPattern("E8 ? ? ? ? EB 31 80 B9 ? ? ? ? ?").RelativeOffset(1).Get(); // 3.5 if (Engine_Version == 422) 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(); // return FindBytes(Addr, { 0x40, 0x55 }, 30000, 0, true); diff --git a/Project Reboot 3.0/gui.h b/Project Reboot 3.0/gui.h index 015c09e..3e741a5 100644 --- a/Project Reboot 3.0/gui.h +++ b/Project Reboot 3.0/gui.h @@ -63,6 +63,7 @@ #define LOADOUT_PLAYERTAB 4 #define FUN_PLAYERTAB 5 +extern inline bool bEnableReverseZone = false; extern inline int AmountOfPlayersWhenBusStart = 0; extern inline bool bHandleDeath = true; extern inline bool bUseCustomMap = false; @@ -700,23 +701,6 @@ static inline void MainUI() UKismetSystemLibrary::ExecuteConsoleCommand(GetWorld(), cmd, nullptr); } - auto GameState = Cast(GetWorld()->GetGameState()); - - if (GameState) - { - static auto DefaultGliderRedeployCanRedeployOffset = FindOffsetStruct("/Script/FortniteGame.FortGameStateAthena", "DefaultGliderRedeployCanRedeploy", false); - - if (DefaultGliderRedeployCanRedeployOffset != -1) - { - bool EnableGliderRedeploy = (bool)GameState->Get(DefaultGliderRedeployCanRedeployOffset); - - if (ImGui::Checkbox("Enable Glider Redeploy", &EnableGliderRedeploy)) - { - GameState->Get(DefaultGliderRedeployCanRedeployOffset) = EnableGliderRedeploy; - } - } - } - /* if (ImGui::Button("Spawn BGAs")) { SpawnBGAs(); @@ -1119,10 +1103,45 @@ static inline void MainUI() LOG_WARN(LogUI, "Invalid Item Definition!"); } } + + auto GameState = Cast(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(DefaultParachuteDeployTraceForGroundDistanceOffset)); + } + + if (DefaultGliderRedeployCanRedeployOffset != -1) + { + bool EnableGliderRedeploy = (bool)GameState->Get(DefaultGliderRedeployCanRedeployOffset); + + if (ImGui::Checkbox("Enable Glider Redeploy", &EnableGliderRedeploy)) + { + GameState->Get(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) { - + ImGui::Checkbox("Enable Reverse Zone (EXPERIMENTAL)", &bEnableReverseZone); } else if (Tab == DEVELOPER_TAB) { diff --git a/Project Reboot 3.0/moderation.h b/Project Reboot 3.0/moderation.h index d643024..94a0eb5 100644 --- a/Project Reboot 3.0/moderation.h +++ b/Project Reboot 3.0/moderation.h @@ -7,7 +7,7 @@ #include "json.hpp" -bool IsBanned(APlayerController* PlayerController) +inline bool IsBanned(APlayerController* PlayerController) { std::ifstream input_file(("banned-ips.json")); std::string line; @@ -33,13 +33,13 @@ bool IsBanned(APlayerController* PlayerController) return false; } -std::string GetFilePath() +inline std::string GetFilePath() { std::string str = "banned-ips.json"; 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); @@ -62,7 +62,7 @@ void Ban(APlayerController* PlayerController, const std::string& Name = "") // KickPlayer(PlayerController, L"You have been banned!"); } -void Unban(APlayerController* PlayerController) +inline void Unban(APlayerController* PlayerController) { std::ifstream input_file(("banned-ips.json")); @@ -101,7 +101,7 @@ void Unban(APlayerController* PlayerController) // return ipToRemove != 1; } -void Op(APlayerController* PlayerController) +inline void Op(APlayerController* PlayerController) { 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")); @@ -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::string line; diff --git a/Project Reboot 3.0/objectviewer.cpp b/Project Reboot 3.0/objectviewer.cpp index 6f5d029..69828c5 100644 --- a/Project Reboot 3.0/objectviewer.cpp +++ b/Project Reboot 3.0/objectviewer.cpp @@ -72,7 +72,7 @@ void ObjectViewer::DumpContentsToFile(UObject* Object, const std::string& FileNa auto PropertyClass = *(UClass**)(__int64(Property) + Offsets::PropertyClass); if (PropertyClass->IsValidLowLevel()) - log(std::format("{} Object: {}\n", PropertyName, PropertyClass->GetPathName())); + log(std::format("{} Object: {}\n", PropertyName, PropertyClass->GetFullName())); } /*