make all file/network-related structs packed

This commit is contained in:
Martin Michelsen
2022-03-29 00:12:16 -07:00
parent b61a9bcdcb
commit 5c388c4052
12 changed files with 147 additions and 149 deletions
+1
View File
@@ -30,6 +30,7 @@ Current known issues / missing features:
- The trade window isn't implemented yet.
- PSO PC and PSOBB are essentially entirely untested. Only GC is fairly well-tested.
- Add all the chat commands that khyller used to have. (Most, but not all, currently exist in newserv.)
- The command structures are defined in multiple places. Centralize them.
## Usage
+2 -2
View File
@@ -16,7 +16,7 @@ struct LevelStats {
uint32_t experience; // EXP value of this level
void apply(PlayerStats& ps) const;
};
} __attribute__((packed));
// level table format (PlyLevelTbl.prs)
struct LevelTable {
@@ -28,4 +28,4 @@ struct LevelTable {
const PlayerStats& base_stats_for_class(uint8_t char_class) const;
const LevelStats& stats_for_level(uint8_t char_class, uint8_t level) const;
};
} __attribute__((packed));
+1 -1
View File
@@ -74,7 +74,7 @@ struct EnemyEntry {
uint32_t reserved14;
uint32_t skin;
uint32_t reserved15;
};
} __attribute__((packed));
static vector<PSOEnemy> parse_map(uint8_t episode, uint8_t difficulty,
const BattleParams* battle_params, const EnemyEntry* map,
+4 -4
View File
@@ -17,7 +17,7 @@ struct BattleParams {
uint8_t unknown[14];
uint32_t experience;
uint32_t difficulty;
};
} __attribute__((packed));
struct BattleParamTable {
BattleParams entries[2][3][4][0x60]; // online/offline, episode, difficulty, monster type
@@ -28,13 +28,13 @@ struct BattleParamTable {
uint8_t monster_type) const;
const BattleParams* get_subtable(bool solo, uint8_t episode,
uint8_t difficulty) const;
};
} __attribute__((packed));
struct BattleParamIndex {
BattleParamTable table_for_episode[3];
};
} __attribute__((packed));
// an enemy entry as loaded by the game
struct PSOEnemy {
@@ -46,7 +46,7 @@ struct PSOEnemy {
PSOEnemy();
PSOEnemy(uint32_t experience, uint32_t rt_index);
};
} __attribute__((packed));
std::vector<PSOEnemy> load_map(const char* filename, uint8_t episode,
uint8_t difficulty, const BattleParams* bp, bool alt_enemies);
+1 -1
View File
@@ -59,7 +59,7 @@ public:
struct KeyFile {
uint32_t initial_keys[18];
uint32_t private_keys[1024];
};
} __attribute__((packed));
PSOBBEncryption(const KeyFile& key, const void* seed, size_t seed_size);
+30 -30
View File
@@ -17,16 +17,16 @@ struct ItemData {
uint8_t item_data1[12];
uint16_t item_data1w[6];
uint32_t item_data1d[3];
};
} __attribute__((packed));
uint32_t item_id;
union {
uint8_t item_data2[4];
uint16_t item_data2w[2];
uint32_t item_data2d;
};
} __attribute__((packed));
uint32_t primary_identifier() const;
};
} __attribute__((packed));
struct PlayerBankItem;
@@ -38,7 +38,7 @@ struct PlayerInventoryItem {
ItemData data;
PlayerBankItem to_bank_item() const;
};
} __attribute__((packed));
// an item in a player's bank
struct PlayerBankItem {
@@ -47,7 +47,7 @@ struct PlayerBankItem {
uint16_t show_flags;
PlayerInventoryItem to_inventory_item() const;
};
} __attribute__((packed));
// a player's inventory (remarkably, the format is the same in all versions of PSO)
struct PlayerInventory {
@@ -58,7 +58,7 @@ struct PlayerInventory {
PlayerInventoryItem items[30];
size_t find_item(uint32_t item_id);
};
} __attribute__((packed));
// a player's bank
struct PlayerBank {
@@ -74,7 +74,7 @@ struct PlayerBank {
void add_item(const PlayerBankItem& item);
void remove_item(uint32_t item_id, uint32_t amount, PlayerBankItem* item);
size_t find_item(uint32_t item_id);
};
} __attribute__((packed));
@@ -87,7 +87,7 @@ struct PlayerStats {
uint16_t dfp;
uint16_t ata;
uint16_t lck;
};
} __attribute__((packed));
struct PlayerDispDataBB;
@@ -124,7 +124,7 @@ struct PlayerDispDataPCGC { // 0xD0 in size
uint8_t technique_levels[0x14];
PlayerDispDataBB to_bb() const;
};
} __attribute__((packed));
// BB player preview format
struct PlayerDispDataBBPreview {
@@ -153,7 +153,7 @@ struct PlayerDispDataBBPreview {
float proportion_y;
char16_t name[16];
uint32_t play_time;
};
} __attribute__((packed));
// BB player appearance and stats data
struct PlayerDispDataBB {
@@ -192,7 +192,7 @@ struct PlayerDispDataBB {
PlayerDispDataPCGC to_pcgc() const;
PlayerDispDataBBPreview to_preview() const;
void apply_preview(const PlayerDispDataBBPreview&);
};
} __attribute__((packed));
@@ -205,7 +205,7 @@ struct GuildCardGC {
uint8_t reserved2; // should be 1
uint8_t section_id;
uint8_t char_class;
};
} __attribute__((packed));
// BB guild card format
struct GuildCardBB {
@@ -217,20 +217,20 @@ struct GuildCardBB {
uint8_t reserved2; // should be 1
uint8_t section_id;
uint8_t char_class;
};
} __attribute__((packed));
// an entry in the BB guild card file
struct GuildCardEntryBB {
GuildCardBB data;
uint8_t unknown[0xB4];
};
} __attribute__((packed));
// the format of the BB guild card file
struct GuildCardFileBB {
uint8_t unknown[0x1F84];
GuildCardEntryBB entry[0x0068]; // that's 104 of them in decimal
uint8_t unknown2[0x01AC];
};
} __attribute__((packed));
// PSOBB key config and team info
struct KeyAndTeamConfigBB {
@@ -242,10 +242,10 @@ struct KeyAndTeamConfigBB {
uint32_t team_info[2]; // 02C0
uint16_t team_privilege_level; // 02C8
uint16_t reserved; // 02CA
char16_t team_name[0x0010]; // 02CC
char16_t team_name[0x0010]; // 02CC
uint8_t team_flag[0x0800]; // 02EC
uint32_t team_rewards[2]; // 0AEC
};
} __attribute__((packed));
// BB account data
struct PlayerAccountDataBB {
@@ -254,7 +254,7 @@ struct PlayerAccountDataBB {
GuildCardFileBB guild_cards;
uint32_t options;
uint8_t shortcuts[0x0A40]; // chat shortcuts (@1FB4 in E7 command)
};
} __attribute__((packed));
@@ -264,7 +264,7 @@ struct PlayerLobbyDataPC {
be_uint32_t ip_address;
uint32_t client_id;
char16_t name[16];
};
} __attribute__((packed));
struct PlayerLobbyDataGC {
uint32_t player_tag;
@@ -272,7 +272,7 @@ struct PlayerLobbyDataGC {
be_uint32_t ip_address;
uint32_t client_id;
char name[16];
};
} __attribute__((packed));
struct PlayerLobbyDataBB {
uint32_t player_tag;
@@ -281,14 +281,14 @@ struct PlayerLobbyDataBB {
uint32_t client_id;
char16_t name[16];
uint32_t unknown2;
};
} __attribute__((packed));
struct PSOPlayerDataPC { // for command 0x61
PlayerInventory inventory;
PlayerDispDataPCGC disp;
};
} __attribute__((packed));
struct PSOPlayerDataGC { // for command 0x61
PlayerInventory inventory;
@@ -298,7 +298,7 @@ struct PSOPlayerDataGC { // for command 0x61
uint32_t blocked[0x1E];
uint32_t auto_reply_enabled;
char auto_reply[0];
};
} __attribute__((packed));
struct PSOPlayerDataBB { // for command 0x61
PlayerInventory inventory;
@@ -308,19 +308,19 @@ struct PSOPlayerDataBB { // for command 0x61
uint32_t blocked[0x1E];
uint32_t auto_reply_enabled;
char16_t auto_reply[0];
};
} __attribute__((packed));
// PC/GC lobby player data (used in lobby/game join commands)
struct PlayerLobbyJoinDataPCGC {
PlayerInventory inventory;
PlayerDispDataPCGC disp;
};
} __attribute__((packed));
// BB lobby player data (used in lobby/game join commands)
struct PlayerLobbyJoinDataBB {
PlayerInventory inventory;
PlayerDispDataBB disp;
};
} __attribute__((packed));
// complete BB player data format (used in E7 command)
struct PlayerBB {
@@ -349,7 +349,7 @@ struct PlayerBB {
uint8_t unknown6[0x002C]; // 2E20 //
uint8_t quest_data2[0x0058]; // 2E4C // player
KeyAndTeamConfigBB key_config; // 2EA4 // account
}; // total size: 39A0
} __attribute__((packed)); // total size: 39A0
@@ -367,7 +367,7 @@ struct SavedPlayerBB { // .nsc file format
uint8_t quest_data1[0x0208];
uint8_t quest_data2[0x0058];
uint8_t tech_menu_config[0x0028];
};
} __attribute__((packed));
struct SavedAccountBB { // .nsa file format
char signature[0x40];
@@ -378,7 +378,7 @@ struct SavedAccountBB { // .nsa file format
uint8_t shortcuts[0x0A40];
uint8_t symbol_chats[0x04E0];
char16_t team_name[0x0010];
};
} __attribute__((packed));
// complete player info stored by the server
struct Player {
@@ -424,7 +424,7 @@ struct Player {
void add_item(const PlayerInventoryItem& item);
void remove_item(uint32_t item_id, uint32_t amount, PlayerInventoryItem* item);
size_t find_item(uint32_t item_id);
};
} __attribute__((packed));
+7 -7
View File
@@ -22,7 +22,7 @@ struct PSODownloadQuestHeader {
be_uint32_t size;
// Note: use PSO PC encryption, even for GC quests.
be_uint32_t encryption_seed;
};
} __attribute__((packed));
@@ -80,7 +80,7 @@ struct PSOQuestHeaderDC { // same for dc v1 and v2, thankfully
char name[0x20];
char short_description[0x80];
char long_description[0x120];
};
} __attribute__((packed));
struct PSOQuestHeaderPC {
uint32_t start_offset;
@@ -93,7 +93,7 @@ struct PSOQuestHeaderPC {
char16_t name[0x20];
char16_t short_description[0x80];
char16_t long_description[0x120];
};
} __attribute__((packed));
struct PSOQuestHeaderGC {
uint32_t start_offset;
@@ -107,7 +107,7 @@ struct PSOQuestHeaderGC {
char name[0x20];
char short_description[0x80];
char long_description[0x120];
};
} __attribute__((packed));
struct PSOQuestHeaderGCEpisode3 {
// there's actually a lot of other important stuff in here but I'm lazy. it
@@ -119,7 +119,7 @@ struct PSOQuestHeaderGCEpisode3 {
char location2[0x3C];
char description[0x190];
uint8_t unused2[0x3A34];
};
} __attribute__((packed));
struct PSOQuestHeaderBB {
uint32_t start_offset;
@@ -135,7 +135,7 @@ struct PSOQuestHeaderBB {
char16_t name[0x20];
char16_t short_description[0x80];
char16_t long_description[0x120];
};
} __attribute__((packed));
@@ -375,7 +375,7 @@ string Quest::decode_gci(const string& filename) {
uint32_t unknown2;
uint32_t decompressed_size;
uint32_t unknown4;
};
} __attribute__((packed));
if (compressed_data_with_header.size() < sizeof(DecryptedHeader)) {
throw runtime_error("GCI file compressed data truncated during header");
}
+3 -2
View File
@@ -7,9 +7,10 @@
struct RareItemDrop {
uint8_t probability;
uint8_t item_code[3];
};
} __attribute__((packed));
struct RareItemSet {
// 0x280 in size; describes one difficulty, section ID, and episode
RareItemDrop rares[0x65]; // 0000 - 0194 in file
uint8_t box_areas[0x1E]; // 0194 - 01B2 in file
RareItemDrop box_rares[0x1E]; // 01B2 - 022A in file
@@ -17,6 +18,6 @@ struct RareItemSet {
RareItemSet(const char* filename, uint8_t episode, uint8_t difficulty,
uint8_t secid);
}; // 0x280 in size; describes one difficulty, section ID, and episode
} __attribute__((packed));
bool sample_rare_item(uint8_t pc);
+25 -25
View File
@@ -229,7 +229,7 @@ void process_login_a_dc_pc_gc(shared_ptr<ServerState> s, shared_ptr<Client> c,
char unused[0x20];
char serial_number[0x10];
char access_key[0x10];
};
} __attribute__((packed));
check_size(size, sizeof(Cmd));
const auto* cmd = reinterpret_cast<const Cmd*>(data);
@@ -265,7 +265,7 @@ void process_login_c_dc_pc_gc(shared_ptr<ServerState> s, shared_ptr<Client> c,
char serial_number[0x30];
char access_key[0x30];
char password[0x30];
};
} __attribute__((packed));
check_size(size, sizeof(Cmd));
const auto* cmd = reinterpret_cast<const Cmd*>(data);
@@ -354,7 +354,7 @@ void process_login_bb(shared_ptr<ServerState> s, shared_ptr<Client> c,
char password[0x10];
char unused3[0x30];
ClientConfig cfg;
};
} __attribute__((packed));
check_size(size, sizeof(Cmd));
const auto* cmd = reinterpret_cast<const Cmd*>(data);
@@ -436,12 +436,12 @@ void process_ep3_jukebox(shared_ptr<ServerState> s, shared_ptr<Client> c,
uint32_t transaction_num;
uint32_t value;
uint32_t unknown_token;
};
} __attribute__((packed));
struct OutputCmd {
uint32_t remaining_meseta;
uint32_t unknown;
uint32_t unknown_token;
};
} __attribute__((packed));
check_size(size, sizeof(InputCmd));
const auto* in_cmd = reinterpret_cast<const InputCmd*>(data);
@@ -582,7 +582,7 @@ void process_menu_item_info_request(shared_ptr<ServerState> s, shared_ptr<Client
struct Cmd {
uint32_t menu_id;
uint32_t item_id;
};
} __attribute__((packed));
check_size(size, sizeof(Cmd), sizeof(Cmd));
const auto* cmd = reinterpret_cast<const Cmd*>(data);
@@ -664,10 +664,10 @@ void process_menu_selection(shared_ptr<ServerState> s, shared_ptr<Client> c,
uint32_t menu_id;
uint32_t item_id;
union {
char16_t password_pc_bb[0];
char password_dc_gc[0];
};
};
char16_t pc_bb[0];
char dc_gc[0];
} __attribute__((packed)) password;
} __attribute__((packed));
check_size(size, sizeof(Cmd), sizeof(Cmd) + 0x10 * (1 + uses_unicode));
const auto* cmd = reinterpret_cast<const Cmd*>(data);
@@ -796,9 +796,9 @@ void process_menu_selection(shared_ptr<ServerState> s, shared_ptr<Client> c,
char16_t password[0x10];
if (size > sizeof(Cmd)) {
if (uses_unicode) {
char16cpy(password, cmd->password_pc_bb, 0x10);
char16cpy(password, cmd->password.pc_bb, 0x10);
} else {
decode_sjis(password, cmd->password_dc_gc, 0x10);
decode_sjis(password, cmd->password.dc_gc, 0x10);
}
}
@@ -918,7 +918,7 @@ void process_change_lobby(shared_ptr<ServerState> s, shared_ptr<Client> c,
struct Cmd {
uint32_t menu_id;
uint32_t item_id;
};
} __attribute__((packed));
check_size(size, sizeof(Cmd));
const auto* cmd = reinterpret_cast<const Cmd*>(data);
@@ -1173,7 +1173,7 @@ void process_chat_pc_bb(shared_ptr<ServerState> s, shared_ptr<Client> c,
struct Cmd {
uint32_t unused[2];
char16_t text[0];
};
} __attribute__((packed));
check_size(size, sizeof(Cmd), 0xFFFF);
const auto* cmd = reinterpret_cast<const Cmd*>(data);
@@ -1185,7 +1185,7 @@ void process_chat_dc_gc(shared_ptr<ServerState> s, shared_ptr<Client> c,
struct Cmd {
uint32_t unused[2];
char text[0];
};
} __attribute__((packed));
check_size(size, sizeof(Cmd), 0xFFFF);
const auto* cmd = reinterpret_cast<const Cmd*>(data);
@@ -1207,7 +1207,7 @@ void process_player_preview_request_bb(shared_ptr<ServerState>, shared_ptr<Clien
struct Cmd {
uint32_t player_index;
uint32_t unused;
};
} __attribute__((packed));
check_size(size, sizeof(Cmd));
const auto* cmd = reinterpret_cast<const Cmd*>(data);
@@ -1257,7 +1257,7 @@ void process_guild_card_data_request_bb(shared_ptr<ServerState>, shared_ptr<Clie
uint32_t unknown;
uint32_t chunk_index;
uint32_t cont;
};
} __attribute__((packed));
check_size(size, sizeof(Cmd));
const auto* cmd = reinterpret_cast<const Cmd*>(data);
@@ -1282,7 +1282,7 @@ void process_create_character_bb(shared_ptr<ServerState> s, shared_ptr<Client> c
struct Cmd {
uint32_t player_index;
PlayerDispDataBBPreview preview;
};
} __attribute__((packed));
check_size(size, sizeof(Cmd));
const auto* cmd = reinterpret_cast<const Cmd*>(data);
@@ -1346,7 +1346,7 @@ void process_change_account_data_bb(shared_ptr<ServerState>, shared_ptr<Client>
uint8_t pad_config[0x38]; // 05ED
uint8_t tech_menu[0x28]; // 06ED
uint8_t customize[0xE8]; // 07ED
};
} __attribute__((packed));
const auto* cmd = reinterpret_cast<const Cmd*>(data);
switch (command) {
@@ -1414,7 +1414,7 @@ void process_card_search(shared_ptr<ServerState> s, shared_ptr<Client> c,
uint32_t player_tag;
uint32_t searcher_serial_number;
uint32_t target_serial_number;
};
} __attribute__((packed));
check_size(size, sizeof(Cmd));
const auto* cmd = reinterpret_cast<const Cmd*>(data);
@@ -1495,7 +1495,7 @@ void process_simple_mail(shared_ptr<ServerState> s, shared_ptr<Client> c,
char from_name[16];
uint32_t target_serial_number;
char data[0x200]; // on GC this appears to contain uninitialized memory!
};
} __attribute__((packed));
check_size(size, sizeof(Cmd));
const auto* cmd = reinterpret_cast<const Cmd*>(data);
@@ -1724,7 +1724,7 @@ void process_create_game_pc(shared_ptr<ServerState> s, shared_ptr<Client> c,
uint8_t battle_mode;
uint8_t challenge_mode;
uint8_t unused2;
};
} __attribute__((packed));
check_size(size, sizeof(Cmd));
const auto* cmd = reinterpret_cast<const Cmd*>(data);
@@ -1746,7 +1746,7 @@ void process_create_game_dc_gc(shared_ptr<ServerState> s, shared_ptr<Client> c,
uint8_t battle_mode;
uint8_t challenge_mode;
uint8_t episode;
};
} __attribute__((packed));
check_size(size, sizeof(Cmd));
const auto* cmd = reinterpret_cast<const Cmd*>(data);
@@ -1787,7 +1787,7 @@ void process_create_game_bb(shared_ptr<ServerState> s, shared_ptr<Client> c,
uint8_t episode;
uint8_t solo_mode;
uint8_t unused2[3];
};
} __attribute__((packed));
check_size(size, sizeof(Cmd));
const auto* cmd = reinterpret_cast<const Cmd*>(data);
@@ -1859,7 +1859,7 @@ void process_login_patch(shared_ptr<ServerState> s, shared_ptr<Client> c,
uint32_t unused[3];
char username[0x10];
char password[0x10];
};
} __attribute__((packed));
check_size(size, sizeof(Cmd));
const auto* cmd = reinterpret_cast<const Cmd*>(data);
+10 -10
View File
@@ -27,7 +27,7 @@ struct ItemSubcommand {
uint8_t unused;
uint32_t item_id;
uint32_t amount;
};
} __attribute__((packed));
@@ -221,7 +221,7 @@ static void process_subcommand_drop_item(shared_ptr<ServerState>,
float x;
float y;
float z;
};
} __attribute__((packed));
auto* cmd = reinterpret_cast<const Cmd*>(p);
if ((cmd->size != 6) || (cmd->client_id != c->lobby_client_id)) {
@@ -253,7 +253,7 @@ static void process_subcommand_drop_stacked_item(shared_ptr<ServerState>,
float y;
uint32_t item_id;
uint32_t amount;
};
} __attribute__((packed));
auto* cmd = reinterpret_cast<const Cmd*>(p);
if (!l->is_game() || (cmd->size != 6) || (cmd->client_id != c->lobby_client_id)) {
@@ -293,7 +293,7 @@ static void process_subcommand_pick_up_item(shared_ptr<ServerState>,
uint32_t item_id;
uint8_t area;
uint8_t unused2[3];
};
} __attribute__((packed));
auto* cmd = reinterpret_cast<const Cmd*>(p);
if (!l->is_game() || (cmd->size != 3) || (cmd->client_id != c->lobby_client_id)) {
@@ -417,7 +417,7 @@ static void process_subcommand_bank_action(shared_ptr<ServerState>,
uint8_t action;
uint8_t item_amount;
uint16_t unused2;
};
} __attribute__((packed));
auto* cmd = reinterpret_cast<const Cmd*>(p);
if (!l->is_game() || (cmd->size != 4)) {
@@ -474,7 +474,7 @@ static void process_subcommand_sort_inventory(shared_ptr<ServerState>,
uint8_t size;
uint16_t unused;
uint32_t item_ids[30];
};
} __attribute__((packed));
auto* cmd = reinterpret_cast<const Cmd*>(p);
if (cmd->size != 31) {
@@ -521,7 +521,7 @@ static void process_subcommand_enemy_drop_item(shared_ptr<ServerState> s,
float x;
float y;
uint32_t unknown[2];
};
} __attribute__((packed));
auto* cmd = reinterpret_cast<const Cmd*>(p);
if ((cmd->size != 6) || !l->is_game()) {
@@ -586,7 +586,7 @@ static void process_subcommand_box_drop_item(shared_ptr<ServerState> s,
float x;
float y;
uint32_t unknown[6];
};
} __attribute__((packed));
auto* cmd = reinterpret_cast<const Cmd*>(p);
if ((cmd->size != 10) || !l->is_game()) {
@@ -655,7 +655,7 @@ static void process_subcommand_monster_hit(shared_ptr<ServerState>,
uint16_t enemy_id;
uint16_t damage;
uint32_t flags;
};
} __attribute__((packed));
auto* cmd = reinterpret_cast<const Cmd*>(p);
if (cmd->size != 10) {
@@ -694,7 +694,7 @@ static void process_subcommand_monster_killed(shared_ptr<ServerState> s,
uint16_t enemy_id;
uint16_t killer_client_id;
uint32_t unused;
};
} __attribute__((packed));
auto* cmd = reinterpret_cast<const Cmd*>(p);
if (!l->is_game() || (cmd->size != 3) || (cmd->enemy_id >= l->enemies.size() ||
+62 -66
View File
@@ -205,7 +205,7 @@ static void send_server_init_bb(shared_ptr<ServerState> s, shared_ptr<Client> c)
uint8_t server_key[0x30];
uint8_t client_key[0x30];
char after_message[200];
} cmd;
} __attribute__((packed)) cmd;
memset(&cmd, 0, sizeof(cmd));
strcpy(cmd.copyright, bb_game_server_copyright);
@@ -227,7 +227,7 @@ static void send_server_init_patch(shared_ptr<Client> c) {
uint32_t client_key;
// BB rejects the command if it's not exactly this size, so we can't add the
// anti-copyright message... lawyers plz be kind kthx
} cmd;
} __attribute__((packed)) cmd;
uint32_t server_key = random_object<uint32_t>();
uint32_t client_key = random_object<uint32_t>();
@@ -263,7 +263,7 @@ void send_update_client_config(shared_ptr<Client> c) {
uint32_t player_tag;
uint32_t serial_number;
ClientConfig config;
} cmd = {
} __attribute__((packed)) cmd = {
0x00010000,
c->license->serial_number,
c->export_config(),
@@ -280,7 +280,7 @@ void send_reconnect(shared_ptr<Client> c, uint32_t address, uint16_t port) {
be_uint32_t address;
uint16_t port;
uint16_t unused;
} cmd = {address, port, 0};
} __attribute__((packed)) cmd = {address, port, 0};
send_command(c, 0x19, 0x00, cmd);
}
@@ -298,7 +298,7 @@ void send_pc_gc_split_reconnect(shared_ptr<Client> c, uint32_t address,
be_uint32_t gc_address;
uint16_t gc_port;
uint8_t unused2[0xB0 - 0x23];
} cmd;
} __attribute__((packed)) cmd;
memset(&cmd, 0, sizeof(cmd));
cmd.pc_address = address;
cmd.pc_port = pc_port;
@@ -321,7 +321,7 @@ void send_client_init_bb(shared_ptr<Client> c, uint32_t error) {
uint32_t team_id; // just randomize it; teams aren't supported
ClientConfig cfg;
uint32_t caps; // should be 0x00000102
} cmd = {
} __attribute__((packed)) cmd = {
error,
0x00010000,
c->license->serial_number,
@@ -346,14 +346,14 @@ void send_player_preview_bb(shared_ptr<Client> c, uint8_t player_index,
struct {
uint32_t player_index;
uint32_t error;
} cmd = {player_index, 0x00000002};
} __attribute__((packed)) cmd = {player_index, 0x00000002};
send_command(c, 0x00E4, 0x00000000, cmd);
} else {
struct {
uint32_t player_index;
PlayerDispDataBBPreview preview;
} cmd = {player_index, *preview};
} __attribute__((packed)) cmd = {player_index, *preview};
send_command(c, 0x00E3, 0x00000000, cmd);
}
}
@@ -363,7 +363,7 @@ void send_accept_client_checksum_bb(shared_ptr<Client> c) {
struct {
uint32_t verify;
uint32_t unused;
} cmd = {1, 0};
} __attribute__((packed)) cmd = {1, 0};
send_command(c, 0x02E8, 0x00000000, cmd);
}
@@ -375,7 +375,7 @@ void send_guild_card_header_bb(shared_ptr<Client> c) {
uint32_t unknown; // should be 1
uint32_t filesize; // 0x0000490
uint32_t checksum;
} cmd = {1, 0x490, checksum};
} __attribute__((packed)) cmd = {1, 0x490, checksum};
send_command(c, 0x01DC, 0x00000000, cmd);
}
@@ -407,7 +407,7 @@ void send_stream_file_bb(shared_ptr<Client> c) {
uint32_t checksum;
uint32_t offset;
char filename[0x40];
};
} __attribute__((packed));
auto index_data = file_cache.get("system/blueburst/streamfile.ind");
if (index_data->size() % sizeof(StreamFileEntry)) {
@@ -422,7 +422,7 @@ void send_stream_file_bb(shared_ptr<Client> c) {
struct {
uint32_t chunk_index;
uint8_t data[0x6800];
} chunk_cmd;
} __attribute__((packed)) chunk_cmd;
chunk_cmd.chunk_index = 0;
uint32_t buffer_offset = 0;
@@ -464,7 +464,7 @@ void send_approve_player_choice_bb(shared_ptr<Client> c) {
struct {
uint32_t player_index;
uint32_t unused;
} cmd = {c->bb_player_index, 1};
} __attribute__((packed)) cmd = {c->bb_player_index, 1};
send_command(c, 0x00E4, 0x00000000, cmd);
}
@@ -493,7 +493,7 @@ void send_check_directory_patch(shared_ptr<Client> c, const char* dir) {
struct LargeMessageOptionalHeader {
uint32_t unused;
uint32_t serial_number;
};
} __attribute__((packed));
static void send_large_message_pc_patch_bb(shared_ptr<Client> c, uint8_t command,
const char16_t* text, uint32_t from_serial_number, bool include_header) {
@@ -594,7 +594,7 @@ void send_simple_mail_gc(std::shared_ptr<Client> c, uint32_t from_serial_number,
char from_name[0x10];
uint32_t to_serial_number;
char text[0x200];
} cmd;
} __attribute__((packed)) cmd;
memset(&cmd, 0, sizeof(cmd));
cmd.player_tag = 0x00010000;
@@ -624,7 +624,7 @@ static void send_info_board_pc_bb(shared_ptr<Client> c, shared_ptr<Lobby> l) {
struct Entry {
char16_t name[0x10];
char16_t message[0xAC];
};
} __attribute__((packed));
vector<Entry> entries;
for (const auto& c : l->clients) {
@@ -647,7 +647,7 @@ static void send_info_board_dc_gc(shared_ptr<Client> c, shared_ptr<Lobby> l) {
struct Entry {
char name[0x10];
char message[0xAC];
};
} __attribute__((packed));
vector<Entry> entries;
for (const auto& c : l->clients) {
@@ -693,23 +693,23 @@ static void send_card_search_result_dc_pc_gc(shared_ptr<ServerState> s,
uint8_t dcgc_command;
uint8_t dcgc_flag;
uint16_t dcgc_size;
};
} __attribute__((packed));
struct {
uint16_t pc_size;
uint8_t pc_command;
uint8_t pc_flag;
};
};
} __attribute__((packed));
} __attribute__((packed));
uint32_t address;
uint16_t port;
uint16_t unused;
} destination_command;
} __attribute__((packed)) destination_command;
char location_string[0x44];
uint32_t menu_id;
uint32_t lobby_id;
char unused[0x3C];
char16_t name[0x20];
} cmd;
} __attribute__((packed)) cmd;
memset(&cmd, 0, sizeof(cmd));
cmd.player_tag = 0x00010000;
@@ -766,13 +766,13 @@ static void send_card_search_result_bb(shared_ptr<ServerState> s,
uint32_t address;
uint16_t port;
uint16_t unused;
} destination_command;
} __attribute__((packed)) destination_command;
char location_string[0x44];
uint32_t menu_id;
uint32_t lobby_id;
char unused[0x3C];
char16_t name[0x20];
} cmd;
} __attribute__((packed)) cmd;
memset(&cmd, 0, sizeof(cmd));
cmd.player_tag = 0x00010000;
@@ -828,7 +828,7 @@ static void send_guild_card_gc(shared_ptr<Client> c, shared_ptr<Client> source)
uint8_t reserved2;
uint8_t section_id;
uint8_t char_class;
} cmd;
} __attribute__((packed)) cmd;
cmd.subcommand = 0x06;
cmd.subsize = 0x25;
@@ -860,7 +860,7 @@ static void send_guild_card_bb(shared_ptr<Client> c, shared_ptr<Client> source)
uint8_t reserved2;
uint8_t section_id;
uint8_t char_class;
} cmd;
} __attribute__((packed)) cmd;
cmd.subcommand = 0x06;
cmd.subsize = 0x43;
@@ -902,7 +902,7 @@ static void send_menu_pc_bb(shared_ptr<Client> c, const char16_t* menu_name,
uint32_t item_id;
uint16_t flags; // should be 0x0F04
char16_t text[17];
};
} __attribute__((packed));
vector<Entry> entries;
entries.emplace_back();
@@ -944,7 +944,7 @@ static void send_menu_dc_gc(shared_ptr<Client> c, const char16_t* menu_name,
uint32_t item_id;
uint16_t flags; // should be 0x0F04
char text[18];
};
} __attribute__((packed));
vector<Entry> entries;
entries.emplace_back();
@@ -1004,7 +1004,7 @@ static void send_game_menu_pc(shared_ptr<Client> c, shared_ptr<ServerState> s) {
char16_t name[0x10];
uint8_t episode;
uint8_t flags;
};
} __attribute__((packed));
vector<Entry> entries;
{
@@ -1046,7 +1046,7 @@ static void send_game_menu_gc(shared_ptr<Client> c, shared_ptr<ServerState> s) {
char name[0x10];
uint8_t episode;
uint8_t flags;
};
} __attribute__((packed));
vector<Entry> entries;
{
@@ -1093,7 +1093,7 @@ static void send_game_menu_bb(shared_ptr<Client> c, shared_ptr<ServerState> s) {
char16_t name[0x10];
uint8_t episode;
uint8_t flags;
};
} __attribute__((packed));
vector<Entry> entries;
{
@@ -1151,7 +1151,7 @@ static void send_quest_menu_pc(shared_ptr<Client> c, uint32_t menu_id,
uint32_t quest_id;
char16_t name[0x20];
char16_t short_desc[0x70];
};
} __attribute__((packed));
vector<Entry> entries;
for (const auto& quest : quests) {
@@ -1174,7 +1174,7 @@ static void send_quest_menu_pc(std::shared_ptr<Client> c, uint32_t menu_id,
uint32_t item_id;
char16_t name[0x20];
char16_t short_desc[0x70];
};
} __attribute__((packed));
vector<Entry> entries;
for (const auto& item : items) {
@@ -1197,7 +1197,7 @@ static void send_quest_menu_gc(shared_ptr<Client> c, uint32_t menu_id,
uint32_t quest_id;
char name[0x20];
char short_desc[0x70];
};
} __attribute__((packed));
vector<Entry> entries;
for (const auto& quest : quests) {
@@ -1220,7 +1220,7 @@ static void send_quest_menu_gc(shared_ptr<Client> c, uint32_t menu_id,
uint32_t item_id;
char name[0x20];
char short_desc[0x70];
};
} __attribute__((packed));
vector<Entry> entries;
for (const auto& item : items) {
@@ -1245,7 +1245,7 @@ static void send_quest_menu_bb(shared_ptr<Client> c, uint32_t menu_id,
uint32_t quest_id;
char16_t name[0x20];
char16_t short_desc[0x7A];
};
} __attribute__((packed));
vector<Entry> entries;
for (const auto& quest : quests) {
@@ -1270,7 +1270,7 @@ static void send_quest_menu_bb(shared_ptr<Client> c, uint32_t menu_id,
uint32_t item_id;
char16_t name[0x20];
char16_t short_desc[0x7A];
};
} __attribute__((packed));
vector<Entry> entries;
for (const auto& item : items) {
@@ -1321,7 +1321,7 @@ void send_lobby_list(shared_ptr<Client> c, shared_ptr<ServerState> s) {
uint32_t menu_id;
uint32_t item_id;
uint32_t unused; // should be 0x00000000
};
} __attribute__((packed));
vector<Entry> entries;
for (shared_ptr<Lobby> l : s->all_lobbies()) {
@@ -1364,7 +1364,7 @@ static void send_join_game_pc(shared_ptr<Client> c, shared_ptr<Lobby> l) {
uint8_t unused2;
uint8_t solo_mode;
uint8_t unused3;
} cmd;
} __attribute__((packed)) cmd;
size_t player_count = 0;
memcpy(cmd.variations, l->variations, sizeof(cmd.variations));
@@ -1458,7 +1458,7 @@ static void send_join_game_bb(shared_ptr<Client> c, shared_ptr<Lobby> l) {
uint8_t unused2;
uint8_t solo_mode;
uint8_t unused3;
} cmd;
} __attribute__((packed)) cmd;
size_t player_count = 0;
memcpy(cmd.variations, l->variations, sizeof(cmd.variations));
@@ -1500,7 +1500,7 @@ static void send_join_lobby_pc(shared_ptr<Client> c, shared_ptr<Lobby> l) {
uint16_t block_number;
uint16_t event;
uint32_t unused;
} cmd = {
} __attribute__((packed)) cmd = {
c->lobby_client_id,
l->leader_id,
0x01,
@@ -1513,7 +1513,7 @@ static void send_join_lobby_pc(shared_ptr<Client> c, shared_ptr<Lobby> l) {
struct Entry {
PlayerLobbyDataPC lobby_data;
PlayerLobbyJoinDataPCGC data;
};
} __attribute__((packed));
vector<Entry> entries;
for (size_t x = 0; x < l->max_clients; x++) {
@@ -1557,7 +1557,7 @@ static void send_join_lobby_gc(shared_ptr<Client> c, shared_ptr<Lobby> l) {
uint16_t block_number;
uint16_t event;
uint32_t unused;
} cmd = {
} __attribute__((packed)) cmd = {
c->lobby_client_id,
l->leader_id,
0x01,
@@ -1570,7 +1570,7 @@ static void send_join_lobby_gc(shared_ptr<Client> c, shared_ptr<Lobby> l) {
struct Entry {
PlayerLobbyDataGC lobby_data;
PlayerLobbyJoinDataPCGC data;
};
} __attribute__((packed));
vector<Entry> entries;
for (size_t x = 0; x < l->max_clients; x++) {
@@ -1606,7 +1606,7 @@ static void send_join_lobby_bb(shared_ptr<Client> c, shared_ptr<Lobby> l) {
uint16_t block_number;
uint16_t event;
uint32_t unused;
} cmd = {
} __attribute__((packed)) cmd = {
c->lobby_client_id,
l->leader_id,
0x01,
@@ -1619,7 +1619,7 @@ static void send_join_lobby_bb(shared_ptr<Client> c, shared_ptr<Lobby> l) {
struct Entry {
PlayerLobbyDataBB lobby_data;
PlayerLobbyJoinDataBB data;
};
} __attribute__((packed));
vector<Entry> entries;
for (size_t x = 0; x < l->max_clients; x++) {
@@ -1693,7 +1693,7 @@ static void send_player_join_notification_pc(shared_ptr<Client> c,
uint32_t unused;
PlayerLobbyDataPC lobby_data;
PlayerLobbyJoinDataPCGC data;
} cmd = {
} __attribute__((packed)) cmd = {
0xFF,
l->leader_id,
0x01,
@@ -1722,7 +1722,7 @@ static void send_player_join_notification_gc(shared_ptr<Client> c,
uint32_t unused;
PlayerLobbyDataGC lobby_data;
PlayerLobbyJoinDataPCGC data;
} cmd = {
} __attribute__((packed)) cmd = {
0xFF,
l->leader_id,
0x01,
@@ -1751,7 +1751,7 @@ static void send_player_join_notification_bb(shared_ptr<Client> c,
uint32_t unused;
PlayerLobbyDataBB lobby_data;
PlayerLobbyJoinDataBB data;
} cmd = {
} __attribute__((packed)) cmd = {
0xFF,
l->leader_id,
0x01,
@@ -1789,7 +1789,7 @@ void send_player_leave_notification(shared_ptr<Lobby> l, uint8_t leaving_client_
uint8_t client_id;
uint8_t leader_id;
uint16_t unused;
} cmd = {leaving_client_id, l->leader_id, 0};
} __attribute__((packed)) cmd = {leaving_client_id, l->leader_id, 0};
send_command(l, l->is_game() ? 0x66 : 0x69, leaving_client_id, cmd);
}
@@ -1807,7 +1807,7 @@ void send_arrow_update(shared_ptr<Lobby> l) {
uint32_t player_tag;
uint32_t serial_number;
uint32_t arrow_color;
};
} __attribute__((packed));
vector<Entry> entries;
for (size_t x = 0; x < l->max_clients; x++) {
@@ -1926,7 +1926,7 @@ void send_drop_item(shared_ptr<Lobby> l, const ItemData& item,
float y;
uint32_t unused2;
ItemData data;
} cmd = {0x5F, 0x0A, 0x0000, area, from_enemy, request_id, x, y, 0, item};
} __attribute__((packed)) cmd = {0x5F, 0x0A, 0x0000, area, from_enemy, request_id, x, y, 0, item};
send_command(l, 0x60, 0x00, cmd);
}
@@ -1943,7 +1943,7 @@ void send_drop_stacked_item(shared_ptr<Lobby> l, const ItemData& item,
float y;
uint32_t unused3;
ItemData data;
} cmd = {0x5D, 0x09, 0x0000, area, 0, x, y, 0, item};
} __attribute__((packed)) cmd = {0x5D, 0x09, 0x0000, area, 0, x, y, 0, item};
send_command(l, 0x60, 0x00, cmd);
}
@@ -1957,7 +1957,7 @@ void send_pick_up_item(shared_ptr<Lobby> l, shared_ptr<Client> c,
uint16_t client_id2;
uint16_t area;
uint32_t item_id;
} cmd = {0x59, 0x03, c->lobby_client_id, c->lobby_client_id, area, item_id};
} __attribute__((packed)) cmd = {0x59, 0x03, c->lobby_client_id, c->lobby_client_id, area, item_id};
send_command(l, 0x60, 0x00, cmd);
}
@@ -1970,7 +1970,7 @@ void send_create_inventory_item(shared_ptr<Lobby> l, shared_ptr<Client> c,
uint16_t client_id;
ItemData item;
uint32_t unused;
} cmd = {0xBE, 0x07, c->lobby_client_id, item, 0};
} __attribute__((packed)) cmd = {0xBE, 0x07, c->lobby_client_id, item, 0};
send_command(l, 0x60, 0x00, cmd);
}
@@ -1983,7 +1983,7 @@ void send_destroy_item(shared_ptr<Lobby> l, shared_ptr<Client> c,
uint16_t client_id;
uint32_t item_id;
uint32_t amount;
} cmd = {0x29, 0x03, c->lobby_client_id, item_id, amount};
} __attribute__((packed)) cmd = {0x29, 0x03, c->lobby_client_id, item_id, amount};
send_command(l, 0x60, 0x00, cmd);
}
@@ -2001,7 +2001,7 @@ void send_bank(shared_ptr<Client> c) {
uint32_t checksum; // can be random; client won't notice
uint32_t numItems;
uint32_t meseta;
} cmd = {0xBC, 0, 0, 0, checksum, c->player.bank.num_items, c->player.bank.meseta};
} __attribute__((packed)) cmd = {0xBC, 0, 0, 0, checksum, c->player.bank.num_items, c->player.bank.meseta};
size_t size = 8 + sizeof(cmd) + items.size() * sizeof(PlayerBankItem);
cmd.size = size;
@@ -2019,7 +2019,7 @@ void send_shop(shared_ptr<Client> c, uint8_t shop_type) {
uint8_t num_items;
uint16_t unused;
ItemData entries[20];
} cmd = {
} __attribute__((packed)) cmd = {
0xB6,
0x2C,
0x037F,
@@ -2104,7 +2104,7 @@ void send_ep3_rank_update(shared_ptr<Client> c) {
uint32_t meseta;
uint32_t max_meseta;
uint32_t jukebox_songs_unlocked;
} cmd = {0, "\0\0\0\0\0\0\0\0\0\0\0", 0x00FFFFFF, 0x00FFFFFF, 0xFFFFFFFF};
} __attribute__((packed)) cmd = {0, "\0\0\0\0\0\0\0\0\0\0\0", 0x00FFFFFF, 0x00FFFFFF, 0xFFFFFFFF};
send_command(c, 0xB7, 0x00, cmd);
}
@@ -2140,10 +2140,6 @@ void send_ep3_map_data(shared_ptr<Lobby> l, uint32_t map_id) {
////////////////////////////////////////////////////////////////////////////////
// CommandLoadQuestFile: sends a quest file to the client.
// the _OpenFile functions send the begin command (44/A6), and the _SendChunk functions send a chunk of data (13/A7).
static void send_quest_open_file_pc_gc(shared_ptr<Client> c,
const string& filename, uint32_t file_size, bool is_download_quest,
bool is_ep3_quest) {
@@ -2153,7 +2149,7 @@ static void send_quest_open_file_pc_gc(shared_ptr<Client> c,
uint16_t flags;
char filename[0x10];
uint32_t file_size;
} cmd;
} __attribute__((packed)) cmd;
memset(&cmd, 0, sizeof(cmd));
strncpy(cmd.name, filename.c_str(), 0x1F);
cmd.flags = 2 + is_ep3_quest;
@@ -2171,7 +2167,7 @@ static void send_quest_open_file_bb(shared_ptr<Client> c,
char filename[0x10];
uint32_t file_size;
char name[0x18];
} cmd;
} __attribute__((packed)) cmd;
memset(&cmd, 0, sizeof(cmd));
cmd.flags = 2 + is_ep3_quest;
strncpy(cmd.filename, filename.c_str(), 0x0F);
@@ -2189,7 +2185,7 @@ static void send_quest_file_chunk(shared_ptr<Client> c, const char* filename,
char filename[0x10];
uint8_t data[0x400];
uint32_t data_size;
} cmd;
} __attribute__((packed)) cmd;
memset(cmd.filename, 0, 0x10);
strncpy(cmd.filename, filename, 0x0F);
memcpy(cmd.data, data, size);
+1 -1
View File
@@ -147,7 +147,7 @@ struct JoinGameCommand_GC_64 {
struct {
PlayerInventory inventory;
PlayerDispDataPCGC disp;
} player[4]; // only used on ep3
} __attribute__((packed)) player[4]; // only used on ep3
} __attribute__((packed));
void send_join_lobby(std::shared_ptr<Client> c, std::shared_ptr<Lobby> l);