diff --git a/.github/workflows/aboveS20.yml b/.github/workflows/aboveS20.yml index f539085..8c0aa4b 100644 --- a/.github/workflows/aboveS20.yml +++ b/.github/workflows/aboveS20.yml @@ -8,7 +8,7 @@ on: permissions: contents: write -jobs: +jobs: update-branches: runs-on: ubuntu-latest steps: diff --git a/.github/workflows/msbuild.yml b/.github/workflows/msbuild.yml index def27c9..2a3b4ef 100644 --- a/.github/workflows/msbuild.yml +++ b/.github/workflows/msbuild.yml @@ -1,19 +1,13 @@ name: MSBuild on: - workflow_call: - inputs: - branch: - required: true - type: string + push: + branches: ["master"] + pull_request: + branches: ["master"] env: - # Path to the solution file relative to the root of the project. SOLUTION_FILE_PATH: . - - # Configuration type to build. - # You can convert this to a build matrix if you need coverage of multiple configuration types. - # https://docs.github.com/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix BUILD_CONFIGURATION: Release permissions: @@ -24,27 +18,35 @@ jobs: runs-on: windows-latest steps: - - uses: actions/checkout@v3 - with: - ref: ${{ inputs.branch }} + - uses: actions/checkout@v3 - - name: Add MSBuild to PATH - uses: microsoft/setup-msbuild@v1.0.2 + - name: Add MSBuild to PATH + uses: microsoft/setup-msbuild@v1.0.2 - - name: Restore NuGet packages - working-directory: ${{env.GITHUB_WORKSPACE}} - run: nuget restore ${{env.SOLUTION_FILE_PATH}} + - name: Restore NuGet packages + working-directory: ${{env.GITHUB_WORKSPACE}} + run: nuget restore ${{env.SOLUTION_FILE_PATH}} - - name: Build - working-directory: ${{env.GITHUB_WORKSPACE}} - # Add additional options to the MSBuild command line here (like platform or verbosity level). - # See https://docs.microsoft.com/visualstudio/msbuild/msbuild-command-line-reference - run: msbuild /m /p:Configuration=${{env.BUILD_CONFIGURATION}} ${{env.SOLUTION_FILE_PATH}} + - name: Build Reboot + working-directory: ${{env.GITHUB_WORKSPACE}} + run: msbuild ${{env.SOLUTION_FILE_PATH}} /t:Clean,Build /p:Configuration=Release - - name: Upload Release Artifact - uses: actions/upload-artifact@v3 - with: - name: Release - path: ${{env.SOLUTION_FILE_PATH}}/x64/Release - if-no-files-found: warn - retention-days: 60 + - name: Upload Artifact without ABOVE_S20 + uses: actions/upload-artifact@v4 + with: + name: Reboot + path: ${{env.SOLUTION_FILE_PATH}}/x64/Release + if-no-files-found: warn + retention-days: 90 + + - name: Build RebootS20 + working-directory: ${{env.GITHUB_WORKSPACE}} + run: msbuild ${{env.SOLUTION_FILE_PATH}} /p:AboveS20=TRUE /t:Clean,Build /p:Configuration=Release + + - name: Upload Artifact with ABOVE_S20 + uses: actions/upload-artifact@v4 + with: + name: RebootS20 + path: ${{env.SOLUTION_FILE_PATH}}/x64/Release + if-no-files-found: warn + retention-days: 90 diff --git a/Project Reboot 3.0/BuildingSMActor.h b/Project Reboot 3.0/BuildingSMActor.h index 7b52424..bcff2be 100644 --- a/Project Reboot 3.0/BuildingSMActor.h +++ b/Project Reboot 3.0/BuildingSMActor.h @@ -55,7 +55,7 @@ public: ) { SetNetDormancy((ENetDormancy)(2 - (NewEditingPlayer != 0))); - this->ForceNetUpdate(); + // they do something here GetEditingPlayer() = NewEditingPlayer; } } diff --git a/Project Reboot 3.0/BuildingWeapons.h b/Project Reboot 3.0/BuildingWeapons.h index 506b3e1..561582f 100644 --- a/Project Reboot 3.0/BuildingWeapons.h +++ b/Project Reboot 3.0/BuildingWeapons.h @@ -24,14 +24,5 @@ public: void OnRep_EditActor(); - void SetEditActor(ABuildingSMActor* EditActor) - { - // if (HasAuthority()) - { - GetEditActor() = EditActor; - originalOnRep_EditActor(this); - } - } - static UClass* StaticClass(); }; \ No newline at end of file diff --git a/Project Reboot 3.0/FortAthenaMutator_InventoryOverride.h b/Project Reboot 3.0/FortAthenaMutator_InventoryOverride.h index 3d128bf..3647bdf 100644 --- a/Project Reboot 3.0/FortAthenaMutator_InventoryOverride.h +++ b/Project Reboot 3.0/FortAthenaMutator_InventoryOverride.h @@ -61,7 +61,7 @@ public: if (!TeamLoadouts) return FItemLoadoutTeamMap(); - for (int i = 0; i < TeamLoadouts->Num(); i++) + for (int i = 0; i < TeamLoadouts->Num(); ++i) { auto& TeamLoadout = TeamLoadouts->at(i); @@ -106,7 +106,7 @@ public: return Get(InventoryUpdateOverrideOffset); } - EAthenaLootDropOverride& GetDropAllItemsOverride(uint8_t TeamIndex = 255) + EAthenaLootDropOverride GetDropAllItemsOverride(uint8_t TeamIndex = 255) { if (TeamIndex != 255) { diff --git a/Project Reboot 3.0/FortGameModeAthena.cpp b/Project Reboot 3.0/FortGameModeAthena.cpp index f6ad6f4..42000f9 100644 --- a/Project Reboot 3.0/FortGameModeAthena.cpp +++ b/Project Reboot 3.0/FortGameModeAthena.cpp @@ -1314,6 +1314,18 @@ void AFortGameModeAthena::Athena_HandleStartingNewPlayerHook(AFortGameModeAthena { OverrideBattleBusSkin = FindObject(L"/Game/Athena/Items/Cosmetics/BattleBuses/BBID_WorldCupBus.BBID_WorldCupBus"); // World Cup } + else if (Fortnite_Version == 14.30) + { + OverrideBattleBusSkin = FindObject(L"/Game/Athena/Items/Cosmetics/BattleBuses/BBID_BusUpgrade1.BBID_BusUpgrade1"); + } + else if (Fortnite_Version == 14.50) + { + OverrideBattleBusSkin = FindObject(L"/Game/Athena/Items/Cosmetics/BattleBuses/BBID_BusUpgrade2.BBID_BusUpgrade2"); + } + else if (Fortnite_Version == 14.60) + { + OverrideBattleBusSkin = FindObject(L"/Game/Athena/Items/Cosmetics/BattleBuses/BBID_BusUpgrade3.BBID_BusUpgrade3"); + } if (OverrideBattleBusSkin) OverrideBattleBus(GameState, OverrideBattleBusSkin); diff --git a/Project Reboot 3.0/FortInventory.cpp b/Project Reboot 3.0/FortInventory.cpp index f18fe37..512073b 100644 --- a/Project Reboot 3.0/FortInventory.cpp +++ b/Project Reboot 3.0/FortInventory.cpp @@ -382,6 +382,32 @@ bool AFortInventory::RemoveItem(const FGuid& ItemGuid, bool* bShouldUpdate, int } } + /* + if (FortPlayerController) + { + if (auto Pawn = FortPlayerController->GetMyFortPawn()) + { + static auto CurrentWeaponListOffset = Pawn->GetOffset("CurrentWeaponList"); + + if (CurrentWeaponListOffset != -1) // shouldnt be possible but better safe than sorry! + { + auto& CurrentWeaponList = Pawn->Get>(CurrentWeaponListOffset); + + for (int i = 0; i < CurrentWeaponList.Num(); ++i) + { + auto Weapon = CurrentWeaponList.At(i); + + if (Weapon->GetItemEntryGuid() == ItemGuid) + { + Weapon->K2_DestroyActor(); + break; + } + } + } + } + } + */ + // todo remove from weaponlist if (bShouldUpdate) diff --git a/Project Reboot 3.0/FortPawn.cpp b/Project Reboot 3.0/FortPawn.cpp index f8aabe1..f1691e1 100644 --- a/Project Reboot 3.0/FortPawn.cpp +++ b/Project Reboot 3.0/FortPawn.cpp @@ -94,6 +94,14 @@ void AFortPawn::SetShield(float NewShield) this->ProcessEvent(SetShieldFn, &NewShield); } +void AFortPawn::SetMaxShield(float NewShieldVal) +{ + static auto SetMaxShieldFn = FindObject("/Script/FortniteGame.FortPawn.SetMaxShield"); + + if (SetMaxShieldFn) + this->ProcessEvent(SetMaxShieldFn, &NewShieldVal); +} + void AFortPawn::NetMulticast_Athena_BatchedDamageCuesHook(UObject* Context, FFrame* Stack, void* Ret) { auto Pawn = (AFortPawn*)Context; diff --git a/Project Reboot 3.0/FortPawn.h b/Project Reboot 3.0/FortPawn.h index 0089f36..25c6ea7 100644 --- a/Project Reboot 3.0/FortPawn.h +++ b/Project Reboot 3.0/FortPawn.h @@ -49,6 +49,7 @@ public: void SetHealth(float NewHealth); void SetMaxHealth(float NewHealthVal); void SetShield(float NewShield); + void SetMaxShield(float NewShieldVal); static void NetMulticast_Athena_BatchedDamageCuesHook(UObject* Context, FFrame* Stack, void* Ret); static void MovingEmoteStoppedHook(UObject* Context, FFrame* Stack, void* Ret); diff --git a/Project Reboot 3.0/FortPlayerController.cpp b/Project Reboot 3.0/FortPlayerController.cpp index fc3c240..ee68edf 100644 --- a/Project Reboot 3.0/FortPlayerController.cpp +++ b/Project Reboot 3.0/FortPlayerController.cpp @@ -1672,39 +1672,6 @@ void AFortPlayerController::ClientOnPawnDiedHook(AFortPlayerController* PlayerCo return ClientOnPawnDiedOriginal(PlayerController, DeathReport); } -bool Idk(ABuildingSMActor* BuildingActor) -{ - return true; // bIsPlayerBuildable && EditModeSupport && EditModePatternData && GameState->StructuralSupportSystem && ?? && ?? -} - -bool IsOkForEditing(ABuildingSMActor* BuildingActor, AFortPlayerController* Controller) -{ - if (BuildingActor->GetEditingPlayer() && - BuildingActor->GetEditingPlayer() != Controller->GetPlayerState()) - return false; - - return !BuildingActor->IsDestroyed() && - // BuildingActor->GetWorld() && - Idk(BuildingActor); -} - -/* - -The editing dilemma: - -15.10: -Valid edit pattern: -ServerBeginEditingActorblahblah -ServerEdit -ClientForceStop - -WHERE IS END EDITING?!?!??! -Invalid EDitPattern: -ServerBeginEditingActorblahblah -ServerEnd - -*/ - void AFortPlayerController::ServerBeginEditingBuildingActorHook(AFortPlayerController* PlayerController, ABuildingSMActor* BuildingActorToEdit) { if (!BuildingActorToEdit || !BuildingActorToEdit->IsPlayerPlaced()) // We need more checks. @@ -1715,9 +1682,6 @@ void AFortPlayerController::ServerBeginEditingBuildingActorHook(AFortPlayerContr if (!Pawn) return; - if (!IsOkForEditing(BuildingActorToEdit, PlayerController)) - return; - auto PlayerState = PlayerController->GetPlayerState(); if (!PlayerState) @@ -1737,14 +1701,15 @@ void AFortPlayerController::ServerBeginEditingBuildingActorHook(AFortPlayerContr if (!EditToolInstance) return; - AFortWeap_EditingTool* EditTool = nullptr; + Pawn->EquipWeaponDefinition(EditToolDef, EditToolInstance->GetItemEntry()->GetItemGuid()); - EditTool = Cast(Pawn->EquipWeaponDefinition(EditToolDef, EditToolInstance->GetItemEntry()->GetItemGuid())); + auto EditTool = Cast(Pawn->GetCurrentWeapon()); if (!EditTool) return; - EditTool->SetEditActor(BuildingActorToEdit); + EditTool->GetEditActor() = BuildingActorToEdit; + EditTool->OnRep_EditActor(); } void AFortPlayerController::ServerEditBuildingActorHook(UObject* Context, FFrame& Stack, void* Ret) @@ -1767,7 +1732,7 @@ void AFortPlayerController::ServerEditBuildingActorHook(UObject* Context, FFrame // LOG_INFO(LogDev, "RotationIterations: {}", RotationIterations); - if (!BuildingActorToEdit || !NewBuildingClass || BuildingActorToEdit->GetEditingPlayer() != PlayerState || BuildingActorToEdit->IsDestroyed()) + if (!BuildingActorToEdit || !NewBuildingClass || BuildingActorToEdit->IsDestroyed() || BuildingActorToEdit->GetEditingPlayer() != PlayerState) { // LOG_INFO(LogDev, "Cheater?"); // LOG_INFO(LogDev, "BuildingActorToEdit->GetEditingPlayer(): {} PlayerState: {} NewBuildingClass: {} BuildingActorToEdit: {}", BuildingActorToEdit ? __int64(BuildingActorToEdit->GetEditingPlayer()) : -1, __int64(PlayerState), __int64(NewBuildingClass), __int64(BuildingActorToEdit)); @@ -1777,7 +1742,7 @@ void AFortPlayerController::ServerEditBuildingActorHook(UObject* Context, FFrame // if (!PlayerState || PlayerState->GetTeamIndex() != BuildingActorToEdit->GetTeamIndex()) //return ServerEditBuildingActorOriginal(Context, Frame, Ret); - // BuildingActorToEdit->SetEditingPlayer(nullptr); // uh? + BuildingActorToEdit->SetEditingPlayer(nullptr); static ABuildingSMActor* (*BuildingSMActorReplaceBuildingActor)(ABuildingSMActor*, __int64, UClass*, int, int, uint8_t, AFortPlayerController*) = decltype(BuildingSMActorReplaceBuildingActor)(Addresses::ReplaceBuildingActor); @@ -1793,7 +1758,7 @@ void AFortPlayerController::ServerEditBuildingActorHook(UObject* Context, FFrame return ServerEditBuildingActorOriginal(Context, Stack, Ret); } -void AFortPlayerController::ServerEndEditingBuildingActorHook(AFortPlayerController* PlayerController, ABuildingSMActor* BuildingActorToStopEditing) +void AFortPlayerController::ServerEndEditingBuildingActorHook(AFortPlayerController* PlayerController, ABuildingSMActor* BuildingActorToStopEditing) { auto Pawn = PlayerController->GetMyFortPawn(); @@ -1816,13 +1781,16 @@ void AFortPlayerController::ServerEndEditingBuildingActorHook(AFortPlayerControl if (!EditToolInstance) return; - // Pawn->EquipWeaponDefinition(EditToolDef, EditToolInstance->GetItemEntry()->GetItemGuid()); // why do they do this on older builds bru + Pawn->EquipWeaponDefinition(EditToolDef, EditToolInstance->GetItemEntry()->GetItemGuid()); - if (auto EditTool = Cast(Pawn->GetCurrentWeapon())) + auto EditTool = Cast(Pawn->GetCurrentWeapon()); + + BuildingActorToStopEditing->GetEditingPlayer() = nullptr; + // BuildingActorToStopEditing->OnRep_EditingPlayer(); + + if (EditTool) { - EditTool->SetEditActor(nullptr); - // PlayerController->ClientForceCancelBuildingTool(); + EditTool->GetEditActor() = nullptr; + EditTool->OnRep_EditActor(); } - - // PlayerController->ClientForceCancelBuildingTool(); -} +} \ No newline at end of file diff --git a/Project Reboot 3.0/FortPlayerControllerAthena.cpp b/Project Reboot 3.0/FortPlayerControllerAthena.cpp index 389e85c..81a2f37 100644 --- a/Project Reboot 3.0/FortPlayerControllerAthena.cpp +++ b/Project Reboot 3.0/FortPlayerControllerAthena.cpp @@ -646,4 +646,60 @@ void AFortPlayerControllerAthena::UpdateTrackedAttributesHook(AFortPlayerControl if (ItemInstancesToRemove.size() > 0) WorldInventory->Update(); +} + +void AFortPlayerControllerAthena::ServerClientIsReadyToRespawnHook(AFortPlayerControllerAthena* PlayerControllerAthena) +{ + AFortPlayerStateAthena* PlayerStateAthena = Cast(PlayerControllerAthena->GetPlayerState()); + AFortGameModeAthena* GameModeAthena = Cast(GetWorld()->GetGameMode()); + + if (!PlayerStateAthena || !GameModeAthena) + return; + + AFortGameStateAthena* GameStateAthena = Cast(GameModeAthena->GetGameState()); + if (!GameStateAthena) return; + + if (GameStateAthena->IsRespawningAllowed(PlayerStateAthena)) + { + FFortRespawnData* RespawnData = PlayerStateAthena->GetRespawnData(); + + if (RespawnData->IsServerReady() && RespawnData->IsRespawnDataAvailable()) + { + const FVector& RespawnLocation = RespawnData->GetRespawnLocation(); + const FRotator& RespawnRotation = RespawnData->GetRespawnRotation(); + + // RestartPlayer doesn't work, idk why + static auto SpawnDefaultPawnAtTransformFn = FindObject(L"/Script/Engine.GameModeBase.SpawnDefaultPawnAtTransform"); + + FTransform SpawnTransform{}; + SpawnTransform.Translation = RespawnLocation; + SpawnTransform.Rotation = RespawnRotation.Quaternion(); + SpawnTransform.Scale3D = FVector(1, 1, 1); + + struct { AController* NewPlayer; FTransform SpawnTransform; APawn* ReturnValue; } + AGameModeBase_SpawnDefaultPawnAtTransform_Params{ PlayerControllerAthena, SpawnTransform }; + + GameModeAthena->ProcessEvent(SpawnDefaultPawnAtTransformFn, &AGameModeBase_SpawnDefaultPawnAtTransform_Params); + + AFortPlayerPawn* PlayerPawn = Cast(AGameModeBase_SpawnDefaultPawnAtTransform_Params.ReturnValue); + + if (!PlayerPawn) + return; + + PlayerPawn->SetOwner(PlayerControllerAthena); + + PlayerControllerAthena->Possess(PlayerPawn); + + PlayerPawn->SetMaxHealth(100); + PlayerPawn->SetHealth(100); + PlayerPawn->SetMaxShield(100); + PlayerPawn->SetShield(100); + + PlayerControllerAthena->RespawnPlayerAfterDeath(true); + + RespawnData->IsClientReady() = true; + } + } + + printf_s(__FUNCTION__"\n"); } \ No newline at end of file diff --git a/Project Reboot 3.0/FortPlayerControllerAthena.h b/Project Reboot 3.0/FortPlayerControllerAthena.h index 1731069..44a7807 100644 --- a/Project Reboot 3.0/FortPlayerControllerAthena.h +++ b/Project Reboot 3.0/FortPlayerControllerAthena.h @@ -264,6 +264,7 @@ public: static void GetPlayerViewPointHook(AFortPlayerControllerAthena* PlayerController, FVector& Location, FRotator& Rotation); static void ServerReadyToStartMatchHook(AFortPlayerControllerAthena* PlayerController); static void UpdateTrackedAttributesHook(AFortPlayerControllerAthena* PlayerController); + static void ServerClientIsReadyToRespawnHook(AFortPlayerControllerAthena* PlayerControllerAthena); // 1:1 static UClass* StaticClass() { diff --git a/Project Reboot 3.0/FortPlayerStateAthena.h b/Project Reboot 3.0/FortPlayerStateAthena.h index 60867d9..e3fff72 100644 --- a/Project Reboot 3.0/FortPlayerStateAthena.h +++ b/Project Reboot 3.0/FortPlayerStateAthena.h @@ -30,6 +30,18 @@ struct FFortRespawnData static auto bServerIsReadyOffset = FindOffsetStruct("/Script/FortniteGame.FortRespawnData", "bServerIsReady"); return *(bool*)(__int64(this) + bServerIsReadyOffset); } + + FVector& GetRespawnLocation() + { + static auto RespawnLocationOffset = FindOffsetStruct("/Script/FortniteGame.FortRespawnData", "RespawnLocation"); + return *(FVector*)(__int64(this) + RespawnLocationOffset); + } + + FRotator& GetRespawnRotation() + { + static auto RespawnRotationOffset = FindOffsetStruct("/Script/FortniteGame.FortRespawnData", "RespawnRotation"); + return *(FRotator*)(__int64(this) + RespawnRotationOffset); + } }; struct FDeathInfo diff --git a/Project Reboot 3.0/Project Reboot 3.0.vcxproj b/Project Reboot 3.0/Project Reboot 3.0.vcxproj index d346fac..921d318 100644 --- a/Project Reboot 3.0/Project Reboot 3.0.vcxproj +++ b/Project Reboot 3.0/Project Reboot 3.0.vcxproj @@ -78,6 +78,7 @@ Level3 true WIN32;_DEBUG;PROJECTREBOOT30_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + ABOVE_S20;%(PreprocessorDefinitions) true NotUsing pch.h @@ -100,6 +101,7 @@ true true WIN32;NDEBUG;PROJECTREBOOT30_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + ABOVE_S20;%(PreprocessorDefinitions) true NotUsing pch.h @@ -124,6 +126,7 @@ Level3 true _DEBUG;PROJECTREBOOT30_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + ABOVE_S20;%(PreprocessorDefinitions) true NotUsing pch.h @@ -146,6 +149,7 @@ true true NDEBUG;PROJECTREBOOT30_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + ABOVE_S20=$(AboveS20);%(PreprocessorDefinitions) true NotUsing pch.h @@ -513,4 +517,4 @@ - \ No newline at end of file + diff --git a/Project Reboot 3.0/SavePackage.cpp b/Project Reboot 3.0/SavePackage.cpp index 968f5ff..589e279 100644 --- a/Project Reboot 3.0/SavePackage.cpp +++ b/Project Reboot 3.0/SavePackage.cpp @@ -4,6 +4,6 @@ UClass* UPackage::StaticClass() { - static auto Class = FindObject("/Script/CoreUObject.Package"); + static auto Class = FindObject(L"/Script/CoreUObject.Package"); return Class; -} \ No newline at end of file +} diff --git a/Project Reboot 3.0/addresses.cpp b/Project Reboot 3.0/addresses.cpp index bd92d98..1ade2d1 100644 --- a/Project Reboot 3.0/addresses.cpp +++ b/Project Reboot 3.0/addresses.cpp @@ -678,6 +678,25 @@ std::vector Addresses::GetFunctionsToNull() } } +#if 0 // untested + auto BeginPlayPedestalStrRef = Memcury::Scanner::FindStringRef("AFortTeamMemberPedestal::BeginPlay - Begun play on pedestal %s"); + + if (BeginPlayPedestalStrRef.Get()) + { + auto Start = BeginPlayPedestalStrRef.ScanFor({ 0x40, 0x53, 0x41, 0x56 }, false); + LOG_INFO(LogDev, "BeginPlayPedestal Start: 0x{:x}", Start); + toNull.push_back(Start.Get()); + } +#else + auto BeginPlayPedestalScanner = Memcury::Scanner::FindPattern("40 53 41 56 48 83 EC 48 48 89 6C 24 ? 48 8B D9 48 89 74 24 ? 48 89 7C 24"); + + if (auto BeginPlayPedestal = BeginPlayPedestalScanner.Get()) + { + LOG_INFO(LogDev, "BeginPlayPedestal Start: 0x{:x}", BeginPlayPedestal - __int64(GetModuleHandleW(0))); + toNull.push_back(BeginPlayPedestal); + } +#endif + toNull.push_back(Addresses::ChangeGameSessionId); return toNull; diff --git a/Project Reboot 3.0/bots.h b/Project Reboot 3.0/bots.h index e2e9ad2..7637329 100644 --- a/Project Reboot 3.0/bots.h +++ b/Project Reboot 3.0/bots.h @@ -323,8 +323,11 @@ public: PickRandomLoadout(); ApplyCosmeticLoadout(); - GameState->GetPlayersLeft()++; - GameState->OnRep_PlayersLeft(); + if (Fortnite_Version <= 10) + { + GameState->GetPlayersLeft()++; + GameState->OnRep_PlayersLeft(); + } if (auto FortPlayerControllerAthena = Cast(Controller)) GameMode->GetAlivePlayers().Add(FortPlayerControllerAthena); diff --git a/Project Reboot 3.0/dllmain.cpp b/Project Reboot 3.0/dllmain.cpp index 82f2f26..03f51e2 100644 --- a/Project Reboot 3.0/dllmain.cpp +++ b/Project Reboot 3.0/dllmain.cpp @@ -1285,6 +1285,13 @@ DWORD WINAPI Main(LPVOID) Hooking::MinHook::Hook(FortPlayerControllerAthenaDefault, FindObject(L"/Script/FortniteGame.FortPlayerController.ServerReadyToStartMatch"), AFortPlayerControllerAthena::ServerReadyToStartMatchHook, (PVOID*)&AFortPlayerControllerAthena::ServerReadyToStartMatchOriginal, false); + if (Fortnite_Version >= 14) + { + Hooking::MinHook::Hook(FortPlayerControllerAthenaDefault, FindObject(L"/Script/FortniteGame.FortPlayerControllerAthena.ServerClientIsReadyToRespawn"), + AFortPlayerControllerAthena::ServerClientIsReadyToRespawnHook, nullptr, false); + } + + auto ServerRequestSeatChangeFn = FindObject(L"/Script/FortniteGame.FortPlayerControllerZone.ServerRequestSeatChange"); if (ServerRequestSeatChangeFn) diff --git a/Project Reboot 3.0/reboot.h b/Project Reboot 3.0/reboot.h index d7cbaf1..b862778 100644 --- a/Project Reboot 3.0/reboot.h +++ b/Project Reboot 3.0/reboot.h @@ -86,6 +86,8 @@ static inline class UWorld* GetWorld() static auto GameViewportOffset = Engine->GetOffset("GameViewport"); auto GameViewport = Engine->Get(GameViewportOffset); + if (!GameViewport) return nullptr; + static auto WorldOffset = GameViewport->GetOffset("World"); return GameViewport->Get(WorldOffset); diff --git a/README.md b/README.md index 9a167bb..83c1d3d 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ ![image](https://github.com/user-attachments/assets/5704e635-31d9-417a-856f-91728f2be7f2) # The reboot discord and my discord account has been terminated -# What does this mean for the future of reboot? This means V4 is definitely not coming. +# New discord at discord.gg/rebootmp # Thanks for all the support over the past years. ![Banner](https://i.imgur.com/p0P4tcI.png)