mirror of
https://github.com/zyllian/classics.git
synced 2025-05-10 19:46:38 -07:00
save player location on save/leave
This commit is contained in:
parent
6b72840495
commit
b146afa72e
6 changed files with 94 additions and 45 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -181,6 +181,7 @@ checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"crunchy",
|
"crunchy",
|
||||||
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
|
@ -8,7 +8,7 @@ bincode = "2.0.0-rc.3"
|
||||||
bitmask-enum = "2"
|
bitmask-enum = "2"
|
||||||
bytes = "1"
|
bytes = "1"
|
||||||
flate2 = "1"
|
flate2 = "1"
|
||||||
half = "2"
|
half = {version = "2", features = ["serde"]}
|
||||||
internment = {version = "0.8", features = ["serde"]}
|
internment = {version = "0.8", features = ["serde"]}
|
||||||
nanoid = "0.4"
|
nanoid = "0.4"
|
||||||
optional_struct = "0.4"
|
optional_struct = "0.4"
|
||||||
|
|
17
src/level.rs
17
src/level.rs
|
@ -1,12 +1,14 @@
|
||||||
use std::{
|
use std::{
|
||||||
collections::BTreeSet,
|
collections::{BTreeMap, BTreeSet},
|
||||||
io::{Read, Write},
|
io::{Read, Write},
|
||||||
path::Path,
|
path::Path,
|
||||||
};
|
};
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::{error::GeneralError, packet::server::ServerPacket, util::neighbors};
|
use crate::{
|
||||||
|
error::GeneralError, packet::server::ServerPacket, player::SavablePlayerData, util::neighbors,
|
||||||
|
};
|
||||||
|
|
||||||
use self::block::BLOCK_INFO;
|
use self::block::BLOCK_INFO;
|
||||||
|
|
||||||
|
@ -39,6 +41,9 @@ pub struct Level {
|
||||||
pub updates: Vec<BlockUpdate>,
|
pub updates: Vec<BlockUpdate>,
|
||||||
#[serde(skip)]
|
#[serde(skip)]
|
||||||
pub save_now: bool,
|
pub save_now: bool,
|
||||||
|
|
||||||
|
#[serde(default)]
|
||||||
|
pub player_data: BTreeMap<String, SavablePlayerData>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Level {
|
impl Level {
|
||||||
|
@ -53,6 +58,7 @@ impl Level {
|
||||||
awaiting_update: Default::default(),
|
awaiting_update: Default::default(),
|
||||||
updates: Default::default(),
|
updates: Default::default(),
|
||||||
save_now: false,
|
save_now: false,
|
||||||
|
player_data: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,6 +113,13 @@ impl Level {
|
||||||
packets
|
packets
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// updates player data for the level
|
||||||
|
pub fn update_player_data(&mut self, player_data: Vec<(String, SavablePlayerData)>) {
|
||||||
|
for (username, data) in player_data {
|
||||||
|
self.player_data.insert(username, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// saves the level
|
/// saves the level
|
||||||
pub async fn save<P>(&self, path: P) -> Result<(), GeneralError>
|
pub async fn save<P>(&self, path: P) -> Result<(), GeneralError>
|
||||||
where
|
where
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
use std::net::SocketAddr;
|
use std::{
|
||||||
|
net::SocketAddr,
|
||||||
|
ops::{Deref, DerefMut},
|
||||||
|
};
|
||||||
|
|
||||||
use half::f16;
|
use half::f16;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
@ -12,16 +15,8 @@ pub struct Player {
|
||||||
pub id: i8,
|
pub id: i8,
|
||||||
/// the player's username
|
/// the player's username
|
||||||
pub username: String,
|
pub username: String,
|
||||||
/// the player's X coordinate
|
/// the player's savable data
|
||||||
pub x: f16,
|
pub savable_data: SavablePlayerData,
|
||||||
/// the player's Y coordinate
|
|
||||||
pub y: f16,
|
|
||||||
/// the player's Z coordinate
|
|
||||||
pub z: f16,
|
|
||||||
/// the player's yaw
|
|
||||||
pub yaw: u8,
|
|
||||||
/// the player's pitch
|
|
||||||
pub pitch: u8,
|
|
||||||
/// the player's permission state
|
/// the player's permission state
|
||||||
pub permissions: PlayerType,
|
pub permissions: PlayerType,
|
||||||
|
|
||||||
|
@ -37,6 +32,35 @@ pub struct Player {
|
||||||
pub should_be_kicked: Option<String>,
|
pub should_be_kicked: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Deref for Player {
|
||||||
|
type Target = SavablePlayerData;
|
||||||
|
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
&self.savable_data
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DerefMut for Player {
|
||||||
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
|
&mut self.savable_data
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// savable data about the player
|
||||||
|
#[derive(Debug, Default, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct SavablePlayerData {
|
||||||
|
/// the player's X coordinate
|
||||||
|
pub x: f16,
|
||||||
|
/// the player's Y coordinate
|
||||||
|
pub y: f16,
|
||||||
|
/// the player's Z coordinate
|
||||||
|
pub z: f16,
|
||||||
|
/// the player's yaw
|
||||||
|
pub yaw: u8,
|
||||||
|
/// the player's pitch
|
||||||
|
pub pitch: u8,
|
||||||
|
}
|
||||||
|
|
||||||
/// enum describing types of players
|
/// enum describing types of players
|
||||||
#[derive(
|
#[derive(
|
||||||
Debug,
|
Debug,
|
||||||
|
|
|
@ -137,7 +137,13 @@ impl Server {
|
||||||
// TODO: cancel pending tasks/send out "Server is stopping" messages *here* instead of elsewhere
|
// TODO: cancel pending tasks/send out "Server is stopping" messages *here* instead of elsewhere
|
||||||
// rn the message isn't guaranteed to actually go out........
|
// rn the message isn't guaranteed to actually go out........
|
||||||
|
|
||||||
let data = self.data.read().await;
|
let mut data = self.data.write().await;
|
||||||
|
let player_data = data
|
||||||
|
.players
|
||||||
|
.iter()
|
||||||
|
.map(|p| (p.username.clone(), p.savable_data.clone()))
|
||||||
|
.collect();
|
||||||
|
data.level.update_player_data(player_data);
|
||||||
data.level
|
data.level
|
||||||
.save(PathBuf::from(LEVELS_PATH).join(&data.config.level_name))
|
.save(PathBuf::from(LEVELS_PATH).join(&data.config.level_name))
|
||||||
.await?;
|
.await?;
|
||||||
|
|
|
@ -122,6 +122,9 @@ pub(super) async fn handle_stream(
|
||||||
player.packets_to_send.push(despawn_packet.clone());
|
player.packets_to_send.push(despawn_packet.clone());
|
||||||
player.packets_to_send.push(message_packet.clone());
|
player.packets_to_send.push(message_packet.clone());
|
||||||
}
|
}
|
||||||
|
data.level
|
||||||
|
.player_data
|
||||||
|
.insert(player.username, player.savable_data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,8 +165,6 @@ async fn handle_stream_inner(
|
||||||
return Err(GeneralError::Custom("Unknown protocol version! Please connect with a classic 0.30-compatible client.".to_string()));
|
return Err(GeneralError::Custom("Unknown protocol version! Please connect with a classic 0.30-compatible client.".to_string()));
|
||||||
}
|
}
|
||||||
|
|
||||||
let zero = f16::from_f32(0.0);
|
|
||||||
|
|
||||||
let mut data = data.write().await;
|
let mut data = data.write().await;
|
||||||
|
|
||||||
match &data.config.protection_mode {
|
match &data.config.protection_mode {
|
||||||
|
@ -208,15 +209,15 @@ async fn handle_stream_inner(
|
||||||
.copied()
|
.copied()
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
|
|
||||||
|
let savable_data = data.level.player_data.get(&username).cloned();
|
||||||
|
let needs_spawn_coords = savable_data.is_none();
|
||||||
|
let savable_data = savable_data.unwrap_or_default();
|
||||||
|
|
||||||
let mut player = Player {
|
let mut player = Player {
|
||||||
_addr: addr,
|
_addr: addr,
|
||||||
id: *own_id, // TODO: actually assign user ids
|
id: *own_id, // TODO: actually assign user ids
|
||||||
username,
|
username,
|
||||||
x: zero,
|
savable_data,
|
||||||
y: zero,
|
|
||||||
z: zero,
|
|
||||||
yaw: 0,
|
|
||||||
pitch: 0,
|
|
||||||
permissions: player_type,
|
permissions: player_type,
|
||||||
extensions: ExtBitmask::none(),
|
extensions: ExtBitmask::none(),
|
||||||
custom_blocks_support_level: 0,
|
custom_blocks_support_level: 0,
|
||||||
|
@ -252,6 +253,7 @@ async fn handle_stream_inner(
|
||||||
|
|
||||||
let username = player.username.clone();
|
let username = player.username.clone();
|
||||||
|
|
||||||
|
if needs_spawn_coords {
|
||||||
let (spawn_x, spawn_y, spawn_z, spawn_yaw, spawn_pitch) =
|
let (spawn_x, spawn_y, spawn_z, spawn_yaw, spawn_pitch) =
|
||||||
if let Some(spawn) = &data.config.spawn {
|
if let Some(spawn) = &data.config.spawn {
|
||||||
(spawn.x, spawn.y, spawn.z, spawn.yaw, spawn.pitch)
|
(spawn.x, spawn.y, spawn.z, spawn.yaw, spawn.pitch)
|
||||||
|
@ -270,17 +272,20 @@ async fn handle_stream_inner(
|
||||||
player.z = spawn_z;
|
player.z = spawn_z;
|
||||||
player.yaw = spawn_yaw;
|
player.yaw = spawn_yaw;
|
||||||
player.pitch = spawn_pitch;
|
player.pitch = spawn_pitch;
|
||||||
data.players.push(player);
|
}
|
||||||
|
|
||||||
let spawn_packet = ServerPacket::SpawnPlayer {
|
let spawn_packet = ServerPacket::SpawnPlayer {
|
||||||
player_id: *own_id,
|
player_id: *own_id,
|
||||||
player_name: username.clone(),
|
player_name: username.clone(),
|
||||||
x: spawn_x,
|
x: player.x,
|
||||||
y: spawn_y,
|
y: player.y,
|
||||||
z: spawn_z,
|
z: player.z,
|
||||||
yaw: spawn_yaw,
|
yaw: player.yaw,
|
||||||
pitch: spawn_pitch,
|
pitch: player.pitch,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
data.players.push(player);
|
||||||
|
|
||||||
let message_packet = ServerPacket::Message {
|
let message_packet = ServerPacket::Message {
|
||||||
player_id: *own_id,
|
player_id: *own_id,
|
||||||
message: format!("&e{} has joined the server.", username),
|
message: format!("&e{} has joined the server.", username),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue