Protocol:Character Data

From Sylverant
(Redirected from Character Data)
Jump to navigationJump to search

Since I'm lazy, and don't feel like doing this the hard way, this is how Sylverant declares character data for PSODC and PSOPC (the relevant struct here is player_t):

/*
    Sylverant Ship Server
    Copyright (C) 2009 Lawrence Sebald

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License version 3 as
    published by the Free Software Foundation.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef PLAYER_H
#define PLAYER_H

#include <inttypes.h>

#ifdef PACKED
#undef PACKED
#endif

#define PACKED __attribute__((packed))

/* The header attached before the player data when sending to a lobby client. */
typedef struct dc_player_hdr {
    uint32_t tag;
    uint32_t guildcard;
    uint32_t ip_addr;
    uint32_t client_id;
    char name[16];
} PACKED dc_player_hdr_t;

typedef struct pc_player_hdr {
    uint32_t tag;
    uint32_t guildcard;
    uint32_t ip_addr;
    uint32_t client_id;
    uint16_t name[16];
} PACKED pc_player_hdr_t;

/* These structures heavily based on those in newserv. */
typedef struct item {
    uint16_t equipped;
    uint16_t tech;
    uint32_t flags;

    union {
        uint8_t data_b[12];
        uint16_t data_w[6];
        uint32_t data_l[3];
    };

    uint32_t item_id;

    union {
        uint8_t data2_b[4];
        uint16_t data2_w[2];
        uint32_t data2_l;
    };
} PACKED item_t;

typedef struct inventory {
    uint8_t item_count;
    uint8_t hpmats_used;
    uint8_t tpmats_used;
    uint8_t language;
    item_t items[30];
} PACKED inventory_t;

typedef struct player {
    inventory_t inv;
    uint16_t atp;
    uint16_t mst;
    uint16_t evp;
    uint16_t hp;
    uint16_t dfp;
    uint16_t ata;
    uint16_t lck;
    uint16_t unk1;
    uint32_t unk2[2];
    uint32_t level;
    uint32_t exp;
    uint32_t meseta;
    char name[16];
    uint32_t unk3[2];
    uint32_t name_color;
    uint8_t model;
    uint8_t unused[15];
    uint32_t name_color_checksum;
    uint8_t section;
    uint8_t ch_class;
    uint8_t v2flags;
    uint8_t version;
    uint32_t v1flags;
    uint16_t costume;
    uint16_t skin;
    uint16_t face;
    uint16_t head;
    uint16_t hair;
    uint16_t hair_r;
    uint16_t hair_g;
    uint16_t hair_b;
    float prop_x;
    float prop_y;
    uint8_t config[0x48];
    uint8_t techniques[0x14];
} PACKED player_t;

#undef PACKED

#endif /* !PLAYER_H */

The following is newserv's definition of PSOGC and PSOBB player data (from player.h):

// in this segment:
// PLAYER_ITEM is the same as item_t
// PLAYER_INVENTORY is the same as inventory_t
// ITEM_DATA is the same as item_t without the first three fields

// an item in a player's bank (BB)
typedef struct {
    ITEM_DATA data;
    WORD amount;
    WORD showflags; } PLAYER_BANK_ITEM;

// a player's bank (BB)
typedef struct {
    DWORD numItems;
    DWORD meseta;
    PLAYER_BANK_ITEM items[200]; } PLAYER_BANK;

////////////////////////////////////////////////////////////////////////////////

// simple player stats (kept in a separate struct in order to facilitate leveling up for BB players)
typedef struct {
    WORD atp;
    WORD mst;
    WORD evp;
    WORD hp;
    WORD dfp;
    WORD ata;
    WORD lck; } PLAYER_STATS;

