Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
NewSoupVi committed Nov 9, 2022
2 parents 29d2bf8 + decd11b commit 0a0e687
Show file tree
Hide file tree
Showing 7 changed files with 122 additions and 18 deletions.
2 changes: 2 additions & 0 deletions App/WRPGconfig.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
colorblind:false
collect:false
45 changes: 34 additions & 11 deletions Source/Archipelago/APRandomizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ bool APRandomizer::Connect(HWND& messageBoxHandle, std::string& server, std::str
}

std::vector<std::string> receivedItems;
std::map<std::string, int> counts;
std::map<std::string, int> itemCounts;
std::map<std::string, std::array<float, 3>> itemColors;

_memory->WritePanelData<int>(0x00293, BACKGROUND_REGION_COLOR + 12, { mostRecentItemId });

Expand Down Expand Up @@ -89,24 +90,27 @@ bool APRandomizer::Connect(HWND& messageBoxHandle, std::string& server, std::str
name += " (" + ap->get_item_name(realitem) + ")";
}

if (counts.find(name) == counts.end()) {
counts[name] = 1;
// Track the quantity of this item received in this batch.
if (itemCounts.find(name) == itemCounts.end()) {
itemCounts[name] = 1;
receivedItems.emplace_back(name);
}

else {
counts[name]++;
itemCounts[name]++;
}

// Assign a color to the item.
itemColors[name] = getColorForItem(item);
}

for (std::string name : receivedItems) {
// If we received more than one of an item in this batch, add the quantity to the output string.
std::string count = "";

if (counts[name] > 1) {
count = " (x" + std::to_string(counts[name]) + ")";
if (itemCounts[name] > 1) {
count = " (x" + std::to_string(itemCounts[name]) + ")";
}

async->queueMessage("Received " + name + count + ".");
async->queueMessage("Received " + name + count + ".", itemColors[name]);
}
});

