inline player_t *add_player(online_t *online, uint32_t uid, int32_t role_tm) { /* 自身数据 (无下级关系链, 以后有工会, 不过应该存储在 player_t 中的 online_player_copy) */ player_t *p = alloc_player(online, uid, role_tm); if (unlikely(!p)) { ERROR_TLOG("failed to alloc_player, u=%u, role_tm=%d, olid=%u", uid, role_tm, online->id); return 0; } /* 直接关系链 */ reg_player(p); return p; }
/* * Returns NULL if failing to allocate. * * If successful, then game->playerc is set to HT_PLAYERS_MAX. The * players are allocated and initialized according to player_init. * * You must still initialize the rest of the game after calling this * function (the players are only initialized because their player * indices correspond to the array in struct game, and then we may as * well fully initialize them). * * These variables are fully allocated, but not initialized: * * * game->rules * * * game->b */ struct game * alloc_game ( const unsigned short bwidth, const unsigned short bheight ) { unsigned short i; const unsigned short blen = (unsigned short)(bwidth * bheight); struct game * const g = malloc(sizeof(* g)); if (NULL == g) { return NULL; } g->rules = alloc_ruleset(bwidth, bheight); if (NULL == g->rules) { free (g); return NULL; } /* * This is set later and uses ruleset information. */ g->b = alloc_board(blen); if (NULL == g->b) { free_ruleset (g->rules); free (g); return NULL; } g->movehist = alloc_listmh(HT_LISTMH_CAP_DEF); if (NULL == g->movehist) { free_board (g->b); free_ruleset (g->rules); free (g); return NULL; } g->playerc = HT_PLAYERS_MAX; g->players = malloc(sizeof(* g->players) * (size_t)g->playerc); if (NULL == g->players) { free_listmh (g->movehist); free_board (g->b); free_ruleset (g->rules); free (g); return NULL; } for (i = (unsigned short)0; i < g->playerc; i++) { g->players[i] = alloc_player(); if (NULL == g->players[i] || !player_init(g->players[i], i)) { unsigned short j; for (j = (unsigned short)0; j <= i /* Check added for GCC's loop optimizations: */ && j <= HT_PLAYERS_MAX ; j++) { if (NULL != g->players[j]) { free_player(g->players[j]); } } free (g->players); free_listmh (g->movehist); free_board (g->b); free_ruleset (g->rules); free (g); return NULL; } } return g; }
int dispatch(void * data, fdsession_t * fdsess, bool cache_flag) { btlsw_proto_t * pkg = reinterpret_cast<btlsw_proto_t *>(data); uint32_t len = pkg->len; uint16_t cmd = pkg->cmd; uint32_t seq = pkg->seq; int fd = fdsess->fd; uint32_t uid = pkg->id; TRACE_TLOG("dispatch[%u] sender=%u, fd=%u, seq=%u, len=%u, cache_flag=%d", cmd, uid, fd, seq, len, cache_flag); c_online *p_online = get_online_by_fd(fd); if (cmd == btlsw_online_register_cmd) { if (p_online) { /* 注册时, 发现通过fd连过来的online, 重复发来注册的包 */ ERROR_TLOG("dup reg online, fd=%d, olip=0x%X, u=%u", fdsess->fd, fdsess->remote_ip, uid); return -1; } uint32_t online_id = *((uint32_t *)pkg->body); p_online = new c_online(fdsess, online_id); add_online(p_online); DEBUG_TLOG("reg_online, fd=%d, olip=0x%X, olid=%u", fdsess->fd, fdsess->remote_ip, online_id); return 0; } if (!p_online) { /* 到此, 无论是新注册, 还是注册后协议, * 都应该有 online 了, 找不到就是有问题 */ ERROR_TLOG("nofound p_online by fd=%d, olip=0x%X, cmd=%u, u=%u", fd, fdsess->remote_ip, cmd, uid); return -1; } c_player *p_player = p_online->get_player(uid); if (cmd == btlsw_player_enter_hall_cmd) { if (p_player) { DEBUG_TLOG("player re_enter_hall, lastinfo: u=%u, role_tm=%u, olid=%u", p_player->m_role_tm, p_player->m_server_id, p_player->m_server_id); destroy_player(p_player); p_player = NULL; } uint32_t online_id = *((uint32_t *)pkg->body); uint32_t role_tm = *((uint32_t *)(pkg->body + 4)); p_player = alloc_player(p_online, uid, online_id, role_tm); } if (!p_player) { ERROR_TLOG("nofound c_player, cmd=%u, u=%u, olid=%u", cmd, uid, p_online->m_id); return -1; } if (cache_flag && p_player->m_waitcmd) { if (g_queue_get_length(p_player->m_pkg_queue) < MAX_CACHE_PKG) { DEBUG_TLOG("cache a pkg u=%u, cmd=%u, wcmd=%u", p_player->m_id, cmd, p_player->m_waitcmd); cache_a_pkg(p_player, pkg, len); return 0; } else { WARN_TLOG("too many cache pkg, u=%u, cmd=%u, wcmd=%u", p_player->m_id, cmd, p_player->m_waitcmd); return 0; } } p_player->m_waitcmd = cmd; p_player->m_seq = seq; p_player->m_ret = 0; p_player->m_last_pkg_time = get_now_tv()->tv_sec; bind_proto_cmd_t * p_cmd = NULL; if (0 != find_btlsw_cmd_bind(cmd, &p_cmd)) { ERROR_TLOG("btl sw cmdid not existed: %u", cmd); return 0; } uint32_t body_len = len - sizeof(btlsw_proto_t); bool read_ret = p_cmd->p_in->read_from_buf_ex((char *)data + sizeof(btlsw_proto_t), body_len); if (!read_ret) { ERROR_TLOG("read_from_buf_ex error cmd=%u, u=%u", cmd, p_player->m_id); return -1; } int cmd_ret = p_cmd->func(p_player, p_cmd->p_in, p_cmd->p_out, NULL); return cmd_ret; }