1
0

generic text 有序 dump

增加文本 hook 测试 (beta版用)
This commit is contained in:
chinosk 2024-05-27 21:41:57 +08:00
parent 3665ae851a
commit c5fd80daa2
No known key found for this signature in database
GPG Key ID: 00610B08C1BF7BE9
7 changed files with 79 additions and 9 deletions

View File

@ -226,8 +226,13 @@ namespace GakumasLocal::HookMain {
return; return;
} }
Local::DumpI18nItem(key->ToString(), value->ToString()); Local::DumpI18nItem(key->ToString(), value->ToString());
if (Config::textTest) {
I18nHelper_SetValue_Orig(_this, key, Il2cppString::New("[I18]" + value->ToString()));
}
else {
I18nHelper_SetValue_Orig(_this, key, value); I18nHelper_SetValue_Orig(_this, key, value);
} }
}
void* fontCache = nullptr; void* fontCache = nullptr;
void* GetReplaceFont() { void* GetReplaceFont() {
@ -286,8 +291,12 @@ namespace GakumasLocal::HookMain {
return TMP_Text_set_text_Orig(_this, UnityResolve::UnityType::String::New(transText)); return TMP_Text_set_text_Orig(_this, UnityResolve::UnityType::String::New(transText));
} }
// TMP_Text_set_text_Orig(_this, UnityResolve::UnityType::String::New("[TS]" + text->ToString())); if (Config::textTest) {
TMP_Text_set_text_Orig(_this, UnityResolve::UnityType::String::New("[TS]" + text->ToString()));
}
else {
TMP_Text_set_text_Orig(_this, text); TMP_Text_set_text_Orig(_this, text);
}
static auto set_font = Il2cppUtils::GetMethod("Unity.TextMeshPro.dll", static auto set_font = Il2cppUtils::GetMethod("Unity.TextMeshPro.dll",
"TMPro", "TMP_Text", "set_font"); "TMPro", "TMP_Text", "set_font");
@ -308,16 +317,21 @@ namespace GakumasLocal::HookMain {
//Log::InfoFmt("TextMeshProUGUI_Awake: %s", currText->ToString().c_str()); //Log::InfoFmt("TextMeshProUGUI_Awake: %s", currText->ToString().c_str());
std::string transText; std::string transText;
if (Local::GetGenericText(currText->ToString(), &transText)) { if (Local::GetGenericText(currText->ToString(), &transText)) {
if (Config::textTest) {
TMP_Text_set_text_Orig(_this, UnityResolve::UnityType::String::New("[TA]" + transText));
}
else {
TMP_Text_set_text_Orig(_this, UnityResolve::UnityType::String::New(transText)); TMP_Text_set_text_Orig(_this, UnityResolve::UnityType::String::New(transText));
} }
} }
}
// set_font->Invoke<void>(_this, font); // set_font->Invoke<void>(_this, font);
UpdateFont(_this); UpdateFont(_this);
TextMeshProUGUI_Awake_Orig(_this, method); TextMeshProUGUI_Awake_Orig(_this, method);
} }
// TODO 文本未hook完整 思路从tips下手... // TODO 文本未hook完整
DEFINE_HOOK(void, TextField_set_value, (void* _this, Il2cppString* value)) { DEFINE_HOOK(void, TextField_set_value, (void* _this, Il2cppString* value)) {
Log::DebugFmt("TextField_set_value: %s", value->ToString().c_str()); Log::DebugFmt("TextField_set_value: %s", value->ToString().c_str());
TextField_set_value_Orig(_this, value); TextField_set_value_Orig(_this, value);
@ -326,7 +340,6 @@ namespace GakumasLocal::HookMain {
DEFINE_HOOK(Il2cppString*, OctoCaching_GetResourceFileName, (void* data, void* method)) { DEFINE_HOOK(Il2cppString*, OctoCaching_GetResourceFileName, (void* data, void* method)) {
auto ret = OctoCaching_GetResourceFileName_Orig(data, method); auto ret = OctoCaching_GetResourceFileName_Orig(data, method);
//Log::DebugFmt("OctoCaching_GetResourceFileName: %s", ret->ToString().c_str()); //Log::DebugFmt("OctoCaching_GetResourceFileName: %s", ret->ToString().c_str());
return ret; return ret;
} }

View File

@ -14,7 +14,7 @@ namespace GakumasLocal::Local {
std::unordered_map<std::string, std::string> i18nData{}; std::unordered_map<std::string, std::string> i18nData{};
std::unordered_map<std::string, std::string> i18nDumpData{}; std::unordered_map<std::string, std::string> i18nDumpData{};
std::unordered_map<std::string, std::string> genericText{}; std::unordered_map<std::string, std::string> genericText{};
std::unordered_map<std::string, std::string> genericTextDumpData{}; std::vector<std::string> genericTextDumpData{};
std::unordered_set<std::string> translatedText{}; std::unordered_set<std::string> translatedText{};
std::filesystem::path GetBasePath() { std::filesystem::path GetBasePath() {
@ -76,6 +76,36 @@ namespace GakumasLocal::Local {
} }
} }
void DumpVectorDataToJson(const std::filesystem::path& dumpBasePath, const std::filesystem::path& fileName,
const std::vector<std::string>& vec) {
const auto dumpFilePath = dumpBasePath / fileName;
try {
if (!is_directory(dumpBasePath)) {
std::filesystem::create_directories(dumpBasePath);
}
if (!std::filesystem::exists(dumpFilePath)) {
std::ofstream dumpWriteLrcFile(dumpFilePath, std::ofstream::out);
dumpWriteLrcFile << "{}";
dumpWriteLrcFile.close();
}
std::ifstream dumpLrcFile(dumpFilePath);
std::string fileContent((std::istreambuf_iterator<char>(dumpLrcFile)), std::istreambuf_iterator<char>());
dumpLrcFile.close();
auto fileData = nlohmann::ordered_json::parse(fileContent);
for (const auto& i : vec) {
fileData[i] = i;
}
const auto newStr = fileData.dump(4, 32, false);
std::ofstream dumpWriteLrcFile(dumpFilePath, std::ofstream::out);
dumpWriteLrcFile << newStr.c_str();
dumpWriteLrcFile.close();
}
catch (std::exception& e) {
Log::ErrorFmt("DumpVectorDataToJson %s failed: %s", dumpFilePath.c_str(), e.what());
}
}
void LoadData() { void LoadData() {
static auto localizationFile = GetBasePath() / "local-files" / "localization.json"; static auto localizationFile = GetBasePath() / "local-files" / "localization.json";
static auto genericFile = GetBasePath() / "local-files" / "generic.json"; static auto genericFile = GetBasePath() / "local-files" / "generic.json";
@ -155,14 +185,18 @@ namespace GakumasLocal::Local {
if (translatedText.contains(origText)) return false; if (translatedText.contains(origText)) return false;
genericTextDumpData.emplace(origText, origText); if (std::find(genericTextDumpData.begin(), genericTextDumpData.end(), "") != genericTextDumpData.end()) {
return false;
}
genericTextDumpData.push_back(origText);
static auto dumpBasePath = GetBasePath() / "dump-files"; static auto dumpBasePath = GetBasePath() / "dump-files";
if (inDumpGeneric) return false; if (inDumpGeneric) return false;
inDumpGeneric = true; inDumpGeneric = true;
std::thread([](){ std::thread([](){
std::this_thread::sleep_for(std::chrono::seconds(5)); std::this_thread::sleep_for(std::chrono::seconds(5));
DumpMapDataToJson(dumpBasePath, "generic.json", genericTextDumpData); DumpVectorDataToJson(dumpBasePath, "generic.json", genericTextDumpData);
genericTextDumpData.clear(); genericTextDumpData.clear();
inDumpGeneric = false; inDumpGeneric = false;
}).detach(); }).detach();

View File

@ -6,6 +6,7 @@ namespace GakumasLocal::Config {
bool isConfigInit = false; bool isConfigInit = false;
bool enabled = true; bool enabled = true;
bool textTest = false;
bool enableFreeCamera = false; bool enableFreeCamera = false;
int targetFrameRate = 0; int targetFrameRate = 0;
bool unlockAllLive = false; bool unlockAllLive = false;
@ -29,6 +30,7 @@ namespace GakumasLocal::Config {
#define GetConfigItem(name) if (config.contains(#name)) name = config[#name] #define GetConfigItem(name) if (config.contains(#name)) name = config[#name]
GetConfigItem(enabled); GetConfigItem(enabled);
GetConfigItem(textTest);
GetConfigItem(targetFrameRate); GetConfigItem(targetFrameRate);
GetConfigItem(enableFreeCamera); GetConfigItem(enableFreeCamera);
GetConfigItem(unlockAllLive); GetConfigItem(unlockAllLive);

View File

@ -6,6 +6,7 @@ namespace GakumasLocal::Config {
extern bool isConfigInit; extern bool isConfigInit;
extern bool enabled; extern bool enabled;
extern bool textTest;
extern bool enableFreeCamera; extern bool enableFreeCamera;
extern int targetFrameRate; extern int targetFrameRate;
extern bool unlockAllLive; extern bool unlockAllLive;

View File

@ -20,6 +20,7 @@ import java.io.File
interface ConfigListener { interface ConfigListener {
fun onClickStartGame() fun onClickStartGame()
fun onEnabledChanged(value: Boolean) fun onEnabledChanged(value: Boolean)
fun onTextTestChanged(value: Boolean)
fun onEnableFreeCameraChanged(value: Boolean) fun onEnableFreeCameraChanged(value: Boolean)
fun onTargetFpsChanged(s: CharSequence, start: Int, before: Int, count: Int) fun onTargetFpsChanged(s: CharSequence, start: Int, before: Int, count: Int)
fun onUnlockAllLiveChanged(value: Boolean) fun onUnlockAllLiveChanged(value: Boolean)
@ -92,6 +93,11 @@ class MainActivity : AppCompatActivity(), ConfigListener {
saveConfig() saveConfig()
} }
override fun onTextTestChanged(value: Boolean) {
binding.config!!.textTest = value
saveConfig()
}
override fun onEnableFreeCameraChanged(value: Boolean) { override fun onEnableFreeCameraChanged(value: Boolean) {
binding.config!!.enableFreeCamera = value binding.config!!.enableFreeCamera = value
saveConfig() saveConfig()

View File

@ -4,6 +4,7 @@ import androidx.databinding.BaseObservable
data class GakumasConfig ( data class GakumasConfig (
var enabled: Boolean = true, var enabled: Boolean = true,
var textTest: Boolean = false,
var enableFreeCamera: Boolean = false, var enableFreeCamera: Boolean = false,
var targetFrameRate: Int = 0, var targetFrameRate: Int = 0,
var unlockAllLive: Boolean = false, var unlockAllLive: Boolean = false,

View File

@ -64,6 +64,19 @@
android:text="@string/enable_plugin" /> android:text="@string/enable_plugin" />
</TableRow> </TableRow>
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.switchmaterial.SwitchMaterial
android:id="@+id/textTestMode"
android:layout_width="match_parent"
android:layout_height="48dp"
android:checked="@={config.textTest}"
android:onCheckedChanged="@{(view, value) -> listener.onTextTestChanged(value)}"
android:text="文本 hook 测试模式" />
</TableRow>
<TableRow <TableRow
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">