mirror of
https://github.com/Milxnor/Project-Reboot-3.0.git
synced 2026-01-13 02:42:22 +01:00
a bit
fix some crashes on playlists when restarting, fix large team gamemode teams (kinda), added pickups to minimap
This commit is contained in:
@@ -7,6 +7,14 @@ UObject* UClass::CreateDefaultObject()
|
|||||||
{
|
{
|
||||||
static std::unordered_map<std::string, UObject*> defaultAbilities; // normal class name, default ability.
|
static std::unordered_map<std::string, UObject*> defaultAbilities; // normal class name, default ability.
|
||||||
|
|
||||||
|
static int LastNum1 = 151;
|
||||||
|
|
||||||
|
if (LastNum1 != Globals::AmountOfListens)
|
||||||
|
{
|
||||||
|
LastNum1 = Globals::AmountOfListens;
|
||||||
|
defaultAbilities.clear();
|
||||||
|
}
|
||||||
|
|
||||||
auto name = this->GetFullName();
|
auto name = this->GetFullName();
|
||||||
|
|
||||||
if (name.contains("Default__"))
|
if (name.contains("Default__"))
|
||||||
|
|||||||
@@ -27,6 +27,8 @@ AFortPickup* AFortAthenaSupplyDrop::SpawnGameModePickupHook(UObject* Context, FF
|
|||||||
if (!ItemDefinition || !PickupClass)
|
if (!ItemDefinition || !PickupClass)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
|
LOG_INFO(LogDev, "Spawning GameModePickup with ItemDefinition: {}", ItemDefinition->GetFullName());
|
||||||
|
|
||||||
*Ret = AFortPickup::SpawnPickup(ItemDefinition, Position, NumberToSpawn, EFortPickupSourceTypeFlag::Other, EFortPickupSpawnSource::SupplyDrop, -1, TriggeringPawn, PickupClass);
|
*Ret = AFortPickup::SpawnPickup(ItemDefinition, Position, NumberToSpawn, EFortPickupSourceTypeFlag::Other, EFortPickupSpawnSource::SupplyDrop, -1, TriggeringPawn, PickupClass);
|
||||||
return *Ret;
|
return *Ret;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -722,6 +722,8 @@ int AFortGameModeAthena::Athena_PickTeamHook(AFortGameModeAthena* GameMode, uint
|
|||||||
|
|
||||||
static int NextTeamIndex = DefaultFirstTeam;
|
static int NextTeamIndex = DefaultFirstTeam;
|
||||||
|
|
||||||
|
LOG_INFO(LogTeams, "Before team assigning NextTeamIndex: {} CurrentTeamMembers: {}", NextTeamIndex, CurrentTeamMembers);
|
||||||
|
|
||||||
if (!bShouldSpreadTeams)
|
if (!bShouldSpreadTeams)
|
||||||
{
|
{
|
||||||
if (CurrentTeamMembers >= MaxSquadSize)
|
if (CurrentTeamMembers >= MaxSquadSize)
|
||||||
@@ -738,7 +740,7 @@ int AFortGameModeAthena::Athena_PickTeamHook(AFortGameModeAthena* GameMode, uint
|
|||||||
|
|
||||||
if (CurrentTeamMembers >= 1) // We spread every player.
|
if (CurrentTeamMembers >= 1) // We spread every player.
|
||||||
{
|
{
|
||||||
if (Idx > TeamsNum)
|
if (Idx >= TeamsNum)
|
||||||
NextTeamIndex = DefaultFirstTeam;
|
NextTeamIndex = DefaultFirstTeam;
|
||||||
else
|
else
|
||||||
NextTeamIndex++;
|
NextTeamIndex++;
|
||||||
@@ -747,7 +749,7 @@ int AFortGameModeAthena::Athena_PickTeamHook(AFortGameModeAthena* GameMode, uint
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_INFO(LogTeams, "Spreading Teams {} Player is going on team {} with {} members.", bShouldSpreadTeams, NextTeamIndex, CurrentTeamMembers);
|
LOG_INFO(LogTeams, "Spreading Teams {} [{}] Player is going on team {} with {} members.", bShouldSpreadTeams, TeamsNum, NextTeamIndex, CurrentTeamMembers);
|
||||||
|
|
||||||
CurrentTeamMembers++;
|
CurrentTeamMembers++;
|
||||||
|
|
||||||
|
|||||||
13
Project Reboot 3.0/FortGameModePickup.h
Normal file
13
Project Reboot 3.0/FortGameModePickup.h
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "FortPickup.h"
|
||||||
|
|
||||||
|
class AFortGameModePickup : public AFortPickup//Athena
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static UClass* StaticClass()
|
||||||
|
{
|
||||||
|
static auto Class = FindObject<UClass>("/Script/FortniteGame.FortGameModePickup");
|
||||||
|
return Class;
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -192,6 +192,7 @@ std::pair<std::vector<UFortItem*>, std::vector<UFortItem*>> AFortInventory::AddI
|
|||||||
|
|
||||||
if (WorldItemDefinition->ShouldFocusWhenAdded()) // Should we also do this for stacking?
|
if (WorldItemDefinition->ShouldFocusWhenAdded()) // Should we also do this for stacking?
|
||||||
{
|
{
|
||||||
|
LOG_INFO(LogDev, "Force focus {}", ItemDefinition->GetFullName());
|
||||||
FortPlayerController->ServerExecuteInventoryItemHook(FortPlayerController, NewItemInstance->GetItemEntry()->GetItemGuid());
|
FortPlayerController->ServerExecuteInventoryItemHook(FortPlayerController, NewItemInstance->GetItemEntry()->GetItemGuid());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#include "FortItemDefinition.h"
|
#include "FortItemDefinition.h"
|
||||||
#include "FortPlayerState.h"
|
#include "FortPlayerState.h"
|
||||||
#include "FortPlayerPawn.h"
|
#include "FortPlayerPawn.h"
|
||||||
|
#include "FortGameModePickup.h"
|
||||||
#include "FortPlayerController.h"
|
#include "FortPlayerController.h"
|
||||||
#include <memcury.h>
|
#include <memcury.h>
|
||||||
|
|
||||||
@@ -34,32 +35,33 @@ AFortPickup* AFortPickup::SpawnPickup(FFortItemEntry* ItemEntry, FVector Locatio
|
|||||||
static auto PawnWhoDroppedPickupOffset = Pickup->GetOffset("PawnWhoDroppedPickup");
|
static auto PawnWhoDroppedPickupOffset = Pickup->GetOffset("PawnWhoDroppedPickup");
|
||||||
Pickup->Get<AFortPawn*>(PawnWhoDroppedPickupOffset) = Pawn;
|
Pickup->Get<AFortPawn*>(PawnWhoDroppedPickupOffset) = Pawn;
|
||||||
|
|
||||||
/* static auto SpecialActorIDOffset = Pickup->GetOffset("SpecialActorID");
|
|
||||||
|
|
||||||
if (auto WorldItemDefinition = Cast<UFortWorldItemDefinition>(ItemDef))
|
|
||||||
{
|
|
||||||
static auto PickupSpecialActorUniqueIDOffset = WorldItemDefinition->GetOffset("PickupSpecialActorUniqueID");
|
|
||||||
auto& PickupSpecialActorUniqueID = WorldItemDefinition->Get<FName>(PickupSpecialActorUniqueIDOffset);
|
|
||||||
Pickup->Get<FName>(SpecialActorIDOffset) = PickupSpecialActorUniqueID;
|
|
||||||
} */
|
|
||||||
|
|
||||||
auto PrimaryPickupItemEntry = Pickup->GetPrimaryPickupItemEntry();
|
auto PrimaryPickupItemEntry = Pickup->GetPrimaryPickupItemEntry();
|
||||||
|
|
||||||
auto OldGuid = PrimaryPickupItemEntry->GetItemGuid();
|
if (Addresses::PickupInitialize)
|
||||||
|
|
||||||
if (false)
|
|
||||||
{
|
{
|
||||||
CopyStruct(PrimaryPickupItemEntry, ItemEntry, FFortItemEntry::GetStructSize(), FFortItemEntry::GetStruct());
|
static void (*SetupPickup)(AFortPickup * Pickup, __int64 ItemEntry, TArray<__int64> MultiItemPickupEntriesIGuess, bool bSplitOnPickup)
|
||||||
|
= decltype(SetupPickup)(Addresses::PickupInitialize); // 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());
|
||||||
|
TArray<__int64> MultiItemPickupEntriesIGuess{};
|
||||||
|
SetupPickup(Pickup, __int64(ItemEntry), MultiItemPickupEntriesIGuess, false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PrimaryPickupItemEntry->GetItemDefinition() = ItemEntry->GetItemDefinition();
|
auto OldGuid = PrimaryPickupItemEntry->GetItemGuid();
|
||||||
PrimaryPickupItemEntry->GetLoadedAmmo() = ItemEntry->GetLoadedAmmo();
|
|
||||||
|
if (false)
|
||||||
|
{
|
||||||
|
CopyStruct(PrimaryPickupItemEntry, ItemEntry, FFortItemEntry::GetStructSize(), FFortItemEntry::GetStruct());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PrimaryPickupItemEntry->GetItemDefinition() = ItemEntry->GetItemDefinition();
|
||||||
|
PrimaryPickupItemEntry->GetLoadedAmmo() = ItemEntry->GetLoadedAmmo();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PrimaryPickupItemEntry->GetCount() = OverrideCount == -1 ? ItemEntry->GetCount() : OverrideCount;
|
PrimaryPickupItemEntry->GetCount() = OverrideCount == -1 ? ItemEntry->GetCount() : OverrideCount;
|
||||||
|
|
||||||
PrimaryPickupItemEntry->GetItemGuid() = OldGuid;
|
// PrimaryPickupItemEntry->GetItemGuid() = OldGuid;
|
||||||
|
|
||||||
// Pickup->OnRep_PrimaryPickupItemEntry();
|
// Pickup->OnRep_PrimaryPickupItemEntry();
|
||||||
|
|
||||||
@@ -133,6 +135,12 @@ char AFortPickup::CompletePickupAnimationHook(AFortPickup* Pickup)
|
|||||||
if (!PickupItemDefinition)
|
if (!PickupItemDefinition)
|
||||||
return CompletePickupAnimationOriginal(Pickup);
|
return CompletePickupAnimationOriginal(Pickup);
|
||||||
|
|
||||||
|
if (auto GameModePickup = Cast<AFortGameModePickup>(Pickup))
|
||||||
|
{
|
||||||
|
LOG_INFO(LogDev, "GameModePickup!");
|
||||||
|
return CompletePickupAnimationOriginal(Pickup);
|
||||||
|
}
|
||||||
|
|
||||||
auto& ItemInstances = WorldInventory->GetItemList().GetItemInstances();
|
auto& ItemInstances = WorldInventory->GetItemList().GetItemInstances();
|
||||||
|
|
||||||
auto& CurrentItemGuid = Pickup->GetPickupLocationData()->GetPickupGuid(); // Pawn->CurrentWeapon->ItemEntryGuid;
|
auto& CurrentItemGuid = Pickup->GetPickupLocationData()->GetPickupGuid(); // Pawn->CurrentWeapon->ItemEntryGuid;
|
||||||
|
|||||||
@@ -20,13 +20,22 @@ void AFortPlayerControllerAthena::StartGhostModeHook(UObject* Context, FFrame* S
|
|||||||
Stack->StepCompiledIn(&ItemProvidingGhostMode);
|
Stack->StepCompiledIn(&ItemProvidingGhostMode);
|
||||||
|
|
||||||
if (!ItemProvidingGhostMode)
|
if (!ItemProvidingGhostMode)
|
||||||
|
{
|
||||||
|
LOG_INFO(LogDev, "Null item!");
|
||||||
return StartGhostModeOriginal(Context, Stack, Ret);
|
return StartGhostModeOriginal(Context, Stack, Ret);
|
||||||
|
}
|
||||||
|
|
||||||
// if (!Controller->HasAuthority) return StartGhostModeOriginal(Context, Stack, Ret);
|
// if (!Controller->HasAuthority()) return StartGhostModeOriginal(Context, Stack, Ret);
|
||||||
|
|
||||||
|
LOG_INFO(LogDev, "Attempting to give item {}", ItemProvidingGhostMode->IsValidLowLevel() ? ItemProvidingGhostMode->GetFullName() : "BadRead");
|
||||||
|
|
||||||
auto GhostModeRepData = Controller->GetGhostModeRepData();
|
auto GhostModeRepData = Controller->GetGhostModeRepData();
|
||||||
|
|
||||||
if (GhostModeRepData->IsInGhostMode()) return StartGhostModeOriginal(Context, Stack, Ret);
|
if (GhostModeRepData->IsInGhostMode())
|
||||||
|
{
|
||||||
|
LOG_INFO(LogDev, "Player is already in ghost mode!");
|
||||||
|
return StartGhostModeOriginal(Context, Stack, Ret);
|
||||||
|
}
|
||||||
|
|
||||||
auto WorldInventory = Controller->GetWorldInventory();
|
auto WorldInventory = Controller->GetWorldInventory();
|
||||||
|
|
||||||
@@ -44,6 +53,7 @@ void AFortPlayerControllerAthena::StartGhostModeHook(UObject* Context, FFrame* S
|
|||||||
WorldInventory->Update();
|
WorldInventory->Update();
|
||||||
|
|
||||||
Controller->ServerExecuteInventoryItemHook(Controller, GhostModeItemInstance->GetItemEntry()->GetItemGuid());
|
Controller->ServerExecuteInventoryItemHook(Controller, GhostModeItemInstance->GetItemEntry()->GetItemGuid());
|
||||||
|
LOG_INFO(LogDev, "Finished!");
|
||||||
|
|
||||||
return StartGhostModeOriginal(Context, Stack, Ret);
|
return StartGhostModeOriginal(Context, Stack, Ret);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -203,7 +203,7 @@ public:
|
|||||||
auto& CurrentAbilitySetSoft = CurrentAbilitySets.at(j);
|
auto& CurrentAbilitySetSoft = CurrentAbilitySets.at(j);
|
||||||
auto CurrentAbilitySet = CurrentAbilitySetSoft.Get(UFortAbilitySet::StaticClass(), true);
|
auto CurrentAbilitySet = CurrentAbilitySetSoft.Get(UFortAbilitySet::StaticClass(), true);
|
||||||
|
|
||||||
if (!CurrentAbilitySet)
|
if (!CurrentAbilitySet->IsValidLowLevel())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
CurrentAbilitySet->GiveToAbilitySystem(AbilitySystemComponent);
|
CurrentAbilitySet->GiveToAbilitySystem(AbilitySystemComponent);
|
||||||
|
|||||||
@@ -5,5 +5,5 @@
|
|||||||
class APlayerState : public AActor
|
class APlayerState : public AActor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
int& GetPlayerID();
|
int& GetPlayerID(); // for future me to deal with (this is a short on some versions).
|
||||||
};
|
};
|
||||||
@@ -315,6 +315,7 @@
|
|||||||
<ClInclude Include="FortGadgetItemDefinition.h" />
|
<ClInclude Include="FortGadgetItemDefinition.h" />
|
||||||
<ClInclude Include="FortGameMode.h" />
|
<ClInclude Include="FortGameMode.h" />
|
||||||
<ClInclude Include="FortGameModeAthena.h" />
|
<ClInclude Include="FortGameModeAthena.h" />
|
||||||
|
<ClInclude Include="FortGameModePickup.h" />
|
||||||
<ClInclude Include="FortGameModePvPBase.h" />
|
<ClInclude Include="FortGameModePvPBase.h" />
|
||||||
<ClInclude Include="FortGameModeZone.h" />
|
<ClInclude Include="FortGameModeZone.h" />
|
||||||
<ClInclude Include="FortGameplayAbilityAthena_PeriodicItemGrant.h" />
|
<ClInclude Include="FortGameplayAbilityAthena_PeriodicItemGrant.h" />
|
||||||
|
|||||||
@@ -803,6 +803,9 @@
|
|||||||
<ClInclude Include="TypeWrapper.h">
|
<ClInclude Include="TypeWrapper.h">
|
||||||
<Filter>Engine\Source\Runtime\Core\Public\Templates</Filter>
|
<Filter>Engine\Source\Runtime\Core\Public\Templates</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="FortGameModePickup.h">
|
||||||
|
<Filter>FortniteGame\Source\FortniteGame\Public\Items</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Filter Include="Engine">
|
<Filter Include="Engine">
|
||||||
|
|||||||
@@ -268,6 +268,9 @@ void Addresses::FindAll()
|
|||||||
LOG_INFO(LogDev, "Finding SetTimer");
|
LOG_INFO(LogDev, "Finding SetTimer");
|
||||||
Addresses::SetTimer = FindSetTimer();
|
Addresses::SetTimer = FindSetTimer();
|
||||||
|
|
||||||
|
LOG_INFO(LogDev, "Finding PickupInitialize");
|
||||||
|
Addresses::PickupInitialize = FindPickupInitialize();
|
||||||
|
|
||||||
LOG_INFO(LogDev, "Finished finding!");
|
LOG_INFO(LogDev, "Finished finding!");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -329,6 +332,7 @@ void Addresses::Print()
|
|||||||
LOG_INFO(LogDev, "ApplyCharacterCustomization: 0x{:x}", ApplyCharacterCustomization - Base);
|
LOG_INFO(LogDev, "ApplyCharacterCustomization: 0x{:x}", ApplyCharacterCustomization - Base);
|
||||||
LOG_INFO(LogDev, "EnterAircraft: 0x{:x}", EnterAircraft - Base);
|
LOG_INFO(LogDev, "EnterAircraft: 0x{:x}", EnterAircraft - Base);
|
||||||
LOG_INFO(LogDev, "SetTimer: 0x{:x}", SetTimer - Base);
|
LOG_INFO(LogDev, "SetTimer: 0x{:x}", SetTimer - Base);
|
||||||
|
LOG_INFO(LogDev, "PickupInitialize: 0x{:x}", PickupInitialize - Base);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Offsets::FindAll()
|
void Offsets::FindAll()
|
||||||
|
|||||||
@@ -62,6 +62,7 @@ namespace Addresses
|
|||||||
extern inline uint64 GetInterfaceAddress = 0;
|
extern inline uint64 GetInterfaceAddress = 0;
|
||||||
extern inline uint64 EnterAircraft = 0;
|
extern inline uint64 EnterAircraft = 0;
|
||||||
extern inline uint64 SetTimer = 0;
|
extern inline uint64 SetTimer = 0;
|
||||||
|
extern inline uint64 PickupInitialize = 0;
|
||||||
|
|
||||||
void SetupVersion(); // Finds Engine Version
|
void SetupVersion(); // Finds Engine Version
|
||||||
void FindAll();
|
void FindAll();
|
||||||
|
|||||||
@@ -497,6 +497,18 @@ void ServerCheatHook(AFortPlayerControllerAthena* PlayerController, FString Msg)
|
|||||||
|
|
||||||
LoopMutators(SpawnBigWall);
|
LoopMutators(SpawnBigWall);
|
||||||
}
|
}
|
||||||
|
else if (Command == "printpawn")
|
||||||
|
{
|
||||||
|
auto Pawn = Cast<APawn>(ReceivingController->GetPawn());
|
||||||
|
|
||||||
|
if (!Pawn)
|
||||||
|
{
|
||||||
|
SendMessageToConsole(PlayerController, L"No pawn to print!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_INFO(LogDev, "Pawn: 0x{:x}", __int64(Pawn));
|
||||||
|
}
|
||||||
else { bSendHelpMessage = true; };
|
else { bSendHelpMessage = true; };
|
||||||
}
|
}
|
||||||
else { bSendHelpMessage = true; };
|
else { bSendHelpMessage = true; };
|
||||||
|
|||||||
@@ -142,6 +142,16 @@ static inline uint64 FindObjectArray()
|
|||||||
return addr;
|
return addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline uint64 FindPickupInitialize()
|
||||||
|
{
|
||||||
|
if (Engine_Version == 423)
|
||||||
|
{
|
||||||
|
return Memcury::Scanner::FindPattern("48 89 5C 24 ? 57 41 56 41 57 48 83 EC 30 80 B9 ? ? ? ? ? 45 0F B6 F1 4D").Get();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static inline uint64 FindCreateNetDriver()
|
static inline uint64 FindCreateNetDriver()
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -34,3 +34,4 @@ extern inline std::string PlaylistName =
|
|||||||
// "/Game/Athena/Playlists/Low/Playlist_Low_Solo.Playlist_Low_Solo";
|
// "/Game/Athena/Playlists/Low/Playlist_Low_Solo.Playlist_Low_Solo";
|
||||||
// "/Game/Athena/Playlists/Bling/Playlist_Bling_Solo.Playlist_Bling_Solo";
|
// "/Game/Athena/Playlists/Bling/Playlist_Bling_Solo.Playlist_Bling_Solo";
|
||||||
// "/Game/Athena/Playlists/Creative/Playlist_PlaygroundV2.Playlist_PlaygroundV2";
|
// "/Game/Athena/Playlists/Creative/Playlist_PlaygroundV2.Playlist_PlaygroundV2";
|
||||||
|
// "/Game/Athena/Playlists/Ashton/Playlist_Ashton_Sm.Playlist_Ashton_Sm";
|
||||||
@@ -810,7 +810,7 @@ void MainUI()
|
|||||||
{
|
{
|
||||||
static std::string ClassNameToDump;
|
static std::string ClassNameToDump;
|
||||||
|
|
||||||
ImGui::InputText("Class Name to get VFT", &ClassNameToDump);
|
ImGui::InputText("Class Name to mess with", &ClassNameToDump);
|
||||||
|
|
||||||
if (ImGui::Button("Print Class VFT"))
|
if (ImGui::Button("Print Class VFT"))
|
||||||
{
|
{
|
||||||
@@ -827,6 +827,17 @@ void MainUI()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* if (ImGui::Button("Load BGA Class (and spawn so no GC)"))
|
||||||
|
{
|
||||||
|
static auto BGAClass = FindObject<UClass>("/Script/Engine.BlueprintGeneratedClass");
|
||||||
|
auto Class = LoadObject<UClass>(ClassNameToDump, BGAClass);
|
||||||
|
|
||||||
|
if (Class)
|
||||||
|
{
|
||||||
|
GetWorld()->SpawnActor<AActor>(Class, FVector());
|
||||||
|
}
|
||||||
|
} */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
ImGui::Text(std::format("Amount of hooks {}", AllFunctionHooks.size()).c_str());
|
ImGui::Text(std::format("Amount of hooks {}", AllFunctionHooks.size()).c_str());
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user