int main (int argc, char ** argv){ printf("-- enetTests started --\n"); if (enet_initialize () != 0){ fprintf (stderr, "An error occurred while initializing ENet.\n"); return EXIT_FAILURE; } ENetAddress address; ENetHost * server; /* Bind the server to the default localhost. */ /* A specific host address can be specified by */ /* enet_address_set_host (& address, "x.x.x.x"); */ address.host = ENET_HOST_ANY; /* Bind the server to port 1234. */ address.port = 1234; server = enet_host_create (& address /* the address to bind the server host to */, 32 /* allow up to 32 clients and/or outgoing connections */, 2 /* allow up to 2 channels to be used, 0 and 1 */, 0 /* assume any amount of incoming bandwidth */, 0 /* assume any amount of outgoing bandwidth */); if (server == NULL){ fprintf (stderr, "An error occurred while trying to create an ENet server host.\n"); exit (EXIT_FAILURE); } ENetHost * client; client = enet_host_create (NULL /* create a client host */, 1 /* only allow 1 outgoing connection */, 2 /* allow up 2 channels to be used, 0 and 1 */, 57600 / 8 /* 56K modem with 56 Kbps downstream bandwidth */, 14400 / 8 /* 56K modem with 14 Kbps upstream bandwidth */); if (client == NULL) { fprintf (stderr, "An error occurred while trying to create an ENet client host.\n"); exit (EXIT_FAILURE); } ENetAddress dstaddress; ENetEvent event; ENetPeer *peer; /* Connect to some.server.net:1234. */ enet_address_set_host (& dstaddress, "localhost"); dstaddress.port = 1234; /* Initiate the connection, allocating the two channels 0 and 1. */ peer = enet_host_connect (client, & dstaddress, 2, 0); if (peer == NULL){ fprintf (stderr, "No available peers for initiating an ENet connection.\n"); exit (EXIT_FAILURE); } waitEvents(client, 100, "client send connect"); waitEvents(server, 100, "server wait connect"); /* Wait up to 5 seconds for the connection attempt to succeed. */ if (enet_host_service (client, & event, 5000) > 0 && event.type == ENET_EVENT_TYPE_CONNECT){ printf("Connection to localhost:1234 succeeded\n"); }else{ /* Either the 5 seconds are up or a disconnect event was */ /* received. Reset the peer in the event the 5 seconds */ /* had run out without any significant event. */ enet_peer_reset (peer); fprintf (stderr, "Connection to localhost:1234 failed\n"); exit(EXIT_FAILURE); } /* Create a reliable packet of size 7 containing "packet\0" */ ENetPacket * packet = enet_packet_create ("packet", strlen ("packet") + 1, ENET_PACKET_FLAG_RELIABLE); /* Extend the packet so and append the string "foo", so it now */ /* contains "packetfoo\0" */ enet_packet_resize (packet, strlen ("packetfoo") + 1); strcpy ((char*)& packet -> data [strlen ("packet")], "foo"); /* Send the packet to the peer over channel id 0. */ /* One could also broadcast the packet by */ /* enet_host_broadcast (host, 0, packet); */ enet_peer_send (peer, 0, packet); /* One could just use enet_host_service() instead. */ waitEvents(client, 100, "client send msg"); waitEvents(server, 100, "server wait connect"); waitEvents(server, 100, "server wait msg"); enet_peer_disconnect (peer, 0); waitEvents(client, 100, "client send disconnect"); waitEvents(server, 100, "server wait disconnect"); if(waitEvents(client, 100, "client wait disconnect")!=ENET_EVENT_TYPE_DISCONNECT){ /* We've arrived here, so the disconnect attempt didn't */ /* succeed yet. Force the connection down. */ enet_peer_reset (peer); fprintf(stderr, "received event is not disconnect, will reset the peer\n"); exit(EXIT_FAILURE); } enet_host_destroy(client); enet_host_destroy(server); enet_deinitialize(); printf("-- enetTests Finished --\n"); return EXIT_SUCCESS; }
void UdpSocket::Disconnect(ENetPeer *peer) { // Disconnect socket enet_peer_disconnect( peer, 0 ); }
void STKPeer::disconnect() { enet_peer_disconnect(m_peer, 0); }
int main(int argc, char* argv[]) { ENetHost *client; ENetAddress address; ENetPeer *peer; ENetEvent event; char message[1024]; int serviceResult; puts("Starting client"); if (enet_initialize() != 0) { fprintf(stderr, "Error initialising enet"); exit(EXIT_FAILURE); } client = enet_host_create(NULL, /* create a client host */ 1, /* number of clients */ 2, /* number of channels */ 57600 / 8, /* incoming bandwith */ 14400 / 8); /* outgoing bandwith */ if (client == NULL) { fprintf(stderr, "Could not create client host"); exit(EXIT_FAILURE); } enet_address_set_host(&address, "localhost"); address.port = 1234; peer = enet_host_connect(client, &address, /* address to connect to */ 2, /* number of channels */ 0); /* user data supplied to the receiving host */ if (peer == NULL) { fprintf(stderr, "No available peers for initiating an ENet " "connection.\n"); exit(EXIT_FAILURE); } /* Try to connect to server within 5 seconds */ if (enet_host_service(client, &event, 5000) > 0 && event.type == ENET_EVENT_TYPE_CONNECT) { puts("Connection to server succeeded."); } else { /* Either the 5 seconds are up or a disconnect event was */ /* received. Reset the peer in the event the 5 seconds */ /* had run out without any significant event. */ enet_peer_reset(peer); fprintf(stderr, "Connection to server failed."); exit(EXIT_FAILURE); } while (true) { serviceResult = 1; /* Keep doing host_service until no events are left */ while (serviceResult > 0) { serviceResult = enet_host_service(client, &event, 0); if (serviceResult > 0) { switch (event.type) { case ENET_EVENT_TYPE_CONNECT: printf("A new client connected from %x:%u.\n", event.peer->address.host, event.peer->address.port); event.peer->data = (void*)"New User"; break; case ENET_EVENT_TYPE_RECEIVE: printf("A packet of length %u containing '%s' was " "received from %s on channel %u.\n", event.packet->dataLength, event.packet->data, event.peer->data, event.channelID); /* Clean up the packet now that we're done using it. > */ enet_packet_destroy(event.packet); break; case ENET_EVENT_TYPE_DISCONNECT: printf("%s disconnected.\n", event.peer->data); break; } } else if (serviceResult > 0) { puts("Error with servicing the client"); exit(EXIT_FAILURE); } } printf("Say> "); #ifdef _WIN32 gets_s(message, 1024); #else gets(message); #endif if (strcmp(message, "exit") == 0 || strcmp(message, "quit") == 0) { break; } if (strlen(message) > 0) { ENetPacket *packet = enet_packet_create(message, strlen (message) + 1, ENET_PACKET_FLAG_RELIABLE); enet_peer_send(peer, 0, packet); } } enet_peer_disconnect(peer, 0); /* Allow up to 3 seconds for the disconnect to succeed */ /* and drop any packets received packets */ while (enet_host_service(client, &event, 3000) > 0) { switch (event.type) { case ENET_EVENT_TYPE_RECEIVE: enet_packet_destroy(event.packet); break; case ENET_EVENT_TYPE_DISCONNECT: puts("Disconnection succeeded."); break; } } enet_host_destroy(client); enet_deinitialize(); return 0; }
void NetServer::ResetNetwork() { if (m_pServer) { ENetPeer * pCurrentPeer; for (pCurrentPeer = m_pServer-> peers; pCurrentPeer < & m_pServer->peers [m_pServer->peerCount]; ++ pCurrentPeer) { if (pCurrentPeer->state != ENET_PEER_STATE_CONNECTED) continue; enet_peer_disconnect (pCurrentPeer, 0); } ENetEvent event; bool bDisconnect = false; /* Allow up to 3 seconds for the disconnect to succeed and drop any received packets. */ while (enet_host_service (m_pServer, & event, 3000) > 0) { switch (event.type) { case ENET_EVENT_TYPE_RECEIVE: enet_packet_destroy (event.packet); break; case ENET_EVENT_TYPE_DISCONNECT: GfLogTrace ("Disconnection succeeded."); bDisconnect=true; break; case ENET_EVENT_TYPE_NONE: case ENET_EVENT_TYPE_CONNECT: // Do nothing. break; } } /* We've arrived here, so the disconnect attempt didn't */ /* succeed yet. Force the connection down. */ if (!bDisconnect) { ENetPeer * pCurrentPeer1; for (pCurrentPeer1 = m_pServer-> peers; pCurrentPeer1 < & m_pServer->peers [m_pServer->peerCount]; ++ pCurrentPeer1) { if (pCurrentPeer1->state != ENET_PEER_STATE_CONNECTED) continue; enet_peer_reset (pCurrentPeer1); } } enet_host_destroy(m_pServer); m_pServer = NULL; } }
bool NetServer::ServerStep() { // use lastTic to keep track of how many tics per second we have; control "tics per second" // perform any periodic, timed events here ENetEvent event; int status = enet_host_service(server, &event, HOST_TIMEOUT); if (status < 0) return false; // ERROR happened! Server shut down! TimedEvent(); if (status == 0) return true; // nothing to do, try again later switch(event.type) { case ENET_EVENT_TYPE_CONNECT: { printf ("A new client (%d) connected from %x:%u.\n", event.peer, event.peer -> address.host, event.peer -> address.port); client *c = new client; char hostname[256] = "error"; enet_address_get_host_ip(&event.peer->address, hostname, 256); printf("%s connected\n", hostname); if (event.peer != master) { c->hostname = string(hostname); c->peer = event.peer; c->state = ST_AUTH; // associate peer with the client object for them event.peer->data = c; // Call HandleConnect method of the game logic // if it returns false, then that means connection denied, otherwise specifies state client is in // also add to list of clients if (HandleConnect(event.peer)) { bool client_added = false; for (size_t i = 0; i < clients.size(); i++) { if (clients.at(i)->state == ST_EMPTY) { clients.at(i) = c; client_added = true; break; } } if (!client_added) clients.push_back(c); } else { enet_peer_disconnect(event.peer, 121); } } else { MasterCheckin(); } break; } case ENET_EVENT_TYPE_DISCONNECT: { if (event.peer != master) { printf ("%d disconnected.\n", event.peer); // Call HandleDisconnect method some form of id for the connection HandleDisconnect(323, event.peer); // free up this client slot for reuse ((client*) event.peer->data)->state = ST_EMPTY; } else { printf ("Master timed out.\n"); master = 0; } break; } case ENET_EVENT_TYPE_RECEIVE: { char hostname[256] = "error"; enet_address_get_host_ip(&event.peer->address, hostname, 256); printf("receiving packet.\n"); printf ("A packet of length %u ", event.packet -> dataLength); printf("containing %s ", event.packet -> data); printf("was received from %s ", hostname); printf("on channel %u.\n", event.channelID); /*printf ("A packet of length %u containing %s was received from %s on channel %u.\n", event.packet -> dataLength, event.packet -> data, ((client*)event.peer -> data)->hostname.c_str(), event.channelID);*/ client *c = (client*) event.peer->data; // Call Packet Handler to deal with packets, and send a response HandlePacket(event.packet->data, event.packet->dataLength, event.peer); if (event.packet->referenceCount == 0) enet_packet_destroy(event.packet); break; } default: break; } enet_host_flush(server); return true; }
extern "C" int main(int argc, char **argv) { #if _WIN32 // hack to redirect output to text files freopen("stdout.txt", "w", stdout); freopen("stderr.txt", "w", stderr); #endif clientConsole = new narf::ClientConsole(); narf::console = clientConsole; narf::console->println("Version: " + std::to_string(VERSION_MAJOR) + "." + std::to_string(VERSION_MINOR) + std::string(VERSION_RELEASE) + "+" VERSION_REV); if (enet_initialize() != 0) { narf::console->println("Error initializing ENet"); return 1; } narf::cmd::cmds["set"] = cmdSet; narf::cmd::cmds["quit"] = cmdQuit; narf::cmd::cmds["connect"] = cmdConnect; narf::cmd::cmds["disconnect"] = cmdDisconnect; narf::cmd::cmds["save"] = cmdSave; narf::cmd::cmds["saveconfig"] = cmdSaveConfig; narf::cmd::cmds["load"] = cmdLoad; narf::cmd::cmds["stats"] = cmdStats; narf::cmd::cmds["about"] = cmdAbout; narf::cmd::cmds["music"] = cmdMusic; narf::MemoryFile iniMem; auto configFile = narf::util::appendPath(narf::util::userConfigDir("narfblock"), "client.ini"); narf::console->println("Attempting to open user config file: " + configFile); if (!iniMem.read(configFile)) { configFile = narf::util::appendPath(narf::util::dataDir(), "client.ini"); narf::console->println("Could not load user config file; falling back to local config file: " + configFile); if (!iniMem.read(configFile)) { narf::console->println("Could not load local config file; falling back to compile-time defaults"); } } if (iniMem.size) { config.load(iniMem.data, iniMem.size); } config.updateSignal += configEvent; client = enet_host_create(nullptr, 1, narf::net::MAX_CHANNELS, 0, 0); if (!client) { fatalError("Could not create ENet client"); return 1; } if (SDL_Init(SDL_INIT_TIMER | SDL_INIT_VIDEO | SDL_INIT_AUDIO) < 0) { fatalError("SDL_Init() failed: " + std::string(SDL_GetError())); SDL_Quit(); return 1; } musicMutex = SDL_CreateMutex(); config.initBool("audio.enabled", true); SDL_DisplayMode mode; // TODO: iterate over monitors? if (SDL_GetDesktopDisplayMode(0, &mode)) { fatalError("SDL_GetDesktopDisplayMode failed: " + std::string(SDL_GetError())); SDL_Quit(); return 1; } auto w = mode.w; auto h = mode.h; narf::console->println("Current video mode is " + std::to_string(w) + "x" + std::to_string(h)); // TODO: convert these to be modifiable at runtime and use config.init* bool fullscreen = config.getBool("video.fullscreen", true); float width_cfg = config.getFloat("video.width", 0.6f); float height_cfg = config.getFloat("video.height", 0.6f); if (!fullscreen) { if (width_cfg > 1) { w = (int32_t)width_cfg; } else { w = (int32_t)((float)w * width_cfg); } if (height_cfg > 1) { h = (int32_t)height_cfg; } else { h = (int32_t)((float)h * height_cfg); } narf::console->println("Setting video to windowed " + std::to_string(w) + "x" + std::to_string(h)); } else { narf::console->println("Setting video to fullscreen"); } if (!initVideo(w, h, fullscreen)) { fatalError("Error: could not set OpenGL video mode " + std::to_string(w) + "x" + std::to_string(h)); SDL_Quit(); return 1; } clientConsole->setGLContext(display); config.initBool("video.vsync", false); newWorld(); playerEID = world->entityManager.newEntity(); { narf::EntityRef player(world->entityManager, playerEID); // initial player position player->position = narf::Vector3f(15.0f, 10.0f, 3.0f * 16.0f); player->prevPosition = player->position; } // initialize camera to look at origin cam.orientation.yaw = atan2f(cam.position.y, cam.position.x); cam.orientation.pitch = 0.0f; bouncyBlockEID = world->entityManager.newEntity(); { narf::EntityRef bouncyBlock(world->entityManager, bouncyBlockEID); bouncyBlock->position = narf::Vector3f(10.0f, 10.0f, 21.0f); bouncyBlock->prevPosition = bouncyBlock->position; bouncyBlock->bouncy = true; bouncyBlock->model = true; } if (!init_textures()) { fatalError("init_textures() failed"); return 1; } renderer = new narf::Renderer(world, *display, tilesTex); config.initInt32("video.renderDistance", 5); fpsTextBuffer = new narf::font::TextBuffer(*display, nullptr); blockInfoBuffer = new narf::font::TextBuffer(*display, nullptr); entityInfoBuffer = new narf::font::TextBuffer(*display, nullptr); locationBuffer = new narf::font::TextBuffer(*display, nullptr); config.initString("video.hudFont", "DroidSansMono"); config.initInt32("video.hudFontSize", 30); if (!fpsTextBuffer->getFont()) { fatalError("Error: could not load HUD font"); return 1; } config.initString("video.consoleFont", "DroidSansMono"); config.initInt32("video.consoleFontSize", 18); if (!clientConsole->getFont()) { fatalError("Error: could not load Console font"); return 1; } config.initString("video.consoleCursorShape", "default"); config.initBool("video.stereo.enabled", false); config.initBool("video.stereo.cross", true); config.initFloat("video.stereo.separation", 0.1f); SDL_SetRelativeMouseMode(SDL_TRUE); config.initDouble("misc.tickRate", 60); config.initDouble("misc.maxFrameTime", 0.25); narf::console->println("Unicode test\xE2\x80\xBC pi: \xCF\x80 (2-byte sequence), square root: \xE2\x88\x9A (3-byte sequence), U+2070E: \xF0\xA0\x9C\x8E (4-byte sequence)"); gameLoop = new ClientGameLoop(config.getDouble("misc.maxFrameTime"), config.getDouble("misc.tickRate")); gameLoop->run(); if (connectState == ConnectState::Connected) { enet_peer_disconnect(server, (uint32_t)narf::net::DisconnectType::UserQuit); } else if (connectState == ConnectState::Connecting) { enet_peer_reset(server); } enet_host_flush(client); enet_host_destroy(client); enet_deinitialize(); SDL_Quit(); return 0; }
/** * Disconnects the client from the server, deinitializes ENet and releases the engine core. * Allow up to 3 seconds for the disconnect to succeed and drop any packets received packets. */ void Client::disconnect() { if(!m_pClientHost) { return; } // Send disconnecting request m_disconnectingEvent.connectionID = m_pPeer->connectID; network::send(m_disconnectingEvent, m_pPeer); enet_host_flush(m_pClientHost); //// Waiting for ACK //bool acked = false; //int startTime = glutGet(GLUT_ELAPSED_TIME); // //while (glutGet(GLUT_ELAPSED_TIME) - startTime < 3000 && enet_host_service(m_clientHost, &m_event, 3000) > 0) { // switch (m_event.type) { // case ENET_EVENT_TYPE_RECEIVE: // // if (unmarshal(m_netObject, std::string((char*) m_event.packet->data, m_event.packet->dataLength))) { // if (m_netObject.type == events::PlayerDisconnectingEvent::NETOBJ_PLAYER_DC) { // if (unmarshal(m_disconnectingEvent, std::string((char*) m_event.packet->data, m_event.packet->dataLength))) { // if (m_disconnectingEvent.connectionID == m_peer->connectID) { // TRACE_NETWORK("Disconnection ACK-ed.", 0); // acked = true; // } // } // } // } // // enet_packet_destroy(m_event.packet); // // break; // } //} enet_peer_disconnect(m_pPeer, 0); // Allow up to 3 seconds for the disconnect to succeed and drop any packets received packets while (enet_host_service(m_pClientHost, &m_event, 3000) > 0) { switch (m_event.type) { case ENET_EVENT_TYPE_RECEIVE: if (unmarshal(m_disconnectingEvent, std::string((char*) m_event.packet->data, m_event.packet->dataLength))) if (m_disconnectingEvent.connectionID == m_pPeer->connectID) { TRACE_NETWORK("Disconnection ACK-ed.", 0); } enet_packet_destroy(m_event.packet); break; case ENET_EVENT_TYPE_DISCONNECT: TRACE_NETWORK("Disconnection succeeded.", 0); break; } } enet_host_destroy(m_pClientHost); enet_deinitialize(); }
void CNetServerSession::Disconnect(u32 reason) { Update((uint)NMT_CONNECTION_LOST, NULL); enet_peer_disconnect(m_Peer, reason); }
void disconnect_client(int n, const char *reason) { printf("client::disconnecting client (%s) [%s]\n", clients[n].hostname, reason); enet_peer_disconnect(clients[n].peer); clients[n].type = ST_EMPTY; send2(true, -1, SV_CDIS, n); }
// called from ---NETPLAY--- thread void NetPlayServer::ThreadFunc() { while (m_do_loop) { // update pings every so many seconds if ((m_ping_timer.GetTimeElapsed() > 1000) || m_update_pings) { m_ping_key = Common::Timer::GetTimeMs(); sf::Packet spac; spac << (MessageId)NP_MSG_PING; spac << m_ping_key; m_ping_timer.Start(); SendToClients(spac); m_update_pings = false; } ENetEvent netEvent; int net; if (m_traversal_client) m_traversal_client->HandleResends(); net = enet_host_service(m_server, &netEvent, 1000); while (!m_async_queue.Empty()) { { std::lock_guard<std::recursive_mutex> lkp(m_crit.players); SendToClients(m_async_queue.Front()); } m_async_queue.Pop(); } if (net > 0) { switch (netEvent.type) { case ENET_EVENT_TYPE_CONNECT: { ENetPeer* accept_peer = netEvent.peer; unsigned int error; { std::lock_guard<std::recursive_mutex> lkg(m_crit.game); error = OnConnect(accept_peer); } if (error) { sf::Packet spac; spac << (MessageId)error; // don't need to lock, this client isn't in the client map Send(accept_peer, spac); if (netEvent.peer->data) { delete (PlayerId*)netEvent.peer->data; netEvent.peer->data = nullptr; } enet_peer_disconnect_later(accept_peer, 0); } } break; case ENET_EVENT_TYPE_RECEIVE: { sf::Packet rpac; rpac.append(netEvent.packet->data, netEvent.packet->dataLength); auto it = m_players.find(*(PlayerId*)netEvent.peer->data); Client& client = it->second; if (OnData(rpac, client) != 0) { // if a bad packet is received, disconnect the client std::lock_guard<std::recursive_mutex> lkg(m_crit.game); OnDisconnect(client); if (netEvent.peer->data) { delete (PlayerId*)netEvent.peer->data; netEvent.peer->data = nullptr; } } enet_packet_destroy(netEvent.packet); } break; case ENET_EVENT_TYPE_DISCONNECT: { std::lock_guard<std::recursive_mutex> lkg(m_crit.game); if (!netEvent.peer->data) break; auto it = m_players.find(*(PlayerId*)netEvent.peer->data); if (it != m_players.end()) { Client& client = it->second; OnDisconnect(client); if (netEvent.peer->data) { delete (PlayerId*)netEvent.peer->data; netEvent.peer->data = nullptr; } } } break; default: break; } } } // close listening socket and client sockets for (auto& player_entry : m_players) { delete (PlayerId*)player_entry.second.socket->data; player_entry.second.socket->data = nullptr; enet_peer_disconnect(player_entry.second.socket, 0); } }
void Client::disconnect() { Debug::log(Debug::Area::NetworkClientInitialArea) << "attempting disconnect from server"; enet_peer_disconnect(m_peer, 0); }
void Room::RoomImpl::HandleModBanPacket(const ENetEvent* event) { if (!HasModPermission(event->peer)) { SendModPermissionDenied(event->peer); return; } Packet packet; packet.Append(event->packet->data, event->packet->dataLength); packet.IgnoreBytes(sizeof(u8)); // Ignore the message type std::string nickname; packet >> nickname; std::string username; std::string ip; { std::lock_guard lock(member_mutex); const auto target_member = std::find_if(members.begin(), members.end(), [&nickname](const auto& member) { return member.nickname == nickname; }); if (target_member == members.end()) { SendModNoSuchUser(event->peer); return; } // Notify the banned member SendUserBanned(target_member->peer); nickname = target_member->nickname; username = target_member->user_data.username; char ip_raw[256]; enet_address_get_host_ip(&target_member->peer->address, ip_raw, sizeof(ip_raw) - 1); ip = ip_raw; enet_peer_disconnect(target_member->peer, 0); members.erase(target_member); } { std::lock_guard lock(ban_list_mutex); if (!username.empty()) { // Ban the forum username if (std::find(username_ban_list.begin(), username_ban_list.end(), username) == username_ban_list.end()) { username_ban_list.emplace_back(username); } } // Ban the member's IP as well if (std::find(ip_ban_list.begin(), ip_ban_list.end(), ip) == ip_ban_list.end()) { ip_ban_list.emplace_back(ip); } } // Announce the change to all clients. SendStatusMessage(IdMemberBanned, nickname, username); BroadcastRoomInformation(); }
int enet_lua_api enet_lua_peer_disconnect(lua_State* L) { ENetPeer** udata = luaL_checkudata(L, 1, "_enet.peer"); enet_peer_disconnect(*udata, 0); return 0; }
void Host::disconnect() { if (mServer) enet_peer_disconnect(mServer, 0); }
bool ENetServer::stop() { if (!isRunning()) { // no clients to disconnect from return 0; } // attempt to gracefully disconnect all clients LOG_DEBUG("Disconnecting " << numClients() << " clients..."); for (auto iter : clients_) { auto client = iter.second; LOG_DEBUG("Disconnecting from client_" << client->incomingPeerID); enet_peer_disconnect(client, 0); } // wait for the disconnections to be acknowledged auto timestamp = Time::timestamp(); bool success = false; ENetEvent event; while (true) { int32_t res = enet_host_service(host_, &event, 0); if (res > 0) { // event occured if (event.type == ENET_EVENT_TYPE_RECEIVE) { // throw away any received packets during disconnect LOG_DEBUG("Discarding received packet"); enet_packet_destroy(event.packet); } else if (event.type == ENET_EVENT_TYPE_DISCONNECT) { // disconnect successful LOG_DEBUG("Disconnection of client_" << event.peer->incomingPeerID << " succeeded, " << (clients_.size() - 1) << " remaining"); // remove from remaining clients_.erase(event.peer->incomingPeerID); } else if (event.type == ENET_EVENT_TYPE_CONNECT) { // client connected LOG_DEBUG("Connection accepted from client_" << event.peer->incomingPeerID << " during server shutdown, disconnect"); // add and remove client enet_peer_disconnect(event.peer, 0); // add to remaining clients_[event.peer->incomingPeerID] = event.peer; } } else if (res < 0) { // error occured LOG_ERROR("Encountered error while polling"); break; } else { // no event, check if finished if (clients_.empty()) { // all clients successfully disconnected LOG_DEBUG("Disconnection from all clients successful"); success = true; break; } } // check timeout if (Time::timestamp() - timestamp > Time::fromMilliseconds(TIMEOUT_MS)) { LOG_ERROR("Disconnection was not acknowledged by server, shutdown forced"); break; } } // force disconnect the remaining clients for (auto iter : clients_) { auto id = iter.first; auto client = iter.second; LOG_DEBUG("Forcibly disconnecting client_" << id); enet_peer_reset(client); } // clear clients clients_ = std::map<uint32_t, ENetPeer*>(); // destroy the host enet_host_destroy(host_); host_ = nullptr; return !success; }
// Disconnect all peers void _ServerNetwork::DisconnectAll() { // Disconnect all connected peers for(auto &Peer : Peers) enet_peer_disconnect(Peer->ENetPeer, 0); }
/** * Destroy any connections to peers and reset the peer metadata. */ void host_disconnect (void) { enet_peer_disconnect(peer, 0); host_listen(0); connected = 0; }
void Peer::disconnect(uint32 reason) { m_disconnecting = true; m_reason = reason; enet_peer_disconnect((ENetPeer*) m_peer, reason); }