Skip to content

Commit

Permalink
Simplify Ares interface
Browse files Browse the repository at this point in the history
for future use
  • Loading branch information
chaserli committed Nov 6, 2024
1 parent 4637167 commit f21e471
Show file tree
Hide file tree
Showing 8 changed files with 46 additions and 88 deletions.
4 changes: 2 additions & 2 deletions src/Ext/Techno/Body.Update.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -738,14 +738,14 @@ void TechnoExt::KillSelf(TechnoClass* pThis, AutoDeathBehavior deathOption, Anim
}

default: //must be AutoDeathBehavior::Kill
if (IS_ARES_FUN_AVAILABLE(SpawnSurvivors))
if (AresFunctions::SpawnSurvivors)
{
switch (pThis->WhatAmI())
{
case AbstractType::Unit:
case AbstractType::Aircraft:
AresFunctions::SpawnSurvivors(static_cast<FootClass*>(pThis), nullptr, false, false);
default:break;
default:;
}
}
pThis->ReceiveDamage(&pThis->Health, 0, RulesClass::Instance->C4Warhead, nullptr, true, false, pThis->Owner);
Expand Down
2 changes: 1 addition & 1 deletion src/Ext/Techno/Body.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ bool TechnoExt::AllowedTargetByZone(TechnoClass* pThis, TechnoClass* pTarget, Ta
// BTW, who said it was merely a Type pointer replacement and he could make a better one than Ares?
bool TechnoExt::ConvertToType(FootClass* pThis, TechnoTypeClass* pToType)
{
if (IS_ARES_FUN_AVAILABLE(ConvertTypeTo))
if (AresFunctions::ConvertTypeTo)
return AresFunctions::ConvertTypeTo(pThis, pToType);
// In case not using Ares 3.0. Only update necessary vanilla properties
AbstractType rtti;
Expand Down
6 changes: 3 additions & 3 deletions src/Ext/TechnoType/Hooks.Drawing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ DEFINE_HOOK(0x73C47A, UnitClass_DrawAsVXL_Shadow, 0x5)
{
if (pType->NoSpawnAlt && pThis->SpawnManager && pThis->SpawnManager->CountDockedSpawns() == 0)
{
if (CAN_USE_ARES && AresHelper::CanUseAres)
if (AresHelper::CanUseAres)
{
vxl_index_key.Invalidate();// I'd just assume most of the time we have spawn
return &reinterpret_cast<DummyExtHere*>(pType->align_2FC)->NoSpawnAltVXL;
Expand Down Expand Up @@ -373,7 +373,7 @@ DEFINE_HOOK(0x73C47A, UnitClass_DrawAsVXL_Shadow, 0x5)
if (idx < 18)
return &pType->ChargerTurrets[idx];

if (CAN_USE_ARES && AresHelper::CanUseAres)
if (AresHelper::CanUseAres)
{
auto* aresTypeExt = reinterpret_cast<DummyExtHere*>(pType->align_2FC);
return &aresTypeExt->ChargerTurrets[idx - 18];
Expand All @@ -390,7 +390,7 @@ DEFINE_HOOK(0x73C47A, UnitClass_DrawAsVXL_Shadow, 0x5)
if (idx < 18)
return &pType->ChargerBarrels[idx];

if (CAN_USE_ARES && AresHelper::CanUseAres)
if (AresHelper::CanUseAres)
{
auto* aresTypeExt = reinterpret_cast<DummyExtHere*>(pType->align_2FC);
return &aresTypeExt->ChargerBarrels[idx - 18];
Expand Down
2 changes: 0 additions & 2 deletions src/Phobos.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@

#include <string>

#define CAN_USE_ARES 1

class CCINIClass;
class AbstractClass;

Expand Down
47 changes: 29 additions & 18 deletions src/Utilities/AresAddressTable.cpp
Original file line number Diff line number Diff line change
@@ -1,24 +1,35 @@
#pragma once
#include "AresFunctions.h"
#include "AresHelper.h"
#include "Patch.h"
#define NOTE_ARES_FUN(name,reladdr) AresFunctions::name = reinterpret_cast<decltype(AresFunctions::name)>(AresHelper::AresBaseAddress + reladdr)

const AresHelper::AresVersionFunctionMap AresHelper::AresFunctionOffsets =
decltype(AresFunctions::ConvertTypeTo) AresFunctions::ConvertTypeTo = nullptr;
decltype(AresFunctions::SpawnSurvivors) AresFunctions::SpawnSurvivors = nullptr;

void AresFunctions::InitAres3_0()
{
NOTE_ARES_FUN(ConvertTypeTo, 0x043650);
if constexpr (AresFunctions::AresWasWrongAboutSpawnSurvivors)
{
AresHelper::Version::Ares30,
{
{ ARES_FUN(ConvertTypeTo), 0x043650 },
{ ARES_FUN(SpawnSurvivors), 0x0464C0 },
{ ARES_FUN(HasFactory), 0x0217C0 },
{ ARES_FUN(CanBeBuiltAt), 0x03E3B0 },
}
},
Patch::Apply_RAW(AresHelper::AresBaseAddress + 0x4C0EB, { 0x5C });
Patch::Apply_RAW(AresHelper::AresBaseAddress + 0x48C69, { 0x30 });
}
else
NOTE_ARES_FUN(SpawnSurvivors, 0x0464C0);
}

void AresFunctions::InitAres3_0p1()
{
NOTE_ARES_FUN(ConvertTypeTo, 0x044130);
if constexpr (AresFunctions::AresWasWrongAboutSpawnSurvivors)
{
AresHelper::Version::Ares30p,
{
{ ARES_FUN(ConvertTypeTo), 0x044130 },
{ ARES_FUN(SpawnSurvivors), 0x047030 },
{ ARES_FUN(HasFactory), 0x0217C0 },
{ ARES_FUN(CanBeBuiltAt), 0x03E3B0 },
}
},
};
Patch::Apply_RAW(AresHelper::AresBaseAddress + 0x4CD4B, { 0x5C });
Patch::Apply_RAW(AresHelper::AresBaseAddress + 0x498B9, { 0x30 });
}
else
NOTE_ARES_FUN(SpawnSurvivors, 0x047030);
}

#undef NOTE_ARES_FUN

47 changes: 8 additions & 39 deletions src/Utilities/AresFunctions.h
Original file line number Diff line number Diff line change
@@ -1,53 +1,22 @@
#pragma once
#include "AresHelper.h"

#include <nameof/nameof.h>
#include <ASMMacros.h>
#include <functional>

class TechnoClass;
class TechnoTypeClass;
class FootClass;
class HouseClass;
class BuildingTypeClass;

class AresTechnoTypeExt
{
public:
__declspec(noinline) bool __thiscall CanBeBuiltAt(BuildingTypeClass* pBuildingType) { return 0; }
};


class AresFunctions
{
public:
#define CALL_ARES(name, ...) std::invoke(reinterpret_cast<decltype(name)*>(AresHelper::AresFunctionOffsetsFinal[ARES_FUN(name)]), __VA_ARGS__)
#define THIS_CALL_ARES(name, ...) std::invoke(*reinterpret_cast<decltype(name)*>(AresHelper::AresFunctionOffsetsFinal[ARES_FUN_M(name)]), __VA_ARGS__)

// ???
static bool ConvertTypeTo(TechnoClass* pFoot, TechnoTypeClass* pConvertTo)
{
return CALL_ARES(ConvertTypeTo, pFoot, pConvertTo);
}

static void InitAres3_0();
static void InitAres3_0p1();
// TechnoExt
static void SpawnSurvivors(FootClass* const pThis, TechnoClass* const pKiller, const bool Select, const bool IgnoreDefenses)
{
CALL_ARES(SpawnSurvivors, pThis, pKiller, Select, IgnoreDefenses);
}

// HouseExt
static int HasFactory(int buffer, HouseClass* pOwner, TechnoTypeClass* pType, bool skipAircraft, bool requirePower, bool checkCanBuild, bool unknown)
{
return CALL_ARES(HasFactory, buffer, pOwner, pType, skipAircraft, requirePower, checkCanBuild, unknown);
}
static bool(__stdcall* ConvertTypeTo)(TechnoClass* pFoot, TechnoTypeClass* pConvertTo);

// TechnoTypeExt
static bool CanBeBuiltAt(AresTechnoTypeExt* pExt, BuildingTypeClass* pBuildingType)
{
return THIS_CALL_ARES(&AresTechnoTypeExt::CanBeBuiltAt, pExt, pBuildingType);
}
static void(__stdcall* SpawnSurvivors)(FootClass* pThis, TechnoClass* pKiller, bool Select, bool IgnoreDefenses);
private:
static constexpr bool _maybe = false;

#undef CALL_ARES
#undef THIS_CALL_ARES
static constexpr bool AresWasWrongAboutSpawnSurvivors = _maybe;
static constexpr bool AresWasWrongAboutAduction = true;
};
15 changes: 3 additions & 12 deletions src/Utilities/AresHelper.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#include "AresHelper.h"

#include "AresFunctions.h"
#include <Phobos.h>
#include <Utilities/Debug.h>
#include <Utilities/Patch.h>
Expand All @@ -15,7 +15,6 @@ uintptr_t AresHelper::AresBaseAddress = 0x0;
HMODULE AresHelper::AresDllHmodule = nullptr;
AresHelper::Version AresHelper::AresVersion = AresHelper::Version::Unknown;
bool AresHelper::CanUseAres = false;
AresHelper::AresFunctionMap AresHelper::AresFunctionOffsetsFinal;

const AresHelper::AresTimestampMap AresHelper::AresTimestampBytes =
{
Expand Down Expand Up @@ -96,22 +95,14 @@ void AresHelper::Init()
{
case Version::Ares30:
Debug::LogDeferred("[Phobos] Detected Ares 3.0.\n");
AresFunctions::InitAres3_0();
break;
case Version::Ares30p:
Debug::LogDeferred("[Phobos] Detected Ares 3.0p1.\n");
AresFunctions::InitAres3_0p1();
break;
default:
Debug::LogDeferred("[Phobos] Detected a version of Ares that is not supported by Phobos. Disabling integration.\n");
break;
}

constexpr const wchar_t* ARES_DLL = L"Ares.dll";
if (CanUseAres && GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_PIN, ARES_DLL, &AresDllHmodule))
{
for (auto x : AresFunctionOffsets.at(AresVersion))
if (x.second > 0)
AresFunctionOffsetsFinal[x.first] = AresBaseAddress + x.second;
else
AresFunctionOffsetsFinal[x.first] = 0;
}
}
11 changes: 0 additions & 11 deletions src/Utilities/AresHelper.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@
#include <unordered_map>
#include <Windows.h>

#define ARES_FUN(name) std::string(NAMEOF(AresFunctions::name))
#define ARES_FUN_M(name) std::string(NAMEOF_MEMBER(name))
#define IS_ARES_FUN_AVAILABLE(name) AresHelper::CanUseAres && (AresHelper::AresFunctionOffsetsFinal[ARES_FUN(name)] != 0)

class AresHelper
{
public:
Expand All @@ -31,13 +27,6 @@ class AresHelper
static uintptr_t AresBaseAddress;
static uintptr_t PhobosBaseAddress;

typedef std::unordered_map<std::string, DWORD> AresFunctionMap;
typedef std::unordered_map<AresHelper::Version, AresFunctionMap> AresVersionFunctionMap;

// offsets of function addresses for each version
static const AresVersionFunctionMap AresFunctionOffsets;
// storage for absolute addresses of functions (module base + offset)
static AresFunctionMap AresFunctionOffsetsFinal;
// numeric id of currently used version, zero-indexed, -1 is unknown or missing
static Version AresVersion;
// is Ares detected and version known?
Expand Down

0 comments on commit f21e471

Please sign in to comment.