From 926afc27334dbd835d5ea4552e69f56dd27eded4 Mon Sep 17 00:00:00 2001 From: aozhiwei Date: Thu, 28 May 2020 17:11:09 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=90=8C=E6=AD=A5bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/gameserver/bullet.cc | 6 ++ server/gameserver/gridservice.cc | 16 ++++- server/gameserver/human.cc | 101 +++++++++++++++++++++++--- server/gameserver/human.h | 6 +- server/gameserver/player.cc | 3 + server/gameserver/room.cc | 117 ++++++++++++++++++++++++++++++- server/gameserver/room.h | 5 ++ 7 files changed, 240 insertions(+), 14 deletions(-) diff --git a/server/gameserver/bullet.cc b/server/gameserver/bullet.cc index 6a21824..a0c1296 100644 --- a/server/gameserver/bullet.cc +++ b/server/gameserver/bullet.cc @@ -27,7 +27,13 @@ void Bullet::Initialize() void Bullet::Update(int delta_time) { + #ifdef DEBUG + player->room->CheckPartObjects(); + #endif MapServiceUpdate(); + #ifdef DEBUG + player->room->CheckPartObjects(); + #endif ++updated_times_; } diff --git a/server/gameserver/gridservice.cc b/server/gameserver/gridservice.cc index c40db9e..71b8ba6 100644 --- a/server/gameserver/gridservice.cc +++ b/server/gameserver/gridservice.cc @@ -280,8 +280,20 @@ bool GridService::InView(int a_grid, int b_grid) bool GridService::InView(int grid_id, float x, float y) { - int b_grid_id = grid_id = x/cell_width_ + (y/cell_width_) * cell_count_per_row_; - return InView(grid_id, b_grid_id); + int b_grid_id = x/cell_width_ + (y/cell_width_) * cell_count_per_row_; + bool in_view = InView(grid_id, b_grid_id); +#ifdef DEBUG + if (in_view) { + a8::UdpLog::Instance()->Debug("InView %d %d %f %f", + { + grid_id, + b_grid_id, + x, + y + }); + } +#endif + return in_view; } void GridService::GetGridList(int grid_id, int offset, diff --git a/server/gameserver/human.cc b/server/gameserver/human.cc index f16da22..8f8512a 100644 --- a/server/gameserver/human.cc +++ b/server/gameserver/human.cc @@ -665,9 +665,36 @@ void Human::SyncAroundPlayers(const char* file, int line, const char* func) if (a8::HasBitFlag(status, HS_Disable)) { return; } + #ifdef DEBUG + room->CheckPartObjects(); + a8::UdpLog::Instance()->Debug("syncaround begin %s %d %s", + { + file, + line, + func + }); + #endif for (auto& cell : grid_list) { for (Human* hum : cell->human_list[room->room_idx]) { hum->AddToNewObjects(this); +#ifdef DEBUG + { + std::string objs_str; + for (auto& obj : hum->part_objects) { + objs_str += a8::Format("%d ", {(long long)obj}); + } + a8::UdpLog::Instance()->Debug("hum1 %d %s", {(long long)hum, objs_str}); + } + { + std::string objs_str; + for (auto& obj : part_objects) { + objs_str += a8::Format("%d ", {(long long)obj}); + } + a8::UdpLog::Instance()->Debug("hum2 %d %s", {(long long)this, objs_str}); + } + room->CheckPartObjects(hum, this); + bool ok = hum->InPartObjects(this); +#endif assert(hum->part_objects.find(this) != hum->part_objects.end()); if (hum->part_objects.find(this) == hum->part_objects.end()) { if (a8::XGetTickCount() - room->last_debugout_tick > 1000 * 10) { @@ -682,6 +709,15 @@ void Human::SyncAroundPlayers(const char* file, int line, const char* func) } } } + #ifdef DEBUG + room->CheckPartObjects(); + a8::UdpLog::Instance()->Debug("syncaround end %s %d %s", + { + file, + line, + func + }); + #endif } void Human::AutoLoadingBullet(bool manual) @@ -813,6 +849,9 @@ void Human::FillSMGameOver(cs::SMGameOver& msg) void Human::BeKill(int killer_id, const std::string& killer_name, int weapon_id) { + #ifdef DEBUG + room->CheckPartObjects(); + #endif if (!dead && !room->game_over && !real_dead) { lethal_weapon = weapon_id; Entity* hum = room->GetEntityByUniId(killer_id); @@ -900,6 +939,9 @@ void Human::BeKill(int killer_id, const std::string& killer_name, int weapon_id) RemoveBuffByEffectId(kBET_Camouflage); } ClearLordMode(); +#ifdef DEBUG + room->CheckPartObjects(); +#endif int max_revive_times = MetaMgr::Instance()->GetSysParamAsInt("max_revive_times", 1); if (weapon_id != VW_Spectate && dead_times <= max_revive_times && @@ -1004,6 +1046,16 @@ void Human::ClearPartObjects() part_objects.clear(); } +int Human::GetPartObjectsCount() +{ + return part_objects.size(); +} + +bool Human::InPartObjects(Human* target) +{ + return part_objects.find(target) != part_objects.end(); +} + void Human::RemoveObjects(Entity* entity) { del_objects.insert(entity->entity_uniid); @@ -1286,6 +1338,13 @@ void Human::OnGridListChange(std::set& old_grid_list, if (!room->grid_service->HumanInGridList(hum, grid_list)) { AddOutObjects(hum); hum->AddOutObjects(this); + #ifdef DEBUG + a8::UdpLog::Instance()->Debug("addoutobjects %d %d", + { + (long long)hum, + hum->entity_uniid + }); + #endif } } for (Entity* entity : cell->entity_list[0]) { @@ -2014,19 +2073,35 @@ void Human::ClearFrameData() new_objects.clear(); } if (!del_objects.empty()) { - for (auto& itr : del_objects) { - Entity* entity = room->GetEntityByUniId(itr); - if (entity) { - RemovePartObjects(entity); + if (!a8::HasBitFlag(status, HS_Disable)) { + for (auto& itr : del_objects) { + Entity* entity = room->GetEntityByUniId(itr); + if (entity) { + RemovePartObjects(entity); + if (entity->entity_type == ET_Player) { + ((Human*)entity)->RemovePartObjects(this); + } +#ifdef DEBUG + room->CheckPartObjects(); +#endif + } } } del_objects.clear(); } if (!out_objects.empty()) { - for (auto& itr : out_objects) { - Entity* entity = room->GetEntityByUniId(itr); - if (entity) { - RemovePartObjects(entity); + if (!a8::HasBitFlag(status, HS_Disable)) { + for (auto& itr : out_objects) { + Entity* entity = room->GetEntityByUniId(itr); + if (entity) { + RemovePartObjects(entity); + if (entity->entity_type == ET_Player) { + ((Human*)entity)->RemovePartObjects(this); + } + } +#ifdef DEBUG + room->CheckPartObjects(); +#endif } } out_objects.clear(); @@ -3287,3 +3362,13 @@ void Human::AdjustDecHp(float old_health, float& new_health) } } } + +void Human::OnEnable() +{ +} + +void Human::OnDisable() +{ + ClearFrameData(); + ClearPartObjects(); +} diff --git a/server/gameserver/human.h b/server/gameserver/human.h index dda3111..b970b02 100644 --- a/server/gameserver/human.h +++ b/server/gameserver/human.h @@ -178,7 +178,8 @@ class Human : public MoveableEntity void AddToNewObjects(Entity* entity); void AddToPartObjects(Entity* entity); void RemovePartObjects(Entity* entity); - void ClearPartObjects(); + bool InPartObjects(Human* target); + int GetPartObjectsCount(); void RemoveObjects(Entity* entity); void AddOutObjects(Entity* entity); void RemoveOutObjects(Entity* entity); @@ -258,6 +259,8 @@ class Human : public MoveableEntity bool IsAndroid(); void DropItems(Obstacle* obstacle); void ProcNewBieLogic(); + void OnEnable(); + void OnDisable(); protected: void _UpdateMove(int speed); @@ -283,6 +286,7 @@ private: void Revive(); void ClearLordMode(); void AdjustDecHp(float old_health, float& new_health); + void ClearPartObjects(); protected: long long last_shot_frameno_ = 0; diff --git a/server/gameserver/player.cc b/server/gameserver/player.cc index e7335f0..4f2eaf5 100644 --- a/server/gameserver/player.cc +++ b/server/gameserver/player.cc @@ -147,6 +147,9 @@ void Player::UpdateMove() tank_oil_value -= old_pos.Distance(GetPos()) * (MetaMgr::Instance()->average_oil / 100.0f); tank_oil_value = std::max(0.0f, tank_oil_value); } + #ifdef DEBUG + room->CheckPartObjects(); + #endif } void Player::UpdateShot() diff --git a/server/gameserver/room.cc b/server/gameserver/room.cc index 6b367e1..99e8c28 100644 --- a/server/gameserver/room.cc +++ b/server/gameserver/room.cc @@ -90,11 +90,17 @@ void Room::UnInit() void Room::Update(int delta_time) { +#ifdef DEBUG + run_in_timer_ = true; +#endif xtimer.Update(); if (game_over && frame_no - game_over_frameno > SERVER_FRAME_RATE * 20) { return; } +#ifdef DEBUG + run_in_timer_ = false; +#endif elapsed_time_ += delta_time; while (elapsed_time_ >= 50) { if (frame_no % 2 == 0) { @@ -1700,17 +1706,21 @@ void Room::SecondRandPoint() break; } } + #ifdef DEBUG + CheckPartObjects(); + #endif for (auto& pair : accountid_hash_) { if (room_type == RT_MidBrid) { pair.second->on_grid_chg = std::bind(&Room::OnHumanGridChg, this, std::placeholders::_1); } } + #ifdef DEBUG + CheckPartObjects(); + #endif } void Room::NotifyGameStart() { - ProcDisableHuman(); - cs::SMGameStart msg; for (auto& pair : accountid_hash_) { pair.second->SendNotifyMsg(msg); @@ -1724,6 +1734,7 @@ void Room::NotifyGameStart() [] (const a8::XParams& param) { Room* room = (Room*)param.sender.GetUserData(); + room->ProcDisableHuman(); room->SecondRandPoint(); }, &xtimer_attacher_.timer_list_); @@ -1794,8 +1805,22 @@ long long Room::GetGasInactiveTime() void Room::EnableHuman(Human* target) { +#ifdef DEBUG + if (!run_in_timer_) { + abort(); + } +#endif + #ifdef DEBUG + CheckPartObjects(); + a8::UdpLog::Instance()->Debug("enablehuman %d %d", + { + (long long)target, + target->entity_uniid + }); + #endif if (a8::HasBitFlag(target->status, HS_Disable)) { a8::UnSetBitFlag(target->status, HS_Disable); + target->OnEnable(); target->enable_frameno = frame_no; moveable_hash_[target->entity_uniid] = target; grid_service->AddHuman(target); @@ -1805,10 +1830,26 @@ void Room::EnableHuman(Human* target) alive_human_hash_[target->entity_uniid] = target; } } + #ifdef DEBUG + CheckPartObjects(); + #endif } void Room::DisableHuman(Human* target) { +#ifdef DEBUG + if (!run_in_timer_) { + abort(); + } +#endif + #ifdef DEBUG + CheckPartObjects(); + a8::UdpLog::Instance()->Debug("disablehuman %d %d", + { + (long long)target, + target->entity_uniid + }); + #endif if (!a8::HasBitFlag(target->status, HS_Disable)) { a8::SetBitFlag(target->status, HS_Disable); moveable_hash_.erase(target->entity_uniid); @@ -1829,8 +1870,11 @@ void Room::DisableHuman(Human* target) for (auto& pair : human_hash_) { pair.second->RemovePartObjects(target); } - target->ClearPartObjects(); + target->OnDisable(); } + #ifdef DEBUG + CheckPartObjects(); + #endif } void Room::ShuaNewBieAndroid(Human* target) @@ -2242,6 +2286,26 @@ void Room::ProcDisableHuman() void Room::OnHumanGridChg(Human* target) { + xtimer.AddDeadLineTimerAndAttach(2, + a8::XParams() + .SetSender(target), + [] (const a8::XParams& param) + { + Human* hum = (Human*)param.sender.GetUserData(); + hum->room->ShuaGridRound(hum); + }, + &target->xtimer_attacher.timer_list_); +} + +void Room::ShuaGridRound(Human* target) +{ + #ifdef DEBUG + static bool shua_ed = false; + if (shua_ed) { + //return; + } + shua_ed = true; + #endif int count = 0; for (auto& pair : human_hash_) { Human* hum = pair.second; @@ -2258,4 +2322,51 @@ void Room::OnHumanGridChg(Human* target) #ifdef DEBUG a8::UdpLog::Instance()->Debug("OnHumanGrid %d %d", {target->grid_id, count}); #endif + #ifdef DEBUG + CheckPartObjects(); + #endif +} + +void Room::CheckPartObjects(Human* testa, Human* testb) +{ + for (auto& pair1 : human_hash_) { + Human* a = pair1.second; + for (auto& pair2 : human_hash_) { + Human* b = pair2.second; + if (testa && testb) { + if ((a == testa && b == testb) || + (a == testb && b == testa)) { + int i = 0; + } + } + if (a->InPartObjects(b)) { + if (!b->InPartObjects(a)) { + abort(); + } + } + } + } + + for (auto& pair1 : human_hash_) { + Human* huma = pair1.second; + for (auto& cell : huma->grid_list) { + for (Human* humb : cell->human_list[room_idx]) { + if (testa && testb) { + if ((huma == testa && humb == testb) || + (huma == testb && humb == testa)) { + int i = 0; + } + } + if (a8::HasBitFlag(huma->status, HS_Disable) || + a8::HasBitFlag(humb->status, HS_Disable) || + huma->GetPartObjectsCount() <= 0 + ) { + continue; + } + if (!huma->InPartObjects(humb)) { + abort(); + } + } + } + } } diff --git a/server/gameserver/room.h b/server/gameserver/room.h index 4d32696..1b0c3ce 100644 --- a/server/gameserver/room.h +++ b/server/gameserver/room.h @@ -122,6 +122,7 @@ public: long long GetGasInactiveTime(); void ShuaNewBieAndroid(Human* target); void InitAirDrop(); + void CheckPartObjects(Human* testa = nullptr, Human* testb = nullptr); private: int AllocUniid(); @@ -167,6 +168,7 @@ private: bool HasPlayerInRound(const a8::Vec2& pos, float rad); void ProcDisableHuman(); void OnHumanGridChg(Human* target); + void ShuaGridRound(Human* target); private: int elapsed_time_ = 0; @@ -194,4 +196,7 @@ private: std::map removed_robot_hash_; std::vector obstacle_datas_; +#ifdef DEBUG + bool run_in_timer_ = false; +#endif };