40250 classic: expand CHARACTER_NAME_MAX_LEN to 64 for full UTF-8 Chinese names

This commit is contained in:
shen
2026-09-19 19:50:40 -07:00
parent 21462cddca
commit 0dafa9f5ff
3 changed files with 51 additions and 51 deletions
+16 -16
View File
@@ -513,8 +513,8 @@
10030 影悲沙漠 3519 6223
10031 沙漠平原 10594 7525
10032 沙漠谷 8283 7635
10033 天意一层 10594 7525
10034 天意二层 10594 7525
10033 天意迷城一层 10594 7525
10034 天意迷城二层 10594 7525
10035 盘丝洞 917 5253
10036 盘丝洞2层 7041 4642
10037 江陵府 3809 8233
@@ -546,7 +546,7 @@
10063 鬼木林 3031 266
10064 赤鬼木林 11133 534
10065 新鬼木林 7754 10553
10066 赤鬼木林 9915 11195
10066 赤鬼木林 9915 11195
10067 下仙洞 7752 4477
10068 江陵府 4062 8756
10069 下仙洞 8520 4477
@@ -558,8 +558,8 @@
10075 影悲沙漠 2879 5407
10076 上仙洞 1352 7300
10078 虎丘 2842 8106
10079 天意一层 1364 13436
10080 天意二层 2413 12755
10079 天意迷城一层 1364 13436
10080 天意迷城二层 2413 12755
10501 . 345 361
10502 . 106 547
10503 . 75 368
@@ -792,8 +792,8 @@
20072 天露炼圣
20073 封印石
20074 亡灵塔武器制作师
20075 亡灵塔防
20076 亡灵塔饰品师
20075 亡灵塔防御品制作
20076 亡灵塔饰品制作
20077 力量祭坛警备兵
20078 力量祭坛警备兵
20079 力量祭坛警备兵
@@ -873,18 +873,18 @@
2414 真天意首领
2413 真天意法师
2412 真天意弓箭手
10081 天意层 99 13618
10081 天意迷城1层 99 13618
10082 长安城 5028 9998
10083 天意一层 1360 14972
10084 天意二层 2414 14289
10085 天意一层 99 15154
10083 天意迷城一层 1360 14972
10084 天意迷城二层 2414 14289
10085 天意迷城一层 99 15154
10086 咸阳城 616 1148
10087 天意一层 1360 16508
10088 天意二层 2414 15825
10089 天意一层 99 16690
10087 天意迷城一层 1360 16508
10088 天意迷城二层 2414 15825
10089 天意迷城一层 99 16690
10090 洛阳城 9609 3188
10091 天意一层 1360 18044
10092 天意二层 2414 17361
10091 天意迷城一层 1360 18044
10092 天意迷城二层 2414 17361
2411 真天意士兵
2404 天意首领
2403 天意法师
+23 -23
View File
@@ -31,7 +31,7 @@
namespace mtnet::classic {
// ------------------------------------------------------------------ constants
inline constexpr int CHARACTER_NAME_MAX_LEN = 24; // common/length.h -> name[25]
inline constexpr int CHARACTER_NAME_MAX_LEN = 64; // common/length.h -> name[65]
inline constexpr int GUILD_NAME_MAX_LEN = 12; // -> guild_name[13]
inline constexpr int GUILD_GRADE_NAME_MAX_LEN = 8;
inline constexpr int GUILD_COMMENT_MAX_LEN = 50;
@@ -373,8 +373,8 @@ struct SimplePlayer { // TSimplePlayer (common/tables.h) == client TSimplePlayer
uint16_t port;
uint8_t skill_group;
};
// 4 + 25 + 1 + 1 + 4 + 4 + 2 + 1 + 2 + 4 + 8 + 4 + 2 + 1
static_assert(sizeof(SimplePlayer) == 63);
// 4 + 65 + 1 + 1 + 4 + 4 + 2 + 1 + 2 + 4 + 8 + 4 + 2 + 1
static_assert(sizeof(SimplePlayer) == 103);
// --- control / handshake ---
struct Blank { uint8_t header; };
@@ -439,9 +439,9 @@ struct GCLoginSuccessT { // packet_login_success — 40250 sends the NEWSLOT (N=
};
using GCLoginSuccess = GCLoginSuccessT<PLAYER_PER_ACCOUNT>; // header 32
using GCLoginSuccess3 = GCLoginSuccessT<PLAYER_PER_ACCOUNT3>; // header 6 (legacy)
// 1 + 63*N + 4*N + 13*N + 4 + 4
static_assert(sizeof(GCLoginSuccess) == 1 + 63 * 4 + 4 * 4 + 13 * 4 + 4 + 4); // 329
static_assert(sizeof(GCLoginSuccess3) == 1 + 63 * 3 + 4 * 3 + 13 * 3 + 4 + 4); // 249
// 1 + 103*N + 4*N + 13*N + 4 + 4
static_assert(sizeof(GCLoginSuccess) == 1 + sizeof(SimplePlayer) * 4 + 4 * 4 + 13 * 4 + 4 + 4); // 489
static_assert(sizeof(GCLoginSuccess3) == 1 + sizeof(SimplePlayer) * 3 + 4 * 3 + 13 * 3 + 4 + 4); // 369
struct GCLoginFailure { uint8_t header; char status[LOGIN_STATUS_MAX_LEN + 1]; };
static_assert(sizeof(GCLoginFailure) == 10);
@@ -487,7 +487,7 @@ struct CGPlayerCreate { // command_player_create — note `job` is WORD here
uint8_t shape;
uint8_t con, intel, str, dex;
};
static_assert(sizeof(CGPlayerCreate) == 1 + 1 + 25 + 2 + 1 + 4);
static_assert(sizeof(CGPlayerCreate) == 1 + 1 + (CHARACTER_NAME_MAX_LEN + 1) + 2 + 1 + 4); // 74
struct CGPlayerDelete { uint8_t header; uint8_t index; char private_code[PRIVATE_CODE_LENGTH]; };
static_assert(sizeof(CGPlayerDelete) == 10);
@@ -497,7 +497,7 @@ struct CGChangeName {
uint8_t index;
char name[CHARACTER_NAME_MAX_LEN + 1];
};
static_assert(sizeof(CGChangeName) == 27);
static_assert(sizeof(CGChangeName) == 1 + 1 + (CHARACTER_NAME_MAX_LEN + 1)); // 67
struct CGEmpire { uint8_t header; uint8_t empire; };
static_assert(sizeof(CGEmpire) == 2);
@@ -524,10 +524,10 @@ struct CGClientVersion2 {
static_assert(sizeof(CGClientVersion2) == 67);
struct GCPlayerCreateSuccess { uint8_t header; uint8_t account_slot; SimplePlayer player; };
static_assert(sizeof(GCPlayerCreateSuccess) == 2 + 63);
static_assert(sizeof(GCPlayerCreateSuccess) == 2 + sizeof(SimplePlayer)); // 105
struct GCPlayerCreateFailure { uint8_t header; uint8_t type; };
struct GCChangeNameNotice { uint8_t header; uint32_t pid; char name[CHARACTER_NAME_MAX_LEN + 1]; };
static_assert(sizeof(GCPlayerCreateFailure) == 2 && sizeof(GCChangeNameNotice) == 30);
static_assert(sizeof(GCPlayerCreateFailure) == 2 && sizeof(GCChangeNameNotice) == 1 + 4 + (CHARACTER_NAME_MAX_LEN + 1)); // 70
struct GCPlayerDeleteSuccess { uint8_t header; uint8_t account_index; };
static_assert(sizeof(GCPlayerDeleteSuccess) == 2);
@@ -568,7 +568,7 @@ struct GCMainCharacter { // packet.h:1043 (== client TPacketGCMainCharacter2_EMP
uint8_t empire;
uint8_t skill_group;
};
static_assert(sizeof(GCMainCharacter) == 1 + 4 + 2 + 25 + 12 + 1 + 1);
static_assert(sizeof(GCMainCharacter) == 1 + 4 + 2 + (CHARACTER_NAME_MAX_LEN + 1) + 12 + 1 + 1); // 86
// SUPPORT_BGM variants emitted by CHARACTER::MainCharacterPacket when the
// map has a configured background track. The BGM field is not needed by the
@@ -595,7 +595,7 @@ struct GCMainCharacter4BGM {
uint8_t empire;
uint8_t skill_group;
};
static_assert(sizeof(GCMainCharacter3BGM) == 71 && sizeof(GCMainCharacter4BGM) == 75);
static_assert(sizeof(GCMainCharacter3BGM) == 111 && sizeof(GCMainCharacter4BGM) == 115);
// --- spawn / despawn / move ---
struct GCCharacterAdd { // packet_add_char (server) — no name/parts
@@ -632,7 +632,7 @@ struct GCCharacterAdd2 { // packet_add_char2 — name + parts + guild
uint32_t mount_vnum;
};
static_assert(sizeof(GCCharacterAdd2) ==
1 + 4 + 25 + 4 + 12 + 1 + 2 + 8 + 1 + 1 + 1 + 8 + 1 + 4 + 2 + 1 + 4);
1 + 4 + (CHARACTER_NAME_MAX_LEN + 1) + 4 + 12 + 1 + 2 + 8 + 1 + 1 + 1 + 8 + 1 + 4 + 2 + 1 + 4); // 120
struct GCCharacterDel { uint8_t header; uint32_t vid; };
static_assert(sizeof(GCCharacterDel) == 5);
@@ -993,7 +993,7 @@ struct GCDragonSoulRefine {
ItemPos pos;
};
static_assert(sizeof(GCAttack) == 10 && sizeof(GCItemUse) == 16 &&
sizeof(GCItemOwnership) == 30 && sizeof(GCOwnership) == 9 && sizeof(GCMount) == 18 &&
sizeof(GCItemOwnership) == 70 && sizeof(GCOwnership) == 9 && sizeof(GCMount) == 18 &&
sizeof(GCCreateFly) == 10 && sizeof(GCFlyTargeting) == 17 &&
sizeof(GCPvp) == 10 && sizeof(GCDuelStart) == 3 && sizeof(GCShopSign) == 38 &&
sizeof(GCSkillGroup) == 2 && sizeof(GCSpecialEffect) == 6 && sizeof(GCSpecificEffect) == 133 &&
@@ -1002,12 +1002,12 @@ static_assert(sizeof(GCAttack) == 10 && sizeof(GCItemUse) == 16 &&
sizeof(GCObserverAdd) == 9 && sizeof(GCObserverMove) == 9 &&
sizeof(GCObserverRemove) == 5 && sizeof(GCTime) == 5 && sizeof(GCChannel) == 2 &&
sizeof(GCDungeonHead) == 1 && sizeof(GCNPCPositionHead) == 2 &&
sizeof(NPCPosition34) == 34 && sizeof(LandPacketElement24) == 24 &&
sizeof(NPCPosition34) == 74 && sizeof(LandPacketElement24) == 24 &&
sizeof(GCTargetCreate43) == 43 && sizeof(GCTargetUpdate13) == 13 &&
sizeof(GCTargetDelete5) == 5 && sizeof(GCLoverInfo) == 27 &&
sizeof(GCTargetDelete5) == 5 && sizeof(GCLoverInfo) == 67 &&
sizeof(GCLovePointUpdate) == 2 && sizeof(GCDigMotion) == 10 &&
sizeof(EquipmentItem38) == 38 && sizeof(GCViewEquip) == 1221 &&
sizeof(GCChangeName) == 30 && sizeof(GCRefineMaterial) == 8 &&
sizeof(GCChangeName) == 70 && sizeof(GCRefineMaterial) == 8 &&
sizeof(GCRefineInfo) == 60 && sizeof(GCDragonSoulRefine) == 5);
// packet_char_additional_info (header 136) — fills a spawned entity's name/parts/...
@@ -1023,7 +1023,7 @@ struct GCCharAddInfo {
uint8_t pk_mode;
uint32_t mount_vnum;
};
static_assert(sizeof(GCCharAddInfo) == 1 + 4 + 25 + 8 + 1 + 4 + 4 + 2 + 1 + 4); // 54
static_assert(sizeof(GCCharAddInfo) == 1 + 4 + (CHARACTER_NAME_MAX_LEN + 1) + 8 + 1 + 4 + 4 + 2 + 1 + 4); // 94
// --- GC skills / quickslots ---
struct PlayerSkill3 { // TPlayerSkill (common/tables.h) — time_t is 32-bit on the -m32 server
@@ -1064,7 +1064,7 @@ struct GCWhisperHead { // packet_whisper (header 34) — + text
uint8_t type;
char name_from[CHARACTER_NAME_MAX_LEN + 1];
};
static_assert(sizeof(GCWhisperHead) == 1 + 2 + 1 + 25); // 29
static_assert(sizeof(GCWhisperHead) == 1 + 2 + 1 + (CHARACTER_NAME_MAX_LEN + 1)); // 69
struct SyncPosElement { uint32_t vid; int32_t x, y; };
static_assert(sizeof(SyncPosElement) == 12);
@@ -1133,7 +1133,7 @@ struct GCPartyRemove { uint8_t header; uint32_t pid; }; // hea
struct GCPartyLink { uint8_t header; uint32_t pid; uint32_t vid; }; // header 91
struct GCPartyUnlink { uint8_t header; uint32_t pid; uint32_t vid; }; // header 92
struct GCPartyParameter { uint8_t header; uint8_t distribute_mode; }; // header 83
static_assert(sizeof(GCPartyInvite) == 5 && sizeof(GCPartyAdd) == 30 &&
static_assert(sizeof(GCPartyInvite) == 5 && sizeof(GCPartyAdd) == 70 &&
sizeof(GCPartyUpdate) == 21 && sizeof(GCPartyRemove) == 5 && sizeof(GCPartyLink) == 9 &&
sizeof(GCPartyParameter) == 2);
@@ -1288,11 +1288,11 @@ struct GuildInvite17 {
uint32_t guild_id;
char guild_name[GUILD_NAME_MAX_LEN + 1];
};
static_assert(sizeof(GuildMember38) == 38 && sizeof(GuildInfo35) == 35 &&
static_assert(sizeof(GuildMember38) == 78 && sizeof(GuildInfo35) == 35 &&
sizeof(GuildGrade10) == 10 && sizeof(GuildWar10) == 10 &&
sizeof(GuildWarPoint12) == 12 && sizeof(GuildWarPair8) == 8 &&
sizeof(GuildName16) == 16 && sizeof(GuildSkill17) == 17 &&
sizeof(GuildComment80) == 80 && sizeof(GuildInvite17) == 17);
sizeof(GuildComment80) == 120 && sizeof(GuildInvite17) == 17);
// CGuild::SendSkillInfoPacket() (guild.cpp) announces
// `size = sizeof(pack) + 6 + GUILD_SKILL_COUNT` (22) but writes only
@@ -1306,7 +1306,7 @@ inline constexpr int GUILD_SKILL_INFO_PACKET_SIZE = 4 + sizeof(GuildSkill17); //
struct CGChatHead { uint8_t header; uint16_t length; uint8_t type; }; // + char szChat[]
static_assert(sizeof(CGChatHead) == 4);
struct CGWhisper { uint8_t header; uint16_t size; char name_to[CHARACTER_NAME_MAX_LEN + 1]; };
static_assert(sizeof(CGWhisper) == 28);
static_assert(sizeof(CGWhisper) == 1 + 2 + (CHARACTER_NAME_MAX_LEN + 1)); // 68
struct GCChatHead { // packet_chatting — + text
uint8_t header;
+12 -12
View File
@@ -31,11 +31,11 @@ int main() {
// --- struct sizes (redundant with static_assert, but explicit) ---
CHECK(sizeof(Handshake) == 13, "sizeof Handshake");
CHECK(sizeof(CGText) == 1, "sizeof CG_TEXT base");
CHECK(sizeof(SimplePlayer) == 63, "sizeof SimplePlayer");
CHECK(sizeof(GCMainCharacter) == 46, "sizeof GCMainCharacter");
CHECK(sizeof(GCMainCharacter3BGM) == 71 && sizeof(GCMainCharacter4BGM) == 75,
CHECK(sizeof(SimplePlayer) == 103, "sizeof SimplePlayer");
CHECK(sizeof(GCMainCharacter) == 86, "sizeof GCMainCharacter");
CHECK(sizeof(GCMainCharacter3BGM) == 111 && sizeof(GCMainCharacter4BGM) == 115,
"sizeof main-character BGM variants");
CHECK(sizeof(GCCharacterAdd2) == 80 && sizeof(GCCharacterUpdate) == 35,
CHECK(sizeof(GCCharacterAdd2) == 120 && sizeof(GCCharacterUpdate) == 35,
"sizeof character add/update variants");
CHECK(sizeof(GCFishing) == 7, "sizeof GC_FISHING");
CHECK(sizeof(GCWarpClassic) == 15, "sizeof classic GC_WARP");
@@ -43,7 +43,7 @@ int main() {
"sizeof auth success packets");
CHECK(sizeof(GCPasspodFailed) == 130 && sizeof(GCXTrapRequest) == 129 && sizeof(GCHSRequest) == 403,
"sizeof optional security packets");
CHECK(sizeof(GCLoginSuccess) == 329, "sizeof GCLoginSuccess (NEWSLOT, 4 players)");
CHECK(sizeof(GCLoginSuccess) == 489, "sizeof GCLoginSuccess (NEWSLOT, 4 players)");
CHECK(sizeof(GCPoints) == 1 + 255 * 4, "sizeof GCPoints");
CHECK(sizeof(GCPointChange) == 17, "sizeof GCPointChange (int header quirk)");
CHECK(sizeof(CGMove) == 16, "sizeof CGMove");
@@ -55,16 +55,16 @@ int main() {
// --- size-table lookup (body size, no trailing seq byte) ---
CHECK(packet_size_gc(HDR_GC_PHASE) == 2, "gc size PHASE");
CHECK(packet_size_gc(HDR_GC_MAIN_CHARACTER) == 46, "gc size MAIN_CHARACTER");
CHECK(packet_size_gc(HDR_GC_MAIN_CHARACTER) == 86, "gc size MAIN_CHARACTER");
CHECK(packet_size_gc(HDR_GC_WARP) == sizeof(GCWarpClassic), "gc size WARP");
CHECK(packet_size_gc(HDR_GC_MAIN_CHARACTER3_BGM) == 71 &&
packet_size_gc(HDR_GC_MAIN_CHARACTER4_BGM_VOL) == 75, "gc size MAIN_CHARACTER BGM");
CHECK(packet_size_gc(HDR_GC_CHARACTER_ADD2) == 80 &&
CHECK(packet_size_gc(HDR_GC_MAIN_CHARACTER3_BGM) == 111 &&
packet_size_gc(HDR_GC_MAIN_CHARACTER4_BGM_VOL) == 115, "gc size MAIN_CHARACTER BGM");
CHECK(packet_size_gc(HDR_GC_CHARACTER_ADD2) == 120 &&
packet_size_gc(HDR_GC_CHARACTER_UPDATE2) == 35, "gc size character variants");
CHECK(packet_size_gc(HDR_GC_FISHING) == 7, "gc size FISHING");
CHECK(packet_size_gc(HDR_GC_AUTH_SUCCESS) == 6 &&
packet_size_gc(HDR_GC_XTRAP_CS1_REQUEST) == 129, "gc size auth/security");
CHECK(packet_size_gc(HDR_GC_LOGIN_SUCCESS_NEWSLOT) == 329, "gc size LOGIN_SUCCESS_NEWSLOT");
CHECK(packet_size_gc(HDR_GC_LOGIN_SUCCESS_NEWSLOT) == 489, "gc size LOGIN_SUCCESS_NEWSLOT");
CHECK(packet_size_gc(HDR_GC_CHARACTER_POINTS) == 1021, "gc size CHARACTER_POINTS");
CHECK(packet_size_gc(HDR_GC_EXCHANGE) == 47, "gc size EXCHANGE");
CHECK(packet_size_gc(HDR_GC_SAFEBOX_MONEY_CHANGE) == 5, "gc size SAFEBOX_MONEY_CHANGE");
@@ -121,8 +121,8 @@ int main() {
CHECK(buf[0] == 113, "wire byte 0 == header");
// header(1) vid(4) race(2) name(25) -> x at offset 32
int32_t x_wire;
std::memcpy(&x_wire, buf + 1 + 4 + 2 + 25, 4);
CHECK(x_wire == 100000, "wire x at offset 32");
std::memcpy(&x_wire, buf + 1 + 4 + 2 + (CHARACTER_NAME_MAX_LEN + 1), 4);
CHECK(x_wire == 100000, "wire x at offset");
GCMainCharacter rt{};
std::memcpy(&rt, buf, sizeof(rt));