mirror of
https://github.com/zhenyan121/Cubed.git
synced 2026-08-09 02:07:04 +08:00
feat(network): synchronize player water sound
This commit is contained in:
Binary file not shown.
@@ -69,6 +69,8 @@ public:
|
||||
|
||||
void receive_remote_player(const PlayerInfoRsp& rsp);
|
||||
void receive_player_logout(const LogoutRsp& rsp);
|
||||
void receive_player_water_sound(const PlayerWaterSound& rsp);
|
||||
void send_player_water_sound(bool underwater, const glm::vec3& pos);
|
||||
int rendering_distance() const;
|
||||
void rendering_distance(int rendering_distance);
|
||||
int get_chunk_task_id() const;
|
||||
|
||||
@@ -54,6 +54,7 @@ enum class PacketEnum : uint16_t {
|
||||
PLAYER_INFO = 2001,
|
||||
C2S_PLAYER_INFO = 2002,
|
||||
PLAYER_INFO_RSP = 2003,
|
||||
PLAYER_WATER_SOUND = 2004,
|
||||
CHUNK_DATA_REQ = 3001,
|
||||
CHUNK_DATA_RSP = 3002,
|
||||
BLOCK_CHANGE_REQ = 3003,
|
||||
@@ -117,6 +118,9 @@ template <> constexpr uint16_t get_packet_id<Ping>() {
|
||||
template <> constexpr uint16_t get_packet_id<Pong>() {
|
||||
return std::to_underlying(PacketEnum::PONG);
|
||||
}
|
||||
template <> constexpr uint16_t get_packet_id<PlayerWaterSound>() {
|
||||
return std::to_underlying(PacketEnum::PLAYER_WATER_SOUND);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
requires std::derived_from<T, google::protobuf::Message>
|
||||
|
||||
@@ -71,6 +71,7 @@ public:
|
||||
bool set_block(const glm::ivec3& block_pos, unsigned id);
|
||||
|
||||
void sync_player_pos(const C2S_PlayerInfo& rsp);
|
||||
void sync_player_water_sound(const PlayerWaterSound& rsp);
|
||||
void handle_player_login(const std::string& player_name,
|
||||
std::shared_ptr<Session> session);
|
||||
glm::vec3 get_player_pos(const std::string& uuid) const;
|
||||
|
||||
@@ -50,8 +50,11 @@ void Camera::update_move_camera() {
|
||||
m_under_water = change;
|
||||
m_player->set_underwater(m_under_water);
|
||||
auto& audio = m_player->get_world().get_audio();
|
||||
audio.play_2d("ambient/water/in_and_out_of_water.flac", true);
|
||||
audio.play_3d("ambient/water/in_and_out_of_water.flac", m_camera_pos,
|
||||
true);
|
||||
audio.underwater_change(m_under_water);
|
||||
m_player->get_world().send_player_water_sound(m_under_water,
|
||||
m_camera_pos);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -354,6 +354,33 @@ void ClientWorld::receive_player_logout(const LogoutRsp& rsp) {
|
||||
}
|
||||
}
|
||||
|
||||
void ClientWorld::receive_player_water_sound(const PlayerWaterSound& rsp) {
|
||||
if (rsp.uuid() == m_player.get_uuid()) {
|
||||
return;
|
||||
}
|
||||
glm::vec3 pos = {rsp.pos().x(), rsp.pos().y(), rsp.pos().z()};
|
||||
|
||||
Logger::info("Client: Receive Player Water Sound");
|
||||
|
||||
m_pending_sound.emplace("ambient/water/in_and_out_of_water.flac", pos);
|
||||
}
|
||||
|
||||
void ClientWorld::send_player_water_sound(bool underwater,
|
||||
const glm::vec3& pos) {
|
||||
Arena arena;
|
||||
auto* r = Arena::Create<PlayerWaterSound>(&arena);
|
||||
|
||||
r->set_underwater(underwater);
|
||||
auto* p = r->mutable_pos();
|
||||
p->set_x(pos.x);
|
||||
p->set_y(pos.y);
|
||||
p->set_z(pos.z);
|
||||
r->set_uuid(m_player.get_uuid());
|
||||
|
||||
m_client->send(make_packet(*r));
|
||||
Logger::info("Client: Send Player Water Sound");
|
||||
}
|
||||
|
||||
void ClientWorld::init(std::string_view player_name,
|
||||
std::shared_ptr<NetworkClient> client) {
|
||||
m_player.init(player_name);
|
||||
|
||||
@@ -119,6 +119,12 @@ asio::awaitable<void> NetworkClient::read_loop() {
|
||||
}
|
||||
}
|
||||
} break;
|
||||
case std::to_underlying(PacketEnum::PLAYER_WATER_SOUND): {
|
||||
auto* rsp = Arena::Create<PlayerWaterSound>(&arena);
|
||||
if (decode_packet(*rsp, body_data, header)) {
|
||||
m_world.receive_player_water_sound(*rsp);
|
||||
}
|
||||
} break;
|
||||
}
|
||||
}
|
||||
} catch (const asio::system_error& e) {
|
||||
|
||||
@@ -597,6 +597,47 @@ void ServerWorld::sync_player_pos(const C2S_PlayerInfo& prsp) {
|
||||
}
|
||||
}
|
||||
|
||||
void ServerWorld::sync_player_water_sound(const PlayerWaterSound& rsp) {
|
||||
auto x = rsp.pos().x();
|
||||
auto y = rsp.pos().y();
|
||||
auto z = rsp.pos().z();
|
||||
ChunkPos pos = get_chunk_pos(x, z);
|
||||
auto uuid = rsp.uuid();
|
||||
auto underwater = rsp.underwater();
|
||||
|
||||
std::vector<std::shared_ptr<Session>> other;
|
||||
|
||||
{
|
||||
std::shared_lock lock(m_player_mutex);
|
||||
for (auto& [o_uuid, player] : m_players) {
|
||||
if (o_uuid == uuid) {
|
||||
continue;
|
||||
}
|
||||
if (player.has_player(pos)) {
|
||||
other.emplace_back(player.get_session());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Arena arena;
|
||||
auto* r = Arena::Create<PlayerWaterSound>(&arena);
|
||||
r->set_uuid(uuid);
|
||||
r->set_underwater(underwater);
|
||||
auto* p = r->mutable_pos();
|
||||
|
||||
p->set_x(x);
|
||||
p->set_y(y);
|
||||
p->set_z(z);
|
||||
|
||||
for (auto& session : other) {
|
||||
if (!session) {
|
||||
continue;
|
||||
}
|
||||
|
||||
session->send(make_packet(*r), 5);
|
||||
}
|
||||
}
|
||||
|
||||
void ServerWorld::handle_player_login(const std::string& name,
|
||||
std::shared_ptr<Session> session) {
|
||||
std::string uuid = generate_uuid();
|
||||
|
||||
@@ -92,6 +92,12 @@ asio::awaitable<void> Session::read_loop() {
|
||||
m_server_world.handle_player_exit(req->uuid());
|
||||
}
|
||||
}
|
||||
if (cmd_id == std::to_underlying(PacketEnum::PLAYER_WATER_SOUND)) {
|
||||
auto* req = Arena::Create<PlayerWaterSound>(&arena);
|
||||
if (decode_packet(*req, body_data, header)) {
|
||||
m_server_world.sync_player_water_sound(*req);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (const asio::system_error& e) {
|
||||
auto ec = e.code();
|
||||
|
||||
@@ -17,4 +17,10 @@ message PlayerInfoRsp {
|
||||
float yaw = 4;
|
||||
float pitch = 5;
|
||||
int32 gait = 6;
|
||||
}
|
||||
|
||||
message PlayerWaterSound {
|
||||
string uuid = 1;
|
||||
Vec3 pos = 2;
|
||||
bool underwater = 3;
|
||||
}
|
||||
Reference in New Issue
Block a user