#include "Packet.hpp"
#include "../app/init.hpp"
-#include "../model/CompositeModel.hpp"
+#include "../model/Model.hpp"
#include "../world/Entity.hpp"
#include "../world/EntityState.hpp"
constexpr size_t Packet::PlayerCorrection::MAX_LEN;
constexpr size_t Packet::ChunkBegin::MAX_LEN;
constexpr size_t Packet::ChunkData::MAX_LEN;
+constexpr size_t Packet::BlockUpdate::MAX_LEN;
Connection::Connection(const IPaddress &addr)
: handler(nullptr)
if (diff > 0) {
for (int i = 0; i < diff; ++i) {
if (i > 32 || (i < 32 && (ctrl_in.hist & (1 << (31 - i))) == 0)) {
- Handler().OnPacketLost(ctrl_in.ack - 32 + i);
+ Handler().PacketLost(ctrl_in.ack - 32 + i);
}
}
}
// check for newly ack'd packets
for (uint16_t s = ctrl_new.AckBegin(); s != ctrl_new.AckEnd(); --s) {
if (ctrl_new.Acks(s) && !ctrl_in.Acks(s)) {
- Handler().OnPacketReceived(s);
+ Handler().PacketReceived(s);
}
}
ctrl_in = ctrl_new;
}
+ConnectionHandler::ConnectionHandler()
+: packets_lost(0)
+, packets_received(0)
+, packet_loss(0.0f) {
+
+}
+
+void ConnectionHandler::PacketLost(uint16_t seq) {
+ OnPacketLost(seq);
+ ++packets_lost;
+ UpdatePacketLoss();
+}
+
+void ConnectionHandler::PacketReceived(uint16_t seq) {
+ OnPacketReceived(seq);
+ ++packets_received;
+ UpdatePacketLoss();
+}
+
+void ConnectionHandler::UpdatePacketLoss() noexcept {
+ unsigned int packets_total = packets_lost + packets_received;
+ if (packets_total >= 256) {
+ packet_loss = float(packets_lost) / float(packets_total);
+ packets_lost = 0;
+ packets_received = 0;
+ }
+}
+
+
ostream &operator <<(ostream &out, const IPaddress &addr) {
const unsigned char *host = reinterpret_cast<const unsigned char *>(&addr.host);
out << int(host[0])
return "ChunkBegin";
case ChunkData::TYPE:
return "ChunkData";
+ case BlockUpdate::TYPE:
+ return "BlockUpdate";
default:
return "Unknown";
}
ReadString(name, 68, 32);
}
-void Packet::PlayerUpdate::WritePlayer(const Entity &player) noexcept {
- Write(player.GetState(), 0);
+void Packet::PlayerUpdate::WritePredictedState(const EntityState &state) noexcept {
+ Write(state, 0);
}
-void Packet::PlayerUpdate::ReadPlayerState(EntityState &state) const noexcept {
+void Packet::PlayerUpdate::ReadPredictedState(EntityState &state) const noexcept {
Read(state, 0);
}
+void Packet::PlayerUpdate::WriteMovement(const glm::vec3 &mov) noexcept {
+ glm::ivec3 conv = clamp(glm::ivec3(mov * 32767.0f), -32767, 32767);
+ Write(int16_t(conv.x), 64);
+ Write(int16_t(conv.y), 66);
+ Write(int16_t(conv.z), 68);
+}
+
+void Packet::PlayerUpdate::ReadMovement(glm::vec3 &mov) const noexcept {
+ int16_t x, y, z;
+ Read(x, 64);
+ Read(y, 66);
+ Read(z, 68);
+ mov = glm::vec3(x, y, z) * .00003051850947599719f;
+}
+
+void Packet::PlayerUpdate::WritePitch(float pitch) noexcept {
+ int16_t conv = pitch * 20860.12008116853786870640f;
+ Write(conv, 70);
+}
+
+void Packet::PlayerUpdate::ReadPitch(float &pitch) const noexcept {
+ int16_t conv = 0;
+ Read(conv, 70);
+ pitch = conv * .00004793836258415163f;
+}
+
+void Packet::PlayerUpdate::WriteYaw(float yaw) noexcept {
+ int16_t conv = yaw * 10430.06004058426893435320f;
+ Write(conv, 72);
+}
+
+void Packet::PlayerUpdate::ReadYaw(float &yaw) const noexcept {
+ int16_t conv = 0;
+ Read(conv, 72);
+ yaw = conv * .00009587672516830326f;
+}
+
+void Packet::PlayerUpdate::WriteActions(uint8_t actions) noexcept {
+ Write(actions, 74);
+}
+
+void Packet::PlayerUpdate::ReadActions(uint8_t &actions) const noexcept {
+ Read(actions, 74);
+}
+
+void Packet::PlayerUpdate::WriteSlot(uint8_t slot) noexcept {
+ Write(slot, 75);
+}
+
+void Packet::PlayerUpdate::ReadSlot(uint8_t &slot) const noexcept {
+ Read(slot, 75);
+}
+
void Packet::SpawnEntity::WriteEntity(const Entity &e) noexcept {
Write(e.ID(), 0);
if (e.GetModel()) {
}
void Packet::EntityUpdate::WriteEntity(const Entity &entity, uint32_t num) noexcept {
- uint32_t off = 4 + (num * 64);
+ uint32_t off = GetSize(num);
Write(entity.ID(), off);
Write(entity.GetState(), off + 4);
}
void Packet::EntityUpdate::ReadEntityID(uint32_t &id, uint32_t num) const noexcept {
- Read(id, 4 + (num * 64));
+ uint32_t off = GetSize(num);
+ Read(id, off);
}
void Packet::EntityUpdate::ReadEntityState(EntityState &state, uint32_t num) const noexcept {
- uint32_t off = 4 + (num * 64);
+ uint32_t off = GetSize(num);
Read(state, off + 4);
}
memcpy(d, &data[12], len);
}
+void Packet::BlockUpdate::WriteChunkCoords(const glm::ivec3 &coords) noexcept {
+ Write(coords, 0);
+}
+
+void Packet::BlockUpdate::ReadChunkCoords(glm::ivec3 &coords) const noexcept {
+ Read(coords, 0);
+}
+
+void Packet::BlockUpdate::WriteBlockCount(uint32_t count) noexcept {
+ Write(count, 12);
+}
+
+void Packet::BlockUpdate::ReadBlockCount(uint32_t &count) const noexcept {
+ Read(count, 12);
+}
+
+void Packet::BlockUpdate::WriteIndex(uint16_t index, uint32_t num) noexcept {
+ uint32_t off = GetSize(num);
+ Write(index, off);
+}
+
+void Packet::BlockUpdate::ReadIndex(uint16_t &index, uint32_t num) const noexcept {
+ uint32_t off = GetSize(num);
+ Read(index, off);
+}
+
+void Packet::BlockUpdate::WriteBlock(const Block &block, uint32_t num) noexcept {
+ uint32_t off = GetSize(num) + 2;
+ Write(block, off);
+}
+
+void Packet::BlockUpdate::ReadBlock(Block &block, uint32_t num) const noexcept {
+ uint32_t off = GetSize(num) + 2;
+ Read(block, off);
+}
+
void ConnectionHandler::Handle(const UDPpacket &udp_pack) {
const Packet &pack = *reinterpret_cast<const Packet *>(udp_pack.data);
case Packet::ChunkData::TYPE:
On(Packet::As<Packet::ChunkData>(udp_pack));
break;
+ case Packet::BlockUpdate::TYPE:
+ On(Packet::As<Packet::BlockUpdate>(udp_pack));
+ break;
default:
// drop unknown or unhandled packets
break;