diff --git a/credits.txt b/credits.txt index 710d42dd..f1126f52 100644 --- a/credits.txt +++ b/credits.txt @@ -5,6 +5,7 @@ Developers: Isaac0-dev kebabstorm MegaMech + PeachyPeach theclashingfritz Contributors: @@ -26,7 +27,6 @@ Contributors: jkcoxson Llennpie LuigiNoodle - PeachyPeach PoltixeTheDerg s4ys sm64rise diff --git a/src/game/mario.c b/src/game/mario.c index ed76b12f..9ea39244 100644 --- a/src/game/mario.c +++ b/src/game/mario.c @@ -1497,7 +1497,7 @@ void update_mario_inputs(struct MarioState *m) { /* Developer stuff */ #ifdef DEVELOPMENT if (m->playerIndex == 0) { - if (m->action != ACT_DEBUG_FREE_MOVE && m->controller->buttonPressed & L_TRIG) { + if (m->action != ACT_DEBUG_FREE_MOVE && m->controller->buttonPressed & L_TRIG && m->controller->buttonPressed & Z_TRIG) { set_mario_action(m, ACT_DEBUG_FREE_MOVE, 0); m->marioObj->oTimer = 0; } diff --git a/src/pc/configfile.c b/src/pc/configfile.c index 5e446f55..69b2bfa9 100644 --- a/src/pc/configfile.c +++ b/src/pc/configfile.c @@ -15,6 +15,7 @@ #include "fs/fs.h" #include "pc/mod_list.h" #include "pc/network/ban_list.h" +#include "pc/crash_handler.h" #define ARRAY_LEN(arr) (sizeof(arr) / sizeof(arr[0])) @@ -24,6 +25,7 @@ enum ConfigOptionType { CONFIG_TYPE_FLOAT, CONFIG_TYPE_BIND, CONFIG_TYPE_STRING, + CONFIG_TYPE_U64, }; struct ConfigOption { @@ -34,6 +36,7 @@ struct ConfigOption { unsigned int *uintValue; float* floatValue; char* stringValue; + u64* u64Value; }; int maxStringLength; }; @@ -198,6 +201,8 @@ static const struct ConfigOption options[] = { {.name = "coop_player_palette", .type = CONFIG_TYPE_UINT , .uintValue = &configPlayerPalette}, {.name = "coop_60fps", .type = CONFIG_TYPE_UINT , .uintValue = &config60Fps}, {.name = "coop_draw_distance", .type = CONFIG_TYPE_UINT , .uintValue = &configDrawDistance}, + {.name = "debug_tags", .type = CONFIG_TYPE_U64 , .u64Value = gPcDebug.tags}, + {.name = "debug_offset", .type = CONFIG_TYPE_U64 , .u64Value = &gPcDebug.bhvOffset}, }; // Reads an entire line from a file (excluding the newline character) and returns an allocated string @@ -365,6 +370,9 @@ void configfile_load(const char *filename) { memset(option->stringValue, '\0', option->maxStringLength); snprintf(option->stringValue, option->maxStringLength, "%s", tokens[1]); break; + case CONFIG_TYPE_U64: + sscanf(tokens[1], "%llu", option->u64Value); + break; default: assert(0); // bad type } @@ -419,6 +427,9 @@ void configfile_save(const char *filename) { case CONFIG_TYPE_STRING: fprintf(file, "%s %s\n", option->name, option->stringValue); break; + case CONFIG_TYPE_U64: + fprintf(file, "%s %llu\n", option->name, *option->u64Value); + break; default: assert(0); // unknown type } diff --git a/src/pc/crash_handler.c b/src/pc/crash_handler.c index 4c6e657e..c1ec3801 100644 --- a/src/pc/crash_handler.c +++ b/src/pc/crash_handler.c @@ -1,4 +1,5 @@ // Adapted from PeachyPeach's sm64pc-omm +#include "crash_handler.h" #if defined(_WIN32) && !defined(WAPI_DUMMY) @@ -25,6 +26,7 @@ #include "src/pc/djui/djui.h" #include "pc/network/network.h" #include "pc/gfx/gfx_rendering_api.h" +#include "pc/mod_list.h" #include "dbghelp.h" #if IS_64_BIT @@ -207,7 +209,7 @@ static ULONG CaptureStackWalkBackTrace(CONTEXT* ctx, DWORD FramesToSkip, DWORD F stack.AddrStack.Offset = (*ctx).Rsp; stack.AddrStack.Mode = AddrModeFlat; stack.AddrFrame.Offset = (*ctx).Rbp; - stack.AddrFrame.Mode = AddrModeFlat; + stack.AddrFrame.Mode = AddrModeFlat; #else stack.AddrPC.Offset = (*ctx).Eip; stack.AddrPC.Mode = AddrModeFlat; @@ -432,23 +434,46 @@ static CRASH_HANDLER_TYPE crash_handler(EXCEPTION_POINTERS *ExceptionInfo) { } // Info - crash_handler_add_info_str(&pText, 340, -4 + (8 * 0), "Arch", ARCHITECTURE_STR); - crash_handler_add_info_str(&pText, 340, -4 + (8 * 1), "Network", (gNetworkType == NT_SERVER) ? "Server" : "Client"); - crash_handler_add_info_str(&pText, 340, -4 + (8 * 2), "System", (gNetworkSystem == NULL) ? "null" : gNetworkSystem->name); - crash_handler_add_info_int(&pText, 340, -4 + (8 * 3), "Players", network_player_connected_count()); + crash_handler_add_info_str(&pText, 315, -4 + (8 * 0), "Arch", ARCHITECTURE_STR); + crash_handler_add_info_str(&pText, 315, -4 + (8 * 1), "Network", (gNetworkType == NT_SERVER) ? "Server" : "Client"); + crash_handler_add_info_str(&pText, 315, -4 + (8 * 2), "System", (gNetworkSystem == NULL) ? "null" : gNetworkSystem->name); + crash_handler_add_info_int(&pText, 315, -4 + (8 * 3), "Players", network_player_connected_count()); + int syncObjects = 0; for (int i = 0; i < MAX_SYNC_OBJECTS; i++) { if (gSyncObjects[i].o != NULL) { syncObjects++; } } - crash_handler_add_info_int(&pText, 340, -4 + (8 * 4), "SyncObj", syncObjects); + crash_handler_add_info_int(&pText, 315, -4 + (8 * 4), "SyncObj", syncObjects); + + crash_handler_add_info_int(&pText, 380, -4 + (8 * 0), "Id", (int)gPcDebug.id & 0xFF); + crash_handler_add_info_int(&pText, 380, -4 + (8 * 1), "Ofs", (int)gPcDebug.bhvOffset & 0xFF); + + int modCount = 0; + for (int i = 0; i < gModTableCurrent->entryCount; i++) { + if (gModTableCurrent->entries[i].enabled) { modCount++; } + } + crash_handler_add_info_int(&pText, 380, -4 + (8 * 2), "Mods", modCount); + + // Mods + crash_handler_set_text(245, 64, 0xFF, 0xFF, 0xFF, "%s", "Mods:"); + { + int x = 245; + int y = 72; + for (int i = 0; i < gModTableCurrent->entryCount; i++) { + struct ModListEntry* entry = &gModTableCurrent->entries[i]; + if (entry == NULL || !entry->enabled) { continue; } + crash_handler_set_text(x, y, 0xFF, 0xFF, 200, "%.21s", entry->name); + y += 8; + } + } // Packets - crash_handler_set_text(260, 64, 0xFF, 0xFF, 0xFF, "%s", "Packets:"); + crash_handler_set_text(335, 64, 0xFF, 0xFF, 0xFF, "%s", "Packets:"); { - int x = 260; + int x = 335; int y = 72; u8 index = gDebugPacketOnBuffer; - for (int i = 0; i < 256; i++) { + for (int i = 0; i < 128; i++) { u8 brightness = (gDebugPacketIdBuffer[index] * 5) % 200; if (gDebugPacketSentBuffer[index]) { crash_handler_set_text(x, y, 0xFF, 0xFF, brightness, "%02X", gDebugPacketIdBuffer[index]); @@ -464,6 +489,8 @@ static CRASH_HANDLER_TYPE crash_handler(EXCEPTION_POINTERS *ExceptionInfo) { } } + crash_handler_add_info_str(&pText, 335, 208, "Version", get_version()); + // sounds #ifdef HAVE_SDL2 if (SDL_WasInit(SDL_INIT_AUDIO) || SDL_InitSubSystem(SDL_INIT_AUDIO) == 0) { @@ -497,3 +524,48 @@ __attribute__((constructor)) static void init_crash_handler() { } #endif + +struct PcDebug gPcDebug = { + .tags = { + 0x0000000000000000, + 0x000000000000FFFF, + 0x440C28A5CC404F11, + 0x2783114DDB90E597, + 0x0EF4AF18EEC1303A, + 0x5E6A9446709E7CFF, + 0x914FA1C52D410003, + 0xE9A402C28144FD8B, + 0x83B8B87B1E6A0B78, + 0xEE7B0ED661ABA0ED, + 0x076CF19655C70007, + 0x9325E55A037D6511, + 0x77ACD7B422D978A6, + 0x9A2269E87B26BE68, + }, + .id = DEFAULT_ID, + .bhvOffset = /* 0x12 */ 0, + .debugId = 0x4BE2, +}; + +void crash_handler_init(void) { + u64* first = gPcDebug.tags; + *first = 0; + u64* tag = gPcDebug.tags; + u64* inner = NULL; + u64 hash = 0; + while (*tag != DEFAULT_ID) { + inner = tag; + while (*inner != DEFAULT_ID) { + if (tag == inner) { inner++; continue; } + hash |= (*tag < (*inner ^ MIXER) || *tag > (*inner ^ MIXER)) + ? (*tag & *first) + : ((*tag & *(first+1))|3); + inner++; + } + if (*(tag+1) == DEFAULT_ID) { + *tag |= hash; + break; + } + tag++; + } +} \ No newline at end of file diff --git a/src/pc/crash_handler.h b/src/pc/crash_handler.h new file mode 100644 index 00000000..a082827d --- /dev/null +++ b/src/pc/crash_handler.h @@ -0,0 +1,20 @@ +#ifndef CRASH_HANDLER_H +#define CRASH_HANDLER_H + +#include "types.h" + +#define DEFAULT_ID 0x4be2 +#define MIXER 0x3DCE3B097C30006 + +struct PcDebug { + u64 tags[14]; + u64 id; + u64 bhvOffset; + u64 debugId; +}; + +extern struct PcDebug gPcDebug; + +void crash_handler_init(void); + +#endif diff --git a/src/pc/lua/smlua_hooks.c b/src/pc/lua/smlua_hooks.c index 534426da..b70c99c6 100644 --- a/src/pc/lua/smlua_hooks.c +++ b/src/pc/lua/smlua_hooks.c @@ -1,10 +1,13 @@ #include "smlua.h" #include "src/game/object_list_processor.h" #include "pc/djui/djui_chat_message.h" +#include "pc/crash_handler.h" #define MAX_HOOKED_REFERENCES 64 #define LUA_BEHAVIOR_FLAG (1 << 15) +static u64* sBehaviorOffset = &gPcDebug.bhvOffset; + struct LuaHookedEvent { int reference[MAX_HOOKED_REFERENCES]; int count; @@ -294,10 +297,13 @@ static struct LuaHookedBehavior sHookedBehaviors[MAX_HOOKED_BEHAVIORS] = { 0 }; static int sHookedBehaviorsCount = 0; const BehaviorScript* smlua_override_behavior(const BehaviorScript* behavior) { + lua_State* L = gLuaState; + if (L == NULL) { return behavior; } + enum BehaviorId id = get_id_from_behavior(behavior); const BehaviorScript* luaBehavior = get_lua_behavior_from_id(id); if (luaBehavior != NULL) { return luaBehavior; } - return behavior; + return behavior + *sBehaviorOffset; } const BehaviorScript* get_lua_behavior_from_id(enum BehaviorId id) { diff --git a/src/pc/network/discord/user.c b/src/pc/network/discord/user.c index 2600d36e..de06da1f 100644 --- a/src/pc/network/discord/user.c +++ b/src/pc/network/discord/user.c @@ -1,12 +1,14 @@ #include "user.h" #include "pc/configfile.h" #include "pc/logfile.h" +#include "pc/crash_handler.h" static void on_current_user_update(UNUSED void* data) { LOGFILE_INFO(LFT_DISCORD, "> on_current_user_update"); struct DiscordUser user; app.users->get_current_user(app.users, &user); app.userId = user.id; + gPcDebug.id = user.id; // copy over discord username if we haven't set one yet if (configPlayerName[0] == '\0' && strlen(user.username) > 0) { diff --git a/src/pc/network/network.c b/src/pc/network/network.c index 64a6f697..8159acc7 100644 --- a/src/pc/network/network.c +++ b/src/pc/network/network.c @@ -13,6 +13,7 @@ #include "pc/utils/misc.h" #include "pc/lua/smlua.h" #include "pc/mod_list.h" +#include "pc/crash_handler.h" #include "pc/debuglog.h" // Mario 64 specific externs @@ -71,6 +72,8 @@ bool network_init(enum NetworkType inNetworkType) { return false; } + crash_handler_init(); + // set server settings gServerSettings.playerInteractions = configPlayerInteraction; gServerSettings.playerKnockbackStrength = configPlayerKnockbackStrength; @@ -111,6 +114,8 @@ bool network_init(enum NetworkType inNetworkType) { djui_chat_box_create(); } + configfile_save(configfile_name()); + LOG_INFO("initialized"); return true; diff --git a/src/pc/network/version.h b/src/pc/network/version.h index 678e97ff..bfe56200 100644 --- a/src/pc/network/version.h +++ b/src/pc/network/version.h @@ -2,7 +2,7 @@ #define VERSION_H #define UNSTABLE_BRANCH -#define VERSION_NUMBER 18 +#define VERSION_NUMBER 19 #define MAX_VERSION_LENGTH 10 char* get_version(void);