فهرست منبع

outgoing packets, support for sending signed types

Kajetan Johannes Hammerle 3 سال پیش
والد
کامیت
b4491e2713
5فایلهای تغییر یافته به همراه212 افزوده شده و 12 حذف شده
  1. 7 0
      network/Client.cpp
  2. 3 0
      network/Client.h
  3. 117 7
      network/Packet.cpp
  4. 31 4
      network/Packet.h
  5. 54 1
      tests/NetworkTests.cpp

+ 7 - 0
network/Client.cpp

@@ -56,4 +56,11 @@ void Client::disconnect() {
     }
     enet_peer_reset(connection);
     connection = nullptr;
+}
+
+void Client::send(OutPacket& p) {
+    if(p.packet != nullptr) {
+        enet_peer_send(connection, 0, p.packet);
+        p.packet = nullptr;
+    }
 }

+ 3 - 0
network/Client.h

@@ -2,6 +2,7 @@
 #define CLIENT_H
 
 #include "network/ENet.h"
+#include "network/Packet.h"
 #include "utils/StringBuffer.h"
 
 class Client final {
@@ -41,6 +42,8 @@ public:
             }
         }
     }
+
+    void send(OutPacket& p);
 };
 
 #endif

+ 117 - 7
network/Packet.cpp

@@ -1,22 +1,24 @@
+#include <utility>
+
 #include "network/Packet.h"
 
