summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhovertank3d <[email protected]>2026-02-23 23:17:56 +0100
committerhovertank3d <[email protected]>2026-02-23 23:38:17 +0100
commit30eb23ffe5f7b9e8c3b4267457d0aa3bd02665e7 (patch)
tree1c09155c7684564f4f642081f6255c76822eda9d
parentce7c377dd839fd8af71dfe505d930884e6fb0e2e (diff)
downloadogurec-30eb23ffe5f7b9e8c3b4267457d0aa3bd02665e7.tar.gz
ogurec-30eb23ffe5f7b9e8c3b4267457d0aa3bd02665e7.zip
implement `connect`, `disconnect` and `accept`
-rw-r--r--PROTOCOL.md64
-rw-r--r--include/net/types.hpp21
-rw-r--r--include/util/io.hpp9
3 files changed, 85 insertions, 9 deletions
diff --git a/PROTOCOL.md b/PROTOCOL.md
index 3bf9358..a0dd433 100644
--- a/PROTOCOL.md
+++ b/PROTOCOL.md
@@ -7,9 +7,9 @@ this should suffice as a starting point.
| id | direction | captured | known | packet name | short description |
|-|-|-|-|-|-|
| 0 | | &#x2610; | &#x2610; | | |
-| 1 | c->s | &#x2611; | &#x2610; | | |
-| 2 | | &#x2610; | &#x2610; | | |
-| 3 | c<-s | &#x2611; | &#x2610; | | |
+| 1 | c->s | &#x2611; | &#x2611; | connect | login initialization |
+| 2 | s->c | &#x2611; | &#x2611; | disconnect | kick client |
+| 3 | c<-s | &#x2611; | &#x2611; | accept | accept connection |
| 4 | c->s | &#x2611; | &#x2610; | | |
| 5 | c->s | &#x2611; | &#x2610; | | |
| 6 | c->s | &#x2611; | &#x2610; | | |
@@ -261,4 +261,60 @@ this should suffice as a starting point.
| 252 | | &#x2610; | &#x2610; | | |
| 253 | | &#x2610; | &#x2610; | | |
| 254 | | &#x2610; | &#x2610; | | |
-| 255 | | &#x2610; | &#x2610; | | | \ No newline at end of file
+| 255 | | &#x2610; | &#x2610; | | |
+
+
+## `id 1` `c->s` connect
+
+| name | type | size | description |
+|--|--|--|--|
+| version | pstring | - | terraria protocol version in form of "TerrariaXXX" |
+
+ilspy decompilation:
+```csharp
+ // Terraria.NetMessage.SendData
+ case 1:
+ writer.Write("Terraria" + 318);
+ break;
+```
+
+## `id 2` `s->c` disconnect
+kick client from server. server closes connection right after sending this
+
+| name | type | size | description |
+|--|--|--|--|
+| reason | netstring | - | reason for kicking. may be ban, invalid client version, etc. |
+
+ilspy decompilation:
+```csharp
+ // Terraria.NetMessage.SendData
+ case 2:
+ text.Serialize(writer);
+ if (Main.dedServ)
+ {
+ Console.WriteLine(Language.GetTextValue("CLI.ClientWasBooted", Netplay.Clients[num].Socket.GetRemoteAddress().ToString(), text));
+ }
+ break;
+```
+
+## `id 3` `s->c` accept
+accept client connection, pick new (player) slot id and send server flags
+
+| name | type | size | description |
+|--|--|--|--|
+| slot | uint8_t | 1 | player id |
+| server_flags | uint8_t | 1 | flags, always 0 |
+
+ilspy decompilation:
+```csharp
+ // Terraria.NetMessage.SendData
+ case 3:
+ writer.Write((byte)remoteClient);
+ writer.Write(value: false);
+ break;
+
+ // Terraria.MessageBuffer.GetData
+ int num95 = reader.ReadByte();
+ bool value2 = reader.ReadBoolean();
+ Netplay.Connection.ServerSpecialFlags[2] = value2;
+``` \ No newline at end of file
diff --git a/include/net/types.hpp b/include/net/types.hpp
index b9453d6..5301021 100644
--- a/include/net/types.hpp
+++ b/include/net/types.hpp
@@ -72,6 +72,25 @@ struct vec2 {
T y;
};
+// NetMessages
+
+struct connect {
+ static constexpr uint8_t packet_id = 1;
+
+ std::string version;
+};
+
+struct disconnect {
+ static constexpr uint8_t packet_id = 2;
+
+ nstring reason;
+};
+
+struct accept {
+ uint8_t slot;
+ uint8_t server_flags = 0;
+};
+
inline nstring operator""_ns(const char* str, std::size_t)
{
return nstring{nstring::Literal, str};
@@ -79,3 +98,5 @@ inline nstring operator""_ns(const char* str, std::size_t)
}
}
+
+using net::packet::operator""_ns;
diff --git a/include/util/io.hpp b/include/util/io.hpp
index 629bf59..9131a96 100644
--- a/include/util/io.hpp
+++ b/include/util/io.hpp
@@ -16,11 +16,11 @@
namespace io {
template <class T, class K>
-concept custom_write = requires(T t) {
- { t.write(K()) } -> std::same_as<ssize_t>;
+concept custom_write = requires(T t, K &k) {
+ { t.write(k) } -> std::same_as<ssize_t>;
};
template <class T, class K>
-concept custom_read = requires(T& t, K& k) {
+concept custom_read = requires(T& t, K &k) {
{ t.read(k) } -> std::same_as<ssize_t>;
};
@@ -108,7 +108,6 @@ public:
template <class I>
class serialized_io {
I io;
-
public:
serialized_io(I io)
: io(io)
@@ -193,7 +192,7 @@ public:
}
template <custom_write<serialized_io<I>> T>
- ssize_t write(T& f)
+ ssize_t write(T f)
{
return f.write(*this);
}