Skip to content

Commit

Permalink
Final changes for 2.0, including switch to Sigscans
Browse files Browse the repository at this point in the history
  • Loading branch information
metzner committed Aug 5, 2022
1 parent 13b1592 commit 31410d5
Show file tree
Hide file tree
Showing 7 changed files with 139 additions and 40 deletions.
1 change: 1 addition & 0 deletions App/Main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,7 @@ int APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance
memory.findMovementSpeed();
memory.findActivePanel();
memory.findPlayerPosition();
memory.findImportantFunctionAddresses();

if (!Memory::GLOBALS) {
std::ifstream file("WRPGglobals.txt");
Expand Down
47 changes: 24 additions & 23 deletions Source/Archipelago/APRandomizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -153,29 +153,27 @@ bool APRandomizer::Connect(HWND& messageBoxHandle, std::string& server, std::str
std::string itemName = ap->get_item_name(item.item);
std::string locationName = ap->get_location_name(item.location);

if (!receiving) {
bool hint = false;
bool hint = false;

for (auto textNode : msg) {
if (textNode.text.find("[Hint]") != std::string::npos) {
hint = true;
}
for (auto textNode : msg) {
if (textNode.text.find("[Hint]") != std::string::npos) {
hint = true;
}
}

if (hint) {
async->queueMessage("Hint: " + itemName + " for " + player + " is on " + locationName + ".");
}
else {
int location = item.location;
if (hint) {
async->queueMessage("Hint: " + itemName + " for " + player + " is on " + locationName + ".");
}
else {
int location = item.location;

if (panelIdToLocationIdReverse.count(location) && !_memory->ReadPanelData<int>(panelIdToLocationIdReverse[location], SOLVED)) {
async->queueMessage("(Collect) Sent " + itemName + " to " + player + ".");
}
else
{
panelLocker->SetItemReward(findResult->first, item);
async->queueMessage("Sent " + itemName + " to " + player + ".");
}
if (panelIdToLocationIdReverse.count(location) && !_memory->ReadPanelData<int>(panelIdToLocationIdReverse[location], SOLVED)) {
async->queueMessage("(Collect) Sent " + itemName + " to " + player + ".");
}
else
{
panelLocker->SetItemReward(findResult->first, item);
if(!receiving) async->queueMessage("Sent " + itemName + " to " + player + ".");
}
}
});
Expand Down Expand Up @@ -250,12 +248,15 @@ std::string APRandomizer::buildUri(std::string& server)

void APRandomizer::PostGeneration(HWND loadingHandle) {
int num_dec = _memory->ReadPanelData<int>(0x17C2E, NUM_DECORATIONS);
std::vector<int> decorations = _memory->ReadArray<int>(0x17C2E, DECORATIONS, num_dec);

decorations[3] = 264;
decorations[12] = 264;
if(num_dec != 1){
std::vector<int> decorations = _memory->ReadArray<int>(0x17C2E, DECORATIONS, num_dec);

_memory->WriteArray<int>(0x17C2E, DECORATIONS, decorations);
decorations[3] = 264;
decorations[12] = 264;

_memory->WriteArray<int>(0x17C2E, DECORATIONS, decorations);
}

PreventSnipes(); //Prevents Snipes to preserve progression randomizer experience

Expand Down
26 changes: 22 additions & 4 deletions Source/Archipelago/APWatchdog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -503,7 +503,12 @@ void APWatchdog::RefreshDoorCollisions() {
s << playerPosition[0] << ", " << playerPosition[1] << ", " << playerPosition[2] << "\n";
OutputDebugStringW(s.str().c_str());

for(auto const& [collisionToUpdate, val] : collisionsToRefresh){
for(auto const& p : collisionsToRefresh){
auto collisionToUpdate = p.first;
auto val = p.second;

if (val == -10) return;

if (val > 0) {
collisionsToRefresh[collisionToUpdate] = val - 1;
continue;
Expand All @@ -519,7 +524,7 @@ void APWatchdog::RefreshDoorCollisions() {
s1 << std::hex << collisionToUpdate << " in range. Testing...\n";
OutputDebugStringW(s1.str().c_str());

collisionsToRefresh.erase(collisionToUpdate);
collisionsToRefresh[collisionToUpdate] = -10;

std::vector<float> newPositions = ReadPanelData<float>(collisionToUpdate, POSITION, 8);

Expand All @@ -531,13 +536,26 @@ void APWatchdog::RefreshDoorCollisions() {
s << std::hex << collisionToUpdate << " didn't move!!! Updating manually...\n";
OutputDebugStringW(s.str().c_str());

_memory->UpdateEntityPosition(collisionToUpdate);
try {
_memory->UpdateEntityPosition(collisionToUpdate);
}
catch (const std::exception& e) {
collisionsToRefresh[collisionToUpdate] = 2;
return;
}

if(!knownIrrelevantCollisions.count(collisionToUpdate)){
collisionsToRefresh[collisionToUpdate] = 10;
}
}

//_memory->UpdateEntityPosition(collisionToUpdate);
for (auto it = collisionsToRefresh.cbegin(), next_it = it; it != collisionsToRefresh.cend(); it = next_it)
{
++next_it;
if (collisionsToRefresh[it->first] == -10)
{
collisionsToRefresh.erase(it);
}
}

OutputDebugStringW(L"-----\n");
Expand Down
1 change: 0 additions & 1 deletion Source/Archipelago/PanelLocker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ void PanelLocker::DisableNonRandomizedPuzzles(std::set<int> exemptDoorPanels)
disablePuzzle(0x00143); //Orchard Apple Tree 1
disablePuzzle(0x00139); //Keep Hedge Maze 1
disablePuzzle(0x0360E); //Keep Laser Hedges
disablePuzzle(0x15ADD); //River Rhombic Avoid Vault

disablePuzzle(0x0042D); //Mountaintop River Shape

Expand Down
2 changes: 1 addition & 1 deletion Source/Archipelago/PuzzleData.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ void PuzzleData::Read(std::shared_ptr<Memory> _memory) {
hasStones = true;
hasColoredStones = true;
}
else if (id == 0x00557 || id == 0x005F1 || id == 0x00620 || id == 0x009F5 || id == 0x0146C || id == 0x3C12D || id == 0x03686 || id == 0x014E9 || id == 0x0367C || id == 0x334D8 || id == 0x00B71) { // quarry erazor + stones (stones are incorrectly detected as b/w)
else if (id == 0x03677 || id == 0x00557 || id == 0x005F1 || id == 0x00620 || id == 0x009F5 || id == 0x0146C || id == 0x3C12D || id == 0x03686 || id == 0x014E9 || id == 0x0367C || id == 0x334D8 || id == 0x00B71) { // quarry erazor + stones (stones are incorrectly detected as b/w)
hasStones = false;
hasColoredStones = true;
}
Expand Down
86 changes: 78 additions & 8 deletions Source/Memory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,64 @@ void Memory::findPlayerPosition() {
});
}

void Memory::findImportantFunctionAddresses()
{
//open door
executeSigScan({ 0x0F, 0x57, 0xC9, 0x48, 0x8B, 0xCB, 0x48, 0x83, 0xC4, 0x20 }, [this](__int64 offset, int index, const std::vector<byte>& data) {
for (; index < data.size(); index++) {
if (data[index - 2] == 0xF3 && data[index - 1] == 0x0F) { // need to find actual function, which I could not get a sigscan to work for, so I did the function right before it
this->openDoorFunction = _baseAddress + index - 2;
break;
}
}

return true;
});

//Update Entity Position
executeSigScan({ 0x44, 0x0F, 0xB6, 0xCA, 0x4C, 0x8D, 0x41, 0x34 }, [this](__int64 offset, int index, const std::vector<byte>& data) {
this->updateEntityPositionFunction = _baseAddress + index;

return true;
});

//Activate Laser
executeSigScan({ 0x40, 0x53, 0x48, 0x83, 0xEC, 0x60, 0x83, 0xB9 }, [this](__int64 offset, int index, const std::vector<byte>& data) {
this->activateLaserFunction = _baseAddress + index;

return true;
});

//hudTime
executeSigScan({ 0x40, 0x53, 0x48, 0x83, 0xEC, 0x20, 0x83, 0x3D }, [this](__int64 offset, int index, const std::vector<byte>& data) {
this->displayHudFunction = _baseAddress + index;

for (; index < data.size(); index++) {
if (data[index - 2] == 0xF3 && data[index - 1] == 0x0F) { // find the movss statement
this->hudTimePointer = _baseAddress + index + 2;

int buff[1];

ReadProcessMemory(_handle, reinterpret_cast<LPCVOID>(this->hudTimePointer), buff, sizeof(buff), NULL);

this->relativeAddressOf6 = buff[0];

uintptr_t addressOf1 = this->hudTimePointer + 4 + buff[0];

executeSigScan({ 0x00, 0x00, 0xC0, 0x40 }, [this](__int64 offset, int index, const std::vector<byte>& data) {
this->relativeAddressOf6 += index;

return true;
}, addressOf1);

break;
}
}

return true;
});
}

void Memory::findMovementSpeed() {
executeSigScan({ 0xF3, 0x0F, 0x59, 0xFD, 0xF3, 0x0F, 0x5C, 0xC8 }, [this](__int64 offset, int index, const std::vector<byte>& data) {
int found = 0;
Expand Down Expand Up @@ -160,22 +218,26 @@ __int64 Memory::ReadStaticInt(__int64 offset, int index, const std::vector<byte>
return offset + index + bytesToEOL + *(int*)&data[index];
}

#define BUFFER_SIZE 0x10000 // 10 KB
void Memory::executeSigScan(const std::vector<byte>& scanBytes, const ScanFunc2& scanFunc) {
#define BUFFER_SIZE 0x1000000 // 10 KB
void Memory::executeSigScan(const std::vector<byte>& scanBytes, const ScanFunc2& scanFunc, uintptr_t startAddress) {
std::vector<byte> buff;
buff.resize(BUFFER_SIZE + 0x100); // padding in case the sigscan is past the end of the buffer

for (uintptr_t i = _baseAddress; i < _baseAddress + 0x500000; i += BUFFER_SIZE) {
for (uintptr_t i = startAddress; i < startAddress + 0x50000000; i += BUFFER_SIZE) {
SIZE_T numBytesWritten;
if (!ReadProcessMemory(_handle, reinterpret_cast<void*>(i), &buff[0], buff.size(), &numBytesWritten)) continue;
buff.resize(numBytesWritten);
int index = find(buff, scanBytes);
if (index == -1) continue;
scanFunc(i - _baseAddress, index, buff); // We're expecting i to be relative to the base address here.
scanFunc(i - startAddress, index, buff); // We're expecting i to be relative to the base address here.
return;
}
}

void Memory::executeSigScan(const std::vector<byte>& scanBytes, const ScanFunc2& scanFunc) {
executeSigScan(scanBytes, scanFunc, _baseAddress);
}

void Memory::ThrowError(std::string message) {
if (!showMsg) {
if(errorWindow != NULL){
Expand Down Expand Up @@ -290,11 +352,11 @@ void Memory::DisplayHudMessage(std::string message) {
if (!_messageAddress) {
_messageAddress = VirtualAllocEx(_handle, NULL, sizeof(buffer), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);

__int64 address = 0x1401E9E6C;
__int64 address = hudTimePointer;
LPVOID addressPointer = reinterpret_cast<LPVOID>(address);
__int32 addressOf8 = 0x0032BEC8;
__int32 addressOf6 = relativeAddressOf6;

Write(addressPointer, &addressOf8, sizeof(addressOf8));
Write(addressPointer, &addressOf6, sizeof(addressOf6));
}

strcpy_s(buffer, message.c_str());
Expand All @@ -304,7 +366,7 @@ void Memory::DisplayHudMessage(std::string message) {



__int64 funcAdress = 0x1401E9E30;
__int64 funcAdress = displayHudFunction;
__int64 messageAddress = reinterpret_cast<__int64>(_messageAddress);

unsigned char asmBuff[] =
Expand Down Expand Up @@ -354,6 +416,14 @@ int Memory::RUNSPEED = 0;
int Memory::CAMERAPOSITION = 0;
int Memory::ACCELERATION = 0;
int Memory::DECELERATION = 0;

uint64_t Memory::relativeAddressOf6 = 0;
uint64_t Memory::openDoorFunction = 0;
uint64_t Memory::activateLaserFunction = 0;
uint64_t Memory::hudTimePointer = 0;
uint64_t Memory::updateEntityPositionFunction = 0;
uint64_t Memory::displayHudFunction = 0;

std::vector<int> Memory::ACTIVEPANELOFFSETS = {};
bool Memory::showMsg = false;
HWND Memory::errorWindow = NULL;
Expand Down
16 changes: 13 additions & 3 deletions Source/Memory.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ class Memory
void findMovementSpeed();
void findActivePanel();
void findPlayerPosition();
void findImportantFunctionAddresses();
int GetActivePanel();
static __int64 ReadStaticInt(__int64 offset, int index, const std::vector<byte>& data, size_t bytesToEOL = 4);
~Memory();
Expand Down Expand Up @@ -140,15 +141,15 @@ class Memory
}

void OpenDoor(int id) {
CallVoidFunction(id, 0x14008EB60);
CallVoidFunction(id, openDoorFunction);
}

void UpdateEntityPosition(int id) {
CallVoidFunction(id, 0x140184F00); // Entity::has_moved_in_a_non_position_way - Still works even if it HAS moved in a non position way, for some reason :P
CallVoidFunction(id, updateEntityPositionFunction); // Entity::has_moved_in_a_non_position_way - Still works even if it HAS moved in a non position way, for some reason :P
}

void ActivateLaser(int id) {
CallVoidFunction(id, 0x1400AF520);
CallVoidFunction(id, activateLaserFunction);
}

void RemoveMesh(int id);
Expand All @@ -160,6 +161,14 @@ class Memory
static int GLOBALS;
static int RUNSPEED;
static int CAMERAPOSITION;

static uint64_t openDoorFunction;
static uint64_t updateEntityPositionFunction;
static uint64_t activateLaserFunction;
static uint64_t hudTimePointer;
static uint64_t relativeAddressOf6;
static uint64_t displayHudFunction;

static std::vector<int> ACTIVEPANELOFFSETS;
static int ACCELERATION;
static int DECELERATION;
Expand Down Expand Up @@ -193,6 +202,7 @@ class Memory

using ScanFunc = std::function<void(__int64 offset, int index, const std::vector<byte>& data)>;
using ScanFunc2 = std::function<bool(__int64 offset, int index, const std::vector<byte>& data)>;
void executeSigScan(const std::vector<byte>& scanBytes, const ScanFunc2& scanFunc, uintptr_t startAddress);
void executeSigScan(const std::vector<byte>& scanBytes, const ScanFunc2& scanFunc);

void ThrowError(std::string message);
Expand Down

0 comments on commit 31410d5

Please sign in to comment.