public void Start() { KeychipId = Settings.System.KeychipId.Trim(); MainId = Settings.System.MainId.Trim(); // Additional patch for annoucement display, by rakisaionji Manipulator.WritePatchNop(0x000000014001F680, 4); // mov [rax+10h], rdi Manipulator.WritePatchNop(0x000000014001F68E, 3); // mov [rcx], dil new Thread(new ThreadStart(Announce)).Start(); if (thread != null) { return; } stopFlag = false; thread = new Thread(new ThreadStart(ThreadCallback)); thread.Start(); Console.WriteLine(" SYSTEM MANAGER : OK"); }
private void InjectPatches() { Manipulator.WritePatch(0x00000001404ACD24, new byte[] { 0x44, 0x8B, 0x0D, 0xD1, 0x08, 0xD0, 0x00 }); // mov r9d, [rbx+63Ch] --> mov r9d, cs:FB1_HEIGHT Manipulator.WritePatch(0x00000001404ACD2B, new byte[] { 0x44, 0x8B, 0x05, 0xC6, 0x08, 0xD0, 0x00 }); // mov r8d, [rbx+638h] --> mov r8d, cs:FB1_WIDTH Manipulator.WritePatchNop(0x00000001405030A0, 6); // Whatever shitty checking flag, only Froggy knows }
internal void ApplyPatches() { foreach (var patch in patches) { Manipulator.WritePatch(patch.Key, patch.Value); } if (Settings.DivaPatches.RamPathFix) { // Write ram files to the current directory instead of Y:/SBZV/ram Manipulator.WritePatch(0x000000014066CF09, new byte[] { 0xE9, 0xD8, 0x00 }); } if (Settings.DivaPatches.FreePlay) { // Always return true for the SelCredit enter SelPv check Manipulator.WritePatch(0x0000000140393610, new byte[] { 0xB0, 0x01, 0xC3, 0x90, 0x90, 0x90 }); Manipulator.WritePatch(0x000000014066E870, new byte[] { 0xEB, 0x0E }); // Thanks vladkorotnev } if (Settings.DivaPatches.GlutCursor != GlutCursor.NONE) { // Use GLUT_CURSOR_RIGHT_ARROW instead of GLUT_CURSOR_NONE Manipulator.WritePatch(0x000000014019341B, new byte[] { (byte)Settings.DivaPatches.GlutCursor }); } if (Settings.DivaPatches.HideCredits) { // Dirty hide of CREDIT(S) counter by rakisaionji Manipulator.WritePatch(0x00000001409F6200, new byte[] { 0x00 }); // CREDIT(S) Manipulator.WritePatch(0x00000001409F61F0, new byte[] { 0x00 }); // FREE PLAY } if (Settings.Components.PlayerDataManager) { // Shitty way to initialize Level Name by rakisaionji Manipulator.WritePatch(0x0000000140205143, new byte[] { 0xE8, 0xC8, 0x27, 0xE0, 0xFF, 0x48, 0x8D, 0x8F, 0x00, 0x01, 0x00, 0x00, 0x44, 0x8D, 0x45, 0x1E, 0x48, 0x8D, 0x15, 0x5E, 0x60, 0x7D, 0x00, 0xE8, 0xB1, 0x27, 0xE0, 0xFF }); Manipulator.WritePatchNop(0x000000014020515F, 20); } // Hide Data Loading text when use_card = 1 by rakisaionji Manipulator.WritePatch(0x0000000140A3E720, new byte[] { 0x00 }); Manipulator.WritePatch(0x0000000140A3E7C8, new byte[] { 0x00 }); if (Settings.DivaPatches.MdataPathFix) { // Change mdata path from "C:/Mount/Option" to "mdata", revised by rakisaionji Manipulator.WritePatch(0x000000014066CE9C, new byte[] { 0x05 }); // Size Manipulator.WritePatch(0x000000014066CEA3, new byte[] { 0xF1, 0x1D, 0x39 }); Manipulator.WritePatch(0x000000014066CEAE, new byte[] { 0x05 }); // Size } // Touch effect is annoying without Scale Component in other resolutions if (Settings.IsCustomRes() || Settings.Components.ScaleComponent) { Manipulator.WritePatch(0x00000001406A1FE2, new byte[] { 0x7E }); // MOVQ XMM0,qword ptr [0x168 + RSP] (change to MOVQ) Manipulator.WritePatch(0x00000001406A1FE9, new byte[] { 0x66, 0x0F, 0xD6, 0x44, 0x24, 0x6C }); // MOVQ qword ptr [RSP + 0x6c],XMM0 Manipulator.WritePatch(0x00000001406A1FEF, new byte[] { 0xC7, 0x44, 0x24, 0x74, 0x00, 0x00, 0x00, 0x00 }); // MOV dword ptr [RSP + 0x74],0x0 Manipulator.WritePatch(0x00000001406A1FF7, new byte[] { 0xEB, 0x0E }); // JMP 0x1406a2007 (to rest of function as usual) Manipulator.WritePatch(0x00000001406A1FF9, new byte[] { 0x66, 0x48, 0x0F, 0x6E, 0xC2 }); // MOVQ XMM0,RDX (load touch pos) Manipulator.WritePatch(0x00000001406A1FFE, new byte[] { 0xEB, 0x5D }); // JMP 0x1406a205d Manipulator.WritePatch(0x00000001406A205D, new byte[] { 0x0F, 0x2A, 0x0D, 0xB8, 0x6A, 0x31, 0x00 }); // CVTPI2PS XMM1,qword ptr [0x1409b8b1c] (load 1280x720) Manipulator.WritePatch(0x00000001406A2064, new byte[] { 0x0F, 0x12, 0x51, 0x1C }); // MOVLPS XMM2,qword ptr [RCX + 0x1c] (load actual res) Manipulator.WritePatch(0x00000001406A2068, new byte[] { 0xE9, 0x14, 0xFF, 0xFF, 0xFF }); // JMP 0x1406a1f81 Manipulator.WritePatch(0x00000001406A1F81, new byte[] { 0x0F, 0x59, 0xC1 }); // MULPS XMM0,XMM1 Manipulator.WritePatch(0x00000001406A1F84, new byte[] { 0x0F, 0x5E, 0xC2 }); // DIVPS XMM0,XMM2 Manipulator.WritePatch(0x00000001406A1F87, new byte[] { 0x66, 0x0F, 0xD6, 0x44, 0x24, 0x10 }); // MOVQ qword ptr [RSP+0x10],XMM0 Manipulator.WritePatch(0x00000001406A1F8D, new byte[] { 0xEB, 0x06 }); // JMP 0x1406a1f95 (back to original function) Manipulator.WritePatch(0x00000001406A1F90, new byte[] { 0xEB, 0x67 }); // JMP 0x1406a1ff9 } // Skip Error Display in ADVERTISE by rakisaionji switch (Settings.System.ErrorDisplay) { case ErrorDisplay.SKIP_CARD: Manipulator.WritePatch(0x00000001403BA7E7, new byte[] { 0xEB, 0x46 }); Manipulator.WritePatch(0x00000001403BA909, new byte[] { 0xEB, 0x1F }); break; case ErrorDisplay.HIDDEN: Manipulator.WritePatch(0x00000001403BA7E7, new byte[] { 0xE9, 0x3C, 0x03, 0x00, 0x00 }); break; case ErrorDisplay.DEFAULT: break; } // Force Hide Main ID and Keychip ID if (Settings.System.HideId) { Manipulator.WritePatch(0x00000001409A5918, new byte[] { 0x00 }); Manipulator.WritePatch(0x00000001409A5928, new byte[] { 0x00 }); } // Other Features by somewhatlurker, improved by rakisaionji var cardStatus = Settings.DivaPatches.CardIcon; if (cardStatus != StatusIcon.DEFAULT) { byte[] cardIcon; switch (cardStatus) { case StatusIcon.ERROR: cardIcon = new byte[] { 0xFA, 0x0A }; break; case StatusIcon.WARNING: cardIcon = new byte[] { 0xFB, 0x0A }; break; case StatusIcon.OK: cardIcon = new byte[] { 0xFC, 0x0A }; break; default: cardIcon = new byte[] { 0xFD, 0x0A }; break; } Manipulator.WritePatch(0x00000001403B9D6E, cardIcon); // error state Manipulator.WritePatch(0x00000001403B9D73, cardIcon); // ok state } var netStatus = Settings.DivaPatches.NetIcon; if (netStatus != StatusIcon.DEFAULT) { byte[] netIcon; switch (netStatus) { case StatusIcon.ERROR: netIcon = new byte[] { 0x9F, 0x1E }; break; case StatusIcon.WARNING: netIcon = new byte[] { 0xA1, 0x1E }; break; case StatusIcon.OK: netIcon = new byte[] { 0xA0, 0x1E }; break; default: netIcon = new byte[] { 0x9E, 0x1E }; break; } // network icon Manipulator.WritePatch(0x00000001403BA14B, netIcon); // error state Manipulator.WritePatch(0x00000001403BA155, netIcon); // ok state Manipulator.WritePatch(0x00000001403BA16B, netIcon); // partial state // never show the error code for partial connection Manipulator.WritePatch(0x00000001403BA1A5, new byte[] { 0x48, 0xE9 }); // jle --> jmp } if (Settings.DivaPatches.HidePvUi) { Manipulator.WritePatch(0x000000014048FA91, new byte[] { 0xEB, 0x6F }); // skip button panel image ( JMP 0x14048FB02 ) // patch minimum PV UI state to 1 instead of 0 // hook check for lyrics enabled (UI state < 2) to change UI state 0 into 1 // dump new code in the skipped button panel condition Manipulator.WritePatch(0x000000014048FA93, new byte[] { 0xC7, 0x83, 0x58, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 }); // MOV dword ptr [0x158 + RBX],0x1 Manipulator.WritePatch(0x000000014048FA9D, new byte[] { 0xC6, 0x80, 0x3A, 0xD1, 0x02, 0x00, 0x01 }); // MOV byte ptr [0x2d13a + RAX],0x1 Manipulator.WritePatch(0x000000014048FAA4, new byte[] { 0xE9, 0x8B, 0xFB, 0xFF, 0xFF }); // JMP 0x14048F634 Manipulator.WritePatch(0x000000014048F62D, new byte[] { 0xE9, 0x61, 0x04, 0x00, 0x00 }); // JMP 0x14048FA93 } if (Settings.DivaPatches.HideLyrics) { Manipulator.WritePatch(0x00000001404E7A25, new byte[] { 0x00, 0x00 }); Manipulator.WritePatch(0x00000001404E7950, new byte[] { 0x48, 0xE9 }); // ensure first iteration doesn't run } if (Settings.DivaPatches.HidePvMark) { Manipulator.WritePatch(0x0000000140A13A88, new byte[] { 0x00 }); } if (Settings.DivaPatches.HideSeBtn) { Manipulator.WritePatch(0x00000001409A4D60, new byte[] { 0xC0, 0xD3 }); } if (Settings.DivaPatches.HideVolume) { Manipulator.WritePatch(0x0000000140A85F10, new byte[] { 0xE0, 0x50 }); } // System Timer Patches, by samyuu and rakisaionji var sys_timer = (int)Settings.System.SysTimer; if (sys_timer > 1) // HIDDEN { Manipulator.WritePatch(0x00000001409C0758, new byte[] { 0x00 }); Manipulator.WritePatch(0x0000000140A3D3F0, new byte[] { 0x00 }); Manipulator.WritePatch(0x0000000140A3D3F8, new byte[] { 0x00 }); } if (sys_timer > 0) // FREEZE { // SEL_CARD_TIMER Manipulator.WriteInt32(0x0000000141802660, SYS_TIMER_TIME); Manipulator.WritePatchNop(0x0000000140566B9E, 3); Manipulator.WritePatchNop(0x0000000140566AEF, 3); // SEL_PV_TIMER Manipulator.WriteInt32(0x00000001405C514A, SYS_TIMER_TIME); Manipulator.WritePatchNop(0x00000001405BDFBF, 6); Manipulator.WritePatchNop(0x00000001405C517A, 6); } // Anti-alias Patches, by lybxlpsv and nastys if (!Settings.System.TemporalAA) // Disable Temporal AA { // Set TAA var (shouldn't be needed but whatever) Manipulator.WriteByte(0x00000001411AB67C, 0); // Make constructor/init not set TAA Manipulator.WritePatchNop(0x00000001404AB11D, 3); // Not sure, but it's somewhere in TaskPvGame init // Just make it set TAA to 0 instead of 1 to avoid possible issues Manipulator.WritePatch(0x00000001401063CE, new byte[] { 0x00 }); // Prevent re-enabling after taking photos Manipulator.WritePatch(0x000000014048FBA9, new byte[] { 0x00 }); } if (!Settings.System.MorphologicalAA) { // Set MLAA var (shouldn't be needed but whatever) Manipulator.WriteByte(0x00000001411AB680, 0); // Make constructor/init not set MLAA Manipulator.WritePatchNop(0x00000001404AB11A, 3); } // Force wqhd for custom internal resolution, by rakisaionji if (Settings.System.CustomRes) { Manipulator.WritePatch(0x00000001401945E4, new byte[] { 0xC7, 0x05, 0xE6, 0x5F, 0xD4, 0x00, 0x0F, 0x00, 0x00, 0x00, 0xE9, 0xD3, 0x01, 0x00, 0x00 }); Manipulator.WritePatch(0x00000001409B8B68, BitConverter.GetBytes(Settings.System.RenderWidth)); Manipulator.WritePatch(0x00000001409B8B6C, BitConverter.GetBytes(Settings.System.RenderHeight)); } }
internal void Initialize() { InjectPatches(); ReadPlayerData(); PlayerNameValue = new byte[21]; var b_name = Encoding.UTF8.GetBytes(playerData.PlayerName); Buffer.BlockCopy(b_name, 0, PlayerNameValue, 0, b_name.Length); PlayerNameAddress = Manipulator.ReadInt64(PLAYER_NAME_ADDRESS); LevelNameValue = new byte[29]; var c_name = Encoding.UTF8.GetBytes(playerData.LevelName); Buffer.BlockCopy(c_name, 0, LevelNameValue, 0, c_name.Length); LevelNameAddress = Manipulator.ReadInt64(PLAYER_LEVEL_NAME_ADDRESS); Manipulator.WriteByte(PLAYER_LEVEL_NAME_ADDRESS + 0x10L, 0xFF); // thanks @vladkorotnev Manipulator.WriteByte(PLAYER_LEVEL_NAME_ADDRESS + 0x18L, 0x1F); // thanks @vladkorotnev if (playerData.Level < 1) { playerData.Level = 1; } if (playerData.ActVol < 0 || playerData.ActVol > 100) { playerData.ActVol = 100; } if (playerData.HpVol < 0 || playerData.HpVol > 100) { playerData.HpVol = 100; } // use_card = 1 // Required to allow for module selection if (playerData.UseCard) { Manipulator.WriteInt32(PLAYER_DATA_ADDRESS, 1); } // Allow player to select the module and extra items (by vladkorotnev) for (long i = 0; i < 128; i++) { Manipulator.WriteByte(MODULE_TABLE_START + i, 0xFF); } for (long i = 0; i < 128; i++) { Manipulator.WriteByte(ITEM_TABLE_START + i, 0xFF); } // Display interim rank and rhythm options Manipulator.WriteByte(PLAYER_RANK_DISP_ADDRESS, 1); // Display custom pv module options Manipulator.WriteByte(PLAYER_USE_PV_MODULE_ADDRESS, 1); // Discovered by vladkorotnev, improved by rakisaionji if (playerData.OptionDisp) { // Allow to use without use_card (by somewhatlurker) if (!playerData.UseCard) { Manipulator.WritePatchNop(0x00000001405CB14A, 6); Manipulator.WritePatchNop(0x0000000140136CFA, 6); } Manipulator.WriteByte(PLAYER_OPTION_DISP_ADDRESS, 1); Manipulator.WritePatchNop(0x00000001405CA0F5, 2); // Allow it to be displayed Manipulator.WritePatchNop(0x00000001405CB1B3, 13); // Allow it to be set and used if (playerData.KeepOption) { // It was reset when changing level or song, annoying so prevent it Manipulator.WritePatchNop(0x00000001405C84EE, 6); // Prevent it to be reset Manipulator.WritePatchNop(0x00000001405C84F9, 3); // Prevent it to be reset } } // Enable module selection without card (by lybxlpsv and crash5band) [WIP / NG] // if (!playerData.UseCard) // { // Manipulator.WritePatch(0x00000001405C513B, new byte[] { 0x01 }); // Manipulator.WritePatch(0x000000014010523F, new byte[] { 0x30, 0xC0, 0x90 }); // } // Display clear borders on the progress bar (by vladkorotnev) Manipulator.WriteByte(PLAYER_CLEAR_BORDER_ADDRESS, playerData.ClearBorder.ToByte()); // First write of play start id, only once per starup // if (playerData.SetPlayData) // { // playIdx = playerData.PlayDataId; // if (playIdx < 10001 || playIdx == uint.MaxValue) playIdx = 10001; // Manipulator.WriteUInt32(PLAYER_PLAY_ID_ADDRESS, playIdx); // } WritePlayerData(); }