void Gate::OnBindLogicAck(IKernel * kernel, s32 nodeType, s32 nodeId, const OArgs & args) { s64 actorId = args.GetDataInt64(0); s64 accountId = args.GetDataInt64(1); s32 errorCode = args.GetDataInt32(2); if (_actors.find(actorId) != _actors.end()) { OASSERT(_players.find(_actors[actorId]) != _players.end(), "wtf"); Player& player = _players[_actors[actorId]]; OASSERT(player.state == ST_BINDING && actorId == player.selectActorId, "wtf"); if (errorCode) { player.state = ST_ONLINE; player.lastActorId = actorId; ICacheDBContext * writer = _cacheDB->PrepareWrite("account", player.accountId); writer->WriteInt64("id", player.accountId); writer->WriteInt64("lastActor", actorId); writer->Update(); const s32 tokenCount = args.GetDataInt32(3); } else { Reset(kernel, _actors[actorId], ST_ROLELOADED, node_type::USER); olib::Buffer<128> buf; buf << _errorBindLogicFailed; SendToClient(kernel, _actors[actorId], _selectRoleAckId, buf.Out()); } } }
bool Redis::Initialize(IKernel * kernel) { s_self = this; s_kernel = kernel; olib::XmlReader reader; std::string coreConfigPath = std::string(tools::GetAppPath()) + "/config/server_conf.xml"; if (!reader.LoadXml(coreConfigPath.c_str())) { OASSERT(false, "can't find core file : %s", coreConfigPath.c_str()); return false; } s_sendBufferSize = reader.Root()["redis"][0].GetAttributeInt32("send"); s_recvBufferSize = reader.Root()["redis"][0].GetAttributeInt32("recv"); s_reconnectTick = reader.Root()["redis"][0].GetAttributeInt32("reconnect"); const olib::IXmlObject& units = reader.Root()["redis"][0]["unit"]; for (s32 i = 0; i < units.Count(); ++i) { const char * ip = units[i].GetAttributeString("ip"); s32 port = units[i].GetAttributeInt32("port"); RedisSession * session = NEW RedisSession; session->SetConnect(i, ip, port); s_kernel->Connect(ip, port, s_sendBufferSize, s_recvBufferSize, session); s_sessions.push_back(session); } s_scriptEngine = (IScriptEngine*)kernel->FindModule("ScriptEngine"); OASSERT(s_scriptEngine, "where is scriptEngine"); return true; }
void Gate::Reset(IKernel * kernel, s64 id, s8 state, s32 from) { OASSERT(state == ST_NONE || state == ST_ROLELOADED, "wtf"); Player& player = _players[id]; s8 old = player.state; if (old > ST_DISTRIBUTE) { OASSERT(player.logic > 0 && player.selectActorId != 0, "wtf"); IArgs<1, 32> args; args << player.selectActorId; args.Fix(); _harbor->Send(user_node_type::LOGIC, player.logic, framework_proto::UNBIND_PLAYER, args.Out()); _actors.erase(player.selectActorId); _logicPlayers[player.logic].erase(id); player.selectActorId = 0; player.logic = 0; } if (old > ST_NONE && state == ST_NONE) { IArgs<1, 32> args; args << player.agentId << player.accountId; args.Fix(); _harbor->Send(user_node_type::ACCOUNT, 1, framework_proto::UNBIND_ACCOUNT, args.Out()); player.accountId = 0; for (const auto& role : player.roles) { _roleMgr->Recover(role.role); } } player.state = state; }
ObjectDescriptor * ObjectMgr::CreateTemplate(IKernel * kernel, const char * name) { auto itr = _namePathMap.find(name); if (itr == _namePathMap.cend()) { OASSERT(false, "wtf"); return nullptr; } olib::XmlReader conf; if (!conf.LoadXml(itr->second.GetString())) { OASSERT(false, "prop xml file %s load file", itr->second.GetString()); return nullptr; } ObjectDescriptor * descriptor = nullptr; if (conf.Root().HasAttribute("parent")) { ObjectDescriptor * parent = QueryTemplate(kernel, conf.Root().GetAttributeString("parent")); OASSERT(parent, "where is parent %s xml", conf.Root().GetAttributeString("parent")); if (nullptr == parent) return nullptr; descriptor = NEW ObjectDescriptor(_nextTypeId++, name, parent); } else { descriptor = NEW ObjectDescriptor(_nextTypeId++, name, nullptr); } if (!descriptor->LoadFrom(conf.Root(), _defines)) { DEL descriptor; return nullptr; } _models[name] = descriptor; return _models[name]; }
s32 BindLooper(struct NetLooper * looper, struct NetBase * base) { OASSERT(base->looper == NULL, "already has a looper"); struct epoll_event ev; ev.data.ptr = base; switch (base->type) { case BNEV_ACCEPT: ev.events = EPOLLIN; break; case BNEV_CONNECT: ev.events = EPOLLOUT | EPOLLET; break; case BNEV_IO: ev.events = EPOLLIN | EPOLLOUT | EPOLLET; break; default: OASSERT(0, "wtf"); return -1; } ev.events |= EPOLLERR | EPOLLHUP; if (epoll_ctl(looper->fd, EPOLL_CTL_ADD, base->fd, &ev) != 0) { printf("epoll add fd error %d\n", errno); return -1; } base->looper = looper; return 0; }
void Gate::OnRecvKickFromLogic(IKernel * kernel, s32 nodeType, s32 nodeId, const OArgs & args) { s64 actorId = args.GetDataInt64(0); if (_actors.find(actorId) != _actors.end()) { OASSERT(_players.find(_actors[actorId]) != _players.end(), "wtf"); Player& player = _players[_actors[actorId]]; OASSERT(player.state == ST_ONLINE && player.logic == nodeId, "wtf"); Reset(kernel, _actors[actorId], ST_NONE, user_node_type::LOGIC); } }
const void * MMObject::Get(const IProp * prop, const s8 type, s32& size) const { const ObjectLayout * layout = ((ObjectProp*)prop)->GetLayout(_descriptor->GetTypeId()); OASSERT(layout, "wtf"); if (layout != nullptr) { OASSERT(layout->type == type && layout->size >= size, "wtf"); if (layout->type == type && layout->size >= size) { size = layout->size; return _memory->Get(layout); } } return nullptr; }
void Slave::StartNode(IKernel * kernel, const char * cmd) { char process[MAX_CMD_LEN]; #ifdef WIN32 SafeSprintf(process, sizeof(process), "%s/%s.exe", tools::GetAppPath(), EXECUTE_NAME); STARTUPINFO si = { sizeof(si) }; si.dwFlags = STARTF_USESHOWWINDOW; si.wShowWindow = TRUE; si.lpTitle = (char*)cmd; PROCESS_INFORMATION pi; BOOL ret = CreateProcess(process, (char*)cmd, nullptr, nullptr, false, CREATE_NEW_CONSOLE, nullptr, nullptr, &si, &pi); OASSERT(ret, "create process failed"); ::CloseHandle(pi.hThread); ::CloseHandle(pi.hProcess); #else SafeSprintf(process, sizeof(process), "%s/%s", tools::GetAppPath(), EXECUTE_NAME); char args[MAX_CMD_LEN]; SafeSprintf(args, sizeof(args), cmd); char * p[MAX_CMD_ARGS_COUNT]; SafeMemset(p, sizeof(p), 0, sizeof(p)); p[0] = EXECUTE_NAME; s32 idx = 1; char * checkPtr = args; char * innderPtr = nullptr; while ((p[idx] = strtok_r(checkPtr, " ", &innderPtr)) != nullptr) { ++idx; checkPtr = nullptr; } pid_t pid; pid = fork(); if (pid < 0) { OASSERT(false, "start process failed"); } else if (pid == 0) { pid = fork(); if (pid == 0) execv(process, p); else exit(0); } else { s32 status; waitpid(pid, &status, 0); } #endif }
bool MMObject::Set(const IProp * prop, const s8 type, const void * data, const s32 size, const bool sync) { const ObjectLayout * layout = ((ObjectProp*)prop)->GetLayout(_descriptor->GetTypeId()); OASSERT(layout, "wtf"); if (layout != nullptr) { OASSERT(layout->type == type && layout->size >= size, "wtf"); if (layout->type == type && layout->size >= size) { _memory->Set(layout, data, size); return true; } PropCall(prop, sync); } return false; }
void Cluster::NewNodeComming(IKernel * kernel, s32 nodeType, s32 nodeId, const void * context, const s32 size) { OASSERT(size == sizeof(node_proto::NewNode), "invalid node size"); node_proto::NewNode& info = *((node_proto::NewNode*)context); OASSERT(info.port > 0, "where is harbor port"); s64 check = ((s64)info.nodeType << 32) | ((s64)info.nodeId); if (s_openNode.find(check) != s_openNode.end()) return; if (info.nodeType == s_harbor->GetNodeType() && info.nodeId <= s_harbor->GetNodeId()) return; s_openNode.insert(check); s_harbor->Connect(info.ip, info.port); }
void ObjectMgr::Recove(IObject * object) { OASSERT(object, "wtf"); if (nullptr == object) return; auto itr = _objects.find(object->GetID()); if (itr == _objects.end()) { OASSERT(false, "where is this object %lld", object->GetID()); return; } OASSERT(itr->second.object == object, "wtf"); DEL object; _objects.erase(itr); }
void Harbor::Brocast(s32 nodeType, const s32 messageId, const OArgs& args) { for (auto itr = _nodes[nodeType].begin(); itr != _nodes[nodeType].end(); ++itr) { if (!itr->second->PrepareSendNodeMessage(args.GetSize() + sizeof(s32))) { OASSERT(false, "send failed"); } if (!itr->second->SendNodeMessage(&messageId, sizeof(s32))) { OASSERT(false, "send failed"); return; } if (!itr->second->SendNodeMessage(args.GetContext(), args.GetSize())) { OASSERT(false, "send failed"); } } }
void Connection::OnRecv() { if (_closing) return; char temp[SINGLE_RECV_SIZE]; u32 size = 0; char * buf = RingBufferReadTemp(_recvBuf, (char*)temp, sizeof(temp), &size); if (buf && size > 0) { s32 used = 0; s32 totalUsed = 0; do { used = _session->OnRecv(Kernel::Instance(), buf + totalUsed, size - totalUsed); if (used > 0) { OASSERT(totalUsed + used <= (s32)size, "wtf"); totalUsed += used; } } while (used > 0 && totalUsed < (s32)size); if (totalUsed > 0) RingBufferOut(_recvBuf, totalUsed); if (used < 0) Close(); } }
IObject * ObjectMgr::CreateObjectByID(const char * file, const s32 line, const char * name, const s64 id, bool shadow) { if (_objects.find(id) != _objects.end()) { OASSERT(false, "object id is exists"); return nullptr; } auto itr = _models.find(name); if (itr == _models.end()) { OASSERT(false, "what's this, %s", name); return nullptr; } MMObject * object = NEW MMObject(name, itr->second); _objects.insert(std::make_pair(id, ObjectCreateInfo({ object, file, line }))); return object; }
void Gate::OnRecvCreateRoleReq(IKernel * kernel, const s64 id, const OBuffer& buf) { OASSERT(_players.find(id) != _players.end(), "where is agent???"); Player& player = _players[id]; if (player.state == ST_ROLELOADED) { if (player.roles.size() >= _maxRole) { olib::Buffer<128> buf; buf << _errorTooMuchRole; SendToClient(kernel, id, _createRoleAckId, buf.Out()); return; } s64 actorId = _idMgr->AllocId(); IRole * role = _roleMgr->CreateRole(actorId, buf); if (role) { player.roles.push_back({ actorId, role }); olib::Buffer<128> buf; buf << _noError; role->Pack(buf); SendToClient(kernel, id, _createRoleAckId, buf.Out()); } else { olib::Buffer<128> buf; buf << _errorCreateRoleFailed; SendToClient(kernel, id, _createRoleAckId, buf.Out()); } } }
void Gate::OnUpdateRole(IKernel * kernel, s32 nodeType, s32 nodeId, const OArgs & args) { s64 actorId = args.GetDataInt64(0); if (_actors.find(actorId) != _actors.end()) { OASSERT(_players.find(_actors[actorId]) != _players.end(), "wtf"); Player& player = _players[_actors[actorId]]; OASSERT(player.state == ST_ONLINE && actorId == player.selectActorId && nodeId == player.logic, "wtf"); auto itr = std::find_if(player.roles.begin(), player.roles.end(), [actorId](const Role& role) { return role.actorId == actorId; }); OASSERT(itr != player.roles.end(), "wtf"); if (itr != player.roles.end()) itr->role->Update(args); } }
void Gate::OnRecvDistributeAck(IKernel * kernel, s32 nodeType, s32 nodeId, const OArgs & args) { s64 agentId = args.GetDataInt64(0); s64 actorId = args.GetDataInt64(1); s32 logic = args.GetDataInt32(2); if (_players.find(agentId) != _players.end()) { if (logic > 0) { Player& player = _players[agentId]; OASSERT(player.state == ST_DISTRIBUTE, "wtf"); player.selectActorId = actorId; player.logic = logic; player.state = ST_BINDING; _actors[actorId] = agentId; _logicPlayers[logic].insert(agentId); IArgs<2, 32> args; args << actorId << player.accountId; args.Fix(); _harbor->Send(user_node_type::LOGIC, logic, framework_proto::BIND_PLAYER, args.Out()); } else { Reset(kernel, agentId, ST_ROLELOADED, node_type::USER); olib::Buffer<128> buf; buf << _errorDistributeLogicFailed; SendToClient(kernel, agentId, _selectRoleAckId, buf.Out()); } } }
const IProp * ObjectMgr::CalcProp(const char * name) { auto itr = _props.find(name); OASSERT(itr != _props.end(), "wtf"); if (itr != _props.end()) return itr->second; return nullptr; }
bool Connection::CheckPipeBroke() { OASSERT(!_broken, "wtf"); _broken = true; if (!_closeing) _closeing = true; return _pushing; }
ITableControl * ObjectMgr::CreateStaticTable(const char * name, const char * model, const char * file, const s32 line) { if (_tableMap.find(tools::CalcStringUniqueId(name)) != _tableMap.end()) { OASSERT(false, "already hsa table %s", name); return nullptr; } auto itr = _tableModels.find(tools::CalcStringUniqueId(model)); OASSERT(itr != _tableModels.end(), "wtf"); if (itr == _tableModels.end()) return nullptr; TableControl * table = NEW TableControl(tools::CalcStringUniqueId(name), itr->second); TableCreateInfo info({ table, file, line }); _tableMap.insert(std::make_pair(tools::CalcStringUniqueId(name), info)); return table; }
void Gate::OnRecvDeleteRoleReq(IKernel * kernel, const s64 id, const OBuffer& buf) { s64 actorId = 0; if (!buf.Read(actorId)) return; OASSERT(_players.find(id) != _players.end(), "where is agent???"); Player& player = _players[id]; if (player.state == ST_ROLELOADED) { auto itr = std::find_if(player.roles.begin(), player.roles.end(), [actorId](const Role& role) { return role.actorId == actorId; }); if (itr != player.roles.end()) { if (_roleMgr->DeleteRole(itr->actorId, itr->role)) { player.roles.erase(itr); olib::Buffer<128> buf; buf << _noError << actorId; SendToClient(kernel, id, _deleteRoleAckId, buf.Out()); } else { olib::Buffer<128> buf; buf << _errorDeleteRoleFailed; SendToClient(kernel, id, _deleteRoleAckId, buf.Out()); } } } }
s32 ProtocolMgr::GetId(const char * group, const char * name) { auto itr = _protos[group].find(name); OASSERT(itr != _protos[group].end(), "wtf"); if (itr != _protos[group].end()) return itr->second; return 0; }
const char * ProtocolMgr::GetDesc(const char * group, const s32 id) { auto itr = _descs[group].find(id); OASSERT(itr != _descs[group].end(), "wtf"); if (itr != _descs[group].end()) return itr->second.GetString(); return ""; }
virtual bool Read(const char * format, ...) const { s32 count = lua_gettop(_state); s32 index = 1; const char * c = format; va_list ap; va_start(ap, format); while (*c != '\0') { if (index > count) { OASSERT(false, "param is not enough"); luaL_error(_state, "param is not enough %s", format); return false; } switch (*c) { case 'c': { s8 * val = va_arg(ap, s8*); *val = (s8)lua_tointeger(_state, index++); } break; case 'd': { s16 * val = va_arg(ap, s16*); *val = (s16)lua_tointeger(_state, index++); } break; case 'i': { s32 * val = va_arg(ap, s32*); *val = (s32)lua_tointeger(_state, index++); } break; case 'l': { s64 * val = va_arg(ap, s64*); *val = lua_tointeger(_state, index++); } break; case 'f': { float * val = va_arg(ap, float*); *val = lua_tonumber(_state, index++); } break; case 'b': { bool * val = va_arg(ap, bool*); *val = lua_toboolean(_state, index++); } break; case 's': { const char ** val = va_arg(ap, const char **); *val = lua_tostring(_state, index++); } break; case 'S': { const char ** val = va_arg(ap, const char **); s32* len = va_arg(ap, s32*); size_t size; *val = lua_tolstring(_state, index++, &size); *len = size; } break; } c++; } va_end(ap); return true; }
void Connection::Close() { OASSERT(!_closeing, "wtf"); if (!_closeing) { if (!_pushing) shutdown(_fd, SHUT_RDWR); _closeing = true; } }
void Harbor::Connect(const char * ip, const s32 port) { core::ISession * session = Create(); OASSERT(session != nullptr, "create session failed"); ((NodeSession*)session)->SetConnect(ip, port); s_kernel->Connect(ip, port, _sendBuffSize, _recvBuffSize, session); }
void Agent::Kick(const s64 id) { auto itr = s_sessions.find(id); if (itr == s_sessions.end()) { OASSERT(false, "where is agent %lld", id); return; } itr->second->Close(); }
void Agent::Send(const s64 id, const void * context, const s32 size) { auto itr = s_sessions.find(id); if (itr == s_sessions.end()) { OASSERT(false, "where is agent %lld", id); return; } itr->second->Send(context, size); }
bool Cluster::Launched(IKernel * kernel) { s_harbor = (IHarbor*)kernel->FindModule("Harbor"); OASSERT(s_harbor, "where is harbor"); s_harbor->Connect(_ip.c_str(), _port); REGPROTOCOL(node_proto::NEW_NODE, Cluster::NewNodeComming); return true; }
bool CapacitySubscriber::Launched(IKernel * kernel) { s_harbor = (IHarbor*)kernel->FindModule("Harbor"); OASSERT(s_harbor, "where is harbor"); s_harbor->AddNodeListener(this, "CapacitySubscriber"); REGPROTOCOL(core_proto::OVER_LOAD, CapacitySubscriber::ReadLoad); return true; }