Expand Down Expand Up @@ -273,12 +277,12 @@ bool APRandomizer::Connect(HWND& messageBoxHandle, std::string& server, std::str
int location = item.location;

if (panelIdToLocationIdReverse.count(location) && !_memory->ReadPanelData<int>(panelIdToLocationIdReverse[location], SOLVED)) {
async->queueMessage("(Collect) Sent " + itemName + " to " + player + ".");
async->queueMessage("(Collect) Sent " + itemName + " to " + player + ".", getColorForItem(item));
}
else
{
panelLocker->SetItemReward(findResult->first, item);
if(!receiving) async->queueMessage("Sent " + itemName + " to " + player + ".");
if(!receiving) async->queueMessage("Sent " + itemName + " to " + player + ".", getColorForItem(item));
}
}
});
Expand Down Expand Up @@ -463,4 +467,23 @@ void APRandomizer::SeverDoors() {
bool APRandomizer::InfiniteChallenge(bool enable) {
if(randomizationFinished) async->InfiniteChallenge(enable);
return randomizationFinished;
}

std::array<float, 3> APRandomizer::getColorForItem(const APClient::NetworkItem& item)
{
// Pick the appropriate color for this item based on its progression flags. Colors are loosely based on AP codes but somewhat
// paler to match the Witness aesthetic. See https://github.com/ArchipelagoMW/Archipelago/blob/main/NetUtils.py for details.
if (item.flags & APClient::ItemFlags::FLAG_ADVANCEMENT) {
return { 0.82f, 0.76f, 0.96f };
}
else if (item.flags & APClient::ItemFlags::FLAG_NEVER_EXCLUDE) {
// NOTE: "never exclude" here maps onto "useful" in the AP source.
return { 0.68f, 0.75f, 0.94f };
}
else if (item.flags & APClient::ItemFlags::FLAG_TRAP) {
return { 1.f, 0.7f, 0.67f };
}
else {
return { 0.81f, 1.f, 1.f };
}
}
2 changes: 2 additions & 0 deletions Source/Archipelago/APRandomizer.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ class APRandomizer {
void setPuzzleLocks(HWND loadingHandle);

std::string buildUri(std::string& server);

std::array<float, 3> getColorForItem(const APClient::NetworkItem& item);
};

#define DATAPACKAGE_CACHE "ap_datapackage.json"
Expand Down
4 changes: 2 additions & 2 deletions Source/Archipelago/APWatchdog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -691,9 +691,9 @@ void APWatchdog::DisplayMessage() {

if (outstandingMessages.empty()) return;

std::string message = outstandingMessages.front();
HudMessage message = outstandingMessages.front();
outstandingMessages.pop();
_memory->DisplayHudMessage(message);
_memory->DisplayHudMessage(message.text, message.rgbColor);

messageCounter = 8;
}
Expand Down
21 changes: 19 additions & 2 deletions Source/Archipelago/APWatchdog.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@
#include "APState.h"
#include "PanelLocker.h"

struct HudMessage {
std::string text;
std::array<float, 3> rgbColor;
};

struct AudioLogMessage {
std::string line1;
std::string line2;
Expand Down Expand Up @@ -59,7 +64,19 @@ class APWatchdog : public Watchdog {

void DoubleDoorTargetHack(int id);

void queueMessage(std::string message) {
void queueMessage(std::string text) {
HudMessage message;
message.text = text;
message.rgbColor = { 1.0f, 1.0f, 1.0f };

outstandingMessages.push(message);
}

void queueMessage(std::string text, std::array<float, 3> rgbColor) {
HudMessage message;
message.text = text;
message.rgbColor = rgbColor;

outstandingMessages.push(message);
}

Expand Down Expand Up @@ -90,7 +107,7 @@ class APWatchdog : public Watchdog {
std::chrono::system_clock::time_point temporarySpeedModificationTime;
bool hasEverModifiedSpeed = false;

std::queue<std::string> outstandingMessages;
std::queue<HudMessage> outstandingMessages;
int messageCounter = 0;

std::map<int, AudioLogMessage> audioLogMessageBuffer;
Expand Down
63 changes: 61 additions & 2 deletions Source/Memory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,27 @@ int find(const std::vector<byte> &data, const std::vector<byte> &search) {
return -1;
}

std::vector<int> findAll(const std::vector<byte>& sourceData, const std::vector<byte>& searchSequence) {
std::vector<int> foundIndices;
for (int sourceIndex = 0; sourceIndex < sourceData.size() - searchSequence.size(); sourceIndex++) {
bool foundMatch = true;

for (int comparisonIndex = 0; comparisonIndex < searchSequence.size(); comparisonIndex++) {
if (sourceData[sourceIndex + comparisonIndex] != searchSequence[comparisonIndex])
{
foundMatch = false;
break;
}
}

if (foundMatch) {
foundIndices.push_back(sourceIndex);
}
}

return foundIndices;
}

int Memory::findGlobals() {
const std::vector<byte> scanBytes = {0x74, 0x41, 0x48, 0x85, 0xC0, 0x74, 0x04, 0x48, 0x8B, 0x48, 0x10};
#define BUFFER_SIZE 0x100000 // 100 KB
Expand Down Expand Up @@ -333,6 +354,36 @@ void Memory::findImportantFunctionAddresses(){
return true;
});

// Find hud_draw_headline and its three hardcoded float values for R, G, and B.
executeSigScan({ 0x48, 0x83, 0xEC, 0x68, 0xF2, 0x0F, 0x10, 0x05 }, [this](__int64 offset, int index, const std::vector<byte>& data) {
// hud_draw_headline draws text twice: once for black text to use as a drop shadow and once using values that are assigned at runtime from hardcoded values. We need to
// find the addresses of the three hardcoded values (which are all 1.0f) and store them off to be overwritten in the future.
uint64_t functionAddress = _baseAddress + offset + index;

// Read the function into memory to ensure that we have the entire function call. This is necessary in case the executeSigScan call found the function very, very close
// to the end of its buffer.
const int functionSize = 0x200;
std::vector<byte> functionBody;
functionBody.resize(functionSize);

SIZE_T numBytesWritten;
ReadProcessMemory(_handle, reinterpret_cast<void*>(functionAddress), &functionBody[0], functionSize, &numBytesWritten);

// Find all three instances of 1.0f. (0x3f800000)
std::vector<int> foundIndices = findAll(functionBody, { 0x00, 0x00, 0x80, 0x3f });
if (foundIndices.size() != 3) {
return false;
}

// Assign values relative to the base function address.
for (int colorIndex = 0; colorIndex < 3; colorIndex++)
{
hudMessageColorAddresses[colorIndex] = functionAddress + foundIndices[colorIndex];
}

return true;
});

//Boat speed
//Find Entity_Boat::set_speed
executeSigScan({0x48, 0x89, 0x5C, 0x24, 0x08, 0x57, 0x48, 0x83, 0xEC, 0x40, 0x0F, 0x29, 0x74, 0x24, 0x30, 0x8B, 0xFA }, [this](__int64 offset, int index, const std::vector<byte>& data) {
Expand Down Expand Up @@ -674,7 +725,7 @@ void Memory::CallVoidFunction(int id, uint64_t functionAdress) {
WaitForSingleObject(thread, INFINITE);
}

void Memory::DisplayHudMessage(std::string message) {
void Memory::DisplayHudMessage(std::string message, std::array<float, 3> rgbColor) {
std::lock_guard<std::recursive_mutex> lock(mtx);
char buffer[1024];

Expand All @@ -692,8 +743,15 @@ void Memory::DisplayHudMessage(std::string message) {

WriteProcessMemory(_handle, _messageAddress, buffer, sizeof(buffer), NULL);

// Write the message's color values to the addresses of the constants we previously found.
const SIZE_T colorSize = sizeof(float);
for (int colorIndex = 0; colorIndex < 3; colorIndex++)
{
void* writeAddress = reinterpret_cast<void*>(hudMessageColorAddresses[colorIndex]);
void* readAddress = reinterpret_cast<void*>(&rgbColor[colorIndex]);


WriteProcessMemory(_handle, writeAddress, readAddress, colorSize, NULL);
}

__int64 funcAdress = displayHudFunction;
__int64 messageAddress = reinterpret_cast<__int64>(_messageAddress);
Expand Down Expand Up @@ -916,6 +974,7 @@ uint64_t Memory::activateLaserFunction = 0;
uint64_t Memory::hudTimePointer = 0;
uint64_t Memory::updateEntityPositionFunction = 0;
uint64_t Memory::displayHudFunction = 0;
uint64_t Memory::hudMessageColorAddresses[3] = {0,0,0};
uint64_t Memory::setBoatSpeed = 0;
uint64_t Memory::boatSpeed4 = 0;
uint64_t Memory::boatSpeed3 = 0;
Expand Down
3 changes: 2 additions & 1 deletion Source/Memory.h
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ class Memory

void RemoveMesh(int id);

void DisplayHudMessage(std::string s);
void DisplayHudMessage(std::string message, std::array<float, 3> rgbColor);

void DisplaySubtitles(std::string line1, std::string line2, std::string line3);

Expand All @@ -180,6 +180,7 @@ class Memory
static uint64_t hudTimePointer;
static uint64_t relativeAddressOf6;
static uint64_t displayHudFunction;
static uint64_t hudMessageColorAddresses[3]; // addresses of constant floats used for HUD message coloring
static uint64_t setBoatSpeed;
static uint64_t boatSpeed4;
static uint64_t boatSpeed3;
Expand Down

0 comments on commit 0a0e687

Please sign in to comment.