diff --git a/server/gameserver/bullet.cc b/server/gameserver/bullet.cc index 54d315d..d65a0a3 100644 --- a/server/gameserver/bullet.cc +++ b/server/gameserver/bullet.cc @@ -56,7 +56,7 @@ void Bullet::Update(int delta_time) if (!objects.empty()) { OnHit(objects); } - room->AddDeletedObject(entity_uniid); + room->AddDeletedObject(entity_uniid, true); } } } @@ -166,5 +166,5 @@ void Bullet::ProcBomb() } break; } - room->AddDeletedObject(entity_uniid); + room->AddDeletedObject(entity_uniid, true); } diff --git a/server/gameserver/framedata.h b/server/gameserver/framedata.h index 446242b..c179f04 100644 --- a/server/gameserver/framedata.h +++ b/server/gameserver/framedata.h @@ -4,12 +4,13 @@ struct RoomFrameData { - std::set deleted_objects; + std::map> deleted_objects_hash; + std::map> softdeleted_objects_hash; std::map> explosions_hash; std::map> smokes_hash; std::map> emotes_hash; - ::google::protobuf::RepeatedPtrField<::cs::MFBullet> bullets; - ::google::protobuf::RepeatedPtrField<::cs::MFShot> shots; + std::map> bullets_hash; + std::map> shots_hash; }; struct HumanFrameData diff --git a/server/gameserver/human.cc b/server/gameserver/human.cc index 2ae0958..ebd6440 100644 --- a/server/gameserver/human.cc +++ b/server/gameserver/human.cc @@ -118,14 +118,37 @@ void Human::Shot(Vector2D& target_dir) return; } { - cs::MFShot* shot = room->frame_data.shots.Add(); + ::google::protobuf::RepeatedPtrField<::cs::MFShot>* shots = nullptr; + { + { + auto itr = room->frame_data.shots_hash.find(room->frame_no); + if (itr == room->frame_data.shots_hash.end()) { + room->frame_data.shots_hash[room->frame_no] = ::google::protobuf::RepeatedPtrField<::cs::MFShot>(); + itr = room->frame_data.shots_hash.find(room->frame_no); + } + shots = &itr->second; + } + } + + cs::MFShot* shot = shots->Add(); shot->set_player_id(entity_uniid); curr_weapon->ToPB(shot->mutable_weapon()); shot->set_offhand(true); shot->set_bullskin(10001); } + ::google::protobuf::RepeatedPtrField<::cs::MFBullet>* bullets = nullptr; { - cs::MFBullet* bullet = room->frame_data.bullets.Add(); + { + auto itr = room->frame_data.bullets_hash.find(room->frame_no); + if (itr == room->frame_data.bullets_hash.end()) { + room->frame_data.bullets_hash[room->frame_no] = ::google::protobuf::RepeatedPtrField<::cs::MFBullet>(); + itr = room->frame_data.bullets_hash.find(room->frame_no); + } + bullets = &itr->second; + } + } + { + cs::MFBullet* bullet = bullets->Add(); bullet->set_player_id(entity_uniid); bullet->set_bullet_id(curr_weapon->meta->i->use_bullet()); pos.ToPB(bullet->mutable_pos()); diff --git a/server/gameserver/player.cc b/server/gameserver/player.cc index 7980b4b..de17591 100644 --- a/server/gameserver/player.cc +++ b/server/gameserver/player.cc @@ -307,7 +307,19 @@ void Player::Shot() } { - cs::MFShot* shot = room->frame_data.shots.Add(); + ::google::protobuf::RepeatedPtrField<::cs::MFShot>* shots = nullptr; + { + { + auto itr = room->frame_data.shots_hash.find(room->frame_no); + if (itr == room->frame_data.shots_hash.end()) { + room->frame_data.shots_hash[room->frame_no] = ::google::protobuf::RepeatedPtrField<::cs::MFShot>(); + itr = room->frame_data.shots_hash.find(room->frame_no); + } + shots = &itr->second; + } + } + + cs::MFShot* shot = shots->Add(); shot->set_player_id(entity_uniid); curr_weapon->ToPB(shot->mutable_weapon()); shot->set_offhand(true); @@ -317,8 +329,19 @@ void Player::Shot() Vector2D bullet_born_offset = Vector2D(std::get<0>(tuple), std::get<1>(tuple)); bullet_born_offset.Rotate(attack_dir.CalcAngle(Vector2D::UP)); Vector2D bullet_born_pos = pos + bullet_born_offset; + ::google::protobuf::RepeatedPtrField<::cs::MFBullet>* bullets = nullptr; { - cs::MFBullet* bullet = room->frame_data.bullets.Add(); + { + auto itr = room->frame_data.bullets_hash.find(room->frame_no); + if (itr == room->frame_data.bullets_hash.end()) { + room->frame_data.bullets_hash[room->frame_no] = ::google::protobuf::RepeatedPtrField<::cs::MFBullet>(); + itr = room->frame_data.bullets_hash.find(room->frame_no); + } + bullets = &itr->second; + } + } + { + cs::MFBullet* bullet = bullets->Add(); bullet->set_player_id(entity_uniid); bullet->set_bullet_id(curr_weapon->meta->i->use_bullet()); bullet_born_pos.ToPB(bullet->mutable_pos()); @@ -560,7 +583,7 @@ void Player::LootInteraction(Loot* entity) break; } entity->pickuped = true; - room->AddDeletedObject(entity->entity_uniid); + room->AddDeletedObject(entity->entity_uniid, false); } void Player::_CMMove(f8::MsgHdr& hdr, const cs::CMMove& msg) @@ -799,12 +822,28 @@ void Player::MakeUpdateMsg() update_msg->Clear(); { update_msg->set_ack(last_seq_id); - for (auto& obj_uniid : room->frame_data.deleted_objects) { - update_msg->add_del_objids(obj_uniid); - } - *update_msg->mutable_shots() = room->frame_data.shots; - *update_msg->mutable_bullets() = room->frame_data.bullets; { + for (auto& pair : room->frame_data.deleted_objects_hash) { + if (pair.first <= room->frame_no) { + for (auto& itr : pair.second) { + update_msg->add_del_objids(itr); + } + } + } + for (auto& pair : room->frame_data.shots_hash) { + if (pair.first <= room->frame_no) { + for (auto& itr : pair.second) { + *update_msg->add_shots() = itr; + } + } + } + for (auto& pair : room->frame_data.bullets_hash) { + if (pair.first <= room->frame_no) { + for (auto& itr : pair.second) { + *update_msg->add_bullets() = itr; + } + } + } for (auto& pair : room->frame_data.explosions_hash) { if (pair.first <= room->frame_no) { for (auto& itr : pair.second) { diff --git a/server/gameserver/room.cc b/server/gameserver/room.cc index 08f5f35..5cf1d1c 100644 --- a/server/gameserver/room.cc +++ b/server/gameserver/room.cc @@ -27,6 +27,7 @@ const int ANDROID_NUM = 10; void Room::Initialize() { ShuaAndroid(); + CreateThings(); #if 0 a8::Timer::Instance()->AddRepeatTimer( 1000 * 5, @@ -63,6 +64,50 @@ void Room::Update(int delta_time) ClearDeletedObjects(); ProcAddedObjects(); { + { + std::vector del_ids; + for (auto& pair : frame_data.deleted_objects_hash) { + if (pair.first < frame_no) { + del_ids.push_back(pair.first); + } + } + for (long long id : del_ids) { + frame_data.deleted_objects_hash.erase(id); + } + } + { + std::vector del_ids; + for (auto& pair : frame_data.softdeleted_objects_hash) { + if (pair.first < frame_no) { + del_ids.push_back(pair.first); + } + } + for (long long id : del_ids) { + frame_data.softdeleted_objects_hash.erase(id); + } + } + { + std::vector del_ids; + for (auto& pair : frame_data.bullets_hash) { + if (pair.first < frame_no) { + del_ids.push_back(pair.first); + } + } + for (long long id : del_ids) { + frame_data.bullets_hash.erase(id); + } + } + { + std::vector del_ids; + for (auto& pair : frame_data.shots_hash) { + if (pair.first < frame_no) { + del_ids.push_back(pair.first); + } + } + for (long long id : del_ids) { + frame_data.shots_hash.erase(id); + } + } { std::vector del_ids; for (auto& pair : frame_data.explosions_hash) { @@ -164,6 +209,21 @@ void Room::AddPlayer(Player* hum) hum->part_objects.insert(pair.second); } } + for (auto& pair : uniid_hash_) { + switch (pair.second->entity_type) { + case ET_Building: + case ET_Obstacle: + { + hum->new_objects.insert(pair.second); + hum->part_objects.insert(pair.second); + } + break; + default: + { + } + break; + } + } } unsigned short Room::AllocUniid() @@ -265,9 +325,25 @@ void Room::CollisionDetection(Entity* sender, int detection_flags, std::vector* deleted_objects = nullptr; + if (soft_delete) { + auto itr = frame_data.softdeleted_objects_hash.find(frame_no); + if (itr == frame_data.softdeleted_objects_hash.end()) { + frame_data.softdeleted_objects_hash[frame_no] = std::set(); + itr = frame_data.softdeleted_objects_hash.find(frame_no); + } + deleted_objects = &itr->second; + } else { + auto itr = frame_data.deleted_objects_hash.find(frame_no); + if (itr == frame_data.deleted_objects_hash.end()) { + frame_data.deleted_objects_hash[frame_no] = std::set(); + itr = frame_data.deleted_objects_hash.find(frame_no); + } + deleted_objects = &itr->second; + } + deleted_objects->insert(obj_uniid); } void Room::FillSMJoinedNotify(Player* self_hum, cs::SMJoinedNotify& msg) @@ -288,9 +364,6 @@ void Room::FillSMJoinedNotify(Player* self_hum, cs::SMJoinedNotify& msg) void Room::ResetFrameData() { - frame_data.deleted_objects.clear(); - frame_data.bullets.Clear(); - frame_data.shots.Clear(); } void Room::ScatterDrop(Vector2D center, int drop_id) @@ -328,10 +401,6 @@ void Room::CreateThings() entity->pos = Vector2D(thing_tpl.i->x(), thing_tpl.i->y()); entity->Initialize(); uniid_hash_[entity->entity_uniid] = entity; - for (auto& pair : human_hash_) { - pair.second->new_objects.insert(entity); - pair.second->part_objects.insert(entity); - } } } else { Obstacle* entity = new Obstacle(); @@ -341,10 +410,6 @@ void Room::CreateThings() entity->pos = Vector2D(thing_tpl.i->x(), thing_tpl.i->y()); entity->Initialize(); uniid_hash_[entity->entity_uniid] = entity; - for (auto& pair : human_hash_) { - pair.second->new_objects.insert(entity); - pair.second->part_objects.insert(entity); - } } } } @@ -510,18 +575,37 @@ void Room::OnHumanDie(Human* hum) void Room::ClearDeletedObjects() { - for (auto& obj_uniid : frame_data.deleted_objects) { - Entity* entity = GetEntityByUniId(obj_uniid); - if (entity) { - if (entity->entity_type != ET_Player) { - uniid_hash_.erase(entity->entity_uniid); - moveable_hash_.erase(entity->entity_uniid); + for (auto& pair : frame_data.deleted_objects_hash) { + for (auto& obj_uniid : pair.second) { + Entity* entity = GetEntityByUniId(obj_uniid); + if (entity) { + if (entity->entity_type != ET_Player) { + uniid_hash_.erase(entity->entity_uniid); + moveable_hash_.erase(entity->entity_uniid); + } + for (auto& pair : human_hash_) { + pair.second->new_objects.erase(entity); + pair.second->part_objects.erase(entity); + } + delete entity; } - for (auto& pair : human_hash_) { - pair.second->new_objects.erase(entity); - pair.second->part_objects.erase(entity); + } + } + + for (auto& pair : frame_data.softdeleted_objects_hash) { + for (auto& obj_uniid : pair.second) { + Entity* entity = GetEntityByUniId(obj_uniid); + if (entity) { + if (entity->entity_type != ET_Player) { + uniid_hash_.erase(entity->entity_uniid); + moveable_hash_.erase(entity->entity_uniid); + } + for (auto& pair : human_hash_) { + pair.second->new_objects.erase(entity); + pair.second->part_objects.erase(entity); + } + delete entity; } - delete entity; } } } diff --git a/server/gameserver/room.h b/server/gameserver/room.h index 29baf6b..0db9dd8 100644 --- a/server/gameserver/room.h +++ b/server/gameserver/room.h @@ -37,7 +37,7 @@ public: Human* FindEnemy(Human* hum); void CollisionDetection(Entity* sender, int detection_flags, std::vector& objects); - void AddDeletedObject(unsigned short obj_uniid); + void AddDeletedObject(unsigned short obj_uniid, bool soft_delete); void BeAddedObject(Entity* entity); void FetchBuilding(Human* hum); diff --git a/server/gameserver/roommgr.cc b/server/gameserver/roommgr.cc index c571870..3be7ff7 100644 --- a/server/gameserver/roommgr.cc +++ b/server/gameserver/roommgr.cc @@ -50,7 +50,6 @@ void RoomMgr::_CMJoin(f8::MsgHdr& hdr, const cs::CMJoin& msg) Player* hum = PlayerMgr::Instance()->CreatePlayerByCMJoin(hdr.socket_handle, msg); hum->meta = hum_meta; room->AddPlayer(hum); - room->CreateThings(); { cs::SMJoinedNotify notifymsg;