perforamce + fix chapter 2 match starting

This commit is contained in:
Milxnor
2023-03-22 14:04:08 -04:00
parent 4913d64719
commit d5bbca9add
21 changed files with 264 additions and 95 deletions

View File

@@ -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<FName>(CurrentPlaylistNameOffset) = Playlist->Get<FName>(PlaylistNameOffset);
Get<int>(CurrentPlaylistIdOffset) = Playlist->Get<int>(PlaylistIdOffset);
}

View File

@@ -5,4 +5,5 @@
class AFortGameMode : public AGameMode class AFortGameMode : public AGameMode
{ {
public: public:
void SetCurrentPlaylistName(UObject* Playlist); // Techinally it takes in a fname
}; };

View File

@@ -158,7 +158,7 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game
{ {
auto GameState = GameMode->GetGameStateAthena(); auto GameState = GameMode->GetGameStateAthena();
auto SetPlaylist = [&GameState](UObject* Playlist) -> void { auto SetPlaylist = [&GameState, &GameMode](UObject* Playlist, bool bOnRep) -> void {
if (Fortnite_Version >= 6.10) if (Fortnite_Version >= 6.10)
{ {
auto CurrentPlaylistInfo = GameState->GetPtr<FFastArraySerializer>("CurrentPlaylistInfo"); auto CurrentPlaylistInfo = GameState->GetPtr<FFastArraySerializer>("CurrentPlaylistInfo");
@@ -177,6 +177,8 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game
if (aeuh) if (aeuh)
{ {
GameMode->SetCurrentPlaylistName(aeuh);
/* if (Fortnite_Version >= 13) /* if (Fortnite_Version >= 13)
{ {
static auto LastSafeZoneIndexOffset = aeuh->GetOffset("LastSafeZoneIndex"); static auto LastSafeZoneIndexOffset = aeuh->GetOffset("LastSafeZoneIndex");
@@ -187,14 +189,14 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game
} }
} */ } */
} }
GameState->OnRep_CurrentPlaylistInfo();
} }
else else
{ {
GameState->Get("CurrentPlaylistData") = Playlist; GameState->Get("CurrentPlaylistData") = Playlist;
GameState->OnRep_CurrentPlaylistInfo(); // calls OnRep_CurrentPlaylistData
} }
if (bOnRep)
GameState->OnRep_CurrentPlaylistInfo();
}; };
auto& LocalPlayers = GetLocalPlayers(); auto& LocalPlayers = GetLocalPlayers();
@@ -212,22 +214,20 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game
LOG_INFO(LogDev, "Presetup!"); LOG_INFO(LogDev, "Presetup!");
GameMode->Get<int>("WarmupRequiredPlayerCount") = 1; GameMode->Get<int>("WarmupRequiredPlayerCount") = 1;
{ auto PlaylistToUse = GetPlaylistToUse();
auto PlaylistToUse = GetPlaylistToUse();
if (!PlaylistToUse) if (!PlaylistToUse)
{ {
LOG_ERROR(LogPlaylist, "Failed to find playlist! Proceeding, but will probably not work as expected!"); LOG_ERROR(LogPlaylist, "Failed to find playlist! Proceeding, but will probably not work as expected!");
}
else
{
SetPlaylist(PlaylistToUse);
LOG_INFO(LogDev, "Set playlist!");
}
} }
else
{
SetPlaylist(PlaylistToUse, true);
LOG_INFO(LogDev, "Set playlist!");
}
// if (false) // if (false)
{ {
auto Fortnite_Season = std::floor(Fortnite_Version); auto Fortnite_Season = std::floor(Fortnite_Version);
@@ -472,6 +472,12 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game
GameState->Get<float>("WarmupCountdownStartTime") = TimeSeconds; GameState->Get<float>("WarmupCountdownStartTime") = TimeSeconds;
GameMode->Get<float>("WarmupEarlyCountdownDuration") = EarlyDuration; GameMode->Get<float>("WarmupEarlyCountdownDuration") = EarlyDuration;
static auto GameSessionOffset = GameMode->GetOffset("GameSession");
auto GameSession = GameMode->Get<AActor*>(GameSessionOffset);
static auto MaxPlayersOffset = GameSession->GetOffset("MaxPlayers");
GameSession->Get<int>(MaxPlayersOffset) = 100;
/* /*
auto AllMegaStormManagers = UGameplayStatics::GetAllActorsOfClass(GetWorld(), GameMode->Get<UClass*>("MegaStormManagerClass")); auto AllMegaStormManagers = UGameplayStatics::GetAllActorsOfClass(GetWorld(), GameMode->Get<UClass*>("MegaStormManagerClass"));
@@ -523,14 +529,19 @@ bool AFortGameModeAthena::Athena_ReadyToStartMatchHook(AFortGameModeAthena* Game
if (Engine_Version >= 424) // returning true is stripped on c2+ if (Engine_Version >= 424) // returning true is stripped on c2+
{ {
if (GameState->GetPlayersLeft() >= GameMode->Get<int>("WarmupRequiredPlayerCount")) static auto WarmupRequiredPlayerCountOffset = GameMode->GetOffset("WarmupRequiredPlayerCount");
if (GameState->GetPlayersLeft() >= GameMode->Get<int>(WarmupRequiredPlayerCountOffset))
{ {
if (MapInfo) if (MapInfo)
{ {
static auto FlightInfosOffset = MapInfo->GetOffset("FlightInfos"); static auto FlightInfosOffset = MapInfo->GetOffset("FlightInfos");
if (MapInfo->Get<TArray<__int64>>(FlightInfosOffset).ArrayNum <= 0) // if (MapInfo->Get<TArray<__int64>>(FlightInfosOffset).ArrayNum > 0)
{
LOG_INFO(LogDev, "ReadyToStartMatch Return Address: 0x{:x}", __int64(_ReturnAddress()) - __int64(GetModuleHandleW(0)));
return true; return true;
}
} }
} }
} }
@@ -571,7 +582,7 @@ void AFortGameModeAthena::Athena_HandleStartingNewPlayerHook(AFortGameModeAthena
// GameState->OnRep_CurrentPlaylistInfo(); // GameState->OnRep_CurrentPlaylistInfo();
} }
static bool bSpawnedFloorLoot = true; static bool bSpawnedFloorLoot = false;
if (!bSpawnedFloorLoot) if (!bSpawnedFloorLoot)
{ {

View File

@@ -32,7 +32,7 @@ std::pair<std::vector<UFortItem*>, std::vector<UFortItem*>> AFortInventory::AddI
auto MaxStackSize = ItemDefinition->GetMaxStackSize(); auto MaxStackSize = ItemDefinition->GetMaxStackSize();
bool bAllowMultipleStacks = true; bool bAllowMultipleStacks = ItemDefinition->DoesAllowMultipleStacks();
int OverStack = 0; int OverStack = 0;
std::vector<UFortItem*> NewItemInstances; std::vector<UFortItem*> NewItemInstances;

View File

@@ -160,7 +160,7 @@ void UFortKismetLibrary::K2_RemoveItemFromPlayerHook(UObject* Context, FFrame& S
if (bShouldUpdate) if (bShouldUpdate)
WorldInventory->Update(); WorldInventory->Update();
LOG_INFO(LogDev, "Removed!"); LOG_INFO(LogDev, "Removed {}!", AmountToRemove);
return K2_RemoveItemFromPlayerOriginal(Context, Stack, Ret); return K2_RemoveItemFromPlayerOriginal(Context, Stack, Ret);
} }
@@ -249,6 +249,54 @@ void UFortKismetLibrary::K2_RemoveFortItemFromPlayerHook(UObject* Context, FFram
return K2_RemoveFortItemFromPlayerOriginal(Context, Stack, Ret); 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) AFortPickup* UFortKismetLibrary::K2_SpawnPickupInWorldHook(UObject* Context, FFrame& Stack, AFortPickup** Ret)
{ {
UObject* WorldContextObject; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic) UObject* WorldContextObject; // (Parm, ZeroConstructor, IsPlainOldData, NoDestructor, HasGetValueTypeHash, NativeAccessSpecifierPublic)

View File

@@ -19,6 +19,7 @@ public:
static inline void (*K2_RemoveFortItemFromPlayerOriginal)(UObject* Context, FFrame& Stack, void* Ret); static inline void (*K2_RemoveFortItemFromPlayerOriginal)(UObject* Context, FFrame& Stack, void* Ret);
static inline AFortPickup* (*K2_SpawnPickupInWorldOriginal)(UObject* Context, FFrame& Stack, AFortPickup** Ret); static inline AFortPickup* (*K2_SpawnPickupInWorldOriginal)(UObject* Context, FFrame& Stack, AFortPickup** Ret);
static inline bool (*PickLootDropsOriginal)(UObject* Context, FFrame& Stack, bool* 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 UFortResourceItemDefinition* K2_GetResourceItemDefinition(EFortResourceType ResourceType);
static void ApplyCharacterCosmetics(UObject* WorldContextObject, const TArray<UObject*>& CharacterParts, UObject* PlayerState, bool* bSuccess); static void ApplyCharacterCosmetics(UObject* WorldContextObject, const TArray<UObject*>& CharacterParts, UObject* PlayerState, bool* bSuccess);
@@ -29,6 +30,7 @@ public:
static void K2_GiveItemToPlayerHook(UObject* Context, FFrame& Stack, void* Ret); static void K2_GiveItemToPlayerHook(UObject* Context, FFrame& Stack, void* Ret);
static void K2_RemoveFortItemFromPlayerHook(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_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 bool PickLootDropsHook(UObject* Context, FFrame& Stack, bool* Ret);
static UClass* StaticClass(); static UClass* StaticClass();

View File

@@ -77,6 +77,8 @@ static FFortLootPackageData* GetLootPackage2(std::vector<FFortLootPackageData*>&
static FFortLootTierData* GetLootTierData(std::vector<FFortLootTierData*>& LootTierData, bool bPrint) static FFortLootTierData* GetLootTierData(std::vector<FFortLootTierData*>& LootTierData, bool bPrint)
{ {
return GetLootTierData2(LootTierData, bPrint);
float TotalWeight = 0; float TotalWeight = 0;
for (auto Item : LootTierData) for (auto Item : LootTierData)
@@ -117,6 +119,8 @@ static FFortLootTierData* GetLootTierData(std::vector<FFortLootTierData*>& LootT
static FFortLootPackageData* GetLootPackage(std::vector<FFortLootPackageData*>& LootPackages) static FFortLootPackageData* GetLootPackage(std::vector<FFortLootPackageData*>& LootPackages)
{ {
return GetLootPackage2(LootPackages);
float TotalWeight = 0; float TotalWeight = 0;
for (auto Item : LootPackages) for (auto Item : LootPackages)

View File

@@ -21,6 +21,22 @@ bool AFortPawn::PickUpActor(AActor* PickupTarget, UFortDecoItemDefinition* Place
return AFortPawn_PickUpActor_Params.ReturnValue; return AFortPawn_PickUpActor_Params.ReturnValue;
} }
void AFortPawn::SetHealth(float NewHealth)
{
static auto SetHealthFn = FindObject<UFunction>("/Script/FortniteGame.FortPawn.SetHealth");
if (SetHealthFn)
this->ProcessEvent(SetHealthFn, &NewHealth);
}
void AFortPawn::SetShield(float NewShield)
{
static auto SetShieldFn = FindObject<UFunction>("/Script/FortniteGame.FortPawn.SetShield");
if (SetShieldFn)
this->ProcessEvent(SetShieldFn, &NewShield);
}
UClass* AFortPawn::StaticClass() UClass* AFortPawn::StaticClass()
{ {
static auto Class = FindObject<UClass>("/Script/FortniteGame.FortPawn"); static auto Class = FindObject<UClass>("/Script/FortniteGame.FortPawn");

View File

@@ -24,5 +24,8 @@ public:
return ReadBitfieldValue(bIsDBNOOffset, bIsDBNOFieldMask); return ReadBitfieldValue(bIsDBNOOffset, bIsDBNOFieldMask);
} }
void SetHealth(float NewHealth);
void SetShield(float NewShield);
static UClass* StaticClass(); static UClass* StaticClass();
}; };

View File

@@ -17,12 +17,12 @@ void AFortPickup::TossPickup(FVector FinalLocation, AFortPawn* ItemOwner, int Ov
this->ProcessEvent(fn, &AFortPickup_TossPickup_Params); 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<UClass>(L"/Script/FortniteGame.FortPickup"); static auto FortPickupClass = FindObject<UClass>(L"/Script/FortniteGame.FortPickup");
auto PlayerState = Pawn ? Cast<AFortPlayerState>(Pawn->GetPlayerState()) : nullptr; auto PlayerState = Pawn ? Cast<AFortPlayerState>(Pawn->GetPlayerState()) : nullptr;
if (auto Pickup = GetWorld()->SpawnActor<AFortPickup>(FortPickupClass, Location)) if (auto Pickup = GetWorld()->SpawnActor<AFortPickup>(OverrideClass ? OverrideClass : FortPickupClass, Location))
{ {
static auto PawnWhoDroppedPickupOffset = Pickup->GetOffset("PawnWhoDroppedPickup"); static auto PawnWhoDroppedPickupOffset = Pickup->GetOffset("PawnWhoDroppedPickup");

View File

@@ -83,7 +83,7 @@ public:
static AFortPickup* SpawnPickup(class UFortItemDefinition* ItemDef, FVector Location, int Count, static AFortPickup* SpawnPickup(class UFortItemDefinition* ItemDef, FVector Location, int Count,
EFortPickupSourceTypeFlag PickupSource = EFortPickupSourceTypeFlag::Other, EFortPickupSpawnSource SpawnSource = EFortPickupSpawnSource::Unset, 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); static char CompletePickupAnimationHook(AFortPickup* Pickup);
}; };

View File

@@ -16,6 +16,7 @@
#include "FortPickup.h" #include "FortPickup.h"
#include "FortPlayerPawn.h" #include "FortPlayerPawn.h"
#include <memcury.h> #include <memcury.h>
#include "KismetStringLibrary.h"
void AFortPlayerController::ClientReportDamagedResourceBuilding(ABuildingSMActor* BuildingSMActor, EFortResourceType PotentialResourceType, int PotentialResourceCount, bool bDestroyed, bool bJustHitWeakspot) 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) void AFortPlayerController::ServerAttemptInteractHook(UObject* Context, FFrame* Stack, void* Ret)
{ {
static auto LlamaClass = FindObject<UClass>("/Game/Athena/SupplyDrops/Llama/AthenaSupplyDrop_Llama.AthenaSupplyDrop_Llama_C");
static auto FortAthenaSupplyDropClass = FindObject<UClass>("/Script/FortniteGame.FortAthenaSupplyDrop");
LOG_INFO(LogInteraction, "ServerAttemptInteract!"); LOG_INFO(LogInteraction, "ServerAttemptInteract!");
auto Params = Stack->Locals; auto Params = Stack->Locals;
@@ -157,6 +161,8 @@ void AFortPlayerController::ServerAttemptInteractHook(UObject* Context, FFrame*
// LOG_INFO(LogInteraction, "ReceivingActor Name: {}", ReceivingActor->GetFullName()); // LOG_INFO(LogInteraction, "ReceivingActor Name: {}", ReceivingActor->GetFullName());
FVector LocationToSpawnLoot = ReceivingActor->GetActorLocation() + ReceivingActor->GetActorRightVector() * 70.f + FVector{ 0, 0, 50 };
static auto FortAthenaVehicleClass = FindObject<UClass>("/Script/FortniteGame.FortAthenaVehicle"); static auto FortAthenaVehicleClass = FindObject<UClass>("/Script/FortniteGame.FortAthenaVehicle");
if (auto BuildingContainer = Cast<ABuildingContainer>(ReceivingActor)) if (auto BuildingContainer = Cast<ABuildingContainer>(ReceivingActor))
@@ -188,8 +194,6 @@ void AFortPlayerController::ServerAttemptInteractHook(UObject* Context, FFrame*
LOG_INFO(LogInteraction, "LootDrops.size(): {}", LootDrops.size()); 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++) for (int i = 0; i < LootDrops.size(); i++)
{ {
auto& lootDrop = LootDrops.at(i); auto& lootDrop = LootDrops.at(i);
@@ -273,6 +277,17 @@ void AFortPlayerController::ServerAttemptInteractHook(UObject* Context, FFrame*
return; 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); return ServerAttemptInteractOriginal(Context, Stack, Ret);
} }
@@ -304,6 +319,11 @@ void AFortPlayerController::ServerAttemptAircraftJumpHook(AFortPlayerController*
auto NewPawn = GameMode->SpawnDefaultPawnForHook(GameMode, (AController*)PlayerController, Aircrafts->at(0)); auto NewPawn = GameMode->SpawnDefaultPawnForHook(GameMode, (AController*)PlayerController, Aircrafts->at(0));
PlayerController->Possess(NewPawn); PlayerController->Possess(NewPawn);
auto NewPawnAsFort = Cast<AFortPawn>(NewPawn);
if (NewPawnAsFort)
NewPawnAsFort->SetHealth(100);
// PlayerController->ServerRestartPlayer(); // PlayerController->ServerRestartPlayer();
} }
@@ -437,6 +457,35 @@ void AFortPlayerController::ServerCreateBuildingActorHook(UObject* Context, FFra
return ServerCreateBuildingActorOriginal(Context, Stack, Ret); 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<AFortPlayerController>(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) void AFortPlayerController::ServerAttemptInventoryDropHook(AFortPlayerController* PlayerController, FGuid ItemGuid, int Count)
{ {
LOG_INFO(LogDev, "ServerAttemptInventoryDropHook!"); LOG_INFO(LogDev, "ServerAttemptInventoryDropHook!");
@@ -625,6 +674,12 @@ void AFortPlayerController::ClientOnPawnDiedHook(AFortPlayerController* PlayerCo
// KillerPlayerState->OnRep_Kills(); // KillerPlayerState->OnRep_Kills();
} }
if (KillerPawn && KillerPawn != DeadPawn)
{
KillerPawn->SetHealth(100);
KillerPawn->SetShield(100);
}
bool bIsRespawningAllowed = GameState->IsRespawningAllowed(DeadPlayerState); bool bIsRespawningAllowed = GameState->IsRespawningAllowed(DeadPlayerState);
if (!bIsRespawningAllowed) if (!bIsRespawningAllowed)

View File

@@ -29,6 +29,7 @@ public:
static inline void (*ClientOnPawnDiedOriginal)(AFortPlayerController* PlayerController, void* DeathReport); static inline void (*ClientOnPawnDiedOriginal)(AFortPlayerController* PlayerController, void* DeathReport);
static inline void (*ServerCreateBuildingActorOriginal)(UObject* Context, FFrame* Stack, void* Ret); static inline void (*ServerCreateBuildingActorOriginal)(UObject* Context, FFrame* Stack, void* Ret);
static inline void (*ServerAttemptInteractOriginal)(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); 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 ServerAttemptAircraftJumpHook(AFortPlayerController* PC, FRotator ClientRotation);
// static void ServerCreateBuildingActorHook(AFortPlayerController* PlayerController, FCreateBuildingActorData CreateBuildingData); // static void ServerCreateBuildingActorHook(AFortPlayerController* PlayerController, FCreateBuildingActorData CreateBuildingData);
static void ServerCreateBuildingActorHook(UObject* Context, FFrame* Stack, void* Ret); 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); static void ServerDropAllItemsHook(AFortPlayerController* PlayerController, UFortItemDefinition* IgnoreItemDef);

View File

@@ -24,68 +24,15 @@ void AFortPlayerPawn::ServerSendZiplineStateHook(AFortPlayerPawn* Pawn, FZipline
if (*(int*)(__int64(&InZiplineState) + AuthoritativeValueOffset) > *(int*)(__int64(PawnZiplineState) + AuthoritativeValueOffset)) if (*(int*)(__int64(&InZiplineState) + AuthoritativeValueOffset) > *(int*)(__int64(PawnZiplineState) + AuthoritativeValueOffset))
{ {
static auto ZiplinePawnStateClass = FindObject<UStruct>("/Script/FortniteGame.ZiplinePawnState"); static auto ZiplinePawnStateStruct = FindObject<UStruct>("/Script/FortniteGame.ZiplinePawnState");
static auto ZiplinePawnStateSize = ZiplinePawnStateClass->GetPropertiesSize(); static auto ZiplinePawnStateSize = ZiplinePawnStateStruct->GetPropertiesSize();
CopyStruct(PawnZiplineState, &InZiplineState, ZiplinePawnStateSize); CopyStruct(PawnZiplineState, &InZiplineState, ZiplinePawnStateSize);
} }
static bool bFoundFunc = false; static bool bFoundFunc = false;
static void (*OnRep_ZiplineState)(AFortPlayerPawn* Pawn); static void (*OnRep_ZiplineState)(AFortPlayerPawn* Pawn) = decltype(OnRep_ZiplineState)(Addresses::OnRep_ZiplineState);
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)));
}
if (OnRep_ZiplineState) if (OnRep_ZiplineState)
OnRep_ZiplineState(Pawn); OnRep_ZiplineState(Pawn);

View File

@@ -180,6 +180,7 @@
<ClCompile Include="FortAthenaCreativePortal.cpp" /> <ClCompile Include="FortAthenaCreativePortal.cpp" />
<ClCompile Include="FortAthenaSupplyDrop.cpp" /> <ClCompile Include="FortAthenaSupplyDrop.cpp" />
<ClCompile Include="FortDecoItemDefinition.cpp" /> <ClCompile Include="FortDecoItemDefinition.cpp" />
<ClCompile Include="FortGameMode.cpp" />
<ClCompile Include="FortGameModeAthena.cpp" /> <ClCompile Include="FortGameModeAthena.cpp" />
<ClCompile Include="FortGameModeZone.cpp" /> <ClCompile Include="FortGameModeZone.cpp" />
<ClCompile Include="FortGameStateAthena.cpp" /> <ClCompile Include="FortGameStateAthena.cpp" />

View File

@@ -149,6 +149,9 @@
<ClCompile Include="Controller.cpp"> <ClCompile Include="Controller.cpp">
<Filter>Engine\Source\Runtime\Engine\Private</Filter> <Filter>Engine\Source\Runtime\Engine\Private</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="FortGameMode.cpp">
<Filter>FortniteGame\Source\FortniteGame\Private</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="log.h" /> <ClInclude Include="log.h" />

View File

@@ -236,6 +236,12 @@ void Addresses::FindAll()
LOG_INFO(LogDev, "Finding CallPreReplication"); LOG_INFO(LogDev, "Finding CallPreReplication");
Addresses::CallPreReplication = FindCallPreReplication(); 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!"); LOG_INFO(LogDev, "Finished finding!");
} }
@@ -284,6 +290,8 @@ void Addresses::Print()
LOG_INFO(LogDev, "SendClientAdjustment: 0x{:x}", SendClientAdjustment - Base); LOG_INFO(LogDev, "SendClientAdjustment: 0x{:x}", SendClientAdjustment - Base);
LOG_INFO(LogDev, "CreateChannel: 0x{:x}", CreateChannel - Base); LOG_INFO(LogDev, "CreateChannel: 0x{:x}", CreateChannel - Base);
LOG_INFO(LogDev, "CallPreReplication: 0x{:x}", CallPreReplication - 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() void Offsets::FindAll()

View File

@@ -50,6 +50,7 @@ namespace Addresses
extern inline uint64 SetChannelActor = 0; extern inline uint64 SetChannelActor = 0;
extern inline uint64 SendClientAdjustment = 0; extern inline uint64 SendClientAdjustment = 0;
extern inline uint64 FrameStep = 0; extern inline uint64 FrameStep = 0;
extern inline uint64 OnRep_ZiplineState = 0;
void SetupVersion(); // Finds Engine Version void SetupVersion(); // Finds Engine Version
void FindAll(); void FindAll();

View File

@@ -262,8 +262,7 @@ void ServerCheatHook(AFortPlayerControllerAthena* PlayerController, FString Msg)
try { Health = std::stof(Arguments[1]); } try { Health = std::stof(Arguments[1]); }
catch (...) {} catch (...) {}
static auto SetHealthFn = FindObject<UFunction>("/Script/FortniteGame.FortPawn.SetHealth"); Pawn->SetHealth(Health);
Pawn->ProcessEvent(SetHealthFn, &Health);
SendMessageToConsole(PlayerController, L"Set health!\n"); SendMessageToConsole(PlayerController, L"Set health!\n");
} }
else if (Command == "testspawn") else if (Command == "testspawn")

View File

@@ -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 ENetMode GetNetModeHook2() { /* std::cout << "AA!\n"; */ return ENetMode::NM_DedicatedServer; }
static bool ReturnTrueHook() { return true; } static bool ReturnTrueHook() { return true; }
static float GetMaxTickRateHook() { return 30.f; }
static int Return2Hook() { return 2; } static int Return2Hook() { return 2; }
static void NoMCPHook() { return; } static void NoMCPHook() { return; }
@@ -82,6 +83,8 @@ DWORD WINAPI Main(LPVOID)
static auto FortKismetLibraryDefault = FindObject<UClass>(L"/Script/FortniteGame.Default__FortKismetLibrary"); static auto FortKismetLibraryDefault = FindObject<UClass>(L"/Script/FortniteGame.Default__FortKismetLibrary");
UKismetSystemLibrary::ExecuteConsoleCommand(GetWorld(), L"log LogAbilitySystem VeryVerbose", nullptr); 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<UFunction>(L"/Script/Engine.PlayerController.SwitchLevel"); static auto SwitchLevel = FindObject<UFunction>(L"/Script/Engine.PlayerController.SwitchLevel");
FString Level = Engine_Version < 424 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 if (Addresses::FrameStep) // put all non rpc exec hooks in this scope
{ {
Hooking::MinHook::Hook(FortKismetLibraryDefault, FindObject<UFunction>(L"Script/FortniteGame.FortKismetLibrary.K2_GiveItemToPlayer"), Hooking::MinHook::Hook(FortKismetLibraryDefault, FindObject<UFunction>(L"/Script/FortniteGame.FortKismetLibrary.K2_GiveItemToPlayer"),
UFortKismetLibrary::K2_GiveItemToPlayerHook, (PVOID*)&UFortKismetLibrary::K2_GiveItemToPlayerOriginal, false, true); UFortKismetLibrary::K2_GiveItemToPlayerHook, (PVOID*)&UFortKismetLibrary::K2_GiveItemToPlayerOriginal, false, true);
Hooking::MinHook::Hook(FortKismetLibraryDefault, FindObject<UFunction>(L"/Script/FortniteGame.FortKismetLibrary.GiveItemToInventoryOwner"), Hooking::MinHook::Hook(FortKismetLibraryDefault, FindObject<UFunction>(L"/Script/FortniteGame.FortKismetLibrary.GiveItemToInventoryOwner"),
UFortKismetLibrary::GiveItemToInventoryOwnerHook, (PVOID*)&UFortKismetLibrary::GiveItemToInventoryOwnerOriginal, false, true); UFortKismetLibrary::GiveItemToInventoryOwnerHook, (PVOID*)&UFortKismetLibrary::GiveItemToInventoryOwnerOriginal, false, true);
@@ -234,6 +237,11 @@ DWORD WINAPI Main(LPVOID)
UFortKismetLibrary::K2_RemoveFortItemFromPlayerHook, (PVOID*)&UFortKismetLibrary::K2_RemoveFortItemFromPlayerOriginal, false, true); UFortKismetLibrary::K2_RemoveFortItemFromPlayerHook, (PVOID*)&UFortKismetLibrary::K2_RemoveFortItemFromPlayerOriginal, false, true);
Hooking::MinHook::Hook(FortKismetLibraryDefault, FindObject<UFunction>(L"/Script/FortniteGame.FortKismetLibrary.K2_SpawnPickupInWorld"), Hooking::MinHook::Hook(FortKismetLibraryDefault, FindObject<UFunction>(L"/Script/FortniteGame.FortKismetLibrary.K2_SpawnPickupInWorld"),
UFortKismetLibrary::K2_SpawnPickupInWorldHook, (PVOID*)&UFortKismetLibrary::K2_SpawnPickupInWorldOriginal, false, true); UFortKismetLibrary::K2_SpawnPickupInWorldHook, (PVOID*)&UFortKismetLibrary::K2_SpawnPickupInWorldOriginal, false, true);
Hooking::MinHook::Hook(FortKismetLibraryDefault, FindObject<UFunction>(L"/Script/FortniteGame.FortKismetLibrary:K2_SpawnPickupInWorldWithClass"),
UFortKismetLibrary::K2_SpawnPickupInWorldWithClassHook, (PVOID*)&UFortKismetLibrary::K2_SpawnPickupInWorldWithClassOriginal, false, true);
Hooking::MinHook::Hook(FortPlayerControllerAthenaDefault, FindObject<UFunction>(L"/Script/FortniteGame.FortPlayerController.DropSpecificItem"),
AFortPlayerController::DropSpecificItemHook, (PVOID*)&AFortPlayerController::DropSpecificItemOriginal, false, true);
static auto FortAthenaSupplyDropDefault = FindObject("/Script/FortniteGame.Default__FortAthenaSupplyDrop"); static auto FortAthenaSupplyDropDefault = FindObject("/Script/FortniteGame.Default__FortAthenaSupplyDrop");
@@ -303,6 +311,7 @@ DWORD WINAPI Main(LPVOID)
if (Engine_Version < 427) if (Engine_Version < 427)
Hooking::MinHook::Hook((PVOID)Addresses::OnDamageServer, (PVOID)ABuildingActor::OnDamageServerHook, (PVOID*)&ABuildingActor::OnDamageServerOriginal); 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::CollectGarbage, (PVOID)CollectGarbageHook, nullptr);
Hooking::MinHook::Hook((PVOID)Addresses::PickTeam, (PVOID)AFortGameModeAthena::Athena_PickTeamHook); Hooking::MinHook::Hook((PVOID)Addresses::PickTeam, (PVOID)AFortGameModeAthena::Athena_PickTeamHook);
// Hooking::MinHook::Hook((PVOID)Addresses::SetZoneToIndex, (PVOID)AFortGameModeAthena::SetZoneToIndexHook, (PVOID*)&AFortGameModeAthena::SetZoneToIndexOriginal); // 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"); 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<int*>() / 8;
LOG_INFO(LogHook, "GetMaxTickRateIndex {}", GetMaxTickRateIndex); */
srand(time(0)); srand(time(0));
LOG_INFO(LogHook, "Finished!"); LOG_INFO(LogHook, "Finished!");

View File

@@ -215,6 +215,55 @@ static inline uint64 FindPauseBeaconRequests()
return FindBytes(Addr, { 0x40, 0x53 }, 1000, 0, true); 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<int*>() / 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() 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 // 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