From e4fe580ec842382c26d90a8f8e672277fa3e9496 Mon Sep 17 00:00:00 2001 From: secsome <302702960@qq.com> Date: Thu, 19 Aug 2021 23:48:37 +0800 Subject: [PATCH 1/8] Implement auto-saving feature --- FA2sp.vcxproj | 1 + FA2sp.vcxproj.filters | 3 + FA2sp/FA2sp.Constants.h | 5 - FA2sp/FA2sp.cpp | 17 +++ FA2sp/FA2sp.h | 4 + FA2sp/Miscs/Hooks.SaveMap.cpp | 190 ++++++++++++++++++++++++++++++++++ README.md | 10 ++ 7 files changed, 225 insertions(+), 5 deletions(-) create mode 100644 FA2sp/Miscs/Hooks.SaveMap.cpp diff --git a/FA2sp.vcxproj b/FA2sp.vcxproj index 0efc64b..e1bf014 100644 --- a/FA2sp.vcxproj +++ b/FA2sp.vcxproj @@ -149,6 +149,7 @@ + diff --git a/FA2sp.vcxproj.filters b/FA2sp.vcxproj.filters index 3232614..a9fd12a 100644 --- a/FA2sp.vcxproj.filters +++ b/FA2sp.vcxproj.filters @@ -275,6 +275,9 @@ 源文件 + + 源文件 + diff --git a/FA2sp/FA2sp.Constants.h b/FA2sp/FA2sp.Constants.h index dd32087..54139a5 100644 --- a/FA2sp/FA2sp.Constants.h +++ b/FA2sp/FA2sp.Constants.h @@ -1,10 +1,5 @@ #pragma once -#define wstr(x) wstr_(x) -#define wstr_(x) L ## #x -#define str(x) str_(x) -#define str_(x) #x - constexpr int PRODUCT_MAJOR = 1; constexpr int PRODUCT_MINOR = 0; constexpr int PRODUCT_REVISION = 3; diff --git a/FA2sp/FA2sp.cpp b/FA2sp/FA2sp.cpp index 97ab221..44849b8 100644 --- a/FA2sp/FA2sp.cpp +++ b/FA2sp/FA2sp.cpp @@ -35,6 +35,10 @@ int ExtConfigs::Waypoint_Background_Color; bool ExtConfigs::ExtWaypoints; int ExtConfigs::UndoRedoLimit; bool ExtConfigs::UseRGBHouseColor; +bool ExtConfigs::SaveMap; +bool ExtConfigs::SaveMap_AutoSave; +int ExtConfigs::SaveMap_AutoSave_Interval; +int ExtConfigs::SaveMap_AutoSave_MaxCount; MultimapHelper Variables::Rules = { &GlobalVars::INIFiles::Rules(), &GlobalVars::INIFiles::CurrentDocument() }; @@ -81,6 +85,19 @@ void FA2sp::ExtConfigsInitialize() ExtConfigs::UndoRedoLimit = fadata.GetInteger("ExtConfigs", "UndoRedoLimit", 16); ExtConfigs::UseRGBHouseColor = fadata.GetBool("ExtConfigs", "UseRGBHouseColor"); + + if (ExtConfigs::SaveMap = fadata.GetBool("ExtConfigs", "SaveMap")) + { + if (ExtConfigs::SaveMap_AutoSave = fadata.GetBool("ExtConfigs", "SaveMap.AutoSave")) + { + ExtConfigs::SaveMap_AutoSave_Interval = fadata.GetInteger("ExtConfigs", "SaveMap.AutoSave.Interval", 300); + ExtConfigs::SaveMap_AutoSave_MaxCount = fadata.GetInteger("ExtConfigs", "SaveMap.AutoSave.MaxCount", 10); + } + else + { + ExtConfigs::SaveMap_AutoSave_Interval = -1; + } + } } // DllMain diff --git a/FA2sp/FA2sp.h b/FA2sp/FA2sp.h index 6410f86..d5468f9 100644 --- a/FA2sp/FA2sp.h +++ b/FA2sp/FA2sp.h @@ -45,6 +45,10 @@ class ExtConfigs static bool ExtWaypoints; static int UndoRedoLimit; static bool UseRGBHouseColor; + static bool SaveMap; + static bool SaveMap_AutoSave; + static int SaveMap_AutoSave_Interval; + static int SaveMap_AutoSave_MaxCount; }; class Variables diff --git a/FA2sp/Miscs/Hooks.SaveMap.cpp b/FA2sp/Miscs/Hooks.SaveMap.cpp new file mode 100644 index 0000000..391ff8e --- /dev/null +++ b/FA2sp/Miscs/Hooks.SaveMap.cpp @@ -0,0 +1,190 @@ +#include + +#include +#include +#include +#include + +#include "../FA2sp.h" +#include "../FA2sp.Constants.h" + +#include +#include + +// FA2 SaveMap is almost O(N^4), who wrote that? +DEFINE_HOOK(428D97, CFinalSunDlg_SaveMap, 7) +{ + if (ExtConfigs::SaveMap) + { + GET(INIClass*, pINI, EAX); + GET_STACK(CFinalSunDlg*, pThis, STACK_OFFS(0x3F4, 0x36C)); + LEA_STACK(ppmfc::CString*, pPath, STACK_OFFS(0x3F4, 0x360)); + + ppmfc::CString path = "TmpMap.map"; + + pThis->MyViewFrame.StatusBar.SetWindowText("Saving..."); + pThis->MyViewFrame.StatusBar.UpdateWindow(); + + DeleteFile(path); + CloseHandle( + CreateFile(path, GENERIC_WRITE, NULL, nullptr, TRUNCATE_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN | FILE_ATTRIBUTE_NORMAL, NULL) + ); + auto hFile = CreateFile(path, GENERIC_WRITE, NULL, nullptr, CREATE_ALWAYS, FILE_FLAG_SEQUENTIAL_SCAN | FILE_ATTRIBUTE_NORMAL, NULL); + + std::stringstream ss; + ss << + "; Map created with FinalAlert 2(tm) Mission Editor\n" + "; Get it at http://www.westwood.com\n" + "; note that all comments were truncated\n" + "\n" + "; This FA2 uses FA2sp created by secsome\n" + "; Get the lastest dll at https://github.com/secsome/FA2sp\n" + "; Current version : "; + ss << PRODUCT_STR; + ss << "\n\n"; + + for (auto& section : pINI->Dict) + { + ss << "["; + ss << section.first; + ss << "]\n"; + for (auto& pair : section.second.EntitiesDictionary) + { + ss << pair.first; + ss << "="; + ss << pair.second; + ss << "\n"; + } + ss << "\n"; + } + + WriteFile(hFile, ss.str().c_str(), ss.str().length(), nullptr, nullptr); + CloseHandle(hFile); + + new(pPath) ppmfc::CString(path); + + return 0x42A859; + } + + return 0; +} + +DEFINE_HOOK(42B30F, CFinalSunDlg_SaveMap_SkipMapDTOR, 7) +{ + return ExtConfigs::SaveMap ? 0x42B323 : 0; +} + +class SaveMapExt +{ +private: + static UINT_PTR Timer; +public: + static bool IsAutoSaving; + + static void ResetTimer() + { + StopTimer(); + if (ExtConfigs::SaveMap_AutoSave_Interval >= 30) + { + Timer = SetTimer(GlobalVars::Dialogs::CFinalSunDlg->m_hWnd, + NULL, 1000 * ExtConfigs::SaveMap_AutoSave_Interval, SaveMapCallback); + } + } + + static void StopTimer() + { + if (Timer != NULL) + { + KillTimer(GlobalVars::Dialogs::CFinalSunDlg->m_hWnd, Timer); + Timer = NULL; + } + } + + static void RemoveEarlySaves() + { + if (ExtConfigs::SaveMap_AutoSave_MaxCount != -1) + { + struct FileTimeComparator + { + bool operator()(const FILETIME& a, const FILETIME& b) const { return CompareFileTime(&a, &b) == -1; } + }; + + std::map m; + + WIN32_FIND_DATA Data; + auto hFindData = FindFirstFile("AutoSaves\\autosave-*.map", &Data); + while (hFindData != INVALID_HANDLE_VALUE) + { + m[Data.ftLastWriteTime] = Data.cFileName; + if (!FindNextFile(hFindData, &Data)) + break; + } + + int count = m.size() - ExtConfigs::SaveMap_AutoSave_MaxCount; + if (count <= 0) + return; + + auto& itr = m.begin(); + ppmfc::CString buffer; + while (count != 0) + { + buffer.Format("AutoSaves\\%s", itr->second); + DeleteFile(buffer); + ++itr; + --count; + } + } + } + + static void CALLBACK SaveMapCallback(HWND hwnd, UINT message, UINT iTimerID, DWORD dwTime) + { + if (!GlobalVars::CMapData->MapWidthPlusHeight || !GlobalVars::CMapData->FieldDataAllocated) + { + StopTimer(); + return; + } + + SYSTEMTIME time; + GetLocalTime(&time); + + CreateDirectory("AutoSaves", nullptr); + + ppmfc::CString path; + path.Format("AutoSaves\\autosave-%04d%02d%02d-%02d%02d%02d-%03d.map", + time.wYear, time.wMonth, time.wDay, + time.wHour, time.wMinute, time.wSecond, + time.wMilliseconds + ); + + IsAutoSaving = true; + GlobalVars::Dialogs::CFinalSunDlg->SaveMap(path); + IsAutoSaving = false; + + RemoveEarlySaves(); + } +}; + +bool SaveMapExt::IsAutoSaving = false; +UINT_PTR SaveMapExt::Timer = NULL; + +DEFINE_HOOK(426E50, CFinalSunDlg_SaveMap_AutoSave_StopTimer, 7) +{ + SaveMapExt::StopTimer(); + return 0; +} + +DEFINE_HOOK(42B3AC, CFinalSunDlg_SaveMap_AutoSave_ResetTimer, 7) +{ + SaveMapExt::ResetTimer(); + return 0; +} + +DEFINE_HOOK(427949, CFinalSunDlg_SaveMap_AutoSave_SkipDialog, A) +{ + return SaveMapExt::IsAutoSaving ? 0x428CF6 : 0; +} + +DEFINE_HOOK(42B294, CFinalSunDlg_SaveMap_AutoSave_SkipEditFilesMenu, 8) +{ + return SaveMapExt::IsAutoSaving ? 0x42B2AF : 0; +} \ No newline at end of file diff --git a/README.md b/README.md index 098f2ba..856ec63 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,12 @@ Compile Using C++ Standard Now: C++14 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~////////// FINALALERT2 - SP CHANGELOG //////////~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\\\\\//////////////////////////////////////\\\\\~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +======================= Changes (2021-08-XX) ============================================================================================== ++) New ExtConfig: SaveMap = BOOLEAN, enable it so that we will replace FA2's vanilla slow saving function + +) New ExtConfig: SaveMap.AutoSave = BOOLEAN, enable it so that we will enable FA2 to save map automatically after one save + +) New ExtConfig: SaveMap.AutoSave.Interval = INTEGER, set the interval between two auto saving, need to be greater than or equal to than 30 + +) New ExtConfig: SaveMap.AutoSave.MaxCount = INTEGER, how many auto saving files can FA2 keep, set to -1 will disable the auto cleanning up + ======================= Changes (2021-08-19 RELEASE 1.0.3) ============================================================================================== *) Now we read file without extracting them to the game folder, this might fix some reading bugs *) The ObjectBrowserView will show player locations again in Multiplayer maps (with Basic -> MultiplayerOnly=yes) @@ -151,6 +157,10 @@ COLORREF - R,G,B each of them is in [0,255] +) ExtWaypoints = BOOLEAN ; Determines if FA2sp supports unlimited count of waypoints, defaults to false (Phobos required) +) UndoRedoLimit = INTEGER ; Determines the maximun step of undo/redo, defaults to 16 +) UseRGBHouseColor = BOOLEAN ; Determines if House colors are recognized as RGB color instead of HSV, defaults to false + +) SaveMap = BOOLEAN ; Determines if FA2 will save map using a faster method + +) SaveMap.AutoSave = BOOLEAN ; Determines if FA2 will save map automatically after one manually saving + +) SaveMap.AutoSave.Interval = INTERGER ; Should be greater than or equal to 30, defaults to 300, determines how many seconds should we wait during the two auto saving + +) SaveMap.AutoSave.MaxCount = INTERGER ; How many saving should FA2 keep, set to -1 will disable the auto cleanning, defaults to 10 +) [Sides] ** (** means Essensial, fa2sp need this section to work properly) {Contains a list of sides registered in rules} \\\ e.g. From c71118b61011499a25dd9ac02a3b3de4d25fa1bc Mon Sep 17 00:00:00 2001 From: secsome <302702960@qq.com> Date: Fri, 20 Aug 2021 01:23:30 +0800 Subject: [PATCH 2/8] Fix several IO issue --- FA2sp/Miscs/Hooks.SaveMap.cpp | 46 +++++++++++++++++++++++++++-------- 1 file changed, 36 insertions(+), 10 deletions(-) diff --git a/FA2sp/Miscs/Hooks.SaveMap.cpp b/FA2sp/Miscs/Hooks.SaveMap.cpp index 391ff8e..bac359d 100644 --- a/FA2sp/Miscs/Hooks.SaveMap.cpp +++ b/FA2sp/Miscs/Hooks.SaveMap.cpp @@ -18,6 +18,7 @@ DEFINE_HOOK(428D97, CFinalSunDlg_SaveMap, 7) { GET(INIClass*, pINI, EAX); GET_STACK(CFinalSunDlg*, pThis, STACK_OFFS(0x3F4, 0x36C)); + REF_STACK(ppmfc::CString, filepath, STACK_OFFS(0x3F4, -0x4)); LEA_STACK(ppmfc::CString*, pPath, STACK_OFFS(0x3F4, 0x360)); ppmfc::CString path = "TmpMap.map"; @@ -25,11 +26,11 @@ DEFINE_HOOK(428D97, CFinalSunDlg_SaveMap, 7) pThis->MyViewFrame.StatusBar.SetWindowText("Saving..."); pThis->MyViewFrame.StatusBar.UpdateWindow(); - DeleteFile(path); + DeleteFile(filepath); CloseHandle( - CreateFile(path, GENERIC_WRITE, NULL, nullptr, TRUNCATE_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN | FILE_ATTRIBUTE_NORMAL, NULL) + CreateFile(filepath, GENERIC_WRITE, NULL, nullptr, TRUNCATE_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN | FILE_ATTRIBUTE_NORMAL, NULL) ); - auto hFile = CreateFile(path, GENERIC_WRITE, NULL, nullptr, CREATE_ALWAYS, FILE_FLAG_SEQUENTIAL_SCAN | FILE_ATTRIBUTE_NORMAL, NULL); + auto hFile = CreateFile(filepath, GENERIC_WRITE, NULL, nullptr, CREATE_ALWAYS, FILE_FLAG_SEQUENTIAL_SCAN | FILE_ATTRIBUTE_NORMAL, NULL); std::stringstream ss; ss << @@ -74,6 +75,28 @@ DEFINE_HOOK(42B30F, CFinalSunDlg_SaveMap_SkipMapDTOR, 7) return ExtConfigs::SaveMap ? 0x42B323 : 0; } +DEFINE_HOOK(42B2AF, CFinalSunDlg_SaveMap_SkipDeleteFile, 7) +{ + return ExtConfigs::SaveMap ? 0x42B2C2 : 0; +} + +DEFINE_HOOK(42A8F5, CFinalSunDlg_SaveMap_ReplaceCopyFile, 7) +{ + if (!ExtConfigs::SaveMap) + return 0; + + REF_STACK(ppmfc::CString, filepath, STACK_OFFS(0x3F4, -0x4)); + + HANDLE hFile = + CreateFile(filepath, GENERIC_READ, NULL, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if (hFile != INVALID_HANDLE_VALUE) + { + CloseHandle(hFile); + return 0x42A92D; + } + return 0x42A911; +} + class SaveMapExt { private: @@ -111,8 +134,10 @@ class SaveMapExt std::map m; + ppmfc::CString buffer = GlobalVars::ExePath(); + buffer += "\\AutoSaves\\autosave-*.map"; WIN32_FIND_DATA Data; - auto hFindData = FindFirstFile("AutoSaves\\autosave-*.map", &Data); + auto hFindData = FindFirstFile(buffer, &Data); while (hFindData != INVALID_HANDLE_VALUE) { m[Data.ftLastWriteTime] = Data.cFileName; @@ -125,10 +150,9 @@ class SaveMapExt return; auto& itr = m.begin(); - ppmfc::CString buffer; while (count != 0) { - buffer.Format("AutoSaves\\%s", itr->second); + buffer.Format("%s\\AutoSaves\\%s", GlobalVars::ExePath(), itr->second); DeleteFile(buffer); ++itr; --count; @@ -147,17 +171,19 @@ class SaveMapExt SYSTEMTIME time; GetLocalTime(&time); - CreateDirectory("AutoSaves", nullptr); + ppmfc::CString buffer = GlobalVars::ExePath(); + buffer += "\\AutoSaves"; + CreateDirectory(buffer, nullptr); - ppmfc::CString path; - path.Format("AutoSaves\\autosave-%04d%02d%02d-%02d%02d%02d-%03d.map", + buffer.Format("%s\\AutoSaves\\autosave-%04d%02d%02d-%02d%02d%02d-%03d.map", + GlobalVars::ExePath(), time.wYear, time.wMonth, time.wDay, time.wHour, time.wMinute, time.wSecond, time.wMilliseconds ); IsAutoSaving = true; - GlobalVars::Dialogs::CFinalSunDlg->SaveMap(path); + GlobalVars::Dialogs::CFinalSunDlg->SaveMap(buffer); IsAutoSaving = false; RemoveEarlySaves(); From 029346f1f352d74f3559df651805e612e847061c Mon Sep 17 00:00:00 2001 From: secsome <302702960@qq.com> Date: Fri, 20 Aug 2021 11:08:23 +0800 Subject: [PATCH 3/8] Fix some stupid error --- FA2sp/Miscs/Hooks.SaveMap.cpp | 36 ++++++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/FA2sp/Miscs/Hooks.SaveMap.cpp b/FA2sp/Miscs/Hooks.SaveMap.cpp index bac359d..c8e949c 100644 --- a/FA2sp/Miscs/Hooks.SaveMap.cpp +++ b/FA2sp/Miscs/Hooks.SaveMap.cpp @@ -19,7 +19,6 @@ DEFINE_HOOK(428D97, CFinalSunDlg_SaveMap, 7) GET(INIClass*, pINI, EAX); GET_STACK(CFinalSunDlg*, pThis, STACK_OFFS(0x3F4, 0x36C)); REF_STACK(ppmfc::CString, filepath, STACK_OFFS(0x3F4, -0x4)); - LEA_STACK(ppmfc::CString*, pPath, STACK_OFFS(0x3F4, 0x360)); ppmfc::CString path = "TmpMap.map"; @@ -62,8 +61,6 @@ DEFINE_HOOK(428D97, CFinalSunDlg_SaveMap, 7) WriteFile(hFile, ss.str().c_str(), ss.str().length(), nullptr, nullptr); CloseHandle(hFile); - new(pPath) ppmfc::CString(path); - return 0x42A859; } @@ -97,6 +94,11 @@ DEFINE_HOOK(42A8F5, CFinalSunDlg_SaveMap_ReplaceCopyFile, 7) return 0x42A911; } +DEFINE_HOOK(42B2EA, CFinalSunDlg_SaveMap_SkipStringDTOR, C) +{ + return ExtConfigs::SaveMap ? 0x42B30F : 0; +} + class SaveMapExt { private: @@ -213,4 +215,32 @@ DEFINE_HOOK(427949, CFinalSunDlg_SaveMap_AutoSave_SkipDialog, A) DEFINE_HOOK(42B294, CFinalSunDlg_SaveMap_AutoSave_SkipEditFilesMenu, 8) { return SaveMapExt::IsAutoSaving ? 0x42B2AF : 0; +} + +DEFINE_HOOK(437D84, CFinalSunDlg_LoadMap_StopTimer, 5) +{ + if (ExtConfigs::SaveMap_AutoSave) + SaveMapExt::StopTimer(); + return 0; +} + +DEFINE_HOOK(438D90, CFinalSunDlg_LoadMap_ResetTimer, 7) +{ + if (ExtConfigs::SaveMap_AutoSave && GlobalVars::CMapData->MapWidthPlusHeight) + SaveMapExt::ResetTimer(); + return 0; +} + +DEFINE_HOOK(42CBF4, CFinalSunDlg_CreateMap_StopTimer, 7) +{ + if (ExtConfigs::SaveMap_AutoSave) + SaveMapExt::StopTimer(); + return 0; +} + +DEFINE_HOOK(42E18E, CFinalSunDlg_CreateMap_ResetTimer, 7) +{ + if (ExtConfigs::SaveMap_AutoSave && GlobalVars::CMapData->MapWidthPlusHeight) + SaveMapExt::ResetTimer(); + return 0; } \ No newline at end of file From b67d0e2dc513f2fbdb8fd7d78297d0cf8278ea70 Mon Sep 17 00:00:00 2001 From: secsome <302702960@qq.com> Date: Fri, 20 Aug 2021 13:04:44 +0800 Subject: [PATCH 4/8] Disable ExceptionHandler, Fix SaveMap on Newmap --- FA2sp/Miscs/Exception.cpp | 12 ++++++------ FA2sp/Miscs/Hooks.SaveMap.cpp | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/FA2sp/Miscs/Exception.cpp b/FA2sp/Miscs/Exception.cpp index 4dfc0cf..c47dae7 100644 --- a/FA2sp/Miscs/Exception.cpp +++ b/FA2sp/Miscs/Exception.cpp @@ -194,10 +194,10 @@ std::wstring Exception::FullDump( } //ifdef DUMP_EXTENSIVE -DEFINE_HOOK(434920, Exception_Handler, 7) -{ - //GET(int, code, ECX); - GET(LPEXCEPTION_POINTERS, pExs, EDX); - Exception::ExceptionHandler(pExs); -} +//DEFINE_HOOK(434920, Exception_Handler, 7) +//{ +// //GET(int, code, ECX); +// GET(LPEXCEPTION_POINTERS, pExs, EDX); +// Exception::ExceptionHandler(pExs); +//} //endif diff --git a/FA2sp/Miscs/Hooks.SaveMap.cpp b/FA2sp/Miscs/Hooks.SaveMap.cpp index c8e949c..7acee84 100644 --- a/FA2sp/Miscs/Hooks.SaveMap.cpp +++ b/FA2sp/Miscs/Hooks.SaveMap.cpp @@ -231,7 +231,7 @@ DEFINE_HOOK(438D90, CFinalSunDlg_LoadMap_ResetTimer, 7) return 0; } -DEFINE_HOOK(42CBF4, CFinalSunDlg_CreateMap_StopTimer, 7) +DEFINE_HOOK(42CBE0, CFinalSunDlg_CreateMap_StopTimer, 5) { if (ExtConfigs::SaveMap_AutoSave) SaveMapExt::StopTimer(); From 50bce3537fb72c6ff0fd41c7e2f9c27be2c4cd7c Mon Sep 17 00:00:00 2001 From: secsome <302702960@qq.com> Date: Fri, 20 Aug 2021 13:20:32 +0800 Subject: [PATCH 5/8] Skip useless iterating --- FA2sp/Miscs/Hooks.Performance.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/FA2sp/Miscs/Hooks.Performance.cpp b/FA2sp/Miscs/Hooks.Performance.cpp index da61c5e..45b3daa 100644 --- a/FA2sp/Miscs/Hooks.Performance.cpp +++ b/FA2sp/Miscs/Hooks.Performance.cpp @@ -8,6 +8,16 @@ #include "../FA2sp.h" +// This is useless +DEFINE_HOOK(47F94E, CLoading_InitPics_SkipBuildingTypeInit, 5) +{ + return 0x47FA2D; +} + + + + + class Performance { public: From 46a657c4a090a916465194aec136b25e3402d428 Mon Sep 17 00:00:00 2001 From: secsome <302702960@qq.com> Date: Fri, 20 Aug 2021 16:30:47 +0800 Subject: [PATCH 6/8] Implement clone AITrigger --- FA2pp | 2 +- FA2sp.vcxproj | 3 + FA2sp.vcxproj.filters | 9 +++ FA2sp/Ext/CAITriggerTypes/Body.cpp | 116 +++++++++++++++++++++++++++-- FA2sp/Ext/CAITriggerTypes/Body.h | 12 +-- FA2sp/Ext/FA2Expand.cpp | 1 + FA2sp/UI/CAITriggerTypes.rc | 51 +++++++++++++ README.md | 28 +++++++ 8 files changed, 208 insertions(+), 14 deletions(-) create mode 100644 FA2sp/UI/CAITriggerTypes.rc diff --git a/FA2pp b/FA2pp index a48db6d..94568cb 160000 --- a/FA2pp +++ b/FA2pp @@ -1 +1 @@ -Subproject commit a48db6d4c24678aa490cfa0316564f958a00f43e +Subproject commit 94568cbf175f54e019120ce370b867e03fee6c93 diff --git a/FA2sp.vcxproj b/FA2sp.vcxproj index e1bf014..bb49d49 100644 --- a/FA2sp.vcxproj +++ b/FA2sp.vcxproj @@ -123,6 +123,7 @@ + @@ -177,6 +178,7 @@ + @@ -214,6 +216,7 @@ + diff --git a/FA2sp.vcxproj.filters b/FA2sp.vcxproj.filters index a9fd12a..b993eb3 100644 --- a/FA2sp.vcxproj.filters +++ b/FA2sp.vcxproj.filters @@ -117,6 +117,9 @@ 头文件 + + 头文件 + @@ -278,6 +281,9 @@ 源文件 + + 源文件 + @@ -331,5 +337,8 @@ 资源文件 + + 资源文件 + \ No newline at end of file diff --git a/FA2sp/Ext/CAITriggerTypes/Body.cpp b/FA2sp/Ext/CAITriggerTypes/Body.cpp index 1fe8c6c..7836370 100644 --- a/FA2sp/Ext/CAITriggerTypes/Body.cpp +++ b/FA2sp/Ext/CAITriggerTypes/Body.cpp @@ -1,18 +1,120 @@ #include "Body.h" -CAITriggerTypes* CAITriggerTypesExt::Instance = nullptr; +#include +#include + +#include "../../Helpers/STDHelpers.h" +#include "../../Helpers/Translations.h" void CAITriggerTypesExt::ProgramStartupInit() { - RunTime::ResetMemoryContentAt(0x591B08, CAITriggerTypesExt::PreTranslateMessageExt); + RunTime::ResetMemoryContentAt(0x591B34, &CAITriggerTypesExt::OnInitDialogExt); + RunTime::ResetMemoryContentAt(0x591B08, &CAITriggerTypesExt::PreTranslateMessageExt); } -BOOL CAITriggerTypesExt::PreTranslateMessageExt(MSG* pMsg) +BOOL CAITriggerTypesExt::OnInitDialogExt() { - switch (pMsg->message) { + BOOL ret = this->CAITriggerTypes::OnInitDialog(); + if (!ret) + return FALSE; + + Translations::TranslateItem(this, "AITriggerTitle"); + Translations::TranslateItem(this, 50900, "AITriggerList"); + Translations::TranslateItem(this, 50901, "AITriggerName"); + Translations::TranslateItem(this, 50902, "AITriggerTeam1"); + Translations::TranslateItem(this, 50903, "AITriggerHouse"); + Translations::TranslateItem(this, 50904, "AITriggerTeam2"); + Translations::TranslateItem(this, 50905, "AITriggerTechlevel"); + Translations::TranslateItem(this, 50906, "AITriggerType"); + Translations::TranslateItem(this, 50907, "AITriggerWeight"); + Translations::TranslateItem(this, 50908, "AITriggerMinWeight"); + Translations::TranslateItem(this, 50909, "AITriggerMaxWeight"); + Translations::TranslateItem(this, 50910, "AITriggerMinDiff"); + Translations::TranslateItem(this, 50911, "AITriggerSide"); + Translations::TranslateItem(this, 50912, "AITriggerTechnoType"); + Translations::TranslateItem(this, 50913, "AITriggerCondition"); + Translations::TranslateItem(this, 50914, "AITriggerNumber"); + Translations::TranslateItem(this, 50915, "AITriggerAdditionalDesc"); + Translations::TranslateItem(this, 1210, "AITriggerData"); + + Translations::TranslateItem(this, 1218, "AITriggerEnabled"); + Translations::TranslateItem(this, 1154, "AITriggerAdd"); + Translations::TranslateItem(this, 1066, "AITriggerDel"); + Translations::TranslateItem(this, 1919, "AITriggerClo"); + Translations::TranslateItem(this, 1452, "AITriggerBaseDefense"); + Translations::TranslateItem(this, 1453, "AITriggerSkirmish"); + Translations::TranslateItem(this, 1424, "AITriggerEasy"); + Translations::TranslateItem(this, 1425, "AITriggerMedium"); + Translations::TranslateItem(this, 1426, "AITriggerHard"); - default: - break; + HWND hSides; + GetDlgItem(1456, &hSides); + while (::SendMessage(hSides, CB_DELETESTRING, 0, NULL) != CB_ERR); + + ::SendMessage(hSides, CB_ADDSTRING, NULL, (LPARAM)"0 - All"); + int i = 1; + if (auto sides = GlobalVars::INIFiles::FAData->GetSection("Sides")) + { + for (auto& itr : sides->EntitiesDictionary) + { + ppmfc::CString buffer; + buffer.Format("%d - %s", i++, itr.second); + ::SendMessage(hSides, CB_ADDSTRING, NULL, (LPARAM)buffer.m_pchData); + } } + + return TRUE; +} + +BOOL CAITriggerTypesExt::PreTranslateMessageExt(MSG* pMsg) +{ + switch (pMsg->message) + { + case WM_LBUTTONUP: + { + if (pMsg->hwnd == this->GetDlgItem(1919)->GetSafeHwnd()) + this->OnBNCloneAITriggerClicked(); + } + } + return this->FA2CDialog::PreTranslateMessage(pMsg); -} \ No newline at end of file +} + +void CAITriggerTypesExt::OnBNCloneAITriggerClicked() +{ + if (this->CCBAITriggerList.GetCount() > 0 && this->CCBAITriggerList.GetCurSel() != CB_ERR) + { + ppmfc::CString currentID; + this->CCBAITriggerList.GetWindowText(currentID); + STDHelpers::TrimIndex(currentID); + + ppmfc::CString key = INIClass::GetAvailableIndex(); + ppmfc::CString value, name; + + HWND hName; + GetDlgItem(1010, &hName); + auto nLen = ::GetWindowTextLength(hName); + auto pStr = new char[nLen + 1]; + ::GetWindowText(hName, pStr, nLen + 1); + name.Format("%s Clone", pStr); + delete[] pStr; + + value = name + ","; + auto& results = STDHelpers::SplitString(GlobalVars::INIFiles::CurrentDocument->GetString("AITriggerTypes", currentID)); + for (int i = 1; i < results.size() - 1; ++i) + value += (results[i] + ","); + value += results.back(); + + GlobalVars::INIFiles::CurrentDocument->WriteString("AITriggerTypes", key, value); + + GlobalVars::INIFiles::CurrentDocument->WriteString( + "AITriggerTypesEnable", key, + GlobalVars::INIFiles::CurrentDocument->GetString("AITriggerTypesEnable", currentID, "no") + ); + + int idx = this->CCBAITriggerList.AddString(key + " (" + name + ")"); + this->CCBAITriggerList.SetCurSel(idx); + + this->SetDlgItemText(1010, name); // update the name huh + } +} diff --git a/FA2sp/Ext/CAITriggerTypes/Body.h b/FA2sp/Ext/CAITriggerTypes/Body.h index 4d8f4b3..cdfc175 100644 --- a/FA2sp/Ext/CAITriggerTypes/Body.h +++ b/FA2sp/Ext/CAITriggerTypes/Body.h @@ -6,18 +6,18 @@ class NOVTABLE CAITriggerTypesExt : public CAITriggerTypes { public: - typedef BOOL(*FuncT_PTM)(MSG* pMsg); - - static CAITriggerTypes* Instance; + static void ProgramStartupInit(); - //hook function to replace in virtual function map + // + // Ext Functions + // + BOOL OnInitDialogExt(); BOOL PreTranslateMessageExt(MSG* pMsg); - static void ProgramStartupInit(); - CAITriggerTypesExt() {}; ~CAITriggerTypesExt() {}; + void OnBNCloneAITriggerClicked(); private: }; \ No newline at end of file diff --git a/FA2sp/Ext/FA2Expand.cpp b/FA2sp/Ext/FA2Expand.cpp index 9bb6e9d..9f1f13a 100644 --- a/FA2sp/Ext/FA2Expand.cpp +++ b/FA2sp/Ext/FA2Expand.cpp @@ -52,6 +52,7 @@ void __stdcall FA2Expand::ExeRun() { + CAITriggerTypesExt::ProgramStartupInit(); CFinalSunDlgExt::ProgramStartupInit(); CHousesExt::ProgramStartupInit(); // CIsoViewExt::ProgramStartupInit(); diff --git a/FA2sp/UI/CAITriggerTypes.rc b/FA2sp/UI/CAITriggerTypes.rc new file mode 100644 index 0000000..bafaabf --- /dev/null +++ b/FA2sp/UI/CAITriggerTypes.rc @@ -0,0 +1,51 @@ +#include + +205 DIALOG 0, 0, 303, 234 +STYLE DS_SETFONT | DS_MODALFRAME | WS_CAPTION | WS_SYSMENU +CAPTION "AI Trigger Types" +LANGUAGE LANG_GERMAN, SUBLANG_GERMAN +FONT 8, "Tahoma" +{ + CONTROL "AI Trigger:", 50900, STATIC, SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 7, 7, 52, 16 + CONTROL "", 1199, COMBOBOX, CBS_DROPDOWNLIST | CBS_SORT | WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_TABSTOP, 60, 7, 236, 307 + CONTROL "Name:", 50901, STATIC, SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 7, 63, 43, 11 + CONTROL "", 1010, EDIT, ES_LEFT | ES_AUTOHSCROLL | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 60, 64, 94, 13 + CONTROL "Teamtype #1:", 50902, STATIC, SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 7, 80, 43, 17 + CONTROL "", 1204, COMBOBOX, CBS_DROPDOWN | CBS_SORT | WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_TABSTOP, 60, 81, 236, 81 + CONTROL "House:", 50903, STATIC, SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 165, 64, 50, 16 + CONTROL "", 1205, COMBOBOX, CBS_DROPDOWN | WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_TABSTOP, 220, 64, 76, 207 + CONTROL "Teamtype #2:", 50904, STATIC, SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 7, 98, 43, 17 + CONTROL "", 1206, COMBOBOX, CBS_DROPDOWN | CBS_SORT | WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_TABSTOP, 60, 98, 235, 81 + CONTROL "Techlevel:", 50905, STATIC, SS_LEFT | WS_CHILD | WS_GROUP, 280, 206, 0, 0 + CONTROL "", 1162, COMBOBOX, CBS_DROPDOWN | WS_CHILD | WS_VSCROLL | WS_TABSTOP, 288, 222, 0, 0 + CONTROL "Type:", 50906, STATIC, SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 6, 44, 53, 17 + CONTROL "", 1163, COMBOBOX, CBS_DROPDOWNLIST | WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_TABSTOP, 60, 45, 235, 71 + CONTROL "Data:", 1210, STATIC, SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 265, 204, 0, 0 + CONTROL "", 1211, COMBOBOX, CBS_DROPDOWN | CBS_AUTOHSCROLL | WS_CHILD | WS_VSCROLL | WS_TABSTOP, 287, 222, 0, 0 + CONTROL "Weight:", 50907, STATIC, SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 6, 150, 33, 11 + CONTROL "", 1213, EDIT, ES_LEFT | ES_AUTOHSCROLL | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 59, 148, 56, 13 + CONTROL "MinWeight:", 50908, STATIC, SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 6, 165, 38, 11 + CONTROL "", 1215, EDIT, ES_LEFT | ES_AUTOHSCROLL | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 59, 164, 56, 13 + CONTROL "MaxWeight:", 50909, STATIC, SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 125, 165, 40, 11 + CONTROL "", 1216, EDIT, ES_LEFT | ES_AUTOHSCROLL | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 180, 164, 54, 13 + CONTROL "MinDiff:", 50910, STATIC, SS_LEFT | WS_CHILD | WS_GROUP, 279, 222, 0, 0 + CONTROL "", 1165, EDIT, ES_LEFT | ES_AUTOHSCROLL | WS_CHILD | WS_BORDER | WS_TABSTOP, 291, 222, 0, 0 + CONTROL "Multi-Side:", 50911, STATIC, SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 7, 115, 33, 12 + CONTROL "Delete", 1066, BUTTON, BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 240, 23, 53, 15 + CONTROL "Add", 1154, BUTTON, BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 121, 23, 53, 15 + CONTROL "Clone", 1919, BUTTON, BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 181, 23, 53, 15 + CONTROL "Enabled", 1218, BUTTON, BS_AUTOCHECKBOX | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 60, 23, 76, 11 + CONTROL "Easy", 1424, BUTTON, BS_AUTOCHECKBOX | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 59, 133, 42, 13 + CONTROL "Medium", 1425, BUTTON, BS_AUTOCHECKBOX | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 124, 132, 42, 13 + CONTROL "Hard", 1426, BUTTON, BS_AUTOCHECKBOX | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 199, 132, 42, 13 + CONTROL "Base defense", 1452, BUTTON, BS_AUTOCHECKBOX | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 124, 116, 67, 13 + CONTROL "Available in Skirmish", 1453, BUTTON, BS_AUTOCHECKBOX | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 199, 116, 85, 14 + CONTROL "", 1456, COMBOBOX, CBS_DROPDOWN | WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_TABSTOP, 60, 116, 56, 63 + CONTROL "Unittype (X):", 50912, STATIC, SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 171, 200, 51, 10 + CONTROL "", 1149, COMBOBOX, CBS_DROPDOWN | WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_TABSTOP, 171, 212, 125, 255 + CONTROL "Condition:", 50913, STATIC, SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 8, 200, 50, 11 + CONTROL "", 1449, COMBOBOX, CBS_DROPDOWNLIST | WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_TABSTOP, 8, 212, 95, 82 + CONTROL "", 1450, EDIT, ES_LEFT | ES_AUTOHSCROLL | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 109, 212, 54, 13 + CONTROL "Number (N):", 50914, STATIC, SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 110, 200, 56, 11 + CONTROL "Additional parameters for the appropiate AI Trigger Types:", 50915, STATIC, SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 6, 188, 295, 12 +} \ No newline at end of file diff --git a/README.md b/README.md index 856ec63..772fc9a 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,7 @@ Compile Using C++ Standard Now: C++14 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\\\\\//////////////////////////////////////\\\\\~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ======================= Changes (2021-08-XX) ============================================================================================== ++) Now you can copy AITriggers +) New ExtConfig: SaveMap = BOOLEAN, enable it so that we will replace FA2's vanilla slow saving function +) New ExtConfig: SaveMap.AutoSave = BOOLEAN, enable it so that we will enable FA2 to save map automatically after one save +) New ExtConfig: SaveMap.AutoSave.Interval = INTEGER, set the interval between two auto saving, need to be greater than or equal to than 30 @@ -444,6 +445,33 @@ COLORREF - R,G,B each of them is in [0,255] +) Menu.Layers.Smudges = TEXT +) Menu.Layers.Tubes = TEXT +) Menu.Layers.Bounds = TEXT + +) AITriggerTitle = TEXT + +) AITriggerList = TEXT + +) AITriggerName = TEXT + +) AITriggerTeam1 = TEXT + +) AITriggerHouse = TEXT + +) AITriggerTeam2 = TEXT + +) AITriggerTechlevel = TEXT + +) AITriggerType = TEXT + +) AITriggerWeight = TEXT + +) AITriggerMinWeight = TEXT + +) AITriggerMaxWeight = TEXT + +) AITriggerMinDiff = TEXT + +) AITriggerSide = TEXT + +) AITriggerTechnoType = TEXT + +) AITriggerCondition = TEXT + +) AITriggerNumber = TEXT + +) AITriggerAdditionalDesc = TEXT + +) AITriggerData = TEXT + +) AITriggerEnabled = TEXT + +) AITriggerAdd = TEXT + +) AITriggerDel = TEXT + +) AITriggerClo = TEXT + +) AITriggerBaseDefense = TEXT + +) AITriggerSkirmish = TEXT + +) AITriggerEasy = TEXT + +) AITriggerMedium = TEXT + +) AITriggerHard = TEXT +) TaskforceTitle = TEXT +) TaskforceList = TEXT +) TaskforceUnits = TEXT From 5b7cd1789c384380a2fd0a7e1f3e8b29b1be0779 Mon Sep 17 00:00:00 2001 From: secsome <302702960@qq.com> Date: Fri, 20 Aug 2021 17:09:49 +0800 Subject: [PATCH 7/8] minor adjustments --- FA2sp/Miscs/Hooks.Performance.cpp | 10 ---------- FA2sp/Miscs/Hooks.SaveMap.cpp | 23 ++++++++++++----------- 2 files changed, 12 insertions(+), 21 deletions(-) diff --git a/FA2sp/Miscs/Hooks.Performance.cpp b/FA2sp/Miscs/Hooks.Performance.cpp index 45b3daa..da61c5e 100644 --- a/FA2sp/Miscs/Hooks.Performance.cpp +++ b/FA2sp/Miscs/Hooks.Performance.cpp @@ -8,16 +8,6 @@ #include "../FA2sp.h" -// This is useless -DEFINE_HOOK(47F94E, CLoading_InitPics_SkipBuildingTypeInit, 5) -{ - return 0x47FA2D; -} - - - - - class Performance { public: diff --git a/FA2sp/Miscs/Hooks.SaveMap.cpp b/FA2sp/Miscs/Hooks.SaveMap.cpp index 7acee84..ce3fb4c 100644 --- a/FA2sp/Miscs/Hooks.SaveMap.cpp +++ b/FA2sp/Miscs/Hooks.SaveMap.cpp @@ -20,12 +20,9 @@ DEFINE_HOOK(428D97, CFinalSunDlg_SaveMap, 7) GET_STACK(CFinalSunDlg*, pThis, STACK_OFFS(0x3F4, 0x36C)); REF_STACK(ppmfc::CString, filepath, STACK_OFFS(0x3F4, -0x4)); - ppmfc::CString path = "TmpMap.map"; - pThis->MyViewFrame.StatusBar.SetWindowText("Saving..."); pThis->MyViewFrame.StatusBar.UpdateWindow(); - DeleteFile(filepath); CloseHandle( CreateFile(filepath, GENERIC_WRITE, NULL, nullptr, TRUNCATE_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN | FILE_ATTRIBUTE_NORMAL, NULL) ); @@ -105,14 +102,17 @@ class SaveMapExt static UINT_PTR Timer; public: static bool IsAutoSaving; + static ppmfc::CString FileName; static void ResetTimer() { StopTimer(); if (ExtConfigs::SaveMap_AutoSave_Interval >= 30) { - Timer = SetTimer(GlobalVars::Dialogs::CFinalSunDlg->m_hWnd, - NULL, 1000 * ExtConfigs::SaveMap_AutoSave_Interval, SaveMapCallback); + if (Timer = SetTimer(NULL, NULL, 1000 * ExtConfigs::SaveMap_AutoSave_Interval, SaveMapCallback)) + Logger::Debug("Successfully created timer with ID = %p\n", Timer); + else + Logger::Debug("Failed to create timer! Auto-save is currently unable to use"); } } @@ -120,7 +120,7 @@ class SaveMapExt { if (Timer != NULL) { - KillTimer(GlobalVars::Dialogs::CFinalSunDlg->m_hWnd, Timer); + KillTimer(NULL, Timer); Timer = NULL; } } @@ -148,7 +148,7 @@ class SaveMapExt } int count = m.size() - ExtConfigs::SaveMap_AutoSave_MaxCount; - if (count <= 0) + if (count <= 0) return; auto& itr = m.begin(); @@ -177,13 +177,13 @@ class SaveMapExt buffer += "\\AutoSaves"; CreateDirectory(buffer, nullptr); - buffer.Format("%s\\AutoSaves\\autosave-%04d%02d%02d-%02d%02d%02d-%03d.map", + buffer.Format("%s\\AutoSaves\\autosave-%04d%02d%02d-%02d%02d%02d-%03d.map", GlobalVars::ExePath(), - time.wYear, time.wMonth, time.wDay, - time.wHour, time.wMinute, time.wSecond, + time.wYear, time.wMonth, time.wDay, + time.wHour, time.wMinute, time.wSecond, time.wMilliseconds ); - + IsAutoSaving = true; GlobalVars::Dialogs::CFinalSunDlg->SaveMap(buffer); IsAutoSaving = false; @@ -195,6 +195,7 @@ class SaveMapExt bool SaveMapExt::IsAutoSaving = false; UINT_PTR SaveMapExt::Timer = NULL; + DEFINE_HOOK(426E50, CFinalSunDlg_SaveMap_AutoSave_StopTimer, 7) { SaveMapExt::StopTimer(); From 5d59368d926ece842bc1451a807ed951e54fca55 Mon Sep 17 00:00:00 2001 From: secsome <302702960@qq.com> Date: Fri, 20 Aug 2021 19:06:00 +0800 Subject: [PATCH 8/8] BUMP version MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 还有随便写写 --- FA2sp/FA2sp.Constants.h | 6 +++--- README.md | 45 +++++++++++++++++++++++++++++++---------- 2 files changed, 37 insertions(+), 14 deletions(-) diff --git a/FA2sp/FA2sp.Constants.h b/FA2sp/FA2sp.Constants.h index 54139a5..df35fed 100644 --- a/FA2sp/FA2sp.Constants.h +++ b/FA2sp/FA2sp.Constants.h @@ -3,12 +3,12 @@ constexpr int PRODUCT_MAJOR = 1; constexpr int PRODUCT_MINOR = 0; constexpr int PRODUCT_REVISION = 3; -constexpr char* PRODUCT_STR = "1.0.3"; +constexpr char* PRODUCT_STR = "1.0.4"; constexpr char* DISPLAY_STR = PRODUCT_STR; -constexpr char* VERSION_STRVER = "FA2sp 1.0.3"; +constexpr char* VERSION_STRVER = "FA2sp 1.0.4"; constexpr char* PRODUCT_NAME = "FA2sp"; -constexpr char* APPLY_INFO = "Found Final Alert 2 version 1.02. Applying FA2sp 1.0.3."; +constexpr char* APPLY_INFO = "Found Final Alert 2 version 1.02. Applying FA2sp 1.0.4."; // constexpr char* APPLY_INFO = "Found Final Alert 2 version 1.02. Applying FA2sp - " __DATE__ " - " __TIME__; constexpr char* MUTEX_HASH_VAL = "b8097bca8590a4f46c975ebb43503aab2243ce7f1c87f12f7984dbe1"; diff --git a/README.md b/README.md index 772fc9a..29a6359 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ Compile Using C++ Standard Now: C++14 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~////////// FINALALERT2 - SP CHANGELOG //////////~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\\\\\//////////////////////////////////////\\\\\~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -======================= Changes (2021-08-XX) ============================================================================================== +======================= Changes (2021-08-20 RELEASE 1.0.4) ============================================================================================== +) Now you can copy AITriggers +) New ExtConfig: SaveMap = BOOLEAN, enable it so that we will replace FA2's vanilla slow saving function +) New ExtConfig: SaveMap.AutoSave = BOOLEAN, enable it so that we will enable FA2 to save map automatically after one save @@ -578,11 +578,6 @@ COLORREF - R,G,B each of them is in [0,255] +) ScriptTypesMoveUp = TEXT +) ScriptTypesMoveDown = TEXT -- WORK IN PROGRESS - - Support for taskforces & ai triggers - - Custom palettes - - ... - - WRITE IN THE END This project was developed after FA2Copy with still many bugs to fix, then Zero Fanker advised to use inline hooks instead of Win32API message hooks to implement @@ -602,9 +597,37 @@ tomsons26 has made great assistance on disassembing it(REALLY HELPFUL). thomassneddon provided me with vxl drawing lib and drawing stuff assistence, without I cannot draw the VXL stuffs. (btw the code of FinalAlert 2 is really in a MESSY! Full of unnecessary constructors. I HATE IT!) - -- CONTACT ME -EMAIL : 3179369262@qq.com -Discord : secsome#5043 -NO OTHER AVAILABLE METHODS ... FOR NOW ;D + +Ŀ20202¿ʼʱFA2CopyΪѾܹFA2ܸһЩ +ʱҲ뵽ԼĿĽйѧôĶ׿FA2PPѾΪĿд4wд롣 +FA2Copyڵ56ӭһ汾ʱҷFA2Copyԭʵdz򵥣ûа취ʵָҪĹˡ +ʱZFңҽ˻SyringeչȻҲʹˣ722ſʼFA2+Ľ֮á +Ŀ֮ԽFA2spԭѾ벻ˣKerb˵secsome's patchҾûͦеģҲ޷ +һʼҲһһϲͨСףԼմOIҲǵһνӴĿһʼĴ·ԣɲ鿴FA2Copyȫҳһ硣 +ҲһĿļܹܹдԼҿĹȥĴˣҲһ + +ڿʱƿCINI࣬FA2ΪõSTLmapһչֱӾ͸ҸſˡһʼҲ͵AlexBINIãҲҪл +˽ɫ޸ҲġǰʱǰƣҾȥһVC5VC5mapֱӰ˳ʱһһضŴһ +ıȽϣһİѺҳӦȥ + +ٺҲûʲô˵ˣӡ̵ľǵһԼFA2ͼݴ洢ࣨDrawing.hеImageDataClassϡǵԼһ +صһذÿԱ;ڿ˵顣 + +Ҫ˵Լʲôܣֱ۵ľԼдľдˡFA2ĺܶ붼ʺɽǶmapO(n^2)ʻǷŵ߰ĽݣҿʱỳԼ +DzǿȷĴˣҪԼ⻹ʲôʵԣFA2ҲһϹĹߣҲûпǵ20һһ +ľͼԭYRRA2˵ĹѾ´࣬һЩʺɽҲ̫Ӱ졣ǵҶõʱҾһҪǵдʱһҪ +ԼдЧʾΡ + +̸̸FA2Ļͼ⣬FA2Ļͼڵһζȡijزĵʱлģֻ֮ǽڴȡbltȥˡ˼·ڿȻһܺõ˼·Ч +ؿFA2ڴռãRSҷһ֮ڹ滻FA2ĽؾߣȾԼζĻơdzӣ +֮ǰҲΪԭ;ˡʵֻһڵʱʵһͦȵģҲҪ͵èĻͼ⣬ԼÿһVXLSE139 +賿ĵ㡣û͵èĿһVXLĻƣͼֻ֧᲻֮ + +ڿиҰкܶ࣬ԱȻӳ汾BUGǹͬŬFA2øӺࡣﲻһһлˡ + +ĿԺҲ£ֻFA2spĵ߼BUG޸ˣĶΪ +ΪһԴĿȻҲӭʵĿPR棬ҪidbҲϵңҲṩ϶ܶBUGˣ + +ijͣ д2021/08/2019:031.0.4汾ǰϦ +||дӢ̫鷳ˣİ|| \ No newline at end of file