dmnt-cheat: Implement cheat management service commands

This commit is contained in:
Michael Scire 2019-03-04 21:11:12 -08:00
parent 862aa73783
commit 7ddb0da5f6
4 changed files with 167 additions and 14 deletions

View file

@ -211,6 +211,14 @@ CheatEntry *DmntCheatManager::GetFreeCheatEntry() {
return nullptr;
}
CheatEntry *DmntCheatManager::GetCheatEntryById(size_t i) {
if (i < DmntCheatManager::MaxCheatCount) {
return &g_cheat_entries[i];
}
return nullptr;
}
bool DmntCheatManager::ParseCheats(const char *s, size_t len) {
size_t i = 0;
CheatEntry *cur_entry = NULL;
@ -352,6 +360,112 @@ bool DmntCheatManager::LoadCheats(u64 title_id, const u8 *build_id) {
return ParseCheats(cht_txt, strlen(cht_txt));
}
Result DmntCheatManager::GetCheatCount(u64 *out_count) {
std::scoped_lock<HosMutex> lk(g_cheat_lock);
if (!HasActiveCheatProcess()) {
return ResultDmntCheatNotAttached;
}
*out_count = 0;
for (size_t i = 0; i < DmntCheatManager::MaxCheatCount; i++) {
if (g_cheat_entries[i].definition.num_opcodes > 0) {
*out_count += 1;
}
}
return 0;
}
Result DmntCheatManager::GetCheats(CheatEntry *cheats, size_t max_count, u64 *out_count, u64 offset) {
std::scoped_lock<HosMutex> lk(g_cheat_lock);
if (!HasActiveCheatProcess()) {
return ResultDmntCheatNotAttached;
}
u64 count = 0;
*out_count = 0;
for (size_t i = 0; i < DmntCheatManager::MaxCheatCount && (*out_count) < max_count; i++) {
if (g_cheat_entries[i].definition.num_opcodes > 0) {
count++;
if (count > offset) {
cheats[(*out_count)++] = g_cheat_entries[i];
}
}
}
return 0;
}
Result DmntCheatManager::GetCheatById(CheatEntry *out_cheat, u32 cheat_id) {
std::scoped_lock<HosMutex> lk(g_cheat_lock);
if (!HasActiveCheatProcess()) {
return ResultDmntCheatNotAttached;
}
const CheatEntry *entry = GetCheatEntryById(cheat_id);
if (entry == nullptr || entry->definition.num_opcodes == 0) {
return ResultDmntCheatUnknownChtId;
}
*out_cheat = *entry;
return 0;
}
Result DmntCheatManager::ToggleCheat(u32 cheat_id) {
std::scoped_lock<HosMutex> lk(g_cheat_lock);
if (!HasActiveCheatProcess()) {
return ResultDmntCheatNotAttached;
}
CheatEntry *entry = GetCheatEntryById(cheat_id);
if (entry == nullptr || entry->definition.num_opcodes == 0) {
return ResultDmntCheatUnknownChtId;
}
entry->enabled = !entry->enabled;
return 0;
}
Result DmntCheatManager::AddCheat(u32 *out_id, CheatDefinition *def, bool enabled) {
std::scoped_lock<HosMutex> lk(g_cheat_lock);
if (!HasActiveCheatProcess()) {
return ResultDmntCheatNotAttached;
}
if (def->num_opcodes == 0 || def->num_opcodes > sizeof(def->opcodes)/sizeof(def->opcodes[0])) {
return ResultDmntCheatInvalidCheat;
}
CheatEntry *new_entry = GetFreeCheatEntry();
if (new_entry == nullptr) {
return ResultDmntCheatOutOfCheats;
}
new_entry->enabled = enabled;
new_entry->definition = *def;
return 0;
}
Result DmntCheatManager::RemoveCheat(u32 cheat_id) {
std::scoped_lock<HosMutex> lk(g_cheat_lock);
if (!HasActiveCheatProcess()) {
return ResultDmntCheatNotAttached;
}
if (cheat_id >= DmntCheatManager::MaxCheatCount) {
return ResultDmntCheatUnknownChtId;
}
ResetCheatEntry(cheat_id);
return 0;
}
Handle DmntCheatManager::PrepareDebugNextApplication() {
Result rc;
Handle event_h;

View file

@ -36,6 +36,7 @@ class DmntCheatManager {
static void ResetCheatEntry(size_t i);
static void ResetAllCheatEntries();
static CheatEntry *GetFreeCheatEntry();
static CheatEntry *GetCheatEntryById(size_t i);
static bool ParseCheats(const char *cht_txt, size_t len);
static bool LoadCheats(u64 title_id, const u8 *build_id);
public:
@ -53,5 +54,12 @@ class DmntCheatManager {
static Result WriteCheatProcessMemory(u64 proc_addr, const void *data, size_t size);
static Result QueryCheatProcessMemory(MemoryInfo *mapping, u64 address);
static Result GetCheatCount(u64 *out_count);
static Result GetCheats(CheatEntry *cheats, size_t max_count, u64 *out_count, u64 offset);
static Result GetCheatById(CheatEntry *out_cheat, u32 cheat_id);
static Result ToggleCheat(u32 cheat_id);
static Result AddCheat(u32 *out_id, CheatDefinition *def, bool enabled);
static Result RemoveCheat(u32 cheat_id);
static void InitializeCheatManager();
};

View file

@ -18,6 +18,10 @@
#include "dmnt_cheat_service.hpp"
#include "dmnt_cheat_manager.hpp"
/* ========================================================================================= */
/* ==================================== Meta Commands ==================================== */
/* ========================================================================================= */
void DmntCheatService::HasCheatProcess(Out<bool> out) {
out.SetValue(DmntCheatManager::GetHasActiveCheatProcess());
}
@ -40,6 +44,9 @@ Result DmntCheatService::ForceOpenCheatProcess() {
return rc;
}
/* ========================================================================================= */
/* =================================== Memory Commands =================================== */
/* ========================================================================================= */
Result DmntCheatService::GetCheatProcessMappingCount(Out<u64> out_count) {
return DmntCheatManager::GetCheatProcessMappingCount(out_count.GetPointer());
@ -83,37 +90,57 @@ Result DmntCheatService::QueryCheatProcessMemory(Out<MemoryInfo> mapping, u64 ad
return DmntCheatManager::QueryCheatProcessMemory(mapping.GetPointer(), address);
}
/* ========================================================================================= */
/* =================================== Cheat Commands ==================================== */
/* ========================================================================================= */
Result DmntCheatService::GetCheatCount(Out<u64> out_count) {
/* TODO */
return 0xF601;
return DmntCheatManager::GetCheatCount(out_count.GetPointer());
}
Result DmntCheatService::GetCheats(OutBuffer<CheatEntry> cheats, Out<u64> out_count, u64 offset) {
/* TODO */
return 0xF601;
if (cheats.buffer == nullptr) {
return ResultDmntCheatNullBuffer;
}
return DmntCheatManager::GetCheats(cheats.buffer, cheats.num_elements, out_count.GetPointer(), offset);
}
Result DmntCheatService::GetCheatById(OutBuffer<CheatEntry> cheat, u32 cheat_id) {
/* TODO */
return 0xF601;
if (cheat.buffer == nullptr) {
return ResultDmntCheatNullBuffer;
}
if (cheat.num_elements < 1) {
return ResultDmntCheatInvalidBuffer;
}
return DmntCheatManager::GetCheatById(cheat.buffer, cheat_id);
}
Result DmntCheatService::ToggleCheat(u32 cheat_id) {
/* TODO */
return 0xF601;
return DmntCheatManager::ToggleCheat(cheat_id);
}
Result DmntCheatService::AddCheat(InBuffer<CheatDefinition> cheat, Out<u32> out_cheat_id, bool enabled) {
/* TODO */
return 0xF601;
if (cheat.buffer == nullptr) {
return ResultDmntCheatNullBuffer;
}
if (cheat.num_elements < 1) {
return ResultDmntCheatInvalidBuffer;
}
return DmntCheatManager::AddCheat(out_cheat_id.GetPointer(), cheat.buffer, enabled);
}
Result DmntCheatService::RemoveCheat(u32 cheat_id) {
/* TODO */
return 0xF601;
return DmntCheatManager::RemoveCheat(cheat_id);
}
/* ========================================================================================= */
/* =================================== Address Commands ================================== */
/* ========================================================================================= */
Result DmntCheatService::GetFrozenAddressCount(Out<u64> out_count) {
/* TODO */

View file

@ -23,5 +23,9 @@ static constexpr u32 Module_Dmnt = 13;
static constexpr Result ResultDmntUnknown = MAKERESULT(Module_Dmnt, 1);
static constexpr Result ResultDmntDebuggingDisabled = MAKERESULT(Module_Dmnt, 2);
static constexpr Result ResultDmntCheatNotAttached = MAKERESULT(Module_Dmnt, 6500);
static constexpr Result ResultDmntCheatNullBuffer = MAKERESULT(Module_Dmnt, 6501);
static constexpr Result ResultDmntCheatNotAttached = MAKERESULT(Module_Dmnt, 6500);
static constexpr Result ResultDmntCheatNullBuffer = MAKERESULT(Module_Dmnt, 6501);
static constexpr Result ResultDmntCheatInvalidBuffer = MAKERESULT(Module_Dmnt, 6502);
static constexpr Result ResultDmntCheatUnknownChtId = MAKERESULT(Module_Dmnt, 6503);
static constexpr Result ResultDmntCheatOutOfCheats = MAKERESULT(Module_Dmnt, 6504);
static constexpr Result ResultDmntCheatInvalidCheat = MAKERESULT(Module_Dmnt, 6505);