diff --git a/Project Reboot 3.0/BuildingWeapons.cpp b/Project Reboot 3.0/BuildingWeapons.cpp index 2c86a43..8d69779 100644 --- a/Project Reboot 3.0/BuildingWeapons.cpp +++ b/Project Reboot 3.0/BuildingWeapons.cpp @@ -4,7 +4,7 @@ void AFortWeap_EditingTool::OnRep_EditActor() { - static auto OnRep_EditActorFn = FindObject("/Script/FortniteGame.FortWeap_EditingTool.OnRep_EditActor"); + static auto OnRep_EditActorFn = FindObject(L"/Script/FortniteGame.FortWeap_EditingTool.OnRep_EditActor"); this->ProcessEvent(OnRep_EditActorFn); } diff --git a/Project Reboot 3.0/Channel.h b/Project Reboot 3.0/Channel.h index f110fd8..55acb0a 100644 --- a/Project Reboot 3.0/Channel.h +++ b/Project Reboot 3.0/Channel.h @@ -23,5 +23,11 @@ public: return ((PlaceholderBitfield*)(__int64(this) + BitfieldOffset))->Third; } + class UNetConnection*& GetConnection() + { + static auto ConnectionOffset = GetOffset("Connection"); + return *(UNetConnection**)(__int64(this) + ConnectionOffset); + } + int32 IsNetReady(bool Saturate); }; \ No newline at end of file diff --git a/Project Reboot 3.0/FortPlayerController.cpp b/Project Reboot 3.0/FortPlayerController.cpp index 065ebeb..2b133c0 100644 --- a/Project Reboot 3.0/FortPlayerController.cpp +++ b/Project Reboot 3.0/FortPlayerController.cpp @@ -930,20 +930,28 @@ void AFortPlayerController::ServerCreateBuildingActorHook(UObject* Context, FFra auto MatDefinition = UFortKismetLibrary::K2_GetResourceItemDefinition(BuildingActor->GetResourceType()); - auto MatInstance = WorldInventory->FindItemInstance(MatDefinition); - bool bBuildFree = PlayerController->DoesBuildFree(); // LOG_INFO(LogDev, "MatInstance->GetItemEntry()->GetCount(): {}", MatInstance->GetItemEntry()->GetCount()); - - int MinimumMaterial = 10; - bool bShouldDestroy = MatInstance && MatInstance->GetItemEntry() ? MatInstance->GetItemEntry()->GetCount() < MinimumMaterial : true; - - if (bShouldDestroy && !bBuildFree) + + if (!bBuildFree) { - ExistingBuildings.Free(); - BuildingActor->SilentDie(); - return ServerCreateBuildingActorOriginal(Context, Stack, Ret); + int MaterialCost = 10; + + UFortItem* MatInstance = WorldInventory->FindItemInstance(MatDefinition); + + if (!MatInstance || MatInstance->GetItemEntry()->GetCount() < MaterialCost) + { + ExistingBuildings.Free(); + BuildingActor->SilentDie(); + return ServerCreateBuildingActorOriginal(Context, Stack, Ret); + } + + bool bShouldUpdate = false; + WorldInventory->RemoveItem(MatInstance->GetItemEntry()->GetItemGuid(), &bShouldUpdate, MaterialCost); + + if (bShouldUpdate) + WorldInventory->Update(); } for (int i = 0; i < ExistingBuildings.Num(); ++i) @@ -959,15 +967,6 @@ void AFortPlayerController::ServerCreateBuildingActorHook(UObject* Context, FFra BuildingActor->InitializeBuildingActor(PlayerController, BuildingActor, true); BuildingActor->SetTeam(PlayerStateAthena->GetTeamIndex()); // required? - if (!bBuildFree) - { - bool bShouldUpdate = false; - WorldInventory->RemoveItem(MatInstance->GetItemEntry()->GetItemGuid(), &bShouldUpdate, 10); - - if (bShouldUpdate) - WorldInventory->Update(); - } - /* GET_PLAYLIST(GameState); @@ -1687,9 +1686,13 @@ void AFortPlayerController::ServerBeginEditingBuildingActorHook(AFortPlayerContr if (!EditToolInstance) return; - Pawn->EquipWeaponDefinition(EditToolDef, EditToolInstance->GetItemEntry()->GetItemGuid()); + AFortWeap_EditingTool* EditTool = nullptr; +#if 1 + EditTool = Cast(Pawn->EquipWeaponDefinition(EditToolDef, EditToolInstance->GetItemEntry()->GetItemGuid())); +#else auto EditTool = Cast(Pawn->GetCurrentWeapon()); +#endif if (!EditTool) return; @@ -1727,7 +1730,7 @@ void AFortPlayerController::ServerEditBuildingActorHook(UObject* Context, FFrame // if (!PlayerState || PlayerState->GetTeamIndex() != BuildingActorToEdit->GetTeamIndex()) //return ServerEditBuildingActorOriginal(Context, Frame, Ret); - BuildingActorToEdit->SetEditingPlayer(nullptr); + // BuildingActorToEdit->SetEditingPlayer(nullptr); // uh? static ABuildingSMActor* (*BuildingSMActorReplaceBuildingActor)(ABuildingSMActor*, __int64, UClass*, int, int, uint8_t, AFortPlayerController*) = decltype(BuildingSMActorReplaceBuildingActor)(Addresses::ReplaceBuildingActor); @@ -1761,17 +1764,26 @@ void AFortPlayerController::ServerEndEditingBuildingActorHook(AFortPlayerControl if (!WorldInventory) return; - BuildingActorToStopEditing->SetEditingPlayer(nullptr); + AFortWeap_EditingTool* EditTool = nullptr; +#if 0 auto EditToolInstance = WorldInventory->FindItemInstance(EditToolDef); if (!EditToolInstance) return; - // Pawn->EquipWeaponDefinition(EditToolDef, EditToolInstance->GetItemEntry()->GetItemGuid()); // ERM + EditTool = Cast(Pawn->EquipWeaponDefinition(EditToolDef, EditToolInstance->GetItemEntry()->GetItemGuid())); // ERM +#else + EditTool = Cast(Pawn->GetCurrentWeapon()); +#endif - if (auto EditTool = Cast(Pawn->GetCurrentWeapon())) + if (EditTool) { + static auto bEditConfirmedOffset = EditTool->GetOffset("bEditConfirmed"); + + if (bEditConfirmedOffset == -1) + EditTool->Get(bEditConfirmedOffset) = true; + EditTool->SetEditActor(nullptr); } } diff --git a/Project Reboot 3.0/NetConnection.h b/Project Reboot 3.0/NetConnection.h index 774b7ec..43db1cc 100644 --- a/Project Reboot 3.0/NetConnection.h +++ b/Project Reboot 3.0/NetConnection.h @@ -71,5 +71,11 @@ public: return Get>(SentTemporariesOffset); } + UObject*& GetPackageMap() + { + static auto PackageMapOffset = GetOffset("PackageMap"); + return Get(PackageMapOffset); + } + bool ClientHasInitializedLevelFor(const AActor* TestActor) const; }; \ No newline at end of file diff --git a/Project Reboot 3.0/NetDriver.cpp b/Project Reboot 3.0/NetDriver.cpp index 713c7bf..d8ba9a5 100644 --- a/Project Reboot 3.0/NetDriver.cpp +++ b/Project Reboot 3.0/NetDriver.cpp @@ -56,7 +56,9 @@ void UNetDriver::TickFlushHook(UNetDriver* NetDriver) if (Globals::bStartedListening) { - static auto ReplicationDriverOffset = NetDriver->GetOffset("ReplicationDriver", false); + static auto ReplicationDriverOffset = NetDriver->GetOffset("ReplicationDriver"/*, false */); + + // LOG_INFO(LogDev, "ReplicationDriverOffset{}", ReplicationDriverOffset); // if (ReplicationDriverOffset == -1) if (ReplicationDriverOffset == -1 || Fortnite_Version >= 20) @@ -66,13 +68,25 @@ void UNetDriver::TickFlushHook(UNetDriver* NetDriver) else { if (auto ReplicationDriver = NetDriver->Get(ReplicationDriverOffset)) + { reinterpret_cast(ReplicationDriver->VFTable[Offsets::ServerReplicateActors])(ReplicationDriver); + } + else + { + // LOG_INFO(LogDev, "ReplicationDriver is nul!!?1//33/221/4/124/123"); // 3.3 MOMENT + } } } return TickFlushOriginal(NetDriver); } +enum class EChannelCreateFlags : uint32_t +{ + None = (1 << 0), + OpenedLocally = (1 << 1) +}; + int32 ServerReplicateActors_PrepConnections(UNetDriver* NetDriver) { auto& ClientConnections = NetDriver->GetClientConnections(); @@ -448,6 +462,117 @@ bool UNetDriver::IsLevelInitializedForActor(const AActor* InActor, const UNetCon return bCorrectWorld || bIsConnectionPC; } +TMap* GetDestroyedStartupOrDormantActors(UNetDriver* Driver) +{ + static int off = Fortnite_Version == 1.11 ? 0x228 : 0; // 0x240 + + return off == 0 ? nullptr : (TMap*)(__int64(Driver) + off); +} + +TSet* GetDestroyedStartupOrDormantActors(UNetConnection* NetConnection) +{ + static int off = Fortnite_Version == 1.11 ? 0x33678 : 0; + + return off == 0 ? nullptr : (TSet*)(__int64(NetConnection) + off); +} + +using FArchive = void; + +bool IsError(FArchive* Ar) +{ + return false; +} + +void SerializeChecksum(FArchive* Ar, uint32 x, bool ErrorOK) +{ + /* + if (Ar->IsLoading()) + { + uint32 Magic = 0; + Ar << Magic; + if ((!ErrorOK || !IsError(Ar)) + // && !ensure(Magic == x) + ) + { + // UE_LOG(LogCoreNet, Warning, TEXT("%d == %d"), Magic, x); + } + + } + else + { + uint32 Magic = x; + Ar << Magic; + } + */ +} + +#define NET_CHECKSUM(Ser) \ +{ \ + SerializeChecksum(Ser,0xE282FA84, false); \ +} + +struct FPacketIdRange +{ + FPacketIdRange(int32 _First, int32 _Last) : First(_First), Last(_Last) { } + FPacketIdRange(int32 PacketId) : First(PacketId), Last(PacketId) { } + FPacketIdRange() : First(INDEX_NONE), Last(INDEX_NONE) { } + int32 First; + int32 Last; + + bool InRange(int32 PacketId) const + { + return (First <= PacketId && PacketId <= Last); + } +}; + +void SetChannelActorForDestroy(UActorChannel* Channel, FActorDestructionInfo* DestructInfo) +{ + auto Connection = Channel->GetConnection(); + + if ( + true + // && !Channel->IsClosing() + // && (Connection->State == USOCK_Open || Connection->State == USOCK_Pending) + ) + { + + // Send a close notify, and wait for ack. + struct FOutBunch + { + char pad[0x600]; // idk real size + }; + + FOutBunch CloseBunch{}; + FOutBunch(*ConstructorFOutBunch)(FOutBunch*, UChannel* , bool) = decltype(ConstructorFOutBunch)(__int64(GetModuleHandleW(0)) + 0x194E800); + ConstructorFOutBunch(&CloseBunch, Channel, 1); + // check(!CloseBunch.IsError()); + // check(CloseBunch.bClose); + + // https://imgur.com/a/EtKFkrD + + *(bool*)(__int64(&CloseBunch) + 0xE8) = 1; + *(bool*)(__int64(&CloseBunch) + 0xE6) = 0; + + // Serialize DestructInfo + // NET_CHECKSUM(CloseBunch); // This is to mirror the Checksum in UPackageMapClient::SerializeNewActor + + using UPackageMap = UObject; + + reinterpret_cast(Connection->GetPackageMap()->VFTable[0x238 / 8])(Connection->GetPackageMap(), &CloseBunch, DestructInfo->ObjOuter.Get(), DestructInfo->NetGUID, DestructInfo->PathName); + + // UE_LOG(LogNetTraffic, Log, TEXT("SetChannelActorForDestroy: Channel %d. NetGUID <%s> Path: %s. Bits: %d"), ChIndex, *DestructInfo->NetGUID.ToString(), *DestructInfo->PathName, CloseBunch.GetNumBits()); + // UE_LOG(LogNetDormancy, Verbose, TEXT("SetChannelActorForDestroy: Channel %d. NetGUID <%s> Path: %s. Bits: %d"), ChIndex, *DestructInfo->NetGUID.ToString(), *DestructInfo->PathName, CloseBunch.GetNumBits()); + + // 0x196E9C0 + reinterpret_cast(Channel->VFTable[0x288 / 8])(Channel, &CloseBunch, false); + } +} + +TSet* GetClientVisibleLevelNames(UNetConnection* NetConnection) +{ + return (TSet*)(__int64(NetConnection) + 0x336C8); +} + int32 UNetDriver::ServerReplicateActors() { int32 Updated = 0; @@ -487,6 +612,11 @@ int32 UNetDriver::ServerReplicateActors() // LOG_INFO(LogReplication, "Considering {} actors.", ConsiderList.size()); + static UChannel* (*CreateChannel)(UNetConnection*, int, bool, int32_t) = decltype(CreateChannel)(Addresses::CreateChannel); + static __int64 (*ReplicateActor)(UActorChannel*) = decltype(ReplicateActor)(Addresses::ReplicateActor); + static UObject* (*CreateChannelByName)(UNetConnection * Connection, FName * ChName, EChannelCreateFlags CreateFlags, int32_t ChannelIndex) = decltype(CreateChannelByName)(Addresses::CreateChannel); + static __int64 (*SetChannelActor)(UActorChannel*, AActor*) = decltype(SetChannelActor)(Addresses::SetChannelActor); + for (int32 i = 0; i < this->GetClientConnections().Num(); i++) { UNetConnection* Connection = this->GetClientConnections().at(i); @@ -522,6 +652,85 @@ int32 UNetDriver::ServerReplicateActors() Connection->GetSentTemporaries().at(j)->GetNetTag() = GetNetTag(); } */ + std::vector DeletionEntries; + + auto ConnectionDestroyedStartupOrDormantActors = GetDestroyedStartupOrDormantActors(Connection); + + if (ConnectionDestroyedStartupOrDormantActors) + { + auto DriverDestroyedStartupOrDormantActors = GetDestroyedStartupOrDormantActors(this); + + if (DriverDestroyedStartupOrDormantActors) + { + for (FNetworkGUID& ConnectionIt : *ConnectionDestroyedStartupOrDormantActors) + { + FActorDestructionInfo* DInfo = nullptr; + + for (TPair& DriverIt : *DriverDestroyedStartupOrDormantActors) + { + if (DriverIt.First == ConnectionIt) + { + DInfo = &DriverIt.Second; + break; + } + } + + if (!DInfo) continue; // should never happen + + DeletionEntries.push_back(DInfo); + } + } + } + + LOG_INFO(LogDev, "DeletionEntries: {}", DeletionEntries.size()); + + for (FActorDestructionInfo* DeletionEntry : DeletionEntries) + { + LOG_INFO(LogDev, "AA: {}", DeletionEntry->PathName.Data.Data ? DeletionEntry->PathName.ToString() : "Null"); + + if (DeletionEntry->StreamingLevelName != -1) + { + auto ClientVisibleLevelNames = GetClientVisibleLevelNames(Connection); + + bool bFound = false; + + for (FName& ClientVisibleLevelName : *ClientVisibleLevelNames) + { + if (ClientVisibleLevelName == DeletionEntry->StreamingLevelName) + { + bFound = true; + break; + } + } + + if (!bFound) + continue; + } + + UActorChannel* Channel = nullptr; + + if (Engine_Version >= 422) + { + FString ActorStr = L"Actor"; + FName ActorName = UKismetStringLibrary::Conv_StringToName(ActorStr); + + int ChannelIndex = -1; // 4294967295 + Channel = (UActorChannel*)CreateChannelByName(Connection, &ActorName, EChannelCreateFlags::OpenedLocally, ChannelIndex); + } + else + { + Channel = (UActorChannel*)CreateChannel(Connection, 2, true, -1); + } + + if (Channel) + { + // FinalRelevantCount++; + + SetChannelActorForDestroy(Channel, DeletionEntry); // Send a close bunch on the new channel + GetDestroyedStartupOrDormantActors(Connection)->Remove(DeletionEntry->NetGUID); // Remove from connections to-be-destroyed list (close bunch of reliable, so it will make it there) + } + } + for (auto& ActorInfo : ConsiderList) { if (!ActorInfo || !ActorInfo->Actor) @@ -592,16 +801,6 @@ int32 UNetDriver::ServerReplicateActors() } } - enum class EChannelCreateFlags : uint32_t - { - None = (1 << 0), - OpenedLocally = (1 << 1) - }; - - static UChannel* (*CreateChannel)(UNetConnection*, int, bool, int32_t) = decltype(CreateChannel)(Addresses::CreateChannel); - static __int64 (*ReplicateActor)(UActorChannel*) = decltype(ReplicateActor)(Addresses::ReplicateActor); - static UObject* (*CreateChannelByName)(UNetConnection* Connection, FName* ChName, EChannelCreateFlags CreateFlags, int32_t ChannelIndex) = decltype(CreateChannelByName)(Addresses::CreateChannel); - static __int64 (*SetChannelActor)(UActorChannel*, AActor*) = decltype(SetChannelActor)(Addresses::SetChannelActor); if (!Channel) { diff --git a/Project Reboot 3.0/Object.h b/Project Reboot 3.0/Object.h index a5f0dfa..d03ee4d 100644 --- a/Project Reboot 3.0/Object.h +++ b/Project Reboot 3.0/Object.h @@ -68,7 +68,7 @@ public: int GetOffset(const std::string& ChildName, bool bWarnIfNotFound = true) const; template - T& Get(int Offset) const { return *(T*)(__int64(this) + Offset); } + inline T& Get(int Offset) const { return *(T*)(__int64(this) + Offset); } void* GetInterfaceAddress(UClass* InterfaceClass); diff --git a/Project Reboot 3.0/dllmain.cpp b/Project Reboot 3.0/dllmain.cpp index 2ff6591..af094d5 100644 --- a/Project Reboot 3.0/dllmain.cpp +++ b/Project Reboot 3.0/dllmain.cpp @@ -969,8 +969,13 @@ DWORD WINAPI Main(LPVOID) Hooking::MinHook::Hook(GameModeDefault, FindObject(L"/Script/Engine.GameMode.ReadyToStartMatch"), AFortGameModeAthena::Athena_ReadyToStartMatchHook, (PVOID*)&AFortGameModeAthena::Athena_ReadyToStartMatchOriginal, false, false, true); - Hooking::MinHook::Hook(GameModeDefault, FindObject(L"/Script/FortniteGame.FortGameModeAthena.OnAircraftEnteredDropZone"), AFortGameModeAthena::OnAircraftEnteredDropZoneHook, - (PVOID*)&AFortGameModeAthena::OnAircraftEnteredDropZoneOriginal, false, false, true, true); + + if (Fortnite_Version != 3.3) // 0xE9 on 3.3 + { + Hooking::MinHook::Hook(GameModeDefault, FindObject(L"/Script/FortniteGame.FortGameModeAthena.OnAircraftEnteredDropZone"), AFortGameModeAthena::OnAircraftEnteredDropZoneHook, + (PVOID*)&AFortGameModeAthena::OnAircraftEnteredDropZoneOriginal, false, false, true, true); + } + Hooking::MinHook::Hook(GameModeDefault, FindObject(L"/Script/Engine.GameModeBase.SpawnDefaultPawnFor"), AGameModeBase::SpawnDefaultPawnForHook, nullptr, false); Hooking::MinHook::Hook(GameModeDefault, FindObject(L"/Script/Engine.GameModeBase.HandleStartingNewPlayer"), AFortGameModeAthena::Athena_HandleStartingNewPlayerHook, @@ -1125,8 +1130,13 @@ DWORD WINAPI Main(LPVOID) AFortPlayerControllerAthena::ServerPlaySquadQuickChatMessageHook, nullptr, false); } - Hooking::MinHook::Hook(FortPlayerControllerAthenaDefault, FindObject(L"/Script/FortniteGame.FortPlayerControllerAthena.ServerTeleportToPlaygroundLobbyIsland"), - AFortPlayerControllerAthena::ServerTeleportToPlaygroundLobbyIslandHook, nullptr, false); + auto ServerTeleportToPlaygroundIslandFn = FindObject(L"/Script/FortniteGame.FortPlayerControllerAthena.ServerTeleportToPlaygroundLobbyIsland"); + + if (ServerTeleportToPlaygroundIslandFn) + { + Hooking::MinHook::Hook(FortPlayerControllerAthenaDefault, ServerTeleportToPlaygroundIslandFn, + AFortPlayerControllerAthena::ServerTeleportToPlaygroundLobbyIslandHook, nullptr, false); + } // Hooking::MinHook::Hook(FortPlayerStateAthenaDefault, FindObject(L"/Script/FortniteGame.FortPlayerStateAthena.ServerSetInAircraft"), // AFortPlayerStateAthena::ServerSetInAircraftHook, (PVOID*)&AFortPlayerStateAthena::ServerSetInAircraftOriginal, false, true); // We could use second method but eh diff --git a/Project Reboot 3.0/finder.cpp b/Project Reboot 3.0/finder.cpp index 69bac66..ef9ef91 100644 --- a/Project Reboot 3.0/finder.cpp +++ b/Project Reboot 3.0/finder.cpp @@ -58,7 +58,7 @@ uint64 FindGIsClient() // {0x44, 0x88} // IDK WHAT VERSION This for but it scuffs older builds }; - int Skip = Engine_Version <= 420 ? 1 : 2; // Skip GIsServer and some variable i forgot + int Skip = 2; // Skip GIsServer and some variable i forgot uint64 Addy; diff --git a/Project Reboot 3.0/finder.h b/Project Reboot 3.0/finder.h index d993c6f..3f904bc 100644 --- a/Project Reboot 3.0/finder.h +++ b/Project Reboot 3.0/finder.h @@ -171,6 +171,9 @@ static inline uint64 FindAddToAlivePlayers() static inline uint64 FindFinishResurrection() { + if (Engine_Version < 423) + return 0; + uintptr_t Addrr = Engine_Version >= 427 ? FindNameRef(L"OnResurrectionCompleted") : FindFunctionCall(L"OnResurrectionCompleted"); // Call is inlined if (!Addrr) @@ -244,7 +247,12 @@ static inline uint64 FindPickupInitialize() if (Engine_Version == 419) return Memcury::Scanner::FindPattern("48 89 6C 24 ? 48 89 74 24 ? 57 48 83 EC 20 80 B9 ? ? ? ? ? 41 0F B6 E9").Get(); // 1.11 if (Engine_Version == 420) + { + if (Fortnite_Version <= 3.3) + return Memcury::Scanner::FindPattern("48 89 6C 24 ? 48 89 74 24 ? 57 48 83 EC 20 80 B9 ? ? ? ? ? 41 0F B6 E9 49 8B F8 48 8B F1 0F 85 ? ? ? ? 48 83 7A").Get(); // 3.3 + return Memcury::Scanner::FindPattern("48 89 5C 24 ? 48 89 6C 24 ? 48 89 74 24 ? 41 56 48 83 EC 20 80 B9 ? ? ? ? ? 45 0F B6 F1 49 8B E8").Get(); // 4.1 + } if (Engine_Version == 421) { auto addr = Memcury::Scanner::FindPattern("48 89 5C 24 ? 55 57 41 57 48 83 EC 30 80 B9 ? ? ? ? ? 41 0F B6", false).Get(); // 6.21 @@ -507,7 +515,9 @@ static inline uint64 FindFree() { uint64 addr = 0; - if (Engine_Version >= 420 && Engine_Version <= 426) + if (Fortnite_Version <= 3.3) // todo check 3.4 + addr = Memcury::Scanner::FindPattern("48 85 C9 74 1D 4C 8B 05 ? ? ? ? 4D 85 C0 0F 84").Get(); + else if (Engine_Version >= 420 && Engine_Version <= 426) addr = Memcury::Scanner::FindPattern("48 85 C9 74 2E 53 48 83 EC 20 48 8B D9").Get(); else if (Engine_Version >= 427) addr = Memcury::Scanner::FindPattern("48 85 C9 0F 84 ? ? ? ? 53 48 83 EC 20 48 89 7C 24 ? 48 8B D9 48 8B 3D").Get(); @@ -547,7 +557,7 @@ static inline uint64 FindSpawnActor() auto Addr = Memcury::Scanner::FindStringRef(L"SpawnActor failed because no class was specified"); - if (Engine_Version >= 416 && Fortnite_Version <= 3.2) + if (Engine_Version >= 416 && Fortnite_Version <= 3.3) return FindBytes(Addr, { 0x40, 0x55 }, 3000, 0, true); return FindBytes(Addr, { 0x4C, 0x8B, 0xDC }, 3000, 0, true); @@ -671,7 +681,9 @@ static inline uint64 FindSpecConstructor() static inline uint64 FindCreateBuildingActorCallForDeco() // kill me { - auto Addrr = Memcury::Scanner::FindStringRef(L"ServerCreateBuildingAndSpawnDeco called without a valid DecoItemDef").Get(); // honestly L (we should get it from the ufunc not string) + return 0; + + auto Addrr = Memcury::Scanner::FindStringRef(L"ServerCreateBuildingAndSpawnDeco called without a valid DecoItemDef", false).Get(); // honestly L (we should get it from the ufunc not string) if (!Addrr) return 0; @@ -824,7 +836,14 @@ static inline uint64 FindNoMCP() return Memcury::Scanner::FindPattern("E8 ? ? ? ? 90 EB EA").RelativeOffset(1).Get(); if (std::floor(Fortnite_Version) == 3) - return Memcury::Scanner::FindPattern("E8 ? ? ? ? 83 A7 ? ? ? ? ? 48 8D 4C 24 ?").RelativeOffset(1).Get(); + { + auto cuh = Memcury::Scanner::FindPattern("E8 ? ? ? ? 83 A7 ? ? ? ? ? 48 8D 4C 24 ?"); + + if (!cuh.Get()) + cuh = Memcury::Scanner::FindPattern(""); // 3.3 + + return cuh.RelativeOffset(1).Get(); + } if (std::floor(Fortnite_Version) == 4) return Memcury::Scanner::FindPattern("E8 ? ? ? ? 83 A7 ? ? ? ? ? 83 E0 01").RelativeOffset(1).Get(); @@ -1460,7 +1479,7 @@ static inline uint64 FindMcpIsDedicatedServerOffset() if (Engine_Version == 421 || Engine_Version == 422) // checked on 5.41 & 6.21 & 7.30 return 0x28; - return 0x60; // 1.7.2 & 1.11 & 4.1 + return 0x60; // 1.7.2 & 1.11 3.3 & & 4.1 } uint64 FindGIsClient(); // AHHH diff --git a/Project Reboot 3.0/hooking.h b/Project Reboot 3.0/hooking.h index 1f05cd0..6b32486 100644 --- a/Project Reboot 3.0/hooking.h +++ b/Project Reboot 3.0/hooking.h @@ -253,7 +253,9 @@ inline __int64 GetFunctionIdxOrPtr(UFunction* Function, bool bBreakWhenHitRet = { // LOG_INFO(LogDev, "[{}] 0x{:x}", i, *(uint8_t*)CurrentAddy); - if (*(uint8_t*)CurrentAddy == 0xE8) + if (*(uint8_t*)CurrentAddy == 0xE8 + // || *(uint8_t*)CurrentAddy == 0xE9 + ) { // LOG_INFO(LogDev, "CurrentAddy 0x{:x}", CurrentAddy - __int64(GetModuleHandleW(0))); functionAddy = (CurrentAddy + 1 + 4) + *(int*)(CurrentAddy + 1);