-InPacket::InPacket(ENetPacket* packet) : packet(packet), readIndex(0) {
+InPacket::InPacket(ENetPacket* packet) : packet(packet), index(0) {
 }
 
 bool InPacket::read(void* buffer, unsigned int length) {
-    if(readIndex + length > packet->dataLength) {
+    if(index + length > packet->dataLength) {
         return true;
     }
-    memcpy(buffer, packet->data + readIndex, length);
-    readIndex += length;
+    memcpy(buffer, packet->data + index, length);
+    index += length;
     return false;
 }
 
-bool InPacket::read(uint8& u) {
+bool InPacket::readU8(uint8& u) {
     return read(&u, sizeof(u));
 }
 
-bool InPacket::read(uint16& u) {
+bool InPacket::readU16(uint16& u) {
     if(read(&u, sizeof(u))) {
         return true;
     }
@@ -24,10 +26,118 @@ bool InPacket::read(uint16& u) {
     return false;
 }
 
-bool InPacket::read(uint32& u) {
+bool InPacket::readU32(uint32& u) {
     if(read(&u, sizeof(u))) {
         return true;
     }
     u = ntohl(u);
     return false;
 }
+
+bool InPacket::readS8(int8& s) {
+    uint8 u;
+    if(readU8(u)) {
+        return true;
+    }
+    if(u < 128) {
+        s = static_cast<int8>(u) - 128;
+    } else {
+        s = u - 128;
+    }
+    return false;
+}
+
+bool InPacket::readS16(int16& s) {
+    uint16 u;
+    if(readU16(u)) {
+        return true;
+    }
+    if(u < 32768) {
+        s = static_cast<int16>(u) - 32768;
+    } else {
+        s = u - 32768;
+    }
+    return false;
+}
+
+bool InPacket::readS32(int32& s) {
+    uint32 u;
+    if(readU32(u)) {
+        return true;
+    }
+    if(u < 2147483648) {
+        s = static_cast<int32>(u) - 2147483648;
+    } else {
+        s = u - 2147483648;
+    }
+    return false;
+}
+
+OutPacket::OutPacket(unsigned int size, int flags)
+    : packet(enet_packet_create(nullptr, size, flags)), index(0) {
+}
+
+OutPacket::~OutPacket() {
+    enet_packet_destroy(packet);
+}
+
+OutPacket::OutPacket(const OutPacket& other)
+    : packet(enet_packet_copy(other.packet)), index(other.index) {
+}
+
+OutPacket::OutPacket(OutPacket&& other) : packet(nullptr), index(0) {
+    std::swap(packet, other.packet);
+    std::swap(index, other.index);
+}
+
+OutPacket& OutPacket::operator=(OutPacket other) {
+    std::swap(packet, other.packet);
+    std::swap(index, other.index);
+    return *this;
+}
+
+void OutPacket::write(const void* buffer, unsigned int length) {
+    if(packet == nullptr || index + length > packet->dataLength) {
+        return;
+    }
+    memcpy(packet->data + index, buffer, length);
+    index += length;
+}
+
+void OutPacket::writeU8(uint8 u) {
+    write(&u, sizeof(u));
+}
+
+void OutPacket::writeU16(uint16 u) {
+    u = htons(u);
+    write(&u, sizeof(u));
+}
+
+void OutPacket::writeU32(uint32 u) {
+    u = htonl(u);
+    write(&u, sizeof(u));
+}
+
+void OutPacket::writeS8(int8 s) {
+    if(s < 0) {
+        writeU8(s + 128);
+    } else {
+        writeU8(static_cast<uint8>(s) + 128);
+    }
+}
+
+void OutPacket::writeS16(int16 s) {
+    if(s < 0) {
+        writeU16(s + 32768);
+    } else {
+        writeU16(static_cast<uint16>(s) + 32768);
+    }
+}
+
+void OutPacket::writeS32(int32 s) {
+    if(s < 0) {
+        writeU32(s + 2147483648);
+    } else {
+        writeU32(static_cast<uint32>(s) + 2147483648);
+    }
+}

+ 31 - 4
network/Packet.h

@@ -6,7 +6,7 @@
 
 class InPacket {
     ENetPacket* packet;
-    unsigned int readIndex;
+    unsigned int index;
 
     friend class Server;
 
@@ -15,9 +15,36 @@ class InPacket {
     bool read(void* buffer, unsigned int length);
 
 public:
-    bool read(uint8& u);
-    bool read(uint16& u);
-    bool read(uint32& u);
+    bool readU8(uint8& u);
+    bool readU16(uint16& u);
+    bool readU32(uint32& u);
+    bool readS8(int8& u);
+    bool readS16(int16& u);
+    bool readS32(int32& u);
+};
+
+class OutPacket {
+    ENetPacket* packet;
+    unsigned int index;
+
+    friend class Client;
+
+public:
+    OutPacket(unsigned int size, int flags);
+    ~OutPacket();
+    OutPacket(const OutPacket& other);
+    OutPacket(OutPacket&& other);
+    OutPacket& operator=(OutPacket other);
+
+    void writeU8(uint8 u);
+    void writeU16(uint16 u);
+    void writeU32(uint32 u);
+    void writeS8(int8 s);
+    void writeS16(int16 s);
+    void writeS32(int32 s);
+
+private:
+    void write(const void* buffer, unsigned int length);
 };
 
 #endif

+ 54 - 1
tests/NetworkTests.cpp

@@ -14,6 +14,16 @@ struct ServerConsumer {
     bool connected = false;
     bool disconnect = false;
 
+    uint8 data1 = 0;
+    uint16 data2 = 0;
+    uint32 data3 = 0;
+    int8 data4 = 0;
+    int16 data5 = 0;
+    int32 data6 = 0;
+    int8 data7 = 0;
+    int16 data8 = 0;
+    int32 data9 = 0;
+
     void onConnection(Server::Client& client) {
         (void)client;
         connected = true;
@@ -26,7 +36,15 @@ struct ServerConsumer {
 
     void onPackage(Server::Client& client, InPacket& in) {
         (void)client;
-        (void)in;
+        in.readU8(data1);
+        in.readU16(data2);
+        in.readU32(data3);
+        in.readS8(data4);
+        in.readS16(data5);
+        in.readS32(data6);
+        in.readS8(data7);
+        in.readS16(data8);
+        in.readS32(data9);
     }
 };
 
@@ -60,8 +78,43 @@ static void testConnect(Test& test) {
         client.consumeEvents(clientConsumer);
     }
 
+    OutPacket out(21, 0);
+    out.writeU8(0xF1);
+    out.writeU16(0xF123);
+    out.writeU32(0xF1234567);
+    out.writeS8(-0x71);
+    out.writeS16(-0x7123);
+    out.writeS32(-0x71234567);
+    out.writeS8(0x71);
+    out.writeS16(0x7123);
+    out.writeS32(0x71234567);
+    client.send(out);
+
+    for(int i = 0; i < 100; i++) {
+        client.consumeEvents(clientConsumer);
+    }
+
     test.checkEqual(true, serverConsumer.connected, "server has connection");
 
+    test.checkEqual(static_cast<uint8>(0xF1), serverConsumer.data1,
+                    "correct value is sent 1");
+    test.checkEqual(static_cast<uint16>(0xF123), serverConsumer.data2,
+                    "correct value is sent 2");
+    test.checkEqual(0xF1234567u, serverConsumer.data3,
+                    "correct value is sent 3");
+    test.checkEqual(static_cast<int8>(-0x71), serverConsumer.data4,
+                    "correct value is sent 4");
+    test.checkEqual(static_cast<int16>(-0x7123), serverConsumer.data5,
+                    "correct value is sent 5");
+    test.checkEqual(-0x71234567, serverConsumer.data6,
+                    "correct value is sent 6");
+    test.checkEqual(static_cast<int8>(0x71), serverConsumer.data7,
+                    "correct value is sent 7");
+    test.checkEqual(static_cast<int16>(0x7123), serverConsumer.data8,
+                    "correct value is sent 8");
+    test.checkEqual(0x71234567, serverConsumer.data9,
+                    "correct value is sent 9");
+
     client.disconnect();
     sleep(100);