mirror of
https://github.com/Pumpkin-MC/Pumpkin.git
synced 2026-08-30 20:14:23 +00:00
Add Player swing animation
This commit is contained in:
@@ -53,7 +53,7 @@ Pumpkin is currently under heavy development.
|
||||
- [x] Player Client brand
|
||||
- [x] Player Teleport
|
||||
- [x] Player Movement
|
||||
- [ ] Player Animation
|
||||
- [x] Player Animation
|
||||
- [ ] Player Inventory
|
||||
- [ ] Player Attack
|
||||
- Server
|
||||
|
||||
31
pumpkin-protocol/src/client/play/c_entity_animation.rs
Normal file
31
pumpkin-protocol/src/client/play/c_entity_animation.rs
Normal file
@@ -0,0 +1,31 @@
|
||||
use num_derive::ToPrimitive;
|
||||
use pumpkin_macros::packet;
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::VarInt;
|
||||
|
||||
#[derive(Serialize, Clone)]
|
||||
#[packet(0x03)]
|
||||
pub struct CEntityAnimation {
|
||||
entity_id: VarInt,
|
||||
/// See `Animation`
|
||||
animation: u8,
|
||||
}
|
||||
|
||||
impl CEntityAnimation {
|
||||
pub fn new(entity_id: VarInt, animation: u8) -> Self {
|
||||
Self {
|
||||
entity_id,
|
||||
animation,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(ToPrimitive)]
|
||||
pub enum Animation {
|
||||
SwingMainArm,
|
||||
LeaveBed,
|
||||
SwingOffhand,
|
||||
CriticalEffect,
|
||||
MagicCriticaleffect,
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
use pumpkin_macros::packet;
|
||||
use serde::Serialize;
|
||||
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[packet(0x38)]
|
||||
pub struct CPlayerAbilities {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
mod c_change_difficulty;
|
||||
mod c_chunk_data_update_light;
|
||||
mod c_entity_animation;
|
||||
mod c_entity_metadata;
|
||||
mod c_game_event;
|
||||
mod c_head_rot;
|
||||
@@ -19,6 +20,7 @@ mod player_action;
|
||||
|
||||
pub use c_change_difficulty::*;
|
||||
pub use c_chunk_data_update_light::*;
|
||||
pub use c_entity_animation::*;
|
||||
pub use c_entity_metadata::*;
|
||||
pub use c_game_event::*;
|
||||
pub use c_head_rot::*;
|
||||
|
||||
@@ -51,6 +51,20 @@ impl ServerPacket for SPlayerPosition {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct SSwingArm {
|
||||
pub hand: VarInt,
|
||||
}
|
||||
|
||||
impl ServerPacket for SSwingArm {
|
||||
const PACKET_ID: VarInt = VarInt(0x36);
|
||||
|
||||
fn read(bytebuf: &mut crate::bytebuf::ByteBuffer) -> Self {
|
||||
Self {
|
||||
hand: bytebuf.get_var_int(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct SPlayerCommand {
|
||||
pub entitiy_id: VarInt,
|
||||
pub action: Action,
|
||||
|
||||
@@ -27,7 +27,7 @@ use pumpkin_protocol::{
|
||||
login::{SEncryptionResponse, SLoginAcknowledged, SLoginPluginResponse, SLoginStart},
|
||||
play::{
|
||||
SChatCommand, SConfirmTeleport, SPlayerCommand, SPlayerPosition,
|
||||
SPlayerPositionRotation, SPlayerRotation,
|
||||
SPlayerPositionRotation, SPlayerRotation, SSwingArm,
|
||||
},
|
||||
status::{SPingRequest, SStatusRequest},
|
||||
},
|
||||
@@ -256,6 +256,7 @@ impl Client {
|
||||
SPlayerCommand::PACKET_ID => {
|
||||
self.handle_player_command(server, SPlayerCommand::read(bytebuf))
|
||||
}
|
||||
SSwingArm::PACKET_ID => self.handle_swing_arm(server, SSwingArm::read(bytebuf)),
|
||||
_ => log::error!("Failed to handle player packet id {}", packet.id.0),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,18 @@
|
||||
use num_traits::FromPrimitive;
|
||||
use pumpkin_protocol::{
|
||||
client::play::{CHeadRot, CUpdateEntityPos, CUpdateEntityPosRot, CUpdateEntityRot},
|
||||
client::play::{
|
||||
Animation, CEntityAnimation, CHeadRot, CUpdateEntityPos, CUpdateEntityPosRot,
|
||||
CUpdateEntityRot,
|
||||
},
|
||||
server::play::{
|
||||
SChatCommand, SConfirmTeleport, SPlayerCommand, SPlayerPosition, SPlayerPositionRotation,
|
||||
SPlayerRotation,
|
||||
SPlayerRotation, SSwingArm,
|
||||
},
|
||||
};
|
||||
|
||||
use crate::{
|
||||
commands::{handle_command, CommandSender},
|
||||
entity::player::Hand,
|
||||
server::Server,
|
||||
};
|
||||
|
||||
@@ -156,4 +161,14 @@ impl Client {
|
||||
pumpkin_protocol::server::play::Action::StartFlyingElytra => todo!(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn handle_swing_arm(&mut self, server: &mut Server, swing_arm: SSwingArm) {
|
||||
let animation = match Hand::from_i32(swing_arm.hand.0).unwrap() {
|
||||
Hand::Main => Animation::SwingMainArm,
|
||||
Hand::Off => Animation::SwingOffhand,
|
||||
};
|
||||
let player = self.player.as_mut().unwrap();
|
||||
let id = player.entity_id();
|
||||
server.broadcast_packet_expect(self, CEntityAnimation::new(id.into(), animation as u8))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,153 +0,0 @@
|
||||
use std::path::Path;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{entity::player::GameMode, server::Difficulty};
|
||||
|
||||
use super::auth_config::Authentication;
|
||||
|
||||
/// Current Config version of the Base Config
|
||||
const CURRENT_BASE_VERSION: &str = "1.0.0";
|
||||
|
||||
#[derive(Deserialize, Serialize)]
|
||||
/// The idea is that Pumpkin should very customizable, You can Enable or Disable Features depning on your needs.
|
||||
/// This also allows you get some Performance or Resource boosts.
|
||||
/// Important: The Configuration should match Vanilla by default
|
||||
pub struct AdvancedConfiguration {
|
||||
pub commands: Commands,
|
||||
pub authentication: Authentication,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Serialize)]
|
||||
pub struct Commands {
|
||||
/// Are commands from the Console accepted ?
|
||||
pub use_console: bool,
|
||||
// todo commands...
|
||||
}
|
||||
|
||||
impl Default for Commands {
|
||||
fn default() -> Self {
|
||||
Self { use_console: true }
|
||||
}
|
||||
}
|
||||
|
||||
/// Important: The Configuration should match Vanilla by default
|
||||
impl Default for AdvancedConfiguration {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
authentication: Authentication::default(),
|
||||
commands: Commands::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct BasicConfiguration {
|
||||
/// A version identifier for the configuration format.
|
||||
pub config_version: String,
|
||||
/// The address to bind the server to.
|
||||
pub server_address: String,
|
||||
/// The port to listen on.
|
||||
pub server_port: u16,
|
||||
/// The seed for world generation.
|
||||
pub seed: String,
|
||||
/// The maximum number of players allowed on the server.
|
||||
pub max_players: u32,
|
||||
/// The maximum view distance for players.
|
||||
pub view_distance: u8,
|
||||
/// The maximum simulated view distance.
|
||||
pub simulation_distance: u8,
|
||||
/// The path to the resource pack.
|
||||
pub resource_pack: String,
|
||||
/// The SHA1 hash of the resource pack.
|
||||
pub resource_pack_sha1: String,
|
||||
/// The default game difficulty.
|
||||
pub default_difficulty: Difficulty,
|
||||
/// Whether the Nether dimension is enabled.
|
||||
pub allow_nether: bool,
|
||||
/// Whether the server is in hardcore mode.
|
||||
pub hardcore: bool,
|
||||
/// Whether online mode is enabled. Requires valid Minecraft accounts.
|
||||
pub online_mode: bool,
|
||||
/// Whether packet encryption is enabled. Required when online mode is enabled.
|
||||
pub encryption: bool,
|
||||
/// The server's description displayed on the status screen.
|
||||
pub motd: String,
|
||||
/// The default game mode for players.
|
||||
pub default_gamemode: GameMode,
|
||||
}
|
||||
|
||||
impl Default for BasicConfiguration {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
config_version: CURRENT_BASE_VERSION.to_string(),
|
||||
server_address: "127.0.0.1".to_string(),
|
||||
server_port: 25565,
|
||||
seed: "".to_string(),
|
||||
max_players: 100000,
|
||||
view_distance: 10,
|
||||
simulation_distance: 10,
|
||||
resource_pack: "".to_string(),
|
||||
resource_pack_sha1: "".to_string(),
|
||||
default_difficulty: Difficulty::Normal,
|
||||
allow_nether: true,
|
||||
hardcore: false,
|
||||
online_mode: true,
|
||||
encryption: true,
|
||||
motd: "A Blazing fast Pumpkin Server!".to_string(),
|
||||
default_gamemode: GameMode::Survival,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl AdvancedConfiguration {
|
||||
pub fn load<P: AsRef<Path>>(path: P) -> AdvancedConfiguration {
|
||||
if path.as_ref().exists() {
|
||||
let toml = std::fs::read_to_string(path).expect("Couldn't read configuration");
|
||||
toml::from_str(toml.as_str()).expect("Couldn't parse, Proberbly old config")
|
||||
} else {
|
||||
let config = AdvancedConfiguration::default();
|
||||
let toml = toml::to_string(&config).expect("Couldn't create toml!");
|
||||
std::fs::write(path, toml).expect("Couldn't save configuration");
|
||||
config
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl BasicConfiguration {
|
||||
pub fn load<P: AsRef<Path>>(path: P) -> BasicConfiguration {
|
||||
if path.as_ref().exists() {
|
||||
let toml = std::fs::read_to_string(path).expect("Couldn't read configuration");
|
||||
toml::from_str(toml.as_str()).expect("Couldn't parse")
|
||||
} else {
|
||||
let config = BasicConfiguration::default();
|
||||
let toml = toml::to_string(&config).expect("Couldn't create toml!");
|
||||
std::fs::write(path, toml).expect("Couldn't save configuration");
|
||||
config.validate();
|
||||
config
|
||||
}
|
||||
}
|
||||
|
||||
pub fn validate(&self) {
|
||||
assert_eq!(
|
||||
self.config_version, CURRENT_BASE_VERSION,
|
||||
"Config version does not match used Config version. Please update your config"
|
||||
);
|
||||
assert!(self.view_distance >= 2, "View distance must be atleast 2");
|
||||
assert!(
|
||||
self.view_distance <= 32,
|
||||
"View distance must be less than 32"
|
||||
);
|
||||
if self.online_mode {
|
||||
assert!(
|
||||
self.encryption,
|
||||
"When Online Mode is enabled, Encryption must be enabled"
|
||||
)
|
||||
}
|
||||
assert_eq!(
|
||||
!self.resource_pack.is_empty(),
|
||||
!self.resource_pack_sha1.is_empty(),
|
||||
"Resource Pack path or Sha1 hash is missing"
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -14,7 +14,8 @@ use pumpkin_protocol::{
|
||||
client::{
|
||||
config::CPluginMessage,
|
||||
play::{
|
||||
CChunkDataUpdateLight, CGameEvent, CLogin, CPlayerAbilities, CPlayerInfoUpdate, CSpawnEntity, PlayerAction,
|
||||
CChunkDataUpdateLight, CGameEvent, CLogin, CPlayerAbilities, CPlayerInfoUpdate,
|
||||
CSpawnEntity, PlayerAction,
|
||||
},
|
||||
},
|
||||
BitSet, ClientPacket, Players, Sample, StatusResponse, VarInt, Version, CURRENT_MC_PROTOCOL,
|
||||
|
||||
Reference in New Issue
Block a user