static void* do_service(void *data) { CallbackData* temp_data = data; temp_data->result = enet_host_service(temp_data->connection->host, temp_data->connection->event, temp_data->timeout); return NULL; }
void Server::Run() { ENetEvent event; string clave = "hola"; string foo = ""; cout << "Servido a la escucha..." << endl; while (true) { foo = ""; enet_host_service (server, & event, 10000); switch (event.type) { //Si se ha producido un evento de conexion case ENET_EVENT_TYPE_CONNECT: cout << "Nuevo cliente conectado. " << event.peer->address.host << ":" << event.peer->address.port << endl; break; //Evento de recibo de mensajes case ENET_EVENT_TYPE_RECEIVE: foo.append(reinterpret_cast<const char*>(event.packet->data)); if(foo == clave) { ENetPacket *response = enet_packet_create ("pepe", strlen ("pepe") + 1, ENET_PACKET_FLAG_RELIABLE); enet_host_broadcast (server, 0, response); } else enet_host_broadcast (server, 0, event.packet); /*cout << "Se ha recibido del cliente: " << event.packet->data << endl; stringstream ss; ss << event.packet->data; ENetPacket *response = enet_packet_create (ss.str(), strlen (event.packet->data) + 1, ENET_PACKET_FLAG_RELIABLE); enet_host_broadcast (server, 0, response); enet_host_broadcast (server, 0, response); enet_packet_destroy (event.packet);*/ break; case ENET_EVENT_TYPE_DISCONNECT: cout << "Se ha desconectado el cliente" << endl; event.peer -> data = NULL; break; case ENET_EVENT_TYPE_NONE: cout << "Se ha desconectado el cliente" << endl; break; } } enet_host_destroy(server); }
bool NetPlayClient::Connect() { // send connect message sf::Packet spac; spac << scm_rev_git_str; spac << netplay_dolphin_ver; spac << m_player_name; Send(spac); enet_host_flush(m_client); sf::Packet rpac; // TODO: make this not hang ENetEvent netEvent; if (enet_host_service(m_client, &netEvent, 5000) > 0 && netEvent.type == ENET_EVENT_TYPE_RECEIVE) { rpac.append(netEvent.packet->data, netEvent.packet->dataLength); enet_packet_destroy(netEvent.packet); } else { return false; } MessageId error; rpac >> error; // got error message if (error) { switch (error) { case CON_ERR_SERVER_FULL: PanicAlertT("The server is full!"); break; case CON_ERR_VERSION_MISMATCH: PanicAlertT("The server and client's NetPlay versions are incompatible!"); break; case CON_ERR_GAME_RUNNING: PanicAlertT("The server responded: the game is currently running!"); break; default: PanicAlertT("The server sent an unknown error message!"); break; } Disconnect(); return false; } else { rpac >> m_pid; Player player; player.name = m_player_name; player.pid = m_pid; player.revision = netplay_dolphin_ver; // add self to player list m_players[m_pid] = player; m_local_player = &m_players[m_pid]; m_dialog->Update(); m_is_connected = true; return true; } }
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; }
/** \brief Thread function checking if data is received. * This function tries to get data from network low-level functions as * often as possible. When something is received, it generates an * event and passes it to the Network Manager. * \param self : used to pass the ENet host to the function. */ void* STKHost::mainLoop(void* self) { VS::setThreadName("STKHost"); ENetEvent event; STKHost* myself = (STKHost*)(self); ENetHost* host = myself->m_network->getENetHost(); if(NetworkConfig::get()->isServer() && NetworkConfig::get()->isLAN() ) { TransportAddress address(0, 2757); ENetAddress eaddr = address.toEnetAddress(); myself->m_lan_network = new Network(1, 1, 0, 0, &eaddr); } while (!myself->mustStopListening()) { if(myself->m_lan_network) { myself->handleLANRequests(); } // if discovery host while (enet_host_service(host, &event, 20) != 0) { if (event.type == ENET_EVENT_TYPE_NONE) continue; // Create an STKEvent with the event data. This will also // create the peer if it doesn't exist already Event* stk_event = new Event(&event); if (stk_event->getType() == EVENT_TYPE_MESSAGE) Network::logPacket(stk_event->data(), true); Log::verbose("STKHost", "Event of type %d received", (int)(stk_event->getType())); STKPeer* peer = stk_event->getPeer(); if (stk_event->getType() == EVENT_TYPE_CONNECTED) { Log::info("STKHost", "A client has just connected. There are " "now %lu peers.", myself->m_peers.size()); Log::debug("STKHost", "Addresses are : %lx, %lx", stk_event->getPeer(), peer); } // EVENT_TYPE_CONNECTED else if (stk_event->getType() == EVENT_TYPE_MESSAGE) { TransportAddress stk_addr(peer->getAddress()); Log::verbose("NetworkManager", "Message, Sender : %s, message = \"%s\"", stk_addr.toString(/*show port*/false).c_str(), stk_event->data().std_string().c_str()); } // if message event // notify for the event now. ProtocolManager::getInstance()->propagateEvent(stk_event); } // while enet_host_service } // while !mustStopListening free(myself->m_listening_thread); myself->m_listening_thread = NULL; Log::info("STKHost", "Listening has been stopped"); return NULL; } // mainLoop
int main(int argc, char *argv[]) { ENetAddress address; ENetHost *server; ENetEvent event; int serviceResult; puts("Starting server"); if (enet_initialize() != 0) { puts("Error initialising enet"); exit(EXIT_FAILURE); } /* 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, 32, /* number of clients */ 2, /* number of channels */ 0, /* Any incoming bandwith */ 0); /* Any outgoing bandwith */ if (server == NULL) { puts("Could not create server host"); exit(EXIT_FAILURE); } while (true) { serviceResult = 1; /* Keep doing host_service until no events are left */ while (serviceResult > 0) { /* Wait up to 1000 milliseconds for an event. */ serviceResult = enet_host_service(server, &event, 1000); 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); /* Store any relevant client information here. */ event.peer->data = (void*)"Client information"; 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); /* Tell all clients about this message */ enet_host_broadcast(server, 0, event.packet); break; case ENET_EVENT_TYPE_DISCONNECT: printf("%s disconnected.\n", event.peer->data); /* Reset the peer's client information. */ event.peer->data = NULL; break; } } else if (serviceResult > 0) { puts("Error with servicing the server"); exit(EXIT_FAILURE); } } } enet_host_destroy(server); enet_deinitialize(); return 0; }
void Client::Step() { ENetEvent event; while(enet_host_service(_host, &event, 1) > 0) { switch(event.type) { case ENET_EVENT_TYPE_RECEIVE: { Packet packet(event.packet->data, event.packet->dataLength); enet_packet_destroy(event.packet); switch(packet.GetType()) { case Packet::Type::Handshake: _clientID = packet.ReadUInt32(); RNDebug("Received handshake. I'm client %d", _clientID); break; case Packet::Type::ClientConnected: { uint32 client = packet.ReadUInt32(); if(client != _clientID) { RNDebug("Another client, %d, connected", client); World::GetSharedInstance()->GetEnemyWithID(client); } break; } case Packet::Type::ClientDisconnected: { uint32 client = packet.ReadUInt32(); if(client != _clientID) { RNDebug("Client %d disconnected", client); World::GetSharedInstance()->RemoveEnemy(client); } break; } case Packet::Type::PositionUpdate: { uint32 client = packet.ReadUInt32(); if(client != _clientID) { Enemy *enemy = World::GetSharedInstance()->GetEnemyWithID(client); enemy->UpdateFromPacket(packet); } break; } case Packet::Type::ShotsFired: { uint32 client = packet.ReadUInt32(); if(client != _clientID) { Missile *missile = new Missile(client, packet); missile->Release(); } break; } case Packet::Type::GoodHit: { uint32 client = packet.ReadUInt32(); uint32 shooter = packet.ReadUInt32(); RN::Vector3 position(packet.ReadFloat(), packet.ReadFloat(), packet.ReadFloat()); if(client == _clientID) SpaceShip::GetLocalShip()->TakeHit(position, shooter); Explosion *explosion = new Explosion(); explosion->SetPosition(position); explosion->Autorelease(); break; } case Packet::Type::GoodKill: { uint32 client = packet.ReadUInt32(); uint32 killer = packet.ReadUInt32(); RNDebug("Good kill on %d by %d", client, killer); if(killer == _clientID) World::GetSharedInstance()->TallyKill(); RN::Vector3 position(packet.ReadFloat(), packet.ReadFloat(), packet.ReadFloat()); Explosion *explosion = new Explosion(); explosion->SetPosition(position); explosion->Autorelease(); } default: break; } break; } case ENET_EVENT_TYPE_DISCONNECT: break; default: break; } } }
void RemoteRulesManager::update(const double& timeStep) { ENetEvent event; while(enet_host_service(m_client, &event, 0) > 0) { switch (event.type) { case ENET_EVENT_TYPE_CONNECT: { sendMessage(MessagePtr(new Hello("Client")), ENET_PACKET_FLAG_RELIABLE); } break; case ENET_EVENT_TYPE_RECEIVE: updateMessages(event.packet->data, event.packet->dataLength); for(auto msg : m_messageQueue) { switch(msg->getType()) { case S_WELCOME: std::cout<<"GOT WELCOME "<<msg->getData()<<std::endl; m_isWaiting = false; break; case G_UPDATE_POS: m_pongScene->updateOpponentPos(((UpdatePos*)msg.get())->getPosition()); break; case G_BALLSTATE: { BallState* ballState = (BallState*)msg.get(); m_pongScene->updateBallState( ballState->getPosition(), ballState->getVelocity(), ballState->getAngularVelocity(), ballState->getServe(), ballState->getHitMagnitude()); } break; case G_META: { MetaGameInfo* meta = (MetaGameInfo*)msg.get(); switch(meta->getEventType()) { case MetaGameInfo::META_ROUND_START: m_pongScene->onNewRound( meta->getLocalScore(), meta->getRemoteScore(), meta->getServe(), meta->getWinner()); break; case MetaGameInfo::META_GAME_OVER: m_pongScene->onGameOver( meta->getLocalScore(), meta->getRemoteScore(), meta->getWinner()); break; } } break; } } m_messageQueue.clear(); //std::cout<<"Got data: "<< event.packet->dataLength << std::endl; break; case ENET_EVENT_TYPE_DISCONNECT: std::cout<<"Client disconnected: "<< event.peer->address.host << " : " << event.peer->address.port<<std::endl; break; } } }
void shmup_game_update(shmup_game *g, double t, double dt) { static int tick = 0; static int mx, my; int i; ENetEvent event; ENetPacket *packet; bullet *b; tick++; while (enet_host_service(g->host, &event, 0) > 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); // sprintf(event.peer->data, "client %x.", event.peer->address.host); g->player[g->num_players].pos = v2(g->window_width/2, g->window_height/2); g->player[g->num_players].vel = v2zero; g->player[g->num_players].acc = v2zero; g->num_players++; break; case ENET_EVENT_TYPE_RECEIVE: g->player[1].keyflags = (short) *event.packet->data; // event.packet->dataLength, // event.packet->data, // event.peer->data, // event.channelID); enet_packet_destroy(event.packet); break; case ENET_EVENT_TYPE_DISCONNECT: printf("%s disconected.\n", event.peer->data); /* Reset the peer's client information. */ event.peer->data = NULL; break; case ENET_EVENT_TYPE_NONE: break; } } glfwGetMousePos(&mx, &my); g->emitter.x = (double) mx; g->emitter.y = (double) g->window_height-my; if (glfwGetMouseButton(GLFW_MOUSE_BUTTON_LEFT)) shmup_game_fire(g, 40, 0, v2zero, v2zero, v2zero); if (glfwGetMouseButton(GLFW_MOUSE_BUTTON_RIGHT)) shmup_game_fire(g, 40, 1, v2zero, v2zero, v2zero); if (glfwGetKey('1')) g->render_type = 1; if (glfwGetKey('2')) g->render_type = 2; g->player->keyflags = KF_NONE; if (glfwGetKey('A')) g->player->keyflags |= KF_MOV_L; if (glfwGetKey('D')) g->player->keyflags |= KF_MOV_R; if (glfwGetKey('W')) g->player->keyflags |= KF_MOV_U; if (glfwGetKey('S')) g->player->keyflags |= KF_MOV_D; if (glfwGetKey(GLFW_KEY_SPACE)) g->player->keyflags |= KF_FIR_1; for (i=0; i < g->num_players; i++) { player_update(g, &g->player[i], dt); } b = g->bpool->bdata; /* * be careful with this pointer, as this data may be moved by the * bpool_resize function! Make sure it points to the right place. */ /* do updates */ for (i=0; i < g->bpool->n_active; i++) { bullet_update(&b[i], dt); } /* do collisions */ for (i=0; i < g->bpool->n_active; i++) { if (!point_vs_aabb(b[i].pos, v2zero, v2(g->window_width, g->window_height))) bpool_deactivate(g->bpool, i--); } if (g->network_type == CLIENT) { packet = enet_packet_create(&g->player->keyflags, sizeof(short), ENET_PACKET_FLAG_RELIABLE); enet_peer_send(g->peer, 0, packet); } else { packet = enet_packet_create(&g->player->keyflags, sizeof(short), ENET_PACKET_FLAG_RELIABLE); enet_host_broadcast(g->host, 0, packet); } }
int main() { int id = 10000; std::string sip = "127.0.0.1"; int sport = 6602; ENetPeer* Peers[2]; Peers[0] = NULL; Peers[1] = NULL; enet_initialize(); ENetAddress address; ENetHost * remote; address.host = ENET_HOST_ANY; address.port = 6680; remote = enet_host_create(&address /* the address to bind the server host to */, 128 * 16 /* allow up to 32 clients and/or outgoing connections */, 17 /* 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 (remote == NULL) { fprintf(stderr, "An error occurred while trying to create an ENet server host.\n"); exit(EXIT_FAILURE); } void* ctx = zmq_ctx_new(); void* req = zmq_socket(ctx, ZMQ_REQ); int timeo = 0; int rc = zmq_setsockopt(req, ZMQ_LINGER, &timeo, sizeof(int)); std::stringstream ss; ss << "tcp://" << sip << ":" << sport; rc = zmq_connect(req, ss.str().c_str()); IPInfo info; info.port = 6680; sprintf(info.sip, "%s", sip.c_str()); if (send_add_stream(id, req, info)) { std::thread* hb = new std::thread([id, req, info] { while (true) { #ifndef RDC_LINUX_SYS Sleep(5000); #else sleep(5); #endif if (!send_heartbeat_stream(id, req, info)) { exit(EXIT_FAILURE); } } }); printf("%s\n", "Initialized!"); } ENetEvent event; /* Wait up to 1000 milliseconds for an event. */ while (enet_host_service(remote, &event, 1000) >= 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); /* Store any relevant client information here. */ { int index = 0; if (Peers[0] != NULL) index = 1; event.peer->data = &Peers[(index + 1) % 2]; Peers[index] = event.peer; } break; case ENET_EVENT_TYPE_RECEIVE: //printf("A packet of length %u was received from %s on channel %u.\n", // event.packet->dataLength, // event.peer->data, // event.channelID); { ENetPeer* peer = *(ENetPeer**)event.peer->data; if (peer) { putc('.', stdout); auto p = enet_packet_create(event.packet->data, event.packet->dataLength, ENET_PACKET_FLAG_RELIABLE); enet_peer_send(peer, event.channelID, p); } } /* 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); /* Reset the peer's client information. */ event.peer->data = NULL; break; } } return 0; }
void joynet_poll_server(JOYNET_SERVER * sp) { if(sp && sp->host) { while(enet_host_service(sp->host, &sp->event, 0)) { switch(sp->event.type) { /* a connection has been received */ case ENET_EVENT_TYPE_CONNECT: { int client = joynet_server_find_free_client(sp); if(client >= 0) { sp->client[client]->peer = sp->event.peer; } sp->client[client]->peer->data = malloc(sizeof(int)); if(!sp->client[client]->peer->data) { /* need error system */ } else { joynet_serialize(sp->serial_data, sp->client[client]->peer->data); joynet_putl(sp->serial_data, client); } sp->client[client]->user = client; strcpy(sp->client[client]->screen_name, ""); break; } /* client disconnected */ case ENET_EVENT_TYPE_DISCONNECT: { sp->client[joynet_get_client_from_peer(sp, sp->event.peer)]->peer = NULL; break; } /* packet received */ case ENET_EVENT_TYPE_RECEIVE: { JOYNET_MESSAGE message; joynet_decode_message(&message, &sp->event); switch(sp->event.channelID) { case JOYNET_CHANNEL_SYSTEM: { break; } case JOYNET_CHANNEL_CHAT: { joynet_handle_server_chat_message(sp, &message); break; } case JOYNET_CHANNEL_GAME: { joynet_handle_server_game_message(sp, &message); break; } } if(sp->channel_callback[sp->event.channelID]) { sp->channel_callback[sp->event.channelID](&message); } break; } default: { break; } } if(sp->internal_callback) { sp->internal_callback(&sp->event); } if(sp->global_callback) { sp->global_callback(&sp->event); } } } }
void LocalRulesManager::update(const double& timeStep) { ENetEvent event; while(enet_host_service(m_server, &event, 0) > 0) { switch (event.type) { case ENET_EVENT_TYPE_CONNECT: std::cout<<"Client connected: "<< event.peer->address.host << " : " << event.peer->address.port<<std::endl; break; case ENET_EVENT_TYPE_RECEIVE: updateMessages(event.packet->data, event.packet->dataLength); for(auto msg : m_messageQueue) { switch(msg->getType()) { case C_HELLO: { sendMessage(MessagePtr(new Welcome("Server")), ENET_PACKET_FLAG_RELIABLE); m_isWaiting = false; } break; case G_UPDATE_POS: m_pongScene->updateOpponentPos(((UpdatePos*)msg.get())->getPosition()); break; case G_BALLEVENT: { //std::cout<<"Ball event: " << (int)((BallEvent*)msg.get())->getEventType() << " "<< (int)((BallEvent*)msg.get())->getPlayerId() << std::endl; BallEvent* evt = (BallEvent*)msg.get(); switch(evt->getEventType()) { case BallEvent::BALLEVENT_TABLE: m_gameRules->onBallHitTable(evt->getPlayerId()); break; case BallEvent::BALLEVENT_RACKET: m_gameRules->onBallHitRacket(evt->getPlayerId()); break; case BallEvent::BALLEVENT_OUTSIDE: m_gameRules->onBallOut(); break; } checkGameRules(); } break; case G_BALLSTATE: { BallState* ballState = (BallState*)msg.get(); m_pongScene->updateBallState( ballState->getPosition(), ballState->getVelocity(), ballState->getAngularVelocity(), ballState->getServe(), ballState->getHitMagnitude()); if(ballState->getServe() != 0) m_gameRules->onNewRound(); } break; } } m_messageQueue.clear(); //std::cout<<"Got data: "<< event.packet->dataLength << std::endl; break; case ENET_EVENT_TYPE_DISCONNECT: std::cout<<"Client disconnected: "<< event.peer->address.host << " : " << event.peer->address.port<<std::endl; break; } } }
void gets2c() // get updates from the server { ENetEvent event; if(!clienthost) return; if(connpeer && totalmillis/3000 > connmillis/3000) { conoutf("attempting to connect..."); connmillis = totalmillis; ++connattempts; if(connattempts > 3) { conoutf("\f3could not connect to server"); abortconnect(); return; } } while(clienthost && enet_host_service(clienthost, &event, 0)>0) switch(event.type) { case ENET_EVENT_TYPE_CONNECT: disconnect(false, false); localdisconnect(false); curpeer = connpeer; connpeer = NULL; conoutf("connected to server"); throttle(); if(GETIV(rate)) setrate(GETIV(rate)); game::gameconnect(true); break; case ENET_EVENT_TYPE_RECEIVE: #if CLIENT // INTENSITY if(discmillis) conoutf("attempting to disconnect..."); else localservertoclient(event.channelID, event.packet); enet_packet_destroy(event.packet); #else // SERVER assert(0); #endif break; case ENET_EVENT_TYPE_DISCONNECT: // LogicSystem::init(); // INTENSITY: Not sure about this...? extern const char *disc_reasons[]; if(event.data>=DISC_NUM) event.data = DISC_NONE; if(event.peer==connpeer) { conoutf("\f3could not connect to server"); abortconnect(); } else { if(!discmillis || event.data) conoutf("\f3server network error, disconnecting (%s) ...", disc_reasons[event.data]); disconnect(); } return; default: break; } }
void clientkeepalive() { if(clienthost) enet_host_service(clienthost, NULL, 0); }
void Manager::update() { assert(_host); ENetEvent event; for (;;) { int serviceResponse = enet_host_service(_host, &event, 0); if (serviceResponse == 0) break; if (serviceResponse < 0) { std::cerr << "Event handling failed." << std::endl; break; } if (serviceResponse > 0) { switch (event.type) { case ENET_EVENT_TYPE_CONNECT: { clientLocal = new Client(event.peer); event.peer->data = clientLocal; clientLocal->setID(_nbPlayer); if (Engine::instance->getInstanceType() == Engine::InstanceType::CLIENT) Engine::instance->GetEntityLocal()->setID(_nbPlayer); _eventListener->onConnected(*clientLocal); sf::Packet packet; packet << "id" << _nbPlayer; send(*clientLocal, packet); _nbPlayer++; std::list<gameplay::PlayerEntity*> theList = Engine::instance->getEntities(); if (Engine::instance->getInstanceType() == Engine::InstanceType::SERVER) { //récupère les anciens joueurs for (std::list<gameplay::PlayerEntity*>::iterator it = theList.begin(); it != theList.end(); ++it) { gameplay::PlayerEntity* p = reinterpret_cast<gameplay::PlayerEntity*>(*it); if (p->getID() != clientLocal->getID()) { sf::Packet createPacket; createPacket << "createPlayer" << p->getID(); send(*clientLocal, createPacket); } } //notifie les autres qu'on se créé CreatePlayerOnClients(clientLocal->getID()); } break; } case ENET_EVENT_TYPE_RECEIVE: { Client *client = reinterpret_cast<Client*>(event.peer->data); sf::Packet packet; packet.append(event.packet->data, event.packet->dataLength); _eventListener->onMessageReceived(*client, packet); enet_packet_destroy(event.packet); break; } case ENET_EVENT_TYPE_DISCONNECT: { Client *client = reinterpret_cast<Client*>(event.peer->data); _eventListener->onDisconnected(*client); delete client; break; } } } } }
void CNetManager::update(const u32 timeOut) { if(connectionStatus == EICS_FAILED) return; if(mode == ENM_CLIENT) { ENetEvent event; for(u32 i = 0; i < netIterations;i++) { if(!(enet_host_service(host, &event, i ? 1 : timeOut) > 0)) break; switch (event.type) { case ENET_EVENT_TYPE_RECEIVE: { enet_uint8* buff = event.packet->data; if(event.channelID == 1) { u8 packiden = 0; memcpy((char*)&packiden,buff,1); if(packiden == 3) { connectionStatus = EICS_ESTABLISHED; if(pHandler) pHandler->onConnect(0); } } else { if(verbose) std::cout << "irrNetLite: A packet of length " << event.packet->dataLength << " was received.\n"; SInPacket inpacket((c8*)buff, event.packet->dataLength); if(pHandler) pHandler->handlePacket(inpacket); } buff = 0; enet_packet_destroy(event.packet); break; } case ENET_EVENT_TYPE_DISCONNECT: std::cout << "irrNetLite: Connection to server lost.\n"; event.peer->data = 0; connectionStatus = EICS_FAILED; if(pHandler) pHandler->onDisconnect(0); default: break; } } } else // (mode == ENM_SERVER) { ENetEvent event; for(u32 i = 0;i < netIterations;i++) { if(!(enet_host_service (host, &event, i ? 1 : timeOut) > 0)) break; switch (event.type) { case ENET_EVENT_TYPE_CONNECT: { if(verbose) std::cout << "irrNetLite: A new client connected from " << event.peer->address.host << ":" << event.peer->address.port << std::endl; u16 pID = 1; while(pID < netParams.maxClients && players[pID] != 0) pID++; if(pID >= netParams.maxClients) { if(verbose) std::cout << "irrNetLite: Warning: Client rejected. Too many clients." << std::endl; pID = 0; } else { event.peer->data = players[pID] = new SPeerData(pID, event.peer); } c8 buffer[3]; u8 packid = 4; memcpy(buffer, (char*)&packid, 1); memcpy(buffer+1, (char*)&pID, 2); ENetPacket* packet; packet = enet_packet_create(buffer, 3, ENET_PACKET_FLAG_RELIABLE); enet_peer_send(event.peer, 1, packet); enet_host_flush(host); if(pID == 0) enet_peer_reset(event.peer); break; } case ENET_EVENT_TYPE_RECEIVE: { enet_uint8* buff = event.packet->data; if(event.channelID == 1) { u8 packiden = 0; memcpy((char*)&packiden, buff, 1); if(packiden == 3) { ENetPacket* packet = enet_packet_create(&packiden, 1, ENET_PACKET_FLAG_RELIABLE); enet_peer_send(event.peer, 1, packet); SPeerData* currentPeer = reinterpret_cast<SPeerData*>(event.peer->data); if(currentPeer && pHandler) pHandler->onConnect(currentPeer->playerID); } } else { SPeerData* currentPeer = reinterpret_cast<SPeerData*>(event.peer->data); if(currentPeer) { SInPacket inPacket((c8*)buff, event.packet->dataLength); inPacket.setPlayerId(currentPeer->playerID); if(verbose) std::cout << "irrNetLite: A packet of length " << event.packet->dataLength << " from player number " << currentPeer->playerID << " was received.\n"; if(pHandler) pHandler->handlePacket(inPacket); if(globPacketRelay) { SOutPacket relayPacket((c8*)buff, event.packet->dataLength); const u32 playersSize = players.size(); for(u32 i = 0;i < playersSize;++i) if(players[i] && players[i] != currentPeer) sendOutPacket(relayPacket, i); } } } buff = 0; enet_packet_destroy(event.packet); break; } case ENET_EVENT_TYPE_DISCONNECT: { SPeerData* pData = reinterpret_cast<SPeerData*>(event.peer->data); if(pData) { if(verbose) std::cout << "irrNetLite: Player number " << pData->playerID << " disconnected.\n"; if(pHandler) pHandler->onDisconnect(pData->playerID); players[pData->playerID] = 0; delete pData; event.peer->data = 0; } } default: break; } } } }
// Receive packets from the network and buffers and create ConnectionEvents void Connection::receive() { if (!m_enet_host) { return; } ENetEvent event; int ret = enet_host_service(m_enet_host, & event, 10); if (ret > 0) { m_last_recieved = porting::getTimeMs(); m_last_recieved_warn = 0; switch (event.type) { case ENET_EVENT_TYPE_CONNECT: { //MutexAutoLock peerlock(m_peers_mutex); u16 peer_id = 0; static u16 last_try = PEER_ID_SERVER + 1; if (m_peers.size() > 0) { for (int i = 0; i < 1000; ++i) { if (last_try > 30000) last_try = PEER_ID_SERVER; ++last_try; if (!m_peers.count(last_try)) { peer_id = last_try; break; } } } else { peer_id = last_try; } if (!peer_id) last_try = peer_id = m_peers.rbegin()->first + 1; m_peers.set(peer_id, event.peer); m_peers_address.set(peer_id, Address(event.peer->address.host, event.peer->address.port)); event.peer->data = new u16; *((u16*)event.peer->data) = peer_id; // Create peer addition event ConnectionEvent e; e.peerAdded(peer_id); putEvent(e); } break; case ENET_EVENT_TYPE_RECEIVE: { ConnectionEvent e; SharedBuffer<u8> resultdata(event.packet->data, event.packet->dataLength); e.dataReceived(*(u16*)event.peer->data, resultdata); putEvent(e); } /* Clean up the packet now that we're done using it. */ enet_packet_destroy (event.packet); break; case ENET_EVENT_TYPE_DISCONNECT: deletePeer(*((u16*)event.peer->data), false); /* Reset the peer's client information. */ delete (u16*)event.peer->data; break; case ENET_EVENT_TYPE_NONE: break; } } else if (ret < 0) { infostream<<"recieve enet_host_service failed = "<< ret << std::endl; if (m_peers.count(PEER_ID_SERVER)) deletePeer(PEER_ID_SERVER, false); } else { //0 if (m_peers.count(PEER_ID_SERVER) && m_last_recieved) { //ugly fix. todo: fix enet and remove unsigned int time = porting::getTimeMs(); const unsigned int t1 = 10000, t2 = 30000 * timeout_mul, t3 = 60000 * timeout_mul; unsigned int wait = time - m_last_recieved; if (wait > t3 && m_last_recieved_warn > t2) { errorstream<<"connection lost [60s], disconnecting."<<std::endl; #if defined(__has_feature) #if __has_feature(thread_sanitizer) || __has_feature(address_sanitizer) if (0) #endif #endif { deletePeer(PEER_ID_SERVER, false); } m_last_recieved_warn = 0; m_last_recieved = 0; } else if (wait > t2 && m_last_recieved_warn > t1 && m_last_recieved_warn < t2) { errorstream<<"connection lost [30s]!"<<std::endl; m_last_recieved_warn = time - m_last_recieved; } else if (wait > t1 && m_last_recieved_warn < t1) { errorstream<<"connection lost [10s]? ping."<<std::endl; enet_peer_ping(m_peers.get(PEER_ID_SERVER)); m_last_recieved_warn = wait; } } } }
bool CNetManager::setUpClient(const c8* addressc, const u32 port) { mode = ENM_CLIENT; if(verbose) std::cout << "irrNetLite: Creating client!" << std::endl; host = enet_host_create(NULL, 1, netParams.downBandwidth / 8, netParams.upBandwidth / 8); ENetEvent event; enet_address_set_host(&address, addressc); address.port = port; if(verbose) std::cout << "irrNetLite: Connecting to " << addressc << ":" << port << std::endl; // Sets up two channels. peer = enet_host_connect(host, &address, 2); if(peer == NULL) { std::cout << "irrNetLite: Error: Could not resolve server address. Connection failed.\n"; return false; } if(!( enet_host_service(host, &event, netParams.connectionTimeout) > 0 && event.type == ENET_EVENT_TYPE_CONNECT)) { enet_peer_reset(peer); std::cout << "irrNetLite: Error: Connection timed out. Connection failed.\n"; return false; } while(enet_host_service(host, &event, netParams.connectionTimeout) > 0) { if(event.channelID == 1 && event.type == ENET_EVENT_TYPE_RECEIVE) { enet_uint8* buff = event.packet->data; u8 packiden = 0; memcpy((char*)&packiden, buff, 1); if(packiden == 4) { memcpy((char*)&playerID, buff+1, 2); if(playerID == 0) { std::cout << "irrNetLite: Error: Null player ID recieved. Server likely full."; enet_peer_reset(event.peer); return false; } if(verbose) std::cout << "irrNetLite: Player ID is " << playerID << ".\n"; u8 packid = 3; ENetPacket* packet = enet_packet_create(&packid, 1, ENET_PACKET_FLAG_RELIABLE); enet_host_broadcast(host, 1, packet); return true; } } } std::cout << "irrNetLite: Error: Failed to recieve Player ID. Connection failed.\n"; return false; }
Message* GetMessage () { ENetEvent event; if (enet_host_service(serverHost, &event, 0)) { Message* msg = NULL; unsigned int clientID = 0; for (ClientMap::iterator iter = clients.begin(); iter != clients.end(); iter++) { if (iter->second == event.peer) { clientID = iter->first; } } switch (event.type) { case ENET_EVENT_TYPE_CONNECT: msg = new Message ( "CONNECT", NULL, 0 ); clientID = nextClientID++; msg->clientID = clientID; clients[clientID] = event.peer; badMessage[clientID][0] = 0; //clear bad-message entry so it can be used Message* keymsg; Message* ivmsg; //make and share encryption keys //ADAM makeBlowKey[clientID]; //ADAM keymsg = new Message( "BLOWKEY", sessionKey[clientID], 16 ); //make a message with the blowkey //ADAM SendMessage( clientID, keymsg ); //send the blowkey //ADAM ivmsg = new Message( "BLOWIV" , sessionIV[clientID], 8 ); //make a message with the blowIV //ADAM SendMessage( clientID, ivmsg ); //send the IV break; case ENET_EVENT_TYPE_DISCONNECT: { msg = new Message ( "DISCONNECT", NULL, 0 ); msg->clientID = clientID; ClientMap::iterator iter = clients.find(clientID); clients.erase(iter); } break; case ENET_EVENT_TYPE_RECEIVE: msg = MessageEncoding::Decode(event.packet); if(msg == NULL) { if (badMessageCount[clientID] >= 4) { KillClient(clientID); } else { BadClient(clientID); } } else { msg->clientID = clientID; /* if( Blowfish::do_decrypt(msg, sessionKey[clientID], sessionIV[clientID]) == false) // msg is passed by reference. Return 0 on error. { //do something with the bad message } else { //do something with the recieved message } */ //disabled until finished implementation } enet_packet_destroy(event.packet); break; } return msg; } return NULL; }
int main (int argc, char ** argv) { prev = getthetime(); (void) signal(SIGINT,leave); if (enet_initialize () != 0) { fprintf (stderr, "An error occurred while initializing ENet.\n"); return EXIT_FAILURE; } atexit (enet_deinitialize); address.host = ENET_HOST_ANY; address.port = 5001; enetserver = enet_host_create (& address /* the address to bind the server host to */, 32 /* allow up to 32 clients and/or outgoing connections */, 0 /* 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 (enetserver== NULL) { fprintf (stderr, "An error occurred while trying to create an ENet server host.\n"); exit (EXIT_FAILURE); } tronserver = server_init(enetserver); atexit(clean_up); printf("This is the TronClone Server.\nPush ^c to kill the server.\n"); /* Main game loop */ while(1) { int i, index, temp; char buf[80]; if (enet_host_service (enetserver, & event, 10) > 0) { switch (event.type) { case ENET_EVENT_TYPE_CONNECT: enet_address_get_host_ip(&event.peer->address, buf, sizeof buf); printf ("A new client connected from %s\n", buf); server_add_user(tronserver, event.peer); break; case ENET_EVENT_TYPE_RECEIVE: server_process_packet(tronserver, event); enet_packet_destroy (event.packet); break; case ENET_EVENT_TYPE_DISCONNECT: enet_address_get_host_ip(&event.peer->address, buf, sizeof buf); printf ("A client disconnected from %s: %u.\n", buf, event.peer -> address.port); server_remove_user(tronserver, event.peer); event.peer -> data = NULL; break; } } now = getthetime(); double h = (now-prev)/1000000.0f; server_update(tronserver, h); prev = now; } clean_up(); }
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 Server::pollEvents() { ENetEvent event; if(enet_host_service (mServer, &event, 0) > 0) { if(event.type==ENET_EVENT_TYPE_CONNECT) { bool found = false; for(int i=0;i<255;++i) { if(mClients.find(i)==mClients.end()) { found = true; mClients[i] = event.peer; AssignPacket ap(i); sendPacket(&ap,false,i); std::cout<<"Assigning Client ID... (ID: "<<i<<")\n"; break; } } if(!found) std::cout<<"SHIT! Something went wrong!\n"; } else if(event.type==ENET_EVENT_TYPE_RECEIVE) { byte id = event.packet->data[0]; if(id<3||id>5) recievePacket(event.packet); else { if(id==3) { IntroPacket ap(event.packet->data,event.packet->dataLength); std::cout<<"Client introduced: "<<ap.name<<" (ID: " <<static_cast<int>(ap.id)<<")\n"; std::map<byte,String>::iterator iter = mClientNames.begin(); for(iter;iter!=mClientNames.end();++iter) { sendPacket(&SpawnPacket(iter->second,iter->first),false,ap.id); } SpawnPacket sp(ap.name,ap.id); mClientNames[ap.id] = ap.name; sendPacket(&sp); for(uint i=0;i<mConnectCallbacks.size();++i) { mConnectCallbacks[i](ap.id); } } } enet_packet_destroy(event.packet); } else if(event.type==ENET_EVENT_TYPE_DISCONNECT) { std::map<byte,ENetPeer*>::iterator it = mClients.begin(); for(it;it!=mClients.end();++it) { if(it->second==event.peer) { std::cout<<"Disconnected Client (ID: "<<static_cast<int>(it->first)<<")\n"; mClientNames.erase(mClientNames.find(it->first)); mClients.erase(it); sendPacket(&QuitPacket(it->first));// notify everyone break; } } } } }
void NetworkedMultiplayerENet::poll(){ ERR_FAIL_COND(!active); _pop_current_packet(); ENetEvent event; /* Wait up to 1000 milliseconds for an event. */ while (true) { if (!host || !active) //might have been disconnected while emitting a notification return; int ret = enet_host_service (host, & event, 1); if (ret<0) { //error, do something? break; } else if (ret==0) { break; } switch (event.type) { case ENET_EVENT_TYPE_CONNECT: { /* Store any relevant client information here. */ if (server && refuse_connections) { enet_peer_reset(event.peer); break; } IP_Address ip; ip.host=event.peer -> address.host; int *new_id = memnew( int ); *new_id = event.data; if (*new_id==0) { //data zero is sent by server (enet won't let you configure this). Server is always 1 *new_id=1; } event.peer->data=new_id; peer_map[*new_id]=event.peer; connection_status=CONNECTION_CONNECTED; //if connecting, this means it connected t something! emit_signal("peer_connected",*new_id); if (server) { //someone connected, let it know of all the peers available for (Map<int,ENetPeer*>::Element *E=peer_map.front();E;E=E->next()) { if (E->key()==*new_id) continue; //send existing peers to new peer ENetPacket * packet = enet_packet_create (NULL,8,ENET_PACKET_FLAG_RELIABLE); encode_uint32(SYSMSG_ADD_PEER,&packet->data[0]); encode_uint32(E->key(),&packet->data[4]); enet_peer_send(event.peer,1,packet); //send the new peer to existing peers packet = enet_packet_create (NULL,8,ENET_PACKET_FLAG_RELIABLE); encode_uint32(SYSMSG_ADD_PEER,&packet->data[0]); encode_uint32(*new_id,&packet->data[4]); enet_peer_send(E->get(),1,packet); } } else { emit_signal("connection_succeeded"); } } break; case ENET_EVENT_TYPE_DISCONNECT: { /* Reset the peer's client information. */ int *id = (int*)event.peer -> data; if (!id) { if (!server) { emit_signal("connection_failed"); } } else { if (server) { //someone disconnected, let it know to everyone else for (Map<int,ENetPeer*>::Element *E=peer_map.front();E;E=E->next()) { if (E->key()==*id) continue; //send the new peer to existing peers ENetPacket* packet = enet_packet_create (NULL,8,ENET_PACKET_FLAG_RELIABLE); encode_uint32(SYSMSG_REMOVE_PEER,&packet->data[0]); encode_uint32(*id,&packet->data[4]); enet_peer_send(E->get(),1,packet); } } else if (!server) { emit_signal("server_disconnected"); close_connection(); return; } emit_signal("peer_disconnected",*id); peer_map.erase(*id); memdelete( id ); } } break; case ENET_EVENT_TYPE_RECEIVE: { if (event.channelID==1) { //some config message ERR_CONTINUE( event.packet->dataLength < 8); int msg = decode_uint32(&event.packet->data[0]); int id = decode_uint32(&event.packet->data[4]); switch(msg) { case SYSMSG_ADD_PEER: { peer_map[id]=NULL; emit_signal("peer_connected",id); } break; case SYSMSG_REMOVE_PEER: { peer_map.erase(id); emit_signal("peer_disconnected",id); } break; } enet_packet_destroy(event.packet); } else if (event.channelID==0){ Packet packet; packet.packet = event.packet; int *id = (int*)event.peer -> data; ERR_CONTINUE(event.packet->dataLength<12) uint32_t source = decode_uint32(&event.packet->data[0]); int target = decode_uint32(&event.packet->data[4]); uint32_t flags = decode_uint32(&event.packet->data[8]); packet.from=source; if (server) { packet.from=*id; if (target==0) { //re-send the everyone but sender :| incoming_packets.push_back(packet); //and make copies for sending for (Map<int,ENetPeer*>::Element *E=peer_map.front();E;E=E->next()) { if (uint32_t(E->key())==source) //do not resend to self continue; ENetPacket* packet2 = enet_packet_create (packet.packet->data,packet.packet->dataLength,flags); enet_peer_send(E->get(),0,packet2); } } else if (target<0) { //to all but one //and make copies for sending for (Map<int,ENetPeer*>::Element *E=peer_map.front();E;E=E->next()) { if (uint32_t(E->key())==source || E->key()==-target) //do not resend to self, also do not send to excluded continue; ENetPacket* packet2 = enet_packet_create (packet.packet->data,packet.packet->dataLength,flags); enet_peer_send(E->get(),0,packet2); } if (-target != 1) { //server is not excluded incoming_packets.push_back(packet); } else { //server is excluded, erase packet enet_packet_destroy(packet.packet); } } else if (target==1) { //to myself and only myself incoming_packets.push_back(packet); } else { //to someone else, specifically ERR_CONTINUE(!peer_map.has(target)); enet_peer_send(peer_map[target],0,packet.packet); } } else { incoming_packets.push_back(packet); } //destroy packet later.. } else { ERR_CONTINUE(true); } }break; case ENET_EVENT_TYPE_NONE: { //do nothing } break; } } }
int main(int argc, char **argv) { int i, j, RetVal = 1; pthread_t KeyboardThread; // Parse the command-line arguments. for (i = 1; i < argc; i++) { if (!strcmp(argv[i], "--client")) IsServer = 0; else if (!strcmp(argv[i], "--server")) IsServer = 1; else if (1 == sscanf (argv[i], "--port=%d", &j)) Port = j; else { fprintf(stderr, "USAGE:\n"); fprintf(stderr, " enetHostTest [OPTIONS]\n"); fprintf(stderr, "The allowed OPTIONS are:\n"); fprintf(stderr, "--help Display this help-info.\n"); fprintf(stderr, "--server Start a server.\n"); fprintf(stderr, "--client Start a client (the default).\n"); fprintf(stderr, "--port=P Defaults to --port=%d.\n", PORT); return (1); } } // Initialize the socket library. if (enet_initialize() != 0) { fprintf(stderr, "An error occurred while initializing ENet.\n"); return EXIT_FAILURE; } atexit(enet_deinitialize); //--------------------------------------------------------------------------- // Set up the host as either a client or a server. In either // case, the variable "host" will be used as a pointer to the host. if (IsServer) { ENetAddress address; ENetHost *server; fprintf(stderr, "Starting up enet server.\n"); /* 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. */ address.port = Port; server = enet_host_create(&address, 32, 1, 0, 0); if (server == NULL) { fprintf(stderr, "An error occurred while trying to create an ENet server host.\n"); exit(EXIT_FAILURE); } host = server; } else // !IsServer, so must be a client. { ENetHost *client; fprintf(stderr, "Starting up enet client.\n"); client = enet_host_create(NULL, 1, 2, 0, 0); if (client == NULL) { fprintf(stderr, "An error occurred while trying to create an ENet client host.\n"); exit(EXIT_FAILURE); } host = client; } //--------------------------------------------------------------------------- // Start up another thread to get keyboard commands, so as to be able to // initiate messages over the socket connection. i = pthread_create(&KeyboardThread, NULL, KeyboardThreadFunction, NULL); if (i != 0) { fprintf(stderr, "Keyboard thread creation failed with code %d.\n", i); goto Done; } //--------------------------------------------------------------------------- // Infinite loop to service the host. while (1) { ENetEvent event; ENetAddress address; // Connect to the server, if necessary. if (!IsServer && peer == NULL) { enet_address_set_host(&address, "localhost"); address.port = Port; peer = enet_host_connect(host, &address, 2, 0); if (peer == NULL) { fprintf(stderr, "\rConnection failed.\n" PROMPT); #ifdef WIN32 Sleep (100); #else usleep(100 * 1000); #endif } } // Service the host for incoming packets, connects, disconnects. enet_host_service(host, &event, 1000); switch (event.type) { case ENET_EVENT_TYPE_CONNECT: fprintf(stderr, "\rA new client connected from 0x%08X:%u.\n" PROMPT, event.peer -> address.host, event.peer -> address.port); /* Store any relevant client information here. */ event.peer -> data = "Client information"; break; case ENET_EVENT_TYPE_RECEIVE: fprintf (stderr, "\r"); printf( "%u 0x%08X:%u \"%s\"\n", event.packet -> dataLength, event.peer -> address.host, event.peer -> address.port, event.packet -> data); fflush(stdout); fprintf (stderr, PROMPT); /* Clean up the packet now that we're done using it. */ enet_packet_destroy(event.packet); break; case ENET_EVENT_TYPE_DISCONNECT: fprintf(stderr, "\r0x%08X:%u disconnected.\n" PROMPT, event.peer -> address.host, event.peer -> address.port); /* Reset the peer's client information. */ event.peer -> data = NULL; if (!IsServer) peer = NULL; break; default: //printf ("No events.\n"); break; } } RetVal = 0; Done: ; enet_host_destroy(host); return (RetVal); }
void PNetworkServer::update() { if (m_state == NETWORK_CONNECTED) { pint32 ret; while ((ret = enet_host_service(m_data->server, &m_data->event, P_NETWORK_POLL_TIME)) > 0) // FIXME: why enet_host_check_events doesn't work as enet_host_service()? //while ((ret = enet_host_check_events(m_data->server, &m_data->event)) > 0) { switch (m_data->event.type) { case ENET_EVENT_TYPE_CONNECT: { puint32 id = m_nextId++; PNetworkPeer *peer = onPeerConnected(id); if (peer != P_NULL) { m_peers.insert(id, peer); peer->data()->peer = m_data->event.peer; } m_data->event.peer->data = PNEW(puint32); *(puint32*)(m_data->event.peer->data) = id; } break; case ENET_EVENT_TYPE_RECEIVE: { puint32 id = *(puint32*)(m_data->event.peer->data); PMap<puint32, PNetworkPeer*>::iterator it = m_peers.find(id); if (it != m_peers.end()) { onMessageReceived(it.value(), (const puint8 *)(m_data->event.packet->data), m_data->event.packet->dataLength); } else { PLOG_ERROR("Failed to find network connection %d.", id); } enet_packet_destroy (m_data->event.packet); } break; case ENET_EVENT_TYPE_DISCONNECT: { puint32 id = *(puint32*)(m_data->event.peer->data); PMap<puint32, PNetworkPeer*>::iterator it = m_peers.find(id); if (it != m_peers.end()) { onPeerDisconnected(it.value()); PDELETE(it.value()); m_peers.erase(it); puint32 *tmp = (puint32*)(m_data->event.peer->data); PDELETE(tmp); } else { PLOG_ERROR("Failed to find network connection %d.", id); } } break; default: PASSERT_NOTREACHABLE("Unknown server side event."); break; } } if (ret < 0) { m_state = NETWORK_ERROR; } } }
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; }
bool CNetServerWorker::RunStep() { // Check for messages from the game thread. // (Do as little work as possible while the mutex is held open, // to avoid performance problems and deadlocks.) m_ScriptInterface->GetRuntime()->MaybeIncrementalGC(0.5f); JSContext* cx = m_ScriptInterface->GetContext(); JSAutoRequest rq(cx); std::vector<std::pair<int, CStr> > newAssignPlayer; std::vector<bool> newStartGame; std::vector<std::pair<CStr, int> > newPlayerReady; std::vector<bool> newPlayerResetReady; std::vector<std::string> newGameAttributes; std::vector<u32> newTurnLength; { CScopeLock lock(m_WorkerMutex); if (m_Shutdown) return false; newStartGame.swap(m_StartGameQueue); newPlayerReady.swap(m_PlayerReadyQueue); newPlayerResetReady.swap(m_PlayerResetReadyQueue); newAssignPlayer.swap(m_AssignPlayerQueue); newGameAttributes.swap(m_GameAttributesQueue); newTurnLength.swap(m_TurnLengthQueue); } for (size_t i = 0; i < newAssignPlayer.size(); ++i) AssignPlayer(newAssignPlayer[i].first, newAssignPlayer[i].second); for (size_t i = 0; i < newPlayerReady.size(); ++i) SetPlayerReady(newPlayerReady[i].first, newPlayerReady[i].second); if (!newPlayerResetReady.empty()) ClearAllPlayerReady(); if (!newGameAttributes.empty()) { JS::RootedValue gameAttributesVal(cx); GetScriptInterface().ParseJSON(newGameAttributes.back(), &gameAttributesVal); UpdateGameAttributes(&gameAttributesVal); } if (!newTurnLength.empty()) SetTurnLength(newTurnLength.back()); // Do StartGame last, so we have the most up-to-date game attributes when we start if (!newStartGame.empty()) StartGame(); // Perform file transfers for (size_t i = 0; i < m_Sessions.size(); ++i) m_Sessions[i]->GetFileTransferer().Poll(); // Process network events: ENetEvent event; int status = enet_host_service(m_Host, &event, HOST_SERVICE_TIMEOUT); if (status < 0) { LOGERROR("CNetServerWorker: enet_host_service failed (%d)", status); // TODO: notify game that the server has shut down return false; } if (status == 0) { // Reached timeout with no events - try again return true; } // Process the event: switch (event.type) { case ENET_EVENT_TYPE_CONNECT: { // Report the client address char hostname[256] = "(error)"; enet_address_get_host_ip(&event.peer->address, hostname, ARRAY_SIZE(hostname)); LOGMESSAGE("Net server: Received connection from %s:%u", hostname, (unsigned int)event.peer->address.port); // Set up a session object for this peer CNetServerSession* session = new CNetServerSession(*this, event.peer); m_Sessions.push_back(session); SetupSession(session); ENSURE(event.peer->data == NULL); event.peer->data = session; HandleConnect(session); break; } case ENET_EVENT_TYPE_DISCONNECT: { // If there is an active session with this peer, then reset and delete it CNetServerSession* session = static_cast<CNetServerSession*>(event.peer->data); if (session) { LOGMESSAGE("Net server: Disconnected %s", DebugName(session).c_str()); // Remove the session first, so we won't send player-update messages to it // when updating the FSM m_Sessions.erase(remove(m_Sessions.begin(), m_Sessions.end(), session), m_Sessions.end()); session->Update((uint)NMT_CONNECTION_LOST, NULL); delete session; event.peer->data = NULL; } break; } case ENET_EVENT_TYPE_RECEIVE: { // If there is an active session with this peer, then process the message CNetServerSession* session = static_cast<CNetServerSession*>(event.peer->data); if (session) { // Create message from raw data CNetMessage* msg = CNetMessageFactory::CreateMessage(event.packet->data, event.packet->dataLength, GetScriptInterface()); if (msg) { LOGMESSAGE("Net server: Received message %s of size %lu from %s", msg->ToString().c_str(), (unsigned long)msg->GetSerializedLength(), DebugName(session).c_str()); HandleMessageReceive(msg, session); delete msg; } } // Done using the packet enet_packet_destroy(event.packet); break; } case ENET_EVENT_TYPE_NONE: break; } return true; }
void NetClient::calc() { ENetEvent event; if (me && server) while (enet_host_service(me, &event, 0) > 0) { char type = (event.type == ENET_EVENT_TYPE_RECEIVE) ? (char) event.packet->data[0] : LEMNET_NOTHING; if (event.type == ENET_EVENT_TYPE_CONNECT) { // Server shall check if protocols and versions match. send_welcome_data(); } else if (event.type == ENET_EVENT_TYPE_DISCONNECT) { exit = true; } else if (type == LEMNET_DISCON_SILENT) { exit = true; } else if (type == LEMNET_WELCOME_DATA) { // The server sends out packets of this sort, but that only // happens to inform clients before 2009 Oct 25 of their very // old version. The server will probably stop that in some // months, and until then we simply ignore these. } else if (type == LEMNET_YOU_TOO_OLD || type == LEMNET_YOU_TOO_NEW) { const bool old = (type == LEMNET_YOU_TOO_OLD); if (old) Console::push_back(Language::net_chat_we_too_old); else Console::push_back(Language::net_chat_we_too_new); std::string msg = Language::net_chat_version_yours; msg += Help::version_to_string(gloB->version); msg += Language::net_chat_version_server; msg += Help::version_to_string( get_uint32_from(event.packet->data + 2)); msg += '.'; Console::push_back(msg); if (old) Console::push_back(Language::net_chat_please_download); else Console::push_back(Language::net_chat_server_update); // The server will throw us out. } else if (type == LEMNET_SOMEONE_OLD || type == LEMNET_SOMEONE_NEW) { int who_nr = event.packet->data[1]; PlDatIt who = players.begin(); while (who != players.end() && who->number != who_nr) ++who; if (type == LEMNET_SOMEONE_NEW) { Console::push_back(Language::net_chat_someone_new); Console::push_back(Language::net_chat_server_update); } // There exists someone with that number else if (who != players.end()) { std::string s = who->name + ' ' + Language::net_chat_named_guy_old; Console::push_back(s); } else Console::push_back(Language::net_chat_someone_old); // This is independent from new or old if (who != players.end()) { // reset player players.erase(who); set_nobody_ready(); player_data_change = true; } } else if (type == LEMNET_RECHECK) { send_welcome_data(); } else if (type == LEMNET_ASSIGN_NUMBER) { PlayerData pd(event.packet->data[2], gloB->user_name.c_str()); // choose some color to get us started based on the player number // this might be already taken though by others, the code here // is just a very simple algorithm pd.style = pd.number % (LixEn::STYLE_MAX - LixEn::RED) + LixEn::RED; if (useR->network_last_style >= LixEn::RED && useR->network_last_style < LixEn::STYLE_MAX) pd.style = static_cast <char> (useR->network_last_style); // The lobby saves the style to useR->... players.clear(); players.push_back(pd); ourself = players.begin(); ENetPacket* p = pd.create_packet(); enet_peer_send(server, LEMNET_CHANNEL_MAIN, p); } else if (type == LEMNET_ROOM_DATA) { rooms.clear(); for (int room = 0; room < NETWORK_ROOMS_MAX; ++room) if (event.packet->data[2 + room] > 0) { RoomData rd; rd.number = room; rd.members = event.packet->data[2 + room]; rooms.insert(rd); } room_data_change = true; } else if (type == LEMNET_ROOM_CHANGE) { // Throw out all people other than us, because we'll soon receive // LEMNET_PLAYER_BEFORE packets for everyone in the new room. PlayerData temp_ourself = *ourself; players.clear(); players.push_back(temp_ourself); ourself = players.begin(); const char target_room = event.packet->data[2]; if (ourself->room == -1) Console::push_back(Language::net_chat_we_connected); else if (target_room == 0) Console::push_back(Language::net_chat_we_in_lobby); else { std::ostringstream message; message << Language::net_chat_we_in_room << (int) target_room << Language::net_chat_we_in_room_2; Console::push_back(message.str()); } ourself->room = target_room; } else if (type == LEMNET_PLAYER_DATA || type == LEMNET_PLAYER_BEFORE) { PlayerData pd; pd.read_from(event.packet); PlDatIt known = get_player(pd.number); // A new person has joined if (known == players.end()) { // Insert new data before the first higher data, so that // the players list is still sorted by operator <. PlDatIt insert_here = --players.end(); while (insert_here != --players.begin() && pd < *insert_here) --insert_here; players.insert(++insert_here, pd); set_nobody_ready(); if (type == LEMNET_PLAYER_DATA) { std::ostringstream message; message << pd.name; if (ourself->room == 0) message << Language::net_chat_player_in_lobby; else { message << Language::net_chat_player_in_room; message << (int) ourself->room; message << Language::net_chat_player_in_room_2; } Console::push_back(message.str()); Sound::play_loud(Sound::JOIN); } } else { // Only the information about readiness doesn't set back // all ready states. Everything else does. // snr = set nobody ready bool dont_call_snr = *known == pd; known->ready = !known->ready; // *known will be overwr. anyway dont_call_snr = dont_call_snr || *known == pd; *known = pd; if (!dont_call_snr) set_nobody_ready(); } player_data_change = true; } else if (type == LEMNET_PLAYER_CLEAR || type == LEMNET_PLAYER_OUT_TO) { unsigned nr = event.packet->data[1]; PlDatIt who = get_player(nr); if (who != players.end()) { std::ostringstream message; message << who->name; if (type == LEMNET_PLAYER_CLEAR) { message << Language::net_chat_disconnection; } else { int room = event.packet->data[2]; if (room == 0) { message << Language::net_chat_player_out_lobby; } else { message << Language::net_chat_player_out_room; message << room; message << Language::net_chat_player_out_room_2; } } Console::push_back(message.str()); players.erase(who); player_data_change = true; set_nobody_ready(); } } else if (type == LEMNET_LEVEL_FILE) { set_nobody_ready(); std::istringstream str((char*) event.packet->data + 2); level.load_from_stream(str); level_change = true; PlDatIt who = get_player(event.packet->data[1]); if (who != players.end()) { std::ostringstream msg; msg << who->name << ' ' << Language::net_chat_level_change << ' ' << level.get_name(); Console::push_back(msg.str()); } } else if (type == LEMNET_CHAT_MESSAGE) { std::string message = (const char*) &event.packet->data[2]; Console::push_back(message, true); // true = weiss } else if (type == LEMNET_GAME_START) { // Reset things to make it possible to play multiple games one // after another set_nobody_ready(); replay_data.clear(); permu = Permu(event.packet->data[2],(char*)event.packet->data + 3); // Jetzt aber... auf geht's! game_start = true; updates_change = 0; std::ostringstream start_message; start_message << Language::net_game_start; if (useR->key_chat > 0 && useR->key_chat < KEY_MAX) { start_message << Language::net_game_how_to_chat_1; start_message << Help::scancode_to_string(useR->key_chat); start_message << Language::net_game_how_to_chat_2; } Console::push_back(start_message.str()); } else if (type == LEMNET_GAME_END) { game_end = true; Console::push_back(Language::net_game_end); } else if (type == LEMNET_REPLAY_DATA) { // Only make available if we aren't the sender if (event.packet->data[1] != ourself->number) { ReplayData data; data.read_from(event.packet); replay_data.push_back(data); } } else if (type == LEMNET_UPDATES) { updates_change = get_uint32_from(&event.packet->data[2]); } if (event.type == ENET_EVENT_TYPE_RECEIVE) enet_packet_destroy(event.packet); } }
// called from ---GUI--- thread NetPlayClient::NetPlayClient(const std::string& address, const u16 port, NetPlayUI* dialog, const std::string& name, bool traversal, const std::string& centralServer, u16 centralPort) : m_dialog(dialog), m_player_name(name) { ClearBuffers(); if (!traversal) { // Direct Connection m_client = enet_host_create(nullptr, 1, 3, 0, 0); if (m_client == nullptr) { PanicAlertT("Couldn't Create Client"); } ENetAddress addr; enet_address_set_host(&addr, address.c_str()); addr.port = port; m_server = enet_host_connect(m_client, &addr, 3, 0); if (m_server == nullptr) { PanicAlertT("Couldn't create peer."); } ENetEvent netEvent; int net = enet_host_service(m_client, &netEvent, 5000); if (net > 0 && netEvent.type == ENET_EVENT_TYPE_CONNECT) { if (Connect()) { m_client->intercept = ENetUtil::InterceptCallback; m_thread = std::thread(&NetPlayClient::ThreadFunc, this); } } else { PanicAlertT("Failed to Connect!"); } } else { if (address.size() > NETPLAY_CODE_SIZE) { PanicAlertT("Host code size is to large.\nPlease recheck that you have the correct code"); return; } if (!EnsureTraversalClient(centralServer, centralPort)) return; m_client = g_MainNetHost.get(); m_traversal_client = g_TraversalClient.get(); // If we were disconnected in the background, reconnect. if (m_traversal_client->m_State == TraversalClient::Failure) m_traversal_client->ReconnectToServer(); m_traversal_client->m_Client = this; m_host_spec = address; m_connection_state = ConnectionState::WaitingForTraversalClientConnection; OnTraversalStateChanged(); m_connecting = true; Common::Timer connect_timer; connect_timer.Start(); while (m_connecting) { ENetEvent netEvent; if (m_traversal_client) m_traversal_client->HandleResends(); while (enet_host_service(m_client, &netEvent, 4) > 0) { sf::Packet rpac; switch (netEvent.type) { case ENET_EVENT_TYPE_CONNECT: m_server = netEvent.peer; if (Connect()) { m_connection_state = ConnectionState::Connected; m_thread = std::thread(&NetPlayClient::ThreadFunc, this); } return; default: break; } } if (connect_timer.GetTimeElapsed() > 5000) break; } PanicAlertT("Failed To Connect!"); } }
/* \brief update enet state internally */ static int _nethckEnetUpdate(void) { __NETHCKclient client; ENetEvent event; unsigned int packets = 0; TRACE(2); /* wait up to 1000 milliseconds for an event */ while (enet_host_service(_NETHCKserver.enet, &event, 1000) > 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); /* fill new client struct */ memset(&client, 0, sizeof(__NETHCKclient)); enet_address_get_host_ip(&event.peer->address, client.host, sizeof(client.host)); event.peer->data = _nethckServerNewClient(&client); break; case ENET_EVENT_TYPE_RECEIVE: /* manage packet by kind */ printf("A packet of length %zu was received on channel %u.\n", event.packet->dataLength, event.channelID); printf("ID: %d\n", ((nethckPacket*)event.packet->data)->type); switch (((nethckPacket*)event.packet->data)->type) { case NETHCK_PACKET_OBJECT: _nethckServerManagePacketObject(event.packet->data); break; case NETHCK_PACKET_OBJECT_TRANSLATION: case NETHCK_PACKET_OBJECT_MATERIAL: case NETHCK_PACKET_OBJECT_TEXTURE: default: break; } /* echo the packet to clients */ enet_host_broadcast(_NETHCKserver.enet, 0, event.packet); /* clean up the packet now that we're done using it. */ //enet_packet_destroy(event.packet); break; case ENET_EVENT_TYPE_DISCONNECT: printf("%s disconected.\n", ((__NETHCKclient*)event.peer->data)->host); /* free the client */ _nethckServerFreeClient(event.peer->data); event.peer->data = NULL; break; default: break; } ++packets; } RET(2, "%u", packets); return packets; }