#include "precompile.h" #include #include #include #include "GGListener.h" #include #include #include #include "app.h" #include "jsondatamgr.h" #include "handlermgr.h" #include "playermgr.h" class SocketDisconnectHandler : public std::enable_shared_from_this { public: a8::CommonCbProc cb; list_head entry; std::shared_ptr holder; SocketDisconnectHandler() { } ~SocketDisconnectHandler() { } }; class GCClientSession: public a8::MixedSession { public: virtual void DecodeUserPacket(char* buf, int& offset, unsigned int buflen) override { #if 1 is_activite = true; #endif bool warning = false; while (buflen - offset >= sizeof(f8::WSProxyPackHead_C)) { f8::WSProxyPackHead_C* p = (f8::WSProxyPackHead_C*)&buf[offset]; if (p->magic_code == f8::MAGIC_CODE) { if (buflen - offset < sizeof(f8::WSProxyPackHead_C) + p->packlen) { break; } f8::App::Instance()->AddSocketMsg (SF_GameGate, (socket_handle << 16) + p->socket_handle, p->ip_saddr, p->msgid, p->seqid, &buf[offset + sizeof(f8::WSProxyPackHead_C)], p->packlen, 0); offset += sizeof(f8::WSProxyPackHead_C) + p->packlen; } else { warning = true; offset++; continue; } } if (warning) { f8::UdpLog::Instance()->Warning("收到client非法数据包", {}); } } virtual void OnRawHttpGet(const std::string& url, const std::string& querystr, std::string& response) override { f8::MsgQueue::Instance()->PostMsg (IM_ExecGM, a8::Args ( { socket_handle, a8::XValue(url).GetString(), a8::XValue(querystr).GetString(), saddr } )); } virtual void OnDisConnect() override { f8::MsgQueue::Instance()->PostMsg (IM_ClientSocketDisconnect, a8::Args ( { socket_handle } )); } }; static void GSListeneron_error(a8::TcpListener*, int type, int errorid) { f8::UdpLog::Instance()->Debug("GGListeneron_error %d %d", {type, errorid}); f8::MsgQueue::Instance()->PostMsg (IM_GGListenerError, a8::Args ( { errorid } )); abort(); } void GGListener::Init() { tcp_listener_ = std::make_shared(); tcp_listener_->RegisterSessionClass(1024 * 1024 * 10); tcp_listener_->on_error = GSListeneron_error; tcp_listener_->bind_address = "0.0.0.0"; tcp_listener_->bind_port = JsonDataMgr::Instance()->GetConf()->At("listen_port")->AsXValue(); tcp_listener_->Open(); f8::MsgQueue::Instance()->RegisterCallBack (IM_GGListenerError, [] (const a8::Args& args) { int error_id = args.Get(0); GGListener::Instance()->OnListenError(error_id); }); f8::MsgQueue::Instance()->RegisterCallBack ( IM_ClientSocketDisconnect, [this] (const a8::Args& args) { int gg_socket = args.Get(0); PlayerMgr::Instance()->OnGateDisconnect(gg_socket); { std::vector> del_handlers; for (auto& pair : disconnect_listener_hash_) { unsigned short parent_socket_handle = (pair.first >> 16) & 0xFFFF; if (parent_socket_handle == gg_socket) { SocketDisconnectHandler *handle = nullptr, *tmp = nullptr; list_for_each_entry_safe(handle, tmp, &pair.second, entry) { del_handlers.push_back(handle->holder); handle->cb(a8::Args({})); } } } for (auto handler : del_handlers) { RemoveSocketDisconnectHandler(handler); } } }); } void GGListener::UnInit() { tcp_listener_ = nullptr; } void GGListener::SendText(int sockhandle, const std::string& text) { tcp_listener_->SendClientMsg(sockhandle, text.data(), text.size()); } void GGListener::ForceCloseClient(int sockhandle) { tcp_listener_->ForceCloseClient(sockhandle); } void GGListener::MarkClient(int sockhandle, bool is_active) { tcp_listener_->MarkClient(sockhandle, is_active); } long long GGListener::GetSendNodeNum() { return tcp_listener_->send_node_num; } long long GGListener::GetSentNodeNum() { return tcp_listener_->sent_node_num; } long long GGListener::GetSentBytesNum() { return tcp_listener_->sent_bytes_num; } void GGListener::OnListenError(int errorid) { a8::XPrintf("GGListeneron_error %d\n", {errorid}); f8::App::Instance()->Terminate(); exit(1); } bool GGListener::DebugNetMsg(int msg_id) { return false; } std::weak_ptr GGListener::AddSocketDisconnectListener(int socket_handle, a8::CommonCbProc cb) { auto itr = disconnect_listener_hash_.find(socket_handle); if (itr == disconnect_listener_hash_.end()) { disconnect_listener_hash_[socket_handle] = list_head(); itr = disconnect_listener_hash_.find(socket_handle); INIT_LIST_HEAD(&itr->second); } auto p = std::make_shared(); p->cb = cb; list_add_tail(&p->entry, &itr->second); p->holder = p; return p; } void GGListener::RemoveSocketDisconnectHandler(std::weak_ptr handler) { if (!handler.expired()) { auto p = handler.lock(); p->cb = nullptr; p->holder = nullptr; list_del_init(&p->entry); } } void GGListener::OnClientDisconnect(int socket_handle) { PlayerMgr::Instance()->OnClientDisconnect(socket_handle); }