mirror of
https://github.com/Pumpkin-MC/Pumpkin.git
synced 2026-08-30 20:14:23 +00:00
improve Status Response
This commit is contained in:
122
Cargo.lock
generated
122
Cargo.lock
generated
@@ -2,12 +2,54 @@
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "adler"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0"
|
||||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
version = "0.22.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "bytemuck"
|
||||
version = "1.16.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b236fc92302c97ed75b38da1f4917b5cdda4984745740f153a5d3059e48d725e"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder-lite"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "colored"
|
||||
version = "2.1.0"
|
||||
@@ -18,6 +60,15 @@ dependencies = [
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crc32fast"
|
||||
version = "1.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-channel"
|
||||
version = "0.5.13"
|
||||
@@ -42,12 +93,43 @@ dependencies = [
|
||||
"powerfmt",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fdeflate"
|
||||
version = "0.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4f9bfee30e4dedf0ab8b422f03af778d9612b63f502710fc500a334ebe2de645"
|
||||
dependencies = [
|
||||
"simd-adler32",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "flate2"
|
||||
version = "1.0.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5f54427cfd1c7829e2a139fcefea601bf088ebca651d2bf53ebc600eac295dae"
|
||||
dependencies = [
|
||||
"crc32fast",
|
||||
"miniz_oxide",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024"
|
||||
|
||||
[[package]]
|
||||
name = "image"
|
||||
version = "0.25.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "99314c8a2152b8ddb211f924cdae532d8c5e4c8bb54728e12fff1b0cd5963a10"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
"byteorder-lite",
|
||||
"num-traits",
|
||||
"png",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.11"
|
||||
@@ -72,6 +154,16 @@ version = "0.4.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c"
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08"
|
||||
dependencies = [
|
||||
"adler",
|
||||
"simd-adler32",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mio"
|
||||
version = "1.0.1"
|
||||
@@ -91,6 +183,15 @@ version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9"
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_threads"
|
||||
version = "0.1.7"
|
||||
@@ -100,6 +201,19 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "png"
|
||||
version = "0.17.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "06e4b0d3d1312775e782c86c91a111aa1f910cbb65e1337f9975b5f9a554b5e1"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"crc32fast",
|
||||
"fdeflate",
|
||||
"flate2",
|
||||
"miniz_oxide",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "powerfmt"
|
||||
version = "0.2.0"
|
||||
@@ -119,8 +233,10 @@ dependencies = [
|
||||
name = "pumpkin"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"byteorder",
|
||||
"crossbeam-channel",
|
||||
"image",
|
||||
"log",
|
||||
"mio",
|
||||
"serde",
|
||||
@@ -175,6 +291,12 @@ dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "simd-adler32"
|
||||
version = "0.3.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe"
|
||||
|
||||
[[package]]
|
||||
name = "simple_logger"
|
||||
version = "5.0.0"
|
||||
|
||||
@@ -8,6 +8,9 @@ edition = "2021"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
|
||||
base64 = "0.22.1"
|
||||
image = { version = "0.25", default-features = false, features = ["png"]}
|
||||
|
||||
simple_logger = "5.0.0"
|
||||
log = "0.4"
|
||||
byteorder = "1"
|
||||
|
||||
BIN
pumpkin/icon.png
Normal file
BIN
pumpkin/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 277 B |
@@ -1,10 +1,11 @@
|
||||
|
||||
|
||||
use crate::protocol::{
|
||||
client::status::{CPingResponse, CStatusResponse},
|
||||
server::{
|
||||
handshake::SHandShake,
|
||||
status::{SPingRequest, SStatusRequest},
|
||||
},
|
||||
StatusResponse, Version,
|
||||
};
|
||||
|
||||
use super::Client;
|
||||
@@ -26,15 +27,9 @@ impl ClientPacketProcessor for Client {
|
||||
|
||||
fn handle_status_request(&mut self, _status_request: SStatusRequest) {
|
||||
dbg!("sending status");
|
||||
let response = StatusResponse {
|
||||
version: Version {
|
||||
version: "1.21".into(),
|
||||
protocol: 767,
|
||||
},
|
||||
description: "Pumpkin Server".into(),
|
||||
};
|
||||
|
||||
self.send_packet(CStatusResponse::new(
|
||||
serde_json::to_string(&response).unwrap(),
|
||||
serde_json::to_string(&self.server.status_response).unwrap(),
|
||||
))
|
||||
}
|
||||
|
||||
|
||||
@@ -1,14 +1,18 @@
|
||||
use std::{
|
||||
collections::VecDeque,
|
||||
io::{self, Write},
|
||||
rc::Rc,
|
||||
};
|
||||
|
||||
use crate::protocol::{
|
||||
server::{
|
||||
handshake::SHandShake,
|
||||
status::{SPingRequest, SStatusRequest},
|
||||
use crate::{
|
||||
protocol::{
|
||||
server::{
|
||||
handshake::SHandShake,
|
||||
status::{SPingRequest, SStatusRequest},
|
||||
},
|
||||
ClientPacket, RawPacket,
|
||||
},
|
||||
ClientPacket, RawPacket,
|
||||
server::Server,
|
||||
};
|
||||
|
||||
use crate::protocol::{bytebuf::buffer::ByteBuffer, ConnectionState};
|
||||
@@ -21,6 +25,7 @@ pub mod player;
|
||||
use client_packet::ClientPacketProcessor;
|
||||
|
||||
pub struct Client {
|
||||
pub server: Rc<Server>,
|
||||
pub connection_state: ConnectionState,
|
||||
pub closed: bool,
|
||||
pub connection: TcpStream,
|
||||
@@ -29,8 +34,9 @@ pub struct Client {
|
||||
}
|
||||
|
||||
impl Client {
|
||||
pub fn new(connection: TcpStream) -> Self {
|
||||
pub fn new(server: Rc<Server>, connection: TcpStream) -> Self {
|
||||
Self {
|
||||
server,
|
||||
connection_state: ConnectionState::HandShake,
|
||||
connection,
|
||||
closed: false,
|
||||
|
||||
@@ -8,10 +8,14 @@ const SERVER: Token = Token(0);
|
||||
|
||||
pub mod client;
|
||||
pub mod protocol;
|
||||
pub mod server;
|
||||
|
||||
#[cfg(not(target_os = "wasi"))]
|
||||
fn main() -> io::Result<()> {
|
||||
use std::rc::Rc;
|
||||
|
||||
use client::{interrupted, Client};
|
||||
use server::Server;
|
||||
|
||||
simple_logger::SimpleLogger::new().init().unwrap();
|
||||
|
||||
@@ -22,11 +26,11 @@ fn main() -> io::Result<()> {
|
||||
|
||||
// Setup the TCP server socket.
|
||||
let addr = "127.0.0.1:25565".parse().unwrap();
|
||||
let mut server = TcpListener::bind(addr)?;
|
||||
let mut listener = TcpListener::bind(addr)?;
|
||||
|
||||
// Register the server with poll we can receive events for it.
|
||||
poll.registry()
|
||||
.register(&mut server, SERVER, Interest::READABLE)?;
|
||||
.register(&mut listener, SERVER, Interest::READABLE)?;
|
||||
|
||||
// Map of `Token` -> `TcpStream`.
|
||||
let mut connections = HashMap::new();
|
||||
@@ -35,7 +39,8 @@ fn main() -> io::Result<()> {
|
||||
|
||||
log::info!("You can connect to the server using `nc`:");
|
||||
log::info!(" $ nc 127.0.0.1 9000");
|
||||
log::info!("You'll see our welcome message and anything you type will be printed here.");
|
||||
|
||||
let server = Rc::new(Server::new());
|
||||
|
||||
loop {
|
||||
if let Err(err) = poll.poll(&mut events, None) {
|
||||
@@ -50,7 +55,7 @@ fn main() -> io::Result<()> {
|
||||
SERVER => loop {
|
||||
// Received an event for the TCP server socket, which
|
||||
// indicates we can accept an connection.
|
||||
let (mut connection, address) = match server.accept() {
|
||||
let (mut connection, address) = match listener.accept() {
|
||||
Ok((connection, address)) => (connection, address),
|
||||
Err(e) if e.kind() == io::ErrorKind::WouldBlock => {
|
||||
// If we get a `WouldBlock` error we know our
|
||||
@@ -75,7 +80,7 @@ fn main() -> io::Result<()> {
|
||||
Interest::READABLE.add(Interest::WRITABLE),
|
||||
)?;
|
||||
|
||||
connections.insert(token, Client::new(connection));
|
||||
connections.insert(token, Client::new(Rc::clone(&server), connection));
|
||||
},
|
||||
token => {
|
||||
// Maybe received an event for a TCP connection.
|
||||
|
||||
@@ -44,11 +44,26 @@ pub trait ClientPacket {
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct StatusResponse {
|
||||
pub version: Version,
|
||||
pub players: Players,
|
||||
pub description: String,
|
||||
// Players, favicon ...
|
||||
pub favicon: String, // data:image/png;base64,<data>
|
||||
// Players, favicon ...
|
||||
}
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct Version {
|
||||
pub version: String,
|
||||
pub name: String,
|
||||
pub protocol: u32,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct Players {
|
||||
pub max: u32,
|
||||
pub online: u32,
|
||||
pub sample: Sample,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct Sample {
|
||||
pub name: String,
|
||||
pub id: String, // uuid
|
||||
}
|
||||
|
||||
53
pumpkin/src/server.rs
Normal file
53
pumpkin/src/server.rs
Normal file
@@ -0,0 +1,53 @@
|
||||
use std::io::Cursor;
|
||||
|
||||
use base64::{engine::general_purpose, Engine};
|
||||
|
||||
use crate::protocol::{Players, Sample, StatusResponse, Version};
|
||||
|
||||
pub struct Server {
|
||||
pub status_response: StatusResponse,
|
||||
}
|
||||
|
||||
impl Default for Server {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl Server {
|
||||
pub fn new() -> Self {
|
||||
let path = concat!(env!("CARGO_MANIFEST_DIR"), "/icon.png");
|
||||
|
||||
let status_response = StatusResponse {
|
||||
version: Version {
|
||||
name: "1.21".into(),
|
||||
protocol: 767,
|
||||
},
|
||||
players: Players {
|
||||
max: 20,
|
||||
online: 0,
|
||||
sample: Sample {
|
||||
name: "".into(),
|
||||
id: "".into(),
|
||||
},
|
||||
},
|
||||
description: "Pumpkin Server".into(),
|
||||
favicon: Self::load_icon(path),
|
||||
};
|
||||
Self { status_response }
|
||||
}
|
||||
|
||||
pub fn load_icon(path: &str) -> String {
|
||||
let mut icon = match image::open(path).map_err(|e| panic!("error loading icon: {}", e)) {
|
||||
Ok(icon) => icon,
|
||||
Err(_) => return "".into(),
|
||||
};
|
||||
icon = icon.resize_exact(64, 64, image::imageops::FilterType::Triangle);
|
||||
let mut image = Vec::new();
|
||||
icon.write_to(&mut Cursor::new(&mut image), image::ImageFormat::Png)
|
||||
.unwrap();
|
||||
let mut result = "data:image/png;base64,".to_owned();
|
||||
general_purpose::STANDARD.encode_string(image, &mut result);
|
||||
result
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user