about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--Source/ChallengeRandomizer.cpp210
-rw-r--r--Source/ChallengeRandomizer.h2
-rw-r--r--Source/Memory.cpp13
-rw-r--r--Source/Memory.h6
-rw-r--r--Source/Randomizer.cpp1
-rw-r--r--Source/Randomizer.h2
6 files changed, 137 insertions, 97 deletions
diff --git a/Source/ChallengeRandomizer.cpp b/Source/ChallengeRandomizer.cpp index 401771e..44886b7 100644 --- a/Source/ChallengeRandomizer.cpp +++ b/Source/ChallengeRandomizer.cpp
@@ -34,23 +34,20 @@ ChallengeRandomizer::ChallengeRandomizer(const std::shared_ptr<Memory>& memory,
34 _memory->WriteData<int>({GLOBALS + 0x30, 0}, {seed}); 34 _memory->WriteData<int>({GLOBALS + 0x30, 0}, {seed});
35 35
36 int do_success_side_effects = -1; 36 int do_success_side_effects = -1;
37 int reveal_exit_hall = -1;
38 int begin_endgame_1 = -1;
37 39
38 for (int i=0; i<0x200000; i+=0x1000) { 40 _memory->SigScan([&](int offset, const std::vector<byte>& data) {
39 std::vector<byte> data = _memory->ReadData<byte>({i}, 0x1100);
40 std::cout << data.size() << std::endl;
41
42 if (!alreadyInjected) HandleSigScans(i, data);
43
44 // This injection ensures that the seed is set every time the challenge is started. 41 // This injection ensures that the seed is set every time the challenge is started.
45 // We always do this sigscan since it affects the seed. 42 // We always do this sigscan since it affects the seed.
46 if (do_success_side_effects == -1) { 43 if (do_success_side_effects == -1) {
47 int index = find(data, {0xFF, 0xC8, 0x99, 0x2B, 0xC2, 0xD1, 0xF8, 0x8B, 0xD0}); 44 int index = find(data, {0xFF, 0xC8, 0x99, 0x2B, 0xC2, 0xD1, 0xF8, 0x8B, 0xD0});
48 if (index != -1) { 45 if (index != -1) {
49 do_success_side_effects = i + index + 0x3E; 46 do_success_side_effects = offset + index + 0x3E;
50 if (GLOBALS == 0x62A080) do_success_side_effects += 4; // There's an extra 4 opcodes in the new version 47 if (GLOBALS == 0x62A080) do_success_side_effects += 4; // There's an extra 4 opcodes in the new version
51 _memory->WriteData<byte>({do_success_side_effects}, { 48 _memory->WriteData<byte>({do_success_side_effects}, {
52 0x8B, 0x0D, 0x00, 0x00, 0x00, 0x00, // mov ecx, [] ;This is going to be the address of the custom RNG 49 0x8B, 0x0D, 0x00, 0x00, 0x00, 0x00, // mov ecx, [0x00000000] ;This is going to be the address of the custom RNG
53 0x67, 0xC7, 0x01, 0x00, 0x00, 0x00, 0x00, // mov dword ptr ds:[ecx], 0x0 ;This is going to be the seed value 50 0x67, 0xC7, 0x01, 0x00, 0x00, 0x00, 0x00, // mov dword ptr ds:[ecx], 0x00000000 ;This is going to be the seed value
54 0x48, 0x83, 0xF8, 0x02, // cmp rax, 0x2 ;This is the short solve on the record player (which turns it off) 51 0x48, 0x83, 0xF8, 0x02, // cmp rax, 0x2 ;This is the short solve on the record player (which turns it off)
55 0x90, 0x90, 0x90 // nop nop nop 52 0x90, 0x90, 0x90 // nop nop nop
56 }); 53 });
@@ -59,10 +56,33 @@ ChallengeRandomizer::ChallengeRandomizer(const std::shared_ptr<Memory>& memory,
59 _memory->WriteData<int>({do_success_side_effects + 0x9}, {seed}); 56 _memory->WriteData<int>({do_success_side_effects + 0x9}, {seed});
60 } 57 }
61 } 58 }
62 } 59
60 // BLEH.
61 if (reveal_exit_hall == -1) {
62 int index = find(data, {0x45, 0x8B, 0xF7, 0x48, 0x8B, 0x4D});
63 if (index != -1) {
64 reveal_exit_hall = offset + index;
65 _memory->WriteData<byte>({reveal_exit_hall + 0x15}, {0xEB});
66 }
67 }
68 if (begin_endgame_1 == -1) {
69 int index = find(data, {0x83, 0x7C, 0x01, 0xD0, 0x04});
70 if (index != -1) {
71 begin_endgame_1 = offset + index;
72 if (GLOBALS == 0x5B28C0) { // Version differences :/
73 begin_endgame_1 += 0x75;
74 } else if (GLOBALS == 0x62A080) {
75 begin_endgame_1 += 0x86;
76 }
77 _memory->WriteData<byte>({begin_endgame_1}, {0xEB});
78 }
79 }
80 });
81
82 if (!alreadyInjected) HandleSigScans();
63} 83}
64 84
65void ChallengeRandomizer::HandleSigScans(int i, const std::vector<byte>& data) { 85void ChallengeRandomizer::HandleSigScans() {
66 static int shuffle_integers = -1; 86 static int shuffle_integers = -1;
67 static int shuffle_int = -1; 87 static int shuffle_int = -1;
68 static int cut_random_edges = -1; 88 static int cut_random_edges = -1;
@@ -76,99 +96,101 @@ void ChallengeRandomizer::HandleSigScans(int i, const std::vector<byte>& data) {
76 static int do_lotus_tenths = -1; 96 static int do_lotus_tenths = -1;
77 static int do_lotus_eighths = -1; 97 static int do_lotus_eighths = -1;
78 98
79 if (shuffle_integers == -1) { 99 _memory->SigScan([&](int offset, const std::vector<byte>& data) {
80 int index = find(data, {0x48, 0x89, 0x5C, 0x24, 0x10, 0x56, 0x48, 0x83, 0xEC, 0x20, 0x48, 0x63, 0xDA, 0x48, 0x8B, 0xF1, 0x83, 0xFB, 0x01}); 100 if (shuffle_integers == -1) {
81 if (index != -1) { 101 int index = find(data, {0x48, 0x89, 0x5C, 0x24, 0x10, 0x56, 0x48, 0x83, 0xEC, 0x20, 0x48, 0x63, 0xDA, 0x48, 0x8B, 0xF1, 0x83, 0xFB, 0x01});
82 shuffle_integers = i + index; 102 if (index != -1) {
83 AdjustRng(shuffle_integers + 0x23); 103 shuffle_integers = offset + index;
104 AdjustRng(shuffle_integers + 0x23);
105 }
84 } 106 }
85 } 107 // shuffle<int>
86 // shuffle<int> 108 if (shuffle_int == -1) {
87 if (shuffle_int == -1) { 109 int index = find(data, {0x33, 0xF6, 0x48, 0x8B, 0xD9, 0x39, 0x31, 0x7E, 0x51});
88 int index = find(data, {0x33, 0xF6, 0x48, 0x8B, 0xD9, 0x39, 0x31, 0x7E, 0x51}); 110 if (index != -1) {
89 if (index != -1) { 111 shuffle_int = offset + index - 0x16;
90 shuffle_int = i + index - 0x16; 112 AdjustRng(shuffle_int + 0x12);
91 AdjustRng(shuffle_int + 0x12); 113 }
92 } 114 }
93 } 115 if (cut_random_edges == -1) {
94 if (cut_random_edges == -1) { 116 int index = find(data, {0x89, 0x44, 0x24, 0x3C, 0x33, 0xC0, 0x85, 0xC0, 0x75, 0xFA});
95 int index = find(data, {0x89, 0x44, 0x24, 0x3C, 0x33, 0xC0, 0x85, 0xC0, 0x75, 0xFA}); 117 if (index != -1) {
96 if (index != -1) { 118 cut_random_edges = offset + index - 0x22;
97 cut_random_edges = i + index - 0x22; 119 AdjustRng(cut_random_edges + 0x5D);
98 AdjustRng(cut_random_edges + 0x5D); 120 }
99 } 121 }
100 } 122 if (get_empty_decoration_slot == -1) {
101 if (get_empty_decoration_slot == -1) { 123 int index = find(data, {0x42, 0x83, 0x3C, 0x80, 0x00, 0x75, 0xDF});
102 int index = find(data, {0x42, 0x83, 0x3C, 0x80, 0x00, 0x75, 0xDF}); 124 if (index != -1) {
103 if (index != -1) { 125 get_empty_decoration_slot = offset + index - 0x2D;
104 get_empty_decoration_slot = i + index - 0x2D; 126 AdjustRng(get_empty_decoration_slot + 0x16);
105 AdjustRng(get_empty_decoration_slot + 0x16); 127 }
106 } 128 }
107 } 129 if (get_empty_dot_spot == -1) {
108 if (get_empty_dot_spot == -1) { 130 int index = find(data, {0xF7, 0xF3, 0x85, 0xD2, 0x74, 0xEC});
109 int index = find(data, {0xF7, 0xF3, 0x85, 0xD2, 0x74, 0xEC}); 131 if (index != -1) {
110 if (index != -1) { 132 get_empty_dot_spot = offset + index - 0x2E;
111 get_empty_dot_spot = i + index - 0x2E; 133 AdjustRng(get_empty_dot_spot + 0x23);
112 AdjustRng(get_empty_dot_spot + 0x23); 134 }
113 } 135 }
114 } 136 if (add_exactly_this_many_bisection_dots == -1) {
115 if (add_exactly_this_many_bisection_dots == -1) { 137 int index = find(data, {0x48, 0x8B, 0xB4, 0x24, 0xB8, 0x00, 0x00, 0x00, 0x48, 0x8B, 0xBC, 0x24, 0xB0, 0x00, 0x00, 0x00});
116 int index = find(data, {0x48, 0x8B, 0xB4, 0x24, 0xB8, 0x00, 0x00, 0x00, 0x48, 0x8B, 0xBC, 0x24, 0xB0, 0x00, 0x00, 0x00}); 138 if (index != -1) {
117 if (index != -1) { 139 add_exactly_this_many_bisection_dots = offset + index - 0x20;
118 add_exactly_this_many_bisection_dots = i + index - 0x20; 140 AdjustRng(add_exactly_this_many_bisection_dots + 0x1C);
119 AdjustRng(add_exactly_this_many_bisection_dots + 0x1C); 141 }
120 } 142 }
121 } 143 if (make_a_shaper == -1) {
122 if (make_a_shaper == -1) { 144 int index = find(data, {0xF7, 0xE3, 0xD1, 0xEA, 0x8D, 0x0C, 0x52});
123 int index = find(data, {0xF7, 0xE3, 0xD1, 0xEA, 0x8D, 0x0C, 0x52}); 145 if (index != -1) {
124 if (index != -1) { 146 make_a_shaper = offset + index - 0x19;
125 make_a_shaper = i + index - 0x19; 147 AdjustRng(make_a_shaper + 0x9);
126 AdjustRng(make_a_shaper + 0x9); 148 AdjustRng(make_a_shaper + 0x35);
127 AdjustRng(make_a_shaper + 0x35); 149 AdjustRng(make_a_shaper + 0x62);
128 AdjustRng(make_a_shaper + 0x62); 150 }
129 } 151 }
130 } 152 if (/*Entity_Machine_Panel::*/init_pattern_data_lotus == -1) {
131 if (/*Entity_Machine_Panel::*/init_pattern_data_lotus == -1) { 153 int index = find(data, {0x40, 0x55, 0x56, 0x48, 0x8D, 0x6C, 0x24, 0xB1});
132 int index = find(data, {0x40, 0x55, 0x56, 0x48, 0x8D, 0x6C, 0x24, 0xB1}); 154 if (index != -1) {
133 if (index != -1) { 155 init_pattern_data_lotus = offset + index;
134 init_pattern_data_lotus = i + index; 156 AdjustRng(init_pattern_data_lotus + 0x433);
135 AdjustRng(init_pattern_data_lotus + 0x433); 157 AdjustRng(init_pattern_data_lotus + 0x45B);
136 AdjustRng(init_pattern_data_lotus + 0x45B); 158 AdjustRng(init_pattern_data_lotus + 0x5A7);
137 AdjustRng(init_pattern_data_lotus + 0x5A7); 159 AdjustRng(init_pattern_data_lotus + 0x5D6);
138 AdjustRng(init_pattern_data_lotus + 0x5D6); 160 AdjustRng(init_pattern_data_lotus + 0x6F6);
139 AdjustRng(init_pattern_data_lotus + 0x6F6); 161 AdjustRng(init_pattern_data_lotus + 0xD17);
140 AdjustRng(init_pattern_data_lotus + 0xD17); 162 AdjustRng(init_pattern_data_lotus + 0xFDA);
141 AdjustRng(init_pattern_data_lotus + 0xFDA); 163 }
142 } 164 }
143 } 165 if (/*Entity_Record_Player::*/reroll_lotus_eater_stuff == -1) {
144 if (/*Entity_Record_Player::*/reroll_lotus_eater_stuff == -1) { 166 int index = find(data, {0xB8, 0xAB, 0xAA, 0xAA, 0xAA, 0x41, 0xC1, 0xE8});
145 int index = find(data, {0xB8, 0xAB, 0xAA, 0xAA, 0xAA, 0x41, 0xC1, 0xE8}); 167 if (index != -1) {
146 if (index != -1) { 168 reroll_lotus_eater_stuff = offset + index - 0x37;
147 reroll_lotus_eater_stuff = i + index - 0x37; 169 AdjustRng(reroll_lotus_eater_stuff + 0x24);
148 AdjustRng(reroll_lotus_eater_stuff + 0x24); 170 AdjustRng(reroll_lotus_eater_stuff + 0x6B);
149 AdjustRng(reroll_lotus_eater_stuff + 0x6B); 171 }
150 } 172 }
151 } 173 // These disable the random locations on timer panels, which would otherwise increment the RNG.
152 // These disable the random locations on timer panels, which would otherwise increment the RNG. 174 if (do_lotus_minutes == -1) {
153 if (do_lotus_minutes == -1) { 175 int index = find(data, {0x0F, 0xBE, 0x6C, 0x08, 0xFF, 0x45});
154 int index = find(data, {0x0F, 0xBE, 0x6C, 0x08, 0xFF, 0x45}); 176 if (index != -1) {
155 if (index != -1) { 177 do_lotus_minutes = offset + index - 0x2B;
156 do_lotus_minutes = i + index - 0x2B; 178 _memory->WriteData<byte>({do_lotus_minutes + 0x43B}, {0x31, 0xC0, 0x90, 0x90, 0x90}); // xor eax, eax ;RNG returns 0
157 _memory->WriteData<byte>({do_lotus_minutes + 0x43B}, {0x31, 0xC0, 0x90, 0x90, 0x90}); // xor eax, eax ;RNG returns 0 179 }
158 } 180 }
159 } 181 if (do_lotus_tenths == -1) {
160 if (do_lotus_tenths == -1) { 182 int index = find(data, {0x00, 0x04, 0x00, 0x00, 0x41, 0x8D, 0x50, 0x09});
161 int index = find(data, {0x00, 0x04, 0x00, 0x00, 0x41, 0x8D, 0x50, 0x09}); 183 if (index != -1) {
162 if (index != -1) { 184 do_lotus_tenths = offset + index - 0x61;
163 do_lotus_tenths = i + index - 0x61; 185 _memory->WriteData<byte>({do_lotus_tenths + 0x103}, {0x31, 0xC0, 0x90, 0x90, 0x90}); // xor eax, eax ;RNG returns 0
164 _memory->WriteData<byte>({do_lotus_tenths + 0x103}, {0x31, 0xC0, 0x90, 0x90, 0x90}); // xor eax, eax ;RNG returns 0 186 }
165 } 187 }
166 } 188 if (do_lotus_eighths == -1) {
167 if (do_lotus_eighths == -1) { 189 int index = find(data, {0x75, 0xF5, 0x0F, 0xBE, 0x44, 0x08, 0xFF});
168 int index = find(data, {0x75, 0xF5, 0x0F, 0xBE, 0x44, 0x08, 0xFF}); 190 if (index != -1) {
169 if (index != -1) { 191 do_lotus_eighths = offset + index - 0x39;
170 do_lotus_eighths = i + index - 0x39; 192 _memory->WriteData<byte>({do_lotus_eighths + 0x1E7}, {0x31, 0xC0, 0x90, 0x90, 0x90}); // xor eax, eax ;RNG returns 0
171 _memory->WriteData<byte>({do_lotus_eighths + 0x1E7}, {0x31, 0xC0, 0x90, 0x90, 0x90}); // xor eax, eax ;RNG returns 0 193 }
172 } 194 }
173 } 195 });
174} \ No newline at end of file 196} \ No newline at end of file
diff --git a/Source/ChallengeRandomizer.h b/Source/ChallengeRandomizer.h index e642685..0a43b4a 100644 --- a/Source/ChallengeRandomizer.h +++ b/Source/ChallengeRandomizer.h
@@ -7,7 +7,7 @@ public:
7 ChallengeRandomizer(const std::shared_ptr<Memory>& memory, int seed); 7 ChallengeRandomizer(const std::shared_ptr<Memory>& memory, int seed);
8 8
9private: 9private:
10 void HandleSigScans(int i, const std::vector<byte>& data); 10 void HandleSigScans();
11 11
12 void AdjustRng(int offset); 12 void AdjustRng(int offset);
13 std::shared_ptr<Memory> _memory; 13 std::shared_ptr<Memory> _memory;
diff --git a/Source/Memory.cpp b/Source/Memory.cpp index 825346a..43cb9b3 100644 --- a/Source/Memory.cpp +++ b/Source/Memory.cpp
@@ -39,6 +39,11 @@ Memory::Memory(const std::string& processName) {
39 if (_baseAddress == 0) { 39 if (_baseAddress == 0) {
40 throw std::exception("Couldn't find the base process address!"); 40 throw std::exception("Couldn't find the base process address!");
41 } 41 }
42
43 // Unprotect regions of memory
44
45 DWORD oldProtect;
46 VirtualProtectEx(_handle, (LPVOID)_baseAddress, sizeof(DWORD), PAGE_READWRITE, &oldProtect);
42} 47}
43 48
44Memory::~Memory() { 49Memory::~Memory() {
@@ -58,6 +63,14 @@ int Memory::GetCurrentFrame()
58 return ReadData<int>({SCRIPT_FRAMES}, 1)[0]; 63 return ReadData<int>({SCRIPT_FRAMES}, 1)[0];
59} 64}
60 65
66void Memory::SigScan(std::function<void(int offset, const std::vector<byte>& data)> scanFunc)
67{
68 for (int i=0; i<0x200000; i+=0x1000) {
69 std::vector<byte> data = ReadData<byte>({i}, 0x1100);
70 scanFunc(i, data);
71 }
72}
73
61void Memory::ThrowError() { 74void Memory::ThrowError() {
62 std::string message(256, '\0'); 75 std::string message(256, '\0');
63 int length = FormatMessageA(4096, nullptr, GetLastError(), 1024, &message[0], static_cast<DWORD>(message.size()), nullptr); 76 int length = FormatMessageA(4096, nullptr, GetLastError(), 1024, &message[0], static_cast<DWORD>(message.size()), nullptr);
diff --git a/Source/Memory.h b/Source/Memory.h index 403b94a..e6110d8 100644 --- a/Source/Memory.h +++ b/Source/Memory.h
@@ -1,6 +1,7 @@
1#pragma once 1#pragma once
2#include <vector> 2#include <functional>
3#include <map> 3#include <map>
4#include <vector>
4#include <windows.h> 5#include <windows.h>
5 6
6// #define GLOBALS 0x5B28C0 7// #define GLOBALS 0x5B28C0
@@ -41,6 +42,8 @@ public:
41 WriteData<T>({GLOBALS, 0x18, panel*8, offset}, data); 42 WriteData<T>({GLOBALS, 0x18, panel*8, offset}, data);
42 } 43 }
43 44
45 void SigScan(std::function<void(int offset, const std::vector<byte>& data)> scanFunc);
46
44 void ClearOffsets() {_computedAddresses = std::map<uintptr_t, uintptr_t>();} 47 void ClearOffsets() {_computedAddresses = std::map<uintptr_t, uintptr_t>();}
45 48
46private: 49private:
@@ -78,4 +81,5 @@ private:
78 81
79 friend class Temp; 82 friend class Temp;
80 friend class ChallengeRandomizer; 83 friend class ChallengeRandomizer;
84 friend class Randomizer;
81}; \ No newline at end of file 85}; \ No newline at end of file
diff --git a/Source/Randomizer.cpp b/Source/Randomizer.cpp index e0cbb2b..ae41bb7 100644 --- a/Source/Randomizer.cpp +++ b/Source/Randomizer.cpp
@@ -1,6 +1,5 @@
1/* 1/*
2 * Random *rotation* of desert laser redirect? 2 * Random *rotation* of desert laser redirect?
3 * Disable wonkavator and hotel, so that 100% runs are possible
4 * Try to wire up both keep halves 3 * Try to wire up both keep halves
5 * Wire up both halves of symmetry laser 4 * Wire up both halves of symmetry laser
6 * Turn off floating panel in desert 5 * Turn off floating panel in desert
diff --git a/Source/Randomizer.h b/Source/Randomizer.h index 8c4d253..53e4149 100644 --- a/Source/Randomizer.h +++ b/Source/Randomizer.h
@@ -119,6 +119,7 @@ private:
119#define AUDIO_LOG_NAME 0xC8 119#define AUDIO_LOG_NAME 0xC8
120#define OPEN_RATE 0xE8 120#define OPEN_RATE 0xE8
121#define METADATA 0xF2 // sizeof(short) 121#define METADATA 0xF2 // sizeof(short)
122#define HOTEL_EP_NAME 0x4BC640
122#elif GLOBALS == 0x62A080 123#elif GLOBALS == 0x62A080
123#define PATH_COLOR 0xC0 124#define PATH_COLOR 0xC0
124#define REFLECTION_PATH_COLOR 0xD0 125#define REFLECTION_PATH_COLOR 0xD0
@@ -184,4 +185,5 @@ private:
184#define AUDIO_LOG_NAME 0x0 185#define AUDIO_LOG_NAME 0x0
185#define OPEN_RATE 0xE0 186#define OPEN_RATE 0xE0
186#define METADATA 0x13A // sizeof(short) 187#define METADATA 0x13A // sizeof(short)
188#define HOTEL_EP_NAME 0x51E340
187#endif \ No newline at end of file 189#endif \ No newline at end of file