What does this mean?
This commit is contained in:
parent
f4a75deba7
commit
54d23ed073
@ -15,7 +15,7 @@ pub fn handle_command(
|
|||||||
extensions: &Arc<Extensions>,
|
extensions: &Arc<Extensions>,
|
||||||
command_string: &String,
|
command_string: &String,
|
||||||
) -> Result<(), AppError> {
|
) -> Result<(), AppError> {
|
||||||
let vectorized_command = command_string.split(" ").collect::<Vec<&str>>();
|
let vectorized_command = command_string.trim().split(" ").collect::<Vec<&str>>();
|
||||||
match vectorized_command[0] {
|
match vectorized_command[0] {
|
||||||
"kick" => {
|
"kick" => {
|
||||||
let mut players = players_arc_clone
|
let mut players = players_arc_clone
|
||||||
@ -54,9 +54,16 @@ pub fn handle_command(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
|
let mut vectorized_command_object: Vec<String> = Vec::new();
|
||||||
|
|
||||||
|
for arg in &vectorized_command {
|
||||||
|
vectorized_command_object.push(arg.to_string());
|
||||||
|
}
|
||||||
|
|
||||||
let found = match extensions.run_command(
|
let found = match extensions.run_command(
|
||||||
vectorized_command[0].to_string(),
|
vectorized_command[0].to_string(),
|
||||||
client_number,
|
client_number,
|
||||||
|
vectorized_command_object,
|
||||||
stream,
|
stream,
|
||||||
) {
|
) {
|
||||||
Ok(result) => result,
|
Ok(result) => result,
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
use log::{error, info};
|
use log::{error, info, warn, debug};
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use rhai::{CustomType, Engine, EvalAltResult, FnPtr, Scope, TypeBuilder, AST};
|
use rhai::{CustomType, Engine, EvalAltResult, FnPtr, Scope, TypeBuilder, AST};
|
||||||
use std::{
|
use std::{
|
||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
ffi::OsStr,
|
ffi::OsStr,
|
||||||
fs,
|
fmt, fs,
|
||||||
net::TcpStream,
|
net::TcpStream,
|
||||||
path::Path,
|
path::Path,
|
||||||
sync::{Arc, Mutex},
|
sync::{Arc, Mutex},
|
||||||
@ -25,6 +25,7 @@ impl Extensions {
|
|||||||
&self,
|
&self,
|
||||||
key: String,
|
key: String,
|
||||||
player: u8,
|
player: u8,
|
||||||
|
argv: Vec<String>,
|
||||||
stream: &mut TcpStream,
|
stream: &mut TcpStream,
|
||||||
) -> Result<bool, AppError> {
|
) -> Result<bool, AppError> {
|
||||||
// Here I'm calling write_chat_stream multiple times. This is because the stock minecraft
|
// Here I'm calling write_chat_stream multiple times. This is because the stock minecraft
|
||||||
@ -44,8 +45,7 @@ impl Extensions {
|
|||||||
stream,
|
stream,
|
||||||
format!(
|
format!(
|
||||||
"&a{} &bv{}",
|
"&a{} &bv{}",
|
||||||
extension.metadata.name,
|
extension.metadata.name, extension.metadata.version
|
||||||
extension.metadata.version.display()
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -61,11 +61,7 @@ impl Extensions {
|
|||||||
for command in extension.commands.keys() {
|
for command in extension.commands.keys() {
|
||||||
let _ = write_chat_stream(
|
let _ = write_chat_stream(
|
||||||
stream,
|
stream,
|
||||||
format!(
|
format!("&c{} &a[{}]", command, extension.metadata.name),
|
||||||
"&c{} &a[{}]",
|
|
||||||
command,
|
|
||||||
extension.metadata.name
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -75,7 +71,17 @@ impl Extensions {
|
|||||||
|
|
||||||
for extension in &self.extensions {
|
for extension in &self.extensions {
|
||||||
if let Some(key_value) = extension.commands.get(&key) {
|
if let Some(key_value) = extension.commands.get(&key) {
|
||||||
key_value.call::<()>(&extension.engine, &extension.ast, (player,))?;
|
// Vector transfer number 2 (get the shit joke?)
|
||||||
|
let mut argv_rhai_array: rhai::Array = rhai::Array::new();
|
||||||
|
for arg in &argv {
|
||||||
|
argv_rhai_array.push(arg.into());
|
||||||
|
}
|
||||||
|
|
||||||
|
key_value.call::<()>(
|
||||||
|
&extension.engine,
|
||||||
|
&extension.ast,
|
||||||
|
(player, argv_rhai_array),
|
||||||
|
)?;
|
||||||
return Ok(true);
|
return Ok(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -92,6 +98,22 @@ pub struct Extension {
|
|||||||
}
|
}
|
||||||
|
|
||||||
////// BEGIN RHAI DEFINITIONS //////
|
////// BEGIN RHAI DEFINITIONS //////
|
||||||
|
fn info(msg: &str) {
|
||||||
|
info!("{}", msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn warn(msg: &str) {
|
||||||
|
warn!("{}", msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn error(msg: &str) {
|
||||||
|
error!("{}", msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn debug(msg: &str) {
|
||||||
|
debug!("{}", msg);
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Eq, PartialEq, CustomType)]
|
#[derive(Debug, Clone, Eq, PartialEq, CustomType)]
|
||||||
#[rhai_type(name = "Version", extra = Self::build_extra)]
|
#[rhai_type(name = "Version", extra = Self::build_extra)]
|
||||||
struct Version {
|
struct Version {
|
||||||
@ -153,16 +175,27 @@ impl Version {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for Version {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
write!(f, "{}", self.display())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Eq, PartialEq, CustomType)]
|
#[derive(Debug, Clone, Eq, PartialEq, CustomType)]
|
||||||
#[rhai_type(name = "Metadata", extra = Self::build_extra)]
|
#[rhai_type(name = "Metadata", extra = Self::build_extra)]
|
||||||
struct ExtensionMetadata {
|
struct ExtensionMetadata {
|
||||||
name: String,
|
name: String,
|
||||||
|
author: String,
|
||||||
version: Version,
|
version: Version,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ExtensionMetadata {
|
impl ExtensionMetadata {
|
||||||
fn new(name: String, version: Version) -> Self {
|
fn new(name: String, author: String, version: Version) -> Self {
|
||||||
Self { name, version }
|
Self {
|
||||||
|
name,
|
||||||
|
author,
|
||||||
|
version,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_extra(builder: &mut TypeBuilder<Self>) {
|
fn build_extra(builder: &mut TypeBuilder<Self>) {
|
||||||
@ -196,8 +229,25 @@ impl PlayersWrapper {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn send_all(self, message: String) -> Result<(), Box<EvalAltResult>> {
|
||||||
|
let mut players = self.0.lock().unwrap();
|
||||||
|
|
||||||
|
let data = &send_chat_message(255, "".to_string(), message);
|
||||||
|
|
||||||
|
for i in 0..255 {
|
||||||
|
if players[i].id != 255 {
|
||||||
|
players[i]
|
||||||
|
.outgoing_data
|
||||||
|
.extend_from_slice(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
fn build_extra(builder: &mut TypeBuilder<Self>) {
|
fn build_extra(builder: &mut TypeBuilder<Self>) {
|
||||||
builder.with_fn("send_message", Self::send_message);
|
builder.with_fn("send_message", Self::send_message);
|
||||||
|
builder.with_fn("send_all", Self::send_all);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -206,12 +256,39 @@ impl PlayersWrapper {
|
|||||||
struct Context {
|
struct Context {
|
||||||
#[rhai_type(skip)]
|
#[rhai_type(skip)]
|
||||||
commands: HashMap<String, FnPtr>,
|
commands: HashMap<String, FnPtr>,
|
||||||
|
#[rhai_type(skip)]
|
||||||
|
event_listener: HashMap<EventListener, FnPtr>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, CustomType)]
|
||||||
|
#[rhai_type(name = "Vec3", extra = Self::build_extra)]
|
||||||
|
struct Vec3 {
|
||||||
|
x: i64,
|
||||||
|
y: i64,
|
||||||
|
z: i64,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Custom type API
|
||||||
|
impl Vec3 {
|
||||||
|
fn new(x: i64, y: i64, z: i64) -> Self {
|
||||||
|
Self { x, y, z }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build_extra(builder: &mut TypeBuilder<Self>) {
|
||||||
|
builder.with_fn("Vec3", Self::new);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Eq, Hash, PartialEq)]
|
||||||
|
enum EventListener {
|
||||||
|
BlockBreak,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Context {
|
impl Context {
|
||||||
fn new() -> Self {
|
fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
commands: HashMap::new(),
|
commands: HashMap::new(),
|
||||||
|
event_listener: HashMap::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -219,9 +296,18 @@ impl Context {
|
|||||||
self.commands.insert(name, callback);
|
self.commands.insert(name, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn add_event_listener(&mut self, event: &str, callback: FnPtr) {
|
||||||
|
let event_listener: EventListener = match event {
|
||||||
|
"block_break" => EventListener::BlockBreak,
|
||||||
|
_ => return,
|
||||||
|
};
|
||||||
|
self.event_listener.insert(event_listener, callback);
|
||||||
|
}
|
||||||
|
|
||||||
fn build_extra(builder: &mut TypeBuilder<Self>) {
|
fn build_extra(builder: &mut TypeBuilder<Self>) {
|
||||||
builder.with_fn("Context", Self::new);
|
builder.with_fn("Context", Self::new);
|
||||||
builder.with_fn("register_command", Self::register_command);
|
builder.with_fn("register_command", Self::register_command);
|
||||||
|
builder.with_fn("add_event_listener", Self::add_event_listener);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
////// END RHAI DEFINITIONS //////
|
////// END RHAI DEFINITIONS //////
|
||||||
@ -252,8 +338,21 @@ impl Extensions {
|
|||||||
engine.build_type::<RhaiPlayer>();
|
engine.build_type::<RhaiPlayer>();
|
||||||
engine.build_type::<PlayersWrapper>();
|
engine.build_type::<PlayersWrapper>();
|
||||||
engine.build_type::<Context>();
|
engine.build_type::<Context>();
|
||||||
|
engine.register_fn("info", info);
|
||||||
|
engine.register_fn("warn", warn);
|
||||||
|
engine.register_fn("error", error);
|
||||||
|
engine.register_fn("debug", debug);
|
||||||
|
|
||||||
let ast = engine.compile_file(extension_path.clone().into())?;
|
let ast = match engine.compile_file(extension_path.clone().into()) {
|
||||||
|
Ok(result) => result,
|
||||||
|
Err(error) => {
|
||||||
|
error!(
|
||||||
|
"Rhai plugin compilation failed for {}, reason: {}",
|
||||||
|
extension_path.display(), error
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
let mut scope = Scope::new();
|
let mut scope = Scope::new();
|
||||||
|
|
||||||
let extension_metadata =
|
let extension_metadata =
|
||||||
@ -300,8 +399,7 @@ impl Extensions {
|
|||||||
|
|
||||||
info!(
|
info!(
|
||||||
"Loaded {} v{}",
|
"Loaded {} v{}",
|
||||||
current_extension.metadata.name,
|
current_extension.metadata.name, current_extension.metadata.version,
|
||||||
current_extension.metadata.version.display()
|
|
||||||
);
|
);
|
||||||
|
|
||||||
extensions.extensions.push(current_extension);
|
extensions.extensions.push(current_extension);
|
||||||
@ -311,9 +409,7 @@ impl Extensions {
|
|||||||
for command_name in extension.commands.keys() {
|
for command_name in extension.commands.keys() {
|
||||||
info!(
|
info!(
|
||||||
"Extension {} v{} has reserved command: {}",
|
"Extension {} v{} has reserved command: {}",
|
||||||
extension.metadata.name,
|
extension.metadata.name, extension.metadata.version, command_name
|
||||||
extension.metadata.version.display(),
|
|
||||||
command_name
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
44
src/extensions/fill.rhai
Normal file
44
src/extensions/fill.rhai
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
fn metadata() {
|
||||||
|
Metadata("fill", "illegitimate-egg", Version("1.0.0")) // Version test util
|
||||||
|
}
|
||||||
|
|
||||||
|
fn init(players) {
|
||||||
|
let ctx = Context();
|
||||||
|
|
||||||
|
let playerData = #{};
|
||||||
|
|
||||||
|
ctx.register_command("fill", |player, argv| {
|
||||||
|
players.send_message(player, "Break two blocks to select area");
|
||||||
|
playerData[player].command_step == 1;
|
||||||
|
});
|
||||||
|
|
||||||
|
ctx.add_event_listener("block_break", |event| {
|
||||||
|
if playerData[event.player].command_step == () {
|
||||||
|
playerData[event.player].command_step == 0;
|
||||||
|
} else {
|
||||||
|
switch playerData[event.player].command_step {
|
||||||
|
0 => {
|
||||||
|
// Do nothing, the command isn't in use
|
||||||
|
}
|
||||||
|
1 => {
|
||||||
|
// Record the block position
|
||||||
|
playerData[event.player].firstBlock = event.position;
|
||||||
|
}
|
||||||
|
2 => {
|
||||||
|
playerData[event.player].secondBlock = event.position;
|
||||||
|
// TODO: Implement the fill
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
error("Unreachable reached");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// NOTE: Currently this doesn't work, as player_leave isn't implemented
|
||||||
|
ctx.add_event_listener("player_leave", |event| {
|
||||||
|
playerData[event.player].command_step = 0;
|
||||||
|
});
|
||||||
|
|
||||||
|
ctx
|
||||||
|
}
|
@ -1,11 +0,0 @@
|
|||||||
fn metadata() {
|
|
||||||
Metadata("jimmy", Version("2.0.0-balls+tweaking"))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn init(players) {
|
|
||||||
let ctx = Context();
|
|
||||||
ctx.register_command("jimmy", |player| {
|
|
||||||
players.send_message(player, "He's dead")
|
|
||||||
});
|
|
||||||
ctx
|
|
||||||
}
|
|
@ -1,14 +1,14 @@
|
|||||||
fn metadata() {
|
fn metadata() {
|
||||||
Metadata("ping-pong", Version("1.0.0"))
|
Metadata("ping-pong", "illegitimate-egg", Version("1.0.0"))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn init(players) {
|
fn init(players) {
|
||||||
let ctx = Context();
|
let ctx = Context();
|
||||||
|
|
||||||
ctx.register_command("ping", |player| {
|
ctx.register_command("ping", |player, argv| {
|
||||||
players.send_message(player, "pong")
|
players.send_message(player, "pong")
|
||||||
});
|
});
|
||||||
ctx.register_command("foo", |player| {
|
ctx.register_command("foo", |player, argv| {
|
||||||
players.send_message(player, "bar")
|
players.send_message(player, "bar")
|
||||||
});
|
});
|
||||||
|
|
||||||
|
13
src/extensions/utils.rhai
Normal file
13
src/extensions/utils.rhai
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
fn metadata() {
|
||||||
|
Metadata("utils", "illegitimate-egg", Version("1.2.3-testp+testb")) // Version test util
|
||||||
|
}
|
||||||
|
|
||||||
|
fn init(players) {
|
||||||
|
let ctx = Context();
|
||||||
|
|
||||||
|
ctx.register_command("args", |player, argv| {
|
||||||
|
players.send_message(player, "" + argv)
|
||||||
|
});
|
||||||
|
|
||||||
|
ctx
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user