PlayerDataManager.cpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512
  1. #include "PlayerDataManager.h"
  2. #include <string>
  3. #include "../framework.h"
  4. #include "../Constants.h"
  5. #include "../Input/Keyboard/Keyboard.h"
  6. #include "../FileSystem/ConfigFile.h"
  7. #include "../Utilities/Operations.h"
  8. #include <windows.h>
  9. #include "GameState.h"
  10. const std::string PLAYER_DATA_FILE_NAME = "playerdata.ini";
  11. static WCHAR configPath[256];
  12. int* headitemequip = (int*)0x0000000141804CDC;
  13. int customheaditemequip;
  14. namespace TLAC::Components
  15. {
  16. PlayerDataManager::PlayerDataManager()
  17. {
  18. }
  19. PlayerDataManager::~PlayerDataManager()
  20. {
  21. if (customPlayerData != nullptr)
  22. delete customPlayerData;
  23. }
  24. const char* PlayerDataManager::GetDisplayName()
  25. {
  26. return "player_data_manager";
  27. }
  28. void PlayerDataManager::Initialize(ComponentsManager*)
  29. {
  30. playerData = (PlayerData*)PLAYER_DATA_ADDRESS;
  31. ApplyPatch();
  32. LoadConfig();
  33. ApplyCustomData();
  34. }
  35. void PlayerDataManager::Update()
  36. {
  37. ApplyCustomData();
  38. /*if (false && Input::Keyboard::GetInstance()->IsTapped(VK_F12))
  39. {
  40. printf("[TLAC] PlayerDataManager::Update(): Loading config...\n");
  41. LoadConfig();
  42. }*/
  43. // nas, I moved the patches back to patches because please.. at least don't apply it every frame when it's not necessary lol
  44. // and reverting was the easiest way to undo that
  45. if (moduleCardWorkaround) {
  46. int* pvId = (int*)0x00000001418054C4;
  47. int* modState = (int*)0x00000001411A9790;
  48. int* loadState = (int*)0x0000000141197E58;
  49. if (!customPlayerData->UseCard)
  50. {
  51. if (*(char*)0x000000014CC5E270 == 32)
  52. {
  53. DWORD oldProtect, bck;
  54. VirtualProtect((BYTE*)0x00000001405BC8E6, 3, PAGE_EXECUTE_READWRITE, &oldProtect);
  55. *((BYTE*)0x00000001405BC8E6 + 0) = 0x00;
  56. VirtualProtect((BYTE*)0x00000001405BC8E6, 3, oldProtect, &bck);
  57. pvModuleLoaded = false;
  58. }
  59. else {
  60. if (!pvModuleLoaded)
  61. {
  62. pvModuleLoaded = true;
  63. DWORD oldProtect, bck;
  64. VirtualProtect((BYTE*)0x00000001405BC8E6, 3, PAGE_EXECUTE_READWRITE, &oldProtect);
  65. *((BYTE*)0x00000001405BC8E6 + 0) = 0x01;
  66. VirtualProtect((BYTE*)0x00000001405BC8E6, 3, oldProtect, &bck);
  67. }
  68. }
  69. if ((initPvId == false) || ((lastModState == 0) && (*modState == 1)))
  70. {
  71. if ((lastModState == 0) && (*modState == 1))
  72. {
  73. *(int*)0x00000001411A8A10 = *(int*)0x00000001411A8A28;
  74. *(int*)(0x00000001411A8A10 + 4) = *(int*)(0x00000001411A8A28 + 4);
  75. *(int*)(0x00000001411A8A10 + 8) = *(int*)(0x00000001411A8A28 + 8);
  76. *(int*)(0x00000001411A8A10 + 12) = *(int*)(0x00000001411A8A28 + 12);
  77. *(int*)(0x00000001411A8A10 + 16) = *(int*)(0x00000001411A8A28 + 16);
  78. *(int*)(0x00000001411A8A10 + 18) = *(int*)(0x00000001411A8A28 + 18);
  79. }
  80. initPvId = true;
  81. lastModState = *modState;
  82. DWORD oldProtect, bck;
  83. VirtualProtect((BYTE*)0x00000001405CBBA3, 8, PAGE_EXECUTE_READWRITE, &oldProtect);
  84. *((BYTE*)0x00000001405CBBA3 + 0) = 0x90;
  85. *((BYTE*)0x00000001405CBBA3 + 1) = 0x90;
  86. *((BYTE*)0x00000001405CBBA3 + 2) = 0x90;
  87. *((BYTE*)0x00000001405CBBA3 + 3) = 0x90;
  88. *((BYTE*)0x00000001405CBBA3 + 4) = 0x90;
  89. *((BYTE*)0x00000001405CBBA3 + 5) = 0x90;
  90. *((BYTE*)0x00000001405CBBA3 + 6) = 0x90;
  91. *((BYTE*)0x00000001405CBBA3 + 7) = 0x90;
  92. VirtualProtect((BYTE*)0x00000001405CBBA3, 8, oldProtect, &bck);
  93. }
  94. if (((*modState == 0) && (*pvId != lastPvId)) || ((lastModState == 1) && (*modState == 0)))
  95. {
  96. if ((lastModState == 1) && (*modState == 0))
  97. {
  98. *(int*)0x00000001411A8A28 = *(int*)0x00000001411A8A10;
  99. *(int*)(0x00000001411A8A28 + 4) = *(int*)(0x00000001411A8A10 + 4);
  100. *(int*)(0x00000001411A8A28 + 8) = *(int*)(0x00000001411A8A10 + 8);
  101. *(int*)(0x00000001411A8A28 + 12) = *(int*)(0x00000001411A8A10 + 12);
  102. *(int*)(0x00000001411A8A28 + 16) = *(int*)(0x00000001411A8A10 + 16);
  103. *(int*)(0x00000001411A8A28 + 18) = *(int*)(0x00000001411A8A10 + 18);
  104. }
  105. initPvId = false;
  106. lastPvId = *pvId;
  107. lastModState = *modState;
  108. DWORD oldProtect, bck;
  109. VirtualProtect((BYTE*)0x00000001405CBBA3, 8, PAGE_EXECUTE_READWRITE, &oldProtect);
  110. *((BYTE*)0x00000001405CBBA3 + 0) = 0x42;
  111. *((BYTE*)0x00000001405CBBA3 + 1) = 0x89;
  112. *((BYTE*)0x00000001405CBBA3 + 2) = 0x84;
  113. *((BYTE*)0x00000001405CBBA3 + 3) = 0xb6;
  114. *((BYTE*)0x00000001405CBBA3 + 4) = 0xc0;
  115. *((BYTE*)0x00000001405CBBA3 + 5) = 0x01;
  116. *((BYTE*)0x00000001405CBBA3 + 6) = 0x00;
  117. *((BYTE*)0x00000001405CBBA3 + 7) = 0x00;
  118. VirtualProtect((BYTE*)0x00000001405CBBA3, 8, oldProtect, &bck);
  119. }
  120. }
  121. else {
  122. if (*(char*)0x000000014CC5E270 == 32)
  123. {
  124. DWORD oldProtect, bck;
  125. VirtualProtect((BYTE*)0x00000001405BC8E6, 3, PAGE_EXECUTE_READWRITE, &oldProtect);
  126. *((BYTE*)0x00000001405BC8E6 + 0) = 0x00;
  127. VirtualProtect((BYTE*)0x00000001405BC8E6, 3, oldProtect, &bck);
  128. VirtualProtect((BYTE*)0x00000001405CBBA3, 8, PAGE_EXECUTE_READWRITE, &oldProtect);
  129. *((BYTE*)0x00000001405CBBA3 + 0) = 0x42;
  130. *((BYTE*)0x00000001405CBBA3 + 1) = 0x89;
  131. *((BYTE*)0x00000001405CBBA3 + 2) = 0x84;
  132. *((BYTE*)0x00000001405CBBA3 + 3) = 0xb6;
  133. *((BYTE*)0x00000001405CBBA3 + 4) = 0xc0;
  134. *((BYTE*)0x00000001405CBBA3 + 5) = 0x01;
  135. *((BYTE*)0x00000001405CBBA3 + 6) = 0x00;
  136. *((BYTE*)0x00000001405CBBA3 + 7) = 0x00;
  137. VirtualProtect((BYTE*)0x00000001405CBBA3, 8, oldProtect, &bck);
  138. VirtualProtect((BYTE*)0x00000001405BCBE3, 2, PAGE_EXECUTE_READWRITE, &oldProtect);
  139. *((BYTE*)0x00000001405BCBE3 + 0) = 0x00;
  140. VirtualProtect((BYTE*)0x00000001405BCBE3, 2, oldProtect, &bck);
  141. pvModuleLoaded = false;
  142. }
  143. else {
  144. if (!pvModuleLoaded)
  145. {
  146. pvModuleLoaded = true;
  147. DWORD oldProtect, bck;
  148. VirtualProtect((BYTE*)0x00000001405BC8E6, 3, PAGE_EXECUTE_READWRITE, &oldProtect);
  149. *((BYTE*)0x00000001405BC8E6 + 0) = 0x00;
  150. VirtualProtect((BYTE*)0x00000001405BC8E6, 3, oldProtect, &bck);
  151. VirtualProtect((BYTE*)0x00000001405CBBA3, 8, PAGE_EXECUTE_READWRITE, &oldProtect);
  152. *((BYTE*)0x00000001405CBBA3 + 0) = 0x90;
  153. *((BYTE*)0x00000001405CBBA3 + 1) = 0x90;
  154. *((BYTE*)0x00000001405CBBA3 + 2) = 0x90;
  155. *((BYTE*)0x00000001405CBBA3 + 3) = 0x90;
  156. *((BYTE*)0x00000001405CBBA3 + 4) = 0x90;
  157. *((BYTE*)0x00000001405CBBA3 + 5) = 0x90;
  158. *((BYTE*)0x00000001405CBBA3 + 6) = 0x90;
  159. *((BYTE*)0x00000001405CBBA3 + 7) = 0x90;
  160. VirtualProtect((BYTE*)0x00000001405CBBA3, 8, oldProtect, &bck);
  161. VirtualProtect((BYTE*)0x00000001405BCBE3, 2, PAGE_EXECUTE_READWRITE, &oldProtect);
  162. *((BYTE*)0x00000001405BCBE3 + 0) = 0x01;
  163. VirtualProtect((BYTE*)0x00000001405BCBE3, 2, oldProtect, &bck);
  164. }
  165. }
  166. }
  167. }
  168. }
  169. void PlayerDataManager::ApplyPatch()
  170. {
  171. DWORD oldProtect;
  172. VirtualProtect((void*)SET_DEFAULT_PLAYER_DATA_ADDRESS, sizeof(uint8_t), PAGE_EXECUTE_READWRITE, &oldProtect);
  173. {
  174. // prevent the PlayerData from being reset
  175. *(uint8_t*)(SET_DEFAULT_PLAYER_DATA_ADDRESS) = RET_OPCODE;
  176. }
  177. VirtualProtect((void*)SET_DEFAULT_PLAYER_DATA_ADDRESS, sizeof(uint8_t), oldProtect, &oldProtect);
  178. // allow player to select the module and extra item
  179. VirtualProtect((void*)MODSELECTOR_CHECK_FUNCTION_ERRRET_ADDRESS, sizeof(byte) * 2, PAGE_EXECUTE_READWRITE, &oldProtect);
  180. {
  181. *(byte*)(MODSELECTOR_CHECK_FUNCTION_ERRRET_ADDRESS) = 0xB0; // xor al,al -> ld al,1
  182. *(byte*)(MODSELECTOR_CHECK_FUNCTION_ERRRET_ADDRESS + 0x1) = 0x01;
  183. }
  184. VirtualProtect((void*)MODSELECTOR_CHECK_FUNCTION_ERRRET_ADDRESS, sizeof(byte) * 2, oldProtect, &oldProtect);
  185. // fix annoying behavior of closing after changing module or item (don't yet know the reason, maybe NW/Card checks)
  186. {
  187. VirtualProtect((void*)MODSELECTOR_CLOSE_AFTER_MODULE, sizeof(uint8_t), PAGE_EXECUTE_READWRITE, &oldProtect);
  188. {
  189. *(uint8_t*)(MODSELECTOR_CLOSE_AFTER_MODULE) = JNE_OPCODE;
  190. }
  191. VirtualProtect((void*)MODSELECTOR_CLOSE_AFTER_MODULE, sizeof(uint8_t), oldProtect, &oldProtect);
  192. VirtualProtect((void*)MODSELECTOR_CLOSE_AFTER_CUSTOMIZE, sizeof(uint8_t), PAGE_EXECUTE_READWRITE, &oldProtect);
  193. {
  194. *(uint8_t*)(MODSELECTOR_CLOSE_AFTER_CUSTOMIZE) = JNE_OPCODE;
  195. }
  196. VirtualProtect((void*)MODSELECTOR_CLOSE_AFTER_CUSTOMIZE, sizeof(uint8_t), oldProtect, &oldProtect);
  197. }
  198. }
  199. void PlayerDataManager::LoadConfig()
  200. {
  201. if (playerData == nullptr)
  202. return;
  203. FileSystem::ConfigFile config(framework::GetModuleDirectory(), PLAYER_DATA_FILE_NAME);
  204. if (!config.OpenRead())
  205. return;
  206. if (customPlayerData != nullptr)
  207. delete customPlayerData;
  208. customPlayerData = new CustomPlayerData();
  209. config.TryGetValue("player_name", &customPlayerData->PlayerName);
  210. config.TryGetValue("level_name", &customPlayerData->LevelName);
  211. // ScoreSaver copies & declaring non-playerdata values
  212. std::string utf8path = TLAC::framework::GetModuleDirectory() + "/playerdata.ini";
  213. MultiByteToWideChar(CP_UTF8, 0, utf8path.c_str(), -1, configPath, 256);
  214. customPlayerData->LevelNum = config.GetIntegerValue("level");
  215. customPlayerData->VocaloidPoints = config.GetIntegerValue("vocaloid_point");
  216. customPlayerData->LevelPlateId = config.GetIntegerValue("level_plate_id");
  217. customPlayerData->LevelPlateEffect = config.GetIntegerValue("level_plate_effect");
  218. customPlayerData->SkinEquip = config.GetIntegerValue("skin_equip");
  219. customPlayerData->BtnSeEquip = config.GetIntegerValue("btn_se_equip");
  220. customPlayerData->SlideSeEquip = config.GetIntegerValue("slide_se_equip");
  221. customPlayerData->ChainslideSeEquip = config.GetIntegerValue("chainslide_se_equip");
  222. customPlayerData->SlidertouchSeEquip = config.GetIntegerValue("slidertouch_se_equip");
  223. customPlayerData->ModuleEquipCmn0 = config.GetIntegerValue("module_equip_cmn0");
  224. customPlayerData->ModuleEquipCmn1 = config.GetIntegerValue("module_equip_cmn1");
  225. customPlayerData->ModuleEquipCmn2 = config.GetIntegerValue("module_equip_cmn2");
  226. customPlayerData->ModuleEquipCmn3 = config.GetIntegerValue("module_equip_cmn3");
  227. customPlayerData->ModuleEquipCmn4 = config.GetIntegerValue("module_equip_cmn4");
  228. customPlayerData->ModuleEquipCmn5 = config.GetIntegerValue("module_equip_cmn5");
  229. customPlayerData->ActionVol = config.GetIntegerValue("act_vol");
  230. customPlayerData->ActionSlideVol = config.GetIntegerValue("act_slide_vol");
  231. customPlayerData->UsePVSFXEquip = config.GetBooleanValue("use_pv_sfx_equip");
  232. customPlayerData->UsePVSkinEquip = config.GetBooleanValue("use_pv_skin_equip");
  233. customPlayerData->UsePVEquip = config.GetBooleanValue("use_pv_module_equip");
  234. customPlayerData->ShowExcellentClearBorder = config.GetBooleanValue("border_excellent");
  235. customPlayerData->ShowGreatClearBorder = config.GetBooleanValue("border_great");
  236. customPlayerData->ShowRivalClearBorder = config.GetBooleanValue("border_rival");
  237. customPlayerData->UseCard = config.GetBooleanValue("use_card");
  238. customPlayerData->GameModifierOptions = config.GetBooleanValue("gamemode_options");
  239. customPlayerData->ActionSE = config.GetBooleanValue("act_toggle");
  240. moduleCardWorkaround = config.GetBooleanValue("module_card_workaround");
  241. // don't want to overwrite the default values
  242. auto setIfNotEqual = [](int* target, int value, int comparison)
  243. {
  244. if (value != comparison)
  245. * target = value;
  246. };
  247. // only need to run this line once on startup, otherwise cannot increase/decrease in-game (or use per-song settings!)
  248. setIfNotEqual(&playerData->vocaloid_point, customPlayerData->VocaloidPoints, 0);
  249. setIfNotEqual(&playerData->skin_equip_cmn, customPlayerData->SkinEquip, 0);
  250. setIfNotEqual(&playerData->module_equip_cmn0, customPlayerData->ModuleEquipCmn0, 0);
  251. setIfNotEqual(&playerData->module_equip_cmn1, customPlayerData->ModuleEquipCmn1, 0);
  252. setIfNotEqual(&playerData->module_equip_cmn2, customPlayerData->ModuleEquipCmn2, 0);
  253. setIfNotEqual(&playerData->module_equip_cmn3, customPlayerData->ModuleEquipCmn3, 0);
  254. setIfNotEqual(&playerData->module_equip_cmn4, customPlayerData->ModuleEquipCmn4, 0);
  255. setIfNotEqual(&playerData->module_equip_cmn5, customPlayerData->ModuleEquipCmn5, 0);
  256. setIfNotEqual(&playerData->act_vol, customPlayerData->ActionVol, 100);
  257. setIfNotEqual(&playerData->act_slide_vol, customPlayerData->ActionSlideVol, 100);
  258. setIfNotEqual(&playerData->btn_se_equip_cmn, customPlayerData->BtnSeEquip, -1);
  259. setIfNotEqual(&playerData->slide_se_equip_cmn, customPlayerData->SlideSeEquip, -1);
  260. setIfNotEqual(&playerData->chainslide_se_equip_cmn, customPlayerData->ChainslideSeEquip, -1);
  261. setIfNotEqual(&playerData->slidertouch_se_equip_cmn, customPlayerData->SlidertouchSeEquip, -1);
  262. setIfNotEqual(&playerData->act_toggle, customPlayerData->ActionSE, 1);
  263. std::string* mylistString;
  264. std::vector<std::string> mylistStringVec;
  265. customPlayerData->Mylist[0].clear();
  266. config.TryGetValue("mylist_A", &mylistString);
  267. if (mylistString != nullptr)
  268. {
  269. for (std::string &pvStr : TLAC::Utilities::Split(*mylistString, ","))
  270. customPlayerData->Mylist[0].push_back(atoi(pvStr.c_str()));
  271. delete mylistString;
  272. }
  273. customPlayerData->Mylist[1].clear();
  274. config.TryGetValue("mylist_B", &mylistString);
  275. if (mylistString != nullptr)
  276. {
  277. for (std::string &pvStr : TLAC::Utilities::Split(*mylistString, ","))
  278. customPlayerData->Mylist[1].push_back(atoi(pvStr.c_str()));
  279. delete mylistString;
  280. }
  281. customPlayerData->Mylist[2].clear();
  282. config.TryGetValue("mylist_C", &mylistString);
  283. if (mylistString != nullptr)
  284. {
  285. for (std::string &pvStr : TLAC::Utilities::Split(*mylistString, ","))
  286. customPlayerData->Mylist[2].push_back(atoi(pvStr.c_str()));
  287. delete mylistString;
  288. }
  289. if (moduleCardWorkaround) {
  290. if (!customPlayerData->UseCard)
  291. {
  292. DWORD oldProtect, bck;
  293. VirtualProtect((BYTE*)0x000000014010523F, 3, PAGE_EXECUTE_READWRITE, &oldProtect);
  294. *((BYTE*)0x000000014010523F + 0) = 0x30;
  295. *((BYTE*)0x000000014010523F + 1) = 0xC0;
  296. *((BYTE*)0x000000014010523F + 2) = 0x90;
  297. VirtualProtect((BYTE*)0x000000014010523F, 3, oldProtect, &bck);
  298. VirtualProtect((BYTE*)0x00000001405BCC48, 6, PAGE_EXECUTE_READWRITE, &oldProtect);
  299. *((BYTE*)0x00000001405BCC48 + 0) = 0x90;
  300. *((BYTE*)0x00000001405BCC48 + 1) = 0x90;
  301. *((BYTE*)0x00000001405BCC48 + 2) = 0x90;
  302. *((BYTE*)0x00000001405BCC48 + 3) = 0x90;
  303. *((BYTE*)0x00000001405BCC48 + 4) = 0x90;
  304. *((BYTE*)0x00000001405BCC48 + 5) = 0x90;
  305. VirtualProtect((BYTE*)0x00000001405BCC48, 6, oldProtect, &bck);
  306. VirtualProtect((BYTE*)0x00000001405BC8E6, 3, PAGE_EXECUTE_READWRITE, &oldProtect);
  307. *((BYTE*)0x00000001405BC8E6 + 0) = 0x01;
  308. VirtualProtect((BYTE*)0x00000001405BC8E6, 3, oldProtect, &bck);
  309. }
  310. else {
  311. DWORD oldProtect, bck;
  312. VirtualProtect((BYTE*)0x00000001405BC8E6, 3, PAGE_EXECUTE_READWRITE, &oldProtect);
  313. *((BYTE*)0x00000001405BC8E6 + 0) = 0x00;
  314. VirtualProtect((BYTE*)0x00000001405BC8E6, 3, oldProtect, &bck);
  315. VirtualProtect((BYTE*)0x00000001405BCC48, 6, PAGE_EXECUTE_READWRITE, &oldProtect);
  316. *((BYTE*)0x00000001405BCC48 + 0) = 0xC7;
  317. *((BYTE*)0x00000001405BCC48 + 1) = 0x03;
  318. *((BYTE*)0x00000001405BCC48 + 2) = 0x00;
  319. *((BYTE*)0x00000001405BCC48 + 3) = 0x00;
  320. *((BYTE*)0x00000001405BCC48 + 4) = 0x00;
  321. *((BYTE*)0x00000001405BCC48 + 5) = 0x00;
  322. VirtualProtect((BYTE*)0x00000001405BCC48, 6, oldProtect, &bck);
  323. VirtualProtect((BYTE*)0x000000014010523F, 3, PAGE_EXECUTE_READWRITE, &oldProtect);
  324. *((BYTE*)0x000000014010523F + 0) = 0x0F;
  325. *((BYTE*)0x000000014010523F + 1) = 0x94;
  326. *((BYTE*)0x000000014010523F + 2) = 0xC1;
  327. VirtualProtect((BYTE*)0x000000014010523F, 3, oldProtect, &bck);
  328. //just incase the player is reloading
  329. VirtualProtect((BYTE*)0x00000001405CBBA3, 8, PAGE_EXECUTE_READWRITE, &oldProtect);
  330. *((BYTE*)0x00000001405CBBA3 + 0) = 0x42;
  331. *((BYTE*)0x00000001405CBBA3 + 1) = 0x89;
  332. *((BYTE*)0x00000001405CBBA3 + 2) = 0x84;
  333. *((BYTE*)0x00000001405CBBA3 + 3) = 0xb6;
  334. *((BYTE*)0x00000001405CBBA3 + 4) = 0xc0;
  335. *((BYTE*)0x00000001405CBBA3 + 5) = 0x01;
  336. *((BYTE*)0x00000001405CBBA3 + 6) = 0x00;
  337. *((BYTE*)0x00000001405CBBA3 + 7) = 0x00;
  338. VirtualProtect((BYTE*)0x00000001405CBBA3, 8, oldProtect, &bck);
  339. }
  340. }
  341. }
  342. void PlayerDataManager::ApplyCustomData()
  343. {
  344. // don't want to overwrite the default values
  345. auto setIfNotEqual = [](int *target, int value, int comparison)
  346. {
  347. if (value != comparison)
  348. *target = value;
  349. };
  350. // check if the playerData in-game value is different from the customPlayerData value and update and save the ini
  351. if (customPlayerData->VocaloidPoints != playerData->vocaloid_point)
  352. {
  353. customPlayerData->VocaloidPoints = playerData->vocaloid_point;
  354. WCHAR val[32];
  355. swprintf(val, 32, L"%d", playerData->vocaloid_point);
  356. WritePrivateProfileStringW(L"playerdata", L"vocaloid_point", val, configPath);
  357. }
  358. // save module choices to module_equip_cmn[0-5]
  359. if (customPlayerData->ModuleEquipCmn0 != playerData->module_equip_cmn0)
  360. {
  361. customPlayerData->ModuleEquipCmn0 = playerData->module_equip_cmn0;
  362. WCHAR val[32];
  363. swprintf(val, 32, L"%d", playerData->module_equip_cmn0);
  364. WritePrivateProfileStringW(L"playerdata", L"module_equip_cmn0", val, configPath);
  365. }
  366. if (customPlayerData->ModuleEquipCmn1 != playerData->module_equip_cmn1)
  367. {
  368. customPlayerData->ModuleEquipCmn1 = playerData->module_equip_cmn1;
  369. WCHAR val[32];
  370. swprintf(val, 32, L"%d", playerData->module_equip_cmn1);
  371. WritePrivateProfileStringW(L"playerdata", L"module_equip_cmn1", val, configPath);
  372. }
  373. if (customPlayerData->ModuleEquipCmn2 != playerData->module_equip_cmn2)
  374. {
  375. customPlayerData->ModuleEquipCmn2 = playerData->module_equip_cmn2;
  376. WCHAR val[32];
  377. swprintf(val, 32, L"%d", playerData->module_equip_cmn2);
  378. WritePrivateProfileStringW(L"playerdata", L"module_equip_cmn2", val, configPath);
  379. }
  380. if (customPlayerData->ModuleEquipCmn3 != playerData->module_equip_cmn3)
  381. {
  382. customPlayerData->ModuleEquipCmn3 = playerData->module_equip_cmn3;
  383. WCHAR val[32];
  384. swprintf(val, 32, L"%d", playerData->module_equip_cmn3);
  385. WritePrivateProfileStringW(L"playerdata", L"module_equip_cmn3", val, configPath);
  386. }
  387. if (customPlayerData->ModuleEquipCmn4 != playerData->module_equip_cmn4)
  388. {
  389. customPlayerData->ModuleEquipCmn4 = playerData->module_equip_cmn4;
  390. WCHAR val[32];
  391. swprintf(val, 32, L"%d", playerData->module_equip_cmn4);
  392. WritePrivateProfileStringW(L"playerdata", L"module_equip_cmn4", val, configPath);
  393. }
  394. if (customPlayerData->ModuleEquipCmn5 != playerData->module_equip_cmn5)
  395. {
  396. customPlayerData->ModuleEquipCmn5 = playerData->module_equip_cmn5;
  397. WCHAR val[32];
  398. swprintf(val, 32, L"%d", playerData->module_equip_cmn5);
  399. WritePrivateProfileStringW(L"playerdata", L"module_equip_cmn5", val, configPath);
  400. }
  401. if (customPlayerData->ActionVol != playerData->act_vol)
  402. {
  403. customPlayerData->ActionVol = playerData->act_vol;
  404. WCHAR val[32];
  405. swprintf(val, 32, L"%d", playerData->act_vol);
  406. WritePrivateProfileStringW(L"playerdata", L"act_vol", val, configPath);
  407. }
  408. if (customPlayerData->ActionSlideVol != playerData->act_slide_vol)
  409. {
  410. customPlayerData->ActionSlideVol = playerData->act_slide_vol;
  411. WCHAR val[32];
  412. swprintf(val, 32, L"%d", playerData->act_slide_vol);
  413. WritePrivateProfileStringW(L"playerdata", L"act_slide_vol", val, configPath);
  414. }
  415. if (customPlayerData->UsePVEquip != playerData->use_pv_module_equip)
  416. {
  417. playerData->use_pv_module_equip = 1;
  418. }
  419. if (customPlayerData->UsePVSFXEquip != playerData->use_pv_btn_se_equip)
  420. {
  421. playerData->use_pv_btn_se_equip = 1;
  422. playerData->use_pv_chainslide_se_equip = 1;
  423. playerData->use_pv_slidertouch_se_equip = 1;
  424. playerData->use_pv_slide_se_equip = 1;
  425. }
  426. if (customPlayerData->UsePVSkinEquip != playerData->use_pv_skin_equip)
  427. {
  428. playerData->use_pv_skin_equip = 1;
  429. }
  430. setIfNotEqual(&playerData->level, customPlayerData->LevelNum, 1);
  431. setIfNotEqual(&playerData->level_plate_id, customPlayerData->LevelPlateId, 0);
  432. setIfNotEqual(&playerData->level_plate_effect, customPlayerData->LevelPlateEffect, 0);
  433. // Display clear borders on the progress bar
  434. playerData->clear_border = (customPlayerData->ShowRivalClearBorder << 2) | (customPlayerData->ShowExcellentClearBorder << 1) | (customPlayerData->ShowGreatClearBorder);
  435. playerData->use_card = customPlayerData->UseCard; // required to allow for module selection
  436. playerData->game_opts = customPlayerData->GameModifierOptions; // hi-speed, etc..
  437. memset((void*)MODULE_TABLE_START, 0xFF, 128);
  438. memset((void*)ITEM_TABLE_START, 0xFF, 128);
  439. playerData->mylistA_begin = customPlayerData->Mylist[0].begin()._Ptr;
  440. playerData->mylistA_end = customPlayerData->Mylist[0].end()._Ptr;
  441. playerData->mylistB_begin = customPlayerData->Mylist[1].begin()._Ptr;
  442. playerData->mylistB_end = customPlayerData->Mylist[1].end()._Ptr;
  443. playerData->mylistC_begin = customPlayerData->Mylist[2].begin()._Ptr;
  444. playerData->mylistC_end = customPlayerData->Mylist[2].end()._Ptr;
  445. if (customPlayerData->PlayerName != nullptr)
  446. {
  447. playerData->field_DC = 0x10;
  448. playerData->player_name = (char*)customPlayerData->PlayerName->c_str();
  449. }
  450. if (customPlayerData->LevelName != nullptr)
  451. {
  452. playerData->level_name = (char*)customPlayerData->LevelName->c_str();
  453. playerData->field_110 = 0xFF;
  454. playerData->field_118 = 0x1F;
  455. }
  456. }
  457. }