summaryrefslogtreecommitdiff
path: root/src/net/packets.hpp
diff options
context:
space:
mode:
authorBen Longbons <b.r.longbons@gmail.com>2014-05-27 13:33:54 -0700
committerBen Longbons <b.r.longbons@gmail.com>2014-05-27 13:33:54 -0700
commitaf4acff261d579428e8eef042cc5359fa392f725 (patch)
treeca73d54da799c3751e87ec88a785d60e7561a2f0 /src/net/packets.hpp
parentcac49afdef0992b93d8718fd928d73d721d434f4 (diff)
downloadtmwa-af4acff261d579428e8eef042cc5359fa392f725.tar.gz
tmwa-af4acff261d579428e8eef042cc5359fa392f725.tar.bz2
tmwa-af4acff261d579428e8eef042cc5359fa392f725.tar.xz
tmwa-af4acff261d579428e8eef042cc5359fa392f725.zip
Generate the char server protocol
Diffstat (limited to 'src/net/packets.hpp')
-rw-r--r--src/net/packets.hpp169
1 files changed, 167 insertions, 2 deletions
diff --git a/src/net/packets.hpp b/src/net/packets.hpp
index 6146b90..293aed8 100644
--- a/src/net/packets.hpp
+++ b/src/net/packets.hpp
@@ -79,6 +79,14 @@ SendResult net_send_fpacket(Session *s, const NetPacket_Fixed<id>& fixed)
template<uint16_t id>
__attribute__((warn_unused_result))
+SendResult net_send_ppacket(Session *s, const NetPacket_Payload<id>& payload)
+{
+ bool ok = packet_send(s, reinterpret_cast<const Byte *>(&payload), sizeof(NetPacket_Payload<id>));
+ return ok ? SendResult::Success : SendResult::Fail;
+}
+
+template<uint16_t id>
+__attribute__((warn_unused_result))
SendResult net_send_vpacket(Session *s, const NetPacket_Head<id>& head, const std::vector<NetPacket_Repeat<id>>& repeat)
{
bool ok = packet_send(s, reinterpret_cast<const Byte *>(&head), sizeof(NetPacket_Head<id>));
@@ -88,6 +96,18 @@ SendResult net_send_vpacket(Session *s, const NetPacket_Head<id>& head, const st
template<uint16_t id>
__attribute__((warn_unused_result))
+SendResult net_send_opacket(Session *s, const NetPacket_Head<id>& head, bool has_opt, const NetPacket_Option<id>& opt)
+{
+ bool ok = packet_send(s, reinterpret_cast<const Byte *>(&head), sizeof(NetPacket_Head<id>));
+ if (has_opt)
+ {
+ ok &= packet_send(s, reinterpret_cast<const Byte *>(&opt), sizeof(NetPacket_Option<id>));
+ }
+ return ok ? SendResult::Success : SendResult::Fail;
+}
+
+template<uint16_t id>
+__attribute__((warn_unused_result))
RecvResult net_recv_fpacket(Session *s, NetPacket_Fixed<id>& fixed)
{
bool ok = packet_fetch(s, 0, reinterpret_cast<Byte *>(&fixed), sizeof(NetPacket_Fixed<id>));
@@ -101,6 +121,19 @@ RecvResult net_recv_fpacket(Session *s, NetPacket_Fixed<id>& fixed)
template<uint16_t id>
__attribute__((warn_unused_result))
+RecvResult net_recv_ppacket(Session *s, NetPacket_Payload<id>& payload)
+{
+ bool ok = packet_fetch(s, 0, reinterpret_cast<Byte *>(&payload), sizeof(NetPacket_Payload<id>));
+ if (ok)
+ {
+ packet_discard(s, sizeof(NetPacket_Payload<id>));
+ return RecvResult::Complete;
+ }
+ return RecvResult::Incomplete;
+}
+
+template<uint16_t id>
+__attribute__((warn_unused_result))
RecvResult net_recv_vpacket(Session *s, NetPacket_Head<id>& head, std::vector<NetPacket_Repeat<id>>& repeat)
{
bool ok = packet_fetch(s, 0, reinterpret_cast<Byte *>(&head), sizeof(NetPacket_Head<id>));
@@ -127,6 +160,37 @@ RecvResult net_recv_vpacket(Session *s, NetPacket_Head<id>& head, std::vector<Ne
return RecvResult::Incomplete;
}
+template<uint16_t id>
+__attribute__((warn_unused_result))
+RecvResult net_recv_opacket(Session *s, NetPacket_Head<id>& head, bool *has_opt, NetPacket_Option<id>& opt)
+{
+ bool ok = packet_fetch(s, 0, reinterpret_cast<Byte *>(&head), sizeof(NetPacket_Head<id>));
+ if (ok)
+ {
+ Packet_Head<id> nat;
+ if (!network_to_native(&nat, head))
+ return RecvResult::Error;
+ if (packet_avail(s) < nat.magic_packet_length)
+ return RecvResult::Incomplete;
+ if (nat.magic_packet_length < sizeof(NetPacket_Head<id>))
+ return RecvResult::Error;
+ size_t bytes_repeat = nat.magic_packet_length - sizeof(NetPacket_Head<id>);
+ if (bytes_repeat % sizeof(NetPacket_Repeat<id>))
+ return RecvResult::Error;
+ size_t has_opt_pls = bytes_repeat / sizeof(NetPacket_Option<id>);
+ if (has_opt_pls > 1)
+ return RecvResult::Error;
+ *has_opt = has_opt_pls;
+ if (!*has_opt || packet_fetch(s, sizeof(NetPacket_Head<id>), reinterpret_cast<Byte *>(&opt), sizeof(NetPacket_Option<id>)))
+ {
+ packet_discard(s, nat.magic_packet_length);
+ return RecvResult::Complete;
+ }
+ return RecvResult::Incomplete;
+ }
+ return RecvResult::Incomplete;
+}
+
template<uint16_t id, uint16_t size>
void send_fpacket(Session *s, const Packet_Fixed<id>& fixed)
@@ -145,6 +209,23 @@ void send_fpacket(Session *s, const Packet_Fixed<id>& fixed)
s->set_eof();
}
+template<uint16_t id>
+void send_ppacket(Session *s, Packet_Payload<id>& payload)
+{
+ static_assert(id == Packet_Payload<id>::PACKET_ID, "Packet_Payload<id>::PACKET_ID");
+
+ NetPacket_Payload<id> net_payload;
+ payload.magic_packet_length = sizeof(NetPacket_Payload<id>);
+ if (!native_to_network(&net_payload, payload))
+ {
+ s->set_eof();
+ return;
+ }
+ SendResult rv = net_send_ppacket(s, net_payload);
+ if (rv != SendResult::Success)
+ s->set_eof();
+}
+
template<uint16_t id, uint16_t headsize, uint16_t repeatsize>
void send_vpacket(Session *s, Packet_Head<id>& head, const std::vector<Packet_Repeat<id>>& repeat)
{
@@ -183,6 +264,43 @@ void send_vpacket(Session *s, Packet_Head<id>& head, const std::vector<Packet_Re
s->set_eof();
}
+template<uint16_t id, uint16_t headsize, uint16_t optsize>
+void send_opacket(Session *s, Packet_Head<id>& head, bool has_opt, const Packet_Option<id>& opt)
+{
+ static_assert(id == Packet_Head<id>::PACKET_ID, "Packet_Head<id>::PACKET_ID");
+ static_assert(headsize == sizeof(NetPacket_Head<id>), "sizeof(NetPacket_Head<id>)");
+ static_assert(id == Packet_Option<id>::PACKET_ID, "Packet_Option<id>::PACKET_ID");
+ static_assert(optsize == sizeof(NetPacket_Option<id>), "sizeof(NetPacket_Option<id>)");
+
+ NetPacket_Head<id> net_head;
+ // since these are already allocated, can't overflow address space
+ size_t total_size = sizeof(NetPacket_Head<id>) + has_opt * sizeof(NetPacket_Option<id>);
+ // truncates
+ head.magic_packet_length = total_size;
+ if (head.magic_packet_length != total_size)
+ {
+ s->set_eof();
+ return;
+ }
+ NetPacket_Option<id> net_opt;
+ if (!native_to_network(&net_head, head))
+ {
+ s->set_eof();
+ return;
+ }
+ if (has_opt)
+ {
+ if (!native_to_network(&net_opt, opt))
+ {
+ s->set_eof();
+ return;
+ }
+ }
+ SendResult rv = net_send_opacket(s, net_head, has_opt, net_opt);
+ if (rv != SendResult::Success)
+ s->set_eof();
+}
+
template<uint16_t id, uint16_t size>
__attribute__((warn_unused_result))
RecvResult recv_fpacket(Session *s, Packet_Fixed<id>& fixed)
@@ -192,11 +310,30 @@ RecvResult recv_fpacket(Session *s, Packet_Fixed<id>& fixed)
NetPacket_Fixed<id> net_fixed;
RecvResult rv = net_recv_fpacket(s, net_fixed);
- assert (fixed.magic_packet_id == Packet_Fixed<id>::PACKET_ID);
if (rv == RecvResult::Complete)
{
if (!network_to_native(&fixed, net_fixed))
return RecvResult::Error;
+ assert (fixed.magic_packet_id == Packet_Fixed<id>::PACKET_ID);
+ }
+ return rv;
+}
+
+template<uint16_t id>
+__attribute__((warn_unused_result))
+RecvResult recv_ppacket(Session *s, Packet_Payload<id>& payload)
+{
+ static_assert(id == Packet_Payload<id>::PACKET_ID, "Packet_Payload<id>::PACKET_ID");
+
+ NetPacket_Payload<id> net_payload;
+ RecvResult rv = net_recv_ppacket(s, net_payload);
+ if (rv == RecvResult::Complete)
+ {
+ if (!network_to_native(&payload, net_payload))
+ return RecvResult::Error;
+ assert (payload.magic_packet_id == Packet_Payload<id>::PACKET_ID);
+ if (payload.magic_packet_length != sizeof(net_payload))
+ return RecvResult::Error;
}
return rv;
}
@@ -213,11 +350,12 @@ RecvResult recv_vpacket(Session *s, Packet_Head<id>& head, std::vector<Packet_Re
NetPacket_Head<id> net_head;
std::vector<NetPacket_Repeat<id>> net_repeat;
RecvResult rv = net_recv_vpacket(s, net_head, net_repeat);
- assert (head.magic_packet_id == Packet_Head<id>::PACKET_ID);
if (rv == RecvResult::Complete)
{
if (!network_to_native(&head, net_head))
return RecvResult::Error;
+ assert (head.magic_packet_id == Packet_Head<id>::PACKET_ID);
+
repeat.resize(net_repeat.size());
for (size_t i = 0; i < net_repeat.size(); ++i)
{
@@ -228,6 +366,33 @@ RecvResult recv_vpacket(Session *s, Packet_Head<id>& head, std::vector<Packet_Re
return rv;
}
+template<uint16_t id, uint16_t headsize, uint16_t optsize>
+__attribute__((warn_unused_result))
+RecvResult recv_opacket(Session *s, Packet_Head<id>& head, bool *has_opt, Packet_Option<id>& opt)
+{
+ static_assert(id == Packet_Head<id>::PACKET_ID, "Packet_Head<id>::PACKET_ID");
+ static_assert(headsize == sizeof(NetPacket_Head<id>), "NetPacket_Head<id>");
+ static_assert(id == Packet_Option<id>::PACKET_ID, "Packet_Option<id>::PACKET_ID");
+ static_assert(optsize == sizeof(NetPacket_Option<id>), "NetPacket_Option<id>");
+
+ NetPacket_Head<id> net_head;
+ NetPacket_Option<id> net_opt;
+ RecvResult rv = net_recv_opacket(s, net_head, has_opt, net_opt);
+ if (rv == RecvResult::Complete)
+ {
+ if (!network_to_native(&head, net_head))
+ return RecvResult::Error;
+ assert (head.magic_packet_id == Packet_Head<id>::PACKET_ID);
+
+ if (*has_opt)
+ {
+ if (!network_to_native(&opt, net_opt))
+ return RecvResult::Error;
+ }
+ }
+ return rv;
+}
+
// convenience for trailing strings