mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Updated changelog, fmt and clippy fixes
This commit is contained in:
parent
9284aed8bd
commit
023888f560
@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- Added chat commands for inviting, kicking, leaving, and promoting in groups
|
- Added chat commands for inviting, kicking, leaving, and promoting in groups
|
||||||
- Aura system
|
- Aura system
|
||||||
- Campfire resting heal
|
- Campfire resting heal
|
||||||
|
- Initial support for game plugins, both server-side and client-side
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
|
@ -28,20 +28,20 @@ use common::{
|
|||||||
outcome::Outcome,
|
outcome::Outcome,
|
||||||
recipe::RecipeBook,
|
recipe::RecipeBook,
|
||||||
span,
|
span,
|
||||||
uid::{Uid, UidAllocator},
|
|
||||||
terrain::{block::Block, neighbors, BiomeKind, SitesKind, TerrainChunk, TerrainChunkSize},
|
terrain::{block::Block, neighbors, BiomeKind, SitesKind, TerrainChunk, TerrainChunkSize},
|
||||||
|
uid::{Uid, UidAllocator},
|
||||||
vol::RectVolSize,
|
vol::RectVolSize,
|
||||||
};
|
};
|
||||||
use common_sys::state::State;
|
|
||||||
use common_net::{
|
use common_net::{
|
||||||
msg::{
|
msg::{
|
||||||
self, validate_chat_msg, world_msg::SiteInfo, ChatMsgValidationError, ClientGeneral, ClientMsg,
|
self, validate_chat_msg, world_msg::SiteInfo, ChatMsgValidationError, ClientGeneral,
|
||||||
ClientRegister, ClientType, DisconnectReason, InviteAnswer, Notification, PingMsg,
|
ClientMsg, ClientRegister, ClientType, DisconnectReason, InviteAnswer, Notification,
|
||||||
PlayerInfo, PlayerListUpdate, PresenceKind, RegisterError, ServerGeneral, ServerInfo,
|
PingMsg, PlayerInfo, PlayerListUpdate, PresenceKind, RegisterError, ServerGeneral,
|
||||||
ServerInit, ServerRegisterAnswer, MAX_BYTES_CHAT_MSG,
|
ServerInfo, ServerInit, ServerRegisterAnswer, MAX_BYTES_CHAT_MSG,
|
||||||
},
|
},
|
||||||
sync::WorldSyncExt,
|
sync::WorldSyncExt,
|
||||||
};
|
};
|
||||||
|
use common_sys::state::State;
|
||||||
use comp::BuffKind;
|
use comp::BuffKind;
|
||||||
use futures_executor::block_on;
|
use futures_executor::block_on;
|
||||||
use futures_timer::Delay;
|
use futures_timer::Delay;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use common::comp;
|
|
||||||
use crate::sync;
|
use crate::sync;
|
||||||
|
use common::comp;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use sum_type::sum_type;
|
use sum_type::sum_type;
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
use super::{ClientType, EcsCompPacket, PingMsg};
|
use super::{ClientType, EcsCompPacket, PingMsg};
|
||||||
|
use crate::sync;
|
||||||
|
use authc::AuthClientError;
|
||||||
use common::{
|
use common::{
|
||||||
character::{self, CharacterItem},
|
character::{self, CharacterItem},
|
||||||
comp,
|
comp,
|
||||||
outcome::Outcome,
|
outcome::Outcome,
|
||||||
recipe::RecipeBook,
|
recipe::RecipeBook,
|
||||||
resources::TimeOfDay,
|
resources::TimeOfDay,
|
||||||
uid::Uid,
|
|
||||||
terrain::{Block, TerrainChunk},
|
terrain::{Block, TerrainChunk},
|
||||||
|
uid::Uid,
|
||||||
};
|
};
|
||||||
use crate::sync;
|
|
||||||
use authc::AuthClientError;
|
|
||||||
use hashbrown::HashMap;
|
use hashbrown::HashMap;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
@ -5,10 +5,10 @@ mod sync_ext;
|
|||||||
mod track;
|
mod track;
|
||||||
|
|
||||||
// Reexports
|
// Reexports
|
||||||
|
pub use common::uid::{Uid, UidAllocator};
|
||||||
pub use packet::{
|
pub use packet::{
|
||||||
handle_insert, handle_modify, handle_remove, CompPacket, CompSyncPackage, EntityPackage,
|
handle_insert, handle_modify, handle_remove, CompPacket, CompSyncPackage, EntityPackage,
|
||||||
EntitySyncPackage, StatePackage,
|
EntitySyncPackage, StatePackage,
|
||||||
};
|
};
|
||||||
pub use sync_ext::WorldSyncExt;
|
pub use sync_ext::WorldSyncExt;
|
||||||
pub use track::UpdateTracker;
|
pub use track::UpdateTracker;
|
||||||
pub use common::uid::{Uid, UidAllocator};
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use uuid::Uuid;
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use specs::{Component, FlaggedStorage, NullStorage};
|
use specs::{Component, FlaggedStorage, NullStorage};
|
||||||
use specs_idvs::IdvStorage;
|
use specs_idvs::IdvStorage;
|
||||||
|
use uuid::Uuid;
|
||||||
|
|
||||||
const MAX_ALIAS_LEN: usize = 32;
|
const MAX_ALIAS_LEN: usize = 32;
|
||||||
|
|
||||||
|
@ -4,11 +4,7 @@ use comp::{
|
|||||||
Ori, Pos,
|
Ori, Pos,
|
||||||
};
|
};
|
||||||
use specs::Entity as EcsEntity;
|
use specs::Entity as EcsEntity;
|
||||||
use std::{
|
use std::{collections::VecDeque, ops::DerefMut, sync::Mutex};
|
||||||
collections::VecDeque,
|
|
||||||
sync::Mutex,
|
|
||||||
ops::DerefMut,
|
|
||||||
};
|
|
||||||
use vek::*;
|
use vek::*;
|
||||||
|
|
||||||
pub enum LocalEvent {
|
pub enum LocalEvent {
|
||||||
|
@ -48,12 +48,11 @@ pub mod store;
|
|||||||
pub mod terrain;
|
pub mod terrain;
|
||||||
pub mod time;
|
pub mod time;
|
||||||
pub mod typed;
|
pub mod typed;
|
||||||
pub mod util;
|
|
||||||
pub mod uid;
|
pub mod uid;
|
||||||
|
pub mod util;
|
||||||
pub mod vol;
|
pub mod vol;
|
||||||
pub mod volumes;
|
pub mod volumes;
|
||||||
|
|
||||||
|
|
||||||
pub use combat::{Damage, DamageSource, GroupTarget, Knockback};
|
pub use combat::{Damage, DamageSource, GroupTarget, Knockback};
|
||||||
pub use explosion::{Explosion, RadiusEffect};
|
pub use explosion::{Explosion, RadiusEffect};
|
||||||
pub use loadout_builder::LoadoutBuilder;
|
pub use loadout_builder::LoadoutBuilder;
|
||||||
|
@ -15,11 +15,14 @@ pub struct DeltaTime(pub f32);
|
|||||||
/// A resource that indicates what mode the local game is being played in.
|
/// A resource that indicates what mode the local game is being played in.
|
||||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||||
pub enum GameMode {
|
pub enum GameMode {
|
||||||
/// The game is being played in server mode (i.e: the code is running server-side)
|
/// The game is being played in server mode (i.e: the code is running
|
||||||
|
/// server-side)
|
||||||
Server,
|
Server,
|
||||||
/// The game is being played in client mode (i.e: the code is running client-side)
|
/// The game is being played in client mode (i.e: the code is running
|
||||||
|
/// client-side)
|
||||||
Client,
|
Client,
|
||||||
/// The game is being played in singleplayer mode (i.e: both client and server at once)
|
/// The game is being played in singleplayer mode (i.e: both client and
|
||||||
|
/// server at once)
|
||||||
// To be used later when we no longer start up an entirely new server for singleplayer
|
// To be used later when we no longer start up an entirely new server for singleplayer
|
||||||
Singleplayer,
|
Singleplayer,
|
||||||
}
|
}
|
||||||
|
@ -139,9 +139,7 @@ impl Body {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn can_climb(&self) -> bool {
|
pub fn can_climb(&self) -> bool { matches!(self, Body::Humanoid(_)) }
|
||||||
matches!(self, Body::Humanoid(_))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Handles updating `Components` to move player based on state of `JoinData`
|
/// Handles updating `Components` to move player based on state of `JoinData`
|
||||||
|
@ -17,9 +17,9 @@ use common::{
|
|||||||
path::{Chaser, TraversalConfig},
|
path::{Chaser, TraversalConfig},
|
||||||
resources::{DeltaTime, Time, TimeOfDay},
|
resources::{DeltaTime, Time, TimeOfDay},
|
||||||
span,
|
span,
|
||||||
uid::{Uid, UidAllocator},
|
|
||||||
terrain::{Block, TerrainGrid},
|
terrain::{Block, TerrainGrid},
|
||||||
time::DayPeriod,
|
time::DayPeriod,
|
||||||
|
uid::{Uid, UidAllocator},
|
||||||
util::Dir,
|
util::Dir,
|
||||||
vol::ReadVol,
|
vol::ReadVol,
|
||||||
};
|
};
|
||||||
|
@ -8,8 +8,8 @@ use common::{
|
|||||||
metrics::{PhysicsMetrics, SysMetrics},
|
metrics::{PhysicsMetrics, SysMetrics},
|
||||||
resources::DeltaTime,
|
resources::DeltaTime,
|
||||||
span,
|
span,
|
||||||
uid::Uid,
|
|
||||||
terrain::{Block, TerrainGrid},
|
terrain::{Block, TerrainGrid},
|
||||||
|
uid::Uid,
|
||||||
vol::ReadVol,
|
vol::ReadVol,
|
||||||
};
|
};
|
||||||
use rayon::iter::ParallelIterator;
|
use rayon::iter::ParallelIterator;
|
||||||
|
@ -7,7 +7,7 @@ pub enum PluginError {
|
|||||||
Toml(toml::de::Error),
|
Toml(toml::de::Error),
|
||||||
NoConfig,
|
NoConfig,
|
||||||
NoSuchModule,
|
NoSuchModule,
|
||||||
PluginModuleError(PluginModuleError)
|
PluginModuleError(PluginModuleError),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -18,4 +18,4 @@ pub enum PluginModuleError {
|
|||||||
Instantiate(wasmer_runtime::error::Error),
|
Instantiate(wasmer_runtime::error::Error),
|
||||||
RunFunction(RuntimeError),
|
RunFunction(RuntimeError),
|
||||||
Encoding(Box<ErrorKind>),
|
Encoding(Box<ErrorKind>),
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,22 @@
|
|||||||
|
|
||||||
pub mod errors;
|
pub mod errors;
|
||||||
pub mod module;
|
pub mod module;
|
||||||
|
|
||||||
use common::assets::ASSETS_PATH;
|
use common::assets::ASSETS_PATH;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::{collections::{HashMap, HashSet}, fs, io::Read, path::{Path, PathBuf}};
|
use std::{
|
||||||
|
collections::{HashMap, HashSet},
|
||||||
|
fs,
|
||||||
|
io::Read,
|
||||||
|
path::{Path, PathBuf},
|
||||||
|
};
|
||||||
use tracing::{error, info};
|
use tracing::{error, info};
|
||||||
|
|
||||||
use plugin_api::Event;
|
use plugin_api::Event;
|
||||||
|
|
||||||
use self::{ errors::PluginError, module::{PluginModule, PreparedEventQuery}};
|
use self::{
|
||||||
|
errors::PluginError,
|
||||||
|
module::{PluginModule, PreparedEventQuery},
|
||||||
|
};
|
||||||
|
|
||||||
use rayon::prelude::*;
|
use rayon::prelude::*;
|
||||||
|
|
||||||
@ -58,7 +65,7 @@ impl Plugin {
|
|||||||
.iter()
|
.iter()
|
||||||
.map(|path| {
|
.map(|path| {
|
||||||
let wasm_data = files.remove(path).ok_or(PluginError::NoSuchModule)?;
|
let wasm_data = files.remove(path).ok_or(PluginError::NoSuchModule)?;
|
||||||
PluginModule::new(&wasm_data).map_err(|e| PluginError::PluginModuleError(e))
|
PluginModule::new(&wasm_data).map_err(PluginError::PluginModuleError)
|
||||||
})
|
})
|
||||||
.collect::<Result<_, _>>()?;
|
.collect::<Result<_, _>>()?;
|
||||||
|
|
||||||
@ -69,10 +76,22 @@ impl Plugin {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn execute_prepared<T>(&self, event_name: &str, event: &PreparedEventQuery<T>) -> Result<Vec<T::Response>, PluginError> where T: Event {
|
pub fn execute_prepared<T>(
|
||||||
self.modules.iter().flat_map(|module| {
|
&self,
|
||||||
module.try_execute(event_name, event).map(|x| x.map_err(|e| PluginError::PluginModuleError(e)))
|
event_name: &str,
|
||||||
}).collect::<Result<Vec<_>,_>>()
|
event: &PreparedEventQuery<T>,
|
||||||
|
) -> Result<Vec<T::Response>, PluginError>
|
||||||
|
where
|
||||||
|
T: Event,
|
||||||
|
{
|
||||||
|
self.modules
|
||||||
|
.iter()
|
||||||
|
.flat_map(|module| {
|
||||||
|
module
|
||||||
|
.try_execute(event_name, event)
|
||||||
|
.map(|x| x.map_err(PluginError::PluginModuleError))
|
||||||
|
})
|
||||||
|
.collect::<Result<Vec<_>, _>>()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,13 +108,32 @@ impl PluginMgr {
|
|||||||
Self::from_dir(assets_path)
|
Self::from_dir(assets_path)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn execute_prepared<T>(&self, event_name: &str,event: &PreparedEventQuery<T>) -> Result<Vec<T::Response>, PluginError> where T: Event {
|
pub fn execute_prepared<T>(
|
||||||
Ok(self.plugins.par_iter().map(|plugin| {
|
&self,
|
||||||
plugin.execute_prepared(event_name, event)
|
event_name: &str,
|
||||||
}).collect::<Result<Vec<_>,_>>()?.into_iter().flatten().collect())
|
event: &PreparedEventQuery<T>,
|
||||||
|
) -> Result<Vec<T::Response>, PluginError>
|
||||||
|
where
|
||||||
|
T: Event,
|
||||||
|
{
|
||||||
|
Ok(self
|
||||||
|
.plugins
|
||||||
|
.par_iter()
|
||||||
|
.map(|plugin| plugin.execute_prepared(event_name, event))
|
||||||
|
.collect::<Result<Vec<_>, _>>()?
|
||||||
|
.into_iter()
|
||||||
|
.flatten()
|
||||||
|
.collect())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn execute_event<T>(&self, event_name: &str,event: &T) -> Result<Vec<T::Response>, PluginError> where T: Event {
|
pub fn execute_event<T>(
|
||||||
|
&self,
|
||||||
|
event_name: &str,
|
||||||
|
event: &T,
|
||||||
|
) -> Result<Vec<T::Response>, PluginError>
|
||||||
|
where
|
||||||
|
T: Event,
|
||||||
|
{
|
||||||
self.execute_prepared(event_name, &PreparedEventQuery::new(event)?)
|
self.execute_prepared(event_name, &PreparedEventQuery::new(event)?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,14 +22,14 @@ pub struct PluginModule {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl PluginModule {
|
impl PluginModule {
|
||||||
|
|
||||||
// This function takes bytes from a WASM File and compile them
|
// This function takes bytes from a WASM File and compile them
|
||||||
pub fn new(wasm_data: &Vec<u8>) -> Result<Self,PluginModuleError> {
|
pub fn new(wasm_data: &[u8]) -> Result<Self, PluginModuleError> {
|
||||||
let module = compile(&wasm_data).map_err(|e| PluginModuleError::Compile(e))?;
|
let module = compile(&wasm_data).map_err(PluginModuleError::Compile)?;
|
||||||
let instance = module
|
let instance = module
|
||||||
.instantiate(&imports! {"env" => {
|
.instantiate(&imports! {"env" => {
|
||||||
"raw_emit_actions" => func!(read_action),
|
"raw_emit_actions" => func!(read_action),
|
||||||
}}).map_err(|e| PluginModuleError::Instantiate(e))?;
|
}})
|
||||||
|
.map_err(PluginModuleError::Instantiate)?;
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
events: instance.exports.into_iter().map(|(name, _)| name).collect(),
|
events: instance.exports.into_iter().map(|(name, _)| name).collect(),
|
||||||
@ -37,12 +37,13 @@ impl PluginModule {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// This function tries to execute an event for the current module. Will return None if the event doesn't exists
|
// This function tries to execute an event for the current module. Will return
|
||||||
|
// None if the event doesn't exists
|
||||||
pub fn try_execute<T>(
|
pub fn try_execute<T>(
|
||||||
&self,
|
&self,
|
||||||
event_name: &str,
|
event_name: &str,
|
||||||
request: &PreparedEventQuery<T>,
|
request: &PreparedEventQuery<T>,
|
||||||
) -> Option<Result<T::Response,PluginModuleError>>
|
) -> Option<Result<T::Response, PluginModuleError>>
|
||||||
where
|
where
|
||||||
T: Event,
|
T: Event,
|
||||||
{
|
{
|
||||||
@ -51,21 +52,26 @@ impl PluginModule {
|
|||||||
}
|
}
|
||||||
let bytes = {
|
let bytes = {
|
||||||
let instance = self.wasm_instance.lock().unwrap();
|
let instance = self.wasm_instance.lock().unwrap();
|
||||||
let func = match instance.exports.get(event_name).map_err(|e| PluginModuleError::FunctionGet(e)) {
|
let func = match instance
|
||||||
|
.exports
|
||||||
|
.get(event_name)
|
||||||
|
.map_err(PluginModuleError::FunctionGet)
|
||||||
|
{
|
||||||
Ok(e) => e,
|
Ok(e) => e,
|
||||||
Err(e) => return Some(Err(e))
|
Err(e) => return Some(Err(e)),
|
||||||
};
|
};
|
||||||
let mem = instance.context().memory(0);
|
let mem = instance.context().memory(0);
|
||||||
match execute_raw(&mem, &func, &request.bytes).map_err(|e| PluginModuleError::RunFunction(e)) {
|
match execute_raw(&mem, &func, &request.bytes).map_err(PluginModuleError::RunFunction) {
|
||||||
Ok(e) => e,
|
Ok(e) => e,
|
||||||
Err(e) => return Some(Err(e))
|
Err(e) => return Some(Err(e)),
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Some(bincode::deserialize(&bytes).map_err(|e| PluginModuleError::Encoding(e)))
|
Some(bincode::deserialize(&bytes).map_err(PluginModuleError::Encoding))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// This structure represent a Pre-encoded event object (Useful to avoid reencoding for each module in every plugin)
|
// This structure represent a Pre-encoded event object (Useful to avoid
|
||||||
|
// reencoding for each module in every plugin)
|
||||||
pub struct PreparedEventQuery<T> {
|
pub struct PreparedEventQuery<T> {
|
||||||
bytes: Vec<u8>,
|
bytes: Vec<u8>,
|
||||||
_phantom: PhantomData<T>,
|
_phantom: PhantomData<T>,
|
||||||
@ -79,7 +85,8 @@ impl<T: Event> PreparedEventQuery<T> {
|
|||||||
T: Event,
|
T: Event,
|
||||||
{
|
{
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
bytes: bincode::serialize(&event).map_err(|e| PluginError::PluginModuleError(PluginModuleError::Encoding(e)))?,
|
bytes: bincode::serialize(&event)
|
||||||
|
.map_err(|e| PluginError::PluginModuleError(PluginModuleError::Encoding(e)))?,
|
||||||
_phantom: PhantomData::default(),
|
_phantom: PhantomData::default(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -87,7 +94,9 @@ impl<T: Event> PreparedEventQuery<T> {
|
|||||||
|
|
||||||
const MEMORY_POS: usize = 100000;
|
const MEMORY_POS: usize = 100000;
|
||||||
|
|
||||||
// This function is not public because this function should not be used without an interface to limit unsafe behaviours
|
// This function is not public because this function should not be used without
|
||||||
|
// an interface to limit unsafe behaviours
|
||||||
|
#[allow(clippy::needless_range_loop)]
|
||||||
fn execute_raw(
|
fn execute_raw(
|
||||||
memory: &Memory,
|
memory: &Memory,
|
||||||
function: &Function,
|
function: &Function,
|
||||||
@ -98,8 +107,7 @@ fn execute_raw(
|
|||||||
for (cell, byte) in view[MEMORY_POS..len + MEMORY_POS].iter().zip(bytes.iter()) {
|
for (cell, byte) in view[MEMORY_POS..len + MEMORY_POS].iter().zip(bytes.iter()) {
|
||||||
cell.set(*byte)
|
cell.set(*byte)
|
||||||
}
|
}
|
||||||
let start = function
|
let start = function.call(MEMORY_POS as i32, len as u32)? as usize;
|
||||||
.call(MEMORY_POS as i32, len as u32)? as usize;
|
|
||||||
let view = memory.view::<u8>();
|
let view = memory.view::<u8>();
|
||||||
let mut new_len_bytes = [0u8; 4];
|
let mut new_len_bytes = [0u8; 4];
|
||||||
// TODO: It is probably better to dirrectly make the new_len_bytes
|
// TODO: It is probably better to dirrectly make the new_len_bytes
|
||||||
@ -127,7 +135,7 @@ pub fn read_action(ctx: &mut Ctx, ptr: u32, len: u32) {
|
|||||||
Err(e) => {
|
Err(e) => {
|
||||||
tracing::error!(?e, "Can't decode action");
|
tracing::error!(?e, "Can't decode action");
|
||||||
return;
|
return;
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
for action in e {
|
for action in e {
|
||||||
@ -135,16 +143,16 @@ pub fn read_action(ctx: &mut Ctx, ptr: u32, len: u32) {
|
|||||||
Action::ServerClose => {
|
Action::ServerClose => {
|
||||||
tracing::info!("Server closed by plugin");
|
tracing::info!("Server closed by plugin");
|
||||||
std::process::exit(-1);
|
std::process::exit(-1);
|
||||||
}
|
},
|
||||||
Action::Print(e) => {
|
Action::Print(e) => {
|
||||||
tracing::info!("{}",e);
|
tracing::info!("{}", e);
|
||||||
}
|
},
|
||||||
Action::PlayerSendMessage(a, b) => {
|
Action::PlayerSendMessage(a, b) => {
|
||||||
tracing::info!("SendMessage {} -> {}",a,b);
|
tracing::info!("SendMessage {} -> {}", a, b);
|
||||||
}
|
},
|
||||||
Action::KillEntity(e) => {
|
Action::KillEntity(e) => {
|
||||||
tracing::info!("Kill Entity {}",e);
|
tracing::info!("Kill Entity {}", e);
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,15 @@
|
|||||||
|
use crate::plugin::PluginMgr;
|
||||||
use common::{
|
use common::{
|
||||||
comp,
|
comp,
|
||||||
event::{EventBus, LocalEvent, ServerEvent},
|
event::{EventBus, LocalEvent, ServerEvent},
|
||||||
metrics::{PhysicsMetrics, SysMetrics},
|
metrics::{PhysicsMetrics, SysMetrics},
|
||||||
region::RegionMap,
|
region::RegionMap,
|
||||||
|
resources,
|
||||||
resources::{DeltaTime, Time, TimeOfDay},
|
resources::{DeltaTime, Time, TimeOfDay},
|
||||||
span,
|
span,
|
||||||
terrain::{Block, TerrainChunk, TerrainGrid},
|
terrain::{Block, TerrainChunk, TerrainGrid},
|
||||||
time::DayPeriod,
|
time::DayPeriod,
|
||||||
vol::{ReadVol, WriteVol},
|
vol::{ReadVol, WriteVol},
|
||||||
resources,
|
|
||||||
};
|
};
|
||||||
use common_net::sync::WorldSyncExt;
|
use common_net::sync::WorldSyncExt;
|
||||||
use hashbrown::{HashMap, HashSet};
|
use hashbrown::{HashMap, HashSet};
|
||||||
@ -21,7 +22,6 @@ use specs::{
|
|||||||
use std::{sync::Arc, time::Duration};
|
use std::{sync::Arc, time::Duration};
|
||||||
use tracing::info;
|
use tracing::info;
|
||||||
use vek::*;
|
use vek::*;
|
||||||
use crate::plugin::PluginMgr;
|
|
||||||
|
|
||||||
/// How much faster should an in-game day be compared to a real day?
|
/// How much faster should an in-game day be compared to a real day?
|
||||||
// TODO: Don't hard-code this.
|
// TODO: Don't hard-code this.
|
||||||
@ -90,6 +90,7 @@ pub struct State {
|
|||||||
impl State {
|
impl State {
|
||||||
/// Create a new `State` in client mode.
|
/// Create a new `State` in client mode.
|
||||||
pub fn client() -> Self { Self::new(resources::GameMode::Client) }
|
pub fn client() -> Self { Self::new(resources::GameMode::Client) }
|
||||||
|
|
||||||
/// Create a new `State` in server mode.
|
/// Create a new `State` in server mode.
|
||||||
pub fn server() -> Self { Self::new(resources::GameMode::Server) }
|
pub fn server() -> Self { Self::new(resources::GameMode::Server) }
|
||||||
|
|
||||||
@ -192,9 +193,9 @@ impl State {
|
|||||||
// Load plugins from asset directory
|
// Load plugins from asset directory
|
||||||
ecs.insert(match PluginMgr::from_assets() {
|
ecs.insert(match PluginMgr::from_assets() {
|
||||||
Ok(plugin_mgr) => {
|
Ok(plugin_mgr) => {
|
||||||
if let Err(e) = plugin_mgr.execute_event("on_load", &plugin_api::event::PluginLoadEvent {
|
if let Err(e) = plugin_mgr
|
||||||
game_mode,
|
.execute_event("on_load", &plugin_api::event::PluginLoadEvent { game_mode })
|
||||||
}) {
|
{
|
||||||
tracing::error!(?e, "Failed to run plugin init");
|
tracing::error!(?e, "Failed to run plugin init");
|
||||||
info!("Error occurred when loading plugins. Running without plugins instead.");
|
info!("Error occurred when loading plugins. Running without plugins instead.");
|
||||||
PluginMgr::default()
|
PluginMgr::default()
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
use serde::{Serialize, de::DeserializeOwned, Deserialize};
|
|
||||||
use common::uid::Uid;
|
use common::uid::Uid;
|
||||||
|
use serde::{de::DeserializeOwned, Deserialize, Serialize};
|
||||||
|
|
||||||
#[derive(Deserialize,Serialize,Debug)]
|
#[derive(Deserialize, Serialize, Debug)]
|
||||||
pub enum Action {
|
pub enum Action {
|
||||||
ServerClose,
|
ServerClose,
|
||||||
Print(String),
|
Print(String),
|
||||||
PlayerSendMessage(usize,String),
|
PlayerSendMessage(usize, String),
|
||||||
KillEntity(usize)
|
KillEntity(usize),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Event: Serialize + DeserializeOwned + Send + Sync{
|
pub trait Event: Serialize + DeserializeOwned + Send + Sync {
|
||||||
type Response: Serialize + DeserializeOwned + Send + Sync;
|
type Response: Serialize + DeserializeOwned + Send + Sync;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -17,7 +17,7 @@ pub use common::resources::GameMode;
|
|||||||
|
|
||||||
pub mod event {
|
pub mod event {
|
||||||
use super::*;
|
use super::*;
|
||||||
use serde::{Serialize,Deserialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)]
|
#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)]
|
||||||
pub struct ChatCommandEvent {
|
pub struct ChatCommandEvent {
|
||||||
@ -38,7 +38,7 @@ pub mod event {
|
|||||||
#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)]
|
#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)]
|
||||||
pub struct PlayerJoinEvent {
|
pub struct PlayerJoinEvent {
|
||||||
pub player_name: String,
|
pub player_name: String,
|
||||||
pub player_id: usize
|
pub player_id: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Event for PlayerJoinEvent {
|
impl Event for PlayerJoinEvent {
|
||||||
@ -48,13 +48,11 @@ pub mod event {
|
|||||||
#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)]
|
#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)]
|
||||||
pub enum PlayerJoinResult {
|
pub enum PlayerJoinResult {
|
||||||
CloseConnection,
|
CloseConnection,
|
||||||
None
|
None,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for PlayerJoinResult {
|
impl Default for PlayerJoinResult {
|
||||||
fn default() -> Self {
|
fn default() -> Self { Self::None }
|
||||||
Self::None
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)]
|
#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)]
|
||||||
|
@ -5,16 +5,13 @@ pub extern crate plugin_derive;
|
|||||||
pub use plugin_api as api;
|
pub use plugin_api as api;
|
||||||
pub use plugin_derive::*;
|
pub use plugin_derive::*;
|
||||||
|
|
||||||
use serde::de::DeserializeOwned;
|
use serde::{de::DeserializeOwned, Serialize};
|
||||||
use serde::Serialize;
|
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
fn raw_emit_actions(ptr: *const u8, len: usize);
|
fn raw_emit_actions(ptr: *const u8, len: usize);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn emit_action(action: api::Action) {
|
pub fn emit_action(action: api::Action) { emit_actions(vec![action]) }
|
||||||
emit_actions(vec![action])
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn emit_actions(actions: Vec<api::Action>) {
|
pub fn emit_actions(actions: Vec<api::Action>) {
|
||||||
let ret = bincode::serialize(&actions).unwrap();
|
let ret = bincode::serialize(&actions).unwrap();
|
||||||
@ -23,11 +20,12 @@ pub fn emit_actions(actions: Vec<api::Action>) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read_input<T>(ptr: i32, len: u32) -> Result<T, &'static str> where T: DeserializeOwned{
|
pub fn read_input<T>(ptr: i32, len: u32) -> Result<T, &'static str>
|
||||||
let slice = unsafe {
|
where
|
||||||
::std::slice::from_raw_parts(ptr as _, len as _)
|
T: DeserializeOwned,
|
||||||
};
|
{
|
||||||
bincode::deserialize(slice).map_err(|_|"Failed to deserialize function input")
|
let slice = unsafe { ::std::slice::from_raw_parts(ptr as _, len as _) };
|
||||||
|
bincode::deserialize(slice).map_err(|_| "Failed to deserialize function input")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_output(value: impl Serialize) -> i32 {
|
pub fn write_output(value: impl Serialize) -> i32 {
|
||||||
|
@ -19,8 +19,8 @@ use common::{
|
|||||||
event::{EventBus, ServerEvent},
|
event::{EventBus, ServerEvent},
|
||||||
npc::{self, get_npc_name},
|
npc::{self, get_npc_name},
|
||||||
resources::TimeOfDay,
|
resources::TimeOfDay,
|
||||||
uid::Uid,
|
|
||||||
terrain::{Block, BlockKind, SpriteKind, TerrainChunkSize},
|
terrain::{Block, BlockKind, SpriteKind, TerrainChunkSize},
|
||||||
|
uid::Uid,
|
||||||
util::Dir,
|
util::Dir,
|
||||||
vol::RectVolSize,
|
vol::RectVolSize,
|
||||||
Damage, DamageSource, Explosion, LoadoutBuilder, RadiusEffect,
|
Damage, DamageSource, Explosion, LoadoutBuilder, RadiusEffect,
|
||||||
@ -48,10 +48,10 @@ impl ChatCommandExt for ChatCommand {
|
|||||||
if self.needs_admin() && !server.entity_is_admin(entity) {
|
if self.needs_admin() && !server.entity_is_admin(entity) {
|
||||||
server.notify_client(
|
server.notify_client(
|
||||||
entity,
|
entity,
|
||||||
ServerGeneral::server_msg(ChatType::CommandError, format!(
|
ServerGeneral::server_msg(
|
||||||
"You don't have permission to use '/{}'.",
|
ChatType::CommandError,
|
||||||
self.keyword()
|
format!("You don't have permission to use '/{}'.", self.keyword()),
|
||||||
)),
|
),
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
@ -150,10 +150,13 @@ fn handle_give_item(
|
|||||||
if inv.push(item).is_some() {
|
if inv.push(item).is_some() {
|
||||||
server.notify_client(
|
server.notify_client(
|
||||||
client,
|
client,
|
||||||
ServerGeneral::server_msg(ChatType::CommandError, format!(
|
ServerGeneral::server_msg(
|
||||||
"Player inventory full. Gave 0 of {} items.",
|
ChatType::CommandError,
|
||||||
give_amount
|
format!(
|
||||||
)),
|
"Player inventory full. Gave 0 of {} items.",
|
||||||
|
give_amount
|
||||||
|
),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -169,10 +172,13 @@ fn handle_give_item(
|
|||||||
if inv.push(item.duplicate()).is_some() {
|
if inv.push(item.duplicate()).is_some() {
|
||||||
server.notify_client(
|
server.notify_client(
|
||||||
client,
|
client,
|
||||||
ServerGeneral::server_msg(ChatType::CommandError, format!(
|
ServerGeneral::server_msg(
|
||||||
"Player inventory full. Gave {} of {} items.",
|
ChatType::CommandError,
|
||||||
i, give_amount
|
format!(
|
||||||
)),
|
"Player inventory full. Gave {} of {} items.",
|
||||||
|
i, give_amount
|
||||||
|
),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -191,7 +197,10 @@ fn handle_give_item(
|
|||||||
} else {
|
} else {
|
||||||
server.notify_client(
|
server.notify_client(
|
||||||
client,
|
client,
|
||||||
ServerGeneral::server_msg(ChatType::CommandError, format!("Invalid item: {}", item_name)),
|
ServerGeneral::server_msg(
|
||||||
|
ChatType::CommandError,
|
||||||
|
format!("Invalid item: {}", item_name),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -218,13 +227,19 @@ fn handle_make_block(
|
|||||||
),
|
),
|
||||||
None => server.notify_client(
|
None => server.notify_client(
|
||||||
client,
|
client,
|
||||||
ServerGeneral::server_msg(ChatType::CommandError, String::from("You have no position.")),
|
ServerGeneral::server_msg(
|
||||||
|
ChatType::CommandError,
|
||||||
|
String::from("You have no position."),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
server.notify_client(
|
server.notify_client(
|
||||||
client,
|
client,
|
||||||
ServerGeneral::server_msg(ChatType::CommandError, format!("Invalid block kind: {}", block_name)),
|
ServerGeneral::server_msg(
|
||||||
|
ChatType::CommandError,
|
||||||
|
format!("Invalid block kind: {}", block_name),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -257,13 +272,19 @@ fn handle_make_sprite(
|
|||||||
},
|
},
|
||||||
None => server.notify_client(
|
None => server.notify_client(
|
||||||
client,
|
client,
|
||||||
ServerGeneral::server_msg(ChatType::CommandError, String::from("You have no position.")),
|
ServerGeneral::server_msg(
|
||||||
|
ChatType::CommandError,
|
||||||
|
String::from("You have no position."),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
server.notify_client(
|
server.notify_client(
|
||||||
client,
|
client,
|
||||||
ServerGeneral::server_msg(ChatType::CommandError, format!("Invalid sprite kind: {}", sprite_name)),
|
ServerGeneral::server_msg(
|
||||||
|
ChatType::CommandError,
|
||||||
|
format!("Invalid sprite kind: {}", sprite_name),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -283,7 +304,10 @@ fn handle_motd(
|
|||||||
) {
|
) {
|
||||||
server.notify_client(
|
server.notify_client(
|
||||||
client,
|
client,
|
||||||
ServerGeneral::server_msg(ChatType::CommandError, (*server.editable_settings().server_description).clone()),
|
ServerGeneral::server_msg(
|
||||||
|
ChatType::CommandError,
|
||||||
|
(*server.editable_settings().server_description).clone(),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -303,7 +327,10 @@ fn handle_set_motd(
|
|||||||
.edit(data_dir.as_ref(), |d| **d = msg.clone());
|
.edit(data_dir.as_ref(), |d| **d = msg.clone());
|
||||||
server.notify_client(
|
server.notify_client(
|
||||||
client,
|
client,
|
||||||
ServerGeneral::server_msg(ChatType::CommandError, format!("Server description set to \"{}\"", msg)),
|
ServerGeneral::server_msg(
|
||||||
|
ChatType::CommandError,
|
||||||
|
format!("Server description set to \"{}\"", msg),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
@ -313,7 +340,10 @@ fn handle_set_motd(
|
|||||||
.edit(data_dir.as_ref(), |d| d.clear());
|
.edit(data_dir.as_ref(), |d| d.clear());
|
||||||
server.notify_client(
|
server.notify_client(
|
||||||
client,
|
client,
|
||||||
ServerGeneral::server_msg(ChatType::CommandError, "Removed server description".to_string()),
|
ServerGeneral::server_msg(
|
||||||
|
ChatType::CommandError,
|
||||||
|
"Removed server description".to_string(),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -459,7 +489,10 @@ fn handle_time(
|
|||||||
None => {
|
None => {
|
||||||
server.notify_client(
|
server.notify_client(
|
||||||
client,
|
client,
|
||||||
ServerGeneral::server_msg(ChatType::CommandError, format!("'{}' is not a valid time.", n)),
|
ServerGeneral::server_msg(
|
||||||
|
ChatType::CommandError,
|
||||||
|
format!("'{}' is not a valid time.", n),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
},
|
},
|
||||||
@ -518,7 +551,10 @@ fn handle_time(
|
|||||||
Some(time) => format!("It is {}", time.format("%H:%M").to_string()),
|
Some(time) => format!("It is {}", time.format("%H:%M").to_string()),
|
||||||
None => String::from("Unknown Time"),
|
None => String::from("Unknown Time"),
|
||||||
};
|
};
|
||||||
server.notify_client(client, ServerGeneral::server_msg(ChatType::CommandInfo, msg));
|
server.notify_client(
|
||||||
|
client,
|
||||||
|
ServerGeneral::server_msg(ChatType::CommandInfo, msg),
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -530,10 +566,10 @@ fn handle_time(
|
|||||||
{
|
{
|
||||||
server.notify_client(
|
server.notify_client(
|
||||||
client,
|
client,
|
||||||
ServerGeneral::server_msg(ChatType::CommandInfo, format!(
|
ServerGeneral::server_msg(
|
||||||
"Time changed to: {}",
|
ChatType::CommandInfo,
|
||||||
new_time.format("%H:%M").to_string(),
|
format!("Time changed to: {}", new_time.format("%H:%M").to_string(),),
|
||||||
)),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -585,7 +621,10 @@ fn handle_alias(
|
|||||||
if let Ok(alias) = scan_fmt!(&args, &action.arg_fmt(), String) {
|
if let Ok(alias) = scan_fmt!(&args, &action.arg_fmt(), String) {
|
||||||
if !comp::Player::alias_is_valid(&alias) {
|
if !comp::Player::alias_is_valid(&alias) {
|
||||||
// Prevent silly aliases
|
// Prevent silly aliases
|
||||||
server.notify_client(client, ServerGeneral::server_msg(ChatType::CommandError, "Invalid alias."));
|
server.notify_client(
|
||||||
|
client,
|
||||||
|
ServerGeneral::server_msg(ChatType::CommandError, "Invalid alias."),
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let old_alias_optional = server
|
let old_alias_optional = server
|
||||||
@ -610,9 +649,10 @@ fn handle_alias(
|
|||||||
|
|
||||||
// Announce alias change if target has a Body.
|
// Announce alias change if target has a Body.
|
||||||
if ecs.read_storage::<comp::Body>().get(target).is_some() {
|
if ecs.read_storage::<comp::Body>().get(target).is_some() {
|
||||||
server.state.notify_players(
|
server.state.notify_players(ServerGeneral::server_msg(
|
||||||
ServerGeneral::server_msg(ChatType::CommandInfo, format!("{} is now known as {}.", old_alias, player.alias)),
|
ChatType::CommandInfo,
|
||||||
);
|
format!("{} is now known as {}.", old_alias, player.alias),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -657,7 +697,10 @@ fn handle_tp(
|
|||||||
} else {
|
} else {
|
||||||
server.notify_client(
|
server.notify_client(
|
||||||
client,
|
client,
|
||||||
ServerGeneral::server_msg(ChatType::CommandError, "Unable to teleport to player!"),
|
ServerGeneral::server_msg(
|
||||||
|
ChatType::CommandError,
|
||||||
|
"Unable to teleport to player!",
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -792,13 +835,19 @@ fn handle_spawn(
|
|||||||
if let Some(uid) = server.state.ecs().uid_from_entity(new_entity) {
|
if let Some(uid) = server.state.ecs().uid_from_entity(new_entity) {
|
||||||
server.notify_client(
|
server.notify_client(
|
||||||
client,
|
client,
|
||||||
ServerGeneral::server_msg(ChatType::CommandInfo, format!("Spawned entity with ID: {}", uid)),
|
ServerGeneral::server_msg(
|
||||||
|
ChatType::CommandInfo,
|
||||||
|
format!("Spawned entity with ID: {}", uid),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
server.notify_client(
|
server.notify_client(
|
||||||
client,
|
client,
|
||||||
ServerGeneral::server_msg(ChatType::CommandInfo, format!("Spawned {} entities", amount)),
|
ServerGeneral::server_msg(
|
||||||
|
ChatType::CommandInfo,
|
||||||
|
format!("Spawned {} entities", amount),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
None => server.notify_client(
|
None => server.notify_client(
|
||||||
@ -920,18 +969,21 @@ fn handle_players(
|
|||||||
|
|
||||||
server.notify_client(
|
server.notify_client(
|
||||||
client,
|
client,
|
||||||
ServerGeneral::server_msg(ChatType::CommandInfo, entity_tuples.join().fold(
|
ServerGeneral::server_msg(
|
||||||
format!("{} online players:", entity_tuples.join().count()),
|
ChatType::CommandInfo,
|
||||||
|s, (_, player, stat)| {
|
entity_tuples.join().fold(
|
||||||
format!(
|
format!("{} online players:", entity_tuples.join().count()),
|
||||||
"{}\n[{}]{} Lvl {}",
|
|s, (_, player, stat)| {
|
||||||
s,
|
format!(
|
||||||
player.alias,
|
"{}\n[{}]{} Lvl {}",
|
||||||
stat.name,
|
s,
|
||||||
stat.level.level()
|
player.alias,
|
||||||
)
|
stat.name,
|
||||||
},
|
stat.level.level()
|
||||||
)),
|
)
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -978,7 +1030,10 @@ fn handle_help(
|
|||||||
action: &ChatCommand,
|
action: &ChatCommand,
|
||||||
) {
|
) {
|
||||||
if let Some(cmd) = scan_fmt_some!(&args, &action.arg_fmt(), ChatCommand) {
|
if let Some(cmd) = scan_fmt_some!(&args, &action.arg_fmt(), ChatCommand) {
|
||||||
server.notify_client(client, ServerGeneral::server_msg(ChatType::CommandInfo, cmd.help_string()));
|
server.notify_client(
|
||||||
|
client,
|
||||||
|
ServerGeneral::server_msg(ChatType::CommandInfo, cmd.help_string()),
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
let mut message = String::new();
|
let mut message = String::new();
|
||||||
for cmd in CHAT_COMMANDS.iter() {
|
for cmd in CHAT_COMMANDS.iter() {
|
||||||
@ -991,7 +1046,10 @@ fn handle_help(
|
|||||||
for (k, v) in CHAT_SHORTCUTS.iter() {
|
for (k, v) in CHAT_SHORTCUTS.iter() {
|
||||||
message += &format!(" /{} => /{}", k, v.keyword());
|
message += &format!(" /{} => /{}", k, v.keyword());
|
||||||
}
|
}
|
||||||
server.notify_client(client, ServerGeneral::server_msg(ChatType::CommandInfo, message));
|
server.notify_client(
|
||||||
|
client,
|
||||||
|
ServerGeneral::server_msg(ChatType::CommandInfo, message),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1025,7 +1083,10 @@ fn handle_kill_npcs(
|
|||||||
} else {
|
} else {
|
||||||
"No NPCs on server.".to_string()
|
"No NPCs on server.".to_string()
|
||||||
};
|
};
|
||||||
server.notify_client(client, ServerGeneral::server_msg(ChatType::CommandInfo, text));
|
server.notify_client(
|
||||||
|
client,
|
||||||
|
ServerGeneral::server_msg(ChatType::CommandInfo, text),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::float_cmp)] // TODO: Pending review in #587
|
#[allow(clippy::float_cmp)] // TODO: Pending review in #587
|
||||||
@ -1079,10 +1140,10 @@ fn handle_object(
|
|||||||
.build();
|
.build();
|
||||||
server.notify_client(
|
server.notify_client(
|
||||||
client,
|
client,
|
||||||
ServerGeneral::server_msg(ChatType::CommandInfo, format!(
|
ServerGeneral::server_msg(
|
||||||
"Spawned: {}",
|
ChatType::CommandInfo,
|
||||||
obj_str_res.unwrap_or("<Unknown object>")
|
format!("Spawned: {}", obj_str_res.unwrap_or("<Unknown object>")),
|
||||||
)),
|
),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return server.notify_client(
|
return server.notify_client(
|
||||||
@ -1116,7 +1177,10 @@ fn handle_light(
|
|||||||
if r < 0.0 || g < 0.0 || b < 0.0 {
|
if r < 0.0 || g < 0.0 || b < 0.0 {
|
||||||
server.notify_client(
|
server.notify_client(
|
||||||
client,
|
client,
|
||||||
ServerGeneral::server_msg(ChatType::CommandError, "cr, cg and cb values mustn't be negative."),
|
ServerGeneral::server_msg(
|
||||||
|
ChatType::CommandError,
|
||||||
|
"cr, cg and cb values mustn't be negative.",
|
||||||
|
),
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1155,7 +1219,10 @@ fn handle_light(
|
|||||||
} else {
|
} else {
|
||||||
builder.build();
|
builder.build();
|
||||||
}
|
}
|
||||||
server.notify_client(client, ServerGeneral::server_msg(ChatType::CommandInfo, "Spawned object."));
|
server.notify_client(
|
||||||
|
client,
|
||||||
|
ServerGeneral::server_msg(ChatType::CommandInfo, "Spawned object."),
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
server.notify_client(
|
server.notify_client(
|
||||||
client,
|
client,
|
||||||
@ -1189,12 +1256,18 @@ fn handle_lantern(
|
|||||||
.into();
|
.into();
|
||||||
server.notify_client(
|
server.notify_client(
|
||||||
client,
|
client,
|
||||||
ServerGeneral::server_msg(ChatType::CommandInfo, "You adjusted flame strength and color."),
|
ServerGeneral::server_msg(
|
||||||
|
ChatType::CommandInfo,
|
||||||
|
"You adjusted flame strength and color.",
|
||||||
|
),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
server.notify_client(
|
server.notify_client(
|
||||||
client,
|
client,
|
||||||
ServerGeneral::server_msg(ChatType::CommandInfo, "You adjusted flame strength."),
|
ServerGeneral::server_msg(
|
||||||
|
ChatType::CommandInfo,
|
||||||
|
"You adjusted flame strength.",
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -1223,13 +1296,19 @@ fn handle_explosion(
|
|||||||
if power > 512.0 {
|
if power > 512.0 {
|
||||||
server.notify_client(
|
server.notify_client(
|
||||||
client,
|
client,
|
||||||
ServerGeneral::server_msg(ChatType::CommandError, "Explosion power mustn't be more than 512."),
|
ServerGeneral::server_msg(
|
||||||
|
ChatType::CommandError,
|
||||||
|
"Explosion power mustn't be more than 512.",
|
||||||
|
),
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
} else if power <= 0.0 {
|
} else if power <= 0.0 {
|
||||||
server.notify_client(
|
server.notify_client(
|
||||||
client,
|
client,
|
||||||
ServerGeneral::server_msg(ChatType::CommandError, "Explosion power must be more than 0."),
|
ServerGeneral::server_msg(
|
||||||
|
ChatType::CommandError,
|
||||||
|
"Explosion power must be more than 0.",
|
||||||
|
),
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1281,7 +1360,10 @@ fn handle_waypoint(
|
|||||||
.ecs()
|
.ecs()
|
||||||
.write_storage::<comp::Waypoint>()
|
.write_storage::<comp::Waypoint>()
|
||||||
.insert(target, comp::Waypoint::temp_new(pos.0, *time));
|
.insert(target, comp::Waypoint::temp_new(pos.0, *time));
|
||||||
server.notify_client(client, ServerGeneral::server_msg(ChatType::CommandInfo, "Waypoint saved!"));
|
server.notify_client(
|
||||||
|
client,
|
||||||
|
ServerGeneral::server_msg(ChatType::CommandInfo, "Waypoint saved!"),
|
||||||
|
);
|
||||||
server.notify_client(
|
server.notify_client(
|
||||||
client,
|
client,
|
||||||
ServerGeneral::Notification(Notification::WaypointSaved),
|
ServerGeneral::Notification(Notification::WaypointSaved),
|
||||||
@ -1332,7 +1414,10 @@ fn handle_adminify(
|
|||||||
None => {
|
None => {
|
||||||
server.notify_client(
|
server.notify_client(
|
||||||
client,
|
client,
|
||||||
ServerGeneral::server_msg(ChatType::CommandError, format!("Player '{}' not found!", alias)),
|
ServerGeneral::server_msg(
|
||||||
|
ChatType::CommandError,
|
||||||
|
format!("Player '{}' not found!", alias),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -1394,7 +1479,10 @@ fn handle_tell(
|
|||||||
} else {
|
} else {
|
||||||
server.notify_client(
|
server.notify_client(
|
||||||
client,
|
client,
|
||||||
ServerGeneral::server_msg(ChatType::CommandError, format!("Player '{}' not found!", alias)),
|
ServerGeneral::server_msg(
|
||||||
|
ChatType::CommandError,
|
||||||
|
format!("Player '{}' not found!", alias),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -1432,7 +1520,10 @@ fn handle_faction(
|
|||||||
} else {
|
} else {
|
||||||
server.notify_client(
|
server.notify_client(
|
||||||
client,
|
client,
|
||||||
ServerGeneral::server_msg(ChatType::CommandError, "Please join a faction with /join_faction"),
|
ServerGeneral::server_msg(
|
||||||
|
ChatType::CommandError,
|
||||||
|
"Please join a faction with /join_faction",
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1497,12 +1588,18 @@ fn handle_group_invite(
|
|||||||
|
|
||||||
server.notify_client(
|
server.notify_client(
|
||||||
client,
|
client,
|
||||||
ServerGeneral::server_msg(ChatType::CommandInfo, format!("Invited {} to the group.", target_alias)),
|
ServerGeneral::server_msg(
|
||||||
|
ChatType::CommandInfo,
|
||||||
|
format!("Invited {} to the group.", target_alias),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
server.notify_client(
|
server.notify_client(
|
||||||
client,
|
client,
|
||||||
ServerGeneral::server_msg(ChatType::CommandError, format!("Player with alias {} not found", target_alias)),
|
ServerGeneral::server_msg(
|
||||||
|
ChatType::CommandError,
|
||||||
|
format!("Player with alias {} not found", target_alias),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -1539,7 +1636,10 @@ fn handle_group_kick(
|
|||||||
} else {
|
} else {
|
||||||
server.notify_client(
|
server.notify_client(
|
||||||
client,
|
client,
|
||||||
ServerGeneral::server_msg(ChatType::CommandError, format!("Player with alias {} not found", target_alias)),
|
ServerGeneral::server_msg(
|
||||||
|
ChatType::CommandError,
|
||||||
|
format!("Player with alias {} not found", target_alias),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -1593,7 +1693,10 @@ fn handle_group_promote(
|
|||||||
} else {
|
} else {
|
||||||
server.notify_client(
|
server.notify_client(
|
||||||
client,
|
client,
|
||||||
ServerGeneral::server_msg(ChatType::CommandError, format!("Player with alias {} not found", target_alias)),
|
ServerGeneral::server_msg(
|
||||||
|
ChatType::CommandError,
|
||||||
|
format!("Player with alias {} not found", target_alias),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -1760,7 +1863,10 @@ fn handle_debug_column(
|
|||||||
) {
|
) {
|
||||||
server.notify_client(
|
server.notify_client(
|
||||||
client,
|
client,
|
||||||
ServerGeneral::server_msg(ChatType::CommandError, "Unsupported without worldgen enabled"),
|
ServerGeneral::server_msg(
|
||||||
|
ChatType::CommandError,
|
||||||
|
"Unsupported without worldgen enabled",
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1782,7 +1888,10 @@ fn handle_debug_column(
|
|||||||
Some(pos) => wpos = pos.0.xy().map(|x| x as i32),
|
Some(pos) => wpos = pos.0.xy().map(|x| x as i32),
|
||||||
None => server.notify_client(
|
None => server.notify_client(
|
||||||
client,
|
client,
|
||||||
ServerGeneral::server_msg(ChatType::CommandError, String::from("You have no position.")),
|
ServerGeneral::server_msg(
|
||||||
|
ChatType::CommandError,
|
||||||
|
String::from("You have no position."),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1858,7 +1967,10 @@ fn find_target(
|
|||||||
.find(|(_, player)| player.alias == alias)
|
.find(|(_, player)| player.alias == alias)
|
||||||
.map(|(entity, _)| entity)
|
.map(|(entity, _)| entity)
|
||||||
.ok_or_else(|| {
|
.ok_or_else(|| {
|
||||||
ServerGeneral::server_msg(ChatType::CommandError, format!("Player '{}' not found!", alias))
|
ServerGeneral::server_msg(
|
||||||
|
ChatType::CommandError,
|
||||||
|
format!("Player '{}' not found!", alias),
|
||||||
|
)
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
Ok(fallback)
|
Ok(fallback)
|
||||||
@ -1885,7 +1997,10 @@ fn handle_give_exp(
|
|||||||
if let Some(stats) = ecs.write_storage::<comp::Stats>().get_mut(player) {
|
if let Some(stats) = ecs.write_storage::<comp::Stats>().get_mut(player) {
|
||||||
stats.exp.change_by(exp);
|
stats.exp.change_by(exp);
|
||||||
} else {
|
} else {
|
||||||
error_msg = Some(ServerGeneral::server_msg(ChatType::CommandError, "Player has no stats!"));
|
error_msg = Some(ServerGeneral::server_msg(
|
||||||
|
ChatType::CommandError,
|
||||||
|
"Player has no stats!",
|
||||||
|
));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
@ -1936,7 +2051,10 @@ fn handle_set_level(
|
|||||||
stats.level.set_level(lvl);
|
stats.level.set_level(lvl);
|
||||||
body_type = Some(stats.body_type);
|
body_type = Some(stats.body_type);
|
||||||
} else {
|
} else {
|
||||||
error_msg = Some(ServerGeneral::server_msg(ChatType::CommandError, "Player has no stats!"));
|
error_msg = Some(ServerGeneral::server_msg(
|
||||||
|
ChatType::CommandError,
|
||||||
|
"Player has no stats!",
|
||||||
|
));
|
||||||
body_type = None;
|
body_type = None;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1986,7 +2104,10 @@ fn handle_debug(
|
|||||||
} else {
|
} else {
|
||||||
server.notify_client(
|
server.notify_client(
|
||||||
client,
|
client,
|
||||||
ServerGeneral::server_msg(ChatType::CommandError, "Debug items not found? Something is very broken."),
|
ServerGeneral::server_msg(
|
||||||
|
ChatType::CommandError,
|
||||||
|
"Debug items not found? Something is very broken.",
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2070,7 +2191,10 @@ fn handle_sudo(
|
|||||||
} else {
|
} else {
|
||||||
server.notify_client(
|
server.notify_client(
|
||||||
client,
|
client,
|
||||||
ServerGeneral::server_msg(ChatType::CommandError, format!("Unknown command: /{}", cmd)),
|
ServerGeneral::server_msg(
|
||||||
|
ChatType::CommandError,
|
||||||
|
format!("Unknown command: /{}", cmd),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -2090,11 +2214,14 @@ fn handle_version(
|
|||||||
) {
|
) {
|
||||||
server.notify_client(
|
server.notify_client(
|
||||||
client,
|
client,
|
||||||
ServerGeneral::server_msg(ChatType::CommandInfo, format!(
|
ServerGeneral::server_msg(
|
||||||
"Server is running {}[{}]",
|
ChatType::CommandInfo,
|
||||||
common::util::GIT_HASH.to_string(),
|
format!(
|
||||||
common::util::GIT_DATE.to_string(),
|
"Server is running {}[{}]",
|
||||||
)),
|
common::util::GIT_HASH.to_string(),
|
||||||
|
common::util::GIT_DATE.to_string(),
|
||||||
|
),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2115,10 +2242,10 @@ fn handle_whitelist(
|
|||||||
.map_err(|_| {
|
.map_err(|_| {
|
||||||
server.notify_client(
|
server.notify_client(
|
||||||
client,
|
client,
|
||||||
ServerGeneral::server_msg(ChatType::CommandError, format!(
|
ServerGeneral::server_msg(
|
||||||
"Unable to determine UUID for username \"{}\"",
|
ChatType::CommandError,
|
||||||
&username
|
format!("Unable to determine UUID for username \"{}\"", &username),
|
||||||
)),
|
),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.ok()
|
.ok()
|
||||||
@ -2132,7 +2259,10 @@ fn handle_whitelist(
|
|||||||
.edit(server.data_dir().as_ref(), |w| w.insert(uuid));
|
.edit(server.data_dir().as_ref(), |w| w.insert(uuid));
|
||||||
server.notify_client(
|
server.notify_client(
|
||||||
client,
|
client,
|
||||||
ServerGeneral::server_msg(ChatType::CommandInfo, format!("\"{}\" added to whitelist", username)),
|
ServerGeneral::server_msg(
|
||||||
|
ChatType::CommandInfo,
|
||||||
|
format!("\"{}\" added to whitelist", username),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else if whitelist_action.eq_ignore_ascii_case("remove") {
|
} else if whitelist_action.eq_ignore_ascii_case("remove") {
|
||||||
@ -2143,7 +2273,10 @@ fn handle_whitelist(
|
|||||||
.edit(server.data_dir().as_ref(), |w| w.remove(&uuid));
|
.edit(server.data_dir().as_ref(), |w| w.remove(&uuid));
|
||||||
server.notify_client(
|
server.notify_client(
|
||||||
client,
|
client,
|
||||||
ServerGeneral::server_msg(ChatType::CommandInfo, format!("\"{}\" removed from whitelist", username)),
|
ServerGeneral::server_msg(
|
||||||
|
ChatType::CommandInfo,
|
||||||
|
format!("\"{}\" removed from whitelist", username),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -2193,15 +2326,21 @@ fn handle_kick(
|
|||||||
kick_player(server, target_player, &reason);
|
kick_player(server, target_player, &reason);
|
||||||
server.notify_client(
|
server.notify_client(
|
||||||
client,
|
client,
|
||||||
ServerGeneral::server_msg(ChatType::CommandInfo, format!(
|
ServerGeneral::server_msg(
|
||||||
"Kicked {} from the server with reason: {}",
|
ChatType::CommandInfo,
|
||||||
target_alias, reason
|
format!(
|
||||||
)),
|
"Kicked {} from the server with reason: {}",
|
||||||
|
target_alias, reason
|
||||||
|
),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
server.notify_client(
|
server.notify_client(
|
||||||
client,
|
client,
|
||||||
ServerGeneral::server_msg(ChatType::CommandError, format!("Player with alias {} not found", target_alias)),
|
ServerGeneral::server_msg(
|
||||||
|
ChatType::CommandError,
|
||||||
|
format!("Player with alias {} not found", target_alias),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -2233,7 +2372,10 @@ fn handle_ban(
|
|||||||
if server.editable_settings().banlist.contains_key(&uuid) {
|
if server.editable_settings().banlist.contains_key(&uuid) {
|
||||||
server.notify_client(
|
server.notify_client(
|
||||||
client,
|
client,
|
||||||
ServerGeneral::server_msg(ChatType::CommandError, format!("{} is already on the banlist", target_alias)),
|
ServerGeneral::server_msg(
|
||||||
|
ChatType::CommandError,
|
||||||
|
format!("{} is already on the banlist", target_alias),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
server
|
server
|
||||||
@ -2247,10 +2389,13 @@ fn handle_ban(
|
|||||||
});
|
});
|
||||||
server.notify_client(
|
server.notify_client(
|
||||||
client,
|
client,
|
||||||
ServerGeneral::server_msg(ChatType::CommandInfo, format!(
|
ServerGeneral::server_msg(
|
||||||
"Added {} to the banlist with reason: {}",
|
ChatType::CommandInfo,
|
||||||
target_alias, reason
|
format!(
|
||||||
)),
|
"Added {} to the banlist with reason: {}",
|
||||||
|
target_alias, reason
|
||||||
|
),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
// If the player is online kick them
|
// If the player is online kick them
|
||||||
@ -2266,10 +2411,10 @@ fn handle_ban(
|
|||||||
} else {
|
} else {
|
||||||
server.notify_client(
|
server.notify_client(
|
||||||
client,
|
client,
|
||||||
ServerGeneral::server_msg(ChatType::CommandError, format!(
|
ServerGeneral::server_msg(
|
||||||
"Unable to determine UUID for username \"{}\"",
|
ChatType::CommandError,
|
||||||
target_alias
|
format!("Unable to determine UUID for username \"{}\"", target_alias),
|
||||||
)),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -2303,15 +2448,18 @@ fn handle_unban(
|
|||||||
});
|
});
|
||||||
server.notify_client(
|
server.notify_client(
|
||||||
client,
|
client,
|
||||||
ServerGeneral::server_msg(ChatType::CommandInfo, format!("{} was successfully unbanned", username)),
|
ServerGeneral::server_msg(
|
||||||
|
ChatType::CommandInfo,
|
||||||
|
format!("{} was successfully unbanned", username),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
server.notify_client(
|
server.notify_client(
|
||||||
client,
|
client,
|
||||||
ServerGeneral::server_msg(ChatType::CommandError, format!(
|
ServerGeneral::server_msg(
|
||||||
"Unable to determine UUID for username \"{}\"",
|
ChatType::CommandError,
|
||||||
username
|
format!("Unable to determine UUID for username \"{}\"", username),
|
||||||
)),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -16,8 +16,8 @@ use common::{
|
|||||||
lottery::Lottery,
|
lottery::Lottery,
|
||||||
outcome::Outcome,
|
outcome::Outcome,
|
||||||
rtsim::RtSimEntity,
|
rtsim::RtSimEntity,
|
||||||
uid::{Uid, UidAllocator},
|
|
||||||
terrain::{Block, TerrainGrid},
|
terrain::{Block, TerrainGrid},
|
||||||
|
uid::{Uid, UidAllocator},
|
||||||
vol::ReadVol,
|
vol::ReadVol,
|
||||||
Damage, DamageSource, Explosion, GroupTarget, RadiusEffect,
|
Damage, DamageSource, Explosion, GroupTarget, RadiusEffect,
|
||||||
};
|
};
|
||||||
@ -227,8 +227,10 @@ pub fn handle_destroy(server: &mut Server, entity: EcsEntity, cause: HealthSourc
|
|||||||
| HealthSource::Heal { by: _ }
|
| HealthSource::Heal { by: _ }
|
||||||
| HealthSource::Unknown => KillSource::Other,
|
| HealthSource::Unknown => KillSource::Other,
|
||||||
};
|
};
|
||||||
state
|
state.notify_players(ServerGeneral::server_msg(
|
||||||
.notify_players(ServerGeneral::server_msg(comp::ChatType::Kill(kill_source, *uid), "".to_string()));
|
comp::ChatType::Kill(kill_source, *uid),
|
||||||
|
"".to_string(),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,8 +98,8 @@ pub fn handle_group(server: &mut Server, entity: specs::Entity, manip: GroupMani
|
|||||||
if let Some(client) = clients.get(entity) {
|
if let Some(client) = clients.get(entity) {
|
||||||
client.send_fallible(ServerGeneral::server_msg(
|
client.send_fallible(ServerGeneral::server_msg(
|
||||||
ChatType::Meta,
|
ChatType::Meta,
|
||||||
"Invite failed, pending invites plus current group size have reached \
|
"Invite failed, pending invites plus current group size have reached the \
|
||||||
the group size limit"
|
group size limit"
|
||||||
.to_owned(),
|
.to_owned(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -55,18 +55,17 @@ use common::{
|
|||||||
recipe::default_recipe_book,
|
recipe::default_recipe_book,
|
||||||
resources::TimeOfDay,
|
resources::TimeOfDay,
|
||||||
rtsim::RtSimEntity,
|
rtsim::RtSimEntity,
|
||||||
uid::Uid,
|
|
||||||
terrain::TerrainChunkSize,
|
terrain::TerrainChunkSize,
|
||||||
|
uid::Uid,
|
||||||
vol::{ReadVol, RectVolSize},
|
vol::{ReadVol, RectVolSize},
|
||||||
};
|
};
|
||||||
use common_net::{
|
use common_net::{
|
||||||
|
msg::{
|
||||||
|
ClientType, DisconnectReason, ServerGeneral, ServerInfo, ServerInit, ServerMsg, WorldMapMsg,
|
||||||
|
},
|
||||||
sync::WorldSyncExt,
|
sync::WorldSyncExt,
|
||||||
msg::{ClientType, DisconnectReason, ServerGeneral, ServerInfo, ServerInit, ServerMsg, WorldMapMsg},
|
|
||||||
};
|
|
||||||
use common_sys::{
|
|
||||||
state::State,
|
|
||||||
plugin::PluginMgr,
|
|
||||||
};
|
};
|
||||||
|
use common_sys::{plugin::PluginMgr, state::State};
|
||||||
use futures_executor::block_on;
|
use futures_executor::block_on;
|
||||||
use metrics::{PhysicsMetrics, ServerMetrics, StateTickMetrics, TickMetrics};
|
use metrics::{PhysicsMetrics, ServerMetrics, StateTickMetrics, TickMetrics};
|
||||||
use network::{Network, Pid, ProtocolAddr};
|
use network::{Network, Pid, ProtocolAddr};
|
||||||
@ -1013,60 +1012,77 @@ impl Server {
|
|||||||
command.execute(self, entity, args);
|
command.execute(self, entity, args);
|
||||||
} else {
|
} else {
|
||||||
let plugin_manager = self.state.ecs().read_resource::<PluginMgr>();
|
let plugin_manager = self.state.ecs().read_resource::<PluginMgr>();
|
||||||
let rs = plugin_manager.execute_event(&format!("on_command_{}",&kwd), &plugin_api::event::ChatCommandEvent {
|
let rs = plugin_manager.execute_event(
|
||||||
command: kwd.clone(),
|
&format!("on_command_{}", &kwd),
|
||||||
command_args: args.split(" ").map(|x| x.to_owned()).collect(),
|
&plugin_api::event::ChatCommandEvent {
|
||||||
player: plugin_api::event::Player {
|
command: kwd.clone(),
|
||||||
id: (*(self.state.ecs().read_storage::<Uid>().get(entity).expect("Can't get player UUID [This should never appen]"))).into()
|
command_args: args.split(' ').map(|x| x.to_owned()).collect(),
|
||||||
|
player: plugin_api::event::Player {
|
||||||
|
id: *(self
|
||||||
|
.state
|
||||||
|
.ecs()
|
||||||
|
.read_storage::<Uid>()
|
||||||
|
.get(entity)
|
||||||
|
.expect("Can't get player UUID [This should never appen]")),
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
);
|
||||||
match rs {
|
match rs {
|
||||||
Ok(e) => {
|
Ok(e) => {
|
||||||
if e.is_empty() {
|
if e.is_empty() {
|
||||||
self.notify_client(
|
self.notify_client(
|
||||||
entity,
|
entity,
|
||||||
ServerGeneral::server_msg(ChatType::CommandError, format!(
|
ServerGeneral::server_msg(
|
||||||
"Unknown command '/{}'.\nType '/help' for available commands",
|
ChatType::CommandError,
|
||||||
kwd
|
format!(
|
||||||
))
|
"Unknown command '/{}'.\nType '/help' for available commands",
|
||||||
|
kwd
|
||||||
|
),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
e.into_iter().for_each(|e| {
|
e.into_iter().for_each(|e| match e {
|
||||||
match e {
|
Ok(e) => {
|
||||||
Ok(e) => {
|
if !e.is_empty() {
|
||||||
if !e.is_empty() {
|
|
||||||
self.notify_client(
|
|
||||||
entity,
|
|
||||||
ServerGeneral::server_msg(ChatType::CommandInfo, e.join("\n")),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
Err(e) => {
|
|
||||||
self.notify_client(
|
self.notify_client(
|
||||||
entity,
|
entity,
|
||||||
ServerGeneral::server_msg(ChatType::CommandError, format!(
|
ServerGeneral::server_msg(
|
||||||
"Error occurred while executing command '/{}'.\n{}",
|
ChatType::CommandInfo,
|
||||||
kwd,
|
e.join("\n"),
|
||||||
e
|
),
|
||||||
)),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
Err(e) => {
|
||||||
|
self.notify_client(
|
||||||
|
entity,
|
||||||
|
ServerGeneral::server_msg(
|
||||||
|
ChatType::CommandError,
|
||||||
|
format!(
|
||||||
|
"Error occurred while executing command '/{}'.\n{}",
|
||||||
|
kwd, e
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
error!(?e, "Can't execute command {} {}",kwd,args);
|
error!(?e, "Can't execute command {} {}", kwd, args);
|
||||||
self.notify_client(
|
self.notify_client(
|
||||||
entity,
|
entity,
|
||||||
ServerGeneral::server_msg(ChatType::CommandError, format!(
|
ServerGeneral::server_msg(
|
||||||
"Internal error while executing '/{}'.\nContact the server administrator",
|
ChatType::CommandError,
|
||||||
kwd
|
format!(
|
||||||
))
|
"Internal error while executing '/{}'.\nContact the server \
|
||||||
|
administrator",
|
||||||
|
kwd
|
||||||
|
),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,8 +13,8 @@ use common::{
|
|||||||
region::{Event as RegionEvent, RegionMap},
|
region::{Event as RegionEvent, RegionMap},
|
||||||
resources::TimeOfDay,
|
resources::TimeOfDay,
|
||||||
span,
|
span,
|
||||||
uid::Uid,
|
|
||||||
terrain::TerrainChunkSize,
|
terrain::TerrainChunkSize,
|
||||||
|
uid::Uid,
|
||||||
vol::RectVolSize,
|
vol::RectVolSize,
|
||||||
};
|
};
|
||||||
use common_net::{msg::ServerGeneral, sync::CompSyncPackage};
|
use common_net::{msg::ServerGeneral, sync::CompSyncPackage};
|
||||||
|
@ -7,7 +7,9 @@ use common::{
|
|||||||
span,
|
span,
|
||||||
uid::Uid,
|
uid::Uid,
|
||||||
};
|
};
|
||||||
use common_net::msg::{validate_chat_msg, ChatMsgValidationError, ClientGeneral, MAX_BYTES_CHAT_MSG};
|
use common_net::msg::{
|
||||||
|
validate_chat_msg, ChatMsgValidationError, ClientGeneral, MAX_BYTES_CHAT_MSG,
|
||||||
|
};
|
||||||
use specs::{Entities, Join, Read, ReadExpect, ReadStorage, System, Write};
|
use specs::{Entities, Join, Read, ReadExpect, ReadStorage, System, Write};
|
||||||
use std::sync::atomic::Ordering;
|
use std::sync::atomic::Ordering;
|
||||||
use tracing::{debug, error, warn};
|
use tracing::{debug, error, warn};
|
||||||
|
@ -10,8 +10,8 @@ use common::{
|
|||||||
comp::{Ori, Pos, Vel},
|
comp::{Ori, Pos, Vel},
|
||||||
region::{region_in_vd, regions_in_vd, Event as RegionEvent, RegionMap},
|
region::{region_in_vd, regions_in_vd, Event as RegionEvent, RegionMap},
|
||||||
span,
|
span,
|
||||||
uid::Uid,
|
|
||||||
terrain::TerrainChunkSize,
|
terrain::TerrainChunkSize,
|
||||||
|
uid::Uid,
|
||||||
vol::RectVolSize,
|
vol::RectVolSize,
|
||||||
};
|
};
|
||||||
use common_net::msg::ServerGeneral;
|
use common_net::msg::ServerGeneral;
|
||||||
|
@ -328,9 +328,7 @@ impl<'a> Widget for Group<'a> {
|
|||||||
let healths = client_state.ecs().read_storage::<common::comp::Health>();
|
let healths = client_state.ecs().read_storage::<common::comp::Health>();
|
||||||
let energy = client_state.ecs().read_storage::<common::comp::Energy>();
|
let energy = client_state.ecs().read_storage::<common::comp::Energy>();
|
||||||
let buffs = client_state.ecs().read_storage::<common::comp::Buffs>();
|
let buffs = client_state.ecs().read_storage::<common::comp::Buffs>();
|
||||||
let uid_allocator = client_state
|
let uid_allocator = client_state.ecs().read_resource::<UidAllocator>();
|
||||||
.ecs()
|
|
||||||
.read_resource::<UidAllocator>();
|
|
||||||
|
|
||||||
// Keep track of the total number of widget ids we are using for buffs
|
// Keep track of the total number of widget ids we are using for buffs
|
||||||
let mut total_buff_count = 0;
|
let mut total_buff_count = 0;
|
||||||
|
@ -5,11 +5,7 @@ use super::{
|
|||||||
};
|
};
|
||||||
use crate::ui::{fonts::Fonts, img_ids};
|
use crate::ui::{fonts::Fonts, img_ids};
|
||||||
use client::{self, Client};
|
use client::{self, Client};
|
||||||
use common::{
|
use common::{comp, terrain::TerrainChunkSize, vol::RectVolSize};
|
||||||
comp,
|
|
||||||
terrain::TerrainChunkSize,
|
|
||||||
vol::RectVolSize,
|
|
||||||
};
|
|
||||||
use common_net::msg::world_msg::SiteKind;
|
use common_net::msg::world_msg::SiteKind;
|
||||||
use conrod_core::{
|
use conrod_core::{
|
||||||
color, position,
|
color, position,
|
||||||
|
@ -62,12 +62,12 @@ use common::{
|
|||||||
BuffKind,
|
BuffKind,
|
||||||
},
|
},
|
||||||
span,
|
span,
|
||||||
uid::Uid,
|
|
||||||
terrain::TerrainChunk,
|
terrain::TerrainChunk,
|
||||||
|
uid::Uid,
|
||||||
util::srgba_to_linear,
|
util::srgba_to_linear,
|
||||||
vol::RectRasterableVol,
|
vol::RectRasterableVol,
|
||||||
};
|
};
|
||||||
use common_net::msg::{PresenceKind, Notification};
|
use common_net::msg::{Notification, PresenceKind};
|
||||||
use conrod_core::{
|
use conrod_core::{
|
||||||
text::cursor::Index,
|
text::cursor::Index,
|
||||||
widget::{self, Button, Image, Text},
|
widget::{self, Button, Image, Text},
|
||||||
@ -2439,9 +2439,7 @@ impl Hud {
|
|||||||
|
|
||||||
pub fn new_message(&mut self, msg: comp::ChatMsg) { self.new_messages.push_back(msg); }
|
pub fn new_message(&mut self, msg: comp::ChatMsg) { self.new_messages.push_back(msg); }
|
||||||
|
|
||||||
pub fn new_notification(&mut self, msg: Notification) {
|
pub fn new_notification(&mut self, msg: Notification) { self.new_notifications.push_back(msg); }
|
||||||
self.new_notifications.push_back(msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn scale_change(&mut self, scale_change: ScaleChange) -> ScaleMode {
|
pub fn scale_change(&mut self, scale_change: ScaleChange) -> ScaleMode {
|
||||||
let scale_mode = match scale_change {
|
let scale_mode = match scale_change {
|
||||||
|
Loading…
Reference in New Issue
Block a user