Decompile 7 functions in Source/Contents/MessageTable.cpp, Source/Contents/MessageTable.h, ...
Batch #1710 by ragnarok-clanker: 0 byte-identical, 7 confirmed by peer review. - fn_18371 DecodeMessageRot: logic confirmed by peer review - fn_18372 InsertMessageRow: logic confirmed by peer review - fn_18374 ImportMessageTable: logic confirmed by peer review - fn_03416 CCommonObject::ReadCsvRow: logic confirmed by peer review - fn_03418 CCommonObject::LoadCsv: logic confirmed by peer review - fn_03420 CCommonObject::OpenCsv: logic confirmed by peer review - fn_18373 ?TransformFields@?A0x79e5ab67@@YA?AV?$vector@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V?$allocator@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@2@@std@@ABV23@@Z: logic confirmed by peer review Reviewed-by: ragnarok-clanker
This commit is contained in:
parent
8125ad1ce1
commit
2845c3431d
2 changed files with 137 additions and 17 deletions
|
|
@ -1,8 +1,12 @@
|
|||
#include "Client/Input/InputCharset.h"
|
||||
#include "Contents/Configuration/ServiceConfiguration.h"
|
||||
#include "Contents/MessageTable.h"
|
||||
#include "File/CommonObject.h"
|
||||
#include "File/File.h"
|
||||
#include "Network/TextEncoding.h"
|
||||
#include "Utility/Text/Base64.h"
|
||||
#include "Utility/Text/FormatString.h"
|
||||
#include "Utility/Text/LanguageCharset.h"
|
||||
#include "Utility/Text/TextTokens.h"
|
||||
|
||||
#include <cstdio>
|
||||
|
|
@ -13,6 +17,9 @@
|
|||
// GLOBAL: gl_24382
|
||||
std::unordered_map<int, std::string> g_messageStrings;
|
||||
|
||||
// GLOBAL: gl_24601
|
||||
static CCommonObject g_messageTableObject;
|
||||
|
||||
namespace {
|
||||
const char* const messageNames[] = {
|
||||
#include "Contents/MessageNames.inc"
|
||||
|
|
@ -42,11 +49,13 @@ namespace {
|
|||
|
||||
// OFFSET: 0x00B009D0
|
||||
// FUNCTION: fn_18373
|
||||
void TransformFields(std::vector<std::string>& row) {
|
||||
std::vector<std::string> TransformFields(const std::vector<std::string>& row) {
|
||||
const char* escapes[] = {"\\r", "\\n", "\\t", "\\'", "\\\"", "\\\\"};
|
||||
const char replacements[] = {'\r', '\n', '\t', '\'', '"', '\\'};
|
||||
|
||||
for (std::string& text : row) {
|
||||
std::vector<std::string> result;
|
||||
result.reserve(row.size());
|
||||
for (std::string text : row) {
|
||||
if (text.empty()) {
|
||||
text = "NO MSG";
|
||||
} else {
|
||||
|
|
@ -56,8 +65,95 @@ namespace {
|
|||
}
|
||||
}
|
||||
}
|
||||
result.push_back(std::move(text));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
// OFFSET: 0x005B8410
|
||||
// FUNCTION: fn_03420
|
||||
bool CCommonObject::OpenCsv(const char* name, CFile& file) {
|
||||
if (!name || !std::strstr(name, ".csv") || !file.Open(name, 0, true, false)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const unsigned char* data = static_cast<const unsigned char*>(file.GetData());
|
||||
if (file.GetSize() >= 2) {
|
||||
if (data[0] == 0xFF && data[1] == 0xFE) {
|
||||
FormatOwnedString("Not Match Encoding Type : %d", 5);
|
||||
return false;
|
||||
}
|
||||
if (data[0] == 0xFE && data[1] == 0xFF) {
|
||||
FormatOwnedString("Not Match Encoding Type : %d", 7);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (file.GetSize() >= 3 && data[0] == 0xEF && data[1] == 0xBB && data[2] == 0xBF) {
|
||||
file.Seek(3, FILE_CURRENT);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// OFFSET: 0x005B7910
|
||||
// FUNCTION: fn_03416
|
||||
std::vector<std::string> CCommonObject::ReadCsvRow(CFile& file, char) {
|
||||
std::vector<std::string> row;
|
||||
std::string field;
|
||||
|
||||
while (!file.IsEOF()) {
|
||||
char value;
|
||||
file.Read(&value, 1);
|
||||
if (value == '\n' || value == '\r' || value == ',') {
|
||||
DecodeField(field, row);
|
||||
field.clear();
|
||||
if (value == '\r') {
|
||||
char next;
|
||||
if (file.Peek(&next, 1) && next == '\n') {
|
||||
file.Read(&value, 1);
|
||||
break;
|
||||
}
|
||||
} else if (value == '\n') {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
field.push_back(value);
|
||||
}
|
||||
}
|
||||
|
||||
DecodeField(field, row);
|
||||
return row;
|
||||
}
|
||||
|
||||
// OFFSET: 0x005B7CD0
|
||||
// FUNCTION: fn_03418
|
||||
bool CCommonObject::LoadCsv(const char* name, std::vector<std::string> (*transform)(const std::vector<std::string>&),
|
||||
void (*insert)(std::vector<const char*>&)) {
|
||||
CFile file;
|
||||
if (!this->OpenCsv(name, file)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
while (!file.IsEOF()) {
|
||||
std::vector<std::string> row = this->ReadCsvRow(file, ',');
|
||||
if (transform) {
|
||||
row = transform(row);
|
||||
}
|
||||
|
||||
if (insert) {
|
||||
std::vector<const char*> fields;
|
||||
fields.reserve(row.size());
|
||||
const int count = static_cast<int>(row.size());
|
||||
for (int i = 0; i < count; ++i) {
|
||||
fields.push_back(row[i].c_str());
|
||||
}
|
||||
insert(fields);
|
||||
}
|
||||
}
|
||||
|
||||
file.Close();
|
||||
return true;
|
||||
}
|
||||
|
||||
// OFFSET: 0x00B00360
|
||||
|
|
@ -86,17 +182,6 @@ int FillMessageBuckets(int* first, std::uintptr_t last, int* value) {
|
|||
return result;
|
||||
}
|
||||
|
||||
struct MessageBucketVector {
|
||||
void* begin;
|
||||
void* end;
|
||||
void* capacity;
|
||||
|
||||
void Clear();
|
||||
};
|
||||
|
||||
// OFFSET: 0x00B00520
|
||||
|
||||
|
||||
// OFFSET: 0x00B00130
|
||||
// FUNCTION: fn_18367
|
||||
void InsertMessage(int id, const char* text) {
|
||||
|
|
@ -138,7 +223,7 @@ const char* LookupMessage(int id) {
|
|||
return result.c_str();
|
||||
}
|
||||
|
||||
void InsertMessageRow(std::vector<std::string>& row);
|
||||
void InsertMessageRow(std::vector<const char*>& row);
|
||||
|
||||
bool ImportMessageCsv(std::string_view bytes) {
|
||||
g_messageStrings.clear();
|
||||
|
|
@ -176,8 +261,13 @@ bool ImportMessageCsv(std::string_view bytes) {
|
|||
}
|
||||
|
||||
DecodeField(field, row);
|
||||
TransformFields(row);
|
||||
InsertMessageRow(row);
|
||||
row = TransformFields(row);
|
||||
std::vector<const char*> fields;
|
||||
fields.reserve(row.size());
|
||||
for (const std::string& text : row) {
|
||||
fields.push_back(text.c_str());
|
||||
}
|
||||
InsertMessageRow(fields);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
@ -200,10 +290,31 @@ int FindMessageId(const char* name) {
|
|||
}
|
||||
|
||||
// OFFSET: 0x00B00890
|
||||
// FUNCTION: fn_18371
|
||||
char* DecodeMessageRot(char* str) {
|
||||
return str;
|
||||
}
|
||||
|
||||
// OFFSET: 0x00B00910
|
||||
// FUNCTION: fn_18372
|
||||
void InsertMessageRow(std::vector<const char*>& row) {
|
||||
const std::ptrdiff_t count = row.end() - row.begin();
|
||||
if (count < 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
int id = FindMessageId(row[0]);
|
||||
if (id < 4698) {
|
||||
g_messageStrings.emplace(id, row[count - 1]);
|
||||
}
|
||||
}
|
||||
|
||||
// OFFSET: 0x00B00E40
|
||||
// FUNCTION: fn_18374
|
||||
void ImportMessageTable() {
|
||||
g_messageStrings.clear();
|
||||
g_messageTableObject.LoadCsv("msgstringtable.csv", TransformFields, InsertMessageRow);
|
||||
}
|
||||
|
||||
// OFFSET: 0x00B00EC0
|
||||
// FUNCTION: fn_18375
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue