From eed8c1d256f29f51fc261ca5b895ca052e3ed326 Mon Sep 17 00:00:00 2001 From: aozhiwei Date: Sat, 2 May 2020 20:58:42 +0800 Subject: [PATCH] add masterserver --- .gitignore | 23 ++ server/,/ss_msgid.proto | 14 + server/,/ss_proto.proto | 35 ++ server/masterserver/CMakeLists.txt | 121 +++++++ server/masterserver/GGListener.cc | 112 ++++++ server/masterserver/GGListener.h | 33 ++ server/masterserver/app.cc | 467 +++++++++++++++++++++++++ server/masterserver/app.h | 87 +++++ server/masterserver/constant.h | 149 ++++++++ server/masterserver/error_code.h | 13 + server/masterserver/global.cc | 37 ++ server/masterserver/global.h | 22 ++ server/masterserver/gsmgr.cc | 237 +++++++++++++ server/masterserver/gsmgr.h | 51 +++ server/masterserver/handlermgr.cc | 90 +++++ server/masterserver/handlermgr.h | 35 ++ server/masterserver/jsondatamgr.cc | 47 +++ server/masterserver/jsondatamgr.h | 21 ++ server/masterserver/main.cc | 11 + server/masterserver/precompile.h | 21 ++ server/masterserver/types.cc | 3 + server/masterserver/types.h | 10 + server/tools/protobuild/ss_msgid.proto | 14 + server/tools/protobuild/ss_proto.proto | 35 ++ sql/relationdb_n.sql | 41 +++ 25 files changed, 1729 insertions(+) create mode 100644 .gitignore create mode 100644 server/,/ss_msgid.proto create mode 100755 server/,/ss_proto.proto create mode 100644 server/masterserver/CMakeLists.txt create mode 100644 server/masterserver/GGListener.cc create mode 100644 server/masterserver/GGListener.h create mode 100755 server/masterserver/app.cc create mode 100644 server/masterserver/app.h create mode 100755 server/masterserver/constant.h create mode 100755 server/masterserver/error_code.h create mode 100755 server/masterserver/global.cc create mode 100755 server/masterserver/global.h create mode 100644 server/masterserver/gsmgr.cc create mode 100644 server/masterserver/gsmgr.h create mode 100644 server/masterserver/handlermgr.cc create mode 100644 server/masterserver/handlermgr.h create mode 100644 server/masterserver/jsondatamgr.cc create mode 100644 server/masterserver/jsondatamgr.h create mode 100644 server/masterserver/main.cc create mode 100644 server/masterserver/precompile.h create mode 100644 server/masterserver/types.cc create mode 100755 server/masterserver/types.h create mode 100644 server/tools/protobuild/ss_msgid.proto create mode 100755 server/tools/protobuild/ss_proto.proto create mode 100644 sql/relationdb_n.sql diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b894d7e --- /dev/null +++ b/.gitignore @@ -0,0 +1,23 @@ +*.*\~ +*.*~ +*.*\# +*.*# +\#* +\.\#* +~*.* +\#*.* +*.pb.* +CMakeCache.txt +cmake_install.cmake +CMakeFiles +Makefile +server/bin +__pycache__ +*pb2.py +*.pyc +*.out +.vs +.user +game.py +*.cxx +compile_commands.json \ No newline at end of file diff --git a/server/,/ss_msgid.proto b/server/,/ss_msgid.proto new file mode 100644 index 0000000..0595eb5 --- /dev/null +++ b/server/,/ss_msgid.proto @@ -0,0 +1,14 @@ +package ss; + +//消息id定义 +enum SSMessageId_e +{ + _SS_Ping = 8; + _SS_Pong = 9; + + _SS_WSP_SocketDisconnect = 10; + _SS_WSP_RequestTargetServer = 11; + _SS_MS_ResponseTargetServer = 12; + _SS_ForceCloseSocket = 13; + +} diff --git a/server/,/ss_proto.proto b/server/,/ss_proto.proto new file mode 100755 index 0000000..be04905 --- /dev/null +++ b/server/,/ss_proto.proto @@ -0,0 +1,35 @@ +package ss; + +message SS_Ping +{ + +} + +message SS_Pong +{ + +} + +message SS_WSP_SocketDisconnect +{ +} + +message SS_WSP_RequestTargetServer +{ + optional int64 context_id = 1; + optional string account_id = 2; + optional string team_id = 3; +} + +message SS_MS_ResponseTargetServer +{ + optional int32 error_code = 1; + optional string error_msg = 2; + optional int64 context_id = 3; + optional string host = 4; + optional int32 port = 5; +} + +message SS_ForceCloseSocket +{ +} diff --git a/server/masterserver/CMakeLists.txt b/server/masterserver/CMakeLists.txt new file mode 100644 index 0000000..b172687 --- /dev/null +++ b/server/masterserver/CMakeLists.txt @@ -0,0 +1,121 @@ +project(masterserver) +cmake_minimum_required(VERSION 2.8) + +if (${GAME_ID}) + message(GAME_ID: ${GAME_ID}) +else() + set(GAME_ID 2001) + message(GAME_ID: ${GAME_ID}) +endif() + +if (${RELEASE}) + set(CMAKE_BUILD_TYPE "Release") + message("release mode") +else() + set(CMAKE_BUILD_TYPE "Debug") + message("debug mode") +endif() +set(CMAKE_CXX_FLAGS_RELEASE "-O3 -Wall -g -std=gnu++11 -DGAME_ID=${GAME_ID} -DNDEBUG") +set(CMAKE_CXX_FLAGS_DEBUG "-Wall -g -std=gnu++11 -DGAME_ID=${GAME_ID} -DDEBUG") + +include_directories( + AFTER + ../../third_party/a8engine + /usr/include/mysql + /usr/include/jsoncpp + /usr/include/hiredis + /usr/include/eigen3 + /usr/include/glm + ../../third_party + ../../third_party/behaviac/inc + ../../third_party/recastnavigation/Detour/Include + ../../third_party/recastnavigation/DetourTileCache/Include + . +) + +link_directories( + /usr/lib64/mysql + /usr/local/lib + ../../third_party/behaviac/lib +) + +aux_source_directory(../../third_party/a8engine/a8 + SRC_LIST +) + +aux_source_directory(../../third_party/framework/cpp + SRC_LIST +) + +aux_source_directory(../../third_party/recastnavigation/Detour/Source + SRC_LIST +) + +aux_source_directory(../../third_party/recastnavigation/DetourTileCache/Source + SRC_LIST +) + +execute_process( + COMMAND touch -a ss_proto.pb.h + COMMAND touch -a ss_proto.pb.cc + COMMAND touch -a ss_msgid.pb.h + COMMAND touch -a ss_msgid.pb.cc + ) +aux_source_directory(. + SRC_LIST +) + +set(EXECUTABLE_OUTPUT_PATH + ${PROJECT_BINARY_DIR}/../bin +) + +add_executable( + masterserver${GAME_ID} ${SRC_LIST} +) + +add_custom_target(script_pb_protocol ALL) +add_custom_command(TARGET script_pb_protocol + PRE_BUILD + COMMAND python ../../third_party/tools/scripts/construct/build_pb.py --cpp_out=. --pb_files=ss_proto,ss_msgid --nohooks 1 +) +add_dependencies(masterserver${GAME_ID} script_pb_protocol) + + +if (CMAKE_BUILD_TYPE STREQUAL "Debug") + target_link_libraries( + masterserver${GAME_ID} + pthread + mysqlclient + protobuf + rt + dl + util + crypto + ssl + jsoncpp + curl + hiredis + tinyxml2 + tcmalloc + behaviac_gcc_debug + ) +else() + target_link_libraries( + masterserver${GAME_ID} + pthread + mysqlclient + protobuf + rt + dl + util + crypto + ssl + jsoncpp + curl + hiredis + tinyxml2 + tcmalloc + behaviac_gcc_release + ) +endif() + diff --git a/server/masterserver/GGListener.cc b/server/masterserver/GGListener.cc new file mode 100644 index 0000000..60cbc29 --- /dev/null +++ b/server/masterserver/GGListener.cc @@ -0,0 +1,112 @@ +#include "precompile.h" + +#include +#include +#include + +#include "framework/cpp/netmsghandler.h" + +#include "app.h" +#include "GGListener.h" +#include "jsondatamgr.h" +#include "handlermgr.h" + +class GGClientSession: 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::PackHead)) { + f8::PackHead* p = (f8::PackHead*)&buf[offset]; + if (p->magic_code == f8::MAGIC_CODE) { + if (buflen - offset < sizeof(f8::PackHead) + p->packlen) { + break; + } + App::Instance()->AddSocketMsg(SF_GameGate, + socket_handle, + saddr, + p->msgid, + p->seqid, + &buf[offset + sizeof(f8::PackHead)], + p->packlen); + offset += sizeof(f8::PackHead) + p->packlen; + } else { + warning = true; + offset++; + continue; + } + } + + if (warning) { + a8::UdpLog::Instance()->Warning("收到client非法数据包", {}); + } + } + + virtual void OnRawHttpGet(const std::string& url, const std::string& querystr, + std::string& response) override + { + App::Instance()->AddIMMsg(IM_ExecGM, + a8::XParams() + .SetSender(socket_handle) + .SetParam1(url) + .SetParam2(querystr) + .SetParam3(saddr) + ); + } + + virtual void OnDisConnect() override + { + App::Instance()->AddIMMsg(IM_ClientSocketDisconnect, + a8::XParams() + .SetSender(socket_handle) + .SetParam1(1)); + } + +}; + +static void CreateGameClientSocket(a8::TcpSession **p) +{ + *p = new GGClientSession(); +} + +static void GSListeneron_error(a8::TcpListener*, int type, int errorid) +{ + a8::UdpLog::Instance()->Debug("GGListeneron_error %d %d", {type, errorid}); +} + +void GGListener::Init() +{ + tcp_listener_ = new a8::TcpListener(); + tcp_listener_->on_create_client_socket = CreateGameClientSocket; + 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(); +} + +void GGListener::UnInit() +{ + delete tcp_listener_; + 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); +} diff --git a/server/masterserver/GGListener.h b/server/masterserver/GGListener.h new file mode 100644 index 0000000..817dde2 --- /dev/null +++ b/server/masterserver/GGListener.h @@ -0,0 +1,33 @@ +#pragma once + +//game client listener +namespace a8 +{ + class TcpListener; +} + +class GGListener : public a8::Singleton +{ + private: + GGListener() {}; + friend class a8::Singleton; + + public: + void Init(); + void UnInit(); + + template + void SendMsg(int sockhandle, T& msg) + { + static int msgid = f8::Net_GetMessageId(msg); + f8::Net_SendMsg(tcp_listener_, sockhandle, 0, msgid, msg); + } + + void SendText(int sockhandle, const std::string& text); + + void ForceCloseClient(int sockhandle); + void MarkClient(int sockhandle, bool is_active); + + private: + a8::TcpListener *tcp_listener_ = nullptr; +}; diff --git a/server/masterserver/app.cc b/server/masterserver/app.cc new file mode 100755 index 0000000..eefb6f2 --- /dev/null +++ b/server/masterserver/app.cc @@ -0,0 +1,467 @@ +#include "precompile.h" + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "framework/cpp/netmsghandler.h" + +#include "app.h" +#include "jsondatamgr.h" +#include "handlermgr.h" +#include "gsmgr.h" +#include "GGListener.h" + +#include "ss_msgid.pb.h" +#include "ss_proto.pb.h" + +#include "framework/cpp/msgqueue.h" +#include "framework/cpp/tglog.h" + +struct MsgNode +{ + SocketFrom_e sockfrom; + int sockhandle; + unsigned short msgid; + unsigned int seqid; + long ip_saddr; + char* buf; + int buflen; + MsgNode* next; +}; + +struct IMMsgNode +{ + unsigned short msgid; + a8::XParams params; + IMMsgNode* next = nullptr; + +}; + +const char* const PROJ_LOG_ROOT_FMT = "/data/logs/%s/logs"; +const char* const PROJ_LOG_FILENAME_FMT = "log_$pid_%Y%m%d.log"; + +static void SavePerfLog() +{ + a8::UdpLog::Instance()->Info("max_mainloop_rundelay:%d", + { + App::Instance()->perf.max_run_delay_time, + }); + App::Instance()->perf.max_run_delay_time = 0; + App::Instance()->perf.max_timer_idle = 0; +} + +void App::Init(int argc, char* argv[]) +{ + #if 0 + { + Vector2D dir; + dir.Normalize(); + } + #endif + signal(SIGPIPE, SIG_IGN); + this->argc = argc; + this->argv = argv; + + if (!ParseOpt()) { + terminated = true; + if (node_id <= 0) { + a8::XPrintf("gameserver启动失败,缺少-n参数\n", {}); + } else if (node_id > MAX_NODE_ID) { + a8::XPrintf("gameserver启动失败,-n参数不能大于%d\n", {MAX_NODE_ID}); + } else if (instance_id <= 0) { + a8::XPrintf("gameserver启动失败,缺少-i参数\n", {}); + } else if (instance_id > MAX_INSTANCE_ID) { + a8::XPrintf("gameserver启动失败,-i参数不能大于%d\n", {MAX_INSTANCE_ID}); + } + return; + } + a8::XPrintf("masterserver starting instance_id:%d pid:%d game_id:%d\n", {instance_id, getpid(), GAME_ID}); + + loop_mutex_ = new std::mutex(); + loop_cond_ = new std::condition_variable(); + msg_mutex_ = new std::mutex(); + im_msg_mutex_ = new std::mutex(); + + srand(time(nullptr)); + InitLog(); + HandlerMgr::Instance()->Init(); + a8::Timer::Instance()->Init(); + f8::MsgQueue::Instance()->Init(); + f8::TGLog::Instance()->Init(a8::Format(PROJ_NAME_FMT, {GAME_ID}), false); + JsonDataMgr::Instance()->Init(); + uuid.SetMachineId((node_id - 1) * MAX_NODE_ID + instance_id); + GGListener::Instance()->Init(); + GSMgr::Instance()->Init(); + + a8::UdpLog::Instance()->Info("masterserver starting instance_id:%d pid:%d", {instance_id, getpid()}); + { + int perf_log_time = 1000 * 60 * 5; + if (getenv("is_dev_env")) { + perf_log_time = 1000 * 10; + } + a8::Timer::Instance()->AddRepeatTimer(perf_log_time, + a8::XParams(), + [] (const a8::XParams& param) + { + SavePerfLog(); + }); + } +} + +void App::UnInit() +{ + if (terminated) { + return; + } + GSMgr::Instance()->UnInit(); + GGListener::Instance()->UnInit(); + JsonDataMgr::Instance()->UnInit(); + f8::MsgQueue::Instance()->UnInit(); + a8::Timer::Instance()->UnInit(); + HandlerMgr::Instance()->UnInit(); + f8::TGLog::Instance()->UnInit(); + UnInitLog(); + + delete im_msg_mutex_; + im_msg_mutex_ = nullptr; + delete msg_mutex_; + msg_mutex_ = nullptr; + delete loop_cond_; + loop_cond_ = nullptr; + delete loop_mutex_; + loop_mutex_ = nullptr; +} + +int App::Run() +{ + if (terminated) { + return 0; + } + int ret = 0; + a8::UdpLog::Instance()->Info("masterserver running", {}); + last_run_tick_ = a8::XGetTickCount(); + int delta_time = 0; + while (!terminated) { + a8::tick_t begin_tick = a8::XGetTickCount(); + Global::g_nowtime = time(nullptr); + QuickExecute(delta_time); + SlowerExecute(delta_time); + Schedule(); + a8::tick_t end_tick = a8::XGetTickCount(); + if (end_tick - begin_tick > perf.max_run_delay_time) { + perf.max_run_delay_time = end_tick - begin_tick; + } + delta_time = end_tick - begin_tick; + } + return ret; +} + +void App::AddSocketMsg(SocketFrom_e sockfrom, + int sockhandle, + long ip_saddr, + unsigned short msgid, + unsigned int seqid, + const char *msgbody, + int bodylen) +{ + MsgNode *p = (MsgNode*) malloc(sizeof(MsgNode)); + memset(p, 0, sizeof(MsgNode)); + p->sockfrom = sockfrom; + p->ip_saddr = ip_saddr; + p->sockhandle = sockhandle; + p->msgid = msgid; + p->seqid = seqid; + p->buf = nullptr; + p->buflen = bodylen; + if (bodylen > 0) { + p->buf = (char*)malloc(bodylen); + memmove(p->buf, msgbody, bodylen); + } + msg_mutex_->lock(); + if (bot_node_) { + bot_node_->next = p; + bot_node_ = p; + } else { + top_node_ = p; + bot_node_ = p; + } + ++msgnode_size_; + msg_mutex_->unlock(); + NotifyLoopCond(); +} + +void App::AddIMMsg(unsigned short imcmd, a8::XParams params) +{ + IMMsgNode *p = new IMMsgNode; + p->msgid = imcmd; + p->params = params; + p->next = nullptr; + im_msg_mutex_->lock(); + if (im_bot_node_) { + im_bot_node_->next = p; + im_bot_node_ = p; + } else { + im_top_node_ = p; + im_bot_node_ = p; + } + im_msg_mutex_->unlock(); + NotifyLoopCond(); +} + +void App::QuickExecute(int delta_time) +{ + ProcessIMMsg(); + DispatchMsg(); + a8::Timer::Instance()->Update(); +} + +void App::SlowerExecute(int delta_time) +{ +} + +void App::NotifyLoopCond() +{ + std::unique_lock lk(*loop_mutex_); + loop_cond_->notify_all(); +} + +void App::Schedule() +{ + #if 1 + { + std::unique_lock lk(*loop_mutex_); + loop_cond_->wait_for(lk, std::chrono::milliseconds(1)); + } + #else + std::unique_lock lk(*loop_mutex_); + if (!HasTask()) { + int sleep_time = a8::Timer::Instance()->GetIdleableMillSeconds(); + loop_cond_->wait_for(lk, std::chrono::milliseconds(sleep_time)); + if (sleep_time > perf.max_timer_idle) { + perf.max_timer_idle = sleep_time; + } + } + #endif +} + +bool App::HasTask() +{ + { + if (!im_work_node_) { + im_msg_mutex_->lock(); + if (!im_work_node_ && im_top_node_) { + im_work_node_ = im_top_node_; + im_top_node_ = nullptr; + im_bot_node_ = nullptr; + } + im_msg_mutex_->unlock(); + } + if (im_work_node_) { + return true; + } + } + { + if (!work_node_) { + msg_mutex_->lock(); + if (!work_node_ && top_node_) { + work_node_ = top_node_; + top_node_ = nullptr; + bot_node_ = nullptr; + } + msg_mutex_->unlock(); + } + if (work_node_) { + return true; + } + } + return false; +} + +void App::DispatchMsg() +{ + long long starttick = a8::XGetTickCount(); + if (!work_node_ && top_node_) { + msg_mutex_->lock(); + work_node_ = top_node_; + top_node_ = nullptr; + bot_node_ = nullptr; + working_msgnode_size_ = msgnode_size_; + msg_mutex_->unlock(); + } + + f8::MsgHdr hdr; + while (work_node_) { + MsgNode *pdelnode = work_node_; + work_node_ = pdelnode->next; + hdr.msgid = pdelnode->msgid; + hdr.seqid = pdelnode->seqid; + hdr.socket_handle = pdelnode->sockhandle; + hdr.buf = pdelnode->buf; + hdr.buflen = pdelnode->buflen; + hdr.offset = 0; + hdr.ip_saddr = pdelnode->ip_saddr; + switch (pdelnode->sockfrom) { + case SF_GameGate: + { + ProcessGameGateMsg(hdr); + } + break; + } + if (pdelnode->buf) { + free(pdelnode->buf); + } + free(pdelnode); + working_msgnode_size_--; + if (a8::XGetTickCount() - starttick > 200) { + break; + } + }//end while + + if (!work_node_) { + working_msgnode_size_ = 0; + } +} + +void App::ProcessGameGateMsg(f8::MsgHdr& hdr) +{ + f8::NetMsgHandler* handler = f8::GetNetMsgHandler(&HandlerMgr::Instance()->ggmsghandler, + hdr.msgid); + if (handler) { + switch (handler->handlerid) { + case HID_GSMgr: + ProcessNetMsg(handler, GSMgr::Instance(), hdr); + break; + } + } +} + +void App::ProcessIMMsg() +{ + if (!im_work_node_ && im_top_node_) { + im_msg_mutex_->lock(); + im_work_node_ = im_top_node_; + im_top_node_ = nullptr; + im_bot_node_ = nullptr; + im_msg_mutex_->unlock(); + } + while (im_work_node_) { + IMMsgNode *pdelnode = im_work_node_; + switch (im_work_node_->msgid) { + case f8::IM_SysMsgQueue: + { + const a8::XParams* param = (const a8::XParams*)pdelnode->params.param1.GetUserData(); + f8::MsgQueue::Instance()->ProcessMsg(pdelnode->params.sender.GetInt(), + *param + ); + delete param; + } + break; + case IM_ClientSocketDisconnect: + { + #if 0 + PlayerMgr::Instance()->OnClientDisconnect(pdelnode->params); + #endif + } + break; + case IM_ExecGM: + { + HandlerMgr::Instance()->ProcGMMsg(pdelnode->params.param3, + pdelnode->params.sender, + pdelnode->params.param1.GetString(), + pdelnode->params.param2.GetString() + ); + } + break; + } + im_work_node_ = im_work_node_->next; + delete pdelnode; + } +} + +void App::InitLog() +{ + std::string filename_fmt = PROJ_LOG_FILENAME_FMT; + a8::ReplaceString(filename_fmt, "$pid", a8::XValue(getpid())); + + std::string proj_root_dir = a8::Format(PROJ_ROOT_FMT, {a8::Format(PROJ_NAME_FMT,{GAME_ID})}); + std::string proj_log_root_dir = a8::Format(PROJ_LOG_ROOT_FMT, {a8::Format(PROJ_NAME_FMT, {GAME_ID})}); + std::string log_file_name = a8::Format(PROJ_LOG_ROOT_FMT, + {a8::Format(PROJ_NAME_FMT, {GAME_ID})}) + "/" + filename_fmt; + + a8::MkDir(proj_root_dir); + a8::MkDir(proj_log_root_dir); + a8::UdpLog::Instance()->SetLogFileName(log_file_name); + a8::UdpLog::Instance()->Init(); + a8::UdpLog::Instance()->Info("proj_root_dir:%s", {proj_root_dir}); + a8::UdpLog::Instance()->Info("proj_log_root_dir:%s", {proj_log_root_dir}); + a8::UdpLog::Instance()->Info("log_file_name:%s", {log_file_name}); +} + +void App::UnInitLog() +{ + a8::UdpLog::Instance()->UnInit(); +} + +bool App::ParseOpt() +{ + int ch = 0; + while ((ch = getopt(argc, argv, "n:i:t:r:f:")) != -1) { + switch (ch) { + case 'n': + { + node_id = a8::XValue(optarg); + } + break; + case 'i': + { + instance_id = a8::XValue(optarg); + } + break; + case 't': + { + is_test_mode = true; + test_param = a8::XValue(optarg); + } + break; + case 'f': + { + std::vector strings; + a8::Split(optarg, strings, ','); + for (auto& str : strings) { + flags.insert(a8::XValue(str).GetInt()); + } + } + break; + } + } + return instance_id > 0 && node_id > 0; +} + +long long App::NewUuid() +{ + return uuid.Generate(); +} + +a8::XParams* App::AddContext(long long context_id) +{ + context_hash_[context_id] = a8::XParams(); + return GetContext(context_id); +} + +void App::DelContext(long long context_id) +{ + context_hash_.erase(context_id); +} + +a8::XParams* App::GetContext(long long context_id) +{ + auto itr = context_hash_.find(context_id); + return itr != context_hash_.end() ? &(itr->second) : nullptr; +} diff --git a/server/masterserver/app.h b/server/masterserver/app.h new file mode 100644 index 0000000..a145067 --- /dev/null +++ b/server/masterserver/app.h @@ -0,0 +1,87 @@ +#pragma once + +#include + +struct MsgNode; +struct IMMsgNode; +class App : public a8::Singleton +{ +private: + App() {}; + friend class a8::Singleton; + +public: + + void Init(int argc, char* argv[]); + void UnInit(); + + int Run(); + + void AddSocketMsg(SocketFrom_e sockfrom, + int sockhandle, + long ip_saddr, + unsigned short msgid, + unsigned int seqid, + const char *msgbody, + int bodylen); + void AddIMMsg(unsigned short imcmd, a8::XParams params); + + void NotifyLoopCond(); + + long long NewUuid(); + a8::XParams* AddContext(long long context_id); + void DelContext(long long context_id); + a8::XParams* GetContext(long long context_id); + +private: + void QuickExecute(int delta_time); + void SlowerExecute(int delta_time); + void Schedule(); + bool HasTask(); + + void DispatchMsg(); + void ProcessIMMsg(); + + void ProcessGameGateMsg(f8::MsgHdr& hdr); + + void InitLog(); + void UnInitLog(); + + bool ParseOpt(); + +public: + int argc = 0; + char** argv = nullptr; + volatile bool terminated = false; + PerfMonitor perf; + a8::uuid::SnowFlake uuid; + +public: + int node_id = 0; + int instance_id = 0; + bool is_test_mode = false; + int test_param = 0; + std::set flags; + +private: + long long last_run_tick_ = 0; + std::mutex *loop_mutex_ = nullptr; + std::condition_variable *loop_cond_ = nullptr; + + std::mutex *msg_mutex_ = nullptr; + MsgNode* top_node_ = nullptr; + MsgNode* bot_node_ = nullptr; + MsgNode* work_node_ = nullptr; + + std::mutex* im_msg_mutex_ = nullptr; + IMMsgNode* im_top_node_ = nullptr; + IMMsgNode* im_bot_node_ = nullptr; + IMMsgNode* im_work_node_ = nullptr; + + std::map context_hash_; + +public: + int msgnode_size_ = 0 ; + int working_msgnode_size_ = 0; + +}; diff --git a/server/masterserver/constant.h b/server/masterserver/constant.h new file mode 100755 index 0000000..24b7fd5 --- /dev/null +++ b/server/masterserver/constant.h @@ -0,0 +1,149 @@ +#pragma once + +enum SocketFrom_e +{ + SF_GameGate, +}; + +enum InnerMesssage_e +{ + IM_ClientSocketDisconnect = 100, + IM_PlayerOffline, + IM_ExecGM, + IM_DBSConnDisconnect, + IM_BSConnDisconnect, + IM_LoadConfig, + IM_HttpResponse, +}; + +//网络处理对象 +enum NetHandler_e +{ + HID_GSMgr, +}; + +enum PlayerState_e +{ + PS_None +}; + +enum VirtualItemId_e +{ + VID_Item_Gold = 50001, + VID_Item_Exp = 50002, + VID_Soul_Stone = 50018, + VID_Pickaxe = 50019 +}; + +enum SyncData_e +{ + SYNC_Data_Exp = 0, +}; + +enum DoorState_e +{ + DoorStateClose = 0, + DoorStateOpen = 1 +}; + +enum GasMode_e +{ + GasInactive = 0, + GasWaiting = 1, + GasMoving = 2, + GasJump = 3 +}; + +enum ActionType_e +{ + AT_None = 0, + AT_Reload = 1, + AT_UseItem = 2, + AT_Relive = 3, + AT_Rescue = 4 +}; + +enum InventorySlot_e +{ + IS_9MM = 0, + IS_556MM = 1, + IS_762MM = 2, + IS_12GAUGE = 3, + IS_RPG = 4, + IS_FRAG = 5, + IS_SMOKE = 6, + IS_HEALTHKIT = 7, + IS_PAIN_KILLER = 8, + + IS_1XSCOPE = 12, + IS_2XSCOPE = 13, + IS_4XSCOPE = 14, + IS_8XSCOPE = 15, + IS_15XSCOPE = 16, + + IS_END +}; + +enum SkillType_e +{ + ST_Hide = 1, + ST_SummonHero = 2, + ST_Accelerate = 3, + ST_DamageAdd = 4, + ST_DefAdd = 5, + ST_RecoverHP = 6, + ST_ReflectDamage = 7, + ST_SelfDetonate = 8 +}; + +enum SkillCond_e +{ + SC_Active = 1, + SC_Passive = 2 +}; + +enum VirtualWeapon_e +{ + VW_SafeArea = 9000000, + VW_Spectate = 9000001, + VW_SelfDetonate = 9000002, + VW_Mine = 9000003, +}; + +enum VirtualPlayer_e +{ + VP_SafeArea = 9000000, + VP_Spectate = 9000001, + VP_SelfDetonate = 9000002, + VP_Mine = 9000003, +}; + +const char* const PROJ_NAME_FMT = "game%d_masterserver"; +const char* const PROJ_ROOT_FMT = "/data/logs/%s"; + +const float TEN_W = 10000 * 10; + +const int SYS_RESET_TIME = 2*60; //每日两点重置 + +const int DEF_WEAPON_ID = 12103; + +const int SERVER_FRAME_RATE = 20; +const int SYNC_FRAME_RATE = 10; +const float FRAME_RATE_MS = 1000.0f / SERVER_FRAME_RATE; + +const int MAX_WEAPON_NUM = 5; + +const int GUN_SLOT1 = 1; +const int GUN_SLOT2 = 2; + +const int FRAG_SLOT = 3; +const int SMOKE_SLOT = 4; + +const int MAP_HEIGHT = 8192; +const int MAP_WIDTH = 8192; +const int MAP_CELL_WIDTH = 64 * 8; + +const int DOOR_THING_ID = 61701; + +const int MAX_NODE_ID = 8; +const int MAX_INSTANCE_ID = 500; diff --git a/server/masterserver/error_code.h b/server/masterserver/error_code.h new file mode 100755 index 0000000..35ec63e --- /dev/null +++ b/server/masterserver/error_code.h @@ -0,0 +1,13 @@ +#pragma once + +/* + 类似http的错误码设计 + 0:成功 + <400: 客户端的错 + >500: 服务器的错 +*/ +enum ErrorCode_e +{ + ERRNO_OK = 0, + +}; diff --git a/server/masterserver/global.cc b/server/masterserver/global.cc new file mode 100755 index 0000000..14f96c9 --- /dev/null +++ b/server/masterserver/global.cc @@ -0,0 +1,37 @@ +#include "precompile.h" +#include "global.h" + +int g_hint_flags = 0; + +bool Global::IsVirtualItem(int itemid) +{ + return (itemid == VID_Item_Exp || + itemid == VID_Item_Gold || + itemid == VID_Soul_Stone || + itemid == VID_Pickaxe); +} + +time_t Global::BetweenDays(time_t time1, time_t time2) +{ + return (time1 + g_time_zone*3600)/3600/24 - (time2 + g_time_zone*3600)/3600/24; +} + +time_t Global::GetDaySeconds(time_t time, int incdays) +{ + return time_t((time + g_time_zone * 3600)/3600/24 + incdays) * 3600 * 24 - 3600 * g_time_zone; +} + +bool Global::IsTimeToReset(int time) +{ + return BetweenDays(g_nowtime - 60 * SYS_RESET_TIME, time - 60 * SYS_RESET_TIME) > 0; +} + + +int Global::g_nowtime = time(nullptr); +int Global::g_time_zone = 8; +bool Global::g_shutdown = false; + +bool IsValidSlotId(int slot_id) +{ + return slot_id >= 0 && slot_id < IS_END; +} diff --git a/server/masterserver/global.h b/server/masterserver/global.h new file mode 100755 index 0000000..9d9df3c --- /dev/null +++ b/server/masterserver/global.h @@ -0,0 +1,22 @@ +#pragma once + +extern int g_hint_flags; + +class Global : public a8::Singleton +{ + private: + Global() {}; + friend class a8::Singleton; + public: + + static bool IsVirtualItem(int itemid); + static bool IsTimeToReset(int time); + static time_t BetweenDays(time_t time1, time_t time2); + static time_t GetDaySeconds(time_t time, int incdays = 0); + + static int g_nowtime; + static int g_time_zone; // 默认东八区 + static bool g_shutdown; +}; + +bool IsValidSlotId(int slot_id); diff --git a/server/masterserver/gsmgr.cc b/server/masterserver/gsmgr.cc new file mode 100644 index 0000000..25b6af9 --- /dev/null +++ b/server/masterserver/gsmgr.cc @@ -0,0 +1,237 @@ +#include "precompile.h" + +#include +#include + +#include "gsmgr.h" +#include "app.h" +#include "GGListener.h" + +void GSMgr::Init() +{ + a8::Timer::Instance()->AddRepeatTimer(1000 * 2, + a8::XParams(), + [] (const a8::XParams& param) + { + GSMgr::Instance()->ClearTimeOutNode(); + }); +} + +void GSMgr::UnInit() +{ + +} + +void GSMgr::_SS_WSP_RequestTargetServer(f8::MsgHdr& hdr, const ss::SS_WSP_RequestTargetServer& msg) +{ + ss::SS_MS_ResponseTargetServer respmsg; + respmsg.set_context_id(msg.context_id()); + GSNode* node = GetNodeByTeamId(msg.team_id()); + if (node) { + respmsg.set_host(node->ip); + respmsg.set_port(node->port); + } else { + node = AllocNode(); + if (node) { + respmsg.set_host(node->ip); + respmsg.set_port(node->port); + team_hash_[msg.team_id()] = node; + } else { + respmsg.set_error_code(1); + respmsg.set_error_msg("无法分配节点"); + } + } + GGListener::Instance()->SendMsg(hdr.socket_handle, respmsg); +} + +void GSMgr::_SS_Ping(f8::MsgHdr& hdr, const ss::SS_Ping& msg) +{ + ss::SS_Pong pongmsg; + GGListener::Instance()->SendMsg(hdr.socket_handle, pongmsg); +} + +void GSMgr::___GSReport(f8::JsonHttpRequest* request) +{ + std::string ip = request->request.Get("ip"); + int port = request->request.Get("port"); + int alive_count = request->request.Get("alive_count"); + int online_num = request->request.Get("online_num"); + int room_num = request->request.Get("room_num"); + int instance_id = request->request.Get("instance_id"); + int node_id = request->request.Get("node_id"); + bool servicing = request->request.Get("servicing"); + std::string key = ip + ":" + a8::XValue(port).GetString(); + + auto itr = node_key_hash_.find(key); + if (itr != node_key_hash_.end()) { + if (itr->second.online_num != online_num || + itr->second.room_num != room_num || + itr->second.alive_count != alive_count || + itr->second.servicing != servicing + ) { + itr->second.online_num = online_num; + itr->second.room_num = room_num; + itr->second.servicing = servicing; + RearrangeNode(); + } + itr->second.alive_count = alive_count; + itr->second.last_active_tick = a8::XGetTickCount(); + } else { + GSNode gs; + gs.key = key; + gs.node_id = node_id; + gs.node_idx = App::Instance()->NewUuid(); + gs.instance_id = instance_id; + gs.alive_count = alive_count; + gs.online_num = online_num; + gs.room_num = room_num; + gs.ip = ip; + gs.port = port; + gs.servicing = servicing; + gs.last_active_tick = a8::XGetTickCount(); + node_key_hash_[key] = gs; + node_sorted_list_.push_back(&node_key_hash_[key]); + RearrangeNode(); + } + + request->resp_xobj->SetVal("errcode", 0); + request->resp_xobj->SetVal("errmsg", ""); +} + +void GSMgr::___GSList(f8::JsonHttpRequest* request) +{ + { + a8::MutableXObject* node_list = a8::MutableXObject::NewArray(); + + for (auto& pair : node_key_hash_) { + a8::MutableXObject* node = a8::MutableXObject::NewObject(); + node->SetVal("node_id", pair.second.node_id); + node->SetVal("instance_id", pair.second.instance_id); + node->SetVal("room_num", pair.second.room_num); + node->SetVal("alive_count", pair.second.alive_count); + node->SetVal("online_num", pair.second.online_num); + node->SetVal("ip", pair.second.ip); + node->SetVal("port", pair.second.port); + node->SetVal("servicing", pair.second.servicing); + node_list->Push(*node); + delete node; + } + + request->resp_xobj->SetVal("errcode", 0); + request->resp_xobj->SetVal("errmsg", ""); + request->resp_xobj->SetVal("node_list", *node_list); + delete node_list; + } + { + a8::MutableXObject* node_list = a8::MutableXObject::NewArray(); + + for (GSNode* gs_node : node_sorted_list_) { + a8::MutableXObject* node = a8::MutableXObject::NewObject(); + node->SetVal("node_id", gs_node->node_id); + node->SetVal("instance_id", gs_node->instance_id); + node->SetVal("room_num", gs_node->room_num); + node->SetVal("online_num", gs_node->online_num); + node->SetVal("ip", gs_node->ip); + node->SetVal("port", gs_node->port); + node->SetVal("servicing", gs_node->servicing); + node_list->Push(*node); + delete node; + } + + request->resp_xobj->SetVal("errcode", 0); + request->resp_xobj->SetVal("errmsg", ""); + request->resp_xobj->SetVal("sorted_node_list", *node_list); + delete node_list; + } +} + +GSNode* GSMgr::GetNodeByTeamId(const std::string& team_id) +{ + auto itr = team_hash_.find(team_id); + return itr != team_hash_.end() ? itr->second : nullptr; +} + +GSNode* GSMgr::AllocNode() +{ + if (node_sorted_list_.empty()) { + return nullptr; + } + size_t rnd = std::min((size_t)2, node_sorted_list_.size()); + int idx = rand() % rnd; + while (idx >= 0) { + if (node_sorted_list_[idx]->servicing) { + return node_sorted_list_[idx]; + } + --idx; + } + a8::UdpLog::Instance()->Warning("节点分配失败 node_sorted_list.size:%d node_list.size:%d", + { + node_sorted_list_.size(), + node_key_hash_.size() + }); + return nullptr; +} + +void GSMgr::RearrangeNode() +{ + std::sort(node_sorted_list_.begin(), node_sorted_list_.end(), + [] (const GSNode* a, const GSNode* b) + { + if (a->servicing && b->servicing) { + if (a->room_num < b->room_num) { + return true; + } + if (a->room_num > b->room_num) { + return false; + } + if (a->online_num < b->online_num) { + return true; + } + if (a->online_num > b->online_num) { + return false; + } + return a->node_idx > b->node_idx; + } + if (a->servicing) { + return true; + } + if (b->servicing) { + return false; + } + return a->node_idx > b->node_idx; + } + ); +} + +void GSMgr::ClearTimeOutNode() +{ + std::vector time_out_nodes; + for (auto& pair : node_key_hash_) { + if (a8::XGetTickCount() - pair.second.last_active_tick > 1000 * 5) { + time_out_nodes.push_back(&pair.second); + } + } + for (GSNode* node : time_out_nodes) { + { + for (size_t i = 0; i < node_sorted_list_.size(); ++i) { + if (node_sorted_list_[i] == node) { + node_sorted_list_.erase(node_sorted_list_.begin() + i); + break; + } + } + } + { + std::vector deleted_teams; + for (auto& pair : team_hash_) { + if (pair.second == node) { + deleted_teams.push_back(pair.first); + } + } + for (const std::string& team_id : deleted_teams) { + team_hash_.erase(team_id); + } + } + node_key_hash_.erase(node->key); + } + RearrangeNode(); +} diff --git a/server/masterserver/gsmgr.h b/server/masterserver/gsmgr.h new file mode 100644 index 0000000..5ad7e40 --- /dev/null +++ b/server/masterserver/gsmgr.h @@ -0,0 +1,51 @@ +#pragma once + +#include "ss_proto.pb.h" + +struct GSNode +{ + std::string key; + long long node_idx = 0; + int node_id = 0; + int instance_id = 0; + int room_num = 0; + int alive_count = 0; + int online_num = 0; + std::string ip; + int port = 0; + bool servicing = false; + long long last_active_tick = 0; +}; + +class GSMgr : public a8::Singleton +{ + public: + enum { HID = HID_GSMgr }; + + private: + GSMgr() {}; + friend class a8::Singleton; + + public: + + void Init(); + void UnInit(); + + void _SS_WSP_RequestTargetServer(f8::MsgHdr& hdr, const ss::SS_WSP_RequestTargetServer& msg); + void _SS_Ping(f8::MsgHdr& hdr, const ss::SS_Ping& msg); + + void ___GSReport(f8::JsonHttpRequest* request); + void ___GSList(f8::JsonHttpRequest* request); + + private: + GSNode* GetNodeByTeamId(const std::string& team_id); + GSNode* AllocNode(); + void RearrangeNode(); + void ClearTimeOutNode(); + + private: + + std::map team_hash_; + std::map node_key_hash_; + std::vector node_sorted_list_; +}; diff --git a/server/masterserver/handlermgr.cc b/server/masterserver/handlermgr.cc new file mode 100644 index 0000000..54cf0ff --- /dev/null +++ b/server/masterserver/handlermgr.cc @@ -0,0 +1,90 @@ +#include "precompile.h" + +#include + +#include "handlermgr.h" + +#include "GGListener.h" +#include "app.h" +#include "gsmgr.h" + +static void _GMOpsSelfChecking(f8::JsonHttpRequest* request) +{ + request->resp_xobj->SetVal("errcode", 0); + request->resp_xobj->SetVal("errmsg", ""); + request->resp_xobj->SetVal("healthy", 1); + request->resp_xobj->SetVal("max_rundelay", App::Instance()->perf.max_run_delay_time); + request->resp_xobj->SetVal("max_timer_idle", App::Instance()->perf.max_timer_idle); +} + +static void _GMOpsReload(f8::JsonHttpRequest* request) +{ + request->resp_xobj->SetVal("errcode", 0); + request->resp_xobj->SetVal("errmsg", ""); + a8::UdpLog::Instance()->Warning("reload config files", {}); +} + +void HandlerMgr::Init() +{ + RegisterNetMsgHandlers(); + RegisterGMMsgHandler("Ops@selfChecking", _GMOpsSelfChecking); + RegisterGMMsgHandler("Ops@reload", _GMOpsReload); + RegisterGMMsgHandler("GS@report", [] (f8::JsonHttpRequest* request) + { + GSMgr::Instance()->___GSReport(request); + }); + RegisterGMMsgHandler("GS@list", [] (f8::JsonHttpRequest* request) + { + GSMgr::Instance()->___GSList(request); + }); +} + +void HandlerMgr::UnInit() +{ +} + +void HandlerMgr::RegisterNetMsgHandlers() +{ + RegisterNetMsgHandler(&ggmsghandler, &GSMgr::_SS_WSP_RequestTargetServer); +} + +void HandlerMgr::ProcGMMsg(unsigned long saddr, int sockhandle, + const std::string& url, const std::string& querystr) +{ + if (url != "/webapp/index.php") { + GGListener::Instance()->SendText(sockhandle, a8::HttpResponse(404, "")); + return; + } + + a8::HTTPRequest request; + a8::ParserUrlQueryString(querystr.c_str(), request); + + std::string msgname = a8::Get(request, "c").GetString() + "@" + a8::Get(request, "a").GetString(); + auto itr = gmhandlers_.find(msgname); + if (itr != gmhandlers_.end()) { + f8::JsonHttpRequest* request = new f8::JsonHttpRequest; + request->saddr = saddr; + request->socket_handle = sockhandle; + request->query_str = querystr; + request->request.ReadFromUrlQueryString(querystr); + request->resp_xobj->SetVal("errcode", 0); + request->resp_xobj->SetVal("errmsg", ""); + itr->second(request); + + if (!request->pending){ + std::string response; + request->resp_xobj->ToJsonStr(response); + GGListener::Instance()->SendText(sockhandle, a8::HttpResponse(response)); + + delete request; + } + } else { + GGListener::Instance()->SendText(sockhandle, a8::HttpResponse("{}")); + } +} + +void HandlerMgr::RegisterGMMsgHandler(const std::string& msgname, + void (*handler)(f8::JsonHttpRequest*)) +{ + gmhandlers_[msgname] = handler; +} diff --git a/server/masterserver/handlermgr.h b/server/masterserver/handlermgr.h new file mode 100644 index 0000000..2bf21b8 --- /dev/null +++ b/server/masterserver/handlermgr.h @@ -0,0 +1,35 @@ +#pragma once + +#include + +#include "framework/cpp/netmsghandler.h" + +namespace a8 +{ + class MutableXObject; +} + +class HandlerMgr : public a8::Singleton +{ + + private: + HandlerMgr() {}; + friend class a8::Singleton; + + public: + + void Init(); + void UnInit(); + + f8::NetMsgHandlerObject ggmsghandler; + + void ProcGMMsg(unsigned long saddr, int sockhandle, + const std::string& url, const std::string& quyerstr); + + private: + void RegisterNetMsgHandlers(); + void RegisterGMMsgHandler(const std::string& msgname, + void (*)(f8::JsonHttpRequest*)); + + std::map gmhandlers_; +}; diff --git a/server/masterserver/jsondatamgr.cc b/server/masterserver/jsondatamgr.cc new file mode 100644 index 0000000..0e11798 --- /dev/null +++ b/server/masterserver/jsondatamgr.cc @@ -0,0 +1,47 @@ +#include "precompile.h" + +#include "jsondatamgr.h" +#include "app.h" + +#include "framework/cpp/utils.h" + +void JsonDataMgr::Init() +{ + std::string masterserver_cluster_json_file; + if (!f8::IsOnlineEnv()) { + if (f8::IsTestEnv()) { + work_path_ = a8::Format("/root/pub/%d/%d/conf_test/game%d/masterserver.test", + { + GAME_ID, + App::Instance()->instance_id, + GAME_ID + }); + } else { + work_path_ = a8::Format("/root/pub/%d/%d/conf_test/game%d/masterserver.dev", + { + GAME_ID, + App::Instance()->instance_id, + GAME_ID + }); + } + } + masterserver_cluster_json_file = a8::Format("%s/node%d/game%d.masterserver.cluster.json", + { + work_path_, + App::Instance()->node_id, + GAME_ID + }); + masterserver_cluster_json_.ReadFromFile(masterserver_cluster_json_file); +} + +void JsonDataMgr::UnInit() +{ +} + +std::shared_ptr JsonDataMgr::GetConf() +{ + if (App::Instance()->instance_id < 1 || App::Instance()->instance_id > masterserver_cluster_json_.Size()) { + abort(); + } + return masterserver_cluster_json_[App::Instance()->instance_id - 1]; +} diff --git a/server/masterserver/jsondatamgr.h b/server/masterserver/jsondatamgr.h new file mode 100644 index 0000000..d772f01 --- /dev/null +++ b/server/masterserver/jsondatamgr.h @@ -0,0 +1,21 @@ +#pragma once + +class JsonDataMgr : public a8::Singleton +{ + private: + JsonDataMgr() {}; + friend class a8::Singleton; + + public: + void Init(); + void UnInit(); + + std::shared_ptr GetConf(); + + std::string ip; + int listen_port = 0; + + private: + std::string work_path_ = "../config"; + a8::XObject masterserver_cluster_json_; +}; diff --git a/server/masterserver/main.cc b/server/masterserver/main.cc new file mode 100644 index 0000000..7dffbf1 --- /dev/null +++ b/server/masterserver/main.cc @@ -0,0 +1,11 @@ +#include "precompile.h" +#include "app.h" + +int main(int argc, char* argv[]) +{ + int exitcode = 0; + App::Instance()->Init(argc, argv); + exitcode = App::Instance()->Run(); + App::Instance()->UnInit(); + return exitcode; +} diff --git a/server/masterserver/precompile.h b/server/masterserver/precompile.h new file mode 100644 index 0000000..49c2658 --- /dev/null +++ b/server/masterserver/precompile.h @@ -0,0 +1,21 @@ +#pragma once + +#include +#include + +#include "constant.h" +#include "types.h" +#include "error_code.h" +#include "global.h" + +namespace google +{ + namespace protobuf + { + class Message; + } +} + +#include "framework/cpp/types.h" +#include "framework/cpp/protoutils.h" + diff --git a/server/masterserver/types.cc b/server/masterserver/types.cc new file mode 100644 index 0000000..981bc36 --- /dev/null +++ b/server/masterserver/types.cc @@ -0,0 +1,3 @@ +#include "precompile.h" + + diff --git a/server/masterserver/types.h b/server/masterserver/types.h new file mode 100755 index 0000000..1467ba7 --- /dev/null +++ b/server/masterserver/types.h @@ -0,0 +1,10 @@ +#pragma once + +struct PerfMonitor +{ + int max_run_delay_time = 0; + int max_timer_idle = 0; + long long out_data_size = 0; + long long in_data_size = 0; + long long read_count = 0; +}; diff --git a/server/tools/protobuild/ss_msgid.proto b/server/tools/protobuild/ss_msgid.proto new file mode 100644 index 0000000..0595eb5 --- /dev/null +++ b/server/tools/protobuild/ss_msgid.proto @@ -0,0 +1,14 @@ +package ss; + +//消息id定义 +enum SSMessageId_e +{ + _SS_Ping = 8; + _SS_Pong = 9; + + _SS_WSP_SocketDisconnect = 10; + _SS_WSP_RequestTargetServer = 11; + _SS_MS_ResponseTargetServer = 12; + _SS_ForceCloseSocket = 13; + +} diff --git a/server/tools/protobuild/ss_proto.proto b/server/tools/protobuild/ss_proto.proto new file mode 100755 index 0000000..be04905 --- /dev/null +++ b/server/tools/protobuild/ss_proto.proto @@ -0,0 +1,35 @@ +package ss; + +message SS_Ping +{ + +} + +message SS_Pong +{ + +} + +message SS_WSP_SocketDisconnect +{ +} + +message SS_WSP_RequestTargetServer +{ + optional int64 context_id = 1; + optional string account_id = 2; + optional string team_id = 3; +} + +message SS_MS_ResponseTargetServer +{ + optional int32 error_code = 1; + optional string error_msg = 2; + optional int64 context_id = 3; + optional string host = 4; + optional int32 port = 5; +} + +message SS_ForceCloseSocket +{ +} diff --git a/sql/relationdb_n.sql b/sql/relationdb_n.sql new file mode 100644 index 0000000..583d5f1 --- /dev/null +++ b/sql/relationdb_n.sql @@ -0,0 +1,41 @@ +-- MySQL dump 10.14 Distrib 5.5.41-MariaDB, for Linux (x86_64) +-- +-- Host: localhost Database: relationdb +-- ------------------------------------------------------ +-- Server version 5.5.41-MariaDB + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!40101 SET NAMES utf8 */; +/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; +/*!40103 SET TIME_ZONE='+00:00' */; +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; +/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; + +-- +-- Table structure for table `version` +-- + +DROP TABLE IF EXISTS `version`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8 */; +CREATE TABLE `version` ( + `idx` int(11) NOT NULL AUTO_INCREMENT COMMENT '自增id', + `version` int(11) NOT NULL DEFAULT '0' COMMENT '版本号', + PRIMARY KEY (`idx`), + UNIQUE KEY `version` (`version`) +) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=utf8 COLLATE=utf8_bin; +/*!40101 SET character_set_client = @saved_cs_client */; + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; +/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; + +-- Dump completed on 2015-08-19 18:52:06