From 1da682211952ed3d76a656bbe7d3636432b4b1ab Mon Sep 17 00:00:00 2001 From: Milxnor Date: Sat, 13 May 2023 19:46:50 -0400 Subject: [PATCH] Reboot Living up to its name almost finish rebooting (im going insane), performance, increase llama spawn radius, remove auto restart for a little bit --- .../AthenaResurrectionComponent.h | 21 +++ .../BuildingGameplayActorSpawnMachine.cpp | 133 ++++++++++++++++++ .../BuildingGameplayActorSpawnMachine.h | 47 +++++++ Project Reboot 3.0/FortAthenaMapInfo.cpp | 3 +- Project Reboot 3.0/FortGameModeAthena.cpp | 115 ++++++++++++--- Project Reboot 3.0/FortGameModeAthena.h | 12 +- .../FortGameSessionDedicatedAthena.cpp | 35 +++++ .../FortGameSessionDedicatedAthena.h | 9 ++ Project Reboot 3.0/FortGameStateAthena.cpp | 21 ++- Project Reboot 3.0/FortGameStateAthena.h | 28 +++- Project Reboot 3.0/FortPlayerController.cpp | 8 +- .../FortPlayerControllerAthena.cpp | 5 +- .../FortPlayerControllerAthena.h | 8 +- Project Reboot 3.0/FortPlayerState.cpp | 6 + Project Reboot 3.0/FortPlayerState.h | 3 + Project Reboot 3.0/FortPlayerStateAthena.h | 45 ++++++ Project Reboot 3.0/GameModeBase.cpp | 50 +++++-- Project Reboot 3.0/GameModeBase.h | 3 + Project Reboot 3.0/OnlineReplStructs.h | 25 ++++ Project Reboot 3.0/Project Reboot 3.0.vcxproj | 5 + .../Project Reboot 3.0.vcxproj.filters | 15 ++ Project Reboot 3.0/addresses.cpp | 18 ++- Project Reboot 3.0/addresses.h | 6 +- Project Reboot 3.0/commands.h | 8 +- Project Reboot 3.0/dllmain.cpp | 23 ++- Project Reboot 3.0/events.h | 14 +- Project Reboot 3.0/finder.h | 59 ++++++++ Project Reboot 3.0/globals.h | 5 +- Project Reboot 3.0/gui.h | 4 +- Project Reboot 3.0/hooking.h | 11 ++ vendor/memcury.h | 3 +- 31 files changed, 684 insertions(+), 64 deletions(-) create mode 100644 Project Reboot 3.0/AthenaResurrectionComponent.h create mode 100644 Project Reboot 3.0/BuildingGameplayActorSpawnMachine.cpp create mode 100644 Project Reboot 3.0/FortGameSessionDedicatedAthena.cpp create mode 100644 Project Reboot 3.0/FortGameSessionDedicatedAthena.h create mode 100644 Project Reboot 3.0/FortPlayerState.cpp diff --git a/Project Reboot 3.0/AthenaResurrectionComponent.h b/Project Reboot 3.0/AthenaResurrectionComponent.h new file mode 100644 index 0000000..93c864a --- /dev/null +++ b/Project Reboot 3.0/AthenaResurrectionComponent.h @@ -0,0 +1,21 @@ +#pragma once + +#include "ActorComponent.h" + +#include "reboot.h" + +class UAthenaResurrectionComponent : public UActorComponent +{ +public: + TWeakObjectPtr& GetResurrectionLocation() + { + static auto ResurrectionLocationOffset = GetOffset("ResurrectionLocation"); + return Get>(ResurrectionLocationOffset); + } + + int& GetClosestSpawnMachineIndex() + { + static auto ClosestSpawnMachineIndexOffset = GetOffset("ClosestSpawnMachineIndex"); + return Get(ClosestSpawnMachineIndexOffset); + } +}; \ No newline at end of file diff --git a/Project Reboot 3.0/BuildingGameplayActorSpawnMachine.cpp b/Project Reboot 3.0/BuildingGameplayActorSpawnMachine.cpp new file mode 100644 index 0000000..021a6e4 --- /dev/null +++ b/Project Reboot 3.0/BuildingGameplayActorSpawnMachine.cpp @@ -0,0 +1,133 @@ +#include "BuildingGameplayActorSpawnMachine.h" + +#include "FortPlayerControllerAthena.h" +#include "GameplayStatics.h" +#include "AthenaResurrectionComponent.h" +#include "FortGameStateAthena.h" +#include "FortGameModeAthena.h" + +void ABuildingGameplayActorSpawnMachine::FinishResurrection(int SquadId) +{ + static void (*FinishResurrectionOriginal)(ABuildingGameplayActorSpawnMachine* SpawnMachine, int SquadId) = decltype(FinishResurrectionOriginal)(Addresses::FinishResurrection); + + if (FinishResurrectionOriginal) + { + FinishResurrectionOriginal(this, SquadId); + } + else + { + + } +} + +void ABuildingGameplayActorSpawnMachine::RebootingDelegateHook(ABuildingGameplayActorSpawnMachine* SpawnMachine) +{ + auto GameMode = Cast(GetWorld()->GetGameMode()); + + LOG_INFO(LogDev, "RebootingDelegateHook!"); + + if (!SpawnMachine->GetResurrectLocation()) + return; + + LOG_INFO(LogDev, "PlayerIdsForResurrection.Num(): {}", SpawnMachine->GetPlayerIdsForResurrection().Num()); + + if (SpawnMachine->GetPlayerIdsForResurrection().Num() <= 0) + return; + + auto GameState = Cast(GetWorld()->GetGameState()); + + AFortPlayerControllerAthena* PlayerController = nullptr; + + if (auto TeamArrayContainer = GameState->GetTeamsArrayContainer()) + { + auto& SquadArray = TeamArrayContainer->SquadsArray.at(SpawnMachine->GetSquadId()); + + for (int i = 0; i < SquadArray.Num(); i++) + { + auto StrongPlayerState = SquadArray.at(i).Get(); + + if (!StrongPlayerState) + continue; + + PlayerController = Cast(StrongPlayerState->GetOwner()); + + if (!PlayerController) + continue; + + if (PlayerController->InternalIndex == SpawnMachine->GetInstigatorPC().ObjectIndex) + continue; + + break; + } + } + + LOG_INFO(LogDev, "PlayerController: {}", __int64(PlayerController)); + + if (!PlayerController) + return; + + auto PlayerState = Cast(PlayerController->GetPlayerState()); + + if (!PlayerState) + return; + + auto ResurrectionComponent = PlayerController->GetResurrectionComponent(); + + if (!ResurrectionComponent) + return; + + static auto FortPlayerStartClass = FindObject(L"/Script/FortniteGame.FortPlayerStart"); + + if (true) // i dont think we actually need this + { + ResurrectionComponent->GetResurrectionLocation().ObjectIndex = SpawnMachine->GetResurrectLocation()->InternalIndex; + ResurrectionComponent->GetResurrectionLocation().ObjectSerialNumber = GetItemByIndex(SpawnMachine->GetResurrectLocation()->InternalIndex)->SerialNumber; + } + + auto StrongResurrectionLocation = ResurrectionComponent->GetResurrectionLocation().Get(); + + LOG_INFO(LogDev, "StrongResurrectionLocation: {} IsClientReady: {}", __int64(StrongResurrectionLocation), PlayerState->GetRespawnData()->IsClientReady()); + + if (!StrongResurrectionLocation) + return; + + GameMode->RestartPlayerAtPlayerStart(PlayerController, StrongResurrectionLocation); + // PlayerController->ServerRestartPlayer(); + + /* static auto PawnClass = FindObject("/Game/Athena/PlayerPawn_Athena.PlayerPawn_Athena_C"); + auto NewPawn = GetWorld()->SpawnActor(PawnClass, StrongResurrectionLocation->GetTransform()); + PlayerController->Possess(NewPawn); */ + + AFortPlayerPawn* NewPawn = Cast(PlayerController->GetMyFortPawn()); + + LOG_INFO(LogDev, "NewPawn: {}", __int64(NewPawn)); + + if (!NewPawn) // Failed to restart player + return; + + NewPawn->SetHealth(100); + NewPawn->SetMaxHealth(100); + + static auto RebootCounterOffset = PlayerState->GetOffset("RebootCounter"); + PlayerState->Get(RebootCounterOffset)++; + + static auto OnRep_RebootCounterFn = FindObject(L"/Script/FortniteGame.FortPlayerStateAthena.OnRep_RebootCounter"); + PlayerState->ProcessEvent(OnRep_RebootCounterFn); + + static void (*AddToAlivePlayersOriginal)(AFortGameModeAthena* GameMode, AFortPlayerControllerAthena* Player) = decltype(AddToAlivePlayersOriginal)(Addresses::AddToAlivePlayers); + + if (AddToAlivePlayersOriginal) + { + AddToAlivePlayersOriginal(GameMode, PlayerController); + } + + auto OnPlayerPawnResurrectedFn = SpawnMachine->FindFunction("OnPlayerPawnResurrected"); + SpawnMachine->ProcessEvent(OnPlayerPawnResurrectedFn, &NewPawn); + + bool IsFinalPlayerToBeRebooted = true; + + if (IsFinalPlayerToBeRebooted) + { + SpawnMachine->FinishResurrection(PlayerState->GetSquadId()); + } +} \ No newline at end of file diff --git a/Project Reboot 3.0/BuildingGameplayActorSpawnMachine.h b/Project Reboot 3.0/BuildingGameplayActorSpawnMachine.h index 3f59c93..1a6187f 100644 --- a/Project Reboot 3.0/BuildingGameplayActorSpawnMachine.h +++ b/Project Reboot 3.0/BuildingGameplayActorSpawnMachine.h @@ -1,2 +1,49 @@ #pragma once +#include "BuildingGameplayActor.h" +#include "OnlineReplStructs.h" +#include "WeakObjectPtr.h" + +class ABuildingGameplayActorSpawnMachine : public ABuildingGameplayActor +{ +public: + TArray& GetPlayerIdsForResurrection() + { + static auto PlayerIdsForResurrectionOffset = GetOffset("PlayerIdsForResurrection"); + return Get>(PlayerIdsForResurrectionOffset); + } + + AActor*& GetResurrectLocation() // actually AFortPlayerStart + { + static auto ResurrectLocationOffset = GetOffset("ResurrectLocation"); + return Get(ResurrectLocationOffset); + } + + uint8& GetActiveTeam() + { + static auto ActiveTeamOffset = GetOffset("ActiveTeam"); + return Get(ActiveTeamOffset); + } + + uint8& GetSquadId() + { + static auto SquadIdOffset = GetOffset("SquadId"); + return Get(SquadIdOffset); + } + + TWeakObjectPtr GetInstigatorPC() + { + static auto InstigatorPCOffset = GetOffset("InstigatorPC"); + return Get>(InstigatorPCOffset); + } + + void FinishResurrection(int SquadId); + + static void RebootingDelegateHook(ABuildingGameplayActorSpawnMachine* SpawnMachine); + + static UClass* StaticClass() + { + static auto Class = FindObject(L"/Script/FortniteGame.BuildingGameplayActorSpawnMachine"); + return Class; + } +}; \ No newline at end of file diff --git a/Project Reboot 3.0/FortAthenaMapInfo.cpp b/Project Reboot 3.0/FortAthenaMapInfo.cpp index 759342e..9e16a1e 100644 --- a/Project Reboot 3.0/FortAthenaMapInfo.cpp +++ b/Project Reboot 3.0/FortAthenaMapInfo.cpp @@ -47,7 +47,8 @@ void AFortAthenaMapInfo::SpawnLlamas() for (int i = 0; i < AmountOfLlamasToSpawn; i++) { - FVector Location = PickSupplyDropLocation(FVector(1, 1, 10000), 30000); + int Radius = 100000; + FVector Location = PickSupplyDropLocation(FVector(1, 1, 10000), Radius); // LOG_INFO(LogDev, "Initial Llama at {} {} {}", Location.X, Location.Y, Location.Z); diff --git a/Project Reboot 3.0/FortGameModeAthena.cpp b/Project Reboot 3.0/FortGameModeAthena.cpp index 9c38f29..ef3d946 100644 --- a/Project Reboot 3.0/FortGameModeAthena.cpp +++ b/Project Reboot 3.0/FortGameModeAthena.cpp @@ -17,6 +17,7 @@ #include "KismetStringLibrary.h" #include "SoftObjectPtr.h" #include "discord.h" +#include "BuildingGameplayActorSpawnMachine.h" #include "vehicles.h" #include "globals.h" @@ -458,8 +459,8 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game // if (!Globals::bCreative) { - static auto FortPlayerStartCreativeClass = FindObject("/Script/FortniteGame.FortPlayerStartCreative"); - static auto FortPlayerStartWarmupClass = FindObject("/Script/FortniteGame.FortPlayerStartWarmup"); + static auto FortPlayerStartCreativeClass = FindObject(L"/Script/FortniteGame.FortPlayerStartCreative"); + static auto FortPlayerStartWarmupClass = FindObject(L"/Script/FortniteGame.FortPlayerStartWarmup"); TArray Actors = UGameplayStatics::GetAllActorsOfClass(GetWorld(), Globals::bCreative ? FortPlayerStartCreativeClass : FortPlayerStartWarmupClass); int ActorsNum = Actors.Num(); @@ -557,23 +558,64 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game SetupAIDirector(); SetupServerBotManager(); + if (auto TeamsArrayContainer = GameState->GetTeamsArrayContainer()) + { + TeamsArrayContainer->TeamIndexesArray.Free(); + + for (int i = 0; i < 100; i++) + { + TeamsArrayContainer->TeamIndexesArray.Add(INT_MAX); // Bro what + } + + TeamsArrayContainer->SquadIdsArray.Free(); + + for (int i = 0; i < 100; i++) + { + TeamsArrayContainer->SquadIdsArray.Add(INT_MAX); // Bro what + } + + // We aren't "freeing", it's just not zero'd I guess? + + for (int i = 0; i < TeamsArrayContainer->TeamsArray.Num(); i++) + { + TeamsArrayContainer->TeamsArray.at(i).Free(); + } + + for (int i = 0; i < TeamsArrayContainer->SquadsArray.Num(); i++) + { + TeamsArrayContainer->SquadsArray.at(i).Free(); + } + } + + auto AllRebootVans = UGameplayStatics::GetAllActorsOfClass(GetWorld(), ABuildingGameplayActorSpawnMachine::StaticClass()); + + for (int i = 0; i < AllRebootVans.Num(); i++) + { + auto CurrentRebootVan = (ABuildingGameplayActorSpawnMachine*)AllRebootVans.at(i); + static auto FortPlayerStartClass = FindObject(L"/Script/FortniteGame.FortPlayerStart"); + CurrentRebootVan->GetResurrectLocation() = CurrentRebootVan->GetClosestActor(FortPlayerStartClass, 100); + } + + AllRebootVans.Free(); + + static auto DefaultRebootMachineHotfixOffset = GameState->GetOffset("DefaultRebootMachineHotfix", false); + + if (DefaultRebootMachineHotfixOffset != -1) + { + // LOG_INFO(LogDev, "Beraau: {}", GameState->Get(DefaultRebootMachineHotfixOffset)); + GameState->Get(DefaultRebootMachineHotfixOffset) = 1; // idk i dont think we need to set + } + if (AmountOfBotsToSpawn != 0) { Bots::SpawnBotsAtPlayerStarts(AmountOfBotsToSpawn); } - // GameState->OnRep_CurrentPlaylistInfo(); - - // return false; - - if (!UptimeWebHook.send_message(std::format("Server up! {} {}", Fortnite_Version, PlaylistName))) // PlaylistName sometimes isn't always what we use. - { - // Sleep(-1); // what why did i have this here i honestly forgot - } + UptimeWebHook.send_message(std::format("Server up! {} {}", Fortnite_Version, PlaylistName)); // PlaylistName sometimes isn't always what we use! if (std::floor(Fortnite_Version) == 5) { - auto NewFn = FindObject("/Game/Athena/Prototype/Blueprints/Cube/CUBE.CUBE_C.New"); + auto NewFn = FindObject(L"/Game/Athena/Prototype/Blueprints/Cube/CUBE.CUBE_C.New"); if (NewFn && (Fortnite_Version == 5.30 ? !Globals::bGoingToPlayEvent : true)) { @@ -615,7 +657,7 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game if (!CurrentObject) continue; - static auto BuildingFoundationClass = FindObject("/Script/FortniteGame.BuildingFoundation"); + static auto BuildingFoundationClass = FindObject(L"/Script/FortniteGame.BuildingFoundation"); if (!CurrentObject->IsA(BuildingFoundationClass)) continue; @@ -651,7 +693,7 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game // if (MapInfo->Get>(FlightInfosOffset).ArrayNum > 0) { - LOG_INFO(LogDev, "ReadyToStartMatch Return Address: 0x{:x}", __int64(_ReturnAddress()) - __int64(GetModuleHandleW(0))); + // LOG_INFO(LogDev, "ReadyToStartMatch Return Address: 0x{:x}", __int64(_ReturnAddress()) - __int64(GetModuleHandleW(0))); Ret = true; } } @@ -680,7 +722,7 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game { // On newer versions there is a second param. - LOG_INFO(LogDev, "FunctionToCallPair.second: {}", __int64(FunctionToCallPair.second)); + // LOG_INFO(LogDev, "FunctionToCallPair.second: {}", __int64(FunctionToCallPair.second)); if (FunctionToCallPair.second) { @@ -711,6 +753,12 @@ int AFortGameModeAthena::Athena_PickTeamHook(AFortGameModeAthena* GameMode, uint auto PlayerState = ((APlayerController*)Controller)->GetPlayerState(); + if (!PlayerState) + { + LOG_ERROR(LogGame, "Player has no playerstate!"); + return 0; + } + if (PlayerState) { bIsBot = PlayerState->IsBot(); @@ -718,7 +766,7 @@ int AFortGameModeAthena::Athena_PickTeamHook(AFortGameModeAthena* GameMode, uint // VERY BASIC IMPLEMENTATION - LOG_INFO(LogTeams, "PickTeam called!"); + // LOG_INFO(LogTeams, "PickTeam called!"); auto GameState = Cast(GameMode->GetGameState()); @@ -770,7 +818,7 @@ int AFortGameModeAthena::Athena_PickTeamHook(AFortGameModeAthena* GameMode, uint if (!Playlist) { CurrentTeamMembers = 0; - LOG_INFO(LogTeams, "Player is going on team {} with {} members (No Playlist).", Current, CurrentTeamMembers); + // LOG_INFO(LogTeams, "Player is going on team {} with {} members (No Playlist).", Current, CurrentTeamMembers); CurrentTeamMembers++; return Current++; } @@ -801,7 +849,7 @@ int AFortGameModeAthena::Athena_PickTeamHook(AFortGameModeAthena* GameMode, uint TeamsNum = 100; } - LOG_INFO(LogTeams, "Before team assigning NextTeamIndex: {} CurrentTeamMembers: {}", NextTeamIndex, CurrentTeamMembers); + // LOG_INFO(LogTeams, "Before team assigning NextTeamIndex: {} CurrentTeamMembers: {}", NextTeamIndex, CurrentTeamMembers); if (!bShouldSpreadTeams) { @@ -832,6 +880,19 @@ int AFortGameModeAthena::Athena_PickTeamHook(AFortGameModeAthena* GameMode, uint CurrentTeamMembers++; + TWeakObjectPtr WeakPlayerState{}; + WeakPlayerState.ObjectIndex = PlayerState->InternalIndex; + WeakPlayerState.ObjectSerialNumber = GetItemByIndex(PlayerState->InternalIndex)->SerialNumber; + + if (auto TeamsArrayContainer = GameState->GetTeamsArrayContainer()) + { + auto& TeamArray = TeamsArrayContainer->TeamsArray.at(NextTeamIndex); + LOG_INFO(LogDev, "TeamsArrayContainer->TeamsArray.Num(): {}", TeamsArrayContainer->TeamsArray.Num()); + LOG_INFO(LogDev, "TeamArray.Num(): {}", TeamArray.Num()); + + TeamArray.Add(WeakPlayerState); + } + return NextTeamIndex; } @@ -1044,13 +1105,13 @@ void AFortGameModeAthena::Athena_HandleStartingNewPlayerHook(AFortGameModeAthena return Athena_HandleStartingNewPlayerOriginal(GameMode, NewPlayerActor); static auto CharacterPartsOffset = PlayerStateAthena->GetOffset("CharacterParts", false); - static auto CustomCharacterPartsStruct = FindObject("/Script/FortniteGame.CustomCharacterParts"); + static auto CustomCharacterPartsStruct = FindObject(L"/Script/FortniteGame.CustomCharacterParts"); auto CharacterParts = PlayerStateAthena->GetPtr<__int64>("CharacterParts"); static auto PartsOffset = FindOffsetStruct("/Script/FortniteGame.CustomCharacterParts", "Parts", false); auto Parts = (UObject**)(__int64(CharacterParts) + PartsOffset); // UCustomCharacterPart* Parts[0x6] - static auto CustomCharacterPartClass = FindObject("/Script/FortniteGame.CustomCharacterPart"); + static auto CustomCharacterPartClass = FindObject(L"/Script/FortniteGame.CustomCharacterPart"); if (Globals::bNoMCP) { @@ -1063,7 +1124,7 @@ void AFortGameModeAthena::Athena_HandleStartingNewPlayerHook(AFortGameModeAthena Parts[(int)EFortCustomPartType::Head] = headPart; Parts[(int)EFortCustomPartType::Body] = bodyPart; - static auto OnRep_CharacterPartsFn = FindObject("/Script/FortniteGame.FortPlayerState.OnRep_CharacterParts"); + static auto OnRep_CharacterPartsFn = FindObject(L"/Script/FortniteGame.FortPlayerState.OnRep_CharacterParts"); PlayerStateAthena->ProcessEvent(OnRep_CharacterPartsFn); } } @@ -1071,7 +1132,19 @@ void AFortGameModeAthena::Athena_HandleStartingNewPlayerHook(AFortGameModeAthena static auto SquadIdOffset = PlayerStateAthena->GetOffset("SquadId", false); if (SquadIdOffset != -1) - PlayerStateAthena->GetSquadId() = PlayerStateAthena->GetTeamIndex() - 2; // wrong place to do this + PlayerStateAthena->GetSquadId() = PlayerStateAthena->GetTeamIndex() - 3; // wrong place to do this + + TWeakObjectPtr WeakPlayerState{}; + WeakPlayerState.ObjectIndex = PlayerStateAthena->InternalIndex; + WeakPlayerState.ObjectSerialNumber = GetItemByIndex(PlayerStateAthena->InternalIndex)->SerialNumber; + + if (auto TeamsArrayContainer = GameState->GetTeamsArrayContainer()) + { + auto& SquadArray = TeamsArrayContainer->SquadsArray.at(PlayerStateAthena->GetSquadId()); + SquadArray.Add(WeakPlayerState); + } + + LOG_INFO(LogDev, "New player going on TeamIndex {} with SquadId {}", PlayerStateAthena->GetTeamIndex(), SquadIdOffset != -1 ? PlayerStateAthena->GetSquadId() : -1); // idk if this is needed diff --git a/Project Reboot 3.0/FortGameModeAthena.h b/Project Reboot 3.0/FortGameModeAthena.h index 24f692c..8adbfa0 100644 --- a/Project Reboot 3.0/FortGameModeAthena.h +++ b/Project Reboot 3.0/FortGameModeAthena.h @@ -133,7 +133,7 @@ static void ShowFoundation(AActor* BuildingFoundation, bool bShow = true) BuildingFoundation->SetBitfieldValue(bShowHLODWhenDisabledOffset, bShowHLODWhenDisabledFieldMask, true); } */ - static auto OnRep_ServerStreamedInLevelFn = FindObject("/Script/FortniteGame.BuildingFoundation.OnRep_ServerStreamedInLevel"); + static auto OnRep_ServerStreamedInLevelFn = FindObject(L"/Script/FortniteGame.BuildingFoundation.OnRep_ServerStreamedInLevel"); BuildingFoundation->ProcessEvent(OnRep_ServerStreamedInLevelFn); static auto DynamicFoundationRepDataOffset = BuildingFoundation->GetOffset("DynamicFoundationRepData", false); @@ -151,7 +151,7 @@ static void ShowFoundation(AActor* BuildingFoundation, bool bShow = true) *(uint8_t*)(__int64(DynamicFoundationRepData) + EnabledStateOffset) = bShow ? Enabled : Disabled; - static auto OnRep_DynamicFoundationRepDataFn = FindObject("/Script/FortniteGame.BuildingFoundation.OnRep_DynamicFoundationRepData"); + static auto OnRep_DynamicFoundationRepDataFn = FindObject(L"/Script/FortniteGame.BuildingFoundation.OnRep_DynamicFoundationRepData"); BuildingFoundation->ProcessEvent(OnRep_DynamicFoundationRepDataFn); } @@ -182,7 +182,7 @@ static void ShowFoundation(AActor* BuildingFoundation, bool bShow = true) static void StreamLevel(const std::string& LevelName, FVector Location = {}) { - static auto BuildingFoundation3x3Class = FindObject("/Script/FortniteGame.BuildingFoundation3x3"); + static auto BuildingFoundation3x3Class = FindObject(L"/Script/FortniteGame.BuildingFoundation3x3"); FTransform Transform{}; Transform.Scale3D = { 1, 1, 1 }; Transform.Translation = Location; @@ -206,7 +206,7 @@ static void StreamLevel(const std::string& LevelName, FVector Location = {}) *(FName*)(__int64(BuildingFoundation) + LevelToStreamOffset) = UKismetStringLibrary::Conv_StringToName(std::wstring(LevelName.begin(), LevelName.end()).c_str()); - static auto OnRep_LevelToStreamFn = FindObject("/Script/FortniteGame.BuildingFoundation.OnRep_LevelToStream"); + static auto OnRep_LevelToStreamFn = FindObject(L"/Script/FortniteGame.BuildingFoundation.OnRep_LevelToStream"); BuildingFoundation->ProcessEvent(OnRep_LevelToStreamFn); ShowFoundation(BuildingFoundation); @@ -245,9 +245,7 @@ public: FName RedirectLootTier(const FName& LootTier); UClass* GetVehicleClassOverride(UClass* DefaultClass); - // Idk where to put these 3 functions. - - static void HandleSpawnRateForActorClass(UClass* ActorClass, float SpawnPercentage); + static void HandleSpawnRateForActorClass(UClass* ActorClass, float SpawnPercentage); // idk where to put static bool Athena_ReadyToStartMatchHook(AFortGameModeAthena* GameMode); static int Athena_PickTeamHook(AFortGameModeAthena* GameMode, uint8 preferredTeam, AActor* Controller); diff --git a/Project Reboot 3.0/FortGameSessionDedicatedAthena.cpp b/Project Reboot 3.0/FortGameSessionDedicatedAthena.cpp new file mode 100644 index 0000000..8560e01 --- /dev/null +++ b/Project Reboot 3.0/FortGameSessionDedicatedAthena.cpp @@ -0,0 +1,35 @@ +#include "FortGameSessionDedicatedAthena.h" +#include "GameplayStatics.h" +#include "FortPlayerStateAthena.h" + +#include "FortPlayerControllerAthena.h" +#include "OnlineReplStructs.h" + +uint8 AFortGameSessionDedicatedAthena::GetSquadIdForCurrentPlayerHook(AFortGameSessionDedicatedAthena* GameSessionDedicated, __int64 UniqueId) +{ + LOG_INFO(LogDev, "GetSquadIdForCurrentPlayerHook!"); + + TArray CONTRTOLLERS = UGameplayStatics::GetAllActorsOfClass(GetWorld(), AFortPlayerControllerAthena::StaticClass()); + + for (int i = 0; i < CONTRTOLLERS.Num(); i++) + { + auto Controller = (AFortPlayerControllerAthena*)CONTRTOLLERS.at(i); + auto PlayerState = Cast(Controller->GetPlayerState()); + + if (!PlayerState) + continue; + + static auto UniqueIdOffset = PlayerState->GetOffset("UniqueId"); + + if (PlayerState->GetPtr(UniqueIdOffset)->IsIdentical((FUniqueNetIdRepl*)&UniqueId)) + { + return PlayerState->GetTeamIndex() - 3; + } + } + + CONTRTOLLERS.Free(); + + LOG_INFO(LogDev, "Failed to find SquadId!"); + + return 0; +} \ No newline at end of file diff --git a/Project Reboot 3.0/FortGameSessionDedicatedAthena.h b/Project Reboot 3.0/FortGameSessionDedicatedAthena.h new file mode 100644 index 0000000..09de8cf --- /dev/null +++ b/Project Reboot 3.0/FortGameSessionDedicatedAthena.h @@ -0,0 +1,9 @@ +#pragma once + +#include "reboot.h" + +class AFortGameSessionDedicatedAthena : public AActor +{ +public: + static uint8 GetSquadIdForCurrentPlayerHook(AFortGameSessionDedicatedAthena* GameSessionDedicated, __int64 UniqueId); +}; \ No newline at end of file diff --git a/Project Reboot 3.0/FortGameStateAthena.cpp b/Project Reboot 3.0/FortGameStateAthena.cpp index a95b7eb..5040387 100644 --- a/Project Reboot 3.0/FortGameStateAthena.cpp +++ b/Project Reboot 3.0/FortGameStateAthena.cpp @@ -247,10 +247,29 @@ void AFortGameStateAthena::OnRep_CurrentPlaylistInfo() void AFortGameStateAthena::OnRep_PlayersLeft() { - static auto OnRep_PlayersLeftFn = FindObject("/Script/FortniteGame.FortGameStateAthena.OnRep_PlayersLeft"); + static auto OnRep_PlayersLeftFn = FindObject(L"/Script/FortniteGame.FortGameStateAthena.OnRep_PlayersLeft"); if (!OnRep_PlayersLeftFn) return; this->ProcessEvent(OnRep_PlayersLeftFn); +} + +TeamsArrayContainer* AFortGameStateAthena::GetTeamsArrayContainer() +{ + static auto FriendlyFireTypeOffset = GetOffset("FriendlyFireType"); + static int Offset = -1; + + if (Offset == -1) + { + Offset = FriendlyFireTypeOffset + 0x5; + } + + return Offset != -1 ? (TeamsArrayContainer*)(__int64(this) + Offset) : nullptr; +} + +UClass* AFortGameStateAthena::StaticClass() +{ + static auto Class = FindObject(L"/Script/FortniteGame.FortGameStateAthena"); + return Class; } \ No newline at end of file diff --git a/Project Reboot 3.0/FortGameStateAthena.h b/Project Reboot 3.0/FortGameStateAthena.h index a20e06c..4740080 100644 --- a/Project Reboot 3.0/FortGameStateAthena.h +++ b/Project Reboot 3.0/FortGameStateAthena.h @@ -1,7 +1,7 @@ #pragma once #include "GameState.h" -#include "FortPlayerState.h" +#include "FortPlayerStateAthena.h" #include "FortPlaylist.h" #include "BuildingStructuralSupportSystem.h" #include "ScriptInterface.h" @@ -43,11 +43,24 @@ class UFortSafeZoneInterface : public UInterface public: static UClass* StaticClass() { - static auto Struct = FindObject("/Script/FortniteGame.FortSafeZoneInterface"); + static auto Struct = FindObject(L"/Script/FortniteGame.FortSafeZoneInterface"); return Struct; } }; +struct TeamsArrayContainer // THANK ANDROIDDD!!!! +{ + TArray>> TeamsArray; // 13D0 + TArray TeamIdk1; // 13E0 + TArray TeamIndexesArray; // 13F0 + + uintptr_t idfk; //(or 2 ints) // 1400 + + TArray>> SquadsArray; // Index = SquadId // 1408 + TArray SquadIdk1; // 1418 + TArray SquadIdsArray; // 0x1428 +}; + struct FPlayerBuildableClassContainer { TArray BuildingClasses; // 0x0000(0x0010) (ZeroConstructor, Transient, UObjectWrapper, NativeAccessSpecifierPublic) @@ -86,6 +99,14 @@ public: return Get(MapInfoOffset); } + bool IsResurrectionEnabled(AFortPlayerPawn* PlayerPawn) + { + static auto IsResurrectionEnabledFn = FindObject("/Script/FortniteGame.FortGameStateAthena.IsResurrectionEnabled"); + struct { AFortPlayerPawn* PlayerPawn; bool Ret; } Params{PlayerPawn}; + this->ProcessEvent(IsResurrectionEnabledFn, &Params); + return Params.Ret; + } + EAthenaGamePhaseStep& GetGamePhaseStep() { static auto GamePhaseStepOffset = GetOffset("GamePhaseStep"); @@ -105,6 +126,9 @@ public: void OnRep_GamePhase(); void OnRep_CurrentPlaylistInfo(); void OnRep_PlayersLeft(); + TeamsArrayContainer* GetTeamsArrayContainer(); + + static UClass* StaticClass(); }; static void* ConstructOnGamePhaseStepChangedParams(EAthenaGamePhaseStep GamePhaseStep) diff --git a/Project Reboot 3.0/FortPlayerController.cpp b/Project Reboot 3.0/FortPlayerController.cpp index 2650e4b..541b980 100644 --- a/Project Reboot 3.0/FortPlayerController.cpp +++ b/Project Reboot 3.0/FortPlayerController.cpp @@ -1371,6 +1371,8 @@ void AFortPlayerController::ClientOnPawnDiedHook(AFortPlayerController* PlayerCo auto GameMode = Cast(GetWorld()->GetGameMode()); + LOG_INFO(LogDev, "PlayersLeft: {} IsDBNO: {}", GameState->GetPlayersLeft(), DeadPawn->IsDBNO()); + if (!DeadPawn->IsDBNO()) { if (Fortnite_Version > 1.8 || Fortnite_Version == 1.11) @@ -1460,12 +1462,12 @@ void AFortPlayerController::ClientOnPawnDiedHook(AFortPlayerController* PlayerCo if (CurrentPlayerState->GetPlace() <= 1) { - bDidSomeoneWin = true; + // bDidSomeoneWin = true; break; } } - LOG_INFO(LogDev, "bDidSomeoneWin: {}", bDidSomeoneWin); + // LOG_INFO(LogDev, "bDidSomeoneWin: {}", bDidSomeoneWin); // if (GameState->GetGamePhase() == EAthenaGamePhase::EndGame) if (bDidSomeoneWin) @@ -1478,7 +1480,7 @@ void AFortPlayerController::ClientOnPawnDiedHook(AFortPlayerController* PlayerCo if (DeadPlayerState->IsBot()) { - // AllPlayerBotsToTick. + // AllPlayerBotsToTick.remov3lbah } return ClientOnPawnDiedOriginal(PlayerController, DeathReport); diff --git a/Project Reboot 3.0/FortPlayerControllerAthena.cpp b/Project Reboot 3.0/FortPlayerControllerAthena.cpp index 764c515..a9b96c3 100644 --- a/Project Reboot 3.0/FortPlayerControllerAthena.cpp +++ b/Project Reboot 3.0/FortPlayerControllerAthena.cpp @@ -8,6 +8,7 @@ #include "hooking.h" #include "FortAthenaMutator_GiveItemsAtGamePhaseStep.h" #include "DataTableFunctionLibrary.h" +#include "AthenaResurrectionComponent.h" #include "FortAthenaMutator_InventoryOverride.h" void AFortPlayerControllerAthena::StartGhostModeHook(UObject* Context, FFrame* Stack, void* Ret) @@ -480,7 +481,7 @@ void AFortPlayerControllerAthena::ServerReadyToStartMatchHook(AFortPlayerControl { auto& QuickBars = PlayerController->Get(QuickBarsOffset); - LOG_INFO(LogDev, "QuickBarsOld: {}", __int64(QuickBars)); + // LOG_INFO(LogDev, "QuickBarsOld: {}", __int64(QuickBars)); if (QuickBars) return ServerReadyToStartMatchOriginal(PlayerController); @@ -489,7 +490,7 @@ void AFortPlayerControllerAthena::ServerReadyToStartMatchHook(AFortPlayerControl QuickBars = GetWorld()->SpawnActor(FortQuickBarsClass); - LOG_INFO(LogDev, "QuickBarsNew: {}", __int64(QuickBars)); + // LOG_INFO(LogDev, "QuickBarsNew: {}", __int64(QuickBars)); if (!QuickBars) return ServerReadyToStartMatchOriginal(PlayerController); diff --git a/Project Reboot 3.0/FortPlayerControllerAthena.h b/Project Reboot 3.0/FortPlayerControllerAthena.h index 0a3ac22..cad77c7 100644 --- a/Project Reboot 3.0/FortPlayerControllerAthena.h +++ b/Project Reboot 3.0/FortPlayerControllerAthena.h @@ -132,6 +132,12 @@ public: static inline void (*StartGhostModeOriginal)(UObject* Context, FFrame* Stack, void* Ret); static inline void (*EndGhostModeOriginal)(AFortPlayerControllerAthena* PlayerController); + class UAthenaResurrectionComponent*& GetResurrectionComponent() + { + static auto ResurrectionComponentOffset = GetOffset("ResurrectionComponent"); + return Get(ResurrectionComponentOffset); + } + AFortPlayerStateAthena* GetPlayerStateAthena() { return (AFortPlayerStateAthena*)GetPlayerState(); @@ -183,7 +189,7 @@ public: static UClass* StaticClass() { - static auto Class = FindObject("/Script/FortniteGame.FortPlayerControllerAthena"); + static auto Class = FindObject(L"/Script/FortniteGame.FortPlayerControllerAthena"); return Class; } }; \ No newline at end of file diff --git a/Project Reboot 3.0/FortPlayerState.cpp b/Project Reboot 3.0/FortPlayerState.cpp new file mode 100644 index 0000000..22aa741 --- /dev/null +++ b/Project Reboot 3.0/FortPlayerState.cpp @@ -0,0 +1,6 @@ +#include "FortPlayerState.h" + +bool AFortPlayerState::AreUniqueIDsIdentical(FUniqueNetIdRepl* A, FUniqueNetIdRepl* B) +{ + return A->IsIdentical(B); +} \ No newline at end of file diff --git a/Project Reboot 3.0/FortPlayerState.h b/Project Reboot 3.0/FortPlayerState.h index f5adf18..ffdac58 100644 --- a/Project Reboot 3.0/FortPlayerState.h +++ b/Project Reboot 3.0/FortPlayerState.h @@ -1,5 +1,6 @@ #pragma once +#include "OnlineReplStructs.h" #include "PlayerState.h" #include "AbilitySystemComponent.h" @@ -18,6 +19,8 @@ public: return this->Get(WorldPlayerIdOffset); } + static bool AreUniqueIDsIdentical(FUniqueNetIdRepl* A, FUniqueNetIdRepl* B); + static UClass* StaticClass() { static auto Class = FindObject("/Script/FortniteGame.FortPlayerState"); diff --git a/Project Reboot 3.0/FortPlayerStateAthena.h b/Project Reboot 3.0/FortPlayerStateAthena.h index 89e9c81..04ad044 100644 --- a/Project Reboot 3.0/FortPlayerStateAthena.h +++ b/Project Reboot 3.0/FortPlayerStateAthena.h @@ -3,6 +3,35 @@ #include "FortPlayerState.h" #include "Stack.h" +struct FFortRespawnData +{ + static UStruct* GetStruct() + { + static auto Struct = FindObject(L"/Script/FortniteGame.FortRespawnData"); + return Struct; + } + + static int GetStructSize() { return GetStruct()->GetPropertiesSize(); } + + bool& IsRespawnDataAvailable() + { + static auto bRespawnDataAvailableOffset = FindOffsetStruct("/Script/FortniteGame.FortRespawnData", "bRespawnDataAvailable"); + return *(bool*)(__int64(this) + bRespawnDataAvailableOffset); + } + + bool& IsClientReady() + { + static auto bClientIsReadyOffset = FindOffsetStruct("/Script/FortniteGame.FortRespawnData", "bClientIsReady"); + return *(bool*)(__int64(this) + bClientIsReadyOffset); + } + + bool& IsServerReady() + { + static auto bServerIsReadyOffset = FindOffsetStruct("/Script/FortniteGame.FortRespawnData", "bServerIsReady"); + return *(bool*)(__int64(this) + bServerIsReadyOffset); + } +}; + class AFortPlayerStateAthena : public AFortPlayerState { public: @@ -26,6 +55,12 @@ public: return Get(PlaceOffset); } + FFortRespawnData* GetRespawnData() + { + static auto RespawnDataOffset = GetOffset("RespawnData"); + return GetPtr(RespawnDataOffset); + } + bool IsInAircraft() { static auto bInAircraftOffset = GetOffset("bInAircraft"); @@ -40,6 +75,16 @@ public: return ReadBitfieldValue(bThankedBusDriverOffset, bThankedBusDriverFieldMask); } + bool& IsResurrectingNow() + { + static auto bResurrectingNowOffset = GetOffset("bResurrectingNow", false); + + // if (bResurrectingNowOffset == -1) + // return false; + + return Get(bResurrectingNowOffset); + } + void ClientReportKill(AFortPlayerStateAthena* Player) { static auto ClientReportKillFn = FindObject("/Script/FortniteGame.FortPlayerStateAthena.ClientReportKill"); diff --git a/Project Reboot 3.0/GameModeBase.cpp b/Project Reboot 3.0/GameModeBase.cpp index 5592d12..e9e066e 100644 --- a/Project Reboot 3.0/GameModeBase.cpp +++ b/Project Reboot 3.0/GameModeBase.cpp @@ -9,6 +9,38 @@ #include "FortAthenaMutator_GG.h" #include "FortAthenaMutator_InventoryOverride.h" +void AGameModeBase::RestartPlayerAtTransform(AController* NewPlayer, FTransform SpawnTransform) +{ + static auto RestartPlayerAtTransformFn = FindObject("/Script/Engine.GameModeBase.RestartPlayerAtTransform"); + + struct + { + AController* NewPlayer; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) + FTransform SpawnTransform; // (ConstParm, Parm, OutParm, ReferenceParm, IsPlainOldData, NoDestructor, NativeAccessSpecifierPublic) + } AGameModeBase_RestartPlayerAtTransform_Params{ NewPlayer, SpawnTransform }; + + this->ProcessEvent(RestartPlayerAtTransformFn, &AGameModeBase_RestartPlayerAtTransform_Params); +} + +void AGameModeBase::RestartPlayerAtPlayerStart(AController* NewPlayer, AActor* StartSpot) +{ + static auto RestartPlayerAtPlayerStartFn = FindObject("/Script/Engine.GameModeBase.RestartPlayerAtPlayerStart"); + + struct + { + AController* NewPlayer; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) + AActor* StartSpot; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) + } AGameModeBase_RestartPlayerAtPlayerStart_Params{ NewPlayer, StartSpot }; + + this->ProcessEvent(RestartPlayerAtPlayerStartFn, &AGameModeBase_RestartPlayerAtPlayerStart_Params); +} + +void AGameModeBase::RestartPlayer(AController* NewPlayer) +{ + static auto RestartPlayerFn = FindObject("/Script/Engine.GameModeBase.RestartPlayer"); + this->ProcessEvent(RestartPlayerFn, &NewPlayer); +} + UClass* AGameModeBase::GetDefaultPawnClassForController(AController* InController) { static auto GetDefaultPawnClassForControllerFn = FindObject("/Script/Engine.GameModeBase.GetDefaultPawnClassForController"); @@ -55,6 +87,8 @@ AActor* AGameModeBase::K2_FindPlayerStart(AController* Player, FString IncomingN APawn* AGameModeBase::SpawnDefaultPawnForHook(AGameModeBase* GameMode, AController* NewPlayer, AActor* StartSpot) { + LOG_INFO(LogDev, "SpawnDefaultPawnForHook!"); + auto NewPlayerAsAthena = Cast(NewPlayer); if (!NewPlayerAsAthena) @@ -71,7 +105,7 @@ APawn* AGameModeBase::SpawnDefaultPawnForHook(AGameModeBase* GameMode, AControll constexpr bool bUseSpawnActor = false; - static auto fn = FindObject(L"/Script/Engine.GameModeBase.SpawnDefaultPawnAtTransform"); + static auto SpawnDefaultPawnAtTransformFn = FindObject(L"/Script/Engine.GameModeBase.SpawnDefaultPawnAtTransform"); FTransform SpawnTransform = StartSpot->GetTransform(); APawn* NewPawn = nullptr; @@ -88,7 +122,7 @@ APawn* AGameModeBase::SpawnDefaultPawnForHook(AGameModeBase* GameMode, AControll struct { AController* NewPlayer; FTransform SpawnTransform; APawn* ReturnValue; } AGameModeBase_SpawnDefaultPawnAtTransform_Params{ NewPlayer, SpawnTransform }; - GameMode->ProcessEvent(fn, &AGameModeBase_SpawnDefaultPawnAtTransform_Params); + GameMode->ProcessEvent(SpawnDefaultPawnAtTransformFn, &AGameModeBase_SpawnDefaultPawnAtTransform_Params); NewPawn = AGameModeBase_SpawnDefaultPawnAtTransform_Params.ReturnValue; } @@ -102,16 +136,10 @@ APawn* AGameModeBase::SpawnDefaultPawnForHook(AGameModeBase* GameMode, AControll if (RespawnDataOffset != -1) { - static auto bServerIsReadyOffset = FindOffsetStruct("/Script/FortniteGame.FortRespawnData", "bServerIsReady"); - static auto bRespawnDataAvailableOffset = FindOffsetStruct("/Script/FortniteGame.FortRespawnData", "bRespawnDataAvailable"); + auto RespawnDataPtr = PlayerStateAthena->GetRespawnData(); - auto RespawnDataPtr = PlayerStateAthena->GetPtr<__int64>(RespawnDataOffset); - - if (*(bool*)(__int64(RespawnDataPtr) + bServerIsReadyOffset) && *(bool*)(__int64(RespawnDataPtr) + bRespawnDataAvailableOffset)) // && GameState->IsRespawningAllowed(PlayerState); + if (RespawnDataPtr->IsServerReady() && RespawnDataPtr->IsClientReady()) // && GameState->IsRespawningAllowed(PlayerState); { - // SpawnTransform.Translation = PlayerState->RespawnData.RespawnLocation; - // SpawnTransform.Rotation = Quaternion(PlayerState->RespawnData.RespawnRotation); - bIsRespawning = true; } } @@ -197,6 +225,8 @@ APawn* AGameModeBase::SpawnDefaultPawnForHook(AGameModeBase* GameMode, AControll } else { + LOG_INFO(LogDev, "Player is respawning!"); + auto DeathInfo = (void*)(__int64(PlayerStateAthena) + MemberOffsets::FortPlayerStateAthena::DeathInfo); static auto DeathInfoStruct = FindObject(L"/Script/FortniteGame.DeathInfo"); diff --git a/Project Reboot 3.0/GameModeBase.h b/Project Reboot 3.0/GameModeBase.h index e097274..86ebe3d 100644 --- a/Project Reboot 3.0/GameModeBase.h +++ b/Project Reboot 3.0/GameModeBase.h @@ -12,6 +12,9 @@ public: UClass* GetDefaultPawnClassForController(AController* InController); void ChangeName(AController* Controller, const FString& NewName, bool bNameChange); AActor* K2_FindPlayerStart(AController* Player, FString IncomingName); + void RestartPlayerAtTransform(AController* NewPlayer, FTransform SpawnTransform); + void RestartPlayerAtPlayerStart(AController* NewPlayer, AActor* StartSpot); + void RestartPlayer(AController* NewPlayer); static APawn* SpawnDefaultPawnForHook(AGameModeBase* GameMode, AController* NewPlayer, AActor* StartSpot); }; \ No newline at end of file diff --git a/Project Reboot 3.0/OnlineReplStructs.h b/Project Reboot 3.0/OnlineReplStructs.h index bbc83f3..c1d9301 100644 --- a/Project Reboot 3.0/OnlineReplStructs.h +++ b/Project Reboot 3.0/OnlineReplStructs.h @@ -24,10 +24,35 @@ struct FUniqueNetIdRepl // : public FUniqueNetIdWrapper return *(TArray*)(__int64(this) + ReplicationBytesOffset); } + bool IsIdentical(FUniqueNetIdRepl* OtherUniqueId) + { + // idk if this is right but whatever + + bool bTest = true; + + if (this->GetReplicationBytes().Num() > this->GetReplicationBytes().Num()) // != ? + bTest = false; + + for (int i = 0; i < this->GetReplicationBytes().Num(); i++) + { + if (this->GetReplicationBytes().at(i) != OtherUniqueId->GetReplicationBytes().at(i)) + { + bTest = false; + break; + } + } + + // LOG_INFO(LogDev, "btest: {}", bTest); + + return bTest; + } + void CopyFromAnotherUniqueId(FUniqueNetIdRepl* OtherUniqueId) { CopyStruct(this, OtherUniqueId, GetSizeOfStruct(), GetStruct()); + return; + auto& ReplicationBytes = GetReplicationBytes(); ReplicationBytes.Free(); diff --git a/Project Reboot 3.0/Project Reboot 3.0.vcxproj b/Project Reboot 3.0/Project Reboot 3.0.vcxproj index 6f420f6..4ebd2d0 100644 --- a/Project Reboot 3.0/Project Reboot 3.0.vcxproj +++ b/Project Reboot 3.0/Project Reboot 3.0.vcxproj @@ -180,6 +180,7 @@ + @@ -207,6 +208,7 @@ + @@ -223,6 +225,7 @@ + @@ -272,6 +275,7 @@ + @@ -333,6 +337,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 03caec9..83422b8 100644 --- a/Project Reboot 3.0/Project Reboot 3.0.vcxproj.filters +++ b/Project Reboot 3.0/Project Reboot 3.0.vcxproj.filters @@ -274,6 +274,15 @@ Reboot\Private + + FortniteGame\Source\FortniteGame\Private\Athena + + + FortniteGame\Source\FortniteGame\Private\Player + + + FortniteGame\Source\FortniteGame\Private\Building + @@ -862,6 +871,12 @@ Reboot\Public + + FortniteGame\Source\FortniteGame\Public\Athena + + + FortniteGame\Source\FortniteGame\Public + diff --git a/Project Reboot 3.0/addresses.cpp b/Project Reboot 3.0/addresses.cpp index ba3d29b..4395dcd 100644 --- a/Project Reboot 3.0/addresses.cpp +++ b/Project Reboot 3.0/addresses.cpp @@ -294,6 +294,18 @@ void Addresses::FindAll() LOG_INFO(LogDev, "Finding LoadAsset"); Addresses::LoadAsset = FindLoadAsset(); + LOG_INFO(LogDev, "Finding RebootingDelegate"); + Addresses::RebootingDelegate = FindRebootingDelegate(); + + LOG_INFO(LogDev, "Finding GetSquadIdForCurrentPlayer"); + Addresses::GetSquadIdForCurrentPlayer = FindGetSquadIdForCurrentPlayer(); + + LOG_INFO(LogDev, "Finding FinishResurrection"); + Addresses::FinishResurrection = FindFinishResurrection(); + + LOG_INFO(LogDev, "Finding AddToAlivePlayers"); + Addresses::AddToAlivePlayers = FindAddToAlivePlayers(); + LOG_INFO(LogDev, "Finished finding!"); } @@ -362,7 +374,11 @@ void Addresses::Print() LOG_INFO(LogDev, "CombinePickupLea: 0x{:x}", CombinePickupLea - Base); LOG_INFO(LogDev, "CreateBuildingActorCallForDeco: 0x{:x}", CreateBuildingActorCallForDeco - Base); LOG_INFO(LogDev, "PickSupplyDropLocation: 0x{:x}", PickSupplyDropLocation - Base); - LOG_INFO(LogDev, "LoadAsset: 0x{:x}", LoadAsset - Base) + LOG_INFO(LogDev, "LoadAsset: 0x{:x}", LoadAsset - Base); + LOG_INFO(LogDev, "RebootingDelegate: 0x{:x}", RebootingDelegate - Base); + LOG_INFO(LogDev, "GetSquadIdForCurrentPlayer: 0x{:x}", GetSquadIdForCurrentPlayer - Base); + LOG_INFO(LogDev, "FinishResurrection: 0x{:x}", FinishResurrection - Base); + LOG_INFO(LogDev, "AddToAlivePlayers: 0x{:x}", AddToAlivePlayers - Base); } void Offsets::FindAll() diff --git a/Project Reboot 3.0/addresses.h b/Project Reboot 3.0/addresses.h index e19ae94..541e0a6 100644 --- a/Project Reboot 3.0/addresses.h +++ b/Project Reboot 3.0/addresses.h @@ -70,7 +70,11 @@ namespace Addresses extern inline uint64 CreateBuildingActorCallForDeco = 0; extern inline uint64 PickSupplyDropLocation = 0; extern inline uint64 LoadAsset = 0; - + extern inline uint64 RebootingDelegate = 0; + extern inline uint64 GetSquadIdForCurrentPlayer = 0; + extern inline uint64 FinishResurrection = 0; + extern inline uint64 AddToAlivePlayers = 0; + void SetupVersion(); // Finds Engine Version void FindAll(); void Print(); diff --git a/Project Reboot 3.0/commands.h b/Project Reboot 3.0/commands.h index 5988b03..e2e2e88 100644 --- a/Project Reboot 3.0/commands.h +++ b/Project Reboot 3.0/commands.h @@ -77,7 +77,8 @@ void ServerCheatHook(AFortPlayerControllerAthena* PlayerController, FString Msg) for (int i = 0; i < ClientConnections.Num(); i++) { - auto CurrentPlayerController = Cast(ClientConnections.at(i)->Get("PlayerController")); + static auto PlayerControllerOffset = ClientConnections.at(i)->GetOffset("PlayerController"); + auto CurrentPlayerController = Cast(ClientConnections.at(i)->Get(PlayerControllerOffset)); if (!CurrentPlayerController) continue; @@ -452,7 +453,8 @@ void ServerCheatHook(AFortPlayerControllerAthena* PlayerController, FString Msg) for (int i = 0; i < ClientConnections.Num(); i++) { - auto CurrentPlayerController = Cast(ClientConnections.at(i)->Get("PlayerController")); + static auto PlayerControllerOffset = ClientConnections.at(i)->GetOffset("PlayerController"); + auto CurrentPlayerController = Cast(ClientConnections.at(i)->Get(PlayerControllerOffset)); if (!CurrentPlayerController) continue; @@ -790,7 +792,7 @@ void ServerCheatHook(AFortPlayerControllerAthena* PlayerController, FString Msg) } LOG_INFO(LogDev, "Pawn: 0x{:x}", __int64(Pawn)); - } + } else { bSendHelpMessage = true; }; } else { bSendHelpMessage = true; }; diff --git a/Project Reboot 3.0/dllmain.cpp b/Project Reboot 3.0/dllmain.cpp index a42cdea..efbe598 100644 --- a/Project Reboot 3.0/dllmain.cpp +++ b/Project Reboot 3.0/dllmain.cpp @@ -14,6 +14,8 @@ #include #include "GenericPlatformTime.h" #include "FortAthenaMutator_GiveItemsAtGamePhaseStep.h" +#include "FortGameStateAthena.h" +#include "BuildingGameplayActorSpawnMachine.h" #include "BuildingFoundation.h" #include "Map.h" @@ -41,6 +43,7 @@ #include "PlaysetLevelStreamComponent.h" #include "FortAthenaVehicleSpawner.h" +#include "FortGameSessionDedicatedAthena.h" enum ENetMode { @@ -191,10 +194,11 @@ DWORD WINAPI Main(LPVOID) UKismetSystemLibrary::ExecuteConsoleCommand(GetWorld(), L"log LogBuilding VeryVerbose", nullptr); // UKismetSystemLibrary::ExecuteConsoleCommand(GetWorld(), L"log LogFortQuest VeryVerbose", nullptr); // UKismetSystemLibrary::ExecuteConsoleCommand(GetWorld(), L"log LogFortUIDirector NoLogging", nullptr); - UKismetSystemLibrary::ExecuteConsoleCommand(GetWorld(), L"log LogAbilitySystem VeryVerbose", nullptr); + // UKismetSystemLibrary::ExecuteConsoleCommand(GetWorld(), L"log LogAbilitySystem VeryVerbose", nullptr); UKismetSystemLibrary::ExecuteConsoleCommand(GetWorld(), L"log LogDataTable VeryVerbose", nullptr); UKismetSystemLibrary::ExecuteConsoleCommand(GetWorld(), L"log LogFort VeryVerbose", nullptr); UKismetSystemLibrary::ExecuteConsoleCommand(GetWorld(), L"log LogGameMode VeryVerbose", nullptr); + UKismetSystemLibrary::ExecuteConsoleCommand(GetWorld(), L"log LogPlayerController VeryVerbose", nullptr); UKismetSystemLibrary::ExecuteConsoleCommand(GetWorld(), L"log LogFortCustomization VeryVerbose", nullptr); Hooking::MinHook::Hook((PVOID)Addresses::NoMCP, (PVOID)NoMCPHook, nullptr); @@ -328,6 +332,12 @@ DWORD WINAPI Main(LPVOID) VirtualProtect((PVOID)func, 1, dwProtection, &dwTemp); } + if (bEnableRebooting) + { + auto GameSessionDedicatedAthenaPatch = Memcury::Scanner::FindPattern("3B 41 38 7F 27 48 8B D0 48 8B 41 30 4C 39 04 D0 75 1A 48 8D 96").Get(); + PatchBytes(GameSessionDedicatedAthenaPatch, { 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90 }); + } + if (Fortnite_Version != 22.4) { auto matchmaking = Memcury::Scanner::FindPattern("83 BD ? ? ? ? 01 7F 18 49 8D 4D D8 48 8B D6 E8 ? ? ? ? 48").Get(); @@ -426,12 +436,19 @@ DWORD WINAPI Main(LPVOID) nullptr, false); } - HookInstruction(Addresses::UpdateTrackedAttributesLea, (PVOID)UFortGadgetItemDefinition::UpdateTrackedAttributesHook, "/Script/FortniteGame.FortPlayerController.Suicide", ERelativeOffsets::LEA, FortPlayerControllerAthenaDefault); - HookInstruction(Addresses::CombinePickupLea, (PVOID)AFortPickup::CombinePickupHook, "/Script/Engine.PlayerController.SetVirtualJoystickVisibility", ERelativeOffsets::LEA, FortPlayerControllerAthenaDefault); + // HookInstruction(Addresses::UpdateTrackedAttributesLea, (PVOID)UFortGadgetItemDefinition::UpdateTrackedAttributesHook, "/Script/FortniteGame.FortPlayerController.Suicide", ERelativeOffsets::LEA, FortPlayerControllerAthenaDefault); + // HookInstruction(Addresses::CombinePickupLea, (PVOID)AFortPickup::CombinePickupHook, "/Script/Engine.PlayerController.SetVirtualJoystickVisibility", ERelativeOffsets::LEA, FortPlayerControllerAthenaDefault); + + if (false) + { + HookInstruction(Addresses::RebootingDelegate, (PVOID)ABuildingGameplayActorSpawnMachine::RebootingDelegateHook, "/Script/Engine.PlayerController.SetVirtualJoystickVisibility", ERelativeOffsets::LEA, FindObject("/Script/FortniteGame.Default__BuildingGameplayActorSpawnMachine")); + } Hooking::MinHook::Hook(FortWeaponDefault, FindObject(L"/Script/FortniteGame.FortWeapon.ServerReleaseWeaponAbility"), AFortWeapon::ServerReleaseWeaponAbilityHook, (PVOID*)&AFortWeapon::ServerReleaseWeaponAbilityOriginal, false, true); + Hooking::MinHook::Hook((PVOID)Addresses::GetSquadIdForCurrentPlayer, (PVOID)AFortGameSessionDedicatedAthena::GetSquadIdForCurrentPlayerHook); + auto OnPlayImpactFXStringRef = Memcury::Scanner::FindStringRef(L"OnPlayImpactFX", true, 0); __int64 OnPlayImpactFXAddr = 0; diff --git a/Project Reboot 3.0/events.h b/Project Reboot 3.0/events.h index 8407000..b840299 100644 --- a/Project Reboot 3.0/events.h +++ b/Project Reboot 3.0/events.h @@ -591,9 +591,17 @@ static inline bool CallOnReadys(bool* bWereAllSuccessful = nullptr) auto EventPlaylist = GetEventPlaylist(); - struct { UObject* GameState; UObject* Playlist; FGameplayTagContainer PlaylistContextTags; } OnReadyParams{ - ((AFortGameModeAthena*)GetWorld()->GetGameMode())->GetGameStateAthena(), EventPlaylist, - EventPlaylist ? EventPlaylist->Get("GameplayTagContainer") : FGameplayTagContainer()}; + struct { UObject* GameState; UObject* Playlist; FGameplayTagContainer PlaylistContextTags; } OnReadyParams{ Cast(GetWorld()->GetGameState()), EventPlaylist }; + + if (EventPlaylist) + { + static auto GameplayTagContainerOffset = EventPlaylist->GetOffset("GameplayTagContainer"); + OnReadyParams.PlaylistContextTags = EventPlaylist->Get(GameplayTagContainerOffset); + } + else + { + OnReadyParams.PlaylistContextTags = FGameplayTagContainer(); + } for (auto& OnReadyFunc : OurEvent.OnReadyFunctions) { diff --git a/Project Reboot 3.0/finder.h b/Project Reboot 3.0/finder.h index cb44fb0..7f92426 100644 --- a/Project Reboot 3.0/finder.h +++ b/Project Reboot 3.0/finder.h @@ -142,6 +142,65 @@ static inline uint64 FindObjectArray() return addr; } +static inline uint64 FindAddToAlivePlayers() +{ + auto Addrr = Memcury::Scanner::FindStringRef(L"FortGameModeAthena: Player [%s] doesn't have a valid PvP team, and won't be added to the alive players list.").Get(); + + if (!Addrr) + return 0; + + for (int i = 0; i < 4000; i++) + { + if (*(uint8_t*)(uint8_t*)(Addrr - i) == 0x48 && *(uint8_t*)(uint8_t*)(Addrr - i + 1) == 0x85 && *(uint8_t*)(uint8_t*)(Addrr - i + 2) == 0xD2) + { + return Addrr - i; + } + } + + return 0; +} + +static inline uint64 FindFinishResurrection() +{ + auto Addrr = FindFunctionCall(L"OnResurrectionCompleted"); + + if (!Addrr) + return 0; + + auto addr = Memcury::Scanner::FindPattern("40 53 48 83 EC 20 0F B6 81 ? ? ? ? 83 C2 03 48 8B D9 3B D0 0F 85").Get(); + + return addr; + + LOG_INFO(LogDev, "WTF: 0x{:x}", Addrr - __int64(GetModuleHandleW(0))); + + for (int i = 0; i < 2000; i++) + { + if (*(uint8_t*)(uint8_t*)(Addrr - i) == 0x40 && *(uint8_t*)(uint8_t*)(Addrr - i + 1) == 0x53) + { + return Addrr - i; + } + } + + return 0; +} + +static inline uint64 FindGetSquadIdForCurrentPlayer() +{ + auto addr = Memcury::Scanner::FindPattern("48 89 5C 24 ? 57 48 83 EC 40 48 8D 99 ? ? ? ? 48 8B FA 4C 8B C2 48 8B CB").Get(); + + return addr; +} + +static inline uint64 FindRebootingDelegate() +{ + if (Fortnite_Version < 8.3) + return 0; + + auto addr = Memcury::Scanner::FindPattern("48 8D 05 ? ? ? ? 33 F6 48 89 44 24 ? 49 8B CE 49 8B 06 89 74 24 60 FF 90 ? ? ? ? 4C 8B A4 24 ? ? ? ? 48 8B 88 ? ? ? ? 48 85 C9").Get(); + + return addr; +} + static inline uint64 FindPickupInitialize() { if (Engine_Version == 419) diff --git a/Project Reboot 3.0/globals.h b/Project Reboot 3.0/globals.h index 2d37eba..e037111 100644 --- a/Project Reboot 3.0/globals.h +++ b/Project Reboot 3.0/globals.h @@ -22,14 +22,13 @@ namespace Globals extern inline bool bStartedListening = false; extern inline bool bAutoRestart = true; extern inline bool bFillVendingMachines = true; - extern inline int AmountOfListens = 0; // TODO: Switch to this for LastNum } extern inline std::string PlaylistName = -"/Game/Athena/Playlists/Playlist_DefaultSolo.Playlist_DefaultSolo"; +// "/Game/Athena/Playlists/Playlist_DefaultSolo.Playlist_DefaultSolo"; // "/Game/Athena/Playlists/gg/Playlist_Gg_Reverse.Playlist_Gg_Reverse"; -// "/Game/Athena/Playlists/Playlist_DefaultDuo.Playlist_DefaultDuo"; +"/Game/Athena/Playlists/Playlist_DefaultDuo.Playlist_DefaultDuo"; // "/Game/Athena/Playlists/Playground/Playlist_Playground.Playlist_Playground"; // "/Game/Athena/Playlists/Carmine/Playlist_Carmine.Playlist_Carmine"; // "/Game/Athena/Playlists/Fill/Playlist_Fill_Solo.Playlist_Fill_Solo"; diff --git a/Project Reboot 3.0/gui.h b/Project Reboot 3.0/gui.h index 184588f..7deb4f9 100644 --- a/Project Reboot 3.0/gui.h +++ b/Project Reboot 3.0/gui.h @@ -68,6 +68,7 @@ extern inline bool bDebugPrintSwapping = false; extern inline bool bEnableBotTick = false; extern inline bool bEnableCombinePickup = false; extern inline int AmountOfBotsToSpawn = 0; +extern inline bool bEnableRebooting = false; // THE BASE CODE IS FROM IMGUI GITHUB @@ -738,7 +739,8 @@ static inline void MainUI() } } - GameState->Get("WarmupCountdownEndTime") = UGameplayStatics::GetTimeSeconds(GetWorld()) + 10; + static auto WarmupCountdownEndTimeOffset = GameState->GetOffset("WarmupCountdownEndTime"); + GameState->Get(WarmupCountdownEndTimeOffset) = UGameplayStatics::GetTimeSeconds(GetWorld()) + 10; } } } diff --git a/Project Reboot 3.0/hooking.h b/Project Reboot 3.0/hooking.h index 79694e4..0f7c196 100644 --- a/Project Reboot 3.0/hooking.h +++ b/Project Reboot 3.0/hooking.h @@ -18,6 +18,17 @@ struct FunctionHooks static inline std::vector AllFunctionHooks; +inline void PatchBytes(uint64 addr, const std::vector& Bytes) +{ + if (!addr) + return; + + for (int i = 0; i < Bytes.size(); i++) + { + *(uint8_t*)(addr + i) = Bytes.at(i); + } +} + inline __int64 GetFunctionIdxOrPtr2(UFunction* Function) { auto NativeAddr = __int64(Function->GetFunc()); diff --git a/vendor/memcury.h b/vendor/memcury.h index 1727ec4..943f7b4 100644 --- a/vendor/memcury.h +++ b/vendor/memcury.h @@ -1437,4 +1437,5 @@ // return true; return *(uint8_t*)(Addr) == 0xC3 || *(uint8_t*)(Addr) == 0xC2; - } \ No newline at end of file + } +