diff --git a/shotchart-solution/HackBase/csvsavedata.cpp b/shotchart-solution/HackBase/csvsavedata.cpp index 793de60..3d7ef44 100644 --- a/shotchart-solution/HackBase/csvsavedata.cpp +++ b/shotchart-solution/HackBase/csvsavedata.cpp @@ -138,7 +138,7 @@ void SaveData::SaveDataFileLines() { srand((int)time(0)); d = ((double)rand()) / RAND_MAX; d = 20 * d - 10; // between -1 and 1 - PerShotData PerShotData0(2, 1, 1272.5 + d, 0.0 + d, 0.0, 2); // 47 - 4 = 43 feet minus 15 inch = 41'9" approx. x=1250cm, y=0 d=0 obviously + PerShotData PerShotData0(2, 1, (float)(1272.5 + d), (float)(0.0 + d), 0.0, 2); // 47 - 4 = 43 feet minus 15 inch = 41'9" approx. x=1250cm, y=0 d=0 obviously this->os << PerShotData0.score_type_s << PerShotData0.score_judge_s << PerShotData0.coordinate_x_100_s << PerShotData0.coordinate_y_100_s << PerShotData0.absolute_dist_rim_s << PerShotData0.type_s << NEWLINE; } else { diff --git a/shotchart-solution/HackBase/main.cpp b/shotchart-solution/HackBase/main.cpp index 22fe864..a9ce463 100644 --- a/shotchart-solution/HackBase/main.cpp +++ b/shotchart-solution/HackBase/main.cpp @@ -7,6 +7,7 @@ HackBase *mHackBase = 0; SaveData *mSaveData = 0; HMODULE g_d3d9Module = NULL; +DWORD total_time_elapsed_addr = 0x05439C1C; bool d3d9hijack(HMODULE hModule) { TCHAR processPath[MAX_PATH]; @@ -78,6 +79,7 @@ void init_main() { while (true) { //infinite loop! might affect the performance. // i > 5 ? i = 0 : ++i; UpdateDMAs(pHandle_r, mSaveData); + ReadProcessMemory(pHandle_r, (LPVOID)total_time_elapsed_addr, &total_time_elapsed, sizeof(total_time_elapsed), 0); // keys after dma cause we need to depend on Z down UpdateHotkeys(i); UpdateDMA_afterKeyDown(pHandle_r, pHandle_w, mSaveData); diff --git a/shotchart-solution/HackBase/memoryaccess.cpp b/shotchart-solution/HackBase/memoryaccess.cpp index 5bd81a8..9b5795a 100644 --- a/shotchart-solution/HackBase/memoryaccess.cpp +++ b/shotchart-solution/HackBase/memoryaccess.cpp @@ -20,7 +20,7 @@ DWORD absolute_dist_rim_addr = 0x05d5f730; // 距离篮筐绝对距离 DWORD projected_percent_addr = 0x05d5f738; // 预计投篮命中率,可参考以提升投篮选择 DWORD shot_triggered_time_addr = 0x05db028c; // 投篮释放时间,即按下z投篮键后键抬起的时间,可用于判断是否扣篮,秒数 -DWORD total_time_elapsed_addr = 0x05439C1C; // 总流逝时间,包括暂停表演等,不包括esc游戏暂停 +DWORD total_time_elapsed_addr1 = 0x05439C1C; // 总流逝时间,包括暂停表演等,不包括esc游戏暂停 // 1. the followings are for quartered games, e.g. // dynasty, quick game, mplayer, jordan, etc. @@ -28,9 +28,56 @@ // 2. the following data are for SG player, particular for jordan mplayer mode -DWORD FTA_ADDR1 = PTS_ADDR + 0x8; -DWORD FGA_ADDR1 = PTS_ADDR + 0x10; -DWORD PA3_ADDR1 = PTS_ADDR + 0x18; +DWORD FTA_ADDR1 = 0x0; +DWORD FGA_ADDR1 = 0x0; +DWORD PA3_ADDR1 = 0x0; + +DWORD HOME_PG_BASE_ADDR = 0x05c2e14f; +DWORD PTS_OFFSET = 0x19; +DWORD PLAYER_OFFSET = 0x43C; + +DWORD HOME_PG_SUR_ADDR = 0x5e4a528; +DWORD HOME_PG_FIR_ADDR = 0x5e4a52c; +DWORD PLAYERS_INFO_OFFSET = 0xB58; // pg sg sf pf c + +void update_attempts_addresses() { + FTA_ADDR1 = PTS_ADDR + 0x8; + FGA_ADDR1 = PTS_ADDR + 0x10; + PA3_ADDR1 = PTS_ADDR + 0x18; +} + +bool if_game_started(HANDLE pHandle) { + float total_time_elapsed_temp; + ReadProcessMemory(pHandle, (LPVOID)total_time_elapsed_addr1, &total_time_elapsed_temp, sizeof(total_time_elapsed_temp), 0); + return total_time_elapsed_temp != total_time_elapsed ? true : false; +} + +int acquire_PTS_ADDR(HANDLE pHandle) { + int i = 0; + DWORD ptSUR_ADDR = 0x0; // the addr of pointer that points to + DWORD ptFIR_ADDR = 0x0; + DWORD SUR_ADDR = 0x0; + DWORD FIR_ADDR = 0x0; + wchar_t SUR[7] = L"Jordan"; // Jordan in unicode string + wchar_t FIR[8] = L"Michael"; // Michael + while(i < 24) { + ptSUR_ADDR = HOME_PG_SUR_ADDR + i * PLAYERS_INFO_OFFSET; + ptFIR_ADDR = HOME_PG_FIR_ADDR + i * PLAYERS_INFO_OFFSET; + ReadProcessMemory(pHandle, (LPVOID)ptSUR_ADDR, &SUR_ADDR, sizeof(SUR_ADDR), 0); + ReadProcessMemory(pHandle, (LPVOID)ptFIR_ADDR, &FIR_ADDR, sizeof(FIR_ADDR), 0); + wchar_t SUR_BUF[64]; // unicode string, make bigger space to avoid overflow + wchar_t FIR_BUF[64]; // + ReadProcessMemory(pHandle, (LPVOID)SUR_ADDR, &SUR_BUF, sizeof(SUR_BUF), 0); + ReadProcessMemory(pHandle, (LPVOID)FIR_ADDR, &FIR_BUF, sizeof(FIR_BUF), 0); + if (VERBOSEMODE) MessageBoxW(0, SUR_BUF, L"see what surname we got", 0); + if ((wcsncmp(SUR, SUR_BUF, 7) == 0) && (wcsncmp(FIR, FIR_BUF, 8) == 0)) { + if (VERBOSEMODE) MessageBox(0, "haha we caught Jordan!", "nana...", 0); + break; + } + ++i; + } + return i; // i = 24 fail, otherwise find offset factor +} void update_shot_coordinates(HANDLE pHandle) { // update_shot_coordinates @@ -50,11 +97,13 @@ void update_score_type(HANDLE pHandle) { ReadProcessMemory(pHandle, (LPVOID)score_judge_addr, &score_judge, sizeof(score_judge), 0); // update_projected_percent ReadProcessMemory(pHandle, (LPVOID)projected_percent_addr, &projected_percent, sizeof(projected_percent), 0); + // update_total_time_elapsed + } void update_projected_percent(HANDLE pHandle) { - + // move to above function to improve performance } @@ -92,40 +141,55 @@ void UpdateDMAs(HANDLE pHandle, SaveData *mSaveData) { - if (record_mode == 1) { // mj mp mode - if (!PTS_ADDR) { // addr == 0 - return; // if mj mode addr not initialized, do not record. - } - else { - int fgatemp = fga_global; - int pa3temp = pa3_global; - int ftatemp = fta_global; - ReadProcessMemory(pHandle, (LPVOID)FGA_ADDR1, &fga_global, sizeof(fga_global), 0); - ReadProcessMemory(pHandle, (LPVOID)PA3_ADDR1, &pa3_global, sizeof(pa3_global), 0); - ReadProcessMemory(pHandle, (LPVOID)FTA_ADDR1, &fta_global, sizeof(fta_global), 0); - // read the points scored out and print it to see if addresses are correct. - ReadProcessMemory(pHandle, (LPVOID)PTS_ADDR, &PTS, sizeof(PTS), 0); - - if (fgatemp != fga_global) { - pts_type = 2; - redraw_shotchart = true; - if (record_shot_chart_and_more) mSaveData->SaveDataFileLines(); - } - else if (pa3temp != pa3_global) { - pts_type = 3; - redraw_shotchart = true; - if (record_shot_chart_and_more) mSaveData->SaveDataFileLines(); - } - else if (ftatemp != fta_global) { - pts_type = 1; - redraw_shotchart = true; - if (record_shot_chart_and_more) mSaveData->SaveDataFileLines(); + if (record_mode == 1 && record_shot_chart_and_more) { // mj mp mode + if (if_game_started(pHandle)) { + if (!PTS_ADDR) { // addr == 0 + int index; + index = acquire_PTS_ADDR(pHandle); + if (index == 24) { // looped through all the players + return; // if mj mode addr not initialized, do not record. + } + else { + PTS_ADDR = HOME_PG_BASE_ADDR + PTS_OFFSET + index * PLAYER_OFFSET; + update_attempts_addresses(); + return; + } } else { - pts_type = 0; // default - redraw_shotchart = false; + int fgatemp = fga_global; + int pa3temp = pa3_global; + int ftatemp = fta_global; + ReadProcessMemory(pHandle, (LPVOID)FGA_ADDR1, &fga_global, sizeof(fga_global), 0); + ReadProcessMemory(pHandle, (LPVOID)PA3_ADDR1, &pa3_global, sizeof(pa3_global), 0); + ReadProcessMemory(pHandle, (LPVOID)FTA_ADDR1, &fta_global, sizeof(fta_global), 0); + // read the points scored out and print it to see if addresses are correct. + ReadProcessMemory(pHandle, (LPVOID)PTS_ADDR, &PTS, sizeof(PTS), 0); + + if (fgatemp != fga_global) { + pts_type = 2; + redraw_shotchart = true; + mSaveData->SaveDataFileLines(); + } + else if (pa3temp != pa3_global) { + pts_type = 3; + redraw_shotchart = true; + mSaveData->SaveDataFileLines(); + } + else if (ftatemp != fta_global) { + pts_type = 1; + redraw_shotchart = true; + mSaveData->SaveDataFileLines(); + } + else { + pts_type = 0; // default + redraw_shotchart = false; + } } } + else { + return; // game not started + } + } } \ No newline at end of file diff --git a/shotchart-solution/HackBase/memoryaccess_afterkeydown.cpp b/shotchart-solution/HackBase/memoryaccess_afterkeydown.cpp index bf81c63..e66de26 100644 --- a/shotchart-solution/HackBase/memoryaccess_afterkeydown.cpp +++ b/shotchart-solution/HackBase/memoryaccess_afterkeydown.cpp @@ -8,22 +8,41 @@ DWORD god_mode_byte_addr = 0x0097D9A3; // nba2k11.exe+57D99D - C7 05 78FAD505 00 // 2. the following data are for SG player, particular for jordan mplayer mode // the address offset for each player is 0x43C, order:pg sg sf pf c 6-12 -DWORD FTM_ADDR = PTS_ADDR + 0x4; -DWORD FTA_ADDR = PTS_ADDR + 0x8; -DWORD FGA_ADDR = PTS_ADDR + 0x10; -DWORD FGM_ADDR = PTS_ADDR + 0xC; -DWORD PA3_ADDR = PTS_ADDR + 0x18; -DWORD PM3_ADDR = PTS_ADDR + 0x14; -DWORD FRB_ADDR = PTS_ADDR + 0x1C8; // 前场板 -DWORD BRB_ADDR = PTS_ADDR + 0x1CC; // 后场板 -DWORD STL_ADDR = PTS_ADDR + 0x1F8; -DWORD BLK_ADDR = PTS_ADDR + 0x1FC; -DWORD AST_ADDR = PTS_ADDR + 0x204; -DWORD TOV_ADDR = PTS_ADDR + 0x208; -DWORD PLM_ADDR = PTS_ADDR + 0x218; // 正负值 -DWORD MIN_ADDR = PTS_ADDR + 0x324; // IN FLOAT seconds +DWORD FTM_ADDR = 0x0; +DWORD FTA_ADDR = 0x0; +DWORD FGA_ADDR = 0x0; +DWORD FGM_ADDR = 0x0; +DWORD PA3_ADDR = 0x0; +DWORD PM3_ADDR = 0x0; +DWORD FRB_ADDR = 0x0; // 前场板 +DWORD BRB_ADDR = 0x0; // 后场板 +DWORD STL_ADDR = 0x0; +DWORD BLK_ADDR = 0x0; +DWORD AST_ADDR = 0x0; +DWORD TOV_ADDR = 0x0; +DWORD PLM_ADDR = 0x0; // 正负值 +DWORD MIN_ADDR = 0x0; // IN FLOAT seconds +void update_stats_addresses() { + // 2. the following data are for SG player, particular for jordan mplayer mode + // the address offset for each player is 0x43C, order:pg sg sf pf c 6-12 + DWORD FTM_ADDR = PTS_ADDR + 0x4; + DWORD FTA_ADDR = PTS_ADDR + 0x8; + DWORD FGA_ADDR = PTS_ADDR + 0x10; + DWORD FGM_ADDR = PTS_ADDR + 0xC; + DWORD PA3_ADDR = PTS_ADDR + 0x18; + DWORD PM3_ADDR = PTS_ADDR + 0x14; + DWORD FRB_ADDR = PTS_ADDR + 0x1C8; // 前场板 + DWORD BRB_ADDR = PTS_ADDR + 0x1CC; // 后场板 + DWORD STL_ADDR = PTS_ADDR + 0x1F8; + DWORD BLK_ADDR = PTS_ADDR + 0x1FC; + DWORD AST_ADDR = PTS_ADDR + 0x204; + DWORD TOV_ADDR = PTS_ADDR + 0x208; + DWORD PLM_ADDR = PTS_ADDR + 0x218; // 正负值 + DWORD MIN_ADDR = PTS_ADDR + 0x324; // IN FLOAT seconds +} + void read_end_of_game_data(HANDLE pHandle, float &min, int &pts, @@ -41,6 +60,7 @@ void read_end_of_game_data(HANDLE pHandle, int &tov, int &plm ) { + update_stats_addresses(); // update addresses for saving data ReadProcessMemory(pHandle, (LPVOID)MIN_ADDR, &min, sizeof(min), 0); ReadProcessMemory(pHandle, (LPVOID)PTS_ADDR, &pts, sizeof(pts), 0); ReadProcessMemory(pHandle, (LPVOID)FGA_ADDR, &fga, sizeof(fga), 0); @@ -70,13 +90,10 @@ void change_god_mode(HANDLE pHandle) { } } - - void UpdateDMA_afterKeyDown(HANDLE pHandle_r, HANDLE pHandle_w, SaveData *mSaveData) { if (IsKeyDown(VK_F6)) { if (record_shot_chart_and_more) { record_shot_chart_and_more = false; - PTS_ADDR = 0x0; // reset addr for MJ float min = 0; int pts = 0; int fga = 0; @@ -92,8 +109,14 @@ void UpdateDMA_afterKeyDown(HANDLE pHandle_r, HANDLE pHandle_w, SaveData *mSaveD int blk = 0; int tov = 0; int plm = 0; - read_end_of_game_data(pHandle_r, min, pts, fga, fgm, pa3, pm3, fta, ftm, freb, breb, ast, stl, blk, tov, plm); - mSaveData->SaveDataFileFooter(min, pts, fga, fgm, pa3, pm3, fta, ftm, freb, breb, ast, stl, blk, tov, plm); + if (record_mode == 2) { // for shootaround mode only record 0 data + mSaveData->SaveDataFileFooter(min, pts, fga, fgm, pa3, pm3, fta, ftm, freb, breb, ast, stl, blk, tov, plm); + } + if (record_mode == 1) { + read_end_of_game_data(pHandle_r, min, pts, fga, fgm, pa3, pm3, fta, ftm, freb, breb, ast, stl, blk, tov, plm); + mSaveData->SaveDataFileFooter(min, pts, fga, fgm, pa3, pm3, fta, ftm, freb, breb, ast, stl, blk, tov, plm); + } + PTS_ADDR = 0x0; // reset addr for MJ } else { record_shot_chart_and_more = true; diff --git a/shotchart-solution/HackBase/trainerbase.h b/shotchart-solution/HackBase/trainerbase.h index d928bc8..dedb32b 100644 --- a/shotchart-solution/HackBase/trainerbase.h +++ b/shotchart-solution/HackBase/trainerbase.h @@ -84,6 +84,7 @@ extern int fta_global; extern int pa3_global; extern int pts_type; // 1pt ft, 2pt, 3pt. default 0 for simple record mode. +extern float total_time_elapsed; // to judge if game started for mj mode // 保存至csv文件 class SaveData { diff --git a/shotchart-solution/HackBase/trainergraphic.cpp b/shotchart-solution/HackBase/trainergraphic.cpp index e6da3be..733cde6 100644 --- a/shotchart-solution/HackBase/trainergraphic.cpp +++ b/shotchart-solution/HackBase/trainergraphic.cpp @@ -65,6 +65,7 @@ float shot_triggered_time = 0; float projected_percent = 0; int PTS = 0; +float total_time_elapsed = 0; int pts_type = 0; int fga_global = 0; @@ -143,13 +144,14 @@ void onRender_dashboard(Renderer *renderer) { renderer->DrawTxt(border_width, 1 + border_width + 4 * column_height, FontColor_default, temp_str); renderer->DrawTxt(border_width, 1 + border_width + 5 * column_height, FontColor_default, dunk_text); if (!PTS_ADDR) { - char temp_str[10]; + char temp_str[32]; sprintf_s(temp_str, "%s", "MJ base addr not init!"); renderer->DrawTxt(border_width, 1 + border_width + 6 * column_height, RED(255), temp_str); } else { - char temp_str[10]; + char temp_str[32]; sprintf_s(temp_str, "MJ PTS: %d", PTS); + // sprintf_s(temp_str, "addr: %x", PTS_ADDR); renderer->DrawTxt(border_width, 1 + border_width + 6 * column_height, FontColor_default, temp_str); } /* do not need to expose the raw data to regular users.