mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2024-11-15 03:27:49 +01:00
dmnt-cheat: Implement cheat management service commands
This commit is contained in:
parent
862aa73783
commit
7ddb0da5f6
@ -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;
|
||||
|
@ -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();
|
||||
};
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
Loading…
Reference in New Issue
Block a user