diff --git a/server/gameserver/building.cc b/server/gameserver/building.cc index f62e118..797d02c 100644 --- a/server/gameserver/building.cc +++ b/server/gameserver/building.cc @@ -57,7 +57,25 @@ void Building::FillMFObjectPart(Room* room, Human* hum, cs::MFObjectPart* part_d void Building::FillMFObjectFull(Room* room, Human* hum, cs::MFObjectFull* full_data) { full_data->set_object_type(ET_Building); + if (IsClientCached(hum)) { + int object_flags = 0; + a8::SetBitFlag(object_flags, kOfReadCache); + full_data->set_obj_uniid(GetEntityUniId()); + full_data->set_object_flags(object_flags); + return; + } + cs::MFBuildingFull* p = full_data->mutable_union_obj_3(); + if (CanClientCache(hum)) { + int object_flags = 0; + a8::SetBitFlag(object_flags, kOfWriteCache); + #if 0 + full_data->set_obj_uniid(GetEntityUniId()); + #endif + full_data->set_object_flags(object_flags); + AddClientCache(hum); + } + p->set_obj_uniid(GetEntityUniId()); TypeConvert::ToPb(GetPos(), p->mutable_pos()); diff --git a/server/gameserver/constant.h b/server/gameserver/constant.h index a335c8f..49a267f 100755 --- a/server/gameserver/constant.h +++ b/server/gameserver/constant.h @@ -264,6 +264,17 @@ enum SkinSlot_e kSkinSlot_HAT = 2, }; +enum ObjectFlags_e +{ + kOfWriteCache = 0, + kOfReadCache = 1, +}; + +enum ObjectSyncFlags_e +{ + kOsfIsDead = 0, +}; + const char* const PROJ_NAME_FMT = "game%d_gameserver"; const char* const PROJ_ROOT_FMT = "/data/logs/%s"; diff --git a/server/gameserver/entity.cc b/server/gameserver/entity.cc index ba9ab55..de785f4 100644 --- a/server/gameserver/entity.cc +++ b/server/gameserver/entity.cc @@ -123,3 +123,46 @@ void Entity::AddEntityCollider(ColliderComponent* collider) { colliders_.push_back(collider); } + +bool Entity::IsClientCached(Human* hum) +{ + ObjectSyncFlags* sync_flags = hum->GetObjectSyncFlags(GetEntityUniId()); + if (sync_flags) { + int flags = sync_flags->flags; + if (IsDead(hum->room)) { + if (a8::HasBitFlag(flags, kOsfIsDead)) { + return sync_flags->last_sync_frameno > 0; + } else { + return false; + } + } else { + if (!a8::HasBitFlag(flags, kOsfIsDead)) { + return sync_flags->last_sync_frameno > 0; + } else { + return false; + } + } + } + return false; +} + +bool Entity::CanClientCache(Human* hum) +{ + ObjectSyncFlags* sync_flags = hum->GetObjectSyncFlags(GetEntityUniId()); + return sync_flags != nullptr; +} + +void Entity::AddClientCache(Human* hum) +{ + ObjectSyncFlags* sync_flags = hum->GetObjectSyncFlags(GetEntityUniId()); + if (sync_flags) { + int flags = sync_flags->flags; + if (IsDead(hum->room)) { + a8::SetBitFlag(flags, kOsfIsDead); + } else { + a8::UnSetBitFlag(flags, kOsfIsDead); + } + sync_flags->flags = flags; + sync_flags->last_sync_frameno = hum->room->GetFrameNo(); + } +} diff --git a/server/gameserver/entity.h b/server/gameserver/entity.h index be7cf67..d34cb8a 100644 --- a/server/gameserver/entity.h +++ b/server/gameserver/entity.h @@ -46,6 +46,11 @@ class Entity void SetX(float x) { pos_.x = x; } void SetY(float y) { pos_.y = y; } +protected: + bool IsClientCached(Human* hum); + bool CanClientCache(Human* hum); + void AddClientCache(Human* hum); + private: void ClearColliders(); void SetGridId(int grid_id) { grid_id_ = grid_id; } diff --git a/server/gameserver/human.cc b/server/gameserver/human.cc index a7da07e..21c8bc7 100644 --- a/server/gameserver/human.cc +++ b/server/gameserver/human.cc @@ -3312,3 +3312,12 @@ void Human::RemoveFromScene() }); last_collision_door_ = nullptr; } + +ObjectSyncFlags* Human::GetObjectSyncFlags(int obj_uniid) +{ + if ((size_t)obj_uniid < fixed_object_sync_flags_.size()) { + return &fixed_object_sync_flags_[obj_uniid]; + } else { + return nullptr; + } +} diff --git a/server/gameserver/human.h b/server/gameserver/human.h index 8f43c02..09dfb5f 100644 --- a/server/gameserver/human.h +++ b/server/gameserver/human.h @@ -267,6 +267,7 @@ class Human : public MoveableEntity void OnDisable(); Entity* GetLastCollisionDoor() { return last_collision_door_; } void SetLastCollisionDoor(Entity* door) { last_collision_door_ = door; } + ObjectSyncFlags* GetObjectSyncFlags(int obj_uniid); protected: void _UpdateMove(int speed); diff --git a/server/gameserver/obstacle.cc b/server/gameserver/obstacle.cc index f79e0ac..8e8b56a 100644 --- a/server/gameserver/obstacle.cc +++ b/server/gameserver/obstacle.cc @@ -111,8 +111,24 @@ void Obstacle::FillMFObjectPart(Room* room, Human* hum, cs::MFObjectPart* part_d void Obstacle::FillMFObjectFull(Room* room, Human* hum, cs::MFObjectFull* full_data) { full_data->set_object_type(ET_Obstacle); + if (IsClientCached(hum)) { + int object_flags = 0; + a8::SetBitFlag(object_flags, kOfReadCache); + full_data->set_obj_uniid(GetEntityUniId()); + full_data->set_object_flags(object_flags); + return; + } cs::MFObstacleFull* p = full_data->mutable_union_obj_2(); + if (CanClientCache(hum)) { + int object_flags = 0; + a8::SetBitFlag(object_flags, kOfWriteCache); + #if 0 + full_data->set_obj_uniid(GetEntityUniId()); + #endif + full_data->set_object_flags(object_flags); + AddClientCache(hum); + } p->set_obj_uniid(GetEntityUniId()); TypeConvert::ToPb(GetPos(), p->mutable_pos()); p->set_scale(1.0f);