mirror of
https://github.com/FelipePrado0/SpartanPort.git
synced 2026-11-07 10:45:59 -10:00
EN-US - Renamed code, binaries, packaging, CI and docs to SpartanPort, with the SP monogram and the SpartanPort logo - Renamed only the names in the shadPS4 core and the FSR patch, keeping authors, dates and licenses - Added scripts/legacy.py, the only place with the former name, kept for three releases - Added a one-time copy of the game settings, the launcher settings and the Linux data folder from their former names, without overwriting or deleting anything - Updated the Linux data move to leave the GPU caches (user/cache) and the run views (out/) in the former folder - Added forwarding of the former GOW3_ variables to SPARTAN_ - Added the launcher under its former names, so the 2.5.0 updater and existing shortcuts keep working - Added a note to the READMEs that the project was gow3_pc and that 2.5.0 players keep their saves and settings - Passed the full Python suite (531 tests, 0 failures) and the Windows zip and Linux AppImage CI builds --- PT-BR - Renomeados código, executáveis, empacotamento, CI e docs para SpartanPort, com o monograma SP e o logotipo SpartanPort - Renomeados só os nomes no núcleo do shadPS4 e no patch do FSR, mantendo autores, datas e licenças - Adicionado o scripts/legacy.py, único lugar com o nome antigo, mantido por três releases - Adicionada a cópia única das configurações do jogo, das configurações do launcher e da pasta de dados do Linux a partir dos nomes antigos, sem sobrescrever nem apagar nada - Atualizada a migração da pasta de dados do Linux para deixar os caches da GPU (user/cache) e as pastas de execução (out/) na pasta antiga - Adicionado o repasse das variáveis GOW3_ antigas para SPARTAN_ - Adicionado o launcher com os nomes antigos, para que o atualizador da 2.5.0 e os atalhos existentes continuem funcionando - Adicionada aos READMEs a nota de que o projeto era o gow3_pc e de que jogadores da 2.5.0 mantêm saves e configurações - Aprovadas a suíte Python completa (531 testes, 0 falhas) e as builds de CI do zip do Windows e da AppImage do Linux
120 lines
4.8 KiB
C++
120 lines
4.8 KiB
C++
#include <cassert>
|
|
#include <cmath>
|
|
#include <limits>
|
|
#include "spartanport_orbs.h"
|
|
#include "../src/orb_hook.h"
|
|
#include <vector>
|
|
#include <array>
|
|
#include <cstdio>
|
|
#include <cstdlib>
|
|
#include <filesystem>
|
|
#include "spartanport_settings.h"
|
|
#ifdef _WIN32
|
|
#include <windows.h>
|
|
#else
|
|
#include <sys/mman.h>
|
|
#endif
|
|
|
|
extern "C" float __attribute__((sysv_abi)) spartanport_orbs_gain(void*, float);
|
|
extern "C" void spartanport_orbs_status(int);
|
|
extern "C" void spartanport_cheat_status(unsigned);
|
|
static void __attribute__((sysv_abi)) Setter(void* player, float balance) {
|
|
balance = std::min(balance, 999999.0f);
|
|
std::memcpy(static_cast<unsigned char*>(player) + 0x1e8, &balance, 4);
|
|
}
|
|
|
|
int main(int argc, char** argv) {
|
|
assert(SpartanOrbs::Scale(100, 110, 2) == 120);
|
|
assert(SpartanOrbs::Scale(100, 90, 100) == 90);
|
|
assert(SpartanOrbs::Scale(100, 100, 100) == 100);
|
|
assert(SpartanOrbs::Scale(100, 110, 1) == 110);
|
|
assert(SpartanOrbs::Scale(0, 1, 100) == 100);
|
|
float balance = 0;
|
|
for (int i = 0; i < 10; ++i) balance = SpartanOrbs::Scale(balance, balance + 1, 0.1f);
|
|
assert(std::abs(balance - 1) < 0.00001f);
|
|
assert(SpartanOrbs::Scale(balance, balance + 2, 2) == balance + 4);
|
|
assert(SpartanOrbs::Scale(100, 110, std::numeric_limits<float>::quiet_NaN()) == 110);
|
|
assert(SpartanOrbs::ClampMultiplier(0) == 0.1f);
|
|
assert(SpartanOrbs::ClampMultiplier(101) == 100);
|
|
assert(SpartanOrbs::ClampMultiplier(std::numeric_limits<float>::infinity()) == 1);
|
|
std::vector<unsigned char> image(0x6fbdc);
|
|
uint64_t calls[3];
|
|
assert(spartanport_orb_find(image.data(), image.size(), calls) == UINT64_MAX);
|
|
assert(spartanport_orb_find(image.data(), 1, calls) == UINT64_MAX);
|
|
if (argc > 1) {
|
|
FILE* file = std::fopen(argv[1], "rb");
|
|
assert(file && !std::fseek(file, 0x4000, SEEK_SET));
|
|
assert(std::fread(image.data(), 1, image.size(), file) == image.size());
|
|
std::fclose(file);
|
|
assert(spartanport_orb_find(image.data(), image.size(), calls) == 0x6a9f0);
|
|
image[calls[1] + 1] ^= 1;
|
|
assert(spartanport_orb_find(image.data(), image.size(), calls) == UINT64_MAX);
|
|
}
|
|
#ifdef _WIN32
|
|
auto* stub = static_cast<unsigned char*>(VirtualAlloc(nullptr, 4096, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE));
|
|
#else
|
|
auto* stub = static_cast<unsigned char*>(mmap(nullptr, 4096, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0));
|
|
assert(stub != MAP_FAILED);
|
|
#endif
|
|
assert(stub);
|
|
spartanport_orb_build_stub(stub, reinterpret_cast<uintptr_t>(spartanport_orbs_gain), reinterpret_cast<uintptr_t>(Setter));
|
|
#ifdef _WIN32
|
|
DWORD previous;
|
|
assert(VirtualProtect(stub, 4096, PAGE_EXECUTE_READ, &previous));
|
|
FlushInstructionCache(GetCurrentProcess(), stub, 26);
|
|
#else
|
|
assert(!mprotect(stub, 4096, PROT_READ | PROT_EXEC));
|
|
#endif
|
|
using Hook = void (__attribute__((sysv_abi)) *)(void*, float);
|
|
auto hook = reinterpret_cast<Hook>(stub);
|
|
std::array<unsigned char, 0x200> player{};
|
|
balance = 100;
|
|
std::memcpy(player.data() + 0x1e8, &balance, 4);
|
|
auto& settings = SpartanSettings::Get();
|
|
settings.red_orb_multiplier = 2;
|
|
hook(player.data(), 110);
|
|
std::memcpy(&balance, player.data() + 0x1e8, 4);
|
|
assert(balance == 120);
|
|
settings.cheats[4] = true;
|
|
assert(spartanport_orbs_gain(player.data(), 130) == 140);
|
|
spartanport_cheat_status(4);
|
|
assert(spartanport_orbs_gain(player.data(), 130) == 130);
|
|
settings.cheats[4] = false;
|
|
assert(spartanport_orbs_gain(player.data(), 130) == 140);
|
|
settings.red_orb_multiplier = 100;
|
|
hook(player.data(), 90);
|
|
std::memcpy(&balance, player.data() + 0x1e8, 4);
|
|
assert(balance == 90);
|
|
hook(player.data(), 100000);
|
|
std::memcpy(&balance, player.data() + 0x1e8, 4);
|
|
assert(balance == 999999);
|
|
spartanport_orbs_status(1);
|
|
assert(settings.red_orbs_supported);
|
|
spartanport_orbs_status(0);
|
|
assert(!settings.red_orbs_supported);
|
|
auto config = std::filesystem::temp_directory_path() / "spartanport-orb-multiplier-test.ini";
|
|
assert(!std::filesystem::exists(config));
|
|
#ifdef _WIN32
|
|
_putenv_s("SPARTAN_CONFIG", config.string().c_str());
|
|
#else
|
|
setenv("SPARTAN_CONFIG", config.string().c_str(), 1);
|
|
#endif
|
|
settings.red_orb_multiplier = 0.125f;
|
|
settings.cheats[0] = true;
|
|
settings.cheats[2] = true;
|
|
SpartanSettings::Save();
|
|
settings.red_orb_multiplier = 1;
|
|
settings.cheats[0] = false;
|
|
settings.cheats[2] = false;
|
|
SpartanSettings::Load();
|
|
assert(settings.red_orb_multiplier == 0.125f);
|
|
assert(settings.cheats[0] && settings.cheats[2] && !settings.cheats[1] && !settings.cheats[4]);
|
|
assert(std::filesystem::remove(config));
|
|
#ifdef _WIN32
|
|
VirtualFree(stub, 0, MEM_RELEASE);
|
|
#else
|
|
munmap(stub, 4096);
|
|
#endif
|
|
std::puts("orb-multiplier-test: OK (gains, spending, fractions, signatures, executable hook)");
|
|
}
|