Add extension information commands
This commit is contained in:
parent
7ab11f7f54
commit
a58b1c9afe
@ -54,7 +54,11 @@ pub fn handle_command(
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
let found = match extensions.run_command(vectorized_command[0].to_string(), client_number) {
|
||||
let found = match extensions.run_command(
|
||||
vectorized_command[0].to_string(),
|
||||
client_number,
|
||||
stream,
|
||||
) {
|
||||
Ok(result) => result,
|
||||
Err(error) => {
|
||||
error!("Rhai plugin error: {}", error);
|
||||
|
@ -5,19 +5,74 @@ use std::{
|
||||
collections::HashMap,
|
||||
ffi::OsStr,
|
||||
fs,
|
||||
net::TcpStream,
|
||||
path::Path,
|
||||
sync::{Arc, Mutex},
|
||||
};
|
||||
|
||||
use crate::{error::AppError, player::Player, utils::send_chat_message};
|
||||
use crate::{
|
||||
error::AppError,
|
||||
player::Player,
|
||||
utils::{send_chat_message, write_chat_stream},
|
||||
};
|
||||
|
||||
pub struct Extensions {
|
||||
extensions: Vec<Extension>,
|
||||
}
|
||||
|
||||
impl Extensions {
|
||||
pub fn run_command(&self, key: String, player: u8) -> Result<bool, AppError> {
|
||||
// Bool success
|
||||
pub fn run_command(
|
||||
&self,
|
||||
key: String,
|
||||
player: u8,
|
||||
stream: &mut TcpStream,
|
||||
) -> Result<bool, AppError> {
|
||||
// Here I'm calling write_chat_stream multiple times. This is because the stock minecraft
|
||||
// chat has a length limit of 64 characters, which is pathetically small. There is a
|
||||
// classic extension to support an unlimited number of characters, but it's not guaranteed
|
||||
// that the client will support it, so the next best option is to just send multiple
|
||||
// messages, they're newline seperated anyway. I am aware that repeated stream writes are
|
||||
// not the best option however, and that at some point I should switch to buffered streams.
|
||||
// TODO: Use buffered streams (That's everywhere not just here)
|
||||
|
||||
// Reserve extension listing command
|
||||
if &key == "extensions" {
|
||||
let _ = write_chat_stream(stream, "Extension listing".to_string());
|
||||
|
||||
for extension in &self.extensions {
|
||||
let _ = write_chat_stream(
|
||||
stream,
|
||||
format!(
|
||||
"&a{} &bv{}",
|
||||
extension.metadata.name,
|
||||
extension.metadata.version.display()
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return Ok(true);
|
||||
}
|
||||
|
||||
// Reserve command listing command
|
||||
if &key == "commands" {
|
||||
let _ = write_chat_stream(stream, "Command listing".to_string());
|
||||
|
||||
for extension in &self.extensions {
|
||||
for command in extension.commands.keys() {
|
||||
let _ = write_chat_stream(
|
||||
stream,
|
||||
format!(
|
||||
"&c{} &a[{}]",
|
||||
command,
|
||||
extension.metadata.name
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return Ok(true);
|
||||
}
|
||||
|
||||
for extension in &self.extensions {
|
||||
if let Some(key_value) = extension.commands.get(&key) {
|
||||
key_value.call::<()>(&extension.engine, &extension.ast, (player,))?;
|
||||
@ -233,7 +288,7 @@ impl Extensions {
|
||||
&mut scope,
|
||||
¤t_extension.ast,
|
||||
"init",
|
||||
(PlayersWrapper::new(players.0.clone()),)
|
||||
(PlayersWrapper::new(players.0.clone()),),
|
||||
) {
|
||||
Ok(result) => result,
|
||||
Err(error) => {
|
||||
|
16
src/extensions/ping-pong.rhai
Normal file
16
src/extensions/ping-pong.rhai
Normal file
@ -0,0 +1,16 @@
|
||||
fn metadata() {
|
||||
Metadata("ping-pong", Version("1.0.0"))
|
||||
}
|
||||
|
||||
fn init(players) {
|
||||
let ctx = Context(players);
|
||||
|
||||
ctx.register_command("ping", |player| {
|
||||
players.send_message(player, "pong")
|
||||
});
|
||||
ctx.register_command("foo", |player| {
|
||||
players.send_message(player, "bar")
|
||||
});
|
||||
|
||||
ctx
|
||||
}
|
23
src/utils.rs
23
src/utils.rs
@ -6,9 +6,9 @@ use std::net::TcpStream;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use crate::error::AppError;
|
||||
use crate::World;
|
||||
use crate::SpecialPlayers;
|
||||
use crate::Player;
|
||||
use crate::SpecialPlayers;
|
||||
use crate::World;
|
||||
|
||||
pub fn to_mc_string(text: &str) -> [u8; 64] {
|
||||
let text_vec: Vec<char> = text.chars().take(64).collect();
|
||||
@ -104,7 +104,11 @@ pub fn despawn_player(player_id: u8) -> Vec<u8> {
|
||||
[0x0C, player_id].to_vec()
|
||||
}
|
||||
|
||||
pub fn send_chat_message(source_id: u8, mut source_username: String, mut message: String) -> Vec<u8> {
|
||||
pub fn send_chat_message(
|
||||
source_id: u8,
|
||||
mut source_username: String,
|
||||
mut message: String,
|
||||
) -> Vec<u8> {
|
||||
let mut ret_val: Vec<u8> = vec![];
|
||||
ret_val.push(0x0D);
|
||||
|
||||
@ -119,6 +123,14 @@ pub fn send_chat_message(source_id: u8, mut source_username: String, mut message
|
||||
ret_val
|
||||
}
|
||||
|
||||
pub fn write_chat_stream(stream: &mut TcpStream, message: String) {
|
||||
let _ = stream.write(&send_chat_message(
|
||||
SpecialPlayers::SelfPlayer as u8,
|
||||
"".to_string(),
|
||||
message,
|
||||
));
|
||||
}
|
||||
|
||||
pub fn set_position_and_orientation(
|
||||
player_id: u8,
|
||||
pos_x: i16,
|
||||
@ -189,9 +201,7 @@ pub fn send_level_data(world_arc_clone: &Arc<Mutex<World>>) -> Result<Vec<u8>, A
|
||||
if remaining_chunk_size > 0 {
|
||||
ret_val.push(0x03);
|
||||
|
||||
ret_val.append(&mut stream_write_short(
|
||||
remaining_chunk_size.try_into()?,
|
||||
));
|
||||
ret_val.append(&mut stream_write_short(remaining_chunk_size.try_into()?));
|
||||
|
||||
let mut remaining_data_buffer = [0u8; 1024];
|
||||
for i in 0..remaining_chunk_size {
|
||||
@ -238,4 +248,3 @@ pub fn bomb_server_details(
|
||||
let _ = stream.write(&compound_data);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -2,6 +2,8 @@ use std::fs::{self, File};
|
||||
use std::io::Write;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use log::info;
|
||||
|
||||
use crate::error::AppError;
|
||||
|
||||
#[derive(Debug)]
|
||||
@ -61,8 +63,10 @@ impl World {
|
||||
}
|
||||
|
||||
world.data = world_data_raw[6..].to_vec();
|
||||
info!("Loaded world {}", "world.wrld");
|
||||
Ok(world)
|
||||
} else {
|
||||
info!("Creating word {}", "world.wrld");
|
||||
Ok(World {
|
||||
size_x: 64,
|
||||
size_y: 32,
|
||||
@ -75,7 +79,9 @@ impl World {
|
||||
pub fn save(world_arc_clone: Arc<Mutex<World>>) -> Result<(), AppError> {
|
||||
let mut to_write: Vec<u8> = Vec::new();
|
||||
{
|
||||
let mut world_dat = world_arc_clone.lock().map_err(|e| AppError::MutexPoisoned(e.to_string()))?;
|
||||
let mut world_dat = world_arc_clone
|
||||
.lock()
|
||||
.map_err(|e| AppError::MutexPoisoned(e.to_string()))?;
|
||||
|
||||
to_write.push((world_dat.size_x >> 8) as u8);
|
||||
to_write.push((world_dat.size_x & 0xFF) as u8);
|
||||
|
Loading…
Reference in New Issue
Block a user