123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154 |
- #include "network/Client.h"
- #include "network/ENet.h"
- static_assert(sizeof(enet_uint16) == sizeof(Client::Port),
- "client port has wrong type");
- static ENetHost* client = nullptr;
- static ENetPeer* connection = nullptr;
- static int connectTicks = 0;
- static int connectTimeoutTicks = 0;
- static int disconnectTicks = 0;
- static int disconnectTimeoutTicks = 0;
- static Client::OnConnect onConnect = []() {};
- static Client::OnDisconnect onDisconnect = []() {};
- static Client::OnPacket onPacket = [](InPacket&) {};
- Error Client::start() {
- if(client != nullptr) {
- return {"already started"};
- } else if(ENet::add()) {
- return {"cannot initialize enet"};
- }
- client = enet_host_create(nullptr, 1, 2, 0, 0);
- if(client == nullptr) {
- ENet::remove();
- return {"cannot create enet client host"};
- }
- return {};
- }
- void Client::stop() {
- if(connection != nullptr) {
- onDisconnect();
- enet_peer_disconnect_now(connection, 0);
- connection = nullptr;
- }
- if(client != nullptr) {
- enet_host_destroy(client);
- ENet::remove();
- client = nullptr;
- }
- connectTicks = 0;
- disconnectTicks = 0;
- }
- Error Client::connect(const char* server, Port port, int timeoutTicks) {
- if(client == nullptr) {
- return {"client not started"};
- } else if(connection != nullptr) {
- return {"connection already exists"};
- }
- ENetAddress address;
- memset(&address, 0, sizeof(ENetAddress));
- enet_address_set_host(&address, server);
- address.port = port;
- connection = enet_host_connect(client, &address, 3, 0);
- if(connection == nullptr) {
- return {"cannot create connection"};
- }
- connectTicks = 1;
- connectTimeoutTicks = timeoutTicks;
- return {};
- }
- void Client::disconnect(int timeoutTicks) {
- if(connection == nullptr) {
- return;
- }
- connectTicks = 0;
- enet_peer_disconnect(connection, 0);
- disconnectTicks = 1;
- disconnectTimeoutTicks = timeoutTicks;
- }
- void Client::send(OutPacket& p, PacketSendMode mode) {
- if(client != nullptr && connection != nullptr && connectTicks < 0) {
- constexpr enet_uint32 flags[] = {ENET_PACKET_FLAG_RELIABLE, 0,
- ENET_PACKET_FLAG_UNSEQUENCED};
- enet_uint8 index = static_cast<enet_uint8>(mode);
- enet_peer_send(connection, index,
- enet_packet_create(
- p.buffer, static_cast<size_t>(p.buffer.getLength()),
- flags[index]));
- }
- }
- void Client::tick() {
- if(client == nullptr) {
- return;
- }
- ENetEvent e;
- while(enet_host_service(client, &e, 0) > 0) {
- switch(e.type) {
- case ENET_EVENT_TYPE_CONNECT:
- connectTicks = -1;
- onConnect();
- break;
- case ENET_EVENT_TYPE_DISCONNECT_TIMEOUT:
- case ENET_EVENT_TYPE_DISCONNECT:
- disconnectTicks = 0;
- onDisconnect();
- connection = nullptr;
- break;
- case ENET_EVENT_TYPE_NONE: return;
- case ENET_EVENT_TYPE_RECEIVE:
- InPacket in(e.packet->data,
- static_cast<int>(e.packet->dataLength));
- onPacket(in);
- enet_packet_destroy(e.packet);
- break;
- }
- }
- if(connectTicks >= 1 && ++connectTicks > connectTimeoutTicks) {
- connectTicks = 0;
- disconnect(connectTimeoutTicks);
- }
- if(disconnectTicks >= 1 && ++disconnectTicks > disconnectTimeoutTicks) {
- disconnectTicks = 0;
- onDisconnect();
- if(connection != nullptr) {
- enet_peer_reset(connection);
- connection = nullptr;
- }
- }
- }
- void Client::setConnectHandler(OnConnect oc) {
- onConnect = oc;
- }
- void Client::setDisconnectHandler(OnDisconnect od) {
- onDisconnect = od;
- }
- void Client::setPacketHandler(OnPacket op) {
- onPacket = op;
- }
- void Client::resetHandler() {
- onConnect = []() {};
- onDisconnect = []() {};
- onPacket = [](InPacket&) {};
- }
- bool Client::isConnecting() {
- return connectTicks >= 1;
- }
- bool Client::isConnected() {
- return connectTicks < 0;
- }
|