fix uninitialized memory in ep3 game join
This commit is contained in:
@@ -30,6 +30,7 @@ Current known issues / missing features:
|
|||||||
- The trade window isn't implemented yet.
|
- The trade window isn't implemented yet.
|
||||||
- PSO PC and PSOBB are essentially entirely untested. Only GC is fairly well-tested.
|
- 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.)
|
- Add all the chat commands that khyller used to have. (Most, but not all, currently exist in newserv.)
|
||||||
|
- Hide the guild card number assigned by the remote server when proxying, and instead rewrite all commands that include the client's guild card number.
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,33 @@ using namespace std;
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PlayerStats::PlayerStats() noexcept
|
||||||
|
: atp(0), mst(0), evp(0), hp(0), dfp(0), ata(0), lck(0) { }
|
||||||
|
|
||||||
|
PlayerDispDataPCGC::PlayerDispDataPCGC() noexcept
|
||||||
|
: level(0),
|
||||||
|
experience(0),
|
||||||
|
meseta(0),
|
||||||
|
unknown_a2(0),
|
||||||
|
name_color(0),
|
||||||
|
extra_model(0),
|
||||||
|
name_color_checksum(0),
|
||||||
|
section_id(0),
|
||||||
|
char_class(0),
|
||||||
|
v2_flags(0),
|
||||||
|
version(0),
|
||||||
|
v1_flags(0),
|
||||||
|
costume(0),
|
||||||
|
skin(0),
|
||||||
|
face(0),
|
||||||
|
head(0),
|
||||||
|
hair(0),
|
||||||
|
hair_r(0),
|
||||||
|
hair_g(0),
|
||||||
|
hair_b(0),
|
||||||
|
proportion_x(0),
|
||||||
|
proportion_y(0) { }
|
||||||
|
|
||||||
void PlayerDispDataPCGC::enforce_pc_limits() {
|
void PlayerDispDataPCGC::enforce_pc_limits() {
|
||||||
// PC has fewer classes, so we'll substitute some here
|
// PC has fewer classes, so we'll substitute some here
|
||||||
if (this->char_class == 11) {
|
if (this->char_class == 11) {
|
||||||
@@ -80,6 +107,32 @@ PlayerDispDataBB PlayerDispDataPCGC::to_bb() const {
|
|||||||
return bb;
|
return bb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PlayerDispDataBB::PlayerDispDataBB() noexcept
|
||||||
|
: level(0),
|
||||||
|
experience(0),
|
||||||
|
meseta(0),
|
||||||
|
unknown_a2(0),
|
||||||
|
name_color(0),
|
||||||
|
extra_model(0),
|
||||||
|
name_color_checksum(0),
|
||||||
|
section_id(0),
|
||||||
|
char_class(0),
|
||||||
|
v2_flags(0),
|
||||||
|
version(0),
|
||||||
|
v1_flags(0),
|
||||||
|
costume(0),
|
||||||
|
skin(0),
|
||||||
|
face(0),
|
||||||
|
head(0),
|
||||||
|
hair(0),
|
||||||
|
hair_r(0),
|
||||||
|
hair_g(0),
|
||||||
|
hair_b(0),
|
||||||
|
proportion_x(0),
|
||||||
|
proportion_y(0) { }
|
||||||
|
|
||||||
// converts BB player data to PC/GC format
|
// converts BB player data to PC/GC format
|
||||||
PlayerDispDataPCGC PlayerDispDataBB::to_pcgc() const {
|
PlayerDispDataPCGC PlayerDispDataBB::to_pcgc() const {
|
||||||
PlayerDispDataPCGC pcgc;
|
PlayerDispDataPCGC pcgc;
|
||||||
@@ -180,6 +233,40 @@ void PlayerDispDataBB::apply_preview(const PlayerDispDataBBPreview& pre) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PlayerDispDataBBPreview::PlayerDispDataBBPreview() noexcept
|
||||||
|
: experience(0),
|
||||||
|
level(0),
|
||||||
|
unknown_a2(0),
|
||||||
|
name_color(0),
|
||||||
|
extra_model(0),
|
||||||
|
name_color_checksum(0),
|
||||||
|
section_id(0),
|
||||||
|
char_class(0),
|
||||||
|
v2_flags(0),
|
||||||
|
version(0),
|
||||||
|
v1_flags(0),
|
||||||
|
costume(0),
|
||||||
|
skin(0),
|
||||||
|
face(0),
|
||||||
|
head(0),
|
||||||
|
hair(0),
|
||||||
|
hair_r(0),
|
||||||
|
hair_g(0),
|
||||||
|
hair_b(0),
|
||||||
|
proportion_x(0),
|
||||||
|
proportion_y(0),
|
||||||
|
play_time(0) { }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
GuildCardGC::GuildCardGC() noexcept
|
||||||
|
: player_tag(0), serial_number(0), reserved1(1), reserved2(1), section_id(0), char_class(0) { }
|
||||||
|
|
||||||
|
GuildCardBB::GuildCardBB() noexcept
|
||||||
|
: serial_number(0), reserved1(1), reserved2(1), section_id(0), char_class(0) { }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void PlayerBank::load(const string& filename) {
|
void PlayerBank::load(const string& filename) {
|
||||||
*this = load_object_file<PlayerBank>(filename);
|
*this = load_object_file<PlayerBank>(filename);
|
||||||
for (uint32_t x = 0; x < this->num_items; x++) {
|
for (uint32_t x = 0; x < this->num_items; x++) {
|
||||||
@@ -339,6 +426,17 @@ void Player::save_player_data(const string& filename) const {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PlayerLobbyDataPC::PlayerLobbyDataPC() noexcept
|
||||||
|
: player_tag(0), guild_card(0), ip_address(0), client_id(0) { }
|
||||||
|
|
||||||
|
PlayerLobbyDataGC::PlayerLobbyDataGC() noexcept
|
||||||
|
: player_tag(0), guild_card(0), ip_address(0), client_id(0) { }
|
||||||
|
|
||||||
|
PlayerLobbyDataBB::PlayerLobbyDataBB() noexcept
|
||||||
|
: player_tag(0), guild_card(0), ip_address(0), client_id(0), unknown2(0) { }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
static const unordered_map<uint32_t, uint32_t> combine_item_to_max({
|
static const unordered_map<uint32_t, uint32_t> combine_item_to_max({
|
||||||
|
|||||||
@@ -89,6 +89,8 @@ struct PlayerStats {
|
|||||||
le_uint16_t dfp;
|
le_uint16_t dfp;
|
||||||
le_uint16_t ata;
|
le_uint16_t ata;
|
||||||
le_uint16_t lck;
|
le_uint16_t lck;
|
||||||
|
|
||||||
|
PlayerStats() noexcept;
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
struct PlayerDispDataBB;
|
struct PlayerDispDataBB;
|
||||||
@@ -124,6 +126,12 @@ struct PlayerDispDataPCGC { // 0xD0 in size
|
|||||||
parray<uint8_t, 0x48> config;
|
parray<uint8_t, 0x48> config;
|
||||||
parray<uint8_t, 0x14> technique_levels;
|
parray<uint8_t, 0x14> technique_levels;
|
||||||
|
|
||||||
|
// Note: This struct has a default constructor because it's used in a command
|
||||||
|
// that has a fixed-size array. If we didn't define this constructor, the
|
||||||
|
// trivial fields in that array's members would be uninitialized, and we could
|
||||||
|
// send uninitialized memory to the client.
|
||||||
|
PlayerDispDataPCGC() noexcept;
|
||||||
|
|
||||||
void enforce_pc_limits();
|
void enforce_pc_limits();
|
||||||
PlayerDispDataBB to_bb() const;
|
PlayerDispDataBB to_bb() const;
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
@@ -155,6 +163,8 @@ struct PlayerDispDataBBPreview {
|
|||||||
le_float proportion_y;
|
le_float proportion_y;
|
||||||
ptext<char16_t, 0x10> name;
|
ptext<char16_t, 0x10> name;
|
||||||
uint32_t play_time;
|
uint32_t play_time;
|
||||||
|
|
||||||
|
PlayerDispDataBBPreview() noexcept;
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
// BB player appearance and stats data
|
// BB player appearance and stats data
|
||||||
@@ -189,6 +199,8 @@ struct PlayerDispDataBB {
|
|||||||
parray<uint8_t, 0xE8> config;
|
parray<uint8_t, 0xE8> config;
|
||||||
parray<uint8_t, 0x14> technique_levels;
|
parray<uint8_t, 0x14> technique_levels;
|
||||||
|
|
||||||
|
PlayerDispDataBB() noexcept;
|
||||||
|
|
||||||
inline void enforce_pc_limits() { }
|
inline void enforce_pc_limits() { }
|
||||||
PlayerDispDataPCGC to_pcgc() const;
|
PlayerDispDataPCGC to_pcgc() const;
|
||||||
PlayerDispDataBBPreview to_preview() const;
|
PlayerDispDataBBPreview to_preview() const;
|
||||||
@@ -206,6 +218,8 @@ struct GuildCardGC {
|
|||||||
uint8_t reserved2; // should be 1
|
uint8_t reserved2; // should be 1
|
||||||
uint8_t section_id;
|
uint8_t section_id;
|
||||||
uint8_t char_class;
|
uint8_t char_class;
|
||||||
|
|
||||||
|
GuildCardGC() noexcept;
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
// BB guild card format
|
// BB guild card format
|
||||||
@@ -218,6 +232,8 @@ struct GuildCardBB {
|
|||||||
uint8_t reserved2; // should be 1
|
uint8_t reserved2; // should be 1
|
||||||
uint8_t section_id;
|
uint8_t section_id;
|
||||||
uint8_t char_class;
|
uint8_t char_class;
|
||||||
|
|
||||||
|
GuildCardBB() noexcept;
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
// an entry in the BB guild card file
|
// an entry in the BB guild card file
|
||||||
@@ -265,6 +281,8 @@ struct PlayerLobbyDataPC {
|
|||||||
be_uint32_t ip_address;
|
be_uint32_t ip_address;
|
||||||
le_uint32_t client_id;
|
le_uint32_t client_id;
|
||||||
ptext<char16_t, 0x10> name;
|
ptext<char16_t, 0x10> name;
|
||||||
|
|
||||||
|
PlayerLobbyDataPC() noexcept;
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
struct PlayerLobbyDataGC {
|
struct PlayerLobbyDataGC {
|
||||||
@@ -273,6 +291,8 @@ struct PlayerLobbyDataGC {
|
|||||||
be_uint32_t ip_address;
|
be_uint32_t ip_address;
|
||||||
le_uint32_t client_id;
|
le_uint32_t client_id;
|
||||||
ptext<char, 0x10> name;
|
ptext<char, 0x10> name;
|
||||||
|
|
||||||
|
PlayerLobbyDataGC() noexcept;
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
struct PlayerLobbyDataBB {
|
struct PlayerLobbyDataBB {
|
||||||
@@ -283,6 +303,8 @@ struct PlayerLobbyDataBB {
|
|||||||
le_uint32_t client_id;
|
le_uint32_t client_id;
|
||||||
ptext<char16_t, 0x10> name;
|
ptext<char16_t, 0x10> name;
|
||||||
le_uint32_t unknown2;
|
le_uint32_t unknown2;
|
||||||
|
|
||||||
|
PlayerLobbyDataBB() noexcept;
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user