#include "connection.h" Connection::Connection(SOCKET sock, sockaddr_in sockaddr, LoginInfo log, PlayerInfo play): m_sock(sock), m_addr(sockaddr), m_loginfo(log), m_playinfo(play) { } Connection::~Connection() { closesocket(m_sock); } uint64_t Connection::GetHash(bool self) const { return self? m_loginfo.sid: m_playinfo.id; } uint64_t Connection::GetTeamHash() const { return m_loginfo.tid; } std::string Connection::GetName() const { return m_loginfo.name; } void Connection::AddInput(Input in) { m_input_manifest.insert({ in.timestamp, in }); } Output* Connection::getOutput(Timestamp time) { auto out = m_output_manifest.find(time); if (out != m_output_manifest.end()) return &out->second; return nullptr; } Sync Connection::getSync(Timestamp time) { Sync sync; auto out = m_output_manifest.find(time); if (out != m_output_manifest.end()) { sync.timestamp = out->second.timestamp; sync.position = out->second.position; sync.sid = m_loginfo.sid; } return sync; } SOCKET Connection::getSock() const { return m_sock; } PlayerInfo* Connection::getInfo() const { return (PlayerInfo*)&m_playinfo; } sockaddr_in* Connection::getAddr() const { return (sockaddr_in*)&m_addr; } void Connection::getPacks(SOCKET sock) { std::vector lsPck; Input in; while (true) { lsPck = recvPacksFrom(sock, &m_buf, m_addr); for (auto& pck : lsPck) { uint32_t bsize = m_buf.len - (pck - m_buf.ptr); switch (netprot::getType(pck, 1)) { using enum netprot::PACKET_TYPE; case INPUT: if (Deserialize(&in, pck, &bsize)) m_input_manifest[in.timestamp] = in; break; default: break; } } lsPck.clear(); } } void Connection::sendPacks(SOCKET sock, std::unordered_map conns) { while (m_last_out < m_output_manifest.size()) { Output out = m_output_manifest.at(m_last_out++); for (auto& [key, conn] : conns) { if (m_playinfo.id == conn->GetHash(true)) continue; sendPackTo(sock, &out, &m_bufout, conn->getAddr()); } } } void Connection::Run(World* world) { Input in, last; Output out; float el; if (m_input_manifest.size() < 2) return; while (m_last_in < m_input_manifest.size()) { in = m_input_manifest.at(m_last_in + 1); last = m_input_manifest.at(m_last_in); el = (float)(in.timestamp - last.timestamp) / 1000.; player.get()->SetDirection(in.direction); player.get()->ApplyPhysics(player.get()->GetInput(in.keys.forward, in.keys.backward, in.keys.left, in.keys.right, in.keys.jump, false, el), world, el); out.position = player.get()->GetPositionAbs(); out.direction = in.direction; out.timestamp = in.timestamp; out.id = m_playinfo.id; m_output_manifest[out.timestamp] = out; ++m_last_in; } } void Connection::CleanInputManifest(Timestamp time) { auto wat = m_input_manifest.find(time); while (wat != m_input_manifest.begin()) m_input_manifest.erase(wat--); }