Add Scoreboard support
This commit is contained in:
parent
5d0bb14a85
commit
406db91f06
@ -18,7 +18,7 @@
|
||||
|
||||
**Cause:** The server is currently not calculating hit boxes for blocks, we're working on that.
|
||||
|
||||
3. The Server is unresponsive
|
||||
3. ### The Server is unresponsive
|
||||
|
||||
**Issue:** You have to wait before reconnecting or can't do basic things while chunks are loading.
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
use pumpkin_core::text::{style::Style, TextComponent};
|
||||
use pumpkin_core::text::TextComponent;
|
||||
use pumpkin_macros::packet;
|
||||
|
||||
use crate::{ClientPacket, NumberFormat, VarInt};
|
||||
|
||||
@ -1,8 +1,10 @@
|
||||
use pumpkin_core::text::TextComponent;
|
||||
use pumpkin_macros::packet;
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::{NumberFormat, VarInt};
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[packet(0x61)]
|
||||
pub struct CUpdateScore<'a> {
|
||||
entity_name: &'a str,
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
use bytebuf::{packet_id::Packet, ByteBuffer, DeserializerError};
|
||||
use bytes::Buf;
|
||||
use pumpkin_core::text::{style::Style, TextComponent};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::io::{self, Write};
|
||||
use thiserror::Error;
|
||||
@ -245,6 +246,7 @@ pub struct KnownPack<'a> {
|
||||
pub version: &'a str,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub enum NumberFormat<'a> {
|
||||
/// Show nothing
|
||||
Blank,
|
||||
|
||||
@ -19,8 +19,11 @@ use pumpkin_protocol::{
|
||||
ClientPacket, VarInt,
|
||||
};
|
||||
use pumpkin_world::level::Level;
|
||||
use scoreboard::Scoreboard;
|
||||
use tokio::sync::mpsc;
|
||||
|
||||
pub mod scoreboard;
|
||||
|
||||
/// Represents a Minecraft world, containing entities, players, and the underlying level data.
|
||||
///
|
||||
/// Each dimension (Overworld, Nether, End) typically has its own `World`.
|
||||
@ -35,6 +38,7 @@ pub struct World {
|
||||
pub level: Arc<Mutex<Level>>,
|
||||
/// A map of active players within the world, keyed by their unique token.
|
||||
pub current_players: Arc<Mutex<HashMap<usize, Arc<Player>>>>,
|
||||
pub scoreboard: Mutex<Scoreboard>,
|
||||
// TODO: entities
|
||||
}
|
||||
|
||||
@ -43,6 +47,7 @@ impl World {
|
||||
Self {
|
||||
level: Arc::new(Mutex::new(level)),
|
||||
current_players: Arc::new(Mutex::new(HashMap::new())),
|
||||
scoreboard: Mutex::new(Scoreboard::new()),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
123
pumpkin/src/world/scoreboard.rs
Normal file
123
pumpkin/src/world/scoreboard.rs
Normal file
@ -0,0 +1,123 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use pumpkin_core::text::TextComponent;
|
||||
use pumpkin_protocol::{
|
||||
client::play::{CDisplayObjective, CUpdateObjectives, CUpdateScore, RenderType},
|
||||
NumberFormat, VarInt,
|
||||
};
|
||||
|
||||
use super::World;
|
||||
|
||||
pub struct Scoreboard {
|
||||
objectives: HashMap<String, ScoreboardObjective<'static>>,
|
||||
// teams: HashMap<String, Team>,
|
||||
}
|
||||
|
||||
impl Default for Scoreboard {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl Scoreboard {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
objectives: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_objective(&mut self, world: &World, objective: ScoreboardObjective) {
|
||||
if self.objectives.contains_key(objective.name) {
|
||||
// Maybe make this an error ?
|
||||
log::warn!(
|
||||
"Tried to create Objective which does already exist, {}",
|
||||
&objective.name
|
||||
);
|
||||
return;
|
||||
}
|
||||
world.broadcast_packet_all(&CUpdateObjectives::new(
|
||||
objective.name,
|
||||
pumpkin_protocol::client::play::Mode::Add,
|
||||
objective.display_name,
|
||||
objective.render_type,
|
||||
objective.number_format,
|
||||
));
|
||||
world.broadcast_packet_all(&CDisplayObjective::new(
|
||||
pumpkin_protocol::client::play::DisplaySlot::Sidebar,
|
||||
"test",
|
||||
));
|
||||
}
|
||||
|
||||
pub fn update_score(&self, world: &World, score: ScoreboardScore) {
|
||||
if self.objectives.contains_key(score.objective_name) {
|
||||
log::warn!(
|
||||
"Tried to place a score into a Objective which does not exist, {}",
|
||||
&score.objective_name
|
||||
);
|
||||
return;
|
||||
}
|
||||
world.broadcast_packet_all(&CUpdateScore::new(
|
||||
score.entity_name,
|
||||
score.objective_name,
|
||||
score.value,
|
||||
score.display_name,
|
||||
score.number_format,
|
||||
));
|
||||
}
|
||||
|
||||
// pub fn add_team(&mut self, name: String) {
|
||||
// if self.teams.contains_key(&name) {
|
||||
// // Maybe make this an error ?
|
||||
// log::warn!("Tried to create Team which does already exist, {}", name);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
pub struct ScoreboardObjective<'a> {
|
||||
name: &'a str,
|
||||
display_name: TextComponent<'a>,
|
||||
render_type: RenderType,
|
||||
number_format: Option<NumberFormat<'a>>,
|
||||
}
|
||||
|
||||
impl<'a> ScoreboardObjective<'a> {
|
||||
pub const fn new(
|
||||
name: &'a str,
|
||||
display_name: TextComponent<'a>,
|
||||
render_type: RenderType,
|
||||
number_format: Option<NumberFormat<'a>>,
|
||||
) -> Self {
|
||||
Self {
|
||||
name,
|
||||
display_name,
|
||||
render_type,
|
||||
number_format,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ScoreboardScore<'a> {
|
||||
entity_name: &'a str,
|
||||
objective_name: &'a str,
|
||||
value: VarInt,
|
||||
display_name: Option<TextComponent<'a>>,
|
||||
number_format: Option<NumberFormat<'a>>,
|
||||
}
|
||||
|
||||
impl<'a> ScoreboardScore<'a> {
|
||||
pub const fn new(
|
||||
entity_name: &'a str,
|
||||
objective_name: &'a str,
|
||||
value: VarInt,
|
||||
display_name: Option<TextComponent<'a>>,
|
||||
number_format: Option<NumberFormat<'a>>,
|
||||
) -> Self {
|
||||
Self {
|
||||
entity_name,
|
||||
objective_name,
|
||||
value,
|
||||
display_name,
|
||||
number_format,
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user