BoTW-Multiplayer/DLL/InjectDLL/CharacterClasses.cpp
2025-01-20 14:05:21 -06:00

1286 lines
37 KiB
C++

#include "Memory.h"
#include <iostream>
#include <filesystem>
#include "LoggerService.h"
using namespace Memory;
////////////////// Link's class //////////////////
void Link_class::UpdatePosition()
{
for (int i = 0; i < 3; i++)
{
Position[i] = Memory::read_bigEndianFloat(PosAddr + (i * 0x4), __FUNCTION__);
}
}
void Link_class::UpdateRotation()
{
Rotation = Memory::read_bigEndianFloat(RotAddr, __FUNCTION__);
}
void Link_class::UpdateSpeed()
{
for (int i = 0; i < 3; i++)
{
Speed[i] = Memory::read_bigEndianFloat(SpdAddr + (i * 0x4), __FUNCTION__);
}
}
void Link_class::UpdateAnimation()
{
Animation = Memory::read_bigEndian4Bytes(AnimAddr, __FUNCTION__);
}
void Link_class::UpdateLocation()
{
Map = Memory::extractLocName(locationAddr + 0x14);
Section = Memory::extractLocName(locationAddr + 0x40);
Town = Memory::extractLocName(townAddr + 0x20);
}
int Link_class::UpdateHealth()
{
int tempHealth = Memory::read_bigEndian4Bytes(HealthAddr, __FUNCTION__);
int ReturnValue = 0;
if (tempHealth != Health)
{
if (Health < tempHealth && Health == 0)
{
ReturnValue = 1;
}
Health = tempHealth;
lastHealthUpdate = GetTickCount();
}
return ReturnValue;
}
std::vector<uint64_t> Link_class::ScanData()
{
std::vector<uint64_t> result;
std::stringstream stream;
WeaponDamages = readWeaponDamages();
lastHealthReduce = GetTickCount();
std::vector<int> sig;
while (true)
{
sig = { 0x03, -1, 0xB5, 0xCC, 0x00, 0x00, 0x00, 0x00, 0x10, 0x54, 0xF6, 0x44, 0x10, 0x2B, 0x7E, 0x78, 0x00, 0x00, 0x00 };
locationAddr = Memory::PatternScan(sig, getBaseAddress(), 8, 0xe000000);
if (locationAddr < 30000)
{
Logging::LoggerService::LogWarning("Failed to find location.", __FUNCTION__);
Sleep(2000);
continue;
}
stream << "Location: " << std::hex << locationAddr << std::endl;
break;
}
MEMORY_BASIC_INFORMATION mbi{ 0 };
uint64_t startAddr = getBaseAddress();
for (int i = 0; i < 7; i++)
{
if (VirtualQuery((LPCVOID)startAddr, &mbi, sizeof(mbi)))
{
startAddr += mbi.RegionSize;
}
}
uint64_t offset = locationAddr - startAddr - 0x500000;
while (true)
{
sig = { 0xff, 0xff, 0xff, 0xf1, 0x3f, -1, -1, -1, 0x80, 0x00, -1, -1, 0x11, -1, -1, -1, 0x10, 0xdf, -1, -1, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x80 };
//PosAddr = Memory::PatternScan(sig, getBaseAddress(), 8, offset, false, false, 0xF999999) + 0xD4;
//if (PosAddr < 30000)
//{
// //std::cout << "Failed to find position" << std::endl;
// continue;
//}
//std::cout << "Position: " << std::hex << PosAddr << std::endl;
//break;
std::vector<uint64_t> ListAddrs = Memory::PatternScanMultiple(sig, getBaseAddress(), 8, offset, false, 0, 5);
if (ListAddrs.size() == 0)
{
continue;
}
else if (ListAddrs.size() == 1)
{
if (PosAddr < 30000)
{
PosAddr = ListAddrs[0] + 0xD4;
stream << "Position: " << std::hex << PosAddr << std::endl;;
break;
}
}
else
{
for (int i = 0; i < ListAddrs.size(); i++)
{
float sum = 0;
for (int j = 0; j < 3; j++)
{
sum += Memory::read_bigEndianFloat(ListAddrs[i] + 0xD4 + (j * 4), __FUNCTION__);
}
if (sum == 0)
{
continue;
}
else
{
PosAddr = ListAddrs[i] + 0xD4;
std::cout << "Found " << ListAddrs.size() << " addreses for Position" << std::endl;
break;
}
}
}
if (PosAddr < 30000)
{
//std::cout << "Failed to find position" << std::endl;
Logging::LoggerService::LogWarning("Failed to find Position.", __FUNCTION__);
continue;
}
stream << "Position: " << std::hex << PosAddr << std::endl;
break;
}
offset += PosAddr - locationAddr;
while (true)
{
sig = { 0x5F, 0x28, 0x32, 0x89, -1, -1, -1, -1, 0x5F, 0x28, 0x32, 0x89 };
porchAddr = Memory::PatternScan(sig, getBaseAddress(), 8, offset, false, false, 0x70000000) + 0x4;
if (porchAddr < 30000)
{
Logging::LoggerService::LogWarning("Failed to find porch.", __FUNCTION__);
continue;
}
stream << "Porch: " << std::hex << porchAddr << std::endl;
break;
}
offset += porchAddr - PosAddr;
while (true)
{
sig = { 0x82, 0x48, 0x92, 0xBE, -1, -1, -1, -1, 0x82, 0x48, 0x92, 0xBE };
equippedAddr = Memory::PatternScan(sig, getBaseAddress(), 8, offset, false, false, 0x70000000) + 0x4;
if (equippedAddr < 30000)
{
Logging::LoggerService::LogWarning("Failed to find inventory status.", __FUNCTION__);
continue;
}
stream << "Equipped: " << std::hex << equippedAddr << std::endl;
break;
}
offset += equippedAddr - porchAddr;
uint64_t dayAddr;
while (true)
{
sig = { 0x7B, 0x4B, 0xE8, 0x51, 0x00, 0x00, 0x00, 0x00, 0x10, 0x29, 0x84, 0xC8 };
dayAddr = Memory::PatternScan(sig, getBaseAddress(), 8, offset, false, false, 0x70000000) - 0x04;
if (dayAddr < 30000)
{
Logging::LoggerService::LogWarning("Failed to find day.", __FUNCTION__);
continue;
}
stream << "Day: " << std::hex << dayAddr << std::endl;
break;
}
offset += porchAddr - dayAddr;
while (true)
{
sig = { 0x10, 0x21, 0x2C, 0xD4, -1, -1, -1, 0xE4, -1, -1, -1, 0x98, -1, -1, -1, 0x24, 0x10, 0x21, 0x2C, 0x94, -1, -1, -1, 0xF4, 0x10, 0x21, 0x29, 0xEC, 0x00, 0x00, 0x01, 0x00 };
townAddr = Memory::PatternScan(sig, getBaseAddress(), 8, offset, false, false, 0x70000000);
if (townAddr < 30000)
{
Logging::LoggerService::LogWarning("Failed to find town.", __FUNCTION__);
continue;
}
stream << "Town: " << std::hex << townAddr << std::endl;
break;
}
offset += townAddr - equippedAddr;
while (true)
{
sig = { 0x6E, -1, -1, 0x38, 0x00, 0x00, 0x00, -1, 0x6E, -1, -1, -1, 0x6E, -1, -1, 0x58, -1, -1, -1, -1, 0x00, 0x00, 0x00, -1, 0x6E, -1, -1, -1, 0x6E, 0xD1 };
HealthAddr = Memory::PatternScan(sig, getBaseAddress(), 8, offset, false, false, 0x70000000) + 0x4;
if (HealthAddr < 30000)
{
Logging::LoggerService::LogWarning("Failed to find health.", __FUNCTION__);
continue;
}
stream << "Health: " << std::hex << HealthAddr << std::endl;
break;
}
offset += HealthAddr - townAddr;
while (true)
{
sig = { 0xBF, 0x80, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, -1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -1, 0x80, 0x00, 0x00 };
RotAddr = Memory::PatternScan(sig, getBaseAddress(), 8, offset, false, false, 0x70000000) + 0x2C;
if (RotAddr < 30000)
{
Logging::LoggerService::LogWarning("Failed to find rotation.", __FUNCTION__);
continue;
}
stream << "Rotation: " << std::hex << RotAddr << std::endl;
break;
}
offset += RotAddr - HealthAddr;
while (true)
{
sig = { 0x6E, -1, -1, 0x68, 0x6E, -1, -1, 0xB4, 0x6E, -1, -1, 0x00, 0x6E };
EqAddr = Memory::PatternScan(sig, getBaseAddress(), 8, offset, false, false, 0x70000000) + 0x40;
if (EqAddr < 30000)
{
Logging::LoggerService::LogWarning("Failed to find equipped status.", __FUNCTION__);
continue;
}
stream << "IsEquipped: " << std::hex << EqAddr << std::endl;
break;
}
offset += EqAddr - RotAddr;
while (true)
{
sig = { 0x10, 0x3C, 0x71, 0xE4, -1, -1, 0x36, 0x84 };
AnimAddr = Memory::PatternScan(sig, getBaseAddress(), 8, offset, false, false, 0x70000000) + 0x08;
if (AnimAddr < 30000)
{
//std::cout << "Failed to find animation" << std::endl;
sig = { 0x8A, 0xB9, 0x46, 0x6F, -1, 0x00, 0x00 };
AnimAddr = Memory::PatternScan(sig, getBaseAddress(), 8, offset, false, false, 0x70000000);
if (AnimAddr < 30000) continue;
}
stream << "Animation: " << std::hex << AnimAddr << std::endl;
break;
}
offset += AnimAddr - EqAddr;
while (true)
{
sig = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -1, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, -1, 0x3F, 0x80, 0x00, 0x00 };
defAddr = Memory::PatternScan(sig, getBaseAddress(), 8, offset, false, false, 0x70000000) + 0x20;
if (defAddr < 30000)
{
Logging::LoggerService::LogWarning("Failed to find defense.", __FUNCTION__);
continue;
}
stream << "Def: " << std::hex << defAddr << std::endl;
break;
}
offset += EqAddr - defAddr;
uint64_t timeAddr;
int attempt = 0;
while (true)
{
std::vector<int> sig0 = { 0x10, 0x29, 0x7D, 0x40, -1, 0x2E, 0xE9, 0x50 };
std::vector<int> sig1 = { 0x10, 0x29, 0x7D, 0x40, -1, 0x2E, 0xB2, 0xC0 };
sig = attempt == 0 ? sig0 : sig1;
timeAddr = Memory::PatternScan(sig, getBaseAddress(), 8, offset, false, false);
if (timeAddr < 30000)
{
attempt = attempt == 0 ? 1 : 0;
Logging::LoggerService::LogWarning("Failed to find time.", __FUNCTION__);
continue;
}
else
{
timeAddr = timeAddr - 0x04;
}
stream << "Time: " << std::hex << timeAddr << std::endl;
break;
}
Logging::LoggerService::LogDebug(stream.str());
lastEquipment["W"] = "";
lastEquipment["S"] = "";
lastEquipment["B"] = "";
lastEquipment["H"] = "";
lastEquipment["U"] = "";
lastEquipment["L"] = "";
atkupAddr = RotAddr + 0xE0;
result.push_back(dayAddr);
result.push_back(timeAddr);
Link_class::UpdateData();
return result;
}
int Link_class::UpdateData() {
int ReturnValue = 0;
if (PosAddr + RotAddr + SpdAddr + AnimAddr > 30000)
{
Link_class::UpdatePosition();
Link_class::UpdateRotation();
Link_class::UpdateAnimation();
Link_class::UpdateLocation();
ReturnValue = Link_class::UpdateHealth();
Link_class::UpdatePlayerEquipment();
Link_class::UpdateAtkDef();
Link_class::UpdateIsEquipped();
}
return ReturnValue;
}
void Link_class::UpdatePlayerEquipment()
{
Equipment.clear();
for (int i = 0; i < 420; i++)
{
int isEquipped = Memory::read_bigEndian4Bytes(equippedAddr + (i * 8), __FUNCTION__);
if (isEquipped == 1)
{
std::string equipmentName = "";
for (int j = 0; j < 16; j++)
{
equipmentName += Memory::read_string(porchAddr + (i * 128) + (j * 8), 4, __FUNCTION__);
}
Equipment.push_back(equipmentName);
}
}
}
void Link_class::UpdateAtkDef()
{
atkup = Memory::read_bigEndianFloat(atkupAddr, __FUNCTION__);
def = Memory::read_bigEndian4Bytes(defAddr, __FUNCTION__);
}
void Link_class::UpdateIsEquipped()
{
IsEquipped = Memory::read_bytes(EqAddr, 1, __FUNCTION__)[0] == 0x0 ? 1 : 0;
}
void Link_class::reduceHealth(int healthToReduce)
{
float timeSinceLastHit = float(GetTickCount() - lastHealthReduce) / 1000;
if (timeSinceLastHit < 1)
{
return;
}
Memory::write_bigEndian4Bytes(HealthAddr, Health - healthToReduce, __FUNCTION__);
lastHealthReduce = GetTickCount();
}
rapidjson::Document Link_class::readWeaponDamages()
{
char* appdata = nullptr;
size_t sz = 0;
_dupenv_s(&appdata, &sz, "APPDATA");
std::string str(appdata);
std::string filepath = "\\BOTWM\\WeaponDamages.txt";
std::ifstream file(appdata + filepath);
std::stringstream buffer;
buffer << file.rdbuf();
rapidjson::Document doc;
doc.Parse(buffer.str().c_str());
rapidjson::StringBuffer buf;
rapidjson::Writer<rapidjson::StringBuffer> writer(buf);
doc.Accept(writer);
return doc;
}
std::map<std::string, std::string> Link_class::GetPosition()
{
std::map<std::string, std::string> result;
result["x"] = to_string_precision(Position[0], 4);
result["y"] = to_string_precision(Position[1], 4);
result["z"] = to_string_precision(Position[2], 4);
return result;
}
std::string Link_class::GetRotation()
{
std::string result = to_string_precision(Rotation, 4);
return result;
}
std::string Link_class::GetAnimation()
{
std::string result = std::to_string(Animation);
return result;
}
std::map<std::string, std::string> Link_class::GetSpeed()
{
std::map<std::string, std::string> result;
result["x"] = to_string_precision(Speed[0], 4);
result["y"] = to_string_precision(Speed[1], 4);
result["z"] = to_string_precision(Speed[2], 4);
return result;
}
std::map<std::string, std::string> Link_class::GetLocation()
{
std::map<std::string, std::string> result;
result["M"] = Map;
result["S"] = Section;
result["T"] = Town;
return result;
}
std::string Link_class::GetHealth()
{
return std::to_string(Health);
}
std::map<std::string, std::string> Link_class::GetEquipment()
{
std::map<std::string, std::string> newEq;
newEq["W"] = "";
newEq["S"] = "";
newEq["B"] = "";
newEq["H"] = "Armor_Default_Head";
newEq["U"] = "Armor_Default_Upper";
newEq["L"] = "Armor_Default_Lower";
for (int i = 0; i < Equipment.size(); i++)
{
if (Equipment[i].find("Weapon") != std::string::npos && Equipment[i].find("Shield") == std::string::npos && Equipment[i].find("Bow") == std::string::npos)
{
if (Equipment[i] != lastEquipment["W"] || 1 == 1)
{
newEq["W"] = Equipment[i];
lastEquipment["W"] = Equipment[i];
}
else
{
newEq["W"] = ".";
}
}
else if (Equipment[i].find("Weapon") != std::string::npos && Equipment[i].find("Shield") != std::string::npos)
{
if (Equipment[i] != lastEquipment["S"] || 1 == 1)
{
newEq["S"] = Equipment[i];
lastEquipment["S"] = Equipment[i];
}
else
{
newEq["S"] = ".";
}
}
else if (Equipment[i].find("Weapon") != std::string::npos && Equipment[i].find("Bow") != std::string::npos)
{
if (Equipment[i] != lastEquipment["B"] || 1 == 1)
{
newEq["B"] = Equipment[i];
lastEquipment["B"] = Equipment[i];
}
else
{
newEq["B"] = ".";
}
}
else if (Equipment[i].find("Head") != std::string::npos)
{
if (Equipment[i] != lastEquipment["H"] || 1 == 1)
{
newEq["H"] = Equipment[i];
lastEquipment["H"] = Equipment[i];
}
else
{
newEq["H"] = ".";
}
}
else if (Equipment[i].find("Upper") != std::string::npos)
{
if (Equipment[i] != lastEquipment["U"] || 1 == 1)
{
newEq["U"] = Equipment[i];
lastEquipment["U"] = Equipment[i];
}
else
{
newEq["U"] = ".";
}
}
else if (Equipment[i].find("Lower") != std::string::npos)
{
if (Equipment[i] != lastEquipment["L"] || 1 == 1)
{
newEq["L"] = Equipment[i];
lastEquipment["L"] = Equipment[i];
}
else
{
newEq["L"] = ".";
}
}
}
return newEq;
}
std::string Link_class::GetAtkUp()
{
return std::to_string(atkup);
}
std::string Link_class::GetDef()
{
return std::to_string(def);
}
std::string Link_class::GetIsEquipped()
{
return std::to_string(IsEquipped);
}
std::string Link_class::GetDataString()
{
std::string dataString = to_string_precision(Position[0], 4) + "," + to_string_precision(Position[1], 4) + "," + to_string_precision(Position[2], 4) + ";" +
to_string_precision(Rotation, 4) + ";" +
std::to_string(Animation) + ";" +
to_string_precision(Speed[0], 0) + "," + to_string_precision(Speed[1], 0) + "," + to_string_precision(Speed[2], 0) + ";" +
Map + "," + Section + "," + Town;
// DON'T FORGET ABOUT HEALTH
return dataString;
}
std::string Link_class::to_string_precision(float number, int precision)
{
std::stringstream stream;
stream << std::fixed << std::setprecision(precision) << number;
return stream.str();
}
void Link_class::Teleport(float newPosition[3])
{
for (int i = 0; i < 3; i++)
Memory::write_bigEndianFloat(PosAddr + (i * 0x4), newPosition[i], __FUNCTION__);
}
////////////////// Other player's class //////////////////
#include <iostream>
OtherPlayer_class::OtherPlayer_class(int PlayerNumber)
{
this->playerNumber = PlayerNumber;
}
uint64_t OtherPlayer_class::FindPosAddr()
{
uint64_t Addr = Memory::read_bigEndian4BytesOffset(this->BaseAddress + 0x3A0, __FUNCTION__);
Addr = Memory::read_bigEndian4BytesOffset(Addr + 0x50, __FUNCTION__);
Addr = Memory::read_bigEndian4BytesOffset(Addr + 0x4, __FUNCTION__);
Addr = Memory::read_bigEndian4BytesOffset(Addr + 0x80, __FUNCTION__);
Addr = Memory::read_bigEndian4BytesOffset(Addr, __FUNCTION__);
Addr = Memory::read_bigEndian4BytesOffset(Addr + 0x5C, __FUNCTION__);
Addr = Memory::read_bigEndian4BytesOffset(Addr + 0x18, __FUNCTION__) + Memory::getBaseAddress();
return Addr + 0x50;
}
void OtherPlayer_class::ClearPointers()
{
this->BaseAddress = 0u;
if (deleteAddr == 0) return;
write_byte(deleteAddr, 0x00, __FUNCTION__);
}
void OtherPlayer_class::FindWeapons()
{
uint64_t TempWeaponAddr = Memory::read_bigEndian4BytesOffset(this->BaseAddress + 0x39C, __FUNCTION__);
TempWeaponAddr = Memory::read_bigEndian4BytesOffset(TempWeaponAddr + 0x78, __FUNCTION__);
TempWeaponAddr = Memory::read_bigEndian4BytesOffset(TempWeaponAddr + 0x244, __FUNCTION__);
int i = 0;
bool Found = false;
while (!Found)
{
uint64_t temp = Memory::read_bigEndian4BytesOffset(TempWeaponAddr + (i * 0x4), __FUNCTION__);
if (int(3518303375) == Memory::read_bigEndian4BytesOffset(temp + 0x10, __FUNCTION__))
{
Found = true;
TempWeaponAddr = Memory::read_bigEndian4BytesOffset(temp + 0x4, __FUNCTION__);
RightHandWeapon = Memory::read_bigEndian4BytesOffset(TempWeaponAddr + 0x1C, __FUNCTION__) + Memory::getBaseAddress();
LeftHandWeapon = Memory::read_bigEndian4BytesOffset(TempWeaponAddr + 0xA0, __FUNCTION__) + Memory::getBaseAddress();
}
i++;
}
}
void OtherPlayer_class::FindArmor()
{
if (this->BaseAddress == 0)
return;
uint64_t TempArmorAddr = Memory::read_bigEndian4BytesOffset(this->BaseAddress + 0x39C, __FUNCTION__);
TempArmorAddr = Memory::read_bigEndian4BytesOffset(TempArmorAddr + 0x6C, __FUNCTION__);
TempArmorAddr = Memory::read_bigEndian4BytesOffset(TempArmorAddr + 0x4B0, __FUNCTION__);
TempArmorAddr = Memory::read_bigEndian4BytesOffset(TempArmorAddr + 0x38, __FUNCTION__);
for (int i = 0; i < 5; i++)
{
uint64_t temp = Memory::read_bigEndian4BytesOffset(TempArmorAddr, __FUNCTION__);
ArmorAddresses[i] = Memory::read_bigEndian4BytesOffset(temp + 0xC, __FUNCTION__) + Memory::getBaseAddress();
TempArmorAddr = Memory::read_bigEndian4BytesOffset(TempArmorAddr + 0x10, __FUNCTION__);
}
}
void OtherPlayer_class::ClearWeapons()
{
std::string BASE_DEFAULT = "BaseHead";
std::string RIGHT_DEFAULT = "RightHandWeaponLongName";
std::string LEFT_DEFAULT = "LeftHandWeaponLongName";
std::string CHEST_DEFAULT = "BaseChest";
std::string UPPER_DEFAULT = "MP_Armor_Default_Upper";
std::string LOWER_DEFAULT = "MP_Armor_Default_Lower";
std::string HEAD_DEFAULT = "MP_Armor_Default_Head";
Memory::write_string(RightHandWeapon, "Jugadorx" + RIGHT_DEFAULT, RIGHT_DEFAULT.size() + 8, __FUNCTION__);
Memory::write_string(LeftHandWeapon, "Jugadorx" + LEFT_DEFAULT, LEFT_DEFAULT.size() + 8, __FUNCTION__);
//Memory::write_string(ArmorAddresses[1], CHEST_DEFAULT, CHEST_DEFAULT.size() + 2);
//Memory::write_string(ArmorAddresses[2], HEAD_DEFAULT, HEAD_DEFAULT.size() + 2);
//Memory::write_string(ArmorAddresses[3], LOWER_DEFAULT, LOWER_DEFAULT.size() + 2);
//Memory::write_string(ArmorAddresses[4], UPPER_DEFAULT, UPPER_DEFAULT.size() + 2);
}
void OtherPlayer_class::SetWeapons()
{
std::string RIGHT_DEFAULT = "RightHandWeaponLongName";
std::string LEFT_DEFAULT = "LeftHandWeaponLongName";
// TODO Despawn and respawn to make sure this data is in memory
FindWeapons();
uint64_t OldAddress = ArmorAddresses[0];
FindArmor();
WeaponChangeMutex.lock();
Memory::write_string(RightHandWeapon, Equipment["W"], RIGHT_DEFAULT.size() + 8, __FUNCTION__);
Memory::write_string(LeftHandWeapon, Equipment["S"], LEFT_DEFAULT.size() + 8, __FUNCTION__);
if (OldAddress == ArmorAddresses[0])
WeaponChanged = false;
WeaponChangeMutex.unlock();
}
void OtherPlayer_class::SetArmor()
{
std::string BASE_DEFAULT = "BaseHead";
std::string CHEST_DEFAULT = "BaseChest";
std::string UPPER_DEFAULT = "MP_Armor_Default_Upper";
std::string LOWER_DEFAULT = "MP_Armor_Default_Lower";
std::string HEAD_DEFAULT = "MP_Armor_Default_Head";
std::string BaseToWrite = BASE_DEFAULT;
std::string UpperToWrite = Equipment["U"] == "" ? UPPER_DEFAULT : "MP_" + Equipment["U"];
std::string LowerToWrite = Equipment["L"] == "" ? LOWER_DEFAULT : "MP_" + Equipment["L"];
std::string HeadToWrite = Equipment["H"] == "" ? HEAD_DEFAULT : "MP_" + Equipment["H"];
std::string ChestToWrite = CHEST_DEFAULT;
if (UpperToWrite == "")
UpperToWrite = UPPER_DEFAULT;
if (UpperToWrite != "" && UpperToWrite != UPPER_DEFAULT)
ChestToWrite = "EmptyModel";
std::vector<std::string> HeadSwapArmors = { "180", "160", "171" };
if (HeadToWrite == "MP_Armor_180_Head" || HeadToWrite == "MP_Armor_160_Head" || HeadToWrite == "MP_Armor_171_Head")
BaseToWrite = "EmptyModel";
if (ArmorAddresses[0] != 0)
{
try {
Memory::write_string(ArmorAddresses[0], BaseToWrite, BASE_DEFAULT.size() + 2, __FUNCTION__);
Memory::write_string(ArmorAddresses[1], ChestToWrite, CHEST_DEFAULT.size() + 2, __FUNCTION__);
Memory::write_string(ArmorAddresses[2], HeadToWrite, HEAD_DEFAULT.size() + 2, __FUNCTION__);
Memory::write_string(ArmorAddresses[3], LowerToWrite, LOWER_DEFAULT.size() + 2, __FUNCTION__);
Memory::write_string(ArmorAddresses[4], UpperToWrite, UPPER_DEFAULT.size() + 2, __FUNCTION__);
}
catch (...)
{
std::cout << "Trying to set armor again" << std::endl;
}
}
}
int OtherPlayer_class::spawnAction(std::vector<std::string> local, std::vector<std::string> server, bool shouldExist, bool isPrint)
{
int action = 0;
bool exists = Memory::read_bytes(existsAddr, 1, __FUNCTION__)[0] == 0x01 ? true : false;
if (exists && !shouldExist)
{
action = -1;
}
else if (!exists && shouldExist)
{
action = 1;
}
if (isPrint) std::cout << exists << " " << shouldExist << " " << action << " | ";
return action;
}
void OtherPlayer_class::setGlyphAddr(uint64_t GAddr)
{
this->GlyphAddr = GAddr;
}
uint64_t OtherPlayer_class::ScanData(uint64_t offset)
{
if (offset == 0)
{
offset = 0x40000000;
}
std::vector<std::vector<int>> sigs = {
{ 0x00, 0x00, 0x00, -1, 0x10, 0x29, 0x84, 0x10, 0x00, 0x09, 0x00, 0x00, 0xD7, 0x31, 0x04, 0xA1 },
{ 0x00, 0x00, 0x00, -1, 0x10, 0x29, 0x84, 0x10, 0x00, 0x09, 0x00, 0x00, 0xE6, 0xD9, 0x1E, 0x3C },
{ 0x00, 0x00, 0x00, -1, 0x10, 0x29, 0x84, 0x10, 0x00, 0x09, 0x00, 0x00, 0x40, 0xAE, 0x15, 0x88 },
{ 0x00, 0x00, 0x00, -1, 0x10, 0x29, 0x84, 0x10, 0x00, 0x09, 0x00, 0x00, 0x85, 0x09, 0x2B, 0x06 }
};
baseAnimationAddr = Memory::PatternScan(sigs[playerNumber - 1], getBaseAddress(), 8, offset) + 0xB;
if (playerNumber == 1)
{
MEMORY_BASIC_INFORMATION mbi{ 0 };
uint64_t startAddr = getBaseAddress();
for (int i = 0; i < 7; i++)
{
if (VirtualQuery((LPCVOID)startAddr, &mbi, sizeof(mbi)))
{
startAddr += mbi.RegionSize;
}
}
offset = baseAnimationAddr - startAddr - 0x500000;
}
lastAnimation = baseAnimationAddr + ((multiplier_animation[80 - 1] - 1) * 0x10);
lastSchedule = baseAnimationAddr + (0x10 * 88) + (0x10 * (multiplier_schedule[11 - 1] - 1));
write_byte(lastAnimation, 0x01, __FUNCTION__);
write_byte(lastSchedule, 0x01, __FUNCTION__);
sigs = {
{ 0xC4, 0x8C, -1, 0x8D, 0x43, 0x8C, 0x00, 0x00, 0x44, 0xEF, 0x5F, 0x3C, 0x71, 0x98, 0x24, 0xBA },
{ 0xC4, 0x8C, -1, 0x8D, 0x43, 0x8C, 0x00, 0x00, 0x44, 0xEF, 0x5F, 0x3C, 0x36, 0x38, 0x5E, 0x6A },
{ 0xC4, 0x8C, -1, 0x8D, 0x43, 0x8C, 0x00, 0x00, 0x44, 0xEF, 0x5F, 0x3C, 0x0B, 0x58, 0x77, 0xDA },
{ 0xC4, 0x8C, -1, 0x8D, 0x43, 0x8C, 0x00, 0x00, 0x44, 0xEF, 0x5F, 0x3C, 0xB9, 0x78, 0xAB, 0xCA }
};
PosAddr = Memory::PatternScan(sigs[playerNumber - 1], getBaseAddress(), 8, offset);
for (int i = 0; i < 3; i++)
{
PosPoint[i] = reinterpret_cast<DWORD*>(PosAddr + (i * 0x4));
}
sigs = {
{ 0x00, 0x00, -1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEC, 0x78, 0x65, 0x77 },
{ 0x00, 0x00, -1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAB, 0xD8, 0x1F, 0xA7 },
{ 0x00, 0x00, -1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x96, 0xB8, 0x36, 0x17 },
{ 0x00, 0x00, -1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x98, 0xEA, 0x07 }
};
RotAddr = Memory::PatternScan(sigs[playerNumber - 1], getBaseAddress(), 8, offset);
sigs = {
{ 0x00, 0x00, -1, 0x00, 0x10, 0x29, 0x84, 0x10, 0x00, 0x09, 0x00, 0x00, 0x73, 0x49, 0x25, 0x2B },
{ 0x00, 0x00, -1, 0x00, 0x10, 0x29, 0x84, 0x10, 0x00, 0x09, 0x00, 0x00, 0xEA, 0x40, 0x74, 0x91 },
{ 0x00, 0x00, -1, 0x00, 0x10, 0x29, 0x84, 0x10, 0x00, 0x09, 0x00, 0x00, 0x9D, 0x47, 0x44, 0x07 },
{ 0x00, 0x00, -1, 0x00, 0x10, 0x29, 0x84, 0x10, 0x00, 0x09, 0x00, 0x00, 0x03, 0x23, 0xD1, 0xA4 }
};
deleteAddr = Memory::PatternScan(sigs[playerNumber - 1], getBaseAddress(), 8, offset) + 0xB;
sigs = {
{ 0x00, 0x00, -1, 0x00, 0x10, 0x29, 0x84, 0x10, 0x00, 0x01, 0x00, -1, 0x52, 0x23, 0x7D, 0x49 },
{ 0x00, 0x00, -1, 0x00, 0x10, 0x29, 0x84, 0x10, 0x00, 0x01, 0x00, -1, 0xDC, 0xAC, 0x7A, 0xAA },
{ 0x00, 0x00, -1, 0x00, 0x10, 0x29, 0x84, 0x10, 0x00, 0x01, 0x00, -1, 0x10, 0x06, 0x7A, 0x34 },
{ 0x00, 0x00, -1, 0x00, 0x10, 0x29, 0x84, 0x10, 0x00, 0x01, 0x00, -1, 0x1A, 0xC3, 0x73, 0x2D }
};
existsAddr = Memory::PatternScan(sigs[playerNumber - 1], getBaseAddress(), 8, offset) + 0xB;
sigs = {
{ 0x00, 0x00, -1, 0x00, 0x10, 0x29, 0x84, 0x10, 0x00, 0x01, 0x00, 0x00, 0x8D, 0x05, 0xC2, 0x9B },
{ 0x00, 0x00, -1, 0x00, 0x10, 0x29, 0x84, 0x10, 0x00, 0x01, 0x00, 0x00, 0xFA, 0x9B, 0x10, 0x6B },
{ 0x00, 0x00, -1, 0x00, 0x10, 0x29, 0x84, 0x10, 0x00, 0x01, 0x00, 0x00, 0x61, 0x3E, 0x5C, 0x04 },
{ 0x00, 0x00, -1, 0x00, 0x10, 0x29, 0x84, 0x10, 0x00, 0x01, 0x00, 0x00, 0x15, 0xA6, 0xB5, 0x8B }
};
isEqAddr = Memory::PatternScan(sigs[playerNumber - 1], getBaseAddress(), 8, offset) + 0xB;
sigs = {
{ 0xAA, 0x06, 0x8A, 0x95, -1, 0x00, 0x00, 0x00, 0x10, 0x29, 0x86, 0x38 },
{ 0x2C, 0x92, 0xF8, 0x3B, -1, 0x00, 0x00, 0x00, 0x10, 0x29, 0x86, 0x38 },
{ 0xE7, 0xCE, 0x2B, 0x9E, -1, 0x00, 0x00, 0x00, 0x10, 0x29, 0x86, 0x38 },
{ 0xFA, 0xCB, 0x1B, 0x26, -1, 0x00, 0x00, 0x00, 0x10, 0x29, 0x86, 0x38 }
};
NameAddr = Memory::PatternScan(sigs[playerNumber - 1], getBaseAddress(), 8, offset) - 0x20;
sigs = {
{ 0xE9, 0xC2, 0xE3, 0xA4, -1, 0x00, 0x00, 0x00, 0x10, 0x29, 0x84, 0x10 },
{ 0x95, 0xA3, 0xC6, 0x7F, -1, 0x00, 0x00, 0x00, 0x10, 0x29, 0x84, 0x10 },
{ 0x08, 0xAC, 0x27, 0x09, -1, 0x00, 0x00, 0x00, 0x10, 0x29, 0x84, 0x10 },
{ 0x6D, 0x61, 0x8D, 0xC9, -1, 0x00, 0x00, 0x00, 0x10, 0x29, 0x84, 0x10 }
};
DisplayNameAddr = Memory::PatternScan(sigs[playerNumber - 1], getBaseAddress(), 8, offset) - 0x1;
counter = 0;
return offset;
}
void OtherPlayer_class::setGlyph(float Position[3])
{
for (int i = 0; i < 3; i++)
{
if (Position[i] != 0)
{
Pos[i] = Position[i];
Memory::write_bigEndianFloat(GlyphAddr + (i * 0x4), Pos[i], __FUNCTION__);
}
}
}
void OtherPlayer_class::setPosition(float Position[3])
{
for (int i = 0; i < 3; i++)
{
if (Position[i] != 0)
{
Pos[i] = Position[i];
//Memory::write_bigEndianFloat(PosAddr + (i * 0x4), Pos[i]);
int val_int;
memcpy(&val_int, &Pos[i], 4);
*PosPoint[i] = (DWORD)Memory::swap_Endian(val_int);
}
}
}
void OtherPlayer_class::setRotation(float Rotation)
{
float correctedRotation = -Rotation + 90;
float rotationRadians = (correctedRotation * 3.1416) / 180;
float axis[] = { 0, 0, 0 };
if (correctedRotation < 90)
{
axis[0] = 1;
}
else
{
axis[0] = -1;
}
axis[2] = tan(rotationRadians) * axis[0];
for (int i = 0; i < 3; i++)
{
Memory::write_bigEndianFloat(RotAddr + (i * 0x4), axis[i], __FUNCTION__);
}
}
void OtherPlayer_class::setAnimation(int Schedule, int Animation)
{
//if (Animation != 0 && Schedule != 0 && doAnimationSync)
//{
// uint64_t newAnimation = baseAnimationAddr + ((multiplier_animation[Animation - 1] - 1) * 0x10);
// uint64_t newSchedule = baseAnimationAddr + (0x10 * 88) + (0x10 * (multiplier_schedule[Schedule - 1] - 1));
// if (Schedule > 13)
// {
// attackTimer = GetTickCount();
// }
// if (lastAnimation != newAnimation)
// {
// Memory::write_byte(lastAnimation, 0x00, __FUNCTION__);
// if (!Memory::read_bytes(lastAnimation, 1, __FUNCTION__)[0])
// {
// Memory::write_byte(newAnimation, 0x01, __FUNCTION__);
// lastAnimation = newAnimation;
// }
// }
// if (lastSchedule != newSchedule)
// {
// Memory::write_byte(lastSchedule, 0x00, __FUNCTION__);
// if (!Memory::read_bytes(lastSchedule, 1, __FUNCTION__)[0])
// {
// Memory::write_byte(newSchedule, 0x01, __FUNCTION__);
// lastSchedule = newSchedule;
// }
// }
//}
}
std::vector<uint64_t> OtherPlayer_class::findWeaponAddr()
{
std::vector<std::vector<int>> sigs = {
{ 0x4A, 0x75, 0x67, 0x61, 0x64, 0x6F, 0x72, 0x31, 0x52, 0x69, 0x67, 0x68, 0x74, 0x48, 0x61, 0x6E, 0x64, 0x57, 0x65, 0x61, 0x70, 0x6F, 0x6E, 0x4C, 0x6F, 0x6E, 0x67, 0x4E, 0x61, 0x6D, 0x65, 0x00, 0x4A, 0x75, 0x67, 0x61, 0x64, 0x6F, 0x72, 0x31, 0x4C, 0x65, 0x66, 0x74, 0x48, 0x61, -1, 0x64, 0x57, 0x65, 0x61, 0x70, 0x6F, 0x6E, 0x4C, 0x6F, 0x6E, 0x67, 0x4E, 0x61, 0x6D, 0x65 },
{ 0x4A, 0x75, 0x67, 0x61, 0x64, 0x6F, 0x72, 0x32, 0x52, 0x69, 0x67, 0x68, 0x74, 0x48, 0x61, 0x6E, 0x64, 0x57, 0x65, 0x61, 0x70, 0x6F, 0x6E, 0x4C, 0x6F, 0x6E, 0x67, 0x4E, 0x61, 0x6D, 0x65, 0x00, 0x4A, 0x75, 0x67, 0x61, 0x64, 0x6F, 0x72, 0x32, 0x4C, 0x65, 0x66, 0x74, 0x48, 0x61, -1, 0x64, 0x57, 0x65, 0x61, 0x70, 0x6F, 0x6E, 0x4C, 0x6F, 0x6E, 0x67, 0x4E, 0x61, 0x6D, 0x65 },
{ 0x4A, 0x75, 0x67, 0x61, 0x64, 0x6F, 0x72, 0x33, 0x52, 0x69, 0x67, 0x68, 0x74, 0x48, 0x61, 0x6E, 0x64, 0x57, 0x65, 0x61, 0x70, 0x6F, 0x6E, 0x4C, 0x6F, 0x6E, 0x67, 0x4E, 0x61, 0x6D, 0x65, 0x00, 0x4A, 0x75, 0x67, 0x61, 0x64, 0x6F, 0x72, 0x33, 0x4C, 0x65, 0x66, 0x74, 0x48, 0x61, -1, 0x64, 0x57, 0x65, 0x61, 0x70, 0x6F, 0x6E, 0x4C, 0x6F, 0x6E, 0x67, 0x4E, 0x61, 0x6D, 0x65 },
{ 0x4A, 0x75, 0x67, 0x61, 0x64, 0x6F, 0x72, 0x34, 0x52, 0x69, 0x67, 0x68, 0x74, 0x48, 0x61, 0x6E, 0x64, 0x57, 0x65, 0x61, 0x70, 0x6F, 0x6E, 0x4C, 0x6F, 0x6E, 0x67, 0x4E, 0x61, 0x6D, 0x65, 0x00, 0x4A, 0x75, 0x67, 0x61, 0x64, 0x6F, 0x72, 0x34, 0x4C, 0x65, 0x66, 0x74, 0x48, 0x61, -1, 0x64, 0x57, 0x65, 0x61, 0x70, 0x6F, 0x6E, 0x4C, 0x6F, 0x6E, 0x67, 0x4E, 0x61, 0x6D, 0x65 }
};
std::vector<uint64_t> result = Memory::PatternScanMultiple(sigs[playerNumber - 1], getBaseAddress(), 8, 0x12000000, false, 0x25000000);
return result;
}
void OtherPlayer_class::deleteActor()
{
write_byte(deleteAddr, 0x01, __FUNCTION__);
}
bool OtherPlayer_class::checkExists()
{
Memory::write_byte(existsAddr, 0, __FUNCTION__);
Sleep(50);
bool exists = Memory::read_bytes(existsAddr, 1, __FUNCTION__)[0] == 0x01 ? true : false;
return exists;
}
//void OtherPlayer_class::changeData(std::map<std::string, std::any> convertedServerData, float time, float coords[])
//{
// float newPos[3] = { -1124.3922, 238, 1914.9768 };
// float newRot = 0;
// float newSpd[3] = { 0, 0, 0 };
// int newSchd = 0;
// int newAnim = 0;
//
// std::vector<std::string> axes = { "x", "y", "z" };
//
// for (int i = 0; i < 3; i++)
// {
// newSpd[i] = (float)std::any_cast<double>(convertedServerData["Speed_" + axes[i]]);
// }
//
// OtherPlayer_class::setPosition(newSpd, time, coords);
//
// if (glyphSync)
// setGlyph(coords);
//
// newRot = (float)std::any_cast<double>(convertedServerData["Rotation"]);
//
// OtherPlayer_class::setRotation(newRot);
//
// newSchd = std::any_cast<int>(convertedServerData["Schedule"]);
// newAnim = std::any_cast<int>(convertedServerData["Animation"]);
//
// OtherPlayer_class::setAnimation(newSchd, newAnim);
//
//}
void OtherPlayer_class::changeData(rapidjson::Value& playerData, float time, float coords[])
{
float newPos[3] = { -1124.3922, 238, 1914.9768 };
float newRot = 0;
int newSchd = 0;
int newAnim = 0;
std::vector<std::string> axes = { "x", "y", "z" };
OtherPlayer_class::setPosition(coords);
if (glyphSync)
setGlyph(coords);
newRot = (float)playerData["R"].GetDouble();
OtherPlayer_class::setRotation(newRot);
newSchd = playerData["Schd"].GetInt();
newAnim = playerData["Anim"].GetInt();
OtherPlayer_class::setAnimation(newSchd, newAnim);
}
bool OtherPlayer_class::changeEq(rapidjson::Value& playerData)
{
std::string RIGHT_DEFAULT = "Jugador1RightHandWeaponLongName";
std::string LEFT_DEFAULT = "Jugador1LeftHandWeaponLongName";
bool isChanged = false;
for (rapidjson::Value::ConstMemberIterator iter = playerData["E"].MemberBegin(); iter != playerData["E"].MemberEnd(); ++iter)
{
std::string EqVal = iter->value.GetString();
std::string EqName = iter->name.GetString();
if (Equipment[EqName] == EqVal)
{
continue;
}
if (EqVal != ".")
{
Equipment[EqName] = EqVal;
if (EqName == "W" || EqName == "S")
{
std::vector<uint64_t> WeaponAddrs = findWeaponAddr();
uint64_t offset = 0;
for (int i = 0; i < WeaponAddrs.size(); i++)
{
Memory::write_string(WeaponAddrs[i], Equipment["W"], RIGHT_DEFAULT.size(), __FUNCTION__);
Memory::write_string(WeaponAddrs[i] + offset, Equipment["S"], LEFT_DEFAULT.size(), __FUNCTION__);
}
isChanged = true;
}
}
}
return isChanged;
}
void OtherPlayer_class::setIsEquipped(int IsEquipped)
{
Memory::write_byte(isEqAddr, IsEquipped, __FUNCTION__);
}
void OtherPlayer_class::restartAnimations()
{
for (int s = 1; s < 16; s++)
{
if (lastSchedule != baseAnimationAddr + (0x10 * 88) + (0x10 * (multiplier_schedule[s - 1] - 1)))
{
Memory::write_byte(baseAnimationAddr + (0x10 * 88) + (0x10 * (multiplier_schedule[s - 1] - 1)), 0x0, __FUNCTION__);
}
}
for (int a = 1; a < 89; a++)
{
if (lastAnimation != baseAnimationAddr + ((multiplier_animation[a - 1] - 1) * 0x10))
{
Memory::write_byte(baseAnimationAddr + ((multiplier_animation[a - 1] - 1) * 0x10), 0x0, __FUNCTION__);
}
}
}
void OtherPlayer_class::changeName(std::string Name, int DisplayName)
{
std::string ActualName = "";
if (Name.size() > 19)
{
ActualName = Name.substr(0, 19);
}
else
{
ActualName = Name;
}
ActualName += " HP: " + std::to_string(Health);
Memory::write_string(NameAddr, ActualName, 32, __FUNCTION__);
Memory::write_byte(DisplayNameAddr, DisplayName, __FUNCTION__);
}