// PC/GC player appearance and stats data
typedef struct {
    PLAYER_STATS stats;
    WORD unknown1;
    DWORD unknown2[2];
    DWORD level;
    DWORD exp;
    DWORD meseta;
    char playername[16];
    DWORD unknown3[2];
    DWORD nameColor;
    BYTE extraModel;
    BYTE unused[15];
    DWORD nameColorChecksum;
    BYTE sectionID;
    BYTE charClass;
    BYTE v2flags;
    BYTE version;
    DWORD v1flags;
    WORD costume;
    WORD skin;
    WORD face;
    WORD head;
    WORD hair;
    WORD hairRed;
    WORD hairGreen;
    WORD hairBlue;
    float propX;
    float propY;
    BYTE config[0x48];
    BYTE techLevels[0x14]; } PCGC_PLAYER_DISPDATA; // 0xD0 in size 

// BB player appearance and stats data
typedef struct {
    PLAYER_STATS stats;
    WORD unknown1;
    DWORD unknown2[2];
    DWORD level;
    DWORD exp;
    DWORD meseta;
    char guildcard[16];
    DWORD unknown3[2];
    DWORD nameColor;
    BYTE extraModel;
    BYTE unused[11];
    DWORD playTime; // not actually a game field; used only by newserv
    DWORD nameColorChecksum;
    BYTE sectionID;
    BYTE charClass;
    BYTE v2flags;
    BYTE version;
    DWORD v1flags;
    WORD costume;
    WORD skin;
    WORD face;
    WORD head;
    WORD hair;
    WORD hairRed;
    WORD hairGreen;
    WORD hairBlue;
    float propX;
    float propY;
    wchar_t playername[16];
    BYTE config[0xE8];
    BYTE techLevels[0x14];
} BB_PLAYER_DISPDATA;

// BB player preview format
typedef struct {
    DWORD exp;
    DWORD level;
    char guildcard[16];
    DWORD unknown3[2];
    DWORD nameColor;
    BYTE extraModel;
    BYTE unused[15];
    DWORD nameColorChecksum;
    BYTE sectionID;
    BYTE charClass;
    BYTE v2flags;
    BYTE version;
    DWORD v1flags;
    WORD costume;
    WORD skin;
    WORD face;
    WORD head;
    WORD hair;
    WORD hairRed;
    WORD hairGreen;
    WORD hairBlue;
    float propX;
    float propY;
    wchar_t playername[16];
    DWORD playTime;
} BB_PLAYER_DISPDATA_PREVIEW;

// complete BB player data format (used in E7 command)
typedef struct {
    PLAYER_INVENTORY inventory;      // 0000 // player
    BB_PLAYER_DISPDATA disp;         // 034C // player
    BYTE unknown[0x0010];            // 04DC //
    DWORD optionFlags;               // 04EC // account
    BYTE questData1[0x0208];         // 04F0 // player
    PLAYER_BANK bank;                // 06F8 // player
    DWORD serialNumber;              // 19C0 // player
    wchar_t name[0x18];              // 19C4 // player
    wchar_t teamname[0x10];          // 19C4 // player
    wchar_t guildcarddesc[0x58];     // 1A14 // player
    BYTE reserved1;                  // 1AC4 // player
    BYTE reserved2;                  // 1AC5 // player
    BYTE sectionID;                  // 1AC6 // player
    BYTE charClass;                  // 1AC7 // player
    DWORD unknown3;                  // 1AC8 //
    BYTE symbolchats[0x04E0];        // 1ACC // account
    BYTE shortcuts[0x0A40];          // 1FAC // account
    wchar_t autoreply[0x00AC];       // 29EC // player
    wchar_t infoboard[0x00AC];       // 2B44 // player
    BYTE unknown5[0x001C];           // 2C9C //
    BYTE challengeData[0x0140];      // 2CB8 // player
    BYTE techMenuConfig[0x0028];     // 2DF8 // player
    BYTE unknown6[0x002C];           // 2E20 //
    BYTE questData2[0x0058];         // 2E4C // player
    BB_KEY_TEAM_CONFIG keyConfig;    // 2EA4 // account
} BB_COMPLETE_PLAYER_DATA_FORMAT;    // total size: 39A0