diff --git a/Project Reboot 3.0/FortLootPackage.cpp b/Project Reboot 3.0/FortLootPackage.cpp index 2fd4496..c647a7a 100644 --- a/Project Reboot 3.0/FortLootPackage.cpp +++ b/Project Reboot 3.0/FortLootPackage.cpp @@ -239,7 +239,7 @@ std::vector PickLootDrops(FName TierGroupName, bool bPrint, int recurs int MinimumLootDrops = 0; - static int AmountToAdd = Engine_Version >= 424 ? 1 : 0; // fr + static int AmountToAdd = Engine_Version >= 424 ? Engine_Version >= 500 ? 2 : 1 : 0; // fr float NumLootPackageDrops = std::floor(ChosenRowLootTierData->GetNumLootPackageDrops() + AmountToAdd); diff --git a/Project Reboot 3.0/FortPlayerController.cpp b/Project Reboot 3.0/FortPlayerController.cpp index e1cc739..35afc11 100644 --- a/Project Reboot 3.0/FortPlayerController.cpp +++ b/Project Reboot 3.0/FortPlayerController.cpp @@ -554,10 +554,10 @@ void AFortPlayerController::ServerPlayEmoteItemHook(AFortPlayerController* Playe FGameplayAbilitySpec* Spec = MakeNewSpec((UClass*)AbilityToUse, EmoteAsset, true); - static unsigned int* (*GiveAbilityAndActivateOnce)(UAbilitySystemComponent * ASC, int* outHandle, __int64 Spec) - = decltype(GiveAbilityAndActivateOnce)(Addresses::GiveAbilityAndActivateOnce); + static unsigned int* (*GiveAbilityAndActivateOnce)(UAbilitySystemComponent* ASC, int* outHandle, __int64 Spec, FGameplayEventData* TriggerEventData) + = decltype(GiveAbilityAndActivateOnce)(Addresses::GiveAbilityAndActivateOnce); // EventData is only on ue500? - GiveAbilityAndActivateOnce(PlayerState->GetAbilitySystemComponent(), &outHandle, __int64(Spec)); + GiveAbilityAndActivateOnce(PlayerState->GetAbilitySystemComponent(), &outHandle, __int64(Spec), nullptr); } uint8 ToDeathCause(const FGameplayTagContainer& TagContainer, bool bWasDBNO = false) @@ -693,29 +693,66 @@ void AFortPlayerController::ClientOnPawnDiedHook(AFortPlayerController* PlayerCo auto& ItemInstances = WorldInventory->GetItemList().GetItemInstances(); + std::vector> GuidAndCountsToRemove; + for (int i = 0; i < ItemInstances.Num(); i++) { auto ItemInstance = ItemInstances.at(i); + LOG_INFO(LogDev, "[{}/{}] CurrentItemInstance {}", i, ItemInstances.Num(), __int64(ItemInstance)); + if (!ItemInstance) continue; auto ItemEntry = ItemInstance->GetItemEntry(); auto WorldItemDefinition = Cast(ItemEntry->GetItemDefinition()); + LOG_INFO(LogDev, "[{}/{}] WorldItemDefinition {}", i, ItemInstances.Num(), WorldItemDefinition ? WorldItemDefinition->GetFullName() : "InvalidObject"); + if (!WorldItemDefinition) continue; - // if (!WorldItemDefinition->ShouldDropOnDeath()) - // continue; + auto ShouldBeDropped = WorldItemDefinition->CanBeDropped(); // WorldItemDefinition->ShouldDropOnDeath(); + + LOG_INFO(LogDev, "[{}/{}] ShouldBeDropped {}", i, ItemInstances.Num(), ShouldBeDropped); + + if (!ShouldBeDropped) + continue; AFortPickup::SpawnPickup(WorldItemDefinition, DeathLocation, ItemEntry->GetCount(), EFortPickupSourceTypeFlag::Player, EFortPickupSpawnSource::PlayerElimination, ItemEntry->GetLoadedAmmo()); - WorldInventory->RemoveItem(ItemEntry->GetItemGuid(), nullptr, ItemEntry->GetCount()); + GuidAndCountsToRemove.push_back({ ItemEntry->GetItemGuid(), ItemEntry->GetCount() }); + // WorldInventory->RemoveItem(ItemEntry->GetItemGuid(), nullptr, ItemEntry->GetCount()); + } + + for (auto& Pair : GuidAndCountsToRemove) + { + WorldInventory->RemoveItem(Pair.first, nullptr, Pair.second); } WorldInventory->Update(); + + auto GameMode = Cast(GetWorld()->GetGameMode()); + + if (!DeadPawn->IsDBNO()) + { + static void (*RemoveFromAlivePlayers)(AFortGameModeAthena* GameMode, AFortPlayerController* PlayerController, APlayerState * PlayerState, APawn * FinisherPawn, + UFortWeaponItemDefinition * FinishingWeapon, uint8_t DeathCause, char a7) + = decltype(RemoveFromAlivePlayers)(Addresses::RemoveFromAlivePlayers); + + AActor* DamageCauser = *(AActor**)(__int64(DeathReport) + MemberOffsets::DeathReport::DamageCauser); + UFortWeaponItemDefinition* KillerWeaponDef = nullptr; + + static auto FortProjectileBaseClass = FindObject("/Script/FortniteGame.FortProjectileBase"); + + if (DamageCauser->IsA(FortProjectileBaseClass)) + KillerWeaponDef = ((AFortWeapon*)DamageCauser->GetOwner())->GetWeaponData(); + if (auto Weapon = Cast(DamageCauser)) + KillerWeaponDef = Weapon->GetWeaponData(); + + RemoveFromAlivePlayers(GameMode, PlayerController, KillerPlayerState == DeadPlayerState ? nullptr : KillerPlayerState, KillerPawn, KillerWeaponDef, DeathCause, 0); + } } return ClientOnPawnDiedOriginal(PlayerController, DeathReport); diff --git a/Project Reboot 3.0/FortPlayerPawn.cpp b/Project Reboot 3.0/FortPlayerPawn.cpp index 3e78c9b..4b40026 100644 --- a/Project Reboot 3.0/FortPlayerPawn.cpp +++ b/Project Reboot 3.0/FortPlayerPawn.cpp @@ -73,6 +73,7 @@ void AFortPlayerPawn::ServerHandlePickupHook(AFortPlayerPawn* Pawn, AFortPickup* void AFortPlayerPawn::ServerHandlePickupInfoHook(AFortPlayerPawn* Pawn, AFortPickup* Pickup, __int64 Params) { + LOG_INFO(LogDev, "ServerHandlePickupInfo!"); return ServerHandlePickupHook(Pawn, Pickup, 0.40f, FVector(), false); } diff --git a/Project Reboot 3.0/addresses.cpp b/Project Reboot 3.0/addresses.cpp index 8949d1c..a2c9bf0 100644 --- a/Project Reboot 3.0/addresses.cpp +++ b/Project Reboot 3.0/addresses.cpp @@ -242,6 +242,10 @@ void Addresses::FindAll() LOG_INFO(LogDev, "Finding GetMaxTickRate"); Addresses::GetMaxTickRate = FindGetMaxTickRate(); + + LOG_INFO(LogDev, "Finding RemoveFromAlivePlayers"); + Addresses::RemoveFromAlivePlayers = FindRemoveFromAlivePlayers(); + LOG_INFO(LogDev, "Finished finding!"); } @@ -292,6 +296,7 @@ void Addresses::Print() 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); + LOG_INFO(LogDev, "RemoveFromAlivePlayers: 0x{:x}", RemoveFromAlivePlayers - Base); } void Offsets::FindAll() diff --git a/Project Reboot 3.0/addresses.h b/Project Reboot 3.0/addresses.h index b563698..b7d7b45 100644 --- a/Project Reboot 3.0/addresses.h +++ b/Project Reboot 3.0/addresses.h @@ -51,6 +51,7 @@ namespace Addresses extern inline uint64 SendClientAdjustment = 0; extern inline uint64 FrameStep = 0; extern inline uint64 OnRep_ZiplineState = 0; + extern inline uint64 RemoveFromAlivePlayers = 0; void SetupVersion(); // Finds Engine Version void FindAll(); diff --git a/Project Reboot 3.0/finder.h b/Project Reboot 3.0/finder.h index 17aeb1b..4372683 100644 --- a/Project Reboot 3.0/finder.h +++ b/Project Reboot 3.0/finder.h @@ -272,10 +272,35 @@ static inline uint64 FindGetPlayerViewpoint() if (Engine_Version == 420) return Memcury::Scanner::FindPattern("48 89 5C 24 ? 48 89 74 24 ? 55 41 56 41 57 48 8B EC 48 83 EC 50").Get(); // idk why finder doesnt work and cba to debug - auto Addr = Memcury::Scanner::FindStringRef(L"APlayerController::GetPlayerViewPoint: out_Location, ViewTarget=%s"); - // return FindBytes(Addr, { 0x48, 0x89 /*, 0x5C */}, 2000, 0, true, 1); - auto add = FindBytes(Addr, { 0x40, 0x55 }, 1000, 0, true); - return add ? add : FindBytes(Addr, { 0x48, 0x89, 0x5C }, 2000, 0, true); + auto Addrr = Memcury::Scanner::FindStringRef(L"APlayerController::GetPlayerViewPoint: out_Location, ViewTarget=%s").Get(); + + for (int i = 0; i < 1000; i++) + { + if (*(uint8_t*)(uint8_t*)(Addrr - i) == 0x40 && *(uint8_t*)(uint8_t*)(Addrr - i + 1) == 0x55) + { + 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) == 0x74) + { + return Addrr - i; + } + + if (*(uint8_t*)(uint8_t*)(Addrr - i) == 0x48 && *(uint8_t*)(uint8_t*)(Addrr - i + 1) == 0x8B && *(uint8_t*)(uint8_t*)(Addrr - i + 2) == 0xC4) + { + return Addrr - i; + } + } + + for (int i = 0; i < 1000; 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 FindSpawnActor() @@ -422,6 +447,9 @@ static inline uint64 FindCompletePickupAnimation() if (Engine_Version == 427) return Memcury::Scanner::FindPattern("48 8B C4 48 89 58 08 48 89 68 10 48 89 70 18 48 89 78 20 41 54 41 56 41 57 48 83 EC 20 48 8B B1 ? ? ? ? 48 8B D9 48 85 F6").Get(); // 17.30 + if (Engine_Version == 500) + return Memcury::Scanner::FindPattern("48 89 5C 24 ? 48 89 74 24 ? 55 57 41 57 48 8D AC 24 ? ? ? ? 48 81 EC ? ? ? ? 48 8B 05 ? ? ? ? 48 33 C4 48 89 85 ? ? ? ? 48 8B B9").Get(); // 19.10 + return 0; } @@ -528,12 +556,40 @@ static inline uint64 FindActorGetNetMode() if (!AActorGetNetmodeStrRef.Get()) { - return Memcury::Scanner::FindPattern("48 89 5C 24 ? 57 48 83 EC 20 48 8B 01 48 8B D9 FF 90 ? ? ? ? 4C 8B").Get(); + return Memcury::Scanner::FindPattern("48 89 5C 24 ? 57 48 83 EC 20 48 8B 01 48 8B D9 FF 90 ? ? ? ? 4C 8B").Get(); // 2.5 i think } return Memcury::Scanner(FindBytes(AActorGetNetmodeStrRef, { 0xE8 }, 255, 0, true)).RelativeOffset(1).Get(); } +static inline uint64 FindRemoveFromAlivePlayers() +{ + auto Addrr = Memcury::Scanner::FindStringRef(L"FortGameModeAthena: Player [%s] removed from alive players list (Team [%d]). Player count is now [%d]. Team count is now [%d].", false).Get(); + + if (!Addrr) + Addrr = Memcury::Scanner::FindStringRef(L"FortGameModeAthena::RemoveFromAlivePlayers: Player [%s] PC [%s] removed from alive players list (Team [%d]). Player count is now [%d]. PlayerBots count is now [%d]. Team count is now [%d].", true, 0, Fortnite_Version >= 18).Get(); // todo check version + + for (int i = 0; i < 2000; i++) + { + if (*(uint8_t*)(uint8_t*)(Addrr - i) == 0x4C && *(uint8_t*)(uint8_t*)(Addrr - i + 1) == 0x89 && *(uint8_t*)(uint8_t*)(Addrr - i + 2) == 0x4C) + { + 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) == 0x54) + { + return Addrr - i; + } + + if (*(uint8_t*)(uint8_t*)(Addrr - i) == 0x48 && *(uint8_t*)(uint8_t*)(Addrr - i + 1) == 0x8B && *(uint8_t*)(uint8_t*)(Addrr - i + 2) == 0xC4) + { + return Addrr - i; + } + } + + return 0; +} + static inline uint64 FindTickFlush() { // auto add = Memcury::Scanner::FindStringRef(L"UDemoNetDriver::TickFlush: ReplayStreamer ERROR: %s"); @@ -910,14 +966,17 @@ static inline uint64 FindFrameStep() static inline uint64 FindCanActivateAbility() { - return 0; + // return 0; + + if (Engine_Version <= 420) + return 0; // ? // this doesn't work on like >2.5 if (Engine_Version == 421 || Engine_Version == 422) return Memcury::Scanner::FindPattern("4C 89 4C 24 20 55 56 57 41 56 48 8D 6C 24 D1").Get(); - auto Addr = Memcury::Scanner::FindStringRef(L"CanActivateAbility %s failed, blueprint refused"); + auto Addr = Memcury::Scanner::FindStringRef(L"CanActivateAbility %s failed, blueprint refused", true, 0, Engine_Version >= 500); return FindBytes(Addr, { 0x48, 0x89, 0x5C }, 2000, 0, true); } @@ -984,7 +1043,9 @@ static inline uint64 FindReplaceBuildingActor() return Memcury::Scanner::FindPattern("4C 89 44 24 ? 55 56 57 41 55 41 56 41 57 48 8D AC 24 ? ? ? ? 48 81 EC ? ? ? ? 45").Get(); // 1.7.2 & 2.4.2 } - return FindBytes(StringRef, (Engine_Version == 420 || Engine_Version == 421 ? std::vector{ 0x48, 0x8B, 0xC4 } : std::vector{ 0x4C, 0x8B }), 1000, 0, true); + return FindBytes(StringRef, + (Engine_Version == 420 || Engine_Version == 421 || Engine_Version == 500 ? std::vector{ 0x48, 0x8B, 0xC4 } : std::vector{ 0x4C, 0x8B }), + 1000, 0, true); } static inline uint64 FindSendClientAdjustment() diff --git a/Project Reboot 3.0/hooking.h b/Project Reboot 3.0/hooking.h index 7b34d16..850d987 100644 --- a/Project Reboot 3.0/hooking.h +++ b/Project Reboot 3.0/hooking.h @@ -99,8 +99,14 @@ inline __int64 GetFunctionIdxOrPtr(UFunction* Function) { // LOG_INFO(LogDev, "0x{:x}", *(uint8_t*)(NativeAddr + i)); + if ((*(uint8_t*)(NativeAddr + i) == 0x41 && *(uint8_t*)(NativeAddr + i + 1) == 0xFF)) // wtf ue500 + { + bFoundValidate = true; + continue; + } + if ((*(uint8_t*)(NativeAddr + i) == 0xFF && *(uint8_t*)(NativeAddr + i + 1) == 0x90) || // call qword ptr - *(uint8_t*)(NativeAddr + i) == 0xFF && *(uint8_t*)(NativeAddr + i + 1) == 0x93) // call qword ptr + (*(uint8_t*)(NativeAddr + i) == 0xFF && *(uint8_t*)(NativeAddr + i + 1) == 0x93)) // call qword ptr { if (bFoundValidate) {