This commit is contained in:
恍兮惚兮 2024-11-06 21:39:52 +08:00
parent b13bcdc5aa
commit 810f333770
12 changed files with 457 additions and 373 deletions

View File

@ -221,7 +221,7 @@ bool adobelair3()
hp.filter_fun = [](TextBuffer *buffer, HookParam *hp) hp.filter_fun = [](TextBuffer *buffer, HookParam *hp)
{ {
// 若当前还有5个字符则这个句子会显示5次然后substr(1,len-1)直到结束总共显示5+4+3+2+1次 // 若当前还有5个字符则这个句子会显示5次然后substr(1,len-1)直到结束总共显示5+4+3+2+1次
auto ws = StringToWideString(buffer->strA()); auto ws = StringToWideString(buffer->viewA());
static int leng = 0; static int leng = 0;
if (ws.length() <= leng) if (ws.length() <= leng)
{ {

View File

@ -55,7 +55,7 @@ namespace
{ {
StringFilter(buffer, "@1r", 3); StringFilter(buffer, "@1r", 3);
StringFilter(buffer, "@-1r", 4); StringFilter(buffer, "@-1r", 4);
if (!StringToWideString(buffer->strA(), 932).has_value()) if (!StringToWideString(buffer->viewA(), 932).has_value())
buffer->clear(); buffer->clear();
}; };
return NewHook(hp, "Aksys"); return NewHook(hp, "Aksys");

View File

@ -615,7 +615,7 @@ namespace
auto arg = (HookArgument *)s->stack[0]; // arg1 auto arg = (HookArgument *)s->stack[0]; // arg1
if (arg && arg->isValid()) if (arg && arg->isValid())
{ // && (quint8)arg->text[0] > 127) { // skip translate text beginning with ascii character { // && (quint8)arg->text[0] > 127) { // skip translate text beginning with ascii character
std::wstring oldText = StringToWideString(std::string(arg->text, arg->size), CP_UTF8).value(), // QString::fromUtf8(arg->text, arg->size), std::wstring oldText = StringToWideString(std::string_view(arg->text, arg->size), CP_UTF8).value(), // QString::fromUtf8(arg->text, arg->size),
prefix, prefix,
suffix, suffix,
trimmedText = trim(oldText, &prefix, &suffix); trimmedText = trim(oldText, &prefix, &suffix);
@ -664,7 +664,7 @@ namespace
auto arg = (HookArgument *)s->stack[0]; // arg1 auto arg = (HookArgument *)s->stack[0]; // arg1
if (arg && arg->isValid()) if (arg && arg->isValid())
{ // && (quint8)arg->text[0] > 127) { // skip translate text beginning with ascii character { // && (quint8)arg->text[0] > 127) { // skip translate text beginning with ascii character
std::wstring oldText = StringToWideString(std::string(arg->text, arg->size), CP_UTF8).value(), // QString::fromUtf8(arg->text, arg->size), std::wstring oldText = StringToWideString(std::string_view(arg->text, arg->size), CP_UTF8).value(), // QString::fromUtf8(arg->text, arg->size),
prefix, prefix,
suffix, suffix,
trimmedText = trim(oldText, &prefix, &suffix); trimmedText = trim(oldText, &prefix, &suffix);
@ -763,7 +763,7 @@ namespace
auto arg = (HookArgument *)s->stack[2]; // arg2 auto arg = (HookArgument *)s->stack[2]; // arg2
if (arg->isValid()) if (arg->isValid())
{ {
auto oldText = StringToWideString(std::string(arg->text), CP_UTF8).value(); auto oldText = StringToWideString(std::string_view(arg->text), CP_UTF8).value();
auto split = s->stack[0]; // return address auto split = s->stack[0]; // return address
buffer->from(oldText); buffer->from(oldText);
// std::wstring newText = EngineController::instance()->dispatchTextWSTD(oldText, role, sig); // std::wstring newText = EngineController::instance()->dispatchTextWSTD(oldText, role, sig);
@ -780,7 +780,7 @@ namespace
auto arg = (HookArgument *)s->stack[2]; // arg2 auto arg = (HookArgument *)s->stack[2]; // arg2
if (arg->isValid()) if (arg->isValid())
{ {
auto oldText = StringToWideString(std::string(arg->text), CP_UTF8).value(); auto oldText = StringToWideString(std::string_view(arg->text), CP_UTF8).value();
auto split = s->stack[0]; // return address auto split = s->stack[0]; // return address
std::wstring old = oldText; std::wstring old = oldText;

View File

@ -145,12 +145,12 @@ namespace
void commonfilter(TextBuffer *buffer, HookParam *hp) void commonfilter(TextBuffer *buffer, HookParam *hp)
{ {
auto str = buffer->strA(); auto str = buffer->viewA();
bool checkchaos = WideStringToString(StringToWideString(str)) != str; bool checkchaos = WideStringToString(StringToWideString(str)) != str;
if (checkchaos) if (checkchaos)
return buffer->clear(); return buffer->clear();
bool check1 = str.find("/") != str.npos || str.find("\\") != str.npos; bool check1 = str.find("/") != str.npos || str.find("\\") != str.npos;
auto hashsuffix = [str]() auto hashsuffix = [&]()
{ {
auto filterpath = { auto filterpath = {
".png", ".jpg", ".bmp", ".png", ".jpg", ".bmp",
@ -163,7 +163,7 @@ namespace
return false; return false;
}; };
bool check2 = hashsuffix(); bool check2 = hashsuffix();
bool check3 = all_ascii(str.c_str(), str.size()); bool check3 = all_ascii(str.data(), str.size());
if (check1 && (check2 || check3)) if (check1 && (check2 || check3))
return buffer->clear(); return buffer->clear();
} }

View File

@ -262,8 +262,7 @@ namespace
} }
void PCSG00776(TextBuffer *buffer, HookParam *hp) void PCSG00776(TextBuffer *buffer, HookParam *hp)
{ {
auto s = buffer->strA(); auto ws = StringToWideString(buffer->viewA(), 932).value();
auto ws = StringToWideString(s, 932).value();
strReplace(ws, L"\x02", L""); strReplace(ws, L"\x02", L"");
Trim(ws); Trim(ws);
buffer->from(WideStringToString(ws)); buffer->from(WideStringToString(ws));
@ -436,20 +435,16 @@ namespace
} }
void FPCSG00477(TextBuffer *buffer, HookParam *hp) void FPCSG00477(TextBuffer *buffer, HookParam *hp)
{ {
auto s = buffer->strA(); auto ws = StringToWideString(buffer->viewA(), 932).value();
auto ws = StringToWideString(s, 932).value();
ws = std::regex_replace(ws, std::wregex(LR"(#n\u3000*)"), L""); ws = std::regex_replace(ws, std::wregex(LR"(#n\u3000*)"), L"");
ws = std::regex_replace(ws, std::wregex(LR"(#\w.+?])"), L""); ws = std::regex_replace(ws, std::wregex(LR"(#\w.+?])"), L"");
s = WideStringToString(ws, 932); buffer->from(WideStringToString(ws, 932));
buffer->from(s);
} }
void FPCSG00852(TextBuffer *buffer, HookParam *hp) void FPCSG00852(TextBuffer *buffer, HookParam *hp)
{ {
auto s = buffer->strA(); auto ws = StringToWideString(buffer->viewA(), 932).value();
auto ws = StringToWideString(s, 932).value();
ws = std::regex_replace(ws, std::wregex(LR"(\^)"), L""); ws = std::regex_replace(ws, std::wregex(LR"(\^)"), L"");
s = WideStringToString(ws, 932); buffer->from(WideStringToString(ws, 932));
buffer->from(s);
} }
void FPCSG01066(TextBuffer *buffer, HookParam *hp) void FPCSG01066(TextBuffer *buffer, HookParam *hp)
{ {

View File

@ -638,8 +638,7 @@ namespace
s = std::regex_replace(s, std::wregex(L"#T2[^#]+"), L""); s = std::regex_replace(s, std::wregex(L"#T2[^#]+"), L"");
s = std::regex_replace(s, std::wregex(L"#T\\d"), L""); s = std::regex_replace(s, std::wregex(L"#T\\d"), L"");
} }
auto u32 = utf16_to_utf32(s.c_str(), s.size()); buffer->from(utf16_to_utf32(s));
buffer->from(u32);
} }
void F010093800DB1C000(TextBuffer *buffer, HookParam *hp) void F010093800DB1C000(TextBuffer *buffer, HookParam *hp)
{ {
@ -651,8 +650,7 @@ namespace
s = std::regex_replace(s, std::wregex(L"\\#T2[^#]+"), L""); s = std::regex_replace(s, std::wregex(L"\\#T2[^#]+"), L"");
s = std::regex_replace(s, std::wregex(L"\\#T\\d"), L""); s = std::regex_replace(s, std::wregex(L"\\#T\\d"), L"");
} }
auto u32 = utf16_to_utf32(s.c_str(), s.size()); buffer->from(utf16_to_utf32(s));
buffer->from(u32);
} }
void F0100F7E00DFC8000(TextBuffer *buffer, HookParam *hp) void F0100F7E00DFC8000(TextBuffer *buffer, HookParam *hp)
{ {
@ -661,8 +659,7 @@ namespace
s = std::regex_replace(s, std::wregex(L"#KW"), L""); s = std::regex_replace(s, std::wregex(L"#KW"), L"");
s = std::regex_replace(s, std::wregex(L"#C\\(TR,0xff0000ff\\)"), L""); s = std::regex_replace(s, std::wregex(L"#C\\(TR,0xff0000ff\\)"), L"");
s = std::regex_replace(s, std::wregex(L"#P\\(.*\\)"), L""); s = std::regex_replace(s, std::wregex(L"#P\\(.*\\)"), L"");
auto u32 = utf16_to_utf32(s.c_str(), s.size()); buffer->from(utf16_to_utf32(s));
buffer->from(u32);
} }
void F0100982015606000(TextBuffer *buffer, HookParam *hp) void F0100982015606000(TextBuffer *buffer, HookParam *hp)
@ -732,8 +729,7 @@ namespace
auto s = utf32_to_utf16(buffer->viewU()); auto s = utf32_to_utf16(buffer->viewU());
s = std::regex_replace(s, std::wregex(L"<[^>]+>"), L""); s = std::regex_replace(s, std::wregex(L"<[^>]+>"), L"");
s = std::regex_replace(s, std::wregex(L"\n+"), L" "); s = std::regex_replace(s, std::wregex(L"\n+"), L" ");
auto u32 = utf16_to_utf32(s.c_str(), s.size()); buffer->from(utf16_to_utf32(s));
buffer->from(u32);
} }
template <int index> template <int index>
void T01000BB01CB8A000(hook_stack *stack, HookParam *hp, TextBuffer *buffer, uintptr_t *split) void T01000BB01CB8A000(hook_stack *stack, HookParam *hp, TextBuffer *buffer, uintptr_t *split)
@ -1121,11 +1117,9 @@ namespace
} }
void F0100E4000F616000(TextBuffer *buffer, HookParam *hp) void F0100E4000F616000(TextBuffer *buffer, HookParam *hp)
{ {
auto s = buffer->strA(); auto ws = StringToWideString(buffer->viewA(), 932).value();
auto ws = StringToWideString(s, 932).value();
ws = std::regex_replace(ws, std::wregex(LR"(\\\w)"), L""); ws = std::regex_replace(ws, std::wregex(LR"(\\\w)"), L"");
s = WideStringToString(ws, 932); buffer->from(WideStringToString(ws, 932));
buffer->from(s);
} }
void F01005A401D766000(TextBuffer *buffer, HookParam *hp) void F01005A401D766000(TextBuffer *buffer, HookParam *hp)
{ {
@ -1225,8 +1219,7 @@ namespace
s = std::regex_replace(s, std::wregex(LR"(\#T\d)"), L""); s = std::regex_replace(s, std::wregex(LR"(\#T\d)"), L"");
if (s == L"  ") if (s == L"  ")
return buffer->clear(); return buffer->clear();
auto u32 = utf16_to_utf32(s.c_str(), s.size()); buffer->from(utf16_to_utf32(s));
buffer->from(u32);
} }
void F010021D01474E000(TextBuffer *buffer, HookParam *hp) void F010021D01474E000(TextBuffer *buffer, HookParam *hp)
{ {
@ -1238,8 +1231,7 @@ namespace
if (last == s) if (last == s)
return buffer->clear(); return buffer->clear();
last = s; last = s;
auto u32 = utf16_to_utf32(s.c_str(), s.size()); buffer->from(utf16_to_utf32(s));
buffer->from(u32);
} }
void F010021D01474E000_2(TextBuffer *buffer, HookParam *hp) void F010021D01474E000_2(TextBuffer *buffer, HookParam *hp)
{ {
@ -1250,8 +1242,7 @@ namespace
if (last == s) if (last == s)
return buffer->clear(); return buffer->clear();
last = s; last = s;
auto u32 = utf16_to_utf32(s.c_str(), s.size()); buffer->from(utf16_to_utf32(s));
buffer->from(u32);
} }
void F01002C00177AE000(TextBuffer *buffer, HookParam *hp) void F01002C00177AE000(TextBuffer *buffer, HookParam *hp)
{ {
@ -1262,8 +1253,7 @@ namespace
if (last == s) if (last == s)
return buffer->clear(); return buffer->clear();
last = s; last = s;
auto u32 = utf16_to_utf32(s.c_str(), s.size()); buffer->from(utf16_to_utf32(s));
buffer->from(u32);
} }
void F0100EA100DF92000(TextBuffer *buffer, HookParam *hp) void F0100EA100DF92000(TextBuffer *buffer, HookParam *hp)
{ {
@ -1582,8 +1572,7 @@ namespace
auto s = utf32_to_utf16(buffer->viewU()); auto s = utf32_to_utf16(buffer->viewU());
s = std::regex_replace(s, std::wregex(L"<rb>(.+?)</rb><rt>.+?</rt>"), L"$1"); s = std::regex_replace(s, std::wregex(L"<rb>(.+?)</rb><rt>.+?</rt>"), L"$1");
s = std::regex_replace(s, std::wregex(L"\n+"), L" "); s = std::regex_replace(s, std::wregex(L"\n+"), L" ");
auto u32 = utf16_to_utf32(s.c_str(), s.size()); buffer->from(utf16_to_utf32(s));
buffer->from(u32);
} }
void F0100771013FA8000(TextBuffer *buffer, HookParam *hp) void F0100771013FA8000(TextBuffer *buffer, HookParam *hp)
{ {
@ -1768,8 +1757,7 @@ namespace
s = std::regex_replace(s, std::wregex(L"【SW】"), L""); s = std::regex_replace(s, std::wregex(L"【SW】"), L"");
s = std::regex_replace(s, std::wregex(L"【SP】"), L""); s = std::regex_replace(s, std::wregex(L"【SP】"), L"");
s = std::regex_replace(s, std::wregex(L"#P\\(.*\\)"), L""); s = std::regex_replace(s, std::wregex(L"#P\\(.*\\)"), L"");
auto u32 = utf16_to_utf32(s.c_str(), s.size()); buffer->from(utf16_to_utf32(s));
buffer->from(u32);
} }
void F010061A01C1CE000(TextBuffer *buffer, HookParam *hp) void F010061A01C1CE000(TextBuffer *buffer, HookParam *hp)
{ {
@ -1854,15 +1842,13 @@ namespace
template <bool choice> template <bool choice>
void F0100E5200D1A2000(TextBuffer *buffer, HookParam *hp) void F0100E5200D1A2000(TextBuffer *buffer, HookParam *hp)
{ {
auto s = buffer->strA(); auto ws = StringToWideString(buffer->viewA(), 932).value();
auto ws = StringToWideString(s, 932).value();
ws = std::regex_replace(ws, std::wregex(LR"((\\n)+)"), L" "); ws = std::regex_replace(ws, std::wregex(LR"((\\n)+)"), L" ");
ws = std::regex_replace(ws, std::wregex(LR"(\\d$|^\@[a-z]+|#.*?#|\$)"), L""); ws = std::regex_replace(ws, std::wregex(LR"(\\d$|^\@[a-z]+|#.*?#|\$)"), L"");
ws = std::regex_replace(ws, std::wregex(LR"(\u3000+)"), L""); ws = std::regex_replace(ws, std::wregex(LR"(\u3000+)"), L"");
if (choice) if (choice)
ws = std::regex_replace(ws, std::wregex(LR"(, ?\w+)"), L""); ws = std::regex_replace(ws, std::wregex(LR"(, ?\w+)"), L"");
s = WideStringToString(ws, 932); buffer->from(WideStringToString(ws, 932));
buffer->from(s);
} }
void F010028D0148E6000_2(TextBuffer *buffer, HookParam *hp) void F010028D0148E6000_2(TextBuffer *buffer, HookParam *hp)
{ {
@ -1900,16 +1886,14 @@ namespace
template <bool choice> template <bool choice>
void F0100EFE0159C6000(TextBuffer *buffer, HookParam *hp) void F0100EFE0159C6000(TextBuffer *buffer, HookParam *hp)
{ {
auto s = buffer->strA(); auto ws = StringToWideString(buffer->viewA(), 932).value();
auto ws = StringToWideString(s, 932).value();
ws = std::regex_replace(ws, std::wregex(LR"((\\n)+)"), L" "); ws = std::regex_replace(ws, std::wregex(LR"((\\n)+)"), L" ");
ws = std::regex_replace(ws, std::wregex(LR"(\\d$|^\@[a-z]+|#.*?#|\$)"), L""); ws = std::regex_replace(ws, std::wregex(LR"(\\d$|^\@[a-z]+|#.*?#|\$)"), L"");
ws = std::regex_replace(ws, std::wregex(LR"(\u3000+)"), L""); ws = std::regex_replace(ws, std::wregex(LR"(\u3000+)"), L"");
ws = std::regex_replace(ws, std::wregex(LR"(@w|\\c)"), L""); ws = std::regex_replace(ws, std::wregex(LR"(@w|\\c)"), L"");
if (choice) if (choice)
ws = std::regex_replace(ws, std::wregex(LR"(, ?\w+)"), L""); ws = std::regex_replace(ws, std::wregex(LR"(, ?\w+)"), L"");
s = WideStringToString(ws, 932); buffer->from(WideStringToString(ws, 932));
buffer->from(s);
} }
void F0100FDB00AA80000(TextBuffer *buffer, HookParam *hp) void F0100FDB00AA80000(TextBuffer *buffer, HookParam *hp)

View File

@ -1,354 +1,425 @@
#include"mages/mages.h" #include "mages/mages.h"
namespace mages{ namespace mages
{
std::map<WORD, std::wstring> createTable(int _idx) {
ConsoleOutput("%d",_idx);
auto compound_charsA=LoadResData(std::vector<const wchar_t*>{
L"compound_chars_default",
L"compound_chars_Robotics_Notes_Elite",
L"compound_chars_Robotics_Notes_Dash",
L"",
L"",
L"",
L"compound_chars_SGHD",
}[_idx],L"COMPOUND_CHARS");
auto charsetA=LoadResData(std::vector<const wchar_t*>{
L"charset_default",
L"charset_Robotics_Notes_Elite",
L"charset_Robotics_Notes_Dash",
L"charset_Famicom_Tantei_Club",
L"charset_SINce_Memories",
L"charset_SG_My_Darlings_Embrace",
L"charset_SG_Linear_Bounded_Phenogram",
L"charset_SGHD"
}[_idx],L"CHARSET");
std::map<WORD, std::wstring> createTable(int _idx)
auto compound_chars=StringToWideString(compound_charsA); {
auto charset=StringToWideString(charsetA); ConsoleOutput("%d", _idx);
strReplace(charset,L"\n",L""); auto compound_charsA = LoadResData(std::vector<const wchar_t *>{
strReplace(charset,L"\r",L""); L"compound_chars_default",
L"compound_chars_Robotics_Notes_Elite",
L"compound_chars_Robotics_Notes_Dash",
L"",
L"",
L"",
L"compound_chars_SGHD",
}[_idx],
L"COMPOUND_CHARS");
auto charsetA = LoadResData(std::vector<const wchar_t *>{
L"charset_default",
L"charset_Robotics_Notes_Elite",
L"charset_Robotics_Notes_Dash",
L"charset_Famicom_Tantei_Club",
L"charset_SINce_Memories",
L"charset_SG_My_Darlings_Embrace",
L"charset_SG_Linear_Bounded_Phenogram",
L"charset_SGHD"}[_idx],
L"CHARSET");
auto compound_chars = StringToWideString(compound_charsA);
auto charset = StringToWideString(charsetA);
strReplace(charset, L"\n", L"");
strReplace(charset, L"\r", L"");
std::map<WORD, std::wstring> table = {}; std::map<WORD, std::wstring> table = {};
for (auto line : strSplit(compound_chars, L"\n")) { for (auto line : strSplit(compound_chars, L"\n"))
{
auto pair = strSplit(line, L"="); auto pair = strSplit(line, L"=");
if (pair.size() != 2) continue; if (pair.size() != 2)
continue;
auto key = pair[0].substr(1, pair[0].size() - 2); auto key = pair[0].substr(1, pair[0].size() - 2);
auto val = pair[1]; auto val = pair[1];
auto keys = strSplit(key, L"-"); auto keys = strSplit(key, L"-");
if (keys.size() == 1)keys.push_back(key); if (keys.size() == 1)
keys.push_back(key);
size_t _; size_t _;
auto start = std::stoi(keys[0], &_, 16); auto start = std::stoi(keys[0], &_, 16);
auto end = std::stoi(keys[1], &_, 16); auto end = std::stoi(keys[1], &_, 16);
for (auto i = start; i <= end; i++) { for (auto i = start; i <= end; i++)
{
auto charCode = ((i & 0xFF) << 8) | i >> 8; // swap endian auto charCode = ((i & 0xFF) << 8) | i >> 8; // swap endian
table[charCode] = val; table[charCode] = val;
} }
} }
WORD charCode; WORD charCode;
for (auto i = 0; i < charset.size(); i++) { for (auto i = 0; i < charset.size(); i++)
{
charCode = 0x8000 + i; charCode = 0x8000 + i;
charCode = ((charCode & 0xFF) << 8) | charCode >> 8; // swap endian (0x8001 -> 0x0180) charCode = ((charCode & 0xFF) << 8) | charCode >> 8; // swap endian (0x8001 -> 0x0180)
table[charCode] = charset[i]; table[charCode] = charset[i];
} }
return table; return table;
} }
std::wstring mages_decode(WORD charCode,int _idx) { std::wstring mages_decode(WORD charCode, int _idx)
static auto table = createTable(_idx); {
if (table.find(charCode) == table.end()) { static auto table = createTable(_idx);
std::wstringstream _; if (table.find(charCode) == table.end())
_ << std::hex << charCode; {
return L"[" + _.str() + L"]"; std::wstringstream _;
} _ << std::hex << charCode;
else { return L"[" + _.str() + L"]";
return table[charCode];
}
}
std::wstring readString(uintptr_t address,int _idx) {
auto edx=address;
std::wstring s = L"", bottom = L"";
while (1) {
auto c = *(BYTE*)edx;
if (c == 0xff)break; // terminated
if (c >= 0xb0) {// b4: next page?
edx += 1;
continue;
} }
if (c >= 0x80) {// readChar else
auto charCode = *(WORD*)edx; {
edx += 2; return table[charCode];
s += mages_decode(charCode,_idx);
} }
else {// readControl }
edx += 1; std::wstring readString(uintptr_t address, int _idx)
if (c == 0) { {
s += L' '; auto edx = address;
std::wstring s = L"", bottom = L"";
while (1)
{
auto c = *(BYTE *)edx;
if (c == 0xff)
break; // terminated
if (c >= 0xb0)
{ // b4: next page?
edx += 1;
continue;
} }
else if (c == 1) {// speaker if (c >= 0x80)
bottom = L""; { // readChar
while (1) auto charCode = *(WORD *)edx;
edx += 2;
s += mages_decode(charCode, _idx);
}
else
{ // readControl
edx += 1;
if (c == 0)
{ {
auto c2 = *(BYTE*)edx; s += L' ';
if (c2 == 2) { }
edx += 1; break; else if (c == 1)
{ // speaker
bottom = L"";
while (1)
{
auto c2 = *(BYTE *)edx;
if (c2 == 2)
{
edx += 1;
break;
}
else if (c2 < 0x20)
edx += 1;
else
{
auto charCode = *(WORD *)edx;
edx += 2;
bottom += mages_decode(charCode, _idx);
}
} }
else if (c2 < 0x20)edx += 1; if (bottom.size())
else { s = s + bottom + L": ";
auto charCode = *(WORD*)edx; }
edx += 2; else if (c == 2)
bottom += mages_decode(charCode,_idx); { // line
// do nothing -> back to readChar
}
else if (c == 4 || c == 0x15)
{ // SetColor, EvaluateExpression => SKIP
////if (c !== 4) console.warn('Warning: ', c, hexdump(address));
// https://github.com/CommitteeOfZero/SciAdv.Net/blob/32489cd21921079975291dbdce9151ad66f1b06a/src/SciAdvNet.SC3/Text/SC3StringDecoder.cs#L98
// https://github.com/CommitteeOfZero/SciAdv.Net/blob/32489cd21921079975291dbdce9151ad66f1b06a/src/SciAdvNet.SC3/Text/StringSegmentCodes.cs#L3
// https://github.com/shiiion/steinsgate_textractor/blob/master/steinsgatetextractor/sg_text_extractor.cpp#L46
auto token = *(BYTE *)edx; // BYTE token = read_single<BYTE>(cur_index);
if (!token)
{
edx += 1; // return cur_index + 1;
}
else
{
do
{
if (token & 0x80)
{
switch (token & 0x60)
{
case 0:
edx += 2; // cur_index += 2;
break;
case 0x20:
edx += 3; // cur_index += 3;
break;
case 0x40:
edx += 4; // cur_index += 4;
break;
case 0x60:
edx += 5; // cur_index += 5;
break;
default:
// impossible
break;
}
}
else
{
edx += 2; // cur_index += 2;
}
token = *(BYTE *)edx; // token = read_single<BYTE>(cur_index);
} while (token);
} }
} }
if(bottom.size()) s = s + bottom + L": "; else if (c == 0x0C // SetFontSize
} || c == 0x11 // SetTopMargin
else if (c == 2) { // line || c == 0x12 // SetLeftMargin
// do nothing -> back to readChar || c == 0x13 // STT_GetHardcodedValue: https://github.com/CommitteeOfZero/impacto/blob/master/src/text.cpp#L43
} )
else if (c == 4 || c == 0x15) { // SetColor, EvaluateExpression => SKIP {
////if (c !== 4) console.warn('Warning: ', c, hexdump(address)); edx += 2;
// https://github.com/CommitteeOfZero/SciAdv.Net/blob/32489cd21921079975291dbdce9151ad66f1b06a/src/SciAdvNet.SC3/Text/SC3StringDecoder.cs#L98 }
// https://github.com/CommitteeOfZero/SciAdv.Net/blob/32489cd21921079975291dbdce9151ad66f1b06a/src/SciAdvNet.SC3/Text/StringSegmentCodes.cs#L3 else if (c == 9)
// https://github.com/shiiion/steinsgate_textractor/blob/master/steinsgatetextractor/sg_text_extractor.cpp#L46 { // ruby (09_text_0A_rubi_0B)
auto token = *(BYTE*)edx; // BYTE token = read_single<BYTE>(cur_index); std::wstring rubi = L"";
if (!token) { bottom = L"";
edx +=1; // return cur_index + 1; while (true)
} {
else { auto c2 = *(BYTE *)edx;
do { if (c2 == 0x0A)
if (token & 0x80) { { // rubi
switch (token & 0x60) { edx += 1;
case 0: while (true)
edx +=2 ; //cur_index += 2; {
break; c2 = *(BYTE *)edx;
case 0x20: if (c2 == 0x0B)
edx +=3; //cur_index += 3; { // end rubi
break; // address = address.add(1);
case 0x40: break; // break lv2 loop
edx +=4; //cur_index += 4; }
break; else if (c2 < 0x20)
case 0x60: { // another control
edx +=5; //cur_index += 5; edx += 1;
break; }
default: else
// impossible { // rubi
break; auto charCode = *(WORD *)edx;
} edx += 2;
} else {
edx +=2; //cur_index += 2;
}
token = *(BYTE*)edx; //token = read_single<BYTE>(cur_index);
} while (token);
}
}
else if (c == 0x0C // SetFontSize
|| c == 0x11 // SetTopMargin
|| c == 0x12 // SetLeftMargin
|| c == 0x13 // STT_GetHardcodedValue: https://github.com/CommitteeOfZero/impacto/blob/master/src/text.cpp#L43
) {
edx+=2;
}
else if (c == 9) { // ruby (09_text_0A_rubi_0B)
std::wstring rubi = L"";
bottom = L"";
while (true) {
auto c2 = *(BYTE*)edx;
if (c2 == 0x0A) { // rubi
edx+=1;
while (true) {
c2 = *(BYTE*)edx;
if (c2 == 0x0B) { // end rubi
// address = address.add(1);
break; // break lv2 loop
}
else if (c2 < 0x20) { // another control
edx+=1;
}
else { // rubi
auto charCode = *(WORD*)edx;
edx+=2;
rubi += mages_decode(charCode,_idx); rubi += mages_decode(charCode, _idx);
}
} // end while
} }
} // end while else if (c2 == 0x0B)
} { // end rubi
else if (c2 == 0x0B) { // end rubi edx += 1;
edx+=1; break; // break lv1 loop
break; // break lv1 loop }
} else if (c2 < 0x20)
else if (c2 < 0x20) { // another control (color?) { // another control (color?)
edx+=1; edx += 1;
} }
else { // char (text) else
auto charCode = *(WORD*)edx; { // char (text)
edx+=2; auto charCode = *(WORD *)edx;
edx += 2;
auto cc = mages_decode(charCode,_idx); auto cc = mages_decode(charCode, _idx);
bottom += cc; bottom += cc;
s += cc; s += cc;
}
}
if (rubi != L"")
{
// console.log('rubi: ', rubi);
// console.log('char: ', bottom);
}
}
else
{
// do nothing (one byte control)
} }
} }
if (rubi != L"") {
//console.log('rubi: ', rubi);
//console.log('char: ', bottom);
}
}
else {
// do nothing (one byte control)
} }
return s;
} }
}
return s;
}
} }
namespace hookmages{ namespace hookmages
regs reg=regs::invalid;
int gametype=0;
template<int filter>
void SpecialHookMAGES(hook_stack *stack, HookParam *hp, TextBuffer *buffer, uintptr_t *split)
{ {
auto edx = regof(reg,stack);//regof(edx, esp_base);
auto s=mages::readString(edx,gametype);
if(filter){ regs reg = regs::invalid;
static std::wstring last=L""; int gametype = 0;
if(last==s)return;
last=s; template <int filter>
void SpecialHookMAGES(hook_stack *stack, HookParam *hp, TextBuffer *buffer, uintptr_t *split)
{
auto edx = regof(reg, stack); // regof(edx, esp_base);
auto s = mages::readString(edx, gametype);
if (filter)
{
static std::wstring last = L"";
if (last == s)
return;
last = s;
}
buffer->from(s);
} }
buffer->from(s);
}
bool MAGES() { bool MAGES()
{
#ifndef _WIN64 #ifndef _WIN64
auto dialogSigOffset = 2; auto dialogSigOffset = 2;
BYTE dialogSig1 []={ BYTE dialogSig1[] = {
0x85,XX,0x74,XX,0x83,XX,0x01,0x74,XX,0x83,XX,0x04,0x74,XX,0xc7,0x05,XX,XX,XX,XX,0x01,0x00,0x00,0x00 0x85, XX, 0x74, XX, 0x83, XX, 0x01, 0x74, XX, 0x83, XX, 0x04, 0x74, XX, 0xc7, 0x05, XX, XX, XX, XX, 0x01, 0x00, 0x00, 0x00};
}; auto addr = MemDbg::findBytes(dialogSig1, sizeof(dialogSig1), processStartAddress, processStopAddress);
auto addr=MemDbg::findBytes(dialogSig1,sizeof(dialogSig1),processStartAddress,processStopAddress); if (addr == 0)
if(addr==0){ {
dialogSigOffset = 3; dialogSigOffset = 3;
BYTE dialogSig2 []={ BYTE dialogSig2[] = {
0x57,0x85,XX,0x74,XX,0x83,XX,0x01,0x74,XX,0x83,XX,0x04 0x57, 0x85, XX, 0x74, XX, 0x83, XX, 0x01, 0x74, XX, 0x83, XX, 0x04};
}; addr = MemDbg::findBytes(dialogSig2, sizeof(dialogSig2), processStartAddress, processStopAddress);
addr=MemDbg::findBytes(dialogSig2,sizeof(dialogSig2),processStartAddress,processStopAddress);
}
if(addr==0)return false;
auto pos = addr+dialogSigOffset;
//.text:00431D3F 74 16 jz short loc_431D57
auto jzoff=*(BYTE*)(pos+1);
pos+=jzoff+2;
auto hookaddr=pos;
for(int i=0;i<0x200;i++){
if(((*(BYTE*)(pos))==0x8a)){
switch(((*(BYTE*)(pos+1)))){
// case 0:reg=pusha_eax_off;break;
//YU-NO
//.text:00431D63 89 0D 20 A9 BF 00 mov dword_BFA920, ecx
//在加载到内存后有时变成89 0d 20 a9 8a 00导致崩溃且这个没有遇到过故注释掉。
case 3:reg=regs::ebx;break;
case 1:reg=regs::ecx;break;
case 2:reg=regs::edx;break;
case 6:reg=regs::esi;break;
case 7:reg=regs::edi;break;
default:reg=regs::invalid;
} }
if(reg!=regs::invalid)break; if (addr == 0)
return false;
auto pos = addr + dialogSigOffset;
//.text:00431D3F 74 16 jz short loc_431D57
auto jzoff = *(BYTE *)(pos + 1);
pos += jzoff + 2;
auto hookaddr = pos;
for (int i = 0; i < 0x200; i++)
{
if (((*(BYTE *)(pos)) == 0x8a))
{
switch (((*(BYTE *)(pos + 1))))
{
// case 0:reg=pusha_eax_off;break;
// YU-NO
//.text:00431D63 89 0D 20 A9 BF 00 mov dword_BFA920, ecx
// 在加载到内存后有时变成89 0d 20 a9 8a 00导致崩溃且这个没有遇到过故注释掉。
case 3:
reg = regs::ebx;
break;
case 1:
reg = regs::ecx;
break;
case 2:
reg = regs::edx;
break;
case 6:
reg = regs::esi;
break;
case 7:
reg = regs::edi;
break;
default:
reg = regs::invalid;
}
if (reg != regs::invalid)
break;
}
pos += 1;
} }
pos+=1; if (reg == regs::invalid)
} return false;
if(reg==regs::invalid)return false; ConsoleOutput("%p", pos - processStartAddress);
ConsoleOutput("%p",pos-processStartAddress); switch (pos - processStartAddress)
switch(pos-processStartAddress){ {
case 0x6e69b://SG My Darling's Embrace 破解版 case 0x6e69b: // SG My Darling's Embrace 破解版
case 0x6e77b://SG My Darling's Embrace case 0x6e77b: // SG My Darling's Embrace
gametype=5;break; gametype = 5;
case 0x4ef60://STEINS;GATE: Linear Bounded Phenogram break;
gametype=6;break; case 0x4ef60: // STEINS;GATE: Linear Bounded Phenogram
case 0x498b0://STEINS;GATE gametype = 6;
gametype=7;break; break;
case 0x9f723://Robotics;Notes-Elite case 0x498b0: // STEINS;GATE
gametype=1;break; gametype = 7;
case 0xf70a6://Robotics;Notes-Dash break;
gametype=2;break; case 0x9f723: // Robotics;Notes-Elite
gametype = 1;
break;
case 0xf70a6: // Robotics;Notes-Dash
gametype = 2;
break;
default: default:
//YU-NO // YU-NO
//测试无效: // 测试无效:
//Steins;Gate-0 // Steins;Gate-0
//Steins;Gate // Steins;Gate
//未测试: // 未测试:
//Steins;Gate-Elite // Steins;Gate-Elite
//Chaos;Child // Chaos;Child
//CHAOS;HEAD_NOAH // CHAOS;HEAD_NOAH
//Memories_Off_-Innocent_Fille // Memories_Off_-Innocent_Fille
//Memories_Off_-Innocent_Fille-_for_Dearest // Memories_Off_-Innocent_Fille-_for_Dearest
gametype=0; gametype = 0;
} }
//ConsoleOutput("%x",pos-processStartAddress); // ConsoleOutput("%x",pos-processStartAddress);
HookParam hp; HookParam hp;
//hp.address = hookaddr; // hp.address = hookaddr;
hp.address=hookaddr; hp.address = hookaddr;
//想い出にかわる君 ~メモリーズオフ~ 想君秋之回忆3在hookaddr上无法正确读取。 // 想い出にかわる君 ~メモリーズオフ~ 想君秋之回忆3在hookaddr上无法正确读取。
//hookaddr上是没有重复的pos上是都能读到但有重复。 // hookaddr上是没有重复的pos上是都能读到但有重复。
hp.text_fun = SpecialHookMAGES<0>; hp.text_fun = SpecialHookMAGES<0>;
hp.type = CODEC_UTF16 | USING_STRING|NO_CONTEXT; hp.type = CODEC_UTF16 | USING_STRING | NO_CONTEXT;
auto _=NewHook(hp, "5pb_MAGES"); auto _ = NewHook(hp, "5pb_MAGES");
hp.address=pos; hp.address = pos;
hp.text_fun = SpecialHookMAGES<1>; hp.text_fun = SpecialHookMAGES<1>;
_|=NewHook(hp, "5pb_MAGES"); _ |= NewHook(hp, "5pb_MAGES");
ConsoleOutput("%p %p",hookaddr,pos); ConsoleOutput("%p %p", hookaddr, pos);
return _; return _;
#else #else
auto dialogSigOffset = 2; auto dialogSigOffset = 2;
BYTE dialogSig1 []={ BYTE dialogSig1[] = {
0x85,XX,0x74,XX,0x41,0x83,XX,0x01,0x74,XX,0x41,0x83,XX,0x04,0x74,XX,0x41 0x85, XX, 0x74, XX, 0x41, 0x83, XX, 0x01, 0x74, XX, 0x41, 0x83, XX, 0x04, 0x74, XX, 0x41};
}; auto addr = MemDbg::findBytes(dialogSig1, sizeof(dialogSig1), processStartAddress, processStopAddress);
auto addr=MemDbg::findBytes(dialogSig1,sizeof(dialogSig1),processStartAddress,processStopAddress); ConsoleOutput("%p", addr);
ConsoleOutput("%p",addr); if (addr == 0)
if(addr==0)return false; return false;
auto pos = addr+dialogSigOffset; auto pos = addr + dialogSigOffset;
auto jzoff=*(BYTE*)(pos+1); auto jzoff = *(BYTE *)(pos + 1);
pos+=jzoff+2; pos += jzoff + 2;
auto hookaddr=pos; auto hookaddr = pos;
// //
for(int i=0;i<0x200;i++){ for (int i = 0; i < 0x200; i++)
//.text:000000014004116B 0F B6 13 movzx edx, byte ptr [rbx] {
//->rbx //.text:000000014004116B 0F B6 13 movzx edx, byte ptr [rbx]
if((((*(DWORD*)(pos))&0xffffff)==0x13b60f)){ //->rbx
reg=regs::rbx;//rbx if ((((*(DWORD *)(pos)) & 0xffffff) == 0x13b60f))
//ConsoleOutput("%p",pos-processStartAddress); {
break; reg = regs::rbx; // rbx
// ConsoleOutput("%p",pos-processStartAddress);
break;
}
pos += 1;
} }
pos+=1; if (reg == regs::invalid)
} return false;
if(reg==regs::invalid)return false; switch (pos - processStartAddress)
switch(pos-processStartAddress){ {
default:
//CHAOS;HEAD_NOAH
gametype=0;
}
HookParam hp;
hp.address=hookaddr;
hp.text_fun = SpecialHookMAGES<0>;
hp.type = CODEC_UTF16 | USING_STRING|NO_CONTEXT;
return NewHook(hp, "5pb_MAGES");
default:
// CHAOS;HEAD_NOAH
gametype = 0;
}
HookParam hp;
hp.address = hookaddr;
hp.text_fun = SpecialHookMAGES<0>;
hp.type = CODEC_UTF16 | USING_STRING | NO_CONTEXT;
return NewHook(hp, "5pb_MAGES");
#endif #endif
} }
} }

View File

@ -88,8 +88,7 @@ namespace ppsspp
void NPJH50909_filter(TextBuffer *buffer, HookParam *hp) void NPJH50909_filter(TextBuffer *buffer, HookParam *hp)
{ {
std::string result = buffer->strA(); auto ws = StringToWideString(buffer->viewA(), 932).value();
auto ws = StringToWideString(result, 932).value();
// Remove single line markers // Remove single line markers
ws = std::regex_replace(ws, std::wregex(L"(\\%N)+"), L" "); ws = std::regex_replace(ws, std::wregex(L"(\\%N)+"), L" ");
@ -240,7 +239,7 @@ namespace ppsspp
void N(TextBuffer *buffer, HookParam *) void N(TextBuffer *buffer, HookParam *)
{ {
auto current1 = buffer->strA(); auto current1 = buffer->strA();
if(current == current1) if (current == current1)
buffer->clear(); buffer->clear();
} }
} }

View File

@ -165,14 +165,14 @@ std::wstring DynamicShiftJISCodecPrivate::decode(const char* data, size_t length
if (ch <= 127) if (ch <= 127)
ret.push_back(ch); ret.push_back(ch);
else if (ch >= 0xa1 && ch <= 0xdf) // size == 1 else if (ch >= 0xa1 && ch <= 0xdf) // size == 1
ret.append(StringToWideString(std::string(data + 1, 1), codepage).value()); ret.append(StringToWideString(std::string_view(data + 1, 1), codepage).value());
else { else {
if (i + 1 == length) // no enough character if (i + 1 == length) // no enough character
return ret; return ret;
UINT8 ch2 = (UINT8)data[++i]; UINT8 ch2 = (UINT8)data[++i];
if ((ch >= 0x81 && ch <= 0x9f || ch >= 0xe0 && ch <= 0xef) if ((ch >= 0x81 && ch <= 0x9f || ch >= 0xe0 && ch <= 0xef)
&& (ch2 != 0x7f && ch2 >= 0x40 && ch2 <= 0xfc)) && (ch2 != 0x7f && ch2 >= 0x40 && ch2 <= 0xfc))
ret.append(StringToWideString(std::string(data + i - 1, 2), codepage).value()); ret.append(StringToWideString(std::string_view(data + i - 1, 2), codepage).value());
else if (wchar_t c = decodeChar(ch, ch2)) { else if (wchar_t c = decodeChar(ch, ch2)) {
ret.push_back(c); ret.push_back(c);
if (dynamic) if (dynamic)

View File

@ -132,7 +132,7 @@ void LunaHost::on_proc_connect(DWORD pid)
std::string name = safequeryjson(savedhookcontext[u8procname], "name", std::string()); std::string name = safequeryjson(savedhookcontext[u8procname], "name", std::string());
if (startWith(name, "UserHook")) if (startWith(name, "UserHook"))
{ {
if (auto hp = HookCode::Parse(StringToWideString(savedhookcontext[u8procname]["hookcode"]))) if (auto hp = HookCode::Parse(StringToWideString(std::string_view(savedhookcontext[u8procname]["hookcode"]))))
Host::InsertHook(pid, hp.value()); Host::InsertHook(pid, hp.value());
} }
} }

View File

@ -94,8 +94,12 @@ typedef HRESULT(WINAPI *CONVERTINETUNICODETOMULTIBYTE)(
LPINT lpnWideCharCount, LPINT lpnWideCharCount,
LPSTR lpDstStr, LPSTR lpDstStr,
LPINT lpnMultiCharCount); LPINT lpnMultiCharCount);
std::optional<std::wstring> StringToWideString(const std::string &text, UINT encoding) std::optional<std::wstring> StringToWideString(const std::string &text, UINT encoding)
{
return StringToWideString(std::string_view(text), encoding);
}
std::optional<std::wstring> StringToWideString(std::string_view text, UINT encoding)
{ {
std::vector<wchar_t> buffer(text.size() + 1); std::vector<wchar_t> buffer(text.size() + 1);
if (disable_mbwc) if (disable_mbwc)
@ -108,7 +112,7 @@ std::optional<std::wstring> StringToWideString(const std::string &text, UINT enc
auto ConvertINetMultiByteToUnicode = (CONVERTINETMULTIBYTETOUNICODE)GetProcAddress(h, "ConvertINetMultiByteToUnicode"); auto ConvertINetMultiByteToUnicode = (CONVERTINETMULTIBYTETOUNICODE)GetProcAddress(h, "ConvertINetMultiByteToUnicode");
if (ConvertINetMultiByteToUnicode == 0) if (ConvertINetMultiByteToUnicode == 0)
return {}; return {};
auto hr = ConvertINetMultiByteToUnicode(0, encoding, text.c_str(), &_s, buffer.data(), &_s2); auto hr = ConvertINetMultiByteToUnicode(0, encoding, text.data(), &_s, buffer.data(), &_s2);
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
return std::wstring(buffer.data(), _s2); return std::wstring(buffer.data(), _s2);
@ -118,7 +122,7 @@ std::optional<std::wstring> StringToWideString(const std::string &text, UINT enc
} }
else else
{ {
if (int length = MultiByteToWideChar(encoding, 0, text.c_str(), text.size() + 1, buffer.data(), buffer.size())) if (int length = MultiByteToWideChar(encoding, 0, text.data(), text.size() + 1, buffer.data(), buffer.size()))
return std::wstring(buffer.data(), length - 1); return std::wstring(buffer.data(), length - 1);
return {}; return {};
} }
@ -128,8 +132,30 @@ std::wstring StringToWideString(const std::string &text)
{ {
return StringToWideString(text, CP_UTF8).value(); return StringToWideString(text, CP_UTF8).value();
} }
std::wstring StringToWideString(std::string_view text)
{
return StringToWideString(text, CP_UTF8).value();
}
std::optional<std::wstring> StringToWideString(const char *text, UINT encoding)
{
return StringToWideString(std::string_view(text), encoding);
}
std::wstring StringToWideString(const char *text)
{
return StringToWideString(std::string_view(text));
}
std::string WideStringToString(const std::wstring &text, UINT cp) std::string WideStringToString(const std::wstring &text, UINT cp)
{
return WideStringToString(std::wstring_view(text), cp);
}
std::string WideStringToString(const wchar_t *text, UINT cp)
{
return WideStringToString(std::wstring_view(text), cp);
}
std::string WideStringToString(std::wstring_view text, UINT cp)
{ {
std::vector<char> buffer((text.size() + 1) * 4); std::vector<char> buffer((text.size() + 1) * 4);
if (disable_wcmb) if (disable_wcmb)
@ -142,7 +168,7 @@ std::string WideStringToString(const std::wstring &text, UINT cp)
auto ConvertINetUnicodeToMultiByte = (CONVERTINETUNICODETOMULTIBYTE)GetProcAddress(h, "ConvertINetUnicodeToMultiByte"); auto ConvertINetUnicodeToMultiByte = (CONVERTINETUNICODETOMULTIBYTE)GetProcAddress(h, "ConvertINetUnicodeToMultiByte");
if (ConvertINetUnicodeToMultiByte == 0) if (ConvertINetUnicodeToMultiByte == 0)
return {}; return {};
auto hr = ConvertINetUnicodeToMultiByte(0, cp, text.c_str(), &_s, buffer.data(), &_s2); auto hr = ConvertINetUnicodeToMultiByte(0, cp, text.data(), &_s, buffer.data(), &_s2);
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
return std::string(buffer.data(), _s2); return std::string(buffer.data(), _s2);
@ -152,7 +178,7 @@ std::string WideStringToString(const std::wstring &text, UINT cp)
} }
else else
{ {
WideCharToMultiByte(cp, 0, text.c_str(), -1, buffer.data(), buffer.size(), nullptr, nullptr); WideCharToMultiByte(cp, 0, text.data(), -1, buffer.data(), buffer.size(), nullptr, nullptr);
return buffer.data(); return buffer.data();
} }
} }
@ -171,16 +197,16 @@ inline unsigned int convertUTF32ToUTF16(unsigned int cUTF32, unsigned int &h, un
return ret; return ret;
} }
std::basic_string<uint32_t> utf16_to_utf32(const wchar_t *u16str, size_t size) u32string utf16_to_utf32(std::wstring_view wsv)
{ {
std::basic_string<uint32_t> utf32String; u32string utf32String;
for (size_t i = 0; i < size; i++) for (size_t i = 0; i < wsv.size(); i++)
{ {
auto u16c = u16str[i]; auto u16c = wsv[i];
if (u16c - 0xd800u < 2048u) if (u16c - 0xd800u < 2048u)
if ((u16c & 0xfffffc00 == 0xd800) && (i < size - 1) && (u16str[i + 1] & 0xfffffc00 == 0xdc00)) if ((u16c & 0xfffffc00 == 0xd800) && (i < wsv.size() - 1) && (wsv[i + 1] & 0xfffffc00 == 0xdc00))
{ {
utf32String += (u16c << 10) + u16str[i + 1] - 0x35fdc00; utf32String += (u16c << 10) + wsv[i + 1] - 0x35fdc00;
i += 1; i += 1;
} }
else else
@ -188,12 +214,12 @@ std::basic_string<uint32_t> utf16_to_utf32(const wchar_t *u16str, size_t size)
// error invalid u16 char // error invalid u16 char
} }
else else
utf32String += u16str[i]; utf32String += wsv[i];
} }
return utf32String; return utf32String;
} }
std::wstring utf32_to_utf16(std::basic_string_view<uint32_t> sv) std::wstring utf32_to_utf16(u32string_view sv)
{ {
std::wstring u16str; std::wstring u16str;
for (auto i = 0; i < sv.size(); i++) for (auto i = 0; i < sv.size(); i++)
@ -284,9 +310,9 @@ std::optional<std::wstring> commonparsestring(void *data, size_t length, void *p
if (hp->type & CODEC_UTF16) if (hp->type & CODEC_UTF16)
return std::wstring((wchar_t *)data, length / sizeof(wchar_t)); return std::wstring((wchar_t *)data, length / sizeof(wchar_t));
else if (hp->type & CODEC_UTF32) else if (hp->type & CODEC_UTF32)
return (std::move(utf32_to_utf16(std::basic_string_view<uint32_t>((uint32_t *)data, length / sizeof(uint32_t))))); return utf32_to_utf16(u32string_view((uint32_t *)data, length / sizeof(uint32_t)));
else if (auto converted = StringToWideString(std::string((char *)data, length), (hp->type & CODEC_UTF8) ? CP_UTF8 : (hp->codepage ? hp->codepage : df))) else if (auto converted = StringToWideString(std::string((char *)data, length), (hp->type & CODEC_UTF8) ? CP_UTF8 : (hp->codepage ? hp->codepage : df)))
return (converted.value()); return converted.value();
else else
return {}; return {};
} }

View File

@ -1,6 +1,8 @@
#ifndef __LUNA_STRINGUILTS_H #ifndef __LUNA_STRINGUILTS_H
#define __LUNA_STRINGUILTS_H #define __LUNA_STRINGUILTS_H
using u32string = std::basic_string<uint32_t>;
using u32string_view = std::basic_string_view<uint32_t>;
enum enum
{ {
VNR_TEXT_CAPACITY = 1500 VNR_TEXT_CAPACITY = 1500
@ -26,12 +28,19 @@ bool startWith(const std::wstring_view &s, const std::wstring_view &s2);
bool endWith(const std::string_view &s, const std::string_view &s2); bool endWith(const std::string_view &s, const std::string_view &s2);
bool endWith(const std::wstring_view &s, const std::wstring_view &s2); bool endWith(const std::wstring_view &s, const std::wstring_view &s2);
std::wstring utf32_to_utf16(std::basic_string_view<uint32_t> sv); std::wstring utf32_to_utf16(u32string_view sv);
std::basic_string<uint32_t> utf16_to_utf32(const wchar_t *u16str, size_t size); u32string utf16_to_utf32(std::wstring_view);
std::string WideStringToString(const std::wstring &text, UINT cp = CP_UTF8); std::string WideStringToString(const std::wstring &text, UINT cp = CP_UTF8);
std::string WideStringToString(std::wstring_view text, UINT cp = CP_UTF8);
std::string WideStringToString(const wchar_t *, UINT cp = CP_UTF8);
std::wstring StringToWideString(const std::string &text); std::wstring StringToWideString(const std::string &text);
std::wstring StringToWideString(std::string_view);
std::wstring StringToWideString(const char *);
std::optional<std::wstring> StringToWideString(const std::string &text, UINT encoding); std::optional<std::wstring> StringToWideString(const std::string &text, UINT encoding);
std::optional<std::wstring> StringToWideString(std::string_view text, UINT encoding);
std::optional<std::wstring> StringToWideString(const char *, UINT encoding);
std::string wcasta(const std::wstring &x); std::string wcasta(const std::wstring &x);
std::wstring acastw(const std::string &x); std::wstring acastw(const std::string &x);