|
1 | 1 | /* |
2 | | -* (In)Visibible Entities List Adjuster |
3 | | -* Copyright (c) 2014 ThirteenAG <thirteenag@gmail.com> |
| 2 | +* Visible Entities List Adjuster |
| 3 | +* Copyright (C) 2014 ThirteenAG <thirteenag@gmail.com> |
| 4 | +* Copyright (C) 2014 LINK/2012 <dma_2012@hotmail.com> |
4 | 5 | * Licensed under the MIT License (http://opensource.org/licenses/MIT) |
5 | 6 | */ |
6 | 7 | #include "LimitAdjuster.h" |
| 8 | +#include "utility/StaticArrayAdjuster.hpp" |
| 9 | +#include <injector/assembly.hpp> |
7 | 10 |
|
8 | | -static std::vector<void*> aInVisibleEntityPtrs; |
9 | | -static std::vector<void*> aVisibleEntityPtrs; |
10 | | - |
11 | | -class InVisibleEntityPtrsIII : public SimpleAdjuster |
| 11 | +/* |
| 12 | + VisibilityPtrsBase |
| 13 | + Base for the visibility pointers rellocation |
| 14 | + @pDefaultArray is the address of the default array at the data segment |
| 15 | + @DefaultArraySize is the default size of that array |
| 16 | + @pArrayUsage is the address where the array usage is stored |
| 17 | +*/ |
| 18 | +template<uintptr_t pDefaultArray, size_t DefaultArraySize, uintptr_t pArrayUsage> |
| 19 | +struct VisibilityPtrsBase : public StaticArrayAdjuster<void*> |
12 | 20 | { |
13 | | -public: |
14 | | - const char* GetLimitName() { return GetGVM().IsIII() ? "InVisibleEntityPtrs" : nullptr; } |
15 | | - |
16 | | - void ChangeLimit(int, const std::string& value) |
17 | | - { |
18 | | - aInVisibleEntityPtrs.resize(std::stoi(value)); |
19 | | - |
20 | | - injector::WriteMemory(0x4A7850 + 0x3, &aInVisibleEntityPtrs[0], true); |
21 | | - injector::WriteMemory(0x4A78D3 + 0x3, &aInVisibleEntityPtrs[0], true); |
22 | | - injector::WriteMemory(0x4A7950 + 0x3, &aInVisibleEntityPtrs[0], true); |
23 | | - injector::WriteMemory(0x4A9300 + 0x33 + 0x3, &aInVisibleEntityPtrs[0], true); |
24 | | - injector::WriteMemory(0x4A9BB0 + 0xB8 + 0x3, &aInVisibleEntityPtrs[0], true); |
25 | | - injector::WriteMemory(0x4A9E30 + 0xC5 + 0x3, &aInVisibleEntityPtrs[0], true); |
26 | | - injector::WriteMemory(0x4AA0A0 + 0x6C + 0x3, &aInVisibleEntityPtrs[0], true); |
27 | | - } |
28 | | - |
29 | | -} InVisibleEntityPtrsIII; |
30 | | - |
31 | | -class VisibleEntityPtrsIII : public SimpleAdjuster |
| 21 | + private: |
| 22 | + size_t& m_dwUsage; // Reference to the array usage (pArrayUsage) |
| 23 | + std::vector<injector::memory_pointer_raw> m_Growers; // List of (mov eax, m_dwUsage) on the code, so we can check if rellocation is necessary |
| 24 | + // (Yeah, the three games use this same register and everything) |
| 25 | + |
| 26 | + // Just to access it from the DoGrowFun functor, unique because of the template parameters |
| 27 | + static VisibilityPtrsBase*& Instance() |
| 28 | + { |
| 29 | + static VisibilityPtrsBase* myself; |
| 30 | + return myself; |
| 31 | + } |
| 32 | + |
| 33 | + public: |
| 34 | + |
| 35 | + VisibilityPtrsBase() : |
| 36 | + StaticArrayAdjuster(pDefaultArray, DefaultArraySize), |
| 37 | + m_dwUsage(*injector::lazy_ptr<pArrayUsage>().get<size_t>()) |
| 38 | + { |
| 39 | + this->Instance() = this; |
| 40 | + } |
| 41 | + |
| 42 | + // Adds a grower address, that's a (mov eax, dwUsage) right before incrementing and adding a element to the array |
| 43 | + // The hook this will produce will be used to check if the array needs to grow |
| 44 | + void AddGrower(uintptr_t addr) |
| 45 | + { |
| 46 | + using namespace injector; |
| 47 | + m_Growers.push_back(raw_ptr(memory_pointer(addr))); |
| 48 | + } |
| 49 | + |
| 50 | + // Called when the limit is found on the ini |
| 51 | + virtual void ChangeLimit(int, const std::string& value) |
| 52 | + { |
| 53 | + if(Adjuster::IsUnlimited(value)) |
| 54 | + { |
| 55 | + // Inline '''assembler''' functor for ensuring the capacity is fine |
| 56 | + struct DoGrowFun |
| 57 | + { |
| 58 | + // All the growing procs for those visibility lists use eax as indexer :) |
| 59 | + void operator()(injector::reg_pack& regs) |
| 60 | + { |
| 61 | + auto m_dwUsage = Instance()->m_dwUsage; |
| 62 | + Instance()->EnsureHasCapacityFor(m_dwUsage + 1); |
| 63 | + regs.eax = m_dwUsage; // replaces a (mov eax, m_dwUsage) |
| 64 | + } |
| 65 | + }; |
| 66 | + |
| 67 | + // Makes the inline grow functor |
| 68 | + for(auto it = m_Growers.begin(); it != m_Growers.end(); ++it) |
| 69 | + injector::MakeInline<DoGrowFun>(*it); |
| 70 | + } |
| 71 | + else |
| 72 | + { |
| 73 | + this->RellocArray(std::stoi(value)); |
| 74 | + } |
| 75 | + } |
| 76 | + |
| 77 | + // Gets the current usage of this visibility array |
| 78 | + virtual bool GetUsage(int, std::string& output) |
| 79 | + { |
| 80 | + return Adjuster::GetUsage(output, m_dwUsage, this->GetArraySize()); |
| 81 | + } |
| 82 | +}; |
| 83 | + |
| 84 | + |
| 85 | + |
| 86 | +// |
| 87 | +// The actual adjusters |
| 88 | +// |
| 89 | + |
| 90 | +struct VisibleEntityPtrsIII : VisibilityPtrsBase<0x6E9920, 2000, 0x940730> // <pDefault, dwMax, dwUsage> |
32 | 91 | { |
33 | | -public: |
34 | | - const char* GetLimitName() { return GetGVM().IsIII() ? "VisibleEntityPtrs" : nullptr; } |
35 | | - |
36 | | - void ChangeLimit(int, const std::string& value) |
37 | | - { |
38 | | - aVisibleEntityPtrs.resize(std::stoi(value)); |
39 | | - |
40 | | - injector::WriteMemory(0x4A7870 + 0x3, &aVisibleEntityPtrs[0], true); |
41 | | - injector::WriteMemory(0x4A9BB0 + 0x1C7 + 0x3, &aVisibleEntityPtrs[0], true); |
42 | | - injector::WriteMemory(0x4A9E30 + 0x1D7 + 0x3, &aVisibleEntityPtrs[0], true); |
43 | | - injector::WriteMemory(0x4AA0A0 + 0xE3 + 0x3, &aVisibleEntityPtrs[0], true); |
44 | | - } |
| 92 | + const char* GetLimitName() |
| 93 | + { |
| 94 | + return IsIII()? "VisibleEntityPtrs" : nullptr; |
| 95 | + } |
| 96 | + |
| 97 | + VisibleEntityPtrsIII() |
| 98 | + { |
| 99 | + this->AddGrower (0x4A9EEA); |
| 100 | + this->AddGrower (0x4A9C5D); |
| 101 | + this->AddGrower (0x4A9328); |
| 102 | + this->AddGrower (0x4AA101); |
| 103 | + this->AddPointer(0x4A7853); |
| 104 | + this->AddPointer(0x4A78D6); |
| 105 | + this->AddPointer(0x4A7953); |
| 106 | + this->AddPointer(0x4A9336); |
| 107 | + this->AddPointer(0x4A9C6B); |
| 108 | + this->AddPointer(0x4A9EF8); |
| 109 | + this->AddPointer(0x4AA10F); |
| 110 | + } |
| 111 | + |
45 | 112 | } VisibleEntityPtrsIII; |
46 | 113 |
|
47 | | -class InVisibleEntityPtrsVC : public SimpleAdjuster |
48 | | -{ |
49 | | -public: |
50 | | - const char* GetLimitName() { return GetGVM().IsVC() ? "InVisibleEntityPtrs" : nullptr; } |
51 | | - |
52 | | - void ChangeLimit(int, const std::string& value) |
53 | | - { |
54 | | - aInVisibleEntityPtrs.resize(std::stoi(value)); |
55 | | - |
56 | | - injector::WriteMemory(0x4C7560 + 0xBE + 0x3, &aInVisibleEntityPtrs[0], true); |
57 | | - injector::WriteMemory(0x4C7740 + 0xB8 + 0x3, &aInVisibleEntityPtrs[0], true); |
58 | | - injector::WriteMemory(0x4C8540 + 0x78 + 0x3, &aInVisibleEntityPtrs[0], true); |
59 | | - injector::WriteMemory(0x4C9F80 + 0x3, &aInVisibleEntityPtrs[0], true); |
60 | | - injector::WriteMemory(0x4CA1B8 + 0x3, &aInVisibleEntityPtrs[0], true); |
61 | | - injector::WriteMemory(0x4CA200 + 0x3, &aInVisibleEntityPtrs[0], true); |
62 | | - } |
63 | | -} InVisibleEntityPtrsVC; |
64 | | - |
65 | | -class VisibleEntityPtrsVC : public SimpleAdjuster |
66 | | -{ |
67 | | -public: |
68 | | - const char* GetLimitName() { return GetGVM().IsVC() ? "VisibleEntityPtrs" : nullptr; } |
69 | | - void ChangeLimit(int, const std::string& value) |
70 | | - { |
71 | | - aVisibleEntityPtrs.resize(std::stoi(value)); |
72 | | - |
73 | | - injector::WriteMemory(0x4C7560 + 0x185 + 0x3, &aVisibleEntityPtrs[0], true); |
74 | | - injector::WriteMemory(0x4C7740 + 0x17F + 0x3, &aVisibleEntityPtrs[0], true); |
75 | | - injector::WriteMemory(0x4CA220 + 0x3, &aVisibleEntityPtrs[0], true); |
76 | | - } |
77 | | -} VisibleEntityPtrsVC; |
78 | 114 |
|
79 | | -class InVisibleEntityPtrsSA : public SimpleAdjuster |
| 115 | +struct VisibleEntityPtrsVC : VisibilityPtrsBase<0x7D54F8, 2000, 0xA0D1E4> // <pDefault, dwMax, dwUsage> |
80 | 116 | { |
81 | | -public: |
82 | | - const char* GetLimitName() { return GetGVM().IsSA() ? "InVisibleEntityPtrs" : nullptr; } |
83 | | - |
84 | | - void ChangeLimit(int, const std::string& value) |
85 | | - { |
86 | | - aInVisibleEntityPtrs.resize(std::stoi(value)); |
| 117 | + const char* GetLimitName() |
| 118 | + { |
| 119 | + return IsVC()? "VisibleEntityPtrs" : nullptr; |
| 120 | + } |
| 121 | + |
| 122 | + VisibleEntityPtrsVC() |
| 123 | + { |
| 124 | + this->AddGrower (0x4C77ED); |
| 125 | + this->AddGrower (0x4C7613); |
| 126 | + this->AddGrower (0x4C85AD); |
| 127 | + this->AddPointer(0x4C7621); |
| 128 | + this->AddPointer(0x4C77FB); |
| 129 | + this->AddPointer(0x4C85BB); |
| 130 | + this->AddPointer(0x4C9F83); |
| 131 | + this->AddPointer(0x4CA1BB); |
| 132 | + this->AddPointer(0x4CA203); |
| 133 | + } |
87 | 134 |
|
88 | | - injector::WriteMemory(0x5534B0 + 0x42 + 0x3, &aInVisibleEntityPtrs[0], true); |
89 | | - injector::WriteMemory(0x553920 + 0x3, &aInVisibleEntityPtrs[0], true); |
90 | | - injector::WriteMemory(0x553CB0 + 0x3, &aInVisibleEntityPtrs[0], true); |
91 | | - } |
92 | | - |
93 | | - // TODO GetUsage |
| 135 | +} VisibleEntityPtrsVC; |
94 | 136 |
|
95 | | -} InVisibleEntityPtrsSA; |
96 | 137 |
|
97 | | -class VisibleEntityPtrsSA : public SimpleAdjuster |
| 138 | +struct VisibleEntityPtrsSA : VisibilityPtrsBase<0xB75898, 1000, 0xB76844> // <pDefault, dwMax, dwUsage> |
98 | 139 | { |
99 | | -public: |
100 | | - const char* GetLimitName() { return GetGVM().IsSA() ? "VisibleEntityPtrs" : nullptr; } |
| 140 | + const char* GetLimitName() |
| 141 | + { |
| 142 | + return IsSA()? "VisibleEntityPtrs" : nullptr; |
| 143 | + } |
101 | 144 |
|
102 | | - void ChangeLimit(int, const std::string& value) |
103 | | - { |
104 | | - aVisibleEntityPtrs.resize(std::stoi(value)); |
105 | | - |
106 | | - injector::WriteMemory(0x5534B0 + 0x76 + 0x3, &aVisibleEntityPtrs[0], true); |
107 | | - injector::WriteMemory(0x553941 + 0x3, &aVisibleEntityPtrs[0], true); |
108 | | - injector::WriteMemory(0x553A50 + 0x3, &aVisibleEntityPtrs[0], true); |
109 | | - injector::WriteMemory(0x553B00 + 0x3, &aVisibleEntityPtrs[0], true); |
110 | | - } |
111 | | - |
112 | | - // TODO GetUsage |
| 145 | + VisibleEntityPtrsSA() |
| 146 | + { |
| 147 | + this->AddGrower (0x553521); |
| 148 | + this->AddPointer(0x553529); |
| 149 | + this->AddPointer(0x553944); |
| 150 | + this->AddPointer(0x553A53); |
| 151 | + this->AddPointer(0x553B03); |
| 152 | + } |
113 | 153 |
|
114 | 154 | } VisibleEntityPtrsSA; |
| 155 | + |
| 156 | +struct VisibleLodPtrsSA : VisibilityPtrsBase<0xB748F8, 1000, 0xB76840> // <pDefault, dwMax, dwUsage> |
| 157 | +{ |
| 158 | + const char* GetLimitName() |
| 159 | + { |
| 160 | + return IsSA()? "VisibleLodPtrs" : nullptr; |
| 161 | + } |
| 162 | + |
| 163 | + VisibleLodPtrsSA() |
| 164 | + { |
| 165 | + this->AddGrower (0x5534ED); |
| 166 | + this->AddPointer(0x5534F5); |
| 167 | + this->AddPointer(0x553923); |
| 168 | + this->AddPointer(0x553CB3); |
| 169 | + } |
| 170 | + |
| 171 | +} VisibleLodPtrsSA; |
0 commit comments