This commit is contained in:
Gray
2024-03-12 19:10:18 -04:00
parent 1169eb80cc
commit 512fb16ee4
10 changed files with 302 additions and 48 deletions

View File

@@ -4,7 +4,7 @@
void AFortWeap_EditingTool::OnRep_EditActor() void AFortWeap_EditingTool::OnRep_EditActor()
{ {
static auto OnRep_EditActorFn = FindObject<UFunction>("/Script/FortniteGame.FortWeap_EditingTool.OnRep_EditActor"); static auto OnRep_EditActorFn = FindObject<UFunction>(L"/Script/FortniteGame.FortWeap_EditingTool.OnRep_EditActor");
this->ProcessEvent(OnRep_EditActorFn); this->ProcessEvent(OnRep_EditActorFn);
} }

View File

@@ -23,5 +23,11 @@ public:
return ((PlaceholderBitfield*)(__int64(this) + BitfieldOffset))->Third; return ((PlaceholderBitfield*)(__int64(this) + BitfieldOffset))->Third;
} }
class UNetConnection*& GetConnection()
{
static auto ConnectionOffset = GetOffset("Connection");
return *(UNetConnection**)(__int64(this) + ConnectionOffset);
}
int32 IsNetReady(bool Saturate); int32 IsNetReady(bool Saturate);
}; };

View File

@@ -930,20 +930,28 @@ void AFortPlayerController::ServerCreateBuildingActorHook(UObject* Context, FFra
auto MatDefinition = UFortKismetLibrary::K2_GetResourceItemDefinition(BuildingActor->GetResourceType()); auto MatDefinition = UFortKismetLibrary::K2_GetResourceItemDefinition(BuildingActor->GetResourceType());
auto MatInstance = WorldInventory->FindItemInstance(MatDefinition);
bool bBuildFree = PlayerController->DoesBuildFree(); bool bBuildFree = PlayerController->DoesBuildFree();
// LOG_INFO(LogDev, "MatInstance->GetItemEntry()->GetCount(): {}", MatInstance->GetItemEntry()->GetCount()); // LOG_INFO(LogDev, "MatInstance->GetItemEntry()->GetCount(): {}", MatInstance->GetItemEntry()->GetCount());
int MinimumMaterial = 10; if (!bBuildFree)
bool bShouldDestroy = MatInstance && MatInstance->GetItemEntry() ? MatInstance->GetItemEntry()->GetCount() < MinimumMaterial : true;
if (bShouldDestroy && !bBuildFree)
{ {
ExistingBuildings.Free(); int MaterialCost = 10;
BuildingActor->SilentDie();
return ServerCreateBuildingActorOriginal(Context, Stack, Ret); 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) for (int i = 0; i < ExistingBuildings.Num(); ++i)
@@ -959,15 +967,6 @@ void AFortPlayerController::ServerCreateBuildingActorHook(UObject* Context, FFra
BuildingActor->InitializeBuildingActor(PlayerController, BuildingActor, true); BuildingActor->InitializeBuildingActor(PlayerController, BuildingActor, true);
BuildingActor->SetTeam(PlayerStateAthena->GetTeamIndex()); // required? BuildingActor->SetTeam(PlayerStateAthena->GetTeamIndex()); // required?
if (!bBuildFree)
{
bool bShouldUpdate = false;
WorldInventory->RemoveItem(MatInstance->GetItemEntry()->GetItemGuid(), &bShouldUpdate, 10);
if (bShouldUpdate)
WorldInventory->Update();
}
/* /*
GET_PLAYLIST(GameState); GET_PLAYLIST(GameState);
@@ -1687,9 +1686,13 @@ void AFortPlayerController::ServerBeginEditingBuildingActorHook(AFortPlayerContr
if (!EditToolInstance) if (!EditToolInstance)
return; return;
Pawn->EquipWeaponDefinition(EditToolDef, EditToolInstance->GetItemEntry()->GetItemGuid()); AFortWeap_EditingTool* EditTool = nullptr;
#if 1
EditTool = Cast<AFortWeap_EditingTool>(Pawn->EquipWeaponDefinition(EditToolDef, EditToolInstance->GetItemEntry()->GetItemGuid()));
#else
auto EditTool = Cast<AFortWeap_EditingTool>(Pawn->GetCurrentWeapon()); auto EditTool = Cast<AFortWeap_EditingTool>(Pawn->GetCurrentWeapon());
#endif
if (!EditTool) if (!EditTool)
return; return;
@@ -1727,7 +1730,7 @@ void AFortPlayerController::ServerEditBuildingActorHook(UObject* Context, FFrame
// if (!PlayerState || PlayerState->GetTeamIndex() != BuildingActorToEdit->GetTeamIndex()) // if (!PlayerState || PlayerState->GetTeamIndex() != BuildingActorToEdit->GetTeamIndex())
//return ServerEditBuildingActorOriginal(Context, Frame, Ret); //return ServerEditBuildingActorOriginal(Context, Frame, Ret);
BuildingActorToEdit->SetEditingPlayer(nullptr); // BuildingActorToEdit->SetEditingPlayer(nullptr); // uh?
static ABuildingSMActor* (*BuildingSMActorReplaceBuildingActor)(ABuildingSMActor*, __int64, UClass*, int, int, uint8_t, AFortPlayerController*) = static ABuildingSMActor* (*BuildingSMActorReplaceBuildingActor)(ABuildingSMActor*, __int64, UClass*, int, int, uint8_t, AFortPlayerController*) =
decltype(BuildingSMActorReplaceBuildingActor)(Addresses::ReplaceBuildingActor); decltype(BuildingSMActorReplaceBuildingActor)(Addresses::ReplaceBuildingActor);
@@ -1761,17 +1764,26 @@ void AFortPlayerController::ServerEndEditingBuildingActorHook(AFortPlayerControl
if (!WorldInventory) if (!WorldInventory)
return; return;
BuildingActorToStopEditing->SetEditingPlayer(nullptr); AFortWeap_EditingTool* EditTool = nullptr;
#if 0
auto EditToolInstance = WorldInventory->FindItemInstance(EditToolDef); auto EditToolInstance = WorldInventory->FindItemInstance(EditToolDef);
if (!EditToolInstance) if (!EditToolInstance)
return; return;
// Pawn->EquipWeaponDefinition(EditToolDef, EditToolInstance->GetItemEntry()->GetItemGuid()); // ERM EditTool = Cast<AFortWeap_EditingTool>(Pawn->EquipWeaponDefinition(EditToolDef, EditToolInstance->GetItemEntry()->GetItemGuid())); // ERM
#else
EditTool = Cast<AFortWeap_EditingTool>(Pawn->GetCurrentWeapon());
#endif
if (auto EditTool = Cast<AFortWeap_EditingTool>(Pawn->GetCurrentWeapon())) if (EditTool)
{ {
static auto bEditConfirmedOffset = EditTool->GetOffset("bEditConfirmed");
if (bEditConfirmedOffset == -1)
EditTool->Get<bool>(bEditConfirmedOffset) = true;
EditTool->SetEditActor(nullptr); EditTool->SetEditActor(nullptr);
} }
} }

View File

@@ -71,5 +71,11 @@ public:
return Get<TArray<AActor*>>(SentTemporariesOffset); return Get<TArray<AActor*>>(SentTemporariesOffset);
} }
UObject*& GetPackageMap()
{
static auto PackageMapOffset = GetOffset("PackageMap");
return Get<UObject*>(PackageMapOffset);
}
bool ClientHasInitializedLevelFor(const AActor* TestActor) const; bool ClientHasInitializedLevelFor(const AActor* TestActor) const;
}; };

View File

@@ -56,7 +56,9 @@ void UNetDriver::TickFlushHook(UNetDriver* NetDriver)
if (Globals::bStartedListening) 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)
if (ReplicationDriverOffset == -1 || Fortnite_Version >= 20) if (ReplicationDriverOffset == -1 || Fortnite_Version >= 20)
@@ -66,13 +68,25 @@ void UNetDriver::TickFlushHook(UNetDriver* NetDriver)
else else
{ {
if (auto ReplicationDriver = NetDriver->Get(ReplicationDriverOffset)) if (auto ReplicationDriver = NetDriver->Get(ReplicationDriverOffset))
{
reinterpret_cast<void(*)(UObject*)>(ReplicationDriver->VFTable[Offsets::ServerReplicateActors])(ReplicationDriver); reinterpret_cast<void(*)(UObject*)>(ReplicationDriver->VFTable[Offsets::ServerReplicateActors])(ReplicationDriver);
}
else
{
// LOG_INFO(LogDev, "ReplicationDriver is nul!!?1//33/221/4/124/123"); // 3.3 MOMENT
}
} }
} }
return TickFlushOriginal(NetDriver); return TickFlushOriginal(NetDriver);
} }
enum class EChannelCreateFlags : uint32_t
{
None = (1 << 0),
OpenedLocally = (1 << 1)
};
int32 ServerReplicateActors_PrepConnections(UNetDriver* NetDriver) int32 ServerReplicateActors_PrepConnections(UNetDriver* NetDriver)
{ {
auto& ClientConnections = NetDriver->GetClientConnections(); auto& ClientConnections = NetDriver->GetClientConnections();
@@ -448,6 +462,117 @@ bool UNetDriver::IsLevelInitializedForActor(const AActor* InActor, const UNetCon
return bCorrectWorld || bIsConnectionPC; return bCorrectWorld || bIsConnectionPC;
} }
TMap<FNetworkGUID, FActorDestructionInfo>* GetDestroyedStartupOrDormantActors(UNetDriver* Driver)
{
static int off = Fortnite_Version == 1.11 ? 0x228 : 0; // 0x240
return off == 0 ? nullptr : (TMap<FNetworkGUID, FActorDestructionInfo>*)(__int64(Driver) + off);
}
TSet<FNetworkGUID>* GetDestroyedStartupOrDormantActors(UNetConnection* NetConnection)
{
static int off = Fortnite_Version == 1.11 ? 0x33678 : 0;
return off == 0 ? nullptr : (TSet<FNetworkGUID>*)(__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<bool(*)(UPackageMap*, FArchive * Ar, UObject * InOuter,FNetworkGUID NetGUID, FString ObjName)>(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<FPacketIdRange(*)(UActorChannel*, FOutBunch*, bool)>(Channel->VFTable[0x288 / 8])(Channel, &CloseBunch, false);
}
}
TSet<FName>* GetClientVisibleLevelNames(UNetConnection* NetConnection)
{
return (TSet<FName>*)(__int64(NetConnection) + 0x336C8);
}
int32 UNetDriver::ServerReplicateActors() int32 UNetDriver::ServerReplicateActors()
{ {
int32 Updated = 0; int32 Updated = 0;
@@ -487,6 +612,11 @@ int32 UNetDriver::ServerReplicateActors()
// LOG_INFO(LogReplication, "Considering {} actors.", ConsiderList.size()); // 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++) for (int32 i = 0; i < this->GetClientConnections().Num(); i++)
{ {
UNetConnection* Connection = this->GetClientConnections().at(i); UNetConnection* Connection = this->GetClientConnections().at(i);
@@ -522,6 +652,85 @@ int32 UNetDriver::ServerReplicateActors()
Connection->GetSentTemporaries().at(j)->GetNetTag() = GetNetTag(); Connection->GetSentTemporaries().at(j)->GetNetTag() = GetNetTag();
} */ } */
std::vector<FActorDestructionInfo*> DeletionEntries;
auto ConnectionDestroyedStartupOrDormantActors = GetDestroyedStartupOrDormantActors(Connection);
if (ConnectionDestroyedStartupOrDormantActors)
{
auto DriverDestroyedStartupOrDormantActors = GetDestroyedStartupOrDormantActors(this);
if (DriverDestroyedStartupOrDormantActors)
{
for (FNetworkGUID& ConnectionIt : *ConnectionDestroyedStartupOrDormantActors)
{
FActorDestructionInfo* DInfo = nullptr;
for (TPair<FNetworkGUID, FActorDestructionInfo>& 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) for (auto& ActorInfo : ConsiderList)
{ {
if (!ActorInfo || !ActorInfo->Actor) 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) if (!Channel)
{ {

View File

@@ -68,7 +68,7 @@ public:
int GetOffset(const std::string& ChildName, bool bWarnIfNotFound = true) const; int GetOffset(const std::string& ChildName, bool bWarnIfNotFound = true) const;
template <typename T = UObject*> template <typename T = UObject*>
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); void* GetInterfaceAddress(UClass* InterfaceClass);

View File

@@ -969,8 +969,13 @@ DWORD WINAPI Main(LPVOID)
Hooking::MinHook::Hook(GameModeDefault, FindObject<UFunction>(L"/Script/Engine.GameMode.ReadyToStartMatch"), AFortGameModeAthena::Athena_ReadyToStartMatchHook, Hooking::MinHook::Hook(GameModeDefault, FindObject<UFunction>(L"/Script/Engine.GameMode.ReadyToStartMatch"), AFortGameModeAthena::Athena_ReadyToStartMatchHook,
(PVOID*)&AFortGameModeAthena::Athena_ReadyToStartMatchOriginal, false, false, true); (PVOID*)&AFortGameModeAthena::Athena_ReadyToStartMatchOriginal, false, false, true);
Hooking::MinHook::Hook(GameModeDefault, FindObject<UFunction>(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<UFunction>(L"/Script/FortniteGame.FortGameModeAthena.OnAircraftEnteredDropZone"), AFortGameModeAthena::OnAircraftEnteredDropZoneHook,
(PVOID*)&AFortGameModeAthena::OnAircraftEnteredDropZoneOriginal, false, false, true, true);
}
Hooking::MinHook::Hook(GameModeDefault, FindObject<UFunction>(L"/Script/Engine.GameModeBase.SpawnDefaultPawnFor"), Hooking::MinHook::Hook(GameModeDefault, FindObject<UFunction>(L"/Script/Engine.GameModeBase.SpawnDefaultPawnFor"),
AGameModeBase::SpawnDefaultPawnForHook, nullptr, false); AGameModeBase::SpawnDefaultPawnForHook, nullptr, false);
Hooking::MinHook::Hook(GameModeDefault, FindObject<UFunction>(L"/Script/Engine.GameModeBase.HandleStartingNewPlayer"), AFortGameModeAthena::Athena_HandleStartingNewPlayerHook, Hooking::MinHook::Hook(GameModeDefault, FindObject<UFunction>(L"/Script/Engine.GameModeBase.HandleStartingNewPlayer"), AFortGameModeAthena::Athena_HandleStartingNewPlayerHook,
@@ -1125,8 +1130,13 @@ DWORD WINAPI Main(LPVOID)
AFortPlayerControllerAthena::ServerPlaySquadQuickChatMessageHook, nullptr, false); AFortPlayerControllerAthena::ServerPlaySquadQuickChatMessageHook, nullptr, false);
} }
Hooking::MinHook::Hook(FortPlayerControllerAthenaDefault, FindObject<UFunction>(L"/Script/FortniteGame.FortPlayerControllerAthena.ServerTeleportToPlaygroundLobbyIsland"), auto ServerTeleportToPlaygroundIslandFn = FindObject<UFunction>(L"/Script/FortniteGame.FortPlayerControllerAthena.ServerTeleportToPlaygroundLobbyIsland");
AFortPlayerControllerAthena::ServerTeleportToPlaygroundLobbyIslandHook, nullptr, false);
if (ServerTeleportToPlaygroundIslandFn)
{
Hooking::MinHook::Hook(FortPlayerControllerAthenaDefault, ServerTeleportToPlaygroundIslandFn,
AFortPlayerControllerAthena::ServerTeleportToPlaygroundLobbyIslandHook, nullptr, false);
}
// Hooking::MinHook::Hook(FortPlayerStateAthenaDefault, FindObject<UFunction>(L"/Script/FortniteGame.FortPlayerStateAthena.ServerSetInAircraft"), // Hooking::MinHook::Hook(FortPlayerStateAthenaDefault, FindObject<UFunction>(L"/Script/FortniteGame.FortPlayerStateAthena.ServerSetInAircraft"),
// AFortPlayerStateAthena::ServerSetInAircraftHook, (PVOID*)&AFortPlayerStateAthena::ServerSetInAircraftOriginal, false, true); // We could use second method but eh // AFortPlayerStateAthena::ServerSetInAircraftHook, (PVOID*)&AFortPlayerStateAthena::ServerSetInAircraftOriginal, false, true); // We could use second method but eh

View File

@@ -58,7 +58,7 @@ uint64 FindGIsClient()
// {0x44, 0x88} // IDK WHAT VERSION This for but it scuffs older builds // {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; uint64 Addy;

View File

@@ -171,6 +171,9 @@ static inline uint64 FindAddToAlivePlayers()
static inline uint64 FindFinishResurrection() 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 uintptr_t Addrr = Engine_Version >= 427 ? FindNameRef(L"OnResurrectionCompleted") : FindFunctionCall(L"OnResurrectionCompleted"); // Call is inlined
if (!Addrr) if (!Addrr)
@@ -244,7 +247,12 @@ static inline uint64 FindPickupInitialize()
if (Engine_Version == 419) 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 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 (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 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) 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 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; 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(); addr = Memcury::Scanner::FindPattern("48 85 C9 74 2E 53 48 83 EC 20 48 8B D9").Get();
else if (Engine_Version >= 427) 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(); 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"); 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, { 0x40, 0x55 }, 3000, 0, true);
return FindBytes(Addr, { 0x4C, 0x8B, 0xDC }, 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 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) if (!Addrr)
return 0; return 0;
@@ -824,7 +836,14 @@ static inline uint64 FindNoMCP()
return Memcury::Scanner::FindPattern("E8 ? ? ? ? 90 EB EA").RelativeOffset(1).Get(); return Memcury::Scanner::FindPattern("E8 ? ? ? ? 90 EB EA").RelativeOffset(1).Get();
if (std::floor(Fortnite_Version) == 3) 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) if (std::floor(Fortnite_Version) == 4)
return Memcury::Scanner::FindPattern("E8 ? ? ? ? 83 A7 ? ? ? ? ? 83 E0 01").RelativeOffset(1).Get(); 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 if (Engine_Version == 421 || Engine_Version == 422) // checked on 5.41 & 6.21 & 7.30
return 0x28; 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 uint64 FindGIsClient(); // AHHH

View File

@@ -253,7 +253,9 @@ inline __int64 GetFunctionIdxOrPtr(UFunction* Function, bool bBreakWhenHitRet =
{ {
// LOG_INFO(LogDev, "[{}] 0x{:x}", i, *(uint8_t*)CurrentAddy); // 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))); // LOG_INFO(LogDev, "CurrentAddy 0x{:x}", CurrentAddy - __int64(GetModuleHandleW(0)));
functionAddy = (CurrentAddy + 1 + 4) + *(int*)(CurrentAddy + 1); functionAddy = (CurrentAddy + 1 + 4) + *(int*)(CurrentAddy + 1);