//------------------------------------------------------------------------------------- void ClientApp::handleGameTick() { g_kbetime++; threadPool_.onMainThreadTick(); networkInterface().processChannels(KBEngine::Network::MessageHandlers::pMainMessageHandlers); tickSend(); switch(state_) { case C_STATE_INIT: state_ = C_STATE_PLAY; break; case C_STATE_INITLOGINAPP_CHANNEL: state_ = C_STATE_PLAY; break; case C_STATE_LOGIN: state_ = C_STATE_PLAY; if(!ClientObjectBase::login()) { WARNING_MSG("ClientApp::handleGameTick: login is failed!\n"); return; } break; case C_STATE_LOGIN_GATEWAY_CHANNEL: { state_ = C_STATE_PLAY; bool ret = updateChannel(false, "", "", "", 0); if(ret) { // 先握手然后等helloCB之后再进行登录 Network::Bundle* pBundle = Network::Bundle::ObjPool().createObject(); (*pBundle).newMessage(BaseappInterface::hello); (*pBundle) << KBEVersion::versionString(); (*pBundle) << KBEVersion::scriptVersionString(); if(Network::g_channelExternalEncryptType == 1) { pBlowfishFilter_ = new Network::BlowfishFilter(); (*pBundle).appendBlob(pBlowfishFilter_->key()); pServerChannel_->pFilter(NULL); } else { std::string key = ""; (*pBundle).appendBlob(key); } pServerChannel_->pEndPoint()->send(pBundle); Network::Bundle::ObjPool().reclaimObject(pBundle); // ret = ClientObjectBase::loginGateWay(); } } break; case C_STATE_LOGIN_GATEWAY: state_ = C_STATE_PLAY; if(!ClientObjectBase::loginGateWay()) { WARNING_MSG("ClientApp::handleGameTick: loginGateWay is failed!\n"); return; } break; case C_STATE_PLAY: break; default: KBE_ASSERT(false); break; }; }
//------------------------------------------------------------------------------------- void ClientObject::gameTick() { if(pServerChannel()->pEndPoint()) { pServerChannel()->processPackets(NULL); } else { if(connectedGateway_) { EventData_ServerCloased eventdata; eventHandler_.fire(&eventdata); connectedGateway_ = false; canReset_ = true; state_ = C_STATE_INIT; DEBUG_MSG(fmt::format("ClientObject({})::tickSend: serverCloased! name({})!\n", this->appID(), this->name())); } } if(locktime() > 0 && timestamp() < locktime()) { return; } switch(state_) { case C_STATE_INIT: state_ = C_STATE_PLAY; if(!initCreate()) return; break; case C_STATE_CREATE: state_ = C_STATE_PLAY; if(!createAccount()) return; break; case C_STATE_LOGIN: state_ = C_STATE_PLAY; if(!login()) return; break; case C_STATE_LOGIN_GATEWAY_CREATE: state_ = C_STATE_PLAY; if(!initLoginGateWay()) return; break; case C_STATE_LOGIN_GATEWAY: state_ = C_STATE_PLAY; if(!loginGateWay()) return; break; case C_STATE_PLAY: break; default: KBE_ASSERT(false); break; }; tickSend(); }
//------------------------------------------------------------------------------------- void ClientObject::gameTick() { if(pServerChannel()->endpoint()) { pServerChannel()->processPackets(NULL); } else { if(connectedGateway_) { EventData_ServerCloased eventdata; eventHandler_.fire(&eventdata); connectedGateway_ = false; canReset_ = true; } } switch(state_) { case C_STATE_INIT: state_ = C_STATE_PLAY; if(!initCreate()) return; break; case C_STATE_CREATE: state_ = C_STATE_PLAY; if(!createAccount()) return; break; case C_STATE_LOGIN: state_ = C_STATE_PLAY; if(!login()) return; break; case C_STATE_LOGIN_GATEWAY_CREATE: state_ = C_STATE_PLAY; if(!initLoginGateWay()) return; break; case C_STATE_LOGIN_GATEWAY: state_ = C_STATE_PLAY; if(!loginGateWay()) return; break; case C_STATE_PLAY: break; default: KBE_ASSERT(false); break; }; tickSend(); }
//------------------------------------------------------------------------------------- void ClientApp::handleGameTick() { g_kbetime++; threadPool_.onMainThreadTick(); handleTimers(); if(lastAddr.ip != 0) { getNetworkInterface().deregisterChannel(lastAddr); getNetworkInterface().registerChannel(pServerChannel_); lastAddr.ip = 0; } getNetworkInterface().processAllChannelPackets(KBEngine::Mercury::MessageHandlers::pMainMessageHandlers); tickSend(); switch(state_) { case C_STATE_INIT: state_ = C_STATE_PLAY; break; case C_STATE_INITLOGINAPP_CHANNEL: state_ = C_STATE_PLAY; break; case C_STATE_LOGIN: state_ = C_STATE_PLAY; if(!ClientObjectBase::login()) { WARNING_MSG("ClientApp::handleGameTick: login is failed!\n"); return; } break; case C_STATE_LOGIN_GATEWAY_CHANNEL: { state_ = C_STATE_PLAY; bool exist = false; if(pServerChannel_->endpoint()) { lastAddr = pServerChannel_->endpoint()->addr(); getNetworkInterface().dispatcher().deregisterFileDescriptor(*pServerChannel_->endpoint()); exist = getNetworkInterface().findChannel(pServerChannel_->endpoint()->addr()) != NULL; } bool ret = initBaseappChannel() != NULL; if(ret) { if(!exist) { getNetworkInterface().registerChannel(pServerChannel_); pTCPPacketReceiver_ = new Mercury::TCPPacketReceiver(*pServerChannel_->endpoint(), getNetworkInterface()); } else { pTCPPacketReceiver_->endpoint(pServerChannel_->endpoint()); } getNetworkInterface().dispatcher().registerFileDescriptor(*pServerChannel_->endpoint(), pTCPPacketReceiver_); // 先握手然后等helloCB之后再进行登录 Mercury::Bundle* pBundle = Mercury::Bundle::ObjPool().createObject(); (*pBundle).newMessage(BaseappInterface::hello); (*pBundle) << KBEVersion::versionString(); if(Mercury::g_channelExternalEncryptType == 1) { pBlowfishFilter_ = new Mercury::BlowfishFilter(); (*pBundle).appendBlob(pBlowfishFilter_->key()); pServerChannel_->pFilter(NULL); } else { std::string key = ""; (*pBundle).appendBlob(key); } pServerChannel_->pushBundle(pBundle); // ret = ClientObjectBase::loginGateWay(); } } break; case C_STATE_LOGIN_GATEWAY: state_ = C_STATE_PLAY; if(!ClientObjectBase::loginGateWay()) { WARNING_MSG("ClientApp::handleGameTick: loginGateWay is failed!\n"); return; } break; case C_STATE_PLAY: break; default: KBE_ASSERT(false); break; }; }
void Client::tick(NetworkEvent* event) { event->eventCode = eNone; if (clientSock_ == INVALID_SOCKET) { // create socket clientSock_ = socket(PF_INET, SOCK_STREAM, 0); if (clientSock_ == INVALID_SOCKET) { cleanup(); event->eventCode = eCreateSocketError; return; } setNonBlocking(clientSock_, true); connecting_ = true; } if (connecting_ == true) { // connect sockaddr_in ai_addr; ai_addr.sin_family = AF_INET; ai_addr.sin_addr.s_addr = inet_addr(ip_.c_str()); ai_addr.sin_port = htons(port_); int c = connect(clientSock_, (struct sockaddr*)&ai_addr, sizeof(ai_addr)); if (c == 0 || getError() == EISCONN2) { connecting_ = false; event->eventCode = eOtherSideConnected; return; } else { if (getError() == EWOULDBLOCK2 || getError() == EALREADY2 || getError() == EINPROGRESS2 || getError() == EINVAL2) { // still trying to connect return; } else { cleanup(); event->eventCode = eConnectError; return; } } } // send and recv if (clientSock_ != INVALID_SOCKET) { tickRecv(event); if (eFirstError < event->eventCode && event->eventCode < eLastError) { cleanup(); return; } if (event->eventCode != eNone) return; tickSend(event); if (eFirstError < event->eventCode && event->eventCode < eLastError) { cleanup(); return; } } }
void Server::tick(NetworkEvent* event) { event->eventCode = eNone; // try to initialize if (serverSock_ == INVALID_SOCKET && clientSock_ == INVALID_SOCKET) { serverSock_ = socket(PF_INET, SOCK_STREAM, 0); if (serverSock_ == INVALID_SOCKET) { cleanup(); event->eventCode = eCreateSocketError; return; } int yes = 1; if (setsockopt(serverSock_, SOL_SOCKET, SO_REUSEADDR, (const char*)&yes, sizeof(int)) == -1) { cleanup(); event->eventCode = eSetReuseAddrError; return; } sockaddr_in ai_addr; memset(&ai_addr, 0, sizeof(ai_addr)); ai_addr.sin_family = AF_INET; ai_addr.sin_addr.s_addr = htonl(INADDR_ANY); ai_addr.sin_port = htons(port_); if (bind(serverSock_, (sockaddr *)&ai_addr, sizeof(ai_addr)) == -1) { cleanup(); event->eventCode = eBindError; return; } if (listen(serverSock_, BACKLOG) == -1) { cleanup(); event->eventCode = eListenError; return; } setNonBlocking(serverSock_, true); } // try to accept if (serverSock_ != INVALID_SOCKET && clientSock_ == INVALID_SOCKET) { sockaddr_in client_addr; socklen_t sizeof_client_addr = sizeof(client_addr); clientSock_ = accept(serverSock_, (sockaddr *)&client_addr, &sizeof_client_addr); if (clientSock_ == INVALID_SOCKET) { if (getError() == EWOULDBLOCK2) { // no connections are present to be accepted, everything is ok, just return return; } else { // there is another error cleanup(); event->eventCode = eAcceptError; return; } } setNonBlocking(clientSock_, true); // we close the listening serverSock_ in order to prevent more incoming connections on the same port setNonBlocking(serverSock_, false); closesocket(serverSock_); serverSock_ = INVALID_SOCKET; event->eventCode = eOtherSideConnected; return; } // send and recv if (clientSock_ != INVALID_SOCKET) { tickRecv(event); if (eFirstError < event->eventCode && event->eventCode < eLastError) { cleanup(); return; } if (event->eventCode != eNone) return; tickSend(event); if (eFirstError < event->eventCode && event->eventCode < eLastError) { cleanup(); return; } } }