diff --git a/Project Reboot 3.0/FortGameMode.cpp b/Project Reboot 3.0/FortGameMode.cpp new file mode 100644 index 0000000..69cbf7e --- /dev/null +++ b/Project Reboot 3.0/FortGameMode.cpp @@ -0,0 +1,19 @@ +#include "FortGameMode.h" + +void AFortGameMode::SetCurrentPlaylistName(UObject* Playlist) // Techinally it takes in a fname +{ + if (!Playlist) + { + LOG_WARN(LogGame, "AFortGameMode::SetCurrentPlaylistName: Invalid playlist."); + return; + } + + static auto PlaylistNameOffset = Playlist->GetOffset("PlaylistName"); + static auto PlaylistIdOffset = Playlist->GetOffset("PlaylistId"); + + static auto CurrentPlaylistNameOffset = GetOffset("CurrentPlaylistName"); + static auto CurrentPlaylistIdOffset = GetOffset("CurrentPlaylistId"); + + Get(CurrentPlaylistNameOffset) = Playlist->Get(PlaylistNameOffset); + Get(CurrentPlaylistIdOffset) = Playlist->Get(PlaylistIdOffset); +} \ No newline at end of file diff --git a/Project Reboot 3.0/FortGameMode.h b/Project Reboot 3.0/FortGameMode.h index 5561af0..6cf34b5 100644 --- a/Project Reboot 3.0/FortGameMode.h +++ b/Project Reboot 3.0/FortGameMode.h @@ -5,4 +5,5 @@ class AFortGameMode : public AGameMode { public: + void SetCurrentPlaylistName(UObject* Playlist); // Techinally it takes in a fname }; \ No newline at end of file diff --git a/Project Reboot 3.0/FortGameModeAthena.cpp b/Project Reboot 3.0/FortGameModeAthena.cpp index 9d6f340..8d119b7 100644 --- a/Project Reboot 3.0/FortGameModeAthena.cpp +++ b/Project Reboot 3.0/FortGameModeAthena.cpp @@ -158,7 +158,7 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game { auto GameState = GameMode->GetGameStateAthena(); - auto SetPlaylist = [&GameState](UObject* Playlist) -> void { + auto SetPlaylist = [&GameState, &GameMode](UObject* Playlist, bool bOnRep) -> void { if (Fortnite_Version >= 6.10) { auto CurrentPlaylistInfo = GameState->GetPtr("CurrentPlaylistInfo"); @@ -177,6 +177,8 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game if (aeuh) { + GameMode->SetCurrentPlaylistName(aeuh); + /* if (Fortnite_Version >= 13) { static auto LastSafeZoneIndexOffset = aeuh->GetOffset("LastSafeZoneIndex"); @@ -187,14 +189,14 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game } } */ } - - GameState->OnRep_CurrentPlaylistInfo(); } else { GameState->Get("CurrentPlaylistData") = Playlist; - GameState->OnRep_CurrentPlaylistInfo(); // calls OnRep_CurrentPlaylistData } + + if (bOnRep) + GameState->OnRep_CurrentPlaylistInfo(); }; auto& LocalPlayers = GetLocalPlayers(); @@ -212,22 +214,20 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game LOG_INFO(LogDev, "Presetup!"); - GameMode->Get("WarmupRequiredPlayerCount") = 1; + GameMode->Get("WarmupRequiredPlayerCount") = 1; - { - auto PlaylistToUse = GetPlaylistToUse(); + auto PlaylistToUse = GetPlaylistToUse(); - if (!PlaylistToUse) - { - LOG_ERROR(LogPlaylist, "Failed to find playlist! Proceeding, but will probably not work as expected!"); - } - else - { - SetPlaylist(PlaylistToUse); - LOG_INFO(LogDev, "Set playlist!"); - } + if (!PlaylistToUse) + { + LOG_ERROR(LogPlaylist, "Failed to find playlist! Proceeding, but will probably not work as expected!"); } - + else + { + SetPlaylist(PlaylistToUse, true); + LOG_INFO(LogDev, "Set playlist!"); + } + // if (false) { auto Fortnite_Season = std::floor(Fortnite_Version); @@ -472,6 +472,12 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game GameState->Get("WarmupCountdownStartTime") = TimeSeconds; GameMode->Get("WarmupEarlyCountdownDuration") = EarlyDuration; + static auto GameSessionOffset = GameMode->GetOffset("GameSession"); + auto GameSession = GameMode->Get(GameSessionOffset); + static auto MaxPlayersOffset = GameSession->GetOffset("MaxPlayers"); + + GameSession->Get(MaxPlayersOffset) = 100; + /* auto AllMegaStormManagers = UGameplayStatics::GetAllActorsOfClass(GetWorld(), GameMode->Get("MegaStormManagerClass")); @@ -523,14 +529,19 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game if (Engine_Version >= 424) // returning true is stripped on c2+ { - if (GameState->GetPlayersLeft() >= GameMode->Get("WarmupRequiredPlayerCount")) + static auto WarmupRequiredPlayerCountOffset = GameMode->GetOffset("WarmupRequiredPlayerCount"); + + if (GameState->GetPlayersLeft() >= GameMode->Get(WarmupRequiredPlayerCountOffset)) { if (MapInfo) { static auto FlightInfosOffset = MapInfo->GetOffset("FlightInfos"); - if (MapInfo->Get>(FlightInfosOffset).ArrayNum <= 0) + // if (MapInfo->Get>(FlightInfosOffset).ArrayNum > 0) + { + LOG_INFO(LogDev, "ReadyToStartMatch Return Address: 0x{:x}", __int64(_ReturnAddress()) - __int64(GetModuleHandleW(0))); return true; + } } } } @@ -571,7 +582,7 @@ void AFortGameModeAthena::Athena_HandleStartingNewPlayerHook(AFortGameModeAthena // GameState->OnRep_CurrentPlaylistInfo(); } - static bool bSpawnedFloorLoot = true; + static bool bSpawnedFloorLoot = false; if (!bSpawnedFloorLoot) { diff --git a/Project Reboot 3.0/FortInventory.cpp b/Project Reboot 3.0/FortInventory.cpp index d95a109..43c0dac 100644 --- a/Project Reboot 3.0/FortInventory.cpp +++ b/Project Reboot 3.0/FortInventory.cpp @@ -32,7 +32,7 @@ std::pair, std::vector> AFortInventory::AddI auto MaxStackSize = ItemDefinition->GetMaxStackSize(); - bool bAllowMultipleStacks = true; + bool bAllowMultipleStacks = ItemDefinition->DoesAllowMultipleStacks(); int OverStack = 0; std::vector NewItemInstances; diff --git a/Project Reboot 3.0/FortKismetLibrary.cpp b/Project Reboot 3.0/FortKismetLibrary.cpp index 1d65af2..518d817 100644 --- a/Project Reboot 3.0/FortKismetLibrary.cpp +++ b/Project Reboot 3.0/FortKismetLibrary.cpp @@ -160,7 +160,7 @@ void UFortKismetLibrary::K2_RemoveItemFromPlayerHook(UObject* Context, FFrame& S if (bShouldUpdate) WorldInventory->Update(); - LOG_INFO(LogDev, "Removed!"); + LOG_INFO(LogDev, "Removed {}!", AmountToRemove); return K2_RemoveItemFromPlayerOriginal(Context, Stack, Ret); } @@ -249,6 +249,54 @@ void UFortKismetLibrary::K2_RemoveFortItemFromPlayerHook(UObject* Context, FFram return K2_RemoveFortItemFromPlayerOriginal(Context, Stack, Ret); } +AFortPickup* UFortKismetLibrary::K2_SpawnPickupInWorldWithClassHook(UObject* Context, FFrame& Stack, AFortPickup** Ret) +{ + UObject* WorldContextObject; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) + UFortWorldItemDefinition* ItemDefinition; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) + UClass* PickupClass; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, UObjectWrapper, HasGetValueTypeHash, NativeAccessSpecifierPublic) + int NumberToSpawn; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) + FVector Position; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) + FVector Direction; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) + int OverrideMaxStackCount; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) + bool bToss; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) + bool bRandomRotation; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) + bool bBlockedFromAutoPickup; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) + int PickupInstigatorHandle; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) + EFortPickupSourceTypeFlag SourceType; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) + EFortPickupSpawnSource Source; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) + AFortPlayerController* OptionalOwnerPC; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) + bool bPickupOnlyRelevantToOwner; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) + + + Stack.Step(Stack.Object, &WorldContextObject); + Stack.Step(Stack.Object, &ItemDefinition); + Stack.Step(Stack.Object, &PickupClass); + Stack.Step(Stack.Object, &NumberToSpawn); + Stack.Step(Stack.Object, &Position); + Stack.Step(Stack.Object, &Direction); + Stack.Step(Stack.Object, &OverrideMaxStackCount); + Stack.Step(Stack.Object, &bToss); + Stack.Step(Stack.Object, &bRandomRotation); + Stack.Step(Stack.Object, &bBlockedFromAutoPickup); + Stack.Step(Stack.Object, &PickupInstigatorHandle); + Stack.Step(Stack.Object, &SourceType); + Stack.Step(Stack.Object, &Source); + Stack.Step(Stack.Object, &OptionalOwnerPC); + Stack.Step(Stack.Object, &bPickupOnlyRelevantToOwner); + + if (!ItemDefinition) + return K2_SpawnPickupInWorldWithClassOriginal(Context, Stack, Ret); + + LOG_INFO(LogDev, "PickupClass: {}", PickupClass ? PickupClass->GetFullName() : "InvalidObject") + + auto aa = AFortPickup::SpawnPickup(ItemDefinition, Position, NumberToSpawn, SourceType, Source, -1, nullptr, PickupClass); + + K2_SpawnPickupInWorldWithClassOriginal(Context, Stack, Ret); + + *Ret = aa; + return *Ret; +} + AFortPickup* UFortKismetLibrary::K2_SpawnPickupInWorldHook(UObject* Context, FFrame& Stack, AFortPickup** Ret) { UObject* WorldContextObject; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) diff --git a/Project Reboot 3.0/FortKismetLibrary.h b/Project Reboot 3.0/FortKismetLibrary.h index ab34a1e..9d52620 100644 --- a/Project Reboot 3.0/FortKismetLibrary.h +++ b/Project Reboot 3.0/FortKismetLibrary.h @@ -19,6 +19,7 @@ public: static inline void (*K2_RemoveFortItemFromPlayerOriginal)(UObject* Context, FFrame& Stack, void* Ret); static inline AFortPickup* (*K2_SpawnPickupInWorldOriginal)(UObject* Context, FFrame& Stack, AFortPickup** Ret); static inline bool (*PickLootDropsOriginal)(UObject* Context, FFrame& Stack, bool* Ret); + static inline AFortPickup* (*K2_SpawnPickupInWorldWithClassOriginal)(UObject* Context, FFrame& Stack, AFortPickup** Ret); static UFortResourceItemDefinition* K2_GetResourceItemDefinition(EFortResourceType ResourceType); static void ApplyCharacterCosmetics(UObject* WorldContextObject, const TArray& CharacterParts, UObject* PlayerState, bool* bSuccess); @@ -29,6 +30,7 @@ public: static void K2_GiveItemToPlayerHook(UObject* Context, FFrame& Stack, void* Ret); static void K2_RemoveFortItemFromPlayerHook(UObject* Context, FFrame& Stack, void* Ret); static AFortPickup* K2_SpawnPickupInWorldHook(UObject* Context, FFrame& Stack, AFortPickup** Ret); + static AFortPickup* K2_SpawnPickupInWorldWithClassHook(UObject* Context, FFrame& Stack, AFortPickup** Ret); static bool PickLootDropsHook(UObject* Context, FFrame& Stack, bool* Ret); static UClass* StaticClass(); diff --git a/Project Reboot 3.0/FortLootPackage.cpp b/Project Reboot 3.0/FortLootPackage.cpp index 50431a7..cce2dca 100644 --- a/Project Reboot 3.0/FortLootPackage.cpp +++ b/Project Reboot 3.0/FortLootPackage.cpp @@ -77,6 +77,8 @@ static FFortLootPackageData* GetLootPackage2(std::vector& static FFortLootTierData* GetLootTierData(std::vector& LootTierData, bool bPrint) { + return GetLootTierData2(LootTierData, bPrint); + float TotalWeight = 0; for (auto Item : LootTierData) @@ -117,6 +119,8 @@ static FFortLootTierData* GetLootTierData(std::vector& LootT static FFortLootPackageData* GetLootPackage(std::vector& LootPackages) { + return GetLootPackage2(LootPackages); + float TotalWeight = 0; for (auto Item : LootPackages) diff --git a/Project Reboot 3.0/FortPawn.cpp b/Project Reboot 3.0/FortPawn.cpp index 32d7d76..af4ab9f 100644 --- a/Project Reboot 3.0/FortPawn.cpp +++ b/Project Reboot 3.0/FortPawn.cpp @@ -21,6 +21,22 @@ bool AFortPawn::PickUpActor(AActor* PickupTarget, UFortDecoItemDefinition* Place return AFortPawn_PickUpActor_Params.ReturnValue; } +void AFortPawn::SetHealth(float NewHealth) +{ + static auto SetHealthFn = FindObject("/Script/FortniteGame.FortPawn.SetHealth"); + + if (SetHealthFn) + this->ProcessEvent(SetHealthFn, &NewHealth); +} + +void AFortPawn::SetShield(float NewShield) +{ + static auto SetShieldFn = FindObject("/Script/FortniteGame.FortPawn.SetShield"); + + if (SetShieldFn) + this->ProcessEvent(SetShieldFn, &NewShield); +} + UClass* AFortPawn::StaticClass() { static auto Class = FindObject("/Script/FortniteGame.FortPawn"); diff --git a/Project Reboot 3.0/FortPawn.h b/Project Reboot 3.0/FortPawn.h index acf17a9..3f49553 100644 --- a/Project Reboot 3.0/FortPawn.h +++ b/Project Reboot 3.0/FortPawn.h @@ -24,5 +24,8 @@ public: return ReadBitfieldValue(bIsDBNOOffset, bIsDBNOFieldMask); } + void SetHealth(float NewHealth); + void SetShield(float NewShield); + static UClass* StaticClass(); }; \ No newline at end of file diff --git a/Project Reboot 3.0/FortPickup.cpp b/Project Reboot 3.0/FortPickup.cpp index 31c6944..98fbbd2 100644 --- a/Project Reboot 3.0/FortPickup.cpp +++ b/Project Reboot 3.0/FortPickup.cpp @@ -17,12 +17,12 @@ void AFortPickup::TossPickup(FVector FinalLocation, AFortPawn* ItemOwner, int Ov this->ProcessEvent(fn, &AFortPickup_TossPickup_Params); } -AFortPickup* AFortPickup::SpawnPickup(UFortItemDefinition* ItemDef, FVector Location, int Count, EFortPickupSourceTypeFlag PickupSource, EFortPickupSpawnSource SpawnSource, int LoadedAmmo, AFortPawn* Pawn) +AFortPickup* AFortPickup::SpawnPickup(UFortItemDefinition* ItemDef, FVector Location, int Count, EFortPickupSourceTypeFlag PickupSource, EFortPickupSpawnSource SpawnSource, int LoadedAmmo, AFortPawn* Pawn, UClass* OverrideClass) { static auto FortPickupClass = FindObject(L"/Script/FortniteGame.FortPickup"); auto PlayerState = Pawn ? Cast(Pawn->GetPlayerState()) : nullptr; - if (auto Pickup = GetWorld()->SpawnActor(FortPickupClass, Location)) + if (auto Pickup = GetWorld()->SpawnActor(OverrideClass ? OverrideClass : FortPickupClass, Location)) { static auto PawnWhoDroppedPickupOffset = Pickup->GetOffset("PawnWhoDroppedPickup"); diff --git a/Project Reboot 3.0/FortPickup.h b/Project Reboot 3.0/FortPickup.h index e559985..09f34d3 100644 --- a/Project Reboot 3.0/FortPickup.h +++ b/Project Reboot 3.0/FortPickup.h @@ -83,7 +83,7 @@ public: static AFortPickup* SpawnPickup(class UFortItemDefinition* ItemDef, FVector Location, int Count, EFortPickupSourceTypeFlag PickupSource = EFortPickupSourceTypeFlag::Other, EFortPickupSpawnSource SpawnSource = EFortPickupSpawnSource::Unset, - int LoadedAmmo = -1, class AFortPawn* Pawn = nullptr); + int LoadedAmmo = -1, class AFortPawn* Pawn = nullptr, UClass* OverrideClass = nullptr); static char CompletePickupAnimationHook(AFortPickup* Pickup); }; \ No newline at end of file diff --git a/Project Reboot 3.0/FortPlayerController.cpp b/Project Reboot 3.0/FortPlayerController.cpp index e8ac511..1c4df2b 100644 --- a/Project Reboot 3.0/FortPlayerController.cpp +++ b/Project Reboot 3.0/FortPlayerController.cpp @@ -16,6 +16,7 @@ #include "FortPickup.h" #include "FortPlayerPawn.h" #include +#include "KismetStringLibrary.h" void AFortPlayerController::ClientReportDamagedResourceBuilding(ABuildingSMActor* BuildingSMActor, EFortResourceType PotentialResourceType, int PotentialResourceCount, bool bDestroyed, bool bJustHitWeakspot) { @@ -133,6 +134,9 @@ void AFortPlayerController::ServerExecuteInventoryItemHook(AFortPlayerController void AFortPlayerController::ServerAttemptInteractHook(UObject* Context, FFrame* Stack, void* Ret) { + static auto LlamaClass = FindObject("/Game/Athena/SupplyDrops/Llama/AthenaSupplyDrop_Llama.AthenaSupplyDrop_Llama_C"); + static auto FortAthenaSupplyDropClass = FindObject("/Script/FortniteGame.FortAthenaSupplyDrop"); + LOG_INFO(LogInteraction, "ServerAttemptInteract!"); auto Params = Stack->Locals; @@ -157,6 +161,8 @@ void AFortPlayerController::ServerAttemptInteractHook(UObject* Context, FFrame* // LOG_INFO(LogInteraction, "ReceivingActor Name: {}", ReceivingActor->GetFullName()); + FVector LocationToSpawnLoot = ReceivingActor->GetActorLocation() + ReceivingActor->GetActorRightVector() * 70.f + FVector{ 0, 0, 50 }; + static auto FortAthenaVehicleClass = FindObject("/Script/FortniteGame.FortAthenaVehicle"); if (auto BuildingContainer = Cast(ReceivingActor)) @@ -188,8 +194,6 @@ void AFortPlayerController::ServerAttemptInteractHook(UObject* Context, FFrame* LOG_INFO(LogInteraction, "LootDrops.size(): {}", LootDrops.size()); - FVector LocationToSpawnLoot = BuildingContainer->GetActorLocation() + BuildingContainer->GetActorRightVector() * 70.f + FVector{0, 0, 50}; - for (int i = 0; i < LootDrops.size(); i++) { auto& lootDrop = LootDrops.at(i); @@ -273,6 +277,17 @@ void AFortPlayerController::ServerAttemptInteractHook(UObject* Context, FFrame* return; } + else if (ReceivingActor->IsA(FortAthenaSupplyDropClass)) + { + auto LootTierGroup = ReceivingActor->IsA(LlamaClass) ? UKismetStringLibrary::Conv_StringToName(L"Loot_AthenaLlama") : UKismetStringLibrary::Conv_StringToName(L"Loot_AthenaSupplyDrop"); // SupplyDrop->GetLootTierGroupOverride(); + + auto LootDrops = PickLootDrops(LootTierGroup); + + for (auto& LootDrop : LootDrops) + { + AFortPickup::SpawnPickup(LootDrop.ItemDefinition, LocationToSpawnLoot, LootDrop.Count, EFortPickupSourceTypeFlag::Other, EFortPickupSpawnSource::SupplyDrop); + } + } return ServerAttemptInteractOriginal(Context, Stack, Ret); } @@ -304,6 +319,11 @@ void AFortPlayerController::ServerAttemptAircraftJumpHook(AFortPlayerController* auto NewPawn = GameMode->SpawnDefaultPawnForHook(GameMode, (AController*)PlayerController, Aircrafts->at(0)); PlayerController->Possess(NewPawn); + auto NewPawnAsFort = Cast(NewPawn); + + if (NewPawnAsFort) + NewPawnAsFort->SetHealth(100); + // PlayerController->ServerRestartPlayer(); } @@ -437,6 +457,35 @@ void AFortPlayerController::ServerCreateBuildingActorHook(UObject* Context, FFra return ServerCreateBuildingActorOriginal(Context, Stack, Ret); } +void AFortPlayerController::DropSpecificItemHook(UObject* Context, FFrame& Stack, void* Ret) +{ + UFortItemDefinition* DropItemDef = nullptr; + + Stack.Step(Stack.Object, &DropItemDef); + + if (!DropItemDef) + return; + + auto PlayerController = Cast(Context); + + if (!PlayerController) + return DropSpecificItemOriginal(Context, Stack, Ret); + + auto WorldInventory = PlayerController->GetWorldInventory(); + + if (!WorldInventory) + return DropSpecificItemOriginal(Context, Stack, Ret); + + auto ItemInstance = WorldInventory->FindItemInstance(DropItemDef); + + if (!ItemInstance) + return DropSpecificItemOriginal(Context, Stack, Ret); + + PlayerController->ServerAttemptInventoryDropHook(PlayerController, ItemInstance->GetItemEntry()->GetItemGuid(), ItemInstance->GetItemEntry()->GetCount()); + + return DropSpecificItemOriginal(Context, Stack, Ret); +} + void AFortPlayerController::ServerAttemptInventoryDropHook(AFortPlayerController* PlayerController, FGuid ItemGuid, int Count) { LOG_INFO(LogDev, "ServerAttemptInventoryDropHook!"); @@ -625,6 +674,12 @@ void AFortPlayerController::ClientOnPawnDiedHook(AFortPlayerController* PlayerCo // KillerPlayerState->OnRep_Kills(); } + if (KillerPawn && KillerPawn != DeadPawn) + { + KillerPawn->SetHealth(100); + KillerPawn->SetShield(100); + } + bool bIsRespawningAllowed = GameState->IsRespawningAllowed(DeadPlayerState); if (!bIsRespawningAllowed) diff --git a/Project Reboot 3.0/FortPlayerController.h b/Project Reboot 3.0/FortPlayerController.h index c42c373..29fee4a 100644 --- a/Project Reboot 3.0/FortPlayerController.h +++ b/Project Reboot 3.0/FortPlayerController.h @@ -29,6 +29,7 @@ public: static inline void (*ClientOnPawnDiedOriginal)(AFortPlayerController* PlayerController, void* DeathReport); static inline void (*ServerCreateBuildingActorOriginal)(UObject* Context, FFrame* Stack, void* Ret); static inline void (*ServerAttemptInteractOriginal)(UObject* Context, FFrame* Stack, void* Ret); + static inline void (*DropSpecificItemOriginal)(UObject* Context, FFrame& Stack, void* Ret); void ClientReportDamagedResourceBuilding(ABuildingSMActor* BuildingSMActor, EFortResourceType PotentialResourceType, int PotentialResourceCount, bool bDestroyed, bool bJustHitWeakspot); @@ -65,6 +66,7 @@ public: static void ServerAttemptAircraftJumpHook(AFortPlayerController* PC, FRotator ClientRotation); // static void ServerCreateBuildingActorHook(AFortPlayerController* PlayerController, FCreateBuildingActorData CreateBuildingData); static void ServerCreateBuildingActorHook(UObject* Context, FFrame* Stack, void* Ret); + static void DropSpecificItemHook(UObject* Context, FFrame& Stack, void* Ret); static void ServerDropAllItemsHook(AFortPlayerController* PlayerController, UFortItemDefinition* IgnoreItemDef); diff --git a/Project Reboot 3.0/FortPlayerPawn.cpp b/Project Reboot 3.0/FortPlayerPawn.cpp index 22372db..1963a31 100644 --- a/Project Reboot 3.0/FortPlayerPawn.cpp +++ b/Project Reboot 3.0/FortPlayerPawn.cpp @@ -24,68 +24,15 @@ void AFortPlayerPawn::ServerSendZiplineStateHook(AFortPlayerPawn* Pawn, FZipline if (*(int*)(__int64(&InZiplineState) + AuthoritativeValueOffset) > *(int*)(__int64(PawnZiplineState) + AuthoritativeValueOffset)) { - static auto ZiplinePawnStateClass = FindObject("/Script/FortniteGame.ZiplinePawnState"); - static auto ZiplinePawnStateSize = ZiplinePawnStateClass->GetPropertiesSize(); + static auto ZiplinePawnStateStruct = FindObject("/Script/FortniteGame.ZiplinePawnState"); + static auto ZiplinePawnStateSize = ZiplinePawnStateStruct->GetPropertiesSize(); CopyStruct(PawnZiplineState, &InZiplineState, ZiplinePawnStateSize); } static bool bFoundFunc = false; - static void (*OnRep_ZiplineState)(AFortPlayerPawn* Pawn); - - if (!bFoundFunc) - { - bFoundFunc = true; - - static auto Addrr = Memcury::Scanner::FindStringRef(L"ZIPLINES!! Role(%s) AFortPlayerPawn::OnRep_ZiplineState ZiplineState.bIsZiplining=%d", false).Get(); - - if (!Addrr) - Addrr = Memcury::Scanner::FindStringRef(L"ZIPLINES!! GetLocalRole()(%s) AFortPlayerPawn::OnRep_ZiplineState ZiplineState.bIsZiplining=%d").Get(); - - // L"%s LocalRole[%s] ZiplineState.bIsZiplining[%d]" for 18.40??? - - // std::cout << "Addrr: " << Addrr << '\n'; - - if (Addrr) - { - for (int i = 0; i < 400; i++) - { - // LOG_INFO(LogDev, "[{}] 0x{:x} 0x{:x}", i, (int)*(uint8_t*)Addrr - i, (int)*(uint8_t*)(Addrr - i + 1), (int)*(uint8_t*)(Addrr - i + 2)); - - if (*(uint8_t*)(uint8_t*)(Addrr - i) == 0x40 && *(uint8_t*)(uint8_t*)(Addrr - i + 1) == 0x53) - { - OnRep_ZiplineState = decltype(OnRep_ZiplineState)(Addrr - i); - break; - } - - if (*(uint8_t*)(uint8_t*)(Addrr - i) == 0x48 && *(uint8_t*)(uint8_t*)(Addrr - i + 1) == 0x89 && *(uint8_t*)(uint8_t*)(Addrr - i + 2) == 0x5C) - { - OnRep_ZiplineState = decltype(OnRep_ZiplineState)(Addrr - i); - break; - } - } - - /* for (int i = 600; i >= 0; i--) - { - LOG_INFO(LogDev, "[{}] 0x{:x} 0x{:x}", i, (int)*(uint8_t*)Addrr - i, (int)*(uint8_t*)(Addrr - i + 1), (int)*(uint8_t*)(Addrr - i + 2)); - - if (*(uint8_t*)(uint8_t*)(Addrr - i) == 0x40 && *(uint8_t*)(uint8_t*)(Addrr - i + 1) == 0x53) - { - OnRep_ZiplineState = decltype(OnRep_ZiplineState)(Addrr - i); - break; - } - - if (*(uint8_t*)(uint8_t*)(Addrr - i) == 0x48 && *(uint8_t*)(uint8_t*)(Addrr - i + 1) == 0x89 && *(uint8_t*)(uint8_t*)(Addrr - i + 2) == 0x5C) - { - OnRep_ZiplineState = decltype(OnRep_ZiplineState)(Addrr - i); - break; - } - } */ - } - - LOG_INFO(LogDev, "OnRep_ZiplineState: 0x{:x}\n", (uintptr_t)OnRep_ZiplineState - __int64(GetModuleHandleW(0))); - } + static void (*OnRep_ZiplineState)(AFortPlayerPawn* Pawn) = decltype(OnRep_ZiplineState)(Addresses::OnRep_ZiplineState); if (OnRep_ZiplineState) OnRep_ZiplineState(Pawn); diff --git a/Project Reboot 3.0/Project Reboot 3.0.vcxproj b/Project Reboot 3.0/Project Reboot 3.0.vcxproj index 6f21a87..798643b 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 @@ + 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 1ce4220..398e1a1 100644 --- a/Project Reboot 3.0/Project Reboot 3.0.vcxproj.filters +++ b/Project Reboot 3.0/Project Reboot 3.0.vcxproj.filters @@ -149,6 +149,9 @@ Engine\Source\Runtime\Engine\Private + + FortniteGame\Source\FortniteGame\Private + diff --git a/Project Reboot 3.0/addresses.cpp b/Project Reboot 3.0/addresses.cpp index 0df79d1..bef005d 100644 --- a/Project Reboot 3.0/addresses.cpp +++ b/Project Reboot 3.0/addresses.cpp @@ -236,6 +236,12 @@ void Addresses::FindAll() LOG_INFO(LogDev, "Finding CallPreReplication"); Addresses::CallPreReplication = FindCallPreReplication(); + LOG_INFO(LogDev, "Finding OnRep_ZiplineState"); + + Addresses::OnRep_ZiplineState = FindOnRep_ZiplineState(); + LOG_INFO(LogDev, "Finding GetMaxTickRate"); + + Addresses::GetMaxTickRate = FindGetMaxTickRate(); LOG_INFO(LogDev, "Finished finding!"); } @@ -284,6 +290,8 @@ void Addresses::Print() LOG_INFO(LogDev, "SendClientAdjustment: 0x{:x}", SendClientAdjustment - Base); LOG_INFO(LogDev, "CreateChannel: 0x{:x}", CreateChannel - Base); LOG_INFO(LogDev, "CallPreReplication: 0x{:x}", CallPreReplication - Base); + LOG_INFO(LogDev, "OnRep_ZiplineState: 0x{:x}", OnRep_ZiplineState - Base); + LOG_INFO(LogDev, "GetMaxTickRate: 0x{:x}", GetMaxTickRate - Base); } void Offsets::FindAll() diff --git a/Project Reboot 3.0/addresses.h b/Project Reboot 3.0/addresses.h index 2ad8638..b563698 100644 --- a/Project Reboot 3.0/addresses.h +++ b/Project Reboot 3.0/addresses.h @@ -50,6 +50,7 @@ namespace Addresses extern inline uint64 SetChannelActor = 0; extern inline uint64 SendClientAdjustment = 0; extern inline uint64 FrameStep = 0; + extern inline uint64 OnRep_ZiplineState = 0; void SetupVersion(); // Finds Engine Version void FindAll(); diff --git a/Project Reboot 3.0/commands.h b/Project Reboot 3.0/commands.h index c297aa0..16d0744 100644 --- a/Project Reboot 3.0/commands.h +++ b/Project Reboot 3.0/commands.h @@ -262,8 +262,7 @@ void ServerCheatHook(AFortPlayerControllerAthena* PlayerController, FString Msg) try { Health = std::stof(Arguments[1]); } catch (...) {} - static auto SetHealthFn = FindObject("/Script/FortniteGame.FortPawn.SetHealth"); - Pawn->ProcessEvent(SetHealthFn, &Health); + Pawn->SetHealth(Health); SendMessageToConsole(PlayerController, L"Set health!\n"); } else if (Command == "testspawn") diff --git a/Project Reboot 3.0/dllmain.cpp b/Project Reboot 3.0/dllmain.cpp index 270d912..2450519 100644 --- a/Project Reboot 3.0/dllmain.cpp +++ b/Project Reboot 3.0/dllmain.cpp @@ -38,6 +38,7 @@ static ENetMode GetNetModeHook() { /* std::cout << "AA!\n"; */ return ENetMode:: static ENetMode GetNetModeHook2() { /* std::cout << "AA!\n"; */ return ENetMode::NM_DedicatedServer; } static bool ReturnTrueHook() { return true; } +static float GetMaxTickRateHook() { return 30.f; } static int Return2Hook() { return 2; } static void NoMCPHook() { return; } @@ -82,6 +83,8 @@ DWORD WINAPI Main(LPVOID) static auto FortKismetLibraryDefault = FindObject(L"/Script/FortniteGame.Default__FortKismetLibrary"); UKismetSystemLibrary::ExecuteConsoleCommand(GetWorld(), L"log LogAbilitySystem VeryVerbose", nullptr); + UKismetSystemLibrary::ExecuteConsoleCommand(GetWorld(), L"log LogFort VeryVerbose", nullptr); + UKismetSystemLibrary::ExecuteConsoleCommand(GetWorld(), L"log LogGameMode VeryVerbose", nullptr); static auto SwitchLevel = FindObject(L"/Script/Engine.PlayerController.SwitchLevel"); FString Level = Engine_Version < 424 @@ -222,7 +225,7 @@ DWORD WINAPI Main(LPVOID) if (Addresses::FrameStep) // put all non rpc exec hooks in this scope { - Hooking::MinHook::Hook(FortKismetLibraryDefault, FindObject(L"Script/FortniteGame.FortKismetLibrary.K2_GiveItemToPlayer"), + Hooking::MinHook::Hook(FortKismetLibraryDefault, FindObject(L"/Script/FortniteGame.FortKismetLibrary.K2_GiveItemToPlayer"), UFortKismetLibrary::K2_GiveItemToPlayerHook, (PVOID*)&UFortKismetLibrary::K2_GiveItemToPlayerOriginal, false, true); Hooking::MinHook::Hook(FortKismetLibraryDefault, FindObject(L"/Script/FortniteGame.FortKismetLibrary.GiveItemToInventoryOwner"), UFortKismetLibrary::GiveItemToInventoryOwnerHook, (PVOID*)&UFortKismetLibrary::GiveItemToInventoryOwnerOriginal, false, true); @@ -234,6 +237,11 @@ DWORD WINAPI Main(LPVOID) UFortKismetLibrary::K2_RemoveFortItemFromPlayerHook, (PVOID*)&UFortKismetLibrary::K2_RemoveFortItemFromPlayerOriginal, false, true); Hooking::MinHook::Hook(FortKismetLibraryDefault, FindObject(L"/Script/FortniteGame.FortKismetLibrary.K2_SpawnPickupInWorld"), UFortKismetLibrary::K2_SpawnPickupInWorldHook, (PVOID*)&UFortKismetLibrary::K2_SpawnPickupInWorldOriginal, false, true); + Hooking::MinHook::Hook(FortKismetLibraryDefault, FindObject(L"/Script/FortniteGame.FortKismetLibrary:K2_SpawnPickupInWorldWithClass"), + UFortKismetLibrary::K2_SpawnPickupInWorldWithClassHook, (PVOID*)&UFortKismetLibrary::K2_SpawnPickupInWorldWithClassOriginal, false, true); + + Hooking::MinHook::Hook(FortPlayerControllerAthenaDefault, FindObject(L"/Script/FortniteGame.FortPlayerController.DropSpecificItem"), + AFortPlayerController::DropSpecificItemHook, (PVOID*)&AFortPlayerController::DropSpecificItemOriginal, false, true); static auto FortAthenaSupplyDropDefault = FindObject("/Script/FortniteGame.Default__FortAthenaSupplyDrop"); @@ -303,6 +311,7 @@ DWORD WINAPI Main(LPVOID) if (Engine_Version < 427) Hooking::MinHook::Hook((PVOID)Addresses::OnDamageServer, (PVOID)ABuildingActor::OnDamageServerHook, (PVOID*)&ABuildingActor::OnDamageServerOriginal); + Hooking::MinHook::Hook((PVOID)Addresses::GetMaxTickRate, GetMaxTickRateHook); // Hooking::MinHook::Hook((PVOID)Addresses::CollectGarbage, (PVOID)CollectGarbageHook, nullptr); Hooking::MinHook::Hook((PVOID)Addresses::PickTeam, (PVOID)AFortGameModeAthena::Athena_PickTeamHook); // Hooking::MinHook::Hook((PVOID)Addresses::SetZoneToIndex, (PVOID)AFortGameModeAthena::SetZoneToIndexHook, (PVOID*)&AFortGameModeAthena::SetZoneToIndexOriginal); @@ -353,15 +362,6 @@ DWORD WINAPI Main(LPVOID) MemberOffsets::DeathReport::DamageCauser = FindOffsetStruct("/Script/FortniteGame.FortPlayerDeathReport", "DamageCauser"); } - /* auto GetMaxTickRateIndex = *Memcury::Scanner::FindStringRef(L"GETMAXTICKRATE") - .ScanFor({ 0x4D, 0x8B, 0xC7, 0xE8 }) - .RelativeOffset(4) - .ScanFor({ 0xFF, 0x90 }) - .AbsoluteOffset(2) - .GetAs() / 8; - - LOG_INFO(LogHook, "GetMaxTickRateIndex {}", GetMaxTickRateIndex); */ - srand(time(0)); LOG_INFO(LogHook, "Finished!"); diff --git a/Project Reboot 3.0/finder.h b/Project Reboot 3.0/finder.h index 0626693..ce9cdda 100644 --- a/Project Reboot 3.0/finder.h +++ b/Project Reboot 3.0/finder.h @@ -215,6 +215,55 @@ static inline uint64 FindPauseBeaconRequests() return FindBytes(Addr, { 0x40, 0x53 }, 1000, 0, true); } +static inline uint64 FindOnRep_ZiplineState() +{ + static auto Addrr = Memcury::Scanner::FindStringRef(L"ZIPLINES!! Role(%s) AFortPlayerPawn::OnRep_ZiplineState ZiplineState.bIsZiplining=%d", false).Get(); + + if (!Addrr) + Addrr = Memcury::Scanner::FindStringRef(L"ZIPLINES!! GetLocalRole()(%s) AFortPlayerPawn::OnRep_ZiplineState ZiplineState.bIsZiplining=%d").Get(); + + // L"%s LocalRole[%s] ZiplineState.bIsZiplining[%d]" for 18.40??? + + if (!Addrr) + return 0; + + for (int i = 0; i < 400; i++) + { + if (*(uint8_t*)(uint8_t*)(Addrr - i) == 0x40 && *(uint8_t*)(uint8_t*)(Addrr - i + 1) == 0x53) + { + return Addrr - i; + } + + if (*(uint8_t*)(uint8_t*)(Addrr - i) == 0x48 && *(uint8_t*)(uint8_t*)(Addrr - i + 1) == 0x89 && *(uint8_t*)(uint8_t*)(Addrr - i + 2) == 0x5C) + { + return Addrr - i; + } + } + + return 0; +} + +static inline uint64 FindGetMaxTickRate() // Uengine::getmaxtickrate +{ + // TODO switch to index maybe? + + /* auto GetMaxTickRateIndex = *Memcury::Scanner::FindStringRef(L"GETMAXTICKRATE") + .ScanFor({ 0x4D, 0x8B, 0xC7, 0xE8 }) + .RelativeOffset(4) + .ScanFor({ 0xFF, 0x90 }) + .AbsoluteOffset(2) + .GetAs() / 8; + + LOG_INFO(LogHook, "GetMaxTickRateIndex {}", GetMaxTickRateIndex); */ + + auto stringRef = Memcury::Scanner::FindStringRef(L"Hitching by request!"); + + if (!stringRef.Get()) + return 0; + + return FindBytes(stringRef, { 0x48, 0x89, 0x5C }, 1000, 0, true); +} + static inline uint64 FindGetPlayerViewpoint() { // return Memcury::Scanner::FindPattern("40 55 56 57 41 57 48 8B EC 48 83 EC 48 48 8B 81 ? ? ? ? 4D 8B F8 48 8B").Get(); // 12.41