From 17d41e82f4fc28c9966e3b4773e686cdec502dc9 Mon Sep 17 00:00:00 2001 From: hovertank3d Date: Fri, 27 Feb 2026 14:51:32 +0100 Subject: implement messages 6 to 9 --- PROTOCOL.md | 60 +++++++++++++++++++++++++++++++--- include/net/types.hpp | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 146 insertions(+), 4 deletions(-) diff --git a/PROTOCOL.md b/PROTOCOL.md index 059f50c..6f0b0be 100644 --- a/PROTOCOL.md +++ b/PROTOCOL.md @@ -12,10 +12,10 @@ this should suffice as a starting point. | 3 | c<-s | ☑ | ☑ | accept | accept connection | | 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 | ☑ | ☐ | | | -| 9 | c<-s | ☑ | ☐ | | | +| 6 | c->s | ☑ | ☑ | request_world_info | | +| 7 | c<-s | ☑ | ☑ | world_info | server sends world metadata | +| 8 | c->s | ☑ | ☑ | request_spawn | request to spawn player at given location | +| 9 | c<-s | ☑ | ☑ | set_loading_message | messages shown while loading the world | | 10 | c<-s | ☑ | ☐ | | | | 11 | | ☐ | ☐ | | | | 12 | c->s | ☑ | ☐ | | | @@ -442,3 +442,55 @@ ilspy decompilation: NetMessage.TrySendData(5, -1, whoAmI, null, num35, num36); } ``` + + +## `id 6` `s<-c` request_world_info +client asks server about world info (parts of world file header) + +| name | type | size | description | +|--|--|--|--| +| | | | | + +## `id 7` `s->c` world_info +info about world state +TODO describe fields + +| name | type | size | description | +|--|--|--|--| +| | | | | + + +## `id 8` `s<-c` request_spawn +request to spawn player at given location with team selected + +| name | type | size | description | +|--|--|--|--| +| tile | vec2 | 8 | spawn location | +| team | uint8_t | 1 | team | + +```csharp + // Terraria.Netplay.InnerClientLoop + else if (Connection.State == 5 && WorldGen.worldCleared) + { + Connection.State = 6; + Main.player[Main.myPlayer].FindSpawn(); + NetMessage.SendData(8, -1, -1, null, Main.player[Main.myPlayer].SpawnX, Main.player[Main.myPlayer].SpawnY, Main.player[Main.myPlayer].team); + } +``` + +## `id 9` `s<-c` set_loading_message + +| name | type | size | description | +|--|--|--|--| +| sections | uint32 | 4 | number of sections | +| message | nstring | - | message to be shown | +| flags | uint8_t | 1 | unused | + +```csharp + // Terraria.NetMessage.SendData + case 9: + writer.Write(number); + text.Serialize(writer); + BitsByte bitsByte30 = (byte)number2; + writer.Write(bitsByte30); +``` \ No newline at end of file diff --git a/include/net/types.hpp b/include/net/types.hpp index b565f51..fcc8b26 100644 --- a/include/net/types.hpp +++ b/include/net/types.hpp @@ -1,6 +1,8 @@ #pragma once +#include #include +#include #include #include #include @@ -73,6 +75,30 @@ struct vec2 { T y; }; + +template +struct plist { + std::vector v; + + template + ssize_t read(io::serialized_io& io) { + uint8_t len; + + auto offset = io.read(len); + v.resize(len); + offset += io.read(v); + + return offset; + } + + template + ssize_t write(io::serialized_io& io) { + auto offset = io.write(uint8_t(v.size())); + offset += io.write(v); + return offset; + } +}; + // NetMessages struct connect { @@ -135,6 +161,70 @@ struct player_inventory_slot { bitset<2> flags; }; +struct request_world_info { + static constexpr uint8_t packet_id = 6; +}; + +struct world_info { + static constexpr uint8_t packet_id = 7; + + int32_t time; + bitset<3> time_flags; // day? blood moon? eclipse? + uint8_t moon_phase; + vec2 tiles_limit; + vec2 spawn_tile; + uint16_t surface_level; + uint16_t rock_level; + int32_t worldid; + std::string worldname; + uint8_t gamemode; + std::array uuid; + uint64_t worldgen_version; + uint8_t moon_type; + std::array backgrounds; + std::array bg_styles; + + float wind_speed_target; + uint8_t num_clouds; + + std::array trees; + std::array trees_styles; + std::array cave_bg; + std::array cave_bg_styles; + + std::array tree_tops; + + float max_raining; + + bitset<81> flags; // TODO: document them + + uint8_t sundial_cooldown; + uint8_t moondial_cooldown; + + std::array world_ores; + int8_t invasion_type; + + uint64_t lobby_id = 0; + + float sandstorm_severity; + plist> extra_spawn_points; +}; + +struct request_spawn { + static constexpr uint8_t packet_id = 8; + + vec2 tile; + uint8_t team; +}; + +struct set_loading_message { + static constexpr uint8_t packet_id = 9; + + int32_t sections; + nstring message; + uint8_t flags = 0; +}; + inline nstring operator""_ns(const char* str, std::size_t) { return nstring{nstring::Literal, str}; -- cgit v1.2.3