int check_msg_common(svr_proto_t* pkg, uint32_t bodylen, fdsession_t* fdsess) { struct report_msg_common { uint32_t gameid; uint32_t userid; uint32_t recvid; uint32_t onlineid; uint32_t timestamp; uint32_t msglen; char msg[]; }__attribute__((packed)); if (bodylen <= sizeof(report_msg_common)) { KERROR_LOG(pkg->id, "invalid len\t[%u]", bodylen); return 0; } report_msg_common* pmsg = (report_msg_common *)pkg->body; if (pmsg->msglen + sizeof(report_msg_common) != bodylen) { KERROR_LOG(pkg->id, "invalid len\t[%u %u %lu]", bodylen, pmsg->msglen, sizeof(report_msg_common)); return 0; } if (pmsg->recvid > 50000) { KDEBUG_LOG(pkg->id, "no public chat\t[%u]", pmsg->recvid); return 0; } //pmsg->msg[pmsg->msglen] = 0; //segment(pmsg->msg, pmsg->msglen); std::map<uint32_t, CChatCheck*>::iterator it = game_chat_check.find(pmsg->gameid); if (it == game_chat_check.end()){ ERROR_LOG("invalid gameid\t[%u]", pmsg->gameid); return 0; } CChatCheck* pcheck = it->second; if (pcheck->chat_forbid.is_forbidden(pkg->id)) { KDEBUG_LOG(pkg->id, "has forbidden in 5 min"); return 0; } if (!pcheck->check_msg(pkg->id, pmsg->timestamp, pmsg->msg, pmsg->msglen)) { //pcheck->chat_forbid.send_pkg_forbid_user(pmsg->userid); uint32_t addtime = pcheck->chat_forbid.add_forbid_user(pkg->id); KDEBUG_LOG(pkg->id, "AAAAAAA\t[%u]", addtime); if (addtime) { ADD_ONLINE_TIMER(&g_events, n_chat_forbid_pop, pcheck, addtime); } } return 0; }
int onli_challenge_battle_callback(sprite_t* initor, uint32_t rcverid, const uint8_t* buf, int len, uint32_t ret) { userid_t challengee = *(uint32_t*)initor->session; //uint32_t btid=*(uint32_t*)(initor->session+8); if (ret) { KERROR_LOG(rcverid, "challengee not online\t[%u]", challengee); // cancle challenge // send error message to client if (initor->btr_info) { batrserv_cancel_battle(initor); return 0; } return send_to_self_error(initor, initor->waitcmd, cli_err_user_offline, 1); } KDEBUG_LOG(rcverid, "ONLINE CHALLENGE BATTLE CALLBACK \t[offline=%d challegee=%u]", ret,challengee); notify_self_team_challenging(initor, challengee); if (initor->pk_switch_is_on()) { response_proto_uint32(initor, initor->waitcmd, 3, 1, 0); } else { response_proto_uint32(initor, initor->waitcmd, 1, 1, 0); } return 0; }
int kick_user_op(sprite_t* initor, uint32_t rcverid, const uint8_t* buf, int len, int ret) { CHECK_BODY_LEN(len, 8); if (ret != 0) { KERROR_LOG (0, "invalid ret when kick user: [ret = %d]", ret); return ret; } int i = 0; uint32_t uid; UNPKG_H_UINT32(buf, uid, i); sprite_t* p = get_sprite(uid); // multiple login if (p) { KDEBUG_LOG(uid, "relogin other"); // send multiple login notification send_to_self_error(p, proto_cli_login, cli_err_login_from_other, 0); // kick the previous login instance offline del_sprite(p, 1); } return 0; }
inline int dispatcher(void* data, fdsession_t* fdsess) { char version[256] = {0}; home_proto_t* proto = data; if(proto->cmd == proto_get_version) { proto = (home_proto_t*)version; proto->len = 256; strncpy((char*)proto->body,g_version,200); return send_pkg_to_client(fdsess, proto, 256); } if (proto->onlineid > MAX_ONLINE_NUM) { KERROR_LOG(proto->id,"invaild onlineid=%u", proto->onlineid); return -1; } if ((proto->opid <= proto_begin) || (proto->opid >= proto_max)) { KERROR_LOG(proto->id, "invalid opid [len=%u cmd=%u onineid=%u homeid=%u opid=%u]",proto->len,proto->cmd,proto->onlineid,(uint32_t)proto->homeid,proto->opid); return -1; } all_fds[proto->onlineid] = fdsess; switch(proto->opid) { case proto_join_group: return join_hero_cup_op(proto); case proto_cancel_group: return cancel_hero_cup_op(proto); case proto_enter_home: return proto_enter_home_op(proto); } home_t* p_home = g_hash_table_lookup(all_home, &proto->homeid); if (!p_home) { KDEBUG_LOG(proto->id,"MAP NOT EXSIT[onlineid=%u mapid=(%x,%u) opid=%u]",proto->onlineid,HI32(proto->homeid),LO32(proto->homeid),proto->opid); return 0; } sprite_ol_t* p = g_hash_table_lookup(p_home->sprites, &proto->id); if(!p) { KDEBUG_LOG(proto->id,"PLAYER NOT EXSIT[onlineid=%u mapid=(%x,%u) opid=%u]",proto->onlineid,HI32(proto->homeid),LO32(proto->homeid),proto->opid); return 0; } return handle_online_op(p_home, p, proto); }
int get_pkg_len(int fd, const void* avail_data, int avail_len, int isparent) { static char request[] = "<policy-file-request/>"; static char response[] = "<?xml version=\"1.0\"?>" "<!DOCTYPE cross-domain-policy>" "<cross-domain-policy>" "<allow-access-from domain=\"*\" to-ports=\"*\" />" "</cross-domain-policy>"; if (avail_len < 4) { return 0; } //DEBUG_LOG("avail_data"); uint32_t len = 0; if (isparent) { // the client requests for a socket policy file if ((avail_len == sizeof(request)) && !memcmp(avail_data, request, sizeof(request))) { net_send(fd, response, sizeof(response)); TRACE_LOG("Policy Req [%s] Received, Rsp [%s] Sent", request, response); return 0; } const protocol_t* pkg = (const protocol_t *)avail_data; len = ntohl(pkg->len); if ((len > cli_proto_max_len) || (len < sizeof(protocol_t))) { KERROR_LOG(0, "[p] invalid len=%d from fd=%d", len, fd); return -1; } } else { len = *(uint32_t*)avail_data; if ((len > db_proto_max_len) || (len < sizeof(db_proto_t))) { KERROR_LOG(0, "[c] invalid len=%d from fd=%d", len, fd); return -1; } } return len; }
int reconnect_service_timely(void* owner, void* data) { KERROR_LOG(0 ,"reconnect_service timely"); Service* service = (Service *)data; if (service->connect() != 0) { ADD_TIMER_EVENT_EX(&g_reconnect_timer, kTimerTypeReconnectServiceTimely, service, get_now_tv()->tv_sec + kTimerIntervalReconnectServiceTimely); } return 0; }
int get_pkg_len(int fd, const void* avail_data, int avail_len, int isparent) { if (avail_len < 4) { return 0; } home_proto_t *pkg = (home_proto_t*)avail_data; if(pkg->len > proto_max_len || pkg->len < sizeof(home_proto_t)) { KERROR_LOG(pkg->id,"invalid len=%u from online(%u):%d",pkg->len,pkg->onlineid,fd); return -1; } return pkg->len; }
Battle* BattleManager::alloc_battle(room_t* room) { Battle* battle = new Battle(room); if (battle == NULL) { KERROR_LOG(0, "out of memory"); return NULL; } battle_list_[battle_idx_] = battle; battle->set_battleid(battle_idx_); battle_idx_++; return battle; }
void check_one_atk_info_by_mp(warrior_t* p, atk_info_t* aai, int& res_mp) { skill_mp_exp_t* psu = get_skill_mp_exp(aai->atk_type, p->prof); if (!psu || !psu->id || aai->confrm_decre_mp != confrm_decre_mp_no_need) return; res_mp -= (psu->mp_a * aai->atk_level + psu->mp_b); if (res_mp < 0){ KERROR_LOG(p->userid, "mp not enough\t[atk_type=%u atk_level=%u]", aai->atk_type, aai->atk_level); if (IS_BEAST_ID(p->userid)){ aai->atk_type = skill_pa_pet_base_fight; if (!aai->atk_mark){ aai->atk_mark = 1; aai->atk_pos = get_rand_alive_warrior_pos(p->enemy_team,p->pet_state); } } else { aai->atk_type = IS_BEAST(p)?skill_pa_pet_dai_ji:skill_pd_fangyu; } aai->atk_level = 1; } }
int check_msg(svr_proto_t* pkg, uint32_t bodylen, fdsession_t* fdsess) { struct report_msg { uint32_t gameid; uint32_t userid; uint32_t recvid; uint32_t onlineid; uint32_t maptype; uint32_t mapid; uint32_t timestamp; uint32_t msglen; char msg[]; }__attribute__((packed)); if (bodylen <= sizeof(report_msg)) { KERROR_LOG(pkg->id, "invalid len\t[%u]", bodylen); return 0; } report_msg* pmsg = (report_msg *)pkg->body; if (pmsg->msglen + sizeof(report_msg) != bodylen) { KERROR_LOG(pkg->id, "invalid len\t[%u %u]", bodylen, pmsg->msglen); return 0; } if (pmsg->recvid > 50000) { KDEBUG_LOG(pmsg->userid, "no public chat\t[%u]", pmsg->recvid); return 0; } std::map<uint32_t, CChatCheck*>::iterator it = game_chat_check.find(pmsg->gameid); if (it == game_chat_check.end()){ ERROR_LOG("invalid gameid\t[%u]", pmsg->gameid); return 0; } CChatCheck* pcheck = it->second; if (pcheck->chat_forbid.is_forbidden(pmsg->userid)) { KDEBUG_LOG(pmsg->userid, "has forbidden in 5 min"); return 0; } bool check_ret = pcheck->check_msg(pmsg->userid, pmsg->timestamp, pmsg->msg, pmsg->msglen); if (!check_ret) { pcheck->chat_forbid.send_pkg_forbid_user(pmsg->userid); uint32_t addtime = pcheck->chat_forbid.add_forbid_user(pmsg->userid); if (addtime) { KDEBUG_LOG(pmsg->userid, "AAAAAAA\t[%u]", addtime); ADD_ONLINE_TIMER(&g_events, n_chat_forbid_pop, pcheck, addtime); } } char buff[4096]; int len = pmsg->msglen >= 4096 ? 4095 : pmsg->msglen; memcpy(buff, pmsg->msg, len); buff[len] = '\0'; KINFO_LOG(pmsg->userid, " %u %s %d", pmsg->timestamp, buff, (int)(!check_ret)); return 0; }
//检查攻击的合法性 void check_user_step_attack_and_insert_atk_list(battle_info_t* abi, warrior_t* p, atk_info_t* pai) { KDEBUG_LOG(p->userid,"check_user_step_attack_and_insert_atk_list:skill=%u pos=%u",pai->atk_type,pai->atk_pos); pai->atk_speed = p->speed; if (pai->atk_type != skill_pet_break_off && pai->atk_type != skill_user_break_off && CANNOT_ATTACK(p)) { clear_warrior_atkinfo(abi, p); return; } //KDEBUG_LOG(p->userid,"add pai->atk_type:%u %u %u",WARRIOR_SHIHUA(p),WARRIOR_HUNSHUI(p),p->p_waor_state->check_state(hunshui_bit)); KDEBUG_LOG(p->userid,"check point(0):skill=%u pos=%u mark=%u",pai->atk_type,pai->atk_pos,pai->atk_mark); if(p->p_waor_state->state & yiwang) { for(int i=0;i<p->skills_forgot_cnt;i++) { if(p->skills_forgot[i] == pai->atk_type) { pai->atk_level = 1; pai->atk_type = IS_BEAST(p) ? skill_pa_pet_dai_ji : skill_pa_dai_ji; break; } } } else if(p->p_waor_state->state & hunluan) { if(rand() & 1) { pai->atk_level = 1; pai->atk_type = IS_BEAST(p) ? skill_pa_pet_base_fight : skill_pa_base_fight; if(rand() & 1) { pai->atk_mark = 0; pai->atk_pos = get_front_rand_alive_warrior_pos(p->self_team); } else { pai->atk_mark = 1; pai->atk_pos = get_front_rand_alive_warrior_pos(p->enemy_team); } DEBUG_LOG("ATK POS\t[%d]", pai->atk_pos); } } else if( WARRIOR_SHIHUA(p) || WARRIOR_HUNSHUI(p)) {//shihua:daiji pai->atk_level = 1; pai->atk_type = IS_BEAST(p) ? skill_pa_pet_dai_ji : skill_pa_dai_ji; } // check skill by weapon and prof KDEBUG_LOG(p->userid,"check point(1):skill=%u pos=%u mark=%u",pai->atk_type,pai->atk_pos,pai->atk_mark); check_skill_by_weapon_prof(p, pai); KDEBUG_LOG(p->userid,"check point(2):skill=%u pos=%u mark=%u",pai->atk_type,pai->atk_pos,pai->atk_mark); check_attack_type_by_mp(p, pai); //检查人物等级 TODO if((p->level/10+1)<pai->atk_level){ KERROR_LOG(p->userid, "level invalid\t[%u %u %u]", p->level, pai->atk_type, pai->atk_level); pai->atk_level = (p->level/10+1); } KDEBUG_LOG(p->userid,"check point(3):skill=%u pos=%u mark=%u",pai->atk_type,pai->atk_pos,pai->atk_mark); atk_info_t* ret_pai = check_sp_atk_func[pai->atk_type](abi, p, pai); KDEBUG_LOG(p->userid,"check point(4):skill=%u pos=%u mark=%u",pai->atk_type,pai->atk_pos,pai->atk_mark); if (ret_pai){ if (pai->atk_seq == 1){ //是第二招 //KDEBUG_LOG(p->userid,"speedddddd %u",p->type_id); if(!p->is_boss()){ pai->atk_speed /= 2; KDEBUG_LOG(p->userid,"speed half"); } } //插入到攻击列表 insert_atkinfo_to_list(abi, ret_pai); } }
//检查技能 void check_skill_by_weapon_prof(warrior_t* p, atk_info_t* pai) { //内部技能不检查 if (pai->atk_type == skill_rl_pet_jiushu_all_only_svr) return ; skill_attr_t* psa = get_skill_attr(pai->atk_type, p->weapon_type); //DEBUG_LOG("xxxxxxx %u %u %u",psa!=NULL,(psa!=NULL)?psa->id:0,psa->usr_type); if (!psa || !psa->id || (IS_BEAST(p) && pai->atk_type < skill_pet_begin) || (!IS_BEAST(p) && pai->atk_type > skill_pet_begin) || (p->petid && psa->usr_type != user_pet_beast)) { KERROR_LOG(p->userid, "skill invalid\t[%u %u %u]", p->petid, pai->atk_type, p->weapon_type); pai->atk_mark = 1; // enemy pai->atk_type = (IS_BEAST(p)) ? skill_pa_pet_dai_ji : skill_pa_dai_ji; pai->atk_level = 1; return; } // check skill by prof skill_mp_exp_t* pma = get_skill_mp_exp(pai->atk_type, p->prof); if (!pma || !pma->id){ KERROR_LOG(p->userid, "mp info invalid\t[petid=%u atk_type=%u prof=%u]", p->petid, pai->atk_type, p->prof); pai->atk_mark = 1; // enemy pai->atk_type = (IS_BEAST(p)) ? skill_pd_pet_fangyu : skill_pd_fangyu; pai->atk_level = 1; return; } // 检查是否需要盾牌 if ((psa->needshield == must_have_shield && !p->shield) || (psa->needshield == must_not_shield && p->shield)) { ERROR_LOG("shield invalid\t[uid=%u petid=%u atk_type=%u prof=%u]", p->userid, p->petid, pai->atk_type, p->prof); pai->atk_mark = 0; // enemy pai->atk_type = (IS_BEAST(p)) ? skill_pa_pet_dai_ji : skill_pa_dai_ji; pai->atk_level = 1; return; } // ren can only send skill + normal attack if (!IS_BEAST_ID(p->userid) && pai->atk_seq){//第二招 switch(p->atk_info[0].atk_type){ case skill_run_away: case skill_pa_base_fight: case skill_pd_fangyu: case skill_md_mokang: case skill_pd_huandun: case skill_pd_huiji: case skill_pd_pet_fangyu: case skill_md_pet_mokang: case skill_pd_pet_huandun: case skill_pd_pet_huiji: case skill_pa_pet_base_fight: case skill_pa_dai_ji: case skill_pa_pet_dai_ji: break; default: switch(pai->atk_type){ case skill_run_away: case skill_pa_base_fight: case skill_pd_fangyu: case skill_md_mokang: case skill_pd_huandun: case skill_pd_huiji: case skill_pd_pet_fangyu: case skill_md_pet_mokang: case skill_pd_pet_huandun: case skill_pd_pet_huiji: case skill_pa_pet_base_fight: case skill_pa_dai_ji: case skill_pa_pet_dai_ji: break; default: pai->atk_type = IS_BEAST(p)?skill_pa_pet_dai_ji:skill_pa_dai_ji; pai->atk_level = 1; break; } } } }