clang-format everything

This commit is contained in:
Martin Michelsen
2023-04-16 15:44:12 -07:00
parent b733f4e199
commit 91e484e514
119 changed files with 5101 additions and 5664 deletions
+107 -147
View File
@@ -1,73 +1,69 @@
#include "SendCommands.hh"
#include <event2/buffer.h>
#include <inttypes.h>
#include <string.h>
#include <event2/buffer.h>
#include <memory>
#include <phosg/Encoding.hh>
#include <phosg/Hash.hh>
#include <phosg/Random.hh>
#include <phosg/Strings.hh>
#include <phosg/Time.hh>
#include <phosg/Hash.hh>
#include "PSOProtocol.hh"
#include "CommandFormats.hh"
#include "Compression.hh"
#include "FileContentsCache.hh"
#include "Text.hh"
#include "PSOProtocol.hh"
#include "StaticGameData.hh"
#include "Text.hh"
using namespace std;
extern const char* QUEST_BARRIER_DISCONNECT_HOOK_NAME;
extern const char* CARD_AUCTION_DISCONNECT_HOOK_NAME;
const unordered_set<uint32_t> v2_crypt_initial_client_commands({
0x00260088, // (17) DCNTE license check
0x00B0008B, // (02) DCNTE login
0x0114008B, // (02) DCNTE extended login
0x00280090, // (17) DCv1 license check
0x00B00093, // (02) DCv1 login
0x01140093, // (02) DCv1 extended login
0x00E0009A, // (17) DCv2/GCNTE license check
0x00CC009D, // (02) DCv2/GCNTE login
0x00CC019D, // (02) DCv2/GCNTE login (UDP off)
0x0130009D, // (02) DCv2/GCNTE extended login
0x0130019D, // (02) DCv2/GCNTE extended login (UDP off)
// Note: PSO PC initial commands are not listed here because we don't use a
// detector encryption for PSO PC (instead, we use the split reconnect command
// to send PC to a different port).
0x00260088, // (17) DCNTE license check
0x00B0008B, // (02) DCNTE login
0x0114008B, // (02) DCNTE extended login
0x00280090, // (17) DCv1 license check
0x00B00093, // (02) DCv1 login
0x01140093, // (02) DCv1 extended login
0x00E0009A, // (17) DCv2/GCNTE license check
0x00CC009D, // (02) DCv2/GCNTE login
0x00CC019D, // (02) DCv2/GCNTE login (UDP off)
0x0130009D, // (02) DCv2/GCNTE extended login
0x0130019D, // (02) DCv2/GCNTE extended login (UDP off)
// Note: PSO PC initial commands are not listed here because we don't use a
// detector encryption for PSO PC (instead, we use the split reconnect command
// to send PC to a different port).
});
const unordered_set<uint32_t> v3_crypt_initial_client_commands({
0x00E000DB, // (17) GC/XB license check
0x00EC009E, // (02) GC login
0x00EC019E, // (02) GC login (UDP off)
0x0150009E, // (02) GC extended login
0x0150019E, // (02) GC extended login (UDP off)
0x0130009E, // (02) XB login
0x0130019E, // (02) XB login (UDP off)
0x0194009E, // (02) XB extended login
0x0194019E, // (02) XB extended login (UDP off)
0x00E000DB, // (17) GC/XB license check
0x00EC009E, // (02) GC login
0x00EC019E, // (02) GC login (UDP off)
0x0150009E, // (02) GC extended login
0x0150019E, // (02) GC extended login (UDP off)
0x0130009E, // (02) XB login
0x0130019E, // (02) XB login (UDP off)
0x0194009E, // (02) XB extended login
0x0194019E, // (02) XB extended login (UDP off)
});
const unordered_set<string> bb_crypt_initial_client_commands({
string("\xB4\x00\x93\x00\x00\x00\x00\x00", 8),
string("\xAC\x00\x93\x00\x00\x00\x00\x00", 8),
string("\xDC\x00\xDB\x00\x00\x00\x00\x00", 8),
string("\xB4\x00\x93\x00\x00\x00\x00\x00", 8),
string("\xAC\x00\x93\x00\x00\x00\x00\x00", 8),
string("\xDC\x00\xDB\x00\x00\x00\x00\x00", 8),
});
void send_command(shared_ptr<Client> c, uint16_t command, uint32_t flag,
const void* data, size_t size) {
const void* data, size_t size) {
c->channel.send(command, flag, data, size);
}
void send_command_excluding_client(shared_ptr<Lobby> l, shared_ptr<Client> c,
uint16_t command, uint32_t flag, const void* data, size_t size) {
uint16_t command, uint32_t flag, const void* data, size_t size) {
for (auto& client : l->clients) {
if (!client || (client == c)) {
continue;
@@ -77,7 +73,7 @@ void send_command_excluding_client(shared_ptr<Lobby> l, shared_ptr<Client> c,
}
void send_command_if_not_loading(shared_ptr<Lobby> l,
uint16_t command, uint32_t flag, const void* data, size_t size) {
uint16_t command, uint32_t flag, const void* data, size_t size) {
for (auto& client : l->clients) {
if (!client || (client->flags & Client::Flag::LOADING)) {
continue;
@@ -87,12 +83,12 @@ void send_command_if_not_loading(shared_ptr<Lobby> l,
}
void send_command(shared_ptr<Lobby> l, uint16_t command, uint32_t flag,
const void* data, size_t size) {
const void* data, size_t size) {
send_command_excluding_client(l, nullptr, command, flag, data, size);
}
void send_command(shared_ptr<ServerState> s, uint16_t command, uint32_t flag,
const void* data, size_t size) {
const void* data, size_t size) {
for (auto& l : s->all_lobbies()) {
send_command(l, command, flag, data, size);
}
@@ -123,8 +119,6 @@ void send_command_with_header(Channel& ch, const void* data, size_t size) {
}
}
static const char* anti_copyright = "This server is in no way affiliated, sponsored, or supported by SEGA Enterprises or SONICTEAM. The preceding message exists only to remain compatible with programs that expect it.";
static const char* dc_port_map_copyright = "DreamCast Port Map. Copyright SEGA Enterprises. 1999";
static const char* dc_lobby_server_copyright = "DreamCast Lobby Server. Copyright SEGA Enterprises. 1999";
@@ -138,7 +132,8 @@ prepare_server_init_contents_console(
bool initial_connection = (flags & SendServerInitFlag::IS_INITIAL_CONNECTION);
S_ServerInitWithAfterMessage_DC_PC_V3_02_17_91_9B<0xB4> cmd;
cmd.basic_cmd.copyright = initial_connection
? dc_port_map_copyright : dc_lobby_server_copyright;
? dc_port_map_copyright
: dc_lobby_server_copyright;
cmd.basic_cmd.server_key = server_key;
cmd.basic_cmd.client_key = client_key;
cmd.after_message = anti_copyright;
@@ -189,7 +184,7 @@ prepare_server_init_contents_bb(
}
void send_server_init_bb(shared_ptr<ServerState> s, shared_ptr<Client> c,
uint8_t flags) {
uint8_t flags) {
bool use_secondary_message = (flags & SendServerInitFlag::USE_SECONDARY_MESSAGE);
parray<uint8_t, 0x30> server_key;
parray<uint8_t, 0x30> client_key;
@@ -245,8 +240,6 @@ void send_server_init(
}
}
void send_update_client_config(shared_ptr<Client> c) {
S_UpdateClientConfig_DC_PC_V3_04 cmd;
cmd.player_tag = 0x00010000;
@@ -255,8 +248,6 @@ void send_update_client_config(shared_ptr<Client> c) {
send_command_t(c, 0x04, 0x00, cmd);
}
template <typename CommandT>
void send_quest_open_file_t(
shared_ptr<Client> c,
@@ -396,15 +387,13 @@ void send_function_call(
ch.send(0xB2, index, w.str());
}
void send_reconnect(shared_ptr<Client> c, uint32_t address, uint16_t port) {
S_Reconnect_19 cmd = {{address, port, 0}};
send_command_t(c, (c->version() == GameVersion::PATCH) ? 0x14 : 0x19, 0x00, cmd);
}
void send_pc_console_split_reconnect(shared_ptr<Client> c, uint32_t address,
uint16_t pc_port, uint16_t console_port) {
uint16_t pc_port, uint16_t console_port) {
S_ReconnectSplit_19 cmd;
cmd.pc_address = address;
cmd.pc_port = pc_port;
@@ -416,8 +405,6 @@ void send_pc_console_split_reconnect(shared_ptr<Client> c, uint32_t address,
send_command_t(c, 0x19, 0x00, cmd);
}
void send_client_init_bb(shared_ptr<Client> c, uint32_t error) {
S_ClientInit_BB_00E6 cmd;
cmd.error = error;
@@ -434,7 +421,7 @@ void send_team_and_key_config_bb(shared_ptr<Client> c) {
}
void send_player_preview_bb(shared_ptr<Client> c, uint8_t player_index,
const PlayerDispDataBBPreview* preview) {
const PlayerDispDataBBPreview* preview) {
if (!preview) {
// no player exists
@@ -475,15 +462,15 @@ void send_guild_card_chunk_bb(shared_ptr<Client> c, size_t chunk_index) {
}
static const vector<string> stream_file_entries = {
"ItemMagEdit.prs",
"ItemPMT.prs",
"BattleParamEntry.dat",
"BattleParamEntry_on.dat",
"BattleParamEntry_lab.dat",
"BattleParamEntry_lab_on.dat",
"BattleParamEntry_ep4.dat",
"BattleParamEntry_ep4_on.dat",
"PlyLevelTbl.prs",
"ItemMagEdit.prs",
"ItemPMT.prs",
"BattleParamEntry.dat",
"BattleParamEntry_on.dat",
"BattleParamEntry_lab.dat",
"BattleParamEntry_lab_on.dat",
"BattleParamEntry_ep4.dat",
"BattleParamEntry_ep4_on.dat",
"PlyLevelTbl.prs",
};
static FileContentsCache bb_stream_files_cache(3600000000ULL);
@@ -523,19 +510,20 @@ void send_stream_file_index_bb(shared_ptr<Client> c) {
}
void send_stream_file_chunk_bb(shared_ptr<Client> c, uint32_t chunk_index) {
auto cache_result = bb_stream_files_cache.get("<BB stream file>", +[](const string&) -> string {
size_t bytes = 0;
for (const auto& name : stream_file_entries) {
bytes += bb_stream_files_cache.get_or_load("system/blueburst/" + name).file->data->size();
}
auto cache_result = bb_stream_files_cache.get(
"<BB stream file>", +[](const string&) -> string {
size_t bytes = 0;
for (const auto& name : stream_file_entries) {
bytes += bb_stream_files_cache.get_or_load("system/blueburst/" + name).file->data->size();
}
string ret;
ret.reserve(bytes);
for (const auto& name : stream_file_entries) {
ret += *bb_stream_files_cache.get_or_load("system/blueburst/" + name).file->data;
}
return ret;
});
string ret;
ret.reserve(bytes);
for (const auto& name : stream_file_entries) {
ret += *bb_stream_files_cache.get_or_load("system/blueburst/" + name).file->data;
}
return ret;
});
const auto& contents = cache_result.file->data;
S_StreamFileChunk_BB_02EB chunk_cmd;
@@ -561,8 +549,6 @@ void send_complete_player_bb(shared_ptr<Client> c) {
send_command_t(c, 0x00E7, 0x00000000, c->game_data.export_player_bb());
}
////////////////////////////////////////////////////////////////////////////////
// patch functions
@@ -596,13 +582,11 @@ void send_patch_file(shared_ptr<Client> c, shared_ptr<PatchFileIndex::File> f) {
send_command_t(c, 0x08, 0x00, close_cmd);
}
////////////////////////////////////////////////////////////////////////////////
// message functions
void send_text(Channel& ch, StringWriter& w, uint16_t command,
const u16string& text, bool should_add_color) {
const u16string& text, bool should_add_color) {
if ((ch.version == GameVersion::DC) ||
(ch.version == GameVersion::GC) ||
(ch.version == GameVersion::XB)) {
@@ -633,7 +617,7 @@ void send_text(Channel& ch, uint16_t command, const u16string& text, bool should
}
void send_header_text(Channel& ch, uint16_t command,
uint32_t guild_card_number, const u16string& text, bool should_add_color) {
uint32_t guild_card_number, const u16string& text, bool should_add_color) {
StringWriter w;
w.put(SC_TextHeader_01_06_11_B0_EE({0, guild_card_number}));
send_text(ch, w, command, text, should_add_color);
@@ -676,7 +660,7 @@ void send_lobby_name(shared_ptr<Client> c, const u16string& text) {
}
void send_quest_info(shared_ptr<Client> c, const u16string& text,
bool is_download_quest) {
bool is_download_quest) {
send_text(c->channel, is_download_quest ? 0xA5 : 0xA3, text, true);
}
@@ -766,12 +750,12 @@ void send_chat_message(Channel& ch, const u16string& text, char private_flags) {
}
void send_chat_message(shared_ptr<Client> c, uint32_t from_guild_card_number,
const u16string& prepared_data) {
const u16string& prepared_data) {
send_header_text(c->channel, 0x06, from_guild_card_number, prepared_data, false);
}
void send_chat_message(shared_ptr<Lobby> l, uint32_t from_guild_card_number,
const u16string& prepared_data) {
const u16string& prepared_data) {
for (auto c : l->clients) {
if (c) {
send_header_text(c->channel, 0x06, from_guild_card_number, prepared_data, false);
@@ -780,7 +764,7 @@ void send_chat_message(shared_ptr<Lobby> l, uint32_t from_guild_card_number,
}
void send_chat_message(shared_ptr<Client> c, uint32_t from_guild_card_number,
const u16string& from_name, const u16string& text, char private_flags) {
const u16string& from_name, const u16string& text, char private_flags) {
auto data = prepare_chat_message(c->version(), from_name, text, private_flags);
send_chat_message(c, from_guild_card_number, data);
}
@@ -816,7 +800,7 @@ void send_simple_mail_bb(
}
void send_simple_mail(shared_ptr<Client> c, uint32_t from_guild_card_number,
const u16string& from_name, const u16string& text) {
const u16string& from_name, const u16string& text) {
switch (c->version()) {
case GameVersion::DC:
case GameVersion::GC:
@@ -836,8 +820,6 @@ void send_simple_mail(shared_ptr<Client> c, uint32_t from_guild_card_number,
}
}
////////////////////////////////////////////////////////////////////////////////
// info board
@@ -866,8 +848,6 @@ void send_info_board(shared_ptr<Client> c, shared_ptr<Lobby> l) {
}
}
template <typename CommandHeaderT, typename CharT>
void send_card_search_result_t(
shared_ptr<ServerState> s,
@@ -892,13 +872,13 @@ void send_card_search_result_t(
if (result_lobby->is_game()) {
string encoded_lobby_name = encode_sjis(result_lobby->name);
location_string = string_printf("%s,BLOCK01,%s",
encoded_lobby_name.c_str(), encoded_server_name.c_str());
encoded_lobby_name.c_str(), encoded_server_name.c_str());
} else if (result_lobby->is_ep3()) {
location_string = string_printf("BLOCK01-C%02" PRIu32 ",BLOCK01,%s",
result_lobby->lobby_id - 15, encoded_server_name.c_str());
result_lobby->lobby_id - 15, encoded_server_name.c_str());
} else {
location_string = string_printf("BLOCK01-%02" PRIu32 ",BLOCK01,%s",
result_lobby->lobby_id, encoded_server_name.c_str());
result_lobby->lobby_id, encoded_server_name.c_str());
}
cmd.location_string = location_string;
cmd.extension.lobby_refs[0].menu_id = MenuID::LOBBY;
@@ -929,8 +909,6 @@ void send_card_search_result(
}
}
template <typename CmdT>
void send_guild_card_dc_pc_v3_t(
Channel& ch,
@@ -1019,8 +997,6 @@ void send_guild_card(shared_ptr<Client> c, shared_ptr<Client> source) {
c->channel, guild_card_number, name, u"", description, section_id, char_class);
}
////////////////////////////////////////////////////////////////////////////////
// menus
@@ -1091,7 +1067,7 @@ void send_menu_t(
}
void send_menu(shared_ptr<Client> c, const u16string& menu_name,
uint32_t menu_id, const vector<MenuItem>& items, bool is_info_menu) {
uint32_t menu_id, const vector<MenuItem>& items, bool is_info_menu) {
if (c->version() == GameVersion::PC ||
c->version() == GameVersion::PATCH ||
c->version() == GameVersion::BB) {
@@ -1101,8 +1077,6 @@ void send_menu(shared_ptr<Client> c, const u16string& menu_name,
}
}
template <typename CharT>
void send_game_menu_t(
shared_ptr<Client> c,
@@ -1212,8 +1186,6 @@ void send_game_menu(
}
}
template <typename EntryT>
void send_quest_menu_t(
shared_ptr<Client> c,
@@ -1251,7 +1223,7 @@ void send_quest_menu_t(
}
void send_quest_menu(shared_ptr<Client> c, uint32_t menu_id,
const vector<shared_ptr<const Quest>>& quests, bool is_download_menu) {
const vector<shared_ptr<const Quest>>& quests, bool is_download_menu) {
switch (c->version()) {
case GameVersion::PC:
send_quest_menu_t<S_QuestMenuEntry_PC_A2_A4>(c, menu_id, quests, is_download_menu);
@@ -1272,7 +1244,7 @@ void send_quest_menu(shared_ptr<Client> c, uint32_t menu_id,
}
void send_quest_menu(shared_ptr<Client> c, uint32_t menu_id,
const vector<MenuItem>& items, bool is_download_menu) {
const vector<MenuItem>& items, bool is_download_menu) {
switch (c->version()) {
case GameVersion::PC:
send_quest_menu_t<S_QuestMenuEntry_PC_A2_A4>(c, menu_id, items, is_download_menu);
@@ -1317,8 +1289,6 @@ void send_lobby_list(shared_ptr<Client> c, shared_ptr<ServerState> s) {
send_command_vt(c, 0x83, entries.size(), entries);
}
////////////////////////////////////////////////////////////////////////////////
// lobby joining
@@ -1498,7 +1468,7 @@ void send_join_game_t(shared_ptr<Client> c, shared_ptr<Lobby> l) {
template <typename LobbyDataT, typename DispDataT>
void send_join_lobby_t(shared_ptr<Client> c, shared_ptr<Lobby> l,
shared_ptr<Client> joining_client = nullptr) {
shared_ptr<Client> joining_client = nullptr) {
uint8_t command;
if (l->is_game()) {
if (joining_client) {
@@ -1616,7 +1586,7 @@ void send_join_lobby(shared_ptr<Client> c, shared_ptr<Lobby> l) {
}
void send_player_join_notification(shared_ptr<Client> c,
shared_ptr<Lobby> l, shared_ptr<Client> joining_client) {
shared_ptr<Lobby> l, shared_ptr<Client> joining_client) {
switch (c->version()) {
case GameVersion::PC:
send_join_lobby_t<PlayerLobbyDataPC, PlayerDispDataDCPCV3>(c, l, joining_client);
@@ -1664,13 +1634,11 @@ void send_get_player_info(shared_ptr<Client> c) {
}
}
////////////////////////////////////////////////////////////////////////////////
// Trade window
void send_execute_item_trade(shared_ptr<Client> c,
const vector<ItemData>& items) {
const vector<ItemData>& items) {
SC_TradeItems_D0_D3 cmd;
if (items.size() > sizeof(cmd.items) / sizeof(cmd.items[0])) {
throw logic_error("too many items in execute trade command");
@@ -1684,7 +1652,7 @@ void send_execute_item_trade(shared_ptr<Client> c,
}
void send_execute_card_trade(shared_ptr<Client> c,
const vector<pair<uint32_t, uint32_t>>& card_to_count) {
const vector<pair<uint32_t, uint32_t>>& card_to_count) {
if (!(c->flags & Client::Flag::IS_EPISODE_3)) {
throw logic_error("cannot send trade cards command to non-Ep3 client");
}
@@ -1709,8 +1677,6 @@ void send_execute_card_trade(shared_ptr<Client> c,
send_command_t(c, 0xEE, 0xD3, cmd);
}
////////////////////////////////////////////////////////////////////////////////
// arrows
@@ -1741,8 +1707,6 @@ void send_resume_game(shared_ptr<Lobby> l, shared_ptr<Client> ready_client) {
send_command_excluding_client(l, ready_client, 0x60, 0x00, &data, sizeof(be_uint32_t));
}
////////////////////////////////////////////////////////////////////////////////
// Game/cheat commands
@@ -1763,7 +1727,7 @@ static vector<G_UpdatePlayerStat_6x9A> generate_stats_change_subcommands(
}
void send_player_stats_change(shared_ptr<Lobby> l, shared_ptr<Client> c,
PlayerStatsChange stat, uint32_t amount) {
PlayerStatsChange stat, uint32_t amount) {
auto subs = generate_stats_change_subcommands(c->lobby_client_id, stat, amount);
send_command_vt(l, (subs.size() > 0x400 / sizeof(G_UpdatePlayerStat_6x9A)) ? 0x6C : 0x60, 0x00, subs);
}
@@ -1789,48 +1753,46 @@ void send_ep3_change_music(Channel& ch, uint32_t song) {
}
void send_set_player_visibility(shared_ptr<Lobby> l, shared_ptr<Client> c,
bool visible) {
bool visible) {
uint8_t subcmd = visible ? 0x23 : 0x22;
uint16_t client_id = c->lobby_client_id;
G_SetPlayerVisibility_6x22_6x23 cmd = {{subcmd, 0x01, client_id}};
send_command_t(l, 0x60, 0x00, cmd);
}
////////////////////////////////////////////////////////////////////////////////
// BB game commands
void send_drop_item(Channel& ch, const ItemData& item,
bool from_enemy, uint8_t area, float x, float z, uint16_t request_id) {
bool from_enemy, uint8_t area, float x, float z, uint16_t request_id) {
G_DropItem_PC_V3_BB_6x5F cmd = {
{{0x5F, 0x0B, 0x0000}, area, from_enemy, request_id, x, z, 0, 0, item}, 0};
ch.send(0x60, 0x00, &cmd, sizeof(cmd));
}
void send_drop_item(shared_ptr<Lobby> l, const ItemData& item,
bool from_enemy, uint8_t area, float x, float z, uint16_t request_id) {
bool from_enemy, uint8_t area, float x, float z, uint16_t request_id) {
G_DropItem_PC_V3_BB_6x5F cmd = {
{{0x5F, 0x0B, 0x0000}, area, from_enemy, request_id, x, z, 0, 0, item}, 0};
send_command_t(l, 0x60, 0x00, cmd);
}
void send_drop_stacked_item(Channel& ch, const ItemData& item,
uint8_t area, float x, float z) {
uint8_t area, float x, float z) {
G_DropStackedItem_PC_V3_BB_6x5D cmd = {
{{0x5D, 0x0A, 0x0000}, area, 0, x, z, item}, 0};
ch.send(0x60, 0x00, &cmd, sizeof(cmd));
}
void send_drop_stacked_item(shared_ptr<Lobby> l, const ItemData& item,
uint8_t area, float x, float z) {
uint8_t area, float x, float z) {
G_DropStackedItem_PC_V3_BB_6x5D cmd = {
{{0x5D, 0x0A, 0x0000}, area, 0, x, z, item}, 0};
send_command_t(l, 0x60, 0x00, cmd);
}
void send_pick_up_item(shared_ptr<Lobby> l, shared_ptr<Client> c,
uint32_t item_id, uint8_t area) {
uint32_t item_id, uint8_t area) {
uint16_t client_id = c->lobby_client_id;
G_PickUpItem_6x59 cmd = {
{0x59, 0x03, client_id}, client_id, area, item_id};
@@ -1840,7 +1802,7 @@ void send_pick_up_item(shared_ptr<Lobby> l, shared_ptr<Client> c,
// Creates an item in a player's inventory (used for withdrawing items from the
// bank)
void send_create_inventory_item(shared_ptr<Lobby> l, shared_ptr<Client> c,
const ItemData& item) {
const ItemData& item) {
uint16_t client_id = c->lobby_client_id;
G_CreateInventoryItem_BB_6xBE cmd = {{0xBE, 0x07, client_id}, item, 0};
send_command_t(l, 0x60, 0x00, cmd);
@@ -1848,7 +1810,7 @@ void send_create_inventory_item(shared_ptr<Lobby> l, shared_ptr<Client> c,
// destroys an item
void send_destroy_item(shared_ptr<Lobby> l, shared_ptr<Client> c,
uint32_t item_id, uint32_t amount) {
uint32_t item_id, uint32_t amount) {
uint16_t client_id = c->lobby_client_id;
G_DeleteInventoryItem_6x29 cmd = {{0x29, 0x03, client_id}, item_id, amount};
send_command_t(l, 0x60, 0x00, cmd);
@@ -1857,7 +1819,7 @@ void send_destroy_item(shared_ptr<Lobby> l, shared_ptr<Client> c,
// sends the player their bank data
void send_bank(shared_ptr<Client> c) {
vector<PlayerBankItem> items(c->game_data.player()->bank.items,
&c->game_data.player()->bank.items[c->game_data.player()->bank.num_items]);
&c->game_data.player()->bank.items[c->game_data.player()->bank.num_items]);
uint32_t checksum = random_object<uint32_t>();
G_BankContentsHeader_BB_6xBC cmd = {
@@ -1874,11 +1836,11 @@ void send_shop(shared_ptr<Client> c, uint8_t shop_type) {
const auto& contents = c->game_data.shop_contents.at(shop_type);
G_ShopContents_BB_6xB6 cmd = {
{0xB6, static_cast<uint8_t>(2 + (sizeof(ItemData) >> 2) * contents.size()), 0x0000},
shop_type,
static_cast<uint8_t>(contents.size()),
0,
{},
{0xB6, static_cast<uint8_t>(2 + (sizeof(ItemData) >> 2) * contents.size()), 0x0000},
shop_type,
static_cast<uint8_t>(contents.size()),
0,
{},
};
for (size_t x = 0; x < contents.size(); x++) {
cmd.entries[x] = contents[x];
@@ -1916,15 +1878,13 @@ void send_level_up(shared_ptr<Lobby> l, shared_ptr<Client> c) {
// gives a player EXP
void send_give_experience(shared_ptr<Lobby> l, shared_ptr<Client> c,
uint32_t amount) {
uint32_t amount) {
uint16_t client_id = c->lobby_client_id;
G_GiveExperience_BB_6xBF cmd = {
{0xBF, sizeof(G_GiveExperience_BB_6xBF) / 4, client_id}, amount};
send_command_t(l, 0x60, 0x00, cmd);
}
////////////////////////////////////////////////////////////////////////////////
// ep3 only commands
@@ -2033,7 +1993,8 @@ void send_ep3_tournament_list(
}
auto& entry = cmd.entries[z];
entry.menu_id = is_for_spectator_team_create
? MenuID::TOURNAMENTS_FOR_SPEC : MenuID::TOURNAMENTS;
? MenuID::TOURNAMENTS_FOR_SPEC
: MenuID::TOURNAMENTS;
entry.item_id = tourn->get_number();
// TODO: What does it mean for a tournament to be locked? Should we support
// that?
@@ -2043,7 +2004,8 @@ void send_ep3_tournament_list(
// as long as the winners of the preceding matches have been determined.
entry.state =
(tourn->get_state() == Episode3::Tournament::State::REGISTRATION)
? 0x00 : 0x05;
? 0x00
: 0x05;
// TODO: Fill in cmd.start_time here when we implement scheduled starts.
entry.name = tourn->get_name();
const auto& teams = tourn->all_teams();
@@ -2216,8 +2178,8 @@ void send_ep3_game_details(shared_ptr<Client> c, shared_ptr<Lobby> l) {
flag = 0x04;
} else if (primary_lobby &&
primary_lobby->ep3_server_base &&
primary_lobby->ep3_server_base->server->get_setup_phase() != Episode3::SetupPhase::REGISTRATION) {
primary_lobby->ep3_server_base &&
primary_lobby->ep3_server_base->server->get_setup_phase() != Episode3::SetupPhase::REGISTRATION) {
cmd.rules = primary_lobby->ep3_server_base->map_and_rules1->rules;
flag = 0x01;
@@ -2313,8 +2275,8 @@ void send_ep3_tournament_match_result(
G_TournamentMatchResult_GC_Ep3_6xB4x51 cmd;
cmd.match_description = (match == tourn->get_final_match())
? string_printf("(%s) Final match", tourn->get_name().c_str())
: string_printf("(%s) Round %zu", tourn->get_name().c_str(), match->round_num);
? string_printf("(%s) Final match", tourn->get_name().c_str())
: string_printf("(%s) Round %zu", tourn->get_name().c_str(), match->round_num);
cmd.names_entries[0].team_name = match->preceding_a->winner_team->name;
write_player_names(cmd.names_entries[0], match->preceding_a->winner_team);
cmd.names_entries[1].team_name = match->preceding_b->winner_team->name;
@@ -2408,8 +2370,6 @@ void set_mask_for_ep3_game_command(void* vdata, size_t size, uint8_t mask_key) {
header->mask_key = mask_key;
}
void send_quest_file_chunk(
shared_ptr<Client> c,
const string& filename,
@@ -2433,7 +2393,7 @@ void send_quest_file_chunk(
}
void send_open_quest_file(shared_ptr<Client> c, const string& quest_name,
const string& basename, shared_ptr<const string> contents, QuestFileType type) {
const string& basename, shared_ptr<const string> contents, QuestFileType type) {
switch (c->version()) {
case GameVersion::DC:
@@ -2463,7 +2423,7 @@ void send_open_quest_file(shared_ptr<Client> c, const string& quest_name,
chunk_bytes = 0x400;
}
send_quest_file_chunk(c, basename.c_str(), offset / 0x400,
contents->data() + offset, chunk_bytes, (type != QuestFileType::ONLINE));
contents->data() + offset, chunk_bytes, (type != QuestFileType::ONLINE));
}
} else {
c->sending_files.emplace(basename, contents);
@@ -2534,7 +2494,7 @@ void send_card_auction_if_all_clients_ready(
num_cards = s->ep3_card_auction_min_size;
} else {
num_cards = s->ep3_card_auction_min_size +
(random_object<uint16_t>() % (s->ep3_card_auction_max_size - s->ep3_card_auction_min_size + 1));
(random_object<uint16_t>() % (s->ep3_card_auction_max_size - s->ep3_card_auction_min_size + 1));
}
num_cards = min<uint16_t>(num_cards, 0x14);
@@ -2574,7 +2534,7 @@ void send_server_time(shared_ptr<Client> c) {
string time_str(128, 0);
size_t len = strftime(time_str.data(), time_str.size(),
"%Y:%m:%d: %H:%M:%S.000", &t_parsed);
"%Y:%m:%d: %H:%M:%S.000", &t_parsed);
if (len == 0) {
throw runtime_error("format_time buffer too short");
}