From 0c56eb8b897d7c257e6de85801e40bf037608ff6 Mon Sep 17 00:00:00 2001 From: CrafterPika Date: Sat, 27 Jun 2026 08:36:30 +0200 Subject: [PATCH] fix wayland and allow save editing of equipped weapon --- Func.cs | 8 ++++ Program.cs | 6 +-- SaveEditor.cs | 5 +++ VERSION.txt | 2 +- assets/Info.plist | 2 +- httpMenu.cs | 12 +++++- modmenu/ids.json | 93 ++++++++++++++++++++++++++++++++++++++++++++++ modmenu/index.html | 12 +++++- modmenu/script.js | 14 +++++++ 9 files changed, 147 insertions(+), 7 deletions(-) diff --git a/Func.cs b/Func.cs index 539b1df..5f5660e 100644 --- a/Func.cs +++ b/Func.cs @@ -200,5 +200,13 @@ namespace Func { return "Game not fully loaded yet..."; } } + public static string EquippedWep() { + try { + var p_SaveDataMgr = Program.readUInt32((uint)(Program.readUInt32(SaveEditor.SAVEDATAMGR_ROOT_PTR) + 0xC)); + return $"{Program.readUInt32((uint)(p_SaveDataMgr + 0x18C))}"; + } catch { + return "Game not fully loaded yet..."; + } + } } } diff --git a/Program.cs b/Program.cs index 548af78..12e1fc7 100644 --- a/Program.cs +++ b/Program.cs @@ -72,9 +72,9 @@ namespace ModMenu { public static bool IsWayland() { string runtimeDir = Environment.GetEnvironmentVariable("XDG_RUNTIME_DIR"); - if (string.IsNullOrEmpty(runtimeDir)) return false; + if (string.IsNullOrEmpty(runtimeDir) || !Directory.Exists(runtimeDir)) return false; - return File.Exists(Path.Combine(runtimeDir, "wayland-0")); + return Directory.EnumerateFiles(runtimeDir, "wayland-*").Any(); } [STAThread] @@ -188,7 +188,7 @@ namespace ModMenu { Console.WriteLine($"Found target process: {targetProcess.ProcessName} (PID: {pid})"); if (cbase != 0) { - Console.WriteLine("SplatTool v3.2.0 by CrafterPika"); + Console.WriteLine("SplatTool v3.2.1 by CrafterPika"); Console.WriteLine("Special Thanks: Winterberry, Javi.ig and Tombuntu, KittenTM."); cbaseCorrected = (Program.cbase + 0xE000000) - 0x10000000; diff --git a/SaveEditor.cs b/SaveEditor.cs index d886d3e..2c58014 100644 --- a/SaveEditor.cs +++ b/SaveEditor.cs @@ -153,6 +153,11 @@ namespace ModMenu { Program.writeUInt32((uint)(p_save_start + 0xA5B4), amount); } + public static void ChangeEquippedWeapon(uint WeaponSetID) { + var p_save_start = Program.readUInt32((uint)(Program.readUInt32(SAVEDATAMGR_ROOT_PTR) + 0xC)); + Program.writeUInt32((uint)(p_save_start + 0x18C), WeaponSetID); + } + private static T ByteArrayToStructure(byte[] bytes) where T : struct { GCHandle handle = GCHandle.Alloc(bytes, GCHandleType.Pinned); try { diff --git a/VERSION.txt b/VERSION.txt index 944880f..e4604e3 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -3.2.0 +3.2.1 diff --git a/assets/Info.plist b/assets/Info.plist index a98b3de..c3cadeb 100644 --- a/assets/Info.plist +++ b/assets/Info.plist @@ -13,7 +13,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 3.2.0 + 3.2.1 CFBundleVersion 1 LSMinimumSystemVersion diff --git a/httpMenu.cs b/httpMenu.cs index 950beaf..e8f91c3 100644 --- a/httpMenu.cs +++ b/httpMenu.cs @@ -22,6 +22,7 @@ namespace ModMenu { public static uint Level; public static uint Cash; public static uint SeaSnails; + public static uint WeaponSetID; public static SessionData session = new SessionData(); static WorkThread sessiondIdThread = new WorkThread(() => { Codes.forceSessiondId(sessionId); @@ -45,12 +46,16 @@ namespace ModMenu { Thread.Sleep(5000); SplatTelemetry.SendTelemetry(); }); + static WorkThread WeaponChangeThread = new WorkThread(() => { + SaveEditor.ChangeEquippedWeapon(WeaponSetID); + }); + public static string RunCode(ModMenuRequest data) { if (data?.action == null) return "0"; switch (data.action) { case "cbase": - return $"Cemu Base: 0x{Program.cbase:X} (0x{Program.cbaseCorrected:X})

Total Wins: {Codes.TotalWins()}
Total Losses: {Codes.TotalLoss()}

Thread Status:
- Write Gear: {WriteGear.Status.ToString()}
- Telemetry: {TelemetryThread.Status.ToString()}
- Change Gender: {ChangeGender.Status.ToString()}
- Change Level: {ChangeLevel.Status.ToString()}
- Change Cash: {ChangeCash.Status.ToString()}
- Change Sea Snails: {ChangeSeaSnails.Status.ToString()}"; + return $"Cemu Base: 0x{Program.cbase:X} (0x{Program.cbaseCorrected:X})

Total Wins: {Codes.TotalWins()}
Total Losses: {Codes.TotalLoss()}
Equipped Weapon: {Codes.EquippedWep()}

Thread Status:
- Write Gear: {WriteGear.Status.ToString()}
- Telemetry: {TelemetryThread.Status.ToString()}
- Change Gender: {ChangeGender.Status.ToString()}
- Change Level: {ChangeLevel.Status.ToString()}
- Change Cash: {ChangeCash.Status.ToString()}
- Change Sea Snails: {ChangeSeaSnails.Status.ToString()}
- Change Weapon: {WeaponChangeThread.Status.ToString()}"; case "sessiondata": return Codes.GetSessionData(); @@ -130,6 +135,11 @@ namespace ModMenu { HandleThread(TelemetryThread); return "1"; + case "WepChange": + WeaponSetID = UInt32.Parse(data.settings[0]); + HandleThread(WeaponChangeThread); + return "1"; + default: return "Not Found"; } diff --git a/modmenu/ids.json b/modmenu/ids.json index 637cbe9..5f00414 100644 --- a/modmenu/ids.json +++ b/modmenu/ids.json @@ -355,5 +355,98 @@ "109": "Ink Resistance Up", "110": "Stealth Jump", "111": "S_Abillity_Locked" + }, + "WeaponSetIds": { + "1000": "Sploosh-o-matic", + "1001": "Neo Sploosh-o-matic", + "1002": "Sploosh-o-matic 7", + "1010": "Splattershot Jr.", + "1011": "Custom Splattershot Jr.", + "1020": "Splash-o-matic", + "1021": "Neo Splash-o-matic", + "1030": "Aerospray MG", + "1031": "Aerospray RG", + "1032": "Aerospray PG", + "1040": "Splattershot", + "1041": "Tentatek Splattershot", + "1042": "Wasabi Splattershot", + "1045": "Hero Shot Replica", + "1046": "Octoshot Replica", + "1050": ".52 Gal", + "1051": ".52 Gal Deco", + "1060": "N-ZAP '85", + "1061": "N-ZAP '89", + "1062": "N-ZAP '83", + "1070": "Splattershot Pro", + "1071": "Forge Splattershot Pro", + "1072": "Berry Splattershot Pro", + "1080": ".96 Gal", + "1081": ".96 Gal Deco", + "1090": "Dual Squelcher", + "1091": "Custom Dual Squelcher", + "1100": "Jet Squelcher", + "1101": "Custom Jet Squelcher", + "1110": "Luna Blaster", + "1111": "Luna Blaster Neo", + "1120": "Blaster", + "1121": "Custom Blaster", + "1130": "Range Blaster", + "1131": "Custom Range Blaster", + "1132": "Grim Range Blaster", + "1140": "Rapid Blaster", + "1141": "Rapid Blaster Deco", + "1150": "Rapid Blaster Pro", + "1151": "Rapid Blaster Pro Deco", + "1160": "L-3 Nozzlenose", + "1161": "L-3 Nozzlenose D", + "1170": "H-3 Nozzlenose", + "1171": "H-3 Nozzlenose D", + "1172": "Cherry H-3 Nozzlenose", + "2000": "Carbon Roller", + "2001": "Carbon Roller Deco", + "2010": "Splat Roller", + "2011": "Krak-On Splat Roller", + "2012": "CoroCoro Splat Roller", + "2015": "Hero Roller Replica", + "2020": "Dynamo Roller", + "2021": "Gold Dynamo Roller", + "2022": "Tempered Dynamo Roller", + "2030": "Inkbrush", + "2031": "Inkbrush Nouveau", + "2032": "Permanent Inkbrush", + "2040": "Octobrush", + "2041": "Octobrush Nouveau", + "3000": "Slosher", + "3001": "Slosher Deco", + "3002": "Soda Slosher", + "3010": "Tri-Slosher", + "3011": "Tri-Slosher Nouveau", + "3020": "Sloshing Machine", + "3021": "Sloshing Machine Neo", + "4000": "Classic Squiffer", + "4001": "New Squiffer", + "4002": "Fresh Squiffer", + "4010": "Splat Charger", + "4011": "Kelp Splat Charger", + "4012": "Bento Splat Charger", + "4015": "Hero Charger Replica", + "4020": "Splatterscope", + "4021": "Kelp Splatterscope", + "4022": "Bento Splatterscope", + "4030": "E-liter 3K", + "4031": "Custom E-liter 3K", + "4040": "E-liter 3K Scope", + "4041": "Custom E-liter 3K Scope", + "4050": "Bamboozler 14 Mk I", + "4051": "Bamboozler 14 Mk II", + "4052": "Bamboozler 14 Mk III", + "5000": "Mini Splatling", + "5001": "Zink Mini Splatling", + "5002": "Refurbished Mini Splatling", + "5010": "Heavy Splatling", + "5011": "Heavy Splatling Deco", + "5012": "Heavy Splatling Remix", + "5020": "Hydra Splatling", + "5021": "Custom Hydra Splatling" } } diff --git a/modmenu/index.html b/modmenu/index.html index 56a433a..72c703e 100644 --- a/modmenu/index.html +++ b/modmenu/index.html @@ -118,6 +118,16 @@ +
+
+ Change Weapon: + Changes Equipped Weapon. +
+
+ + +
+
@@ -177,7 +187,7 @@
-

SplatTool v3.2.0

+

SplatTool v3.2.1

Written by CrafterPika
Special Thanks: Winterberry, Javi.ig, Tombuntu, KittenTM, apoplexy
diff --git a/modmenu/script.js b/modmenu/script.js index f2da8bf..4eb6043 100644 --- a/modmenu/script.js +++ b/modmenu/script.js @@ -73,6 +73,17 @@ function populateAbilities() { }); } +function populateWeaponSets() { + const select = document.getElementById("weapon-sets"); + select.innerHTML = ''; + for (const [val, name] of Object.entries(gearData.WeaponSetIds)) { + const opt = document.createElement('option'); + opt.value = val; + opt.textContent = name; + select.appendChild(opt); + } +} + window.external.receiveMessage(message => { // console.log(message) if (message.startsWith("Cemu Base:")) { @@ -212,12 +223,15 @@ function openTab(evt, tabName) { if (tabName === 'Tab6') { keepStatsUpdated = true; updateStatsPage(); + } else if (tabName == 'Tab8') { + populateWeaponSets() } else { keepStatsUpdated = false; } } function namechange() { sendToCSharp("namechange", [document.getElementById("name-input").value]); } +function changeWeapon() { sendToCSharp("WepChange", [document.getElementById("weapon-sets").value]); } function sessionid() { sendToCSharp("sessionid", [document.getElementById("session-input").value]); } function faceimgtga() { sendToCSharp("faceimgtga", [document.getElementById("format-select").value]); } function GenderChange() { sendToCSharp("ChangeGender", [document.getElementById("gender-select").value]); }