From 503d6ae839c89d7fc481492dd7d2cbe1d39086eb Mon Sep 17 00:00:00 2001 From: hovertank3d Date: Thu, 26 Feb 2026 16:31:25 +0100 Subject: implement `player_inventory_slot` --- PROTOCOL.md | 52 ++++++++++++++++++++++++++++++++++++++++++++++++--- include/net/types.hpp | 39 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 86 insertions(+), 5 deletions(-) diff --git a/PROTOCOL.md b/PROTOCOL.md index 0ac162a..059f50c 100644 --- a/PROTOCOL.md +++ b/PROTOCOL.md @@ -10,8 +10,8 @@ this should suffice as a starting point. | 1 | c->s | ☑ | ☑ | connect | login initialization | | 2 | s->c | ☑ | ☑ | disconnect | kick client | | 3 | c<-s | ☑ | ☑ | accept | accept connection | -| 4 | c->s | ☑ | ☐ | player_info | inform server about player appearance and permabuffs| -| 5 | c->s | ☑ | ☐ | | | +| 4 | c->s | ☑ | ☑ | player_info | inform server about player appearance and permabuffs| +| 5 | c->s | ☑ | ☑ | player_inventory slot | tell the server about single inventory slot contents | | 6 | c->s | ☑ | ☐ | | | | 7 | c<-s | ☑ | ☐ | | | | 8 | c->s | ☑ | ☐ | | | @@ -395,4 +395,50 @@ ilspy decompilation: bitsByte22[5] = player5.usedAmbrosia; bitsByte22[6] = player5.ateArtisanBread; writer.Write(bitsByte22); -``` \ No newline at end of file +``` + +## `id 5` `s<-c` player_inventory_slot +tell the server about single inventory slot contents. +flags[1] have something to do with auto stacking to locked chests + +| name | type | size | description | +|--|--|--|--| +| slot | uint8_t | 1 | player id | +| inventory_id | uint16_t | 2 | inventory slot id | +| stack | uint16_t | 2 | item count in the slot | +| prefix | uint8_t | 1 | prefix id | +| type | uint16_t | 2 | item id | +| flags | bitset | 1 | flags. flags[0] - favourite, flags[1] - block transfer | + +ilspy decompilation: +```csharp + // Terraria.NetMessage.SendData + writer.Write((byte)number); + writer.Write((short)number2); + Item item5 = new PlayerItemSlotID.SlotReference(Main.player[number], (int)number2).Item; + if (item5.Name == "" || item5.stack == 0 || item5.type == 0) + { + item5.SetDefaults(0); + } + int num7 = item5.stack; + int type = item5.type; + if (num7 < 0) + { + num7 = 0; + } + writer.Write((short)num7); + writer.Write(item5.prefix); + writer.Write((short)type); + writer.Write(new BitsByte + { + [0] = item5.favorited, + [1] = number3 != 0f + }); + + // Terraria.MessageBuffer.GetData + bool[] canRelay = PlayerItemSlotID.CanRelay; + if (Main.netMode == 2 && num35 == whoAmI && canRelay.IndexInRange(num36) && canRelay[num36]) + { + NetMessage.TrySendData(5, -1, whoAmI, null, num35, num36); + } +``` diff --git a/include/net/types.hpp b/include/net/types.hpp index c16ca36..b565f51 100644 --- a/include/net/types.hpp +++ b/include/net/types.hpp @@ -7,6 +7,7 @@ #include #include "util/io.hpp" +#include "util/bitset.hpp" namespace net { namespace packet { @@ -96,8 +97,42 @@ struct accept { struct player_info { static constexpr uint8_t packet_id = 4; - uint8_t slot; - uint8_t server_flags = 0; + uint8_t slot; + uint8_t skin_variant; + uint8_t voice_variant; + float voice_offset; + uint8_t hair; + std::string name; + uint8_t hair_dye; + bitset<16> hidden_accessories; // FIXME: this is rounded number of flags. Terraria may use less than 16 + bitset<8> hide_misc; // same here + rgb hair_color; + rgb skin_color; + rgb eye_color; + rgb shirt_color; + rgb undershirt_color; + rgb pants_color; + rgb shoe_color; + bitset<4> player_difficulty; + bitset<5> permanent_buffs; + bitset<7> permanent_buffs_shimmer; +}; + +struct player_inventory_slot { + static constexpr uint8_t packet_id = 5; + + enum class slot_flags : int { + Favourite = 0, + BlockTransfer = 1, + }; + + uint8_t slot; + uint16_t item_slot_id; + + uint16_t stack; + uint8_t prefix; + uint16_t type; + bitset<2> flags; }; inline nstring operator""_ns(const char* str, std::size_t) -- cgit v1.2.3