mirror of
https://github.com/HIllya51/LunaTranslator.git
synced 2024-12-26 23:24:13 +08:00
views
This commit is contained in:
parent
b13bcdc5aa
commit
810f333770
@ -221,7 +221,7 @@ bool adobelair3()
|
||||
hp.filter_fun = [](TextBuffer *buffer, HookParam *hp)
|
||||
{
|
||||
// 若当前还有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;
|
||||
if (ws.length() <= leng)
|
||||
{
|
||||
|
@ -55,7 +55,7 @@ namespace
|
||||
{
|
||||
StringFilter(buffer, "@1r", 3);
|
||||
StringFilter(buffer, "@-1r", 4);
|
||||
if (!StringToWideString(buffer->strA(), 932).has_value())
|
||||
if (!StringToWideString(buffer->viewA(), 932).has_value())
|
||||
buffer->clear();
|
||||
};
|
||||
return NewHook(hp, "Aksys");
|
||||
|
@ -615,7 +615,7 @@ namespace
|
||||
auto arg = (HookArgument *)s->stack[0]; // arg1
|
||||
if (arg && arg->isValid())
|
||||
{ // && (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,
|
||||
suffix,
|
||||
trimmedText = trim(oldText, &prefix, &suffix);
|
||||
@ -664,7 +664,7 @@ namespace
|
||||
auto arg = (HookArgument *)s->stack[0]; // arg1
|
||||
if (arg && arg->isValid())
|
||||
{ // && (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,
|
||||
suffix,
|
||||
trimmedText = trim(oldText, &prefix, &suffix);
|
||||
@ -763,7 +763,7 @@ namespace
|
||||
auto arg = (HookArgument *)s->stack[2]; // arg2
|
||||
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
|
||||
buffer->from(oldText);
|
||||
// std::wstring newText = EngineController::instance()->dispatchTextWSTD(oldText, role, sig);
|
||||
@ -780,7 +780,7 @@ namespace
|
||||
auto arg = (HookArgument *)s->stack[2]; // arg2
|
||||
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
|
||||
std::wstring old = oldText;
|
||||
|
||||
|
@ -145,12 +145,12 @@ namespace
|
||||
|
||||
void commonfilter(TextBuffer *buffer, HookParam *hp)
|
||||
{
|
||||
auto str = buffer->strA();
|
||||
auto str = buffer->viewA();
|
||||
bool checkchaos = WideStringToString(StringToWideString(str)) != str;
|
||||
if (checkchaos)
|
||||
return buffer->clear();
|
||||
bool check1 = str.find("/") != str.npos || str.find("\\") != str.npos;
|
||||
auto hashsuffix = [str]()
|
||||
auto hashsuffix = [&]()
|
||||
{
|
||||
auto filterpath = {
|
||||
".png", ".jpg", ".bmp",
|
||||
@ -163,7 +163,7 @@ namespace
|
||||
return false;
|
||||
};
|
||||
bool check2 = hashsuffix();
|
||||
bool check3 = all_ascii(str.c_str(), str.size());
|
||||
bool check3 = all_ascii(str.data(), str.size());
|
||||
if (check1 && (check2 || check3))
|
||||
return buffer->clear();
|
||||
}
|
||||
|
@ -262,8 +262,7 @@ namespace
|
||||
}
|
||||
void PCSG00776(TextBuffer *buffer, HookParam *hp)
|
||||
{
|
||||
auto s = buffer->strA();
|
||||
auto ws = StringToWideString(s, 932).value();
|
||||
auto ws = StringToWideString(buffer->viewA(), 932).value();
|
||||
strReplace(ws, L"\x02", L"");
|
||||
Trim(ws);
|
||||
buffer->from(WideStringToString(ws));
|
||||
@ -436,20 +435,16 @@ namespace
|
||||
}
|
||||
void FPCSG00477(TextBuffer *buffer, HookParam *hp)
|
||||
{
|
||||
auto s = buffer->strA();
|
||||
auto ws = StringToWideString(s, 932).value();
|
||||
auto ws = StringToWideString(buffer->viewA(), 932).value();
|
||||
ws = std::regex_replace(ws, std::wregex(LR"(#n\u3000*)"), L"");
|
||||
ws = std::regex_replace(ws, std::wregex(LR"(#\w.+?])"), L"");
|
||||
s = WideStringToString(ws, 932);
|
||||
buffer->from(s);
|
||||
buffer->from(WideStringToString(ws, 932));
|
||||
}
|
||||
void FPCSG00852(TextBuffer *buffer, HookParam *hp)
|
||||
{
|
||||
auto s = buffer->strA();
|
||||
auto ws = StringToWideString(s, 932).value();
|
||||
auto ws = StringToWideString(buffer->viewA(), 932).value();
|
||||
ws = std::regex_replace(ws, std::wregex(LR"(\^)"), L"");
|
||||
s = WideStringToString(ws, 932);
|
||||
buffer->from(s);
|
||||
buffer->from(WideStringToString(ws, 932));
|
||||
}
|
||||
void FPCSG01066(TextBuffer *buffer, HookParam *hp)
|
||||
{
|
||||
|
@ -638,8 +638,7 @@ namespace
|
||||
s = std::regex_replace(s, std::wregex(L"#T2[^#]+"), L"");
|
||||
s = std::regex_replace(s, std::wregex(L"#T\\d"), L"");
|
||||
}
|
||||
auto u32 = utf16_to_utf32(s.c_str(), s.size());
|
||||
buffer->from(u32);
|
||||
buffer->from(utf16_to_utf32(s));
|
||||
}
|
||||
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"\\#T\\d"), L"");
|
||||
}
|
||||
auto u32 = utf16_to_utf32(s.c_str(), s.size());
|
||||
buffer->from(u32);
|
||||
buffer->from(utf16_to_utf32(s));
|
||||
}
|
||||
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"#C\\(TR,0xff0000ff\\)"), L"");
|
||||
s = std::regex_replace(s, std::wregex(L"#P\\(.*\\)"), L"");
|
||||
auto u32 = utf16_to_utf32(s.c_str(), s.size());
|
||||
buffer->from(u32);
|
||||
buffer->from(utf16_to_utf32(s));
|
||||
}
|
||||
|
||||
void F0100982015606000(TextBuffer *buffer, HookParam *hp)
|
||||
@ -732,8 +729,7 @@ namespace
|
||||
auto s = utf32_to_utf16(buffer->viewU());
|
||||
s = std::regex_replace(s, std::wregex(L"<[^>]+>"), L"");
|
||||
s = std::regex_replace(s, std::wregex(L"\n+"), L" ");
|
||||
auto u32 = utf16_to_utf32(s.c_str(), s.size());
|
||||
buffer->from(u32);
|
||||
buffer->from(utf16_to_utf32(s));
|
||||
}
|
||||
template <int index>
|
||||
void T01000BB01CB8A000(hook_stack *stack, HookParam *hp, TextBuffer *buffer, uintptr_t *split)
|
||||
@ -1121,11 +1117,9 @@ namespace
|
||||
}
|
||||
void F0100E4000F616000(TextBuffer *buffer, HookParam *hp)
|
||||
{
|
||||
auto s = buffer->strA();
|
||||
auto ws = StringToWideString(s, 932).value();
|
||||
auto ws = StringToWideString(buffer->viewA(), 932).value();
|
||||
ws = std::regex_replace(ws, std::wregex(LR"(\\\w)"), L"");
|
||||
s = WideStringToString(ws, 932);
|
||||
buffer->from(s);
|
||||
buffer->from(WideStringToString(ws, 932));
|
||||
}
|
||||
void F01005A401D766000(TextBuffer *buffer, HookParam *hp)
|
||||
{
|
||||
@ -1225,8 +1219,7 @@ namespace
|
||||
s = std::regex_replace(s, std::wregex(LR"(\#T\d)"), L"");
|
||||
if (s == L" ")
|
||||
return buffer->clear();
|
||||
auto u32 = utf16_to_utf32(s.c_str(), s.size());
|
||||
buffer->from(u32);
|
||||
buffer->from(utf16_to_utf32(s));
|
||||
}
|
||||
void F010021D01474E000(TextBuffer *buffer, HookParam *hp)
|
||||
{
|
||||
@ -1238,8 +1231,7 @@ namespace
|
||||
if (last == s)
|
||||
return buffer->clear();
|
||||
last = s;
|
||||
auto u32 = utf16_to_utf32(s.c_str(), s.size());
|
||||
buffer->from(u32);
|
||||
buffer->from(utf16_to_utf32(s));
|
||||
}
|
||||
void F010021D01474E000_2(TextBuffer *buffer, HookParam *hp)
|
||||
{
|
||||
@ -1250,8 +1242,7 @@ namespace
|
||||
if (last == s)
|
||||
return buffer->clear();
|
||||
last = s;
|
||||
auto u32 = utf16_to_utf32(s.c_str(), s.size());
|
||||
buffer->from(u32);
|
||||
buffer->from(utf16_to_utf32(s));
|
||||
}
|
||||
void F01002C00177AE000(TextBuffer *buffer, HookParam *hp)
|
||||
{
|
||||
@ -1262,8 +1253,7 @@ namespace
|
||||
if (last == s)
|
||||
return buffer->clear();
|
||||
last = s;
|
||||
auto u32 = utf16_to_utf32(s.c_str(), s.size());
|
||||
buffer->from(u32);
|
||||
buffer->from(utf16_to_utf32(s));
|
||||
}
|
||||
void F0100EA100DF92000(TextBuffer *buffer, HookParam *hp)
|
||||
{
|
||||
@ -1582,8 +1572,7 @@ namespace
|
||||
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"\n+"), L" ");
|
||||
auto u32 = utf16_to_utf32(s.c_str(), s.size());
|
||||
buffer->from(u32);
|
||||
buffer->from(utf16_to_utf32(s));
|
||||
}
|
||||
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"【SP】"), L"");
|
||||
s = std::regex_replace(s, std::wregex(L"#P\\(.*\\)"), L"");
|
||||
auto u32 = utf16_to_utf32(s.c_str(), s.size());
|
||||
buffer->from(u32);
|
||||
buffer->from(utf16_to_utf32(s));
|
||||
}
|
||||
void F010061A01C1CE000(TextBuffer *buffer, HookParam *hp)
|
||||
{
|
||||
@ -1854,15 +1842,13 @@ namespace
|
||||
template <bool choice>
|
||||
void F0100E5200D1A2000(TextBuffer *buffer, HookParam *hp)
|
||||
{
|
||||
auto s = buffer->strA();
|
||||
auto ws = StringToWideString(s, 932).value();
|
||||
auto ws = StringToWideString(buffer->viewA(), 932).value();
|
||||
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"(\u3000+)"), L"");
|
||||
if (choice)
|
||||
ws = std::regex_replace(ws, std::wregex(LR"(, ?\w+)"), L"");
|
||||
s = WideStringToString(ws, 932);
|
||||
buffer->from(s);
|
||||
buffer->from(WideStringToString(ws, 932));
|
||||
}
|
||||
void F010028D0148E6000_2(TextBuffer *buffer, HookParam *hp)
|
||||
{
|
||||
@ -1900,16 +1886,14 @@ namespace
|
||||
template <bool choice>
|
||||
void F0100EFE0159C6000(TextBuffer *buffer, HookParam *hp)
|
||||
{
|
||||
auto s = buffer->strA();
|
||||
auto ws = StringToWideString(s, 932).value();
|
||||
auto ws = StringToWideString(buffer->viewA(), 932).value();
|
||||
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"(\u3000+)"), L"");
|
||||
ws = std::regex_replace(ws, std::wregex(LR"(@w|\\c)"), L"");
|
||||
if (choice)
|
||||
ws = std::regex_replace(ws, std::wregex(LR"(, ?\w+)"), L"");
|
||||
s = WideStringToString(ws, 932);
|
||||
buffer->from(s);
|
||||
buffer->from(WideStringToString(ws, 932));
|
||||
}
|
||||
|
||||
void F0100FDB00AA80000(TextBuffer *buffer, HookParam *hp)
|
||||
|
@ -1,354 +1,425 @@
|
||||
#include"mages/mages.h"
|
||||
#include "mages/mages.h"
|
||||
|
||||
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");
|
||||
namespace mages
|
||||
{
|
||||
|
||||
|
||||
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> 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");
|
||||
|
||||
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 = {};
|
||||
|
||||
for (auto line : strSplit(compound_chars, L"\n")) {
|
||||
|
||||
for (auto line : strSplit(compound_chars, L"\n"))
|
||||
{
|
||||
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 val = pair[1];
|
||||
auto keys = strSplit(key, L"-");
|
||||
if (keys.size() == 1)keys.push_back(key);
|
||||
if (keys.size() == 1)
|
||||
keys.push_back(key);
|
||||
size_t _;
|
||||
auto start = std::stoi(keys[0], &_, 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
|
||||
table[charCode] = val;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
WORD charCode;
|
||||
for (auto i = 0; i < charset.size(); i++) {
|
||||
for (auto i = 0; i < charset.size(); i++)
|
||||
{
|
||||
charCode = 0x8000 + i;
|
||||
charCode = ((charCode & 0xFF) << 8) | charCode >> 8; // swap endian (0x8001 -> 0x0180)
|
||||
table[charCode] = charset[i];
|
||||
}
|
||||
return table;
|
||||
}
|
||||
|
||||
std::wstring mages_decode(WORD charCode,int _idx) {
|
||||
static auto table = createTable(_idx);
|
||||
if (table.find(charCode) == table.end()) {
|
||||
std::wstringstream _;
|
||||
_ << std::hex << charCode;
|
||||
return L"[" + _.str() + L"]";
|
||||
}
|
||||
else {
|
||||
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;
|
||||
|
||||
std::wstring mages_decode(WORD charCode, int _idx)
|
||||
{
|
||||
static auto table = createTable(_idx);
|
||||
if (table.find(charCode) == table.end())
|
||||
{
|
||||
std::wstringstream _;
|
||||
_ << std::hex << charCode;
|
||||
return L"[" + _.str() + L"]";
|
||||
}
|
||||
if (c >= 0x80) {// readChar
|
||||
auto charCode = *(WORD*)edx;
|
||||
edx += 2;
|
||||
s += mages_decode(charCode,_idx);
|
||||
else
|
||||
{
|
||||
return table[charCode];
|
||||
}
|
||||
else {// readControl
|
||||
edx += 1;
|
||||
if (c == 0) {
|
||||
s += L' ';
|
||||
}
|
||||
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;
|
||||
}
|
||||
else if (c == 1) {// speaker
|
||||
bottom = L"";
|
||||
while (1)
|
||||
if (c >= 0x80)
|
||||
{ // readChar
|
||||
auto charCode = *(WORD *)edx;
|
||||
edx += 2;
|
||||
s += mages_decode(charCode, _idx);
|
||||
}
|
||||
else
|
||||
{ // readControl
|
||||
edx += 1;
|
||||
if (c == 0)
|
||||
{
|
||||
auto c2 = *(BYTE*)edx;
|
||||
if (c2 == 2) {
|
||||
edx += 1; break;
|
||||
s += L' ';
|
||||
}
|
||||
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;
|
||||
else {
|
||||
auto charCode = *(WORD*)edx;
|
||||
edx += 2;
|
||||
bottom += mages_decode(charCode,_idx);
|
||||
if (bottom.size())
|
||||
s = s + bottom + L": ";
|
||||
}
|
||||
else if (c == 2)
|
||||
{ // 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 == 2) { // 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);
|
||||
}
|
||||
}
|
||||
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;
|
||||
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
|
||||
edx+=1;
|
||||
break; // break lv1 loop
|
||||
}
|
||||
else if (c2 < 0x20) { // another control (color?)
|
||||
edx+=1;
|
||||
}
|
||||
else { // char (text)
|
||||
auto charCode = *(WORD*)edx;
|
||||
edx+=2;
|
||||
else if (c2 == 0x0B)
|
||||
{ // end rubi
|
||||
edx += 1;
|
||||
break; // break lv1 loop
|
||||
}
|
||||
else if (c2 < 0x20)
|
||||
{ // another control (color?)
|
||||
edx += 1;
|
||||
}
|
||||
else
|
||||
{ // char (text)
|
||||
auto charCode = *(WORD *)edx;
|
||||
edx += 2;
|
||||
|
||||
auto cc = mages_decode(charCode,_idx);
|
||||
bottom += cc;
|
||||
s += cc;
|
||||
auto cc = mages_decode(charCode, _idx);
|
||||
bottom += 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{
|
||||
|
||||
regs reg=regs::invalid;
|
||||
int gametype=0;
|
||||
|
||||
template<int filter>
|
||||
void SpecialHookMAGES(hook_stack *stack, HookParam *hp, TextBuffer *buffer, uintptr_t *split)
|
||||
namespace hookmages
|
||||
{
|
||||
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;
|
||||
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)
|
||||
{
|
||||
static std::wstring last = L"";
|
||||
if (last == s)
|
||||
return;
|
||||
last = s;
|
||||
}
|
||||
buffer->from(s);
|
||||
}
|
||||
buffer->from(s);
|
||||
}
|
||||
|
||||
bool MAGES() {
|
||||
bool MAGES()
|
||||
{
|
||||
#ifndef _WIN64
|
||||
auto dialogSigOffset = 2;
|
||||
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
|
||||
};
|
||||
auto addr=MemDbg::findBytes(dialogSig1,sizeof(dialogSig1),processStartAddress,processStopAddress);
|
||||
if(addr==0){
|
||||
dialogSigOffset = 3;
|
||||
BYTE dialogSig2 []={
|
||||
0x57,0x85,XX,0x74,XX,0x83,XX,0x01,0x74,XX,0x83,XX,0x04
|
||||
};
|
||||
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;
|
||||
auto dialogSigOffset = 2;
|
||||
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};
|
||||
auto addr = MemDbg::findBytes(dialogSig1, sizeof(dialogSig1), processStartAddress, processStopAddress);
|
||||
if (addr == 0)
|
||||
{
|
||||
dialogSigOffset = 3;
|
||||
BYTE dialogSig2[] = {
|
||||
0x57, 0x85, XX, 0x74, XX, 0x83, XX, 0x01, 0x74, XX, 0x83, XX, 0x04};
|
||||
addr = MemDbg::findBytes(dialogSig2, sizeof(dialogSig2), processStartAddress, processStopAddress);
|
||||
}
|
||||
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;
|
||||
ConsoleOutput("%p",pos-processStartAddress);
|
||||
switch(pos-processStartAddress){
|
||||
case 0x6e69b://SG My Darling's Embrace 破解版
|
||||
case 0x6e77b://SG My Darling's Embrace
|
||||
gametype=5;break;
|
||||
case 0x4ef60://STEINS;GATE: Linear Bounded Phenogram
|
||||
gametype=6;break;
|
||||
case 0x498b0://STEINS;GATE
|
||||
gametype=7;break;
|
||||
case 0x9f723://Robotics;Notes-Elite
|
||||
gametype=1;break;
|
||||
case 0xf70a6://Robotics;Notes-Dash
|
||||
gametype=2;break;
|
||||
|
||||
if (reg == regs::invalid)
|
||||
return false;
|
||||
ConsoleOutput("%p", pos - processStartAddress);
|
||||
switch (pos - processStartAddress)
|
||||
{
|
||||
case 0x6e69b: // SG My Darling's Embrace 破解版
|
||||
case 0x6e77b: // SG My Darling's Embrace
|
||||
gametype = 5;
|
||||
break;
|
||||
case 0x4ef60: // STEINS;GATE: Linear Bounded Phenogram
|
||||
gametype = 6;
|
||||
break;
|
||||
case 0x498b0: // STEINS;GATE
|
||||
gametype = 7;
|
||||
break;
|
||||
case 0x9f723: // Robotics;Notes-Elite
|
||||
gametype = 1;
|
||||
break;
|
||||
case 0xf70a6: // Robotics;Notes-Dash
|
||||
gametype = 2;
|
||||
break;
|
||||
|
||||
default:
|
||||
//YU-NO
|
||||
//测试无效:
|
||||
//Steins;Gate-0
|
||||
//Steins;Gate
|
||||
//未测试:
|
||||
//Steins;Gate-Elite
|
||||
//Chaos;Child
|
||||
//CHAOS;HEAD_NOAH
|
||||
//Memories_Off_-Innocent_Fille
|
||||
//Memories_Off_-Innocent_Fille-_for_Dearest
|
||||
gametype=0;
|
||||
}
|
||||
//ConsoleOutput("%x",pos-processStartAddress);
|
||||
HookParam hp;
|
||||
//hp.address = hookaddr;
|
||||
hp.address=hookaddr;
|
||||
//想い出にかわる君 ~メモリーズオフ~ 想君:秋之回忆3在hookaddr上无法正确读取。
|
||||
//hookaddr上是没有重复的,pos上是都能读到但有重复。
|
||||
hp.text_fun = SpecialHookMAGES<0>;
|
||||
hp.type = CODEC_UTF16 | USING_STRING|NO_CONTEXT;
|
||||
auto _=NewHook(hp, "5pb_MAGES");
|
||||
hp.address=pos;
|
||||
hp.text_fun = SpecialHookMAGES<1>;
|
||||
_|=NewHook(hp, "5pb_MAGES");
|
||||
ConsoleOutput("%p %p",hookaddr,pos);
|
||||
return _;
|
||||
// YU-NO
|
||||
// 测试无效:
|
||||
// Steins;Gate-0
|
||||
// Steins;Gate
|
||||
// 未测试:
|
||||
// Steins;Gate-Elite
|
||||
// Chaos;Child
|
||||
// CHAOS;HEAD_NOAH
|
||||
// Memories_Off_-Innocent_Fille
|
||||
// Memories_Off_-Innocent_Fille-_for_Dearest
|
||||
gametype = 0;
|
||||
}
|
||||
// ConsoleOutput("%x",pos-processStartAddress);
|
||||
HookParam hp;
|
||||
// hp.address = hookaddr;
|
||||
hp.address = hookaddr;
|
||||
// 想い出にかわる君 ~メモリーズオフ~ 想君:秋之回忆3在hookaddr上无法正确读取。
|
||||
// hookaddr上是没有重复的,pos上是都能读到但有重复。
|
||||
hp.text_fun = SpecialHookMAGES<0>;
|
||||
hp.type = CODEC_UTF16 | USING_STRING | NO_CONTEXT;
|
||||
auto _ = NewHook(hp, "5pb_MAGES");
|
||||
hp.address = pos;
|
||||
hp.text_fun = SpecialHookMAGES<1>;
|
||||
_ |= NewHook(hp, "5pb_MAGES");
|
||||
ConsoleOutput("%p %p", hookaddr, pos);
|
||||
return _;
|
||||
|
||||
#else
|
||||
|
||||
auto dialogSigOffset = 2;
|
||||
BYTE dialogSig1 []={
|
||||
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);
|
||||
ConsoleOutput("%p",addr);
|
||||
if(addr==0)return false;
|
||||
auto pos = addr+dialogSigOffset;
|
||||
auto jzoff=*(BYTE*)(pos+1);
|
||||
pos+=jzoff+2;
|
||||
auto hookaddr=pos;
|
||||
//
|
||||
for(int i=0;i<0x200;i++){
|
||||
//.text:000000014004116B 0F B6 13 movzx edx, byte ptr [rbx]
|
||||
//->rbx
|
||||
if((((*(DWORD*)(pos))&0xffffff)==0x13b60f)){
|
||||
reg=regs::rbx;//rbx
|
||||
//ConsoleOutput("%p",pos-processStartAddress);
|
||||
break;
|
||||
auto dialogSigOffset = 2;
|
||||
BYTE dialogSig1[] = {
|
||||
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);
|
||||
ConsoleOutput("%p", addr);
|
||||
if (addr == 0)
|
||||
return false;
|
||||
auto pos = addr + dialogSigOffset;
|
||||
auto jzoff = *(BYTE *)(pos + 1);
|
||||
pos += jzoff + 2;
|
||||
auto hookaddr = pos;
|
||||
//
|
||||
for (int i = 0; i < 0x200; i++)
|
||||
{
|
||||
//.text:000000014004116B 0F B6 13 movzx edx, byte ptr [rbx]
|
||||
//->rbx
|
||||
if ((((*(DWORD *)(pos)) & 0xffffff) == 0x13b60f))
|
||||
{
|
||||
reg = regs::rbx; // rbx
|
||||
// ConsoleOutput("%p",pos-processStartAddress);
|
||||
break;
|
||||
}
|
||||
pos += 1;
|
||||
}
|
||||
pos+=1;
|
||||
}
|
||||
if(reg==regs::invalid)return false;
|
||||
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");
|
||||
if (reg == regs::invalid)
|
||||
return false;
|
||||
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");
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -88,8 +88,7 @@ namespace ppsspp
|
||||
|
||||
void NPJH50909_filter(TextBuffer *buffer, HookParam *hp)
|
||||
{
|
||||
std::string result = buffer->strA();
|
||||
auto ws = StringToWideString(result, 932).value();
|
||||
auto ws = StringToWideString(buffer->viewA(), 932).value();
|
||||
// Remove single line markers
|
||||
ws = std::regex_replace(ws, std::wregex(L"(\\%N)+"), L" ");
|
||||
|
||||
@ -240,7 +239,7 @@ namespace ppsspp
|
||||
void N(TextBuffer *buffer, HookParam *)
|
||||
{
|
||||
auto current1 = buffer->strA();
|
||||
if(current == current1)
|
||||
if (current == current1)
|
||||
buffer->clear();
|
||||
}
|
||||
}
|
||||
|
@ -165,14 +165,14 @@ std::wstring DynamicShiftJISCodecPrivate::decode(const char* data, size_t length
|
||||
if (ch <= 127)
|
||||
ret.push_back(ch);
|
||||
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 {
|
||||
if (i + 1 == length) // no enough character
|
||||
return ret;
|
||||
UINT8 ch2 = (UINT8)data[++i];
|
||||
if ((ch >= 0x81 && ch <= 0x9f || ch >= 0xe0 && ch <= 0xef)
|
||||
&& (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)) {
|
||||
ret.push_back(c);
|
||||
if (dynamic)
|
||||
|
@ -132,7 +132,7 @@ void LunaHost::on_proc_connect(DWORD pid)
|
||||
std::string name = safequeryjson(savedhookcontext[u8procname], "name", std::string());
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
@ -94,8 +94,12 @@ typedef HRESULT(WINAPI *CONVERTINETUNICODETOMULTIBYTE)(
|
||||
LPINT lpnWideCharCount,
|
||||
LPSTR lpDstStr,
|
||||
LPINT lpnMultiCharCount);
|
||||
|
||||
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);
|
||||
if (disable_mbwc)
|
||||
@ -108,7 +112,7 @@ std::optional<std::wstring> StringToWideString(const std::string &text, UINT enc
|
||||
auto ConvertINetMultiByteToUnicode = (CONVERTINETMULTIBYTETOUNICODE)GetProcAddress(h, "ConvertINetMultiByteToUnicode");
|
||||
if (ConvertINetMultiByteToUnicode == 0)
|
||||
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))
|
||||
{
|
||||
return std::wstring(buffer.data(), _s2);
|
||||
@ -118,7 +122,7 @@ std::optional<std::wstring> StringToWideString(const std::string &text, UINT enc
|
||||
}
|
||||
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 {};
|
||||
}
|
||||
@ -128,8 +132,30 @@ std::wstring StringToWideString(const std::string &text)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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);
|
||||
if (disable_wcmb)
|
||||
@ -142,7 +168,7 @@ std::string WideStringToString(const std::wstring &text, UINT cp)
|
||||
auto ConvertINetUnicodeToMultiByte = (CONVERTINETUNICODETOMULTIBYTE)GetProcAddress(h, "ConvertINetUnicodeToMultiByte");
|
||||
if (ConvertINetUnicodeToMultiByte == 0)
|
||||
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))
|
||||
{
|
||||
return std::string(buffer.data(), _s2);
|
||||
@ -152,7 +178,7 @@ std::string WideStringToString(const std::wstring &text, UINT cp)
|
||||
}
|
||||
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();
|
||||
}
|
||||
}
|
||||
@ -171,16 +197,16 @@ inline unsigned int convertUTF32ToUTF16(unsigned int cUTF32, unsigned int &h, un
|
||||
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;
|
||||
for (size_t i = 0; i < size; i++)
|
||||
u32string utf32String;
|
||||
for (size_t i = 0; i < wsv.size(); i++)
|
||||
{
|
||||
auto u16c = u16str[i];
|
||||
auto u16c = wsv[i];
|
||||
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;
|
||||
}
|
||||
else
|
||||
@ -188,12 +214,12 @@ std::basic_string<uint32_t> utf16_to_utf32(const wchar_t *u16str, size_t size)
|
||||
// error invalid u16 char
|
||||
}
|
||||
else
|
||||
utf32String += u16str[i];
|
||||
utf32String += wsv[i];
|
||||
}
|
||||
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;
|
||||
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)
|
||||
return std::wstring((wchar_t *)data, length / sizeof(wchar_t));
|
||||
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)))
|
||||
return (converted.value());
|
||||
return converted.value();
|
||||
else
|
||||
return {};
|
||||
}
|
@ -1,6 +1,8 @@
|
||||
#ifndef __LUNA_STRINGUILTS_H
|
||||
#define __LUNA_STRINGUILTS_H
|
||||
|
||||
using u32string = std::basic_string<uint32_t>;
|
||||
using u32string_view = std::basic_string_view<uint32_t>;
|
||||
enum
|
||||
{
|
||||
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::wstring_view &s, const std::wstring_view &s2);
|
||||
std::wstring utf32_to_utf16(std::basic_string_view<uint32_t> sv);
|
||||
std::basic_string<uint32_t> utf16_to_utf32(const wchar_t *u16str, size_t size);
|
||||
std::wstring utf32_to_utf16(u32string_view sv);
|
||||
u32string utf16_to_utf32(std::wstring_view);
|
||||
|
||||
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(std::string_view);
|
||||
std::wstring StringToWideString(const char *);
|
||||
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::wstring acastw(const std::string &x);
|
||||
|
Loading…
x
Reference in New Issue
Block a user