do better caching
This commit is contained in:
parent
4ee1c6190f
commit
5a1d333f02
@ -5,6 +5,7 @@ use crate::{
|
|||||||
login::{CEncryptionRequest, CLoginSuccess},
|
login::{CEncryptionRequest, CLoginSuccess},
|
||||||
status::{CPingResponse, CStatusResponse},
|
status::{CPingResponse, CStatusResponse},
|
||||||
},
|
},
|
||||||
|
registry::{DimensionCodec, WolfCodec},
|
||||||
server::{
|
server::{
|
||||||
config::{SAcknowledgeFinishConfig, SClientInformation, SKnownPacks},
|
config::{SAcknowledgeFinishConfig, SClientInformation, SKnownPacks},
|
||||||
handshake::SHandShake,
|
handshake::SHandShake,
|
||||||
@ -67,12 +68,8 @@ impl ClientPacketProcessor for Client {
|
|||||||
fn handle_status_request(&mut self, server: &mut Server, _status_request: SStatusRequest) {
|
fn handle_status_request(&mut self, server: &mut Server, _status_request: SStatusRequest) {
|
||||||
dbg!("sending status");
|
dbg!("sending status");
|
||||||
|
|
||||||
if let Ok(response) = serde_json::to_string(&server.status_response) {
|
self.send_packet(CStatusResponse::new(&server.status_response_json))
|
||||||
self.send_packet(CStatusResponse::new(response))
|
.unwrap_or_else(|e| self.kick(&e.to_string()));
|
||||||
.unwrap_or_else(|e| self.kick(&e.to_string()));
|
|
||||||
} else {
|
|
||||||
log::error!("Failed to parse Status response to JSON")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_ping_request(&mut self, _server: &mut Server, ping_request: SPingRequest) {
|
fn handle_ping_request(&mut self, _server: &mut Server, ping_request: SPingRequest) {
|
||||||
@ -129,11 +126,13 @@ impl ClientPacketProcessor for Client {
|
|||||||
|
|
||||||
fn handle_login_acknowledged(
|
fn handle_login_acknowledged(
|
||||||
&mut self,
|
&mut self,
|
||||||
_server: &mut Server,
|
server: &mut Server,
|
||||||
_login_acknowledged: SLoginAcknowledged,
|
_login_acknowledged: SLoginAcknowledged,
|
||||||
) {
|
) {
|
||||||
self.connection_state = ConnectionState::Config;
|
self.connection_state = ConnectionState::Config;
|
||||||
Server::send_brand(self).unwrap_or_else(|e| self.kick(&e.to_string()));
|
server
|
||||||
|
.send_brand(self)
|
||||||
|
.unwrap_or_else(|e| self.kick(&e.to_string()));
|
||||||
// known data packs
|
// known data packs
|
||||||
self.send_packet(CKnownPacks::new(&[KnownPack {
|
self.send_packet(CKnownPacks::new(&[KnownPack {
|
||||||
namespace: "minecraft",
|
namespace: "minecraft",
|
||||||
@ -167,6 +166,12 @@ impl ClientPacketProcessor for Client {
|
|||||||
Entry {
|
Entry {
|
||||||
entry_id: "minecraft:dimension_type",
|
entry_id: "minecraft:dimension_type",
|
||||||
has_data: true,
|
has_data: true,
|
||||||
|
data: &DimensionCodec::parse(),
|
||||||
|
},
|
||||||
|
Entry {
|
||||||
|
entry_id: "minecraft:wolf_variant",
|
||||||
|
has_data: true,
|
||||||
|
data: &WolfCodec::parse(),
|
||||||
},
|
},
|
||||||
/* Entry {
|
/* Entry {
|
||||||
entry_id: "minecraft:worldgen/biome".into(),
|
entry_id: "minecraft:worldgen/biome".into(),
|
||||||
|
|||||||
@ -83,10 +83,12 @@ impl Client {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// adds a Incoming packet to the queue
|
||||||
pub fn add_packet(&mut self, packet: RawPacket) {
|
pub fn add_packet(&mut self, packet: RawPacket) {
|
||||||
self.client_packets_queue.push_back(packet);
|
self.client_packets_queue.push_back(packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// enables encryption
|
||||||
pub fn enable_encryption(
|
pub fn enable_encryption(
|
||||||
&mut self,
|
&mut self,
|
||||||
server: &mut Server,
|
server: &mut Server,
|
||||||
@ -126,6 +128,7 @@ impl Client {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Handles an incoming decoded Packet
|
||||||
pub fn handle_packet(&mut self, server: &mut Server, packet: &mut RawPacket) {
|
pub fn handle_packet(&mut self, server: &mut Server, packet: &mut RawPacket) {
|
||||||
dbg!("Handling packet");
|
dbg!("Handling packet");
|
||||||
let bytebuf = &mut packet.bytebuf;
|
let bytebuf = &mut packet.bytebuf;
|
||||||
@ -186,6 +189,7 @@ impl Client {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Reads the connection until our buffer of len 4096 is full, then decode
|
||||||
/// Returns `true` if the connection is closed.
|
/// Returns `true` if the connection is closed.
|
||||||
pub fn poll(&mut self, server: &mut Server, event: &Event) -> Result<bool, io::Error> {
|
pub fn poll(&mut self, server: &mut Server, event: &Event) -> Result<bool, io::Error> {
|
||||||
if event.is_readable() {
|
if event.is_readable() {
|
||||||
@ -233,6 +237,7 @@ impl Client {
|
|||||||
Ok(self.closed)
|
Ok(self.closed)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Kicks the Client with a reason depending on the connection state
|
||||||
pub fn kick(&mut self, reason: &str) {
|
pub fn kick(&mut self, reason: &str) {
|
||||||
// Todo
|
// Todo
|
||||||
match self.connection_state {
|
match self.connection_state {
|
||||||
@ -251,7 +256,7 @@ impl Client {
|
|||||||
self.close()
|
self.close()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Kick before when needed
|
/// You should prefer to use `kick` when you can
|
||||||
pub fn close(&mut self) {
|
pub fn close(&mut self) {
|
||||||
self.closed = true;
|
self.closed = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
use crate::protocol::{bytebuf::ByteBuffer, registry, ClientPacket, KnownPack, VarInt};
|
use crate::protocol::{bytebuf::ByteBuffer, ClientPacket, KnownPack, VarInt};
|
||||||
|
|
||||||
pub struct CCookieRequest {
|
pub struct CCookieRequest {
|
||||||
// TODO
|
// TODO
|
||||||
@ -11,12 +11,12 @@ impl ClientPacket for CCookieRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct CPluginMessage<'a> {
|
pub struct CPluginMessage<'a> {
|
||||||
channel: String,
|
channel: &'a str,
|
||||||
data: &'a [u8],
|
data: &'a [u8],
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> CPluginMessage<'a> {
|
impl<'a> CPluginMessage<'a> {
|
||||||
pub fn new(channel: String, data: &'a [u8]) -> Self {
|
pub fn new(channel: &'a str, data: &'a [u8]) -> Self {
|
||||||
Self { channel, data }
|
Self { channel, data }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -25,7 +25,7 @@ impl<'a> ClientPacket for CPluginMessage<'a> {
|
|||||||
const PACKET_ID: VarInt = 0x01;
|
const PACKET_ID: VarInt = 0x01;
|
||||||
|
|
||||||
fn write(&self, bytebuf: &mut ByteBuffer) {
|
fn write(&self, bytebuf: &mut ByteBuffer) {
|
||||||
bytebuf.put_string(&self.channel);
|
bytebuf.put_string(self.channel);
|
||||||
bytebuf.put_slice(self.data);
|
bytebuf.put_slice(self.data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -107,7 +107,7 @@ impl<'a> CRegistryData<'a> {
|
|||||||
pub struct Entry<'a> {
|
pub struct Entry<'a> {
|
||||||
pub entry_id: &'a str,
|
pub entry_id: &'a str,
|
||||||
pub has_data: bool,
|
pub has_data: bool,
|
||||||
// data provided by registry::write_codec
|
pub data: &'a [u8],
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> ClientPacket for CRegistryData<'a> {
|
impl<'a> ClientPacket for CRegistryData<'a> {
|
||||||
@ -118,7 +118,7 @@ impl<'a> ClientPacket for CRegistryData<'a> {
|
|||||||
bytebuf.put_list::<Entry>(self.entries, |p, v| {
|
bytebuf.put_list::<Entry>(self.entries, |p, v| {
|
||||||
p.put_string(v.entry_id);
|
p.put_string(v.entry_id);
|
||||||
p.put_bool(v.has_data);
|
p.put_bool(v.has_data);
|
||||||
registry::write_codec(p, -64, 384);
|
p.put_slice(v.data);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -18,20 +18,20 @@ impl ClientPacket for CPingResponse {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct CStatusResponse {
|
pub struct CStatusResponse<'a> {
|
||||||
json_response: String, // 32767
|
json_response: &'a str, // 32767
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CStatusResponse {
|
impl<'a> CStatusResponse<'a> {
|
||||||
pub fn new(json_response: String) -> Self {
|
pub fn new(json_response: &'a str) -> Self {
|
||||||
Self { json_response }
|
Self { json_response }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ClientPacket for CStatusResponse {
|
impl<'a> ClientPacket for CStatusResponse<'a> {
|
||||||
const PACKET_ID: VarInt = 0x00;
|
const PACKET_ID: VarInt = 0x00;
|
||||||
|
|
||||||
fn write(&self, bytebuf: &mut ByteBuffer) {
|
fn write(&self, bytebuf: &mut ByteBuffer) {
|
||||||
bytebuf.put_string(self.json_response.as_str());
|
bytebuf.put_string(self.json_response);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,7 +6,7 @@ use serde::Serialize;
|
|||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
pub mod bytebuf;
|
pub mod bytebuf;
|
||||||
mod registry;
|
pub mod registry;
|
||||||
|
|
||||||
pub mod client;
|
pub mod client;
|
||||||
pub mod server;
|
pub mod server;
|
||||||
|
|||||||
@ -2,25 +2,25 @@ use serde::{Deserialize, Serialize};
|
|||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
pub struct Dimension {
|
pub struct Dimension {
|
||||||
pub ambient_light: f32,
|
ambient_light: f32,
|
||||||
bed_works: i32,
|
bed_works: u8,
|
||||||
coordinate_scale: f64,
|
coordinate_scale: f64,
|
||||||
effects: DimensionEffects,
|
effects: DimensionEffects,
|
||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
fixed_time: Option<i32>,
|
fixed_time: Option<i64>,
|
||||||
has_ceiling: i32,
|
has_ceiling: u8,
|
||||||
has_raids: i32,
|
has_raids: u8,
|
||||||
has_skylight: i32,
|
has_skylight: u8,
|
||||||
height: i32,
|
height: i32,
|
||||||
infiniburn: String,
|
infiniburn: String,
|
||||||
logical_height: i32,
|
logical_height: i32,
|
||||||
min_y: i32,
|
min_y: i32,
|
||||||
monster_spawn_block_light_limit: i32,
|
monster_spawn_block_light_limit: i32,
|
||||||
monster_spawn_light_level: MonsterSpawnLightLevel,
|
monster_spawn_light_level: MonsterSpawnLightLevel,
|
||||||
natural: i32,
|
natural: u8,
|
||||||
piglin_safe: i32,
|
piglin_safe: u8,
|
||||||
respawn_anchor_works: i32,
|
respawn_anchor_works: u8,
|
||||||
ultrawarm: i32,
|
ultrawarm: u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Clone, Copy, PartialEq, Eq, Default, Debug)]
|
#[derive(Serialize, Deserialize, Clone, Copy, PartialEq, Eq, Default, Debug)]
|
||||||
@ -50,7 +50,12 @@ impl Default for Dimension {
|
|||||||
logical_height: 384,
|
logical_height: 384,
|
||||||
min_y: -64,
|
min_y: -64,
|
||||||
monster_spawn_block_light_limit: 0,
|
monster_spawn_block_light_limit: 0,
|
||||||
monster_spawn_light_level: MonsterSpawnLightLevel::Int(7),
|
monster_spawn_light_level: MonsterSpawnLightLevel::Tagged(
|
||||||
|
MonsterSpawnLightLevelTagged::Uniform {
|
||||||
|
min_inclusive: 7,
|
||||||
|
max_inclusive: 0,
|
||||||
|
},
|
||||||
|
),
|
||||||
natural: 1,
|
natural: 1,
|
||||||
piglin_safe: 0,
|
piglin_safe: 0,
|
||||||
respawn_anchor_works: 0,
|
respawn_anchor_works: 0,
|
||||||
|
|||||||
@ -1,10 +1,7 @@
|
|||||||
use core::str;
|
use dimensions::Dimension;
|
||||||
use std::{fs::File, io::Read};
|
use fastnbt::SerOpts;
|
||||||
|
|
||||||
use dimensions::{Dimension, DimensionEffects, MonsterSpawnLightLevel};
|
|
||||||
use fastnbt::{nbt, to_bytes_with_opts, SerOpts};
|
|
||||||
use flate2::read::GzDecoder;
|
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
use wolf::WolfVariant;
|
||||||
|
|
||||||
use super::bytebuf::ByteBuffer;
|
use super::bytebuf::ByteBuffer;
|
||||||
|
|
||||||
@ -12,11 +9,14 @@ mod biomes;
|
|||||||
mod chat_type;
|
mod chat_type;
|
||||||
mod damage_type;
|
mod damage_type;
|
||||||
mod dimensions;
|
mod dimensions;
|
||||||
|
mod wolf;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize)]
|
#[derive(Debug, Clone, Serialize)]
|
||||||
struct LoginInfo {
|
struct LoginInfo {
|
||||||
#[serde(rename = "minecraft:dimension_type")]
|
#[serde(rename = "minecraft:dimension_type")]
|
||||||
dimensions: Codec<dimensions::Dimension>,
|
dimensions: Codec<dimensions::Dimension>,
|
||||||
|
// #[serde(rename = "minecraft:wolf_variant")]
|
||||||
|
// wolf: Codec<wolf::WolfVariant>,
|
||||||
/* #[serde(rename = "minecraft:worldgen/biome")]
|
/* #[serde(rename = "minecraft:worldgen/biome")]
|
||||||
biomes: Codec<biomes::Biome>,
|
biomes: Codec<biomes::Biome>,
|
||||||
#[serde(rename = "minecraft:chat_type")]
|
#[serde(rename = "minecraft:chat_type")]
|
||||||
@ -25,6 +25,52 @@ struct LoginInfo {
|
|||||||
damage: Codec<damage_type::DamageType>, */
|
damage: Codec<damage_type::DamageType>, */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize)]
|
||||||
|
pub struct DimensionCodec {
|
||||||
|
#[serde(rename = "minecraft:dimension_type")]
|
||||||
|
dimensions: Codec<dimensions::Dimension>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DimensionCodec {
|
||||||
|
pub fn parse() -> Vec<u8> {
|
||||||
|
let dimension = Dimension::default();
|
||||||
|
let codec = DimensionCodec {
|
||||||
|
dimensions: Codec {
|
||||||
|
ty: "minecraft:dimension_type".into(),
|
||||||
|
value: vec![RegistryValue {
|
||||||
|
name: "minecraft:overworld".into(),
|
||||||
|
id: 0,
|
||||||
|
element: dimension,
|
||||||
|
}],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
fastnbt::to_bytes_with_opts(&codec, SerOpts::network_nbt()).unwrap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize)]
|
||||||
|
pub struct WolfCodec {
|
||||||
|
#[serde(rename = "minecraft:wolf_variant")]
|
||||||
|
wolf: Codec<wolf::WolfVariant>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WolfCodec {
|
||||||
|
pub fn parse() -> Vec<u8> {
|
||||||
|
let wolf = WolfVariant::default();
|
||||||
|
let codec = WolfCodec {
|
||||||
|
wolf: Codec {
|
||||||
|
ty: "minecraft:wolf_variant".into(),
|
||||||
|
value: vec![RegistryValue {
|
||||||
|
name: "minecraft:wolf_variant".into(),
|
||||||
|
id: 0,
|
||||||
|
element: wolf,
|
||||||
|
}],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
fastnbt::to_bytes_with_opts(&codec, SerOpts::network_nbt()).unwrap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize)]
|
#[derive(Debug, Clone, Serialize)]
|
||||||
struct Codec<T> {
|
struct Codec<T> {
|
||||||
#[serde(rename = "type")]
|
#[serde(rename = "type")]
|
||||||
@ -33,13 +79,14 @@ struct Codec<T> {
|
|||||||
}
|
}
|
||||||
#[derive(Debug, Clone, Serialize)]
|
#[derive(Debug, Clone, Serialize)]
|
||||||
struct RegistryValue<T> {
|
struct RegistryValue<T> {
|
||||||
id: i32,
|
|
||||||
name: String,
|
name: String,
|
||||||
|
id: i32,
|
||||||
element: T,
|
element: T,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_codec(out: &mut ByteBuffer, world_min_y: i32, world_height: u32) {
|
pub fn write_codec(out: &mut ByteBuffer, world_min_y: i32, world_height: u32) -> Vec<u8> {
|
||||||
let dimension = Dimension::default();
|
let dimension = Dimension::default();
|
||||||
|
let wolf = WolfVariant::default();
|
||||||
|
|
||||||
let info = LoginInfo {
|
let info = LoginInfo {
|
||||||
dimensions: Codec {
|
dimensions: Codec {
|
||||||
@ -50,7 +97,14 @@ pub fn write_codec(out: &mut ByteBuffer, world_min_y: i32, world_height: u32) {
|
|||||||
element: dimension,
|
element: dimension,
|
||||||
}],
|
}],
|
||||||
},
|
},
|
||||||
/* biomes: Codec {
|
/* wolf: Codec {
|
||||||
|
ty: "minecraft:wolf_variant".into(),
|
||||||
|
value: vec![RegistryValue {
|
||||||
|
name: "minecraft:wolf_variant".into(),
|
||||||
|
id: 0,
|
||||||
|
element: wolf,
|
||||||
|
}],
|
||||||
|
}, */ /* biomes: Codec {
|
||||||
ty: "minecraft:worldgen/biome".into(),
|
ty: "minecraft:worldgen/biome".into(),
|
||||||
value: biomes::all(),
|
value: biomes::all(),
|
||||||
},
|
},
|
||||||
@ -64,8 +118,5 @@ pub fn write_codec(out: &mut ByteBuffer, world_min_y: i32, world_height: u32) {
|
|||||||
}, */
|
}, */
|
||||||
};
|
};
|
||||||
|
|
||||||
let val = &fastnbt::to_bytes_with_opts(&info, SerOpts::network_nbt()).unwrap();
|
fastnbt::to_bytes_with_opts(&info, SerOpts::network_nbt()).unwrap()
|
||||||
dbg!(val);
|
|
||||||
// Dimension codec
|
|
||||||
out.put_slice(val);
|
|
||||||
}
|
}
|
||||||
|
|||||||
20
pumpkin/src/protocol/registry/wolf.rs
Normal file
20
pumpkin/src/protocol/registry/wolf.rs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct WolfVariant {
|
||||||
|
wild_texture: String,
|
||||||
|
tame_texture: String,
|
||||||
|
angry_texture: String,
|
||||||
|
biomes: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for WolfVariant {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
wild_texture: "minecraft:entity/wolf/wolf_ashen".to_string(),
|
||||||
|
tame_texture: "minecraft:entity/wolf/wolf_ashen_tame".to_string(),
|
||||||
|
angry_texture: "minecraft:entity/wolf/wolf_ashen_angry".to_string(),
|
||||||
|
biomes: "minecraft:snowy_taiga".to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -31,11 +31,18 @@ pub struct Server {
|
|||||||
pub private_key: RsaPrivateKey,
|
pub private_key: RsaPrivateKey,
|
||||||
pub public_key_der: Box<[u8]>,
|
pub public_key_der: Box<[u8]>,
|
||||||
|
|
||||||
|
/// the maximum amount of players that can join the Server
|
||||||
pub max_players: u32,
|
pub max_players: u32,
|
||||||
|
|
||||||
pub world: World,
|
pub world: World,
|
||||||
|
|
||||||
pub status_response: StatusResponse,
|
pub status_response: StatusResponse,
|
||||||
|
// We cache the json response here so we don't parse it every time someone makes a Status request.
|
||||||
|
// Keep in mind that we must parse this again, when the StatusResponse changes which usally happen when a player joins or leaves
|
||||||
|
pub status_response_json: String,
|
||||||
|
|
||||||
|
/// Cache the Server brand buffer so we don't have to rebuild them every time a player joins
|
||||||
|
pub cached_server_brand: Vec<u8>,
|
||||||
|
|
||||||
// todo replace with HashMap <World, Player>
|
// todo replace with HashMap <World, Player>
|
||||||
entity_id: AtomicI32, // todo: place this into every world
|
entity_id: AtomicI32, // todo: place this into every world
|
||||||
@ -44,9 +51,11 @@ pub struct Server {
|
|||||||
|
|
||||||
impl Server {
|
impl Server {
|
||||||
pub fn new(config: (BasicConfiguration, AdvancedConfiguration)) -> Self {
|
pub fn new(config: (BasicConfiguration, AdvancedConfiguration)) -> Self {
|
||||||
let max_players = 20;
|
let status_response = Self::build_response(&config.0);
|
||||||
let config_clone = &config;
|
let status_response_json = serde_json::to_string(&status_response)
|
||||||
let status_response = Self::default_response(config_clone);
|
.expect("Failed to parse Status response into JSON");
|
||||||
|
|
||||||
|
let cached_server_brand = Self::build_brand();
|
||||||
|
|
||||||
// todo, only create when needed
|
// todo, only create when needed
|
||||||
let (public_key, private_key) = Self::generate_keys();
|
let (public_key, private_key) = Self::generate_keys();
|
||||||
@ -65,9 +74,11 @@ impl Server {
|
|||||||
encryption: config.1.encryption,
|
encryption: config.1.encryption,
|
||||||
compression_threshold: None, // 256
|
compression_threshold: None, // 256
|
||||||
public_key,
|
public_key,
|
||||||
|
cached_server_brand,
|
||||||
private_key,
|
private_key,
|
||||||
max_players,
|
max_players: config.0.max_plyers,
|
||||||
status_response,
|
status_response,
|
||||||
|
status_response_json,
|
||||||
public_key_der,
|
public_key_der,
|
||||||
difficulty: config.0.default_difficulty,
|
difficulty: config.0.default_difficulty,
|
||||||
}
|
}
|
||||||
@ -127,21 +138,23 @@ impl Server {
|
|||||||
self.entity_id.fetch_add(1, Ordering::SeqCst)
|
self.entity_id.fetch_add(1, Ordering::SeqCst)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn send_brand(client: &mut Client) -> Result<(), PacketError> {
|
pub fn build_brand() -> Vec<u8> {
|
||||||
// send server brand
|
|
||||||
let brand = "pumpkin";
|
let brand = "pumpkin";
|
||||||
let mut buf = vec![];
|
let mut buf = vec![];
|
||||||
let _ = VarInt32(brand.len() as i32).encode(&mut buf);
|
let _ = VarInt32(brand.len() as i32).encode(&mut buf);
|
||||||
buf.extend_from_slice(brand.as_bytes());
|
buf.extend_from_slice(brand.as_bytes());
|
||||||
|
buf
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn send_brand(&self, client: &mut Client) -> Result<(), PacketError> {
|
||||||
|
// send server brand
|
||||||
client.send_packet(CPluginMessage::new(
|
client.send_packet(CPluginMessage::new(
|
||||||
"minecraft:brand".to_string(),
|
"minecraft:brand",
|
||||||
buf.as_slice(),
|
&self.cached_server_brand,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn default_response(
|
pub fn build_response(config: &BasicConfiguration) -> StatusResponse {
|
||||||
config: &(BasicConfiguration, AdvancedConfiguration),
|
|
||||||
) -> StatusResponse {
|
|
||||||
let path = concat!(env!("CARGO_MANIFEST_DIR"), "/icon.png");
|
let path = concat!(env!("CARGO_MANIFEST_DIR"), "/icon.png");
|
||||||
|
|
||||||
StatusResponse {
|
StatusResponse {
|
||||||
@ -150,14 +163,14 @@ impl Server {
|
|||||||
protocol: 767,
|
protocol: 767,
|
||||||
},
|
},
|
||||||
players: Players {
|
players: Players {
|
||||||
max: config.0.max_plyers,
|
max: config.max_plyers,
|
||||||
online: 0,
|
online: 0,
|
||||||
sample: vec![Sample {
|
sample: vec![Sample {
|
||||||
name: "".into(),
|
name: "".into(),
|
||||||
id: "".into(),
|
id: "".into(),
|
||||||
}],
|
}],
|
||||||
},
|
},
|
||||||
description: config.0.motd.clone(),
|
description: config.motd.clone(),
|
||||||
favicon: Self::load_icon(path),
|
favicon: Self::load_icon(path),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user