//同步带client标记的属性给客户端 void CEntityParent::SyncClientProp(int32_t nPropId, const VOBJECT& v) { //获得当前entity的client fd static const string strClient = "client"; map<string, VOBJECT*>::iterator iter = m_data.find(strClient); if(iter != m_data.end()) { //当前已经有client了 world* pWorld = GetWorld(); lua_State* L = pWorld->GetLuaState(); ClearLuaStack(L); CLuaCallback& cb = pWorld->GetLuaTables(); int ref = (int)(iter->second->vv.i32); //LogDebug("CEntityParent::SyncClientProp", "m_id=%d;ref=%d", m_id, ref); cb.GetObj(L, ref); if(lua_istable(L, -1)) { lua_rawgeti(L, -1, g_nMailBoxServerIdKey); int fd = (int)lua_tointeger(L, -1); CMailBox* mb = pWorld->GetServer()->GetClientMailbox(fd); if(mb) { //LogDebug("CEntityParent::SyncClientProp", "m_id=%d;nPropId=%d;", m_id, nPropId); CPluto* u = new CPluto; (*u).Encode(MSGID_CLIENT_AVATAR_ATTRI_SYNC) << (uint16_t)nPropId; u->FillPluto(v); (*u) << EndPluto; mb->PushPluto(u); } } ClearLuaStack(L); } }
bool CLuaTimer< T1, T2 >::operator()() { lua_State* lua = GetWorld()->GetLuaState(); if (!lua) return false; CEntityParent* pEntity = GetWorld()->GetEntity(m_u32EntityID); if (!pEntity) return false; lua_pushnumber(lua, m_u64ActionID); lua_pushinteger(lua, m_u32ActionCount); _Lua_PushParam(lua, m_Param1); _Lua_PushParam(lua, m_Param2); const int nExtParamCount = 2; EntityMethodCall(lua, pEntity, m_strLuaFuncName.c_str(), 2 + nExtParamCount, 0); ClearLuaStack(lua); return true; }
int CEntityBase::GiveClient(lua_State* L, int fd) { static const string strClient = "client"; int old_fd = -1; ClearLuaStack(L); map<string, VOBJECT*>::iterator iter = m_data.lower_bound(strClient); if(iter != m_data.end() && iter->first == strClient) { CWorldBase& the_world = GetWorldbase(); CLuaCallback& cb = the_world.GetLuaTables(); int ref = (int)(iter->second->vv.i32); cb.GetObj(L, ref); LogDebug("CEntityBase::GiveClient", "m_id=%d;ref=%d", m_id, ref); if(lua_istable(L, -1)) { lua_rawgeti(L, -1, g_nMailBoxServerIdKey); old_fd = (int)lua_tointeger(L, -1); //printf("old_fd:%d,new_fd:%d\n", old_fd, fd); lua_pop(L, 1); lua_pushinteger(L, fd); lua_rawseti(L, -2, g_nMailBoxServerIdKey); } } else { //先用table,以后再改为userdata;table的话可以在lua里修改id,sid等几个值 NewClientMailbox(L, fd, m_etype, m_id); CLuaCallback& cb = GetWorld()->GetLuaTables(); int nRef = cb.Ref(L); LogDebug("CEntityBase::GiveClient", "m_id=%d;nRef=%d", m_id, nRef); VOBJECT* v = new VOBJECT; v->vt = V_LUATABLE; v->vv.i32 = nRef; m_data.insert(iter, make_pair("client", v) ); } this->SetClientFd(fd); m_bHasClient = true;//获得client标记 //通知客户端attach到entity,并刷所有带CLIENT标记的数据给客户端 CMailBox* mb = GetWorld()->GetServer()->GetClientMailbox(fd); if(mb) { CPluto* u = new CPluto; u->Encode(MSGID_CLIENT_ENTITY_ATTACHED); #ifdef __RELOGIN //客户端一旦登录,则先生成一个key值,用于断线重连时使用 const string& key = GetWorldbase().MakeClientReLoginKey("", m_id); s_clientReLoginKey = key; (*u) << key.c_str(); LogDebug("CEntityBase::GiveClient", "s_clientReLoginKey=%s;m_id=%d", s_clientReLoginKey.c_str(), m_id); #endif if(PickleClientToPluto(*u)) { (*u) << EndPluto; mb->PushPluto(u); //LogDebug("CEntityBase::GiveClient", "u->GetLen()=%d;", u->GetLen()); } else { delete u; } //如果有cell则通知cell同步数据 this->NotifyCellSyncClientAttris(); } //通知cell刷aoi数据给客户端 int nCellId = GetCellServerId(); if(nCellId > 0) { GetWorld()->RpcCall(nCellId, MSGID_CELLAPP_PICKLE_AOI_ENTITIES, m_id); } //通知脚本 { //clear_lua_stack(L); int _n = EntityMethodCall(L, this, "onClientGetBase", 0, 0); lua_pop(L, _n); } if(old_fd > 0 && old_fd != fd) { //关闭老的连接 GetWorldbase().KickOffFd(old_fd); } return 0; }