fix some text handling with DC NTE
This commit is contained in:
@@ -2860,7 +2860,14 @@ static void on_06(shared_ptr<Client> c, uint16_t, uint32_t, string& data) {
|
||||
}
|
||||
|
||||
if (l->battle_record && l->battle_record->battle_in_progress()) {
|
||||
auto prepared_message = prepare_chat_data(c->version(), c->language(), p->disp.name.decode(c->language()), text, private_flags);
|
||||
auto prepared_message = prepare_chat_data(
|
||||
c->version(),
|
||||
c->flags & Client::Flag::IS_DC_TRIAL_EDITION,
|
||||
c->language(),
|
||||
c->lobby_client_id,
|
||||
p->disp.name.decode(c->language()),
|
||||
text,
|
||||
private_flags);
|
||||
l->battle_record->add_chat_message(c->license->serial_number, std::move(prepared_message));
|
||||
}
|
||||
}
|
||||
|
||||
+76
-31
@@ -679,10 +679,32 @@ void send_patch_file(shared_ptr<Client> c, shared_ptr<PatchFileIndex::File> f) {
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// message functions
|
||||
|
||||
void send_text(Channel& ch, StringWriter& w, uint16_t command, const string& text, bool should_add_color) {
|
||||
enum class ColorMode {
|
||||
NONE,
|
||||
ADD,
|
||||
STRIP,
|
||||
};
|
||||
|
||||
static void send_text(
|
||||
Channel& ch,
|
||||
StringWriter& w,
|
||||
uint16_t command,
|
||||
const string& text,
|
||||
ColorMode color_mode) {
|
||||
bool is_w = (ch.version == GameVersion::PC || ch.version == GameVersion::BB || ch.version == GameVersion::PATCH);
|
||||
|
||||
w.write(tt_encode_marked_optional(should_add_color ? add_color(text) : text, ch.language, is_w));
|
||||
switch (color_mode) {
|
||||
case ColorMode::NONE:
|
||||
w.write(tt_encode_marked_optional(text, ch.language, is_w));
|
||||
break;
|
||||
case ColorMode::ADD:
|
||||
w.write(tt_encode_marked_optional(add_color(text), ch.language, is_w));
|
||||
break;
|
||||
case ColorMode::STRIP:
|
||||
w.write(tt_encode_marked_optional(strip_color(text), ch.language, is_w));
|
||||
break;
|
||||
}
|
||||
|
||||
if (is_w) {
|
||||
w.put_u16(0);
|
||||
} else {
|
||||
@@ -695,15 +717,15 @@ void send_text(Channel& ch, StringWriter& w, uint16_t command, const string& tex
|
||||
ch.send(command, 0x00, w.str());
|
||||
}
|
||||
|
||||
void send_text(Channel& ch, uint16_t command, const string& text, bool should_add_color) {
|
||||
static void send_text(Channel& ch, uint16_t command, const string& text, ColorMode color_mode) {
|
||||
StringWriter w;
|
||||
send_text(ch, w, command, text, should_add_color);
|
||||
send_text(ch, w, command, text, color_mode);
|
||||
}
|
||||
|
||||
void send_header_text(Channel& ch, uint16_t command, uint32_t guild_card_number, const string& text, bool should_add_color) {
|
||||
static void send_header_text(Channel& ch, uint16_t command, uint32_t guild_card_number, const string& text, ColorMode color_mode) {
|
||||
StringWriter w;
|
||||
w.put(SC_TextHeader_01_06_11_B0_EE({0, guild_card_number}));
|
||||
send_text(ch, w, command, text, should_add_color);
|
||||
send_text(ch, w, command, text, color_mode);
|
||||
}
|
||||
|
||||
void send_message_box(shared_ptr<Client> c, const string& text) {
|
||||
@@ -724,7 +746,7 @@ void send_message_box(shared_ptr<Client> c, const string& text) {
|
||||
default:
|
||||
throw logic_error("invalid game version");
|
||||
}
|
||||
send_text(c->channel, command, text, true);
|
||||
send_text(c->channel, command, text, (c->flags & Client::Flag::IS_DC_TRIAL_EDITION) ? ColorMode::STRIP : ColorMode::ADD);
|
||||
}
|
||||
|
||||
void send_ep3_timed_message_box(Channel& ch, uint32_t frames, const string& message) {
|
||||
@@ -740,31 +762,35 @@ void send_ep3_timed_message_box(Channel& ch, uint32_t frames, const string& mess
|
||||
}
|
||||
|
||||
void send_lobby_name(shared_ptr<Client> c, const string& text) {
|
||||
send_text(c->channel, 0x8A, text, false);
|
||||
send_text(c->channel, 0x8A, text, ColorMode::NONE);
|
||||
}
|
||||
|
||||
void send_quest_info(shared_ptr<Client> c, const string& text, bool is_download_quest) {
|
||||
send_text(c->channel, is_download_quest ? 0xA5 : 0xA3, text, true);
|
||||
send_text(
|
||||
c->channel, is_download_quest ? 0xA5 : 0xA3, text,
|
||||
(c->flags & Client::Flag::IS_DC_TRIAL_EDITION) ? ColorMode::STRIP : ColorMode::ADD);
|
||||
}
|
||||
|
||||
void send_lobby_message_box(shared_ptr<Client> c, const string& text) {
|
||||
send_header_text(c->channel, 0x01, 0, text, true);
|
||||
send_header_text(c->channel, 0x01, 0, text, (c->flags & Client::Flag::IS_DC_TRIAL_EDITION) ? ColorMode::STRIP : ColorMode::ADD);
|
||||
}
|
||||
|
||||
void send_ship_info(shared_ptr<Client> c, const string& text) {
|
||||
send_header_text(c->channel, 0x11, 0, text, true);
|
||||
send_header_text(c->channel, 0x11, 0, text, (c->flags & Client::Flag::IS_DC_TRIAL_EDITION) ? ColorMode::STRIP : ColorMode::ADD);
|
||||
}
|
||||
|
||||
void send_ship_info(Channel& ch, const string& text) {
|
||||
send_header_text(ch, 0x11, 0, text, true);
|
||||
send_header_text(ch, 0x11, 0, text, ColorMode::ADD);
|
||||
}
|
||||
|
||||
void send_text_message(Channel& ch, const string& text) {
|
||||
send_header_text(ch, 0xB0, 0, text, true);
|
||||
send_header_text(ch, 0xB0, 0, text, ColorMode::ADD);
|
||||
}
|
||||
|
||||
void send_text_message(shared_ptr<Client> c, const string& text) {
|
||||
send_header_text(c->channel, 0xB0, 0, text, true);
|
||||
if (!(c->flags & Client::Flag::IS_DC_TRIAL_EDITION)) {
|
||||
send_header_text(c->channel, 0xB0, 0, text, ColorMode::ADD);
|
||||
}
|
||||
}
|
||||
|
||||
void send_text_message(shared_ptr<Lobby> l, const string& text) {
|
||||
@@ -797,26 +823,37 @@ __attribute__((format(printf, 2, 3))) void send_ep3_text_message_printf(shared_p
|
||||
}
|
||||
}
|
||||
|
||||
string prepare_chat_data(GameVersion version, uint8_t language, const string& from_name, const string& text, char private_flags) {
|
||||
string prepare_chat_data(
|
||||
GameVersion version,
|
||||
bool is_nte,
|
||||
uint8_t language,
|
||||
uint8_t from_client_id,
|
||||
const string& from_name,
|
||||
const string& text,
|
||||
char private_flags) {
|
||||
string data;
|
||||
if ((version == GameVersion::BB) || (version == GameVersion::PC)) {
|
||||
if (version == GameVersion::BB) {
|
||||
data.append("\tJ");
|
||||
}
|
||||
data.append(from_name);
|
||||
|
||||
if (version == GameVersion::BB) {
|
||||
data.append("\tJ");
|
||||
}
|
||||
data.append(from_name);
|
||||
if (is_nte) {
|
||||
data.append(string_printf(">%X", from_client_id));
|
||||
} else {
|
||||
data.append(1, '\t');
|
||||
if (private_flags) {
|
||||
data.append(1, static_cast<uint16_t>(private_flags));
|
||||
}
|
||||
}
|
||||
if (private_flags) {
|
||||
data.append(1, static_cast<uint16_t>(private_flags));
|
||||
}
|
||||
|
||||
if ((version == GameVersion::BB) || (version == GameVersion::PC)) {
|
||||
data.append(language ? "\tE" : "\tJ");
|
||||
data.append(text);
|
||||
return tt_utf8_to_utf16(data);
|
||||
} else if (is_nte) {
|
||||
data.append(tt_utf8_to_sjis(text));
|
||||
return data;
|
||||
} else {
|
||||
data.append(from_name);
|
||||
data.append(1, '\t');
|
||||
if (private_flags) {
|
||||
data.append(1, static_cast<uint16_t>(private_flags));
|
||||
}
|
||||
data.append(tt_encode_marked(text, language, false));
|
||||
return data;
|
||||
}
|
||||
@@ -830,9 +867,9 @@ void send_chat_message_from_client(Channel& ch, const string& text, char private
|
||||
string effective_text;
|
||||
effective_text.push_back(private_flags);
|
||||
effective_text += text;
|
||||
send_header_text(ch, 0x06, 0, effective_text, false);
|
||||
send_header_text(ch, 0x06, 0, effective_text, ColorMode::NONE);
|
||||
} else {
|
||||
send_header_text(ch, 0x06, 0, text, false);
|
||||
send_header_text(ch, 0x06, 0, text, ColorMode::NONE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -859,7 +896,15 @@ void send_prepared_chat_message(shared_ptr<Lobby> l, uint32_t from_guild_card_nu
|
||||
}
|
||||
|
||||
void send_chat_message(shared_ptr<Client> c, uint32_t from_guild_card_number, const string& from_name, const string& text, char private_flags) {
|
||||
send_prepared_chat_message(c, from_guild_card_number, prepare_chat_data(c->version(), c->language(), from_name, text, private_flags));
|
||||
string prepared_data = prepare_chat_data(
|
||||
c->version(),
|
||||
c->flags & Client::Flag::IS_DC_TRIAL_EDITION,
|
||||
c->language(),
|
||||
c->lobby_client_id,
|
||||
from_name,
|
||||
text,
|
||||
private_flags);
|
||||
send_prepared_chat_message(c, from_guild_card_number, prepared_data);
|
||||
}
|
||||
|
||||
template <typename CmdT>
|
||||
|
||||
@@ -189,7 +189,9 @@ void send_text_message(std::shared_ptr<ServerState> s, const std::string& text);
|
||||
|
||||
std::string prepare_chat_data(
|
||||
GameVersion version,
|
||||
bool is_nte,
|
||||
uint8_t language,
|
||||
uint8_t from_client_id,
|
||||
const std::string& from_name,
|
||||
const std::string& text,
|
||||
char private_flags);
|
||||
|
||||
+17
-4
@@ -132,7 +132,7 @@ TextTranscoder tt_utf8_to_utf16("UTF-16LE", "UTF-8");
|
||||
TextTranscoder tt_ascii_to_utf8("UTF-8", "ASCII");
|
||||
TextTranscoder tt_utf8_to_ascii("ASCII", "UTF-8");
|
||||
|
||||
std::string tt_encode_marked_optional(const std::string& utf8, uint8_t default_language, bool is_utf16) {
|
||||
string tt_encode_marked_optional(const string& utf8, uint8_t default_language, bool is_utf16) {
|
||||
if (is_utf16) {
|
||||
return tt_utf8_to_utf16(utf8);
|
||||
} else {
|
||||
@@ -152,7 +152,7 @@ std::string tt_encode_marked_optional(const std::string& utf8, uint8_t default_l
|
||||
}
|
||||
}
|
||||
|
||||
std::string tt_encode_marked(const std::string& utf8, uint8_t default_language, bool is_utf16) {
|
||||
string tt_encode_marked(const string& utf8, uint8_t default_language, bool is_utf16) {
|
||||
if (is_utf16) {
|
||||
return tt_utf8_to_utf16((default_language ? "\tE" : "\tJ") + utf8);
|
||||
} else {
|
||||
@@ -172,7 +172,7 @@ std::string tt_encode_marked(const std::string& utf8, uint8_t default_language,
|
||||
}
|
||||
}
|
||||
|
||||
std::string tt_decode_marked(const std::string& data, uint8_t default_language, bool is_utf16) {
|
||||
string tt_decode_marked(const string& data, uint8_t default_language, bool is_utf16) {
|
||||
if (is_utf16) {
|
||||
string ret = tt_utf16_to_utf8(data);
|
||||
if (ret.size() >= 2 && ret[0] == '\t' && (ret[1] == 'E' || ret[1] == 'J')) {
|
||||
@@ -286,8 +286,21 @@ void add_color(StringWriter& w, const char* src, size_t max_input_chars) {
|
||||
w.put<char>(0);
|
||||
}
|
||||
|
||||
std::string add_color(const std::string& s) {
|
||||
string add_color(const string& s) {
|
||||
StringWriter w;
|
||||
add_color(w, s.data(), s.size());
|
||||
return std::move(w.str());
|
||||
}
|
||||
|
||||
string strip_color(const string& s) {
|
||||
string ret;
|
||||
for (size_t r = 0; r < s.size(); r++) {
|
||||
if ((s[r] == '$' || s[r] == '\t') &&
|
||||
(s[r + 1] == 'C') && (((s[r + 2] >= '0') && (s[r + 2] <= '9')) || (s[r + 2] == 'G') || (s[r + 2] == 'a'))) {
|
||||
r += 2;
|
||||
} else {
|
||||
ret.push_back(s[r]);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -521,3 +521,5 @@ std::string add_color(const std::string& s);
|
||||
|
||||
size_t add_color_inplace(char* a, size_t max_chars);
|
||||
void add_color_inplace(std::string& s);
|
||||
|
||||
std::string strip_color(const std::string& s);
|
||||
|
||||
Reference in New Issue
Block a user