escape player-provided text in various places
This commit is contained in:
+13
-11
@@ -639,7 +639,7 @@ static void proxy_command_get_player_card(shared_ptr<ProxyServer::LinkedSession>
|
||||
send_guild_card(ses->client_channel, p.guild_card_number, p.guild_card_number, p.name, "", "", p.language, p.section_id, p.char_class);
|
||||
}
|
||||
} catch (const exception& e) {
|
||||
send_text_message_printf(ses->client_channel, "Error: %s", e.what());
|
||||
send_text_message(ses->client_channel, "Error: " + remove_color(e.what()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -685,7 +685,7 @@ static void server_command_lobby_event(shared_ptr<Client> c, const std::string&
|
||||
|
||||
uint8_t new_event = event_for_name(args);
|
||||
if (new_event == 0xFF) {
|
||||
send_text_message(c, "$C6No such lobby event.");
|
||||
send_text_message(c, "$C6No such lobby event");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -699,7 +699,7 @@ static void proxy_command_lobby_event(shared_ptr<ProxyServer::LinkedSession> ses
|
||||
} else {
|
||||
uint8_t new_event = event_for_name(args);
|
||||
if (new_event == 0xFF) {
|
||||
send_text_message(ses->client_channel, "$C6No such lobby event.");
|
||||
send_text_message(ses->client_channel, "$C6No such lobby event");
|
||||
} else {
|
||||
ses->config.override_lobby_event = new_event;
|
||||
if (!is_v1_or_v2(ses->version())) {
|
||||
@@ -714,7 +714,7 @@ static void server_command_lobby_event_all(shared_ptr<Client> c, const std::stri
|
||||
|
||||
uint8_t new_event = event_for_name(args);
|
||||
if (new_event == 0xFF) {
|
||||
send_text_message(c, "$C6No such lobby event.");
|
||||
send_text_message(c, "$C6No such lobby event");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -919,7 +919,8 @@ static void server_command_password(shared_ptr<Client> c, const std::string& arg
|
||||
|
||||
} else {
|
||||
l->password = args;
|
||||
send_text_message_printf(l, "$C6Game password:\n%s", l->password.c_str());
|
||||
string escaped = remove_color(l->password);
|
||||
send_text_message_printf(l, "$C6Game password:\n%s", escaped.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1113,7 +1114,8 @@ static void server_command_change_bank(shared_ptr<Client> c, const std::string&
|
||||
} else if (new_char_index <= 4) {
|
||||
c->use_character_bank(new_char_index - 1);
|
||||
auto bp = c->current_bank_character();
|
||||
auto name = bp->disp.name.decode(c->language());
|
||||
|
||||
auto name = escape_player_name(bp->disp.name.decode(c->language()));
|
||||
send_text_message_printf(c, "$C6Using %s\'s bank (%zu)", name.c_str(), new_char_index);
|
||||
} else {
|
||||
throw runtime_error("invalid bank number");
|
||||
@@ -1201,7 +1203,7 @@ static void server_command_save(shared_ptr<Client> c, const std::string&) {
|
||||
c->save_all();
|
||||
send_text_message(c, "All data saved");
|
||||
} catch (const exception& e) {
|
||||
send_text_message_printf(c, "Can\'t save data:\n%s", e.what());
|
||||
send_text_message(c, "Can\'t save data:\n" + remove_color(e.what()));
|
||||
}
|
||||
c->reschedule_save_game_data_event();
|
||||
}
|
||||
@@ -1212,7 +1214,7 @@ static void server_command_save(shared_ptr<Client> c, const std::string&) {
|
||||
static string name_for_client(shared_ptr<Client> c) {
|
||||
auto player = c->character(false);
|
||||
if (player.get()) {
|
||||
return player->disp.name.decode(player->inventory.language);
|
||||
return escape_player_name(player->disp.name.decode(player->inventory.language));
|
||||
}
|
||||
|
||||
if (c->license.get()) {
|
||||
@@ -1778,7 +1780,7 @@ static void server_command_surrender(shared_ptr<Client> c, const std::string&) {
|
||||
send_text_message(c, "$C6Battle has not\nyet started");
|
||||
return;
|
||||
}
|
||||
const string& name = c->character()->disp.name.decode(c->language());
|
||||
string name = remove_color(c->character()->disp.name.decode(c->language()));
|
||||
send_text_message_printf(l, "$C6%s has\nsurrendered", name.c_str());
|
||||
for (const auto& watcher_l : l->watcher_lobbies) {
|
||||
send_text_message_printf(watcher_l, "$C6%s has\nsurrendered", name.c_str());
|
||||
@@ -1983,7 +1985,7 @@ void on_chat_command(std::shared_ptr<Client> c, const std::string& text) {
|
||||
} catch (const precondition_failed& e) {
|
||||
send_text_message(c, e.what());
|
||||
} catch (const exception& e) {
|
||||
send_text_message_printf(c, "$C6Failed:\n%s", e.what());
|
||||
send_text_message(c, "$C6Failed:\n" + remove_color(e.what()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2007,7 +2009,7 @@ void on_chat_command(shared_ptr<ProxyServer::LinkedSession> ses, const std::stri
|
||||
} catch (const precondition_failed& e) {
|
||||
send_text_message(ses->client_channel, e.what());
|
||||
} catch (const exception& e) {
|
||||
send_text_message_printf(ses->client_channel, "$C6Failed:\n%s", e.what());
|
||||
send_text_message(ses->client_channel, "$C6Failed:\n" + remove_color(e.what()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1400,8 +1400,7 @@ static HandlerResult S_65_67_68_EB(shared_ptr<ProxyServer::LinkedSession> ses, u
|
||||
if (index >= ses->lobby_players.size()) {
|
||||
ses->log.warning("Ignoring invalid player index %zu at position %zu", index, x);
|
||||
} else {
|
||||
string name = entry.disp.visual.name.decode(entry.inventory.language);
|
||||
|
||||
string name = escape_player_name(entry.disp.visual.name.decode(entry.inventory.language));
|
||||
if (ses->license && (entry.lobby_data.guild_card_number == ses->remote_guild_card_number)) {
|
||||
entry.lobby_data.guild_card_number = ses->license->serial_number;
|
||||
num_replacements++;
|
||||
@@ -1578,9 +1577,10 @@ static HandlerResult S_66_69_E9(shared_ptr<ProxyServer::LinkedSession> ses, uint
|
||||
ses->log.warning("Lobby leave command references missing position");
|
||||
} else {
|
||||
auto& p = ses->lobby_players[index];
|
||||
string name = escape_player_name(p.name);
|
||||
if (ses->config.check_flag(Client::Flag::PROXY_PLAYER_NOTIFICATIONS_ENABLED)) {
|
||||
send_text_message_printf(ses->client_channel, "$C4Leave: %zu/%" PRIu32 "\n%s",
|
||||
index, p.guild_card_number, p.name.c_str());
|
||||
index, p.guild_card_number, name.c_str());
|
||||
}
|
||||
p.guild_card_number = 0;
|
||||
p.name.clear();
|
||||
|
||||
+13
-9
@@ -1786,7 +1786,7 @@ static void on_09(shared_ptr<Client> c, uint16_t, uint32_t, string& data) {
|
||||
const auto& game_c = game->clients[x];
|
||||
if (game_c.get()) {
|
||||
auto player = game_c->character();
|
||||
string name = player->disp.name.decode(game_c->language());
|
||||
string name = escape_player_name(player->disp.name.decode(game_c->language()));
|
||||
if (game->is_ep3()) {
|
||||
info += string_printf("%zu: $C6%s$C7 L%" PRIu32 "\n",
|
||||
x + 1, name.c_str(), player->disp.stats.level + 1);
|
||||
@@ -1808,16 +1808,16 @@ static void on_09(shared_ptr<Client> c, uint16_t, uint32_t, string& data) {
|
||||
bool cheats_enabled = game->check_flag(Lobby::Flag::CHEATS_ENABLED);
|
||||
bool locked = !game->password.empty();
|
||||
if (cheats_enabled && locked) {
|
||||
info += "$C4Locked$C7, $C6cheats enabled$C7\n";
|
||||
info += "$C4Locked$C7, $C6cheats on$C7\n";
|
||||
} else if (cheats_enabled) {
|
||||
info += "$C6Cheats enabled$C7\n";
|
||||
info += "$C6Cheats on$C7\n";
|
||||
} else if (locked) {
|
||||
info += "$C4Locked$C7\n";
|
||||
}
|
||||
|
||||
if (game->quest) {
|
||||
info += (game->check_flag(Lobby::Flag::JOINABLE_QUEST_IN_PROGRESS)) ? "$C6Quest: " : "$C4Quest: ";
|
||||
info += game->quest->name;
|
||||
info += remove_color(game->quest->name);
|
||||
info += "\n";
|
||||
} else if (game->check_flag(Lobby::Flag::JOINABLE_QUEST_IN_PROGRESS)) {
|
||||
info += "$C6Quest in progress\n";
|
||||
@@ -1862,17 +1862,18 @@ static void on_09(shared_ptr<Client> c, uint16_t, uint32_t, string& data) {
|
||||
auto team = tourn->get_team(team_index);
|
||||
if (team) {
|
||||
string message;
|
||||
if (team->name.empty()) {
|
||||
string team_name = escape_player_name(team->name);
|
||||
if (team_name.empty()) {
|
||||
message = "(No registrant)";
|
||||
} else if (team->max_players == 1) {
|
||||
message = string_printf("$C6%s$C7\n%zu %s (%s)\nPlayers:",
|
||||
team->name.c_str(),
|
||||
team_name.c_str(),
|
||||
team->num_rounds_cleared,
|
||||
team->num_rounds_cleared == 1 ? "win" : "wins",
|
||||
team->is_active ? "active" : "defeated");
|
||||
} else {
|
||||
message = string_printf("$C6%s$C7\n%zu %s (%s)%s\nPlayers:",
|
||||
team->name.c_str(),
|
||||
team_name.c_str(),
|
||||
team->num_rounds_cleared,
|
||||
team->num_rounds_cleared == 1 ? "win" : "wins",
|
||||
team->is_active ? "active" : "defeated",
|
||||
@@ -1883,10 +1884,13 @@ static void on_09(shared_ptr<Client> c, uint16_t, uint32_t, string& data) {
|
||||
if (player.player_name.empty()) {
|
||||
message += string_printf("\n $C6%08" PRIX32 "$C7", player.serial_number);
|
||||
} else {
|
||||
message += string_printf("\n $C6%s$C7 (%08" PRIX32 ")", player.player_name.c_str(), player.serial_number);
|
||||
string player_name = escape_player_name(player.player_name);
|
||||
message += string_printf("\n $C6%s$C7 (%08" PRIX32 ")", player_name.c_str(), player.serial_number);
|
||||
}
|
||||
} else {
|
||||
message += string_printf("\n $C3%s \"%s\"$C7", player.com_deck->player_name.c_str(), player.com_deck->deck_name.c_str());
|
||||
string player_name = escape_player_name(player.com_deck->player_name);
|
||||
string deck_name = escape_player_name(player.com_deck->deck_name);
|
||||
message += string_printf("\n $C3%s \"%s\"$C7", player_name.c_str(), deck_name.c_str());
|
||||
}
|
||||
}
|
||||
send_ship_info(c, message);
|
||||
|
||||
@@ -842,7 +842,7 @@ static void on_word_select_t(shared_ptr<Client> c, uint8_t command, uint8_t, voi
|
||||
}
|
||||
|
||||
} catch (const exception& e) {
|
||||
string name = c->character()->disp.name.decode(c->language());
|
||||
string name = escape_player_name(c->character()->disp.name.decode(c->language()));
|
||||
lc->log.warning("Untranslatable Word Select message: %s", e.what());
|
||||
send_text_message_printf(lc, "$C4Untranslatable Word\nSelect message from\n%s", name.c_str());
|
||||
}
|
||||
|
||||
+37
-1
@@ -281,7 +281,6 @@ void add_color(StringWriter& w, const char* src, size_t max_input_chars) {
|
||||
}
|
||||
src++;
|
||||
}
|
||||
w.put<char>(0);
|
||||
}
|
||||
|
||||
string add_color(const string& s) {
|
||||
@@ -290,6 +289,35 @@ string add_color(const string& s) {
|
||||
return std::move(w.str());
|
||||
}
|
||||
|
||||
void remove_color(StringWriter& w, const char* src, size_t max_input_chars) {
|
||||
for (size_t x = 0; (x < max_input_chars) && *src; x++) {
|
||||
if (*src == '$') {
|
||||
w.put<char>('%');
|
||||
w.put<char>('s');
|
||||
} else if (*src == '%') {
|
||||
w.put<char>('%');
|
||||
w.put<char>('%');
|
||||
} else if (*src == '#') {
|
||||
w.put<char>('%');
|
||||
w.put<char>('n');
|
||||
} else if (*src == '\t') {
|
||||
w.put<char>('$');
|
||||
} else if (*src == '\n') {
|
||||
w.put<char>('#');
|
||||
} else {
|
||||
w.put<char>(*src);
|
||||
}
|
||||
src++;
|
||||
}
|
||||
w.put<char>(0);
|
||||
}
|
||||
|
||||
string remove_color(const string& s) {
|
||||
StringWriter w;
|
||||
remove_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++) {
|
||||
@@ -302,3 +330,11 @@ string strip_color(const string& s) {
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
string escape_player_name(const string& name) {
|
||||
if (name.size() > 2 && name[0] == '\t' && name[1] != 'C') {
|
||||
return remove_color(name.substr(2));
|
||||
} else {
|
||||
return remove_color(name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -549,4 +549,11 @@ 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);
|
||||
|
||||
// remove_color does the opposite of add_color (it changes \t into $, for
|
||||
// example). strip_color is irreversible; it deletes color escape sequences.
|
||||
void remove_color(StringWriter& w, const char* src, size_t max_input_chars);
|
||||
std::string remove_color(const std::string& s);
|
||||
|
||||
std::string strip_color(const std::string& s);
|
||||
|
||||
std::string escape_player_name(const std::string& name);
|
||||
|
||||
Reference in New Issue
Block a user