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
|
||||
- Aura system
|
||||
- Campfire resting heal
|
||||
- Initial support for game plugins, both server-side and client-side
|
||||
|
||||
### Changed
|
||||
|
||||
|
@ -28,20 +28,20 @@ use common::{
|
||||
outcome::Outcome,
|
||||
recipe::RecipeBook,
|
||||
span,
|
||||
uid::{Uid, UidAllocator},
|
||||
terrain::{block::Block, neighbors, BiomeKind, SitesKind, TerrainChunk, TerrainChunkSize},
|
||||
uid::{Uid, UidAllocator},
|
||||
vol::RectVolSize,
|
||||
};
|
||||
use common_sys::state::State;
|
||||
use common_net::{
|
||||
msg::{
|
||||
self, validate_chat_msg, world_msg::SiteInfo, ChatMsgValidationError, ClientGeneral, ClientMsg,
|
||||
ClientRegister, ClientType, DisconnectReason, InviteAnswer, Notification, PingMsg,
|
||||
PlayerInfo, PlayerListUpdate, PresenceKind, RegisterError, ServerGeneral, ServerInfo,
|
||||
ServerInit, ServerRegisterAnswer, MAX_BYTES_CHAT_MSG,
|
||||
self, validate_chat_msg, world_msg::SiteInfo, ChatMsgValidationError, ClientGeneral,
|
||||
ClientMsg, ClientRegister, ClientType, DisconnectReason, InviteAnswer, Notification,
|
||||
PingMsg, PlayerInfo, PlayerListUpdate, PresenceKind, RegisterError, ServerGeneral,
|
||||
ServerInfo, ServerInit, ServerRegisterAnswer, MAX_BYTES_CHAT_MSG,
|
||||
},
|
||||
sync::WorldSyncExt,
|
||||
};
|
||||
use common_sys::state::State;
|
||||
use comp::BuffKind;
|
||||
use futures_executor::block_on;
|
||||
use futures_timer::Delay;
|
||||
|
@ -1,5 +1,5 @@
|
||||
use common::comp;
|
||||
use crate::sync;
|
||||
use common::comp;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::marker::PhantomData;
|
||||
use sum_type::sum_type;
|
||||
|
@ -1,15 +1,15 @@
|
||||
use super::{ClientType, EcsCompPacket, PingMsg};
|
||||
use crate::sync;
|
||||
use authc::AuthClientError;
|
||||
use common::{
|
||||
character::{self, CharacterItem},
|
||||
comp,
|
||||
outcome::Outcome,
|
||||
recipe::RecipeBook,
|
||||
resources::TimeOfDay,
|
||||
uid::Uid,
|
||||
terrain::{Block, TerrainChunk},
|
||||
uid::Uid,
|
||||
};
|
||||
use crate::sync;
|
||||
use authc::AuthClientError;
|
||||
use hashbrown::HashMap;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::time::Duration;
|
||||
|
@ -5,10 +5,10 @@ mod sync_ext;
|
||||
mod track;
|
||||
|
||||
// Reexports
|
||||
pub use common::uid::{Uid, UidAllocator};
|
||||
pub use packet::{
|
||||
handle_insert, handle_modify, handle_remove, CompPacket, CompSyncPackage, EntityPackage,
|
||||
EntitySyncPackage, StatePackage,
|
||||
};
|
||||
pub use sync_ext::WorldSyncExt;
|
||||
pub use track::UpdateTracker;
|
||||
pub use common::uid::{Uid, UidAllocator};
|
||||
|
@ -1,7 +1,7 @@
|
||||
use uuid::Uuid;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use specs::{Component, FlaggedStorage, NullStorage};
|
||||
use specs_idvs::IdvStorage;
|
||||
use uuid::Uuid;
|
||||
|
||||
const MAX_ALIAS_LEN: usize = 32;
|
||||
|
||||
|
@ -4,11 +4,7 @@ use comp::{
|
||||
Ori, Pos,
|
||||
};
|
||||
use specs::Entity as EcsEntity;
|
||||
use std::{
|
||||
collections::VecDeque,
|
||||
sync::Mutex,
|
||||
ops::DerefMut,
|
||||
};
|
||||
use std::{collections::VecDeque, ops::DerefMut, sync::Mutex};
|
||||
use vek::*;
|
||||
|
||||
pub enum LocalEvent {
|
||||
|
@ -48,12 +48,11 @@ pub mod store;
|
||||
pub mod terrain;
|
||||
pub mod time;
|
||||
pub mod typed;
|
||||
pub mod util;
|
||||
pub mod uid;
|
||||
pub mod util;
|
||||
pub mod vol;
|
||||
pub mod volumes;
|
||||
|
||||
|
||||
pub use combat::{Damage, DamageSource, GroupTarget, Knockback};
|
||||
pub use explosion::{Explosion, RadiusEffect};
|
||||
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.
|
||||
#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||
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,
|
||||
/// 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,
|
||||
/// 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
|
||||
Singleplayer,
|
||||
}
|
||||
|
@ -139,9 +139,7 @@ impl Body {
|
||||
)
|
||||
}
|
||||
|
||||
pub fn can_climb(&self) -> bool {
|
||||
matches!(self, Body::Humanoid(_))
|
||||
}
|
||||
pub fn can_climb(&self) -> bool { matches!(self, Body::Humanoid(_)) }
|
||||
}
|
||||
|
||||
/// Handles updating `Components` to move player based on state of `JoinData`
|
||||
|
@ -17,9 +17,9 @@ use common::{
|
||||
path::{Chaser, TraversalConfig},
|
||||
resources::{DeltaTime, Time, TimeOfDay},
|
||||
span,
|
||||
uid::{Uid, UidAllocator},
|
||||
terrain::{Block, TerrainGrid},
|
||||
time::DayPeriod,
|
||||
uid::{Uid, UidAllocator},
|
||||
util::Dir,
|
||||
vol::ReadVol,
|
||||
};
|
||||
|
@ -8,8 +8,8 @@ use common::{
|
||||
metrics::{PhysicsMetrics, SysMetrics},
|
||||
resources::DeltaTime,
|
||||
span,
|
||||
uid::Uid,
|
||||
terrain::{Block, TerrainGrid},
|
||||
uid::Uid,
|
||||
vol::ReadVol,
|
||||
};
|
||||
use rayon::iter::ParallelIterator;
|
||||
|
@ -7,7 +7,7 @@ pub enum PluginError {
|
||||
Toml(toml::de::Error),
|
||||
NoConfig,
|
||||
NoSuchModule,
|
||||
PluginModuleError(PluginModuleError)
|
||||
PluginModuleError(PluginModuleError),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -1,15 +1,22 @@
|
||||
|
||||
pub mod errors;
|
||||
pub mod module;
|
||||
|
||||
use common::assets::ASSETS_PATH;
|
||||
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 plugin_api::Event;
|
||||
|
||||
use self::{ errors::PluginError, module::{PluginModule, PreparedEventQuery}};
|
||||
use self::{
|
||||
errors::PluginError,
|
||||
module::{PluginModule, PreparedEventQuery},
|
||||
};
|
||||
|
||||
use rayon::prelude::*;
|
||||
|
||||
@ -58,7 +65,7 @@ impl Plugin {
|
||||
.iter()
|
||||
.map(|path| {
|
||||
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<_, _>>()?;
|
||||
|
||||
@ -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 {
|
||||
self.modules.iter().flat_map(|module| {
|
||||
module.try_execute(event_name, event).map(|x| x.map_err(|e| PluginError::PluginModuleError(e)))
|
||||
}).collect::<Result<Vec<_>,_>>()
|
||||
pub fn execute_prepared<T>(
|
||||
&self,
|
||||
event_name: &str,
|
||||
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)
|
||||
}
|
||||
|
||||
pub fn execute_prepared<T>(&self, event_name: &str,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_prepared<T>(
|
||||
&self,
|
||||
event_name: &str,
|
||||
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)?)
|
||||
}
|
||||
|
||||
|
@ -22,14 +22,14 @@ pub struct PluginModule {
|
||||
}
|
||||
|
||||
impl PluginModule {
|
||||
|
||||
// This function takes bytes from a WASM File and compile them
|
||||
pub fn new(wasm_data: &Vec<u8>) -> Result<Self,PluginModuleError> {
|
||||
let module = compile(&wasm_data).map_err(|e| PluginModuleError::Compile(e))?;
|
||||
pub fn new(wasm_data: &[u8]) -> Result<Self, PluginModuleError> {
|
||||
let module = compile(&wasm_data).map_err(PluginModuleError::Compile)?;
|
||||
let instance = module
|
||||
.instantiate(&imports! {"env" => {
|
||||
"raw_emit_actions" => func!(read_action),
|
||||
}}).map_err(|e| PluginModuleError::Instantiate(e))?;
|
||||
}})
|
||||
.map_err(PluginModuleError::Instantiate)?;
|
||||
|
||||
Ok(Self {
|
||||
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>(
|
||||
&self,
|
||||
event_name: &str,
|
||||
request: &PreparedEventQuery<T>,
|
||||
) -> Option<Result<T::Response,PluginModuleError>>
|
||||
) -> Option<Result<T::Response, PluginModuleError>>
|
||||
where
|
||||
T: Event,
|
||||
{
|
||||
@ -51,21 +52,26 @@ impl PluginModule {
|
||||
}
|
||||
let bytes = {
|
||||
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,
|
||||
Err(e) => return Some(Err(e))
|
||||
Err(e) => return Some(Err(e)),
|
||||
};
|
||||
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,
|
||||
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> {
|
||||
bytes: Vec<u8>,
|
||||
_phantom: PhantomData<T>,
|
||||
@ -79,7 +85,8 @@ impl<T: Event> PreparedEventQuery<T> {
|
||||
T: Event,
|
||||
{
|
||||
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(),
|
||||
})
|
||||
}
|
||||
@ -87,7 +94,9 @@ impl<T: Event> PreparedEventQuery<T> {
|
||||
|
||||
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(
|
||||
memory: &Memory,
|
||||
function: &Function,
|
||||
@ -98,8 +107,7 @@ fn execute_raw(
|
||||
for (cell, byte) in view[MEMORY_POS..len + MEMORY_POS].iter().zip(bytes.iter()) {
|
||||
cell.set(*byte)
|
||||
}
|
||||
let start = function
|
||||
.call(MEMORY_POS as i32, len as u32)? as usize;
|
||||
let start = function.call(MEMORY_POS as i32, len as u32)? as usize;
|
||||
let view = memory.view::<u8>();
|
||||
let mut new_len_bytes = [0u8; 4];
|
||||
// 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) => {
|
||||
tracing::error!(?e, "Can't decode action");
|
||||
return;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
for action in e {
|
||||
@ -135,16 +143,16 @@ pub fn read_action(ctx: &mut Ctx, ptr: u32, len: u32) {
|
||||
Action::ServerClose => {
|
||||
tracing::info!("Server closed by plugin");
|
||||
std::process::exit(-1);
|
||||
}
|
||||
},
|
||||
Action::Print(e) => {
|
||||
tracing::info!("{}",e);
|
||||
}
|
||||
tracing::info!("{}", e);
|
||||
},
|
||||
Action::PlayerSendMessage(a, b) => {
|
||||
tracing::info!("SendMessage {} -> {}",a,b);
|
||||
}
|
||||
tracing::info!("SendMessage {} -> {}", a, b);
|
||||
},
|
||||
Action::KillEntity(e) => {
|
||||
tracing::info!("Kill Entity {}",e);
|
||||
}
|
||||
tracing::info!("Kill Entity {}", e);
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,14 +1,15 @@
|
||||
use crate::plugin::PluginMgr;
|
||||
use common::{
|
||||
comp,
|
||||
event::{EventBus, LocalEvent, ServerEvent},
|
||||
metrics::{PhysicsMetrics, SysMetrics},
|
||||
region::RegionMap,
|
||||
resources,
|
||||
resources::{DeltaTime, Time, TimeOfDay},
|
||||
span,
|
||||
terrain::{Block, TerrainChunk, TerrainGrid},
|
||||
time::DayPeriod,
|
||||
vol::{ReadVol, WriteVol},
|
||||
resources,
|
||||
};
|
||||
use common_net::sync::WorldSyncExt;
|
||||
use hashbrown::{HashMap, HashSet};
|
||||
@ -21,7 +22,6 @@ use specs::{
|
||||
use std::{sync::Arc, time::Duration};
|
||||
use tracing::info;
|
||||
use vek::*;
|
||||
use crate::plugin::PluginMgr;
|
||||
|
||||
/// How much faster should an in-game day be compared to a real day?
|
||||
// TODO: Don't hard-code this.
|
||||
@ -90,6 +90,7 @@ pub struct State {
|
||||
impl State {
|
||||
/// Create a new `State` in client mode.
|
||||
pub fn client() -> Self { Self::new(resources::GameMode::Client) }
|
||||
|
||||
/// Create a new `State` in server mode.
|
||||
pub fn server() -> Self { Self::new(resources::GameMode::Server) }
|
||||
|
||||
@ -192,9 +193,9 @@ impl State {
|
||||
// Load plugins from asset directory
|
||||
ecs.insert(match PluginMgr::from_assets() {
|
||||
Ok(plugin_mgr) => {
|
||||
if let Err(e) = plugin_mgr.execute_event("on_load", &plugin_api::event::PluginLoadEvent {
|
||||
game_mode,
|
||||
}) {
|
||||
if let Err(e) = plugin_mgr
|
||||
.execute_event("on_load", &plugin_api::event::PluginLoadEvent { game_mode })
|
||||
{
|
||||
tracing::error!(?e, "Failed to run plugin init");
|
||||
info!("Error occurred when loading plugins. Running without plugins instead.");
|
||||
PluginMgr::default()
|
||||
|
@ -1,15 +1,15 @@
|
||||
use serde::{Serialize, de::DeserializeOwned, Deserialize};
|
||||
use common::uid::Uid;
|
||||
use serde::{de::DeserializeOwned, Deserialize, Serialize};
|
||||
|
||||
#[derive(Deserialize,Serialize,Debug)]
|
||||
#[derive(Deserialize, Serialize, Debug)]
|
||||
pub enum Action {
|
||||
ServerClose,
|
||||
Print(String),
|
||||
PlayerSendMessage(usize,String),
|
||||
KillEntity(usize)
|
||||
PlayerSendMessage(usize, String),
|
||||
KillEntity(usize),
|
||||
}
|
||||
|
||||
pub trait Event: Serialize + DeserializeOwned + Send + Sync{
|
||||
pub trait Event: Serialize + DeserializeOwned + Send + Sync {
|
||||
type Response: Serialize + DeserializeOwned + Send + Sync;
|
||||
}
|
||||
|
||||
@ -17,7 +17,7 @@ pub use common::resources::GameMode;
|
||||
|
||||
pub mod event {
|
||||
use super::*;
|
||||
use serde::{Serialize,Deserialize};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)]
|
||||
pub struct ChatCommandEvent {
|
||||
@ -38,7 +38,7 @@ pub mod event {
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)]
|
||||
pub struct PlayerJoinEvent {
|
||||
pub player_name: String,
|
||||
pub player_id: usize
|
||||
pub player_id: usize,
|
||||
}
|
||||
|
||||
impl Event for PlayerJoinEvent {
|
||||
@ -48,13 +48,11 @@ pub mod event {
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)]
|
||||
pub enum PlayerJoinResult {
|
||||
CloseConnection,
|
||||
None
|
||||
None,
|
||||
}
|
||||
|
||||
impl Default for PlayerJoinResult {
|
||||
fn default() -> Self {
|
||||
Self::None
|
||||
}
|
||||
fn default() -> Self { Self::None }
|
||||
}
|
||||
|
||||
#[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_derive::*;
|
||||
|
||||
use serde::de::DeserializeOwned;
|
||||
use serde::Serialize;
|
||||
use serde::{de::DeserializeOwned, Serialize};
|
||||
|
||||
extern "C" {
|
||||
fn raw_emit_actions(ptr: *const u8, len: usize);
|
||||
}
|
||||
|
||||
pub fn emit_action(action: api::Action) {
|
||||
emit_actions(vec![action])
|
||||
}
|
||||
pub fn emit_action(action: api::Action) { emit_actions(vec![action]) }
|
||||
|
||||
pub fn emit_actions(actions: Vec<api::Action>) {
|
||||
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{
|
||||
let slice = unsafe {
|
||||
::std::slice::from_raw_parts(ptr as _, len as _)
|
||||
};
|
||||
bincode::deserialize(slice).map_err(|_|"Failed to deserialize function input")
|
||||
pub fn read_input<T>(ptr: i32, len: u32) -> Result<T, &'static str>
|
||||
where
|
||||
T: DeserializeOwned,
|
||||
{
|
||||
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 {
|
||||
|
@ -19,8 +19,8 @@ use common::{
|
||||
event::{EventBus, ServerEvent},
|
||||
npc::{self, get_npc_name},
|
||||
resources::TimeOfDay,
|
||||
uid::Uid,
|
||||
terrain::{Block, BlockKind, SpriteKind, TerrainChunkSize},
|
||||
uid::Uid,
|
||||
util::Dir,
|
||||
vol::RectVolSize,
|
||||
Damage, DamageSource, Explosion, LoadoutBuilder, RadiusEffect,
|
||||
@ -48,10 +48,10 @@ impl ChatCommandExt for ChatCommand {
|
||||
if self.needs_admin() && !server.entity_is_admin(entity) {
|
||||
server.notify_client(
|
||||
entity,
|
||||
ServerGeneral::server_msg(ChatType::CommandError, format!(
|
||||
"You don't have permission to use '/{}'.",
|
||||
self.keyword()
|
||||
)),
|
||||
ServerGeneral::server_msg(
|
||||
ChatType::CommandError,
|
||||
format!("You don't have permission to use '/{}'.", self.keyword()),
|
||||
),
|
||||
);
|
||||
return;
|
||||
} else {
|
||||
@ -150,10 +150,13 @@ fn handle_give_item(
|
||||
if inv.push(item).is_some() {
|
||||
server.notify_client(
|
||||
client,
|
||||
ServerGeneral::server_msg(ChatType::CommandError, format!(
|
||||
"Player inventory full. Gave 0 of {} items.",
|
||||
give_amount
|
||||
)),
|
||||
ServerGeneral::server_msg(
|
||||
ChatType::CommandError,
|
||||
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() {
|
||||
server.notify_client(
|
||||
client,
|
||||
ServerGeneral::server_msg(ChatType::CommandError, format!(
|
||||
"Player inventory full. Gave {} of {} items.",
|
||||
i, give_amount
|
||||
)),
|
||||
ServerGeneral::server_msg(
|
||||
ChatType::CommandError,
|
||||
format!(
|
||||
"Player inventory full. Gave {} of {} items.",
|
||||
i, give_amount
|
||||
),
|
||||
),
|
||||
);
|
||||
break;
|
||||
}
|
||||
@ -191,7 +197,10 @@ fn handle_give_item(
|
||||
} else {
|
||||
server.notify_client(
|
||||
client,
|
||||
ServerGeneral::server_msg(ChatType::CommandError, format!("Invalid item: {}", item_name)),
|
||||
ServerGeneral::server_msg(
|
||||
ChatType::CommandError,
|
||||
format!("Invalid item: {}", item_name),
|
||||
),
|
||||
);
|
||||
}
|
||||
} else {
|
||||
@ -218,13 +227,19 @@ fn handle_make_block(
|
||||
),
|
||||
None => server.notify_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 {
|
||||
server.notify_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 {
|
||||
@ -257,13 +272,19 @@ fn handle_make_sprite(
|
||||
},
|
||||
None => server.notify_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 {
|
||||
server.notify_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 {
|
||||
@ -283,7 +304,10 @@ fn handle_motd(
|
||||
) {
|
||||
server.notify_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());
|
||||
server.notify_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(_) => {
|
||||
@ -313,7 +340,10 @@ fn handle_set_motd(
|
||||
.edit(data_dir.as_ref(), |d| d.clear());
|
||||
server.notify_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 => {
|
||||
server.notify_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;
|
||||
},
|
||||
@ -518,7 +551,10 @@ fn handle_time(
|
||||
Some(time) => format!("It is {}", time.format("%H:%M").to_string()),
|
||||
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;
|
||||
},
|
||||
};
|
||||
@ -530,10 +566,10 @@ fn handle_time(
|
||||
{
|
||||
server.notify_client(
|
||||
client,
|
||||
ServerGeneral::server_msg(ChatType::CommandInfo, format!(
|
||||
"Time changed to: {}",
|
||||
new_time.format("%H:%M").to_string(),
|
||||
)),
|
||||
ServerGeneral::server_msg(
|
||||
ChatType::CommandInfo,
|
||||
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 !comp::Player::alias_is_valid(&alias) {
|
||||
// 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;
|
||||
}
|
||||
let old_alias_optional = server
|
||||
@ -610,9 +649,10 @@ fn handle_alias(
|
||||
|
||||
// Announce alias change if target has a Body.
|
||||
if ecs.read_storage::<comp::Body>().get(target).is_some() {
|
||||
server.state.notify_players(
|
||||
ServerGeneral::server_msg(ChatType::CommandInfo, format!("{} is now known as {}.", old_alias, player.alias)),
|
||||
);
|
||||
server.state.notify_players(ServerGeneral::server_msg(
|
||||
ChatType::CommandInfo,
|
||||
format!("{} is now known as {}.", old_alias, player.alias),
|
||||
));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -657,7 +697,10 @@ fn handle_tp(
|
||||
} else {
|
||||
server.notify_client(
|
||||
client,
|
||||
ServerGeneral::server_msg(ChatType::CommandError, "Unable to teleport to player!"),
|
||||
ServerGeneral::server_msg(
|
||||
ChatType::CommandError,
|
||||
"Unable to teleport to player!",
|
||||
),
|
||||
);
|
||||
}
|
||||
} else {
|
||||
@ -792,13 +835,19 @@ fn handle_spawn(
|
||||
if let Some(uid) = server.state.ecs().uid_from_entity(new_entity) {
|
||||
server.notify_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(
|
||||
client,
|
||||
ServerGeneral::server_msg(ChatType::CommandInfo, format!("Spawned {} entities", amount)),
|
||||
ServerGeneral::server_msg(
|
||||
ChatType::CommandInfo,
|
||||
format!("Spawned {} entities", amount),
|
||||
),
|
||||
);
|
||||
},
|
||||
None => server.notify_client(
|
||||
@ -920,18 +969,21 @@ fn handle_players(
|
||||
|
||||
server.notify_client(
|
||||
client,
|
||||
ServerGeneral::server_msg(ChatType::CommandInfo, entity_tuples.join().fold(
|
||||
format!("{} online players:", entity_tuples.join().count()),
|
||||
|s, (_, player, stat)| {
|
||||
format!(
|
||||
"{}\n[{}]{} Lvl {}",
|
||||
s,
|
||||
player.alias,
|
||||
stat.name,
|
||||
stat.level.level()
|
||||
)
|
||||
},
|
||||
)),
|
||||
ServerGeneral::server_msg(
|
||||
ChatType::CommandInfo,
|
||||
entity_tuples.join().fold(
|
||||
format!("{} online players:", entity_tuples.join().count()),
|
||||
|s, (_, player, stat)| {
|
||||
format!(
|
||||
"{}\n[{}]{} Lvl {}",
|
||||
s,
|
||||
player.alias,
|
||||
stat.name,
|
||||
stat.level.level()
|
||||
)
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@ -978,7 +1030,10 @@ fn handle_help(
|
||||
action: &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 {
|
||||
let mut message = String::new();
|
||||
for cmd in CHAT_COMMANDS.iter() {
|
||||
@ -991,7 +1046,10 @@ fn handle_help(
|
||||
for (k, v) in CHAT_SHORTCUTS.iter() {
|
||||
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 {
|
||||
"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
|
||||
@ -1079,10 +1140,10 @@ fn handle_object(
|
||||
.build();
|
||||
server.notify_client(
|
||||
client,
|
||||
ServerGeneral::server_msg(ChatType::CommandInfo, format!(
|
||||
"Spawned: {}",
|
||||
obj_str_res.unwrap_or("<Unknown object>")
|
||||
)),
|
||||
ServerGeneral::server_msg(
|
||||
ChatType::CommandInfo,
|
||||
format!("Spawned: {}", obj_str_res.unwrap_or("<Unknown object>")),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
return server.notify_client(
|
||||
@ -1116,7 +1177,10 @@ fn handle_light(
|
||||
if r < 0.0 || g < 0.0 || b < 0.0 {
|
||||
server.notify_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;
|
||||
}
|
||||
@ -1155,7 +1219,10 @@ fn handle_light(
|
||||
} else {
|
||||
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 {
|
||||
server.notify_client(
|
||||
client,
|
||||
@ -1189,12 +1256,18 @@ fn handle_lantern(
|
||||
.into();
|
||||
server.notify_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 {
|
||||
server.notify_client(
|
||||
client,
|
||||
ServerGeneral::server_msg(ChatType::CommandInfo, "You adjusted flame strength."),
|
||||
ServerGeneral::server_msg(
|
||||
ChatType::CommandInfo,
|
||||
"You adjusted flame strength.",
|
||||
),
|
||||
);
|
||||
}
|
||||
} else {
|
||||
@ -1223,13 +1296,19 @@ fn handle_explosion(
|
||||
if power > 512.0 {
|
||||
server.notify_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;
|
||||
} else if power <= 0.0 {
|
||||
server.notify_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;
|
||||
}
|
||||
@ -1281,7 +1360,10 @@ fn handle_waypoint(
|
||||
.ecs()
|
||||
.write_storage::<comp::Waypoint>()
|
||||
.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(
|
||||
client,
|
||||
ServerGeneral::Notification(Notification::WaypointSaved),
|
||||
@ -1332,7 +1414,10 @@ fn handle_adminify(
|
||||
None => {
|
||||
server.notify_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 {
|
||||
server.notify_client(
|
||||
client,
|
||||
ServerGeneral::server_msg(ChatType::CommandError, format!("Player '{}' not found!", alias)),
|
||||
ServerGeneral::server_msg(
|
||||
ChatType::CommandError,
|
||||
format!("Player '{}' not found!", alias),
|
||||
),
|
||||
);
|
||||
}
|
||||
} else {
|
||||
@ -1432,7 +1520,10 @@ fn handle_faction(
|
||||
} else {
|
||||
server.notify_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(
|
||||
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 {
|
||||
server.notify_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 {
|
||||
@ -1539,7 +1636,10 @@ fn handle_group_kick(
|
||||
} else {
|
||||
server.notify_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 {
|
||||
@ -1593,7 +1693,10 @@ fn handle_group_promote(
|
||||
} else {
|
||||
server.notify_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 {
|
||||
@ -1760,7 +1863,10 @@ fn handle_debug_column(
|
||||
) {
|
||||
server.notify_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),
|
||||
None => server.notify_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)
|
||||
.map(|(entity, _)| entity)
|
||||
.ok_or_else(|| {
|
||||
ServerGeneral::server_msg(ChatType::CommandError, format!("Player '{}' not found!", alias))
|
||||
ServerGeneral::server_msg(
|
||||
ChatType::CommandError,
|
||||
format!("Player '{}' not found!", alias),
|
||||
)
|
||||
})
|
||||
} else {
|
||||
Ok(fallback)
|
||||
@ -1885,7 +1997,10 @@ fn handle_give_exp(
|
||||
if let Some(stats) = ecs.write_storage::<comp::Stats>().get_mut(player) {
|
||||
stats.exp.change_by(exp);
|
||||
} 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) => {
|
||||
@ -1936,7 +2051,10 @@ fn handle_set_level(
|
||||
stats.level.set_level(lvl);
|
||||
body_type = Some(stats.body_type);
|
||||
} 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;
|
||||
}
|
||||
|
||||
@ -1986,7 +2104,10 @@ fn handle_debug(
|
||||
} else {
|
||||
server.notify_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 {
|
||||
server.notify_client(
|
||||
client,
|
||||
ServerGeneral::server_msg(ChatType::CommandError, format!("Unknown command: /{}", cmd)),
|
||||
ServerGeneral::server_msg(
|
||||
ChatType::CommandError,
|
||||
format!("Unknown command: /{}", cmd),
|
||||
),
|
||||
);
|
||||
}
|
||||
} else {
|
||||
@ -2090,11 +2214,14 @@ fn handle_version(
|
||||
) {
|
||||
server.notify_client(
|
||||
client,
|
||||
ServerGeneral::server_msg(ChatType::CommandInfo, format!(
|
||||
"Server is running {}[{}]",
|
||||
common::util::GIT_HASH.to_string(),
|
||||
common::util::GIT_DATE.to_string(),
|
||||
)),
|
||||
ServerGeneral::server_msg(
|
||||
ChatType::CommandInfo,
|
||||
format!(
|
||||
"Server is running {}[{}]",
|
||||
common::util::GIT_HASH.to_string(),
|
||||
common::util::GIT_DATE.to_string(),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@ -2115,10 +2242,10 @@ fn handle_whitelist(
|
||||
.map_err(|_| {
|
||||
server.notify_client(
|
||||
client,
|
||||
ServerGeneral::server_msg(ChatType::CommandError, format!(
|
||||
"Unable to determine UUID for username \"{}\"",
|
||||
&username
|
||||
)),
|
||||
ServerGeneral::server_msg(
|
||||
ChatType::CommandError,
|
||||
format!("Unable to determine UUID for username \"{}\"", &username),
|
||||
),
|
||||
)
|
||||
})
|
||||
.ok()
|
||||
@ -2132,7 +2259,10 @@ fn handle_whitelist(
|
||||
.edit(server.data_dir().as_ref(), |w| w.insert(uuid));
|
||||
server.notify_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") {
|
||||
@ -2143,7 +2273,10 @@ fn handle_whitelist(
|
||||
.edit(server.data_dir().as_ref(), |w| w.remove(&uuid));
|
||||
server.notify_client(
|
||||
client,
|
||||
ServerGeneral::server_msg(ChatType::CommandInfo, format!("\"{}\" removed from whitelist", username)),
|
||||
ServerGeneral::server_msg(
|
||||
ChatType::CommandInfo,
|
||||
format!("\"{}\" removed from whitelist", username),
|
||||
),
|
||||
);
|
||||
}
|
||||
} else {
|
||||
@ -2193,15 +2326,21 @@ fn handle_kick(
|
||||
kick_player(server, target_player, &reason);
|
||||
server.notify_client(
|
||||
client,
|
||||
ServerGeneral::server_msg(ChatType::CommandInfo, format!(
|
||||
"Kicked {} from the server with reason: {}",
|
||||
target_alias, reason
|
||||
)),
|
||||
ServerGeneral::server_msg(
|
||||
ChatType::CommandInfo,
|
||||
format!(
|
||||
"Kicked {} from the server with reason: {}",
|
||||
target_alias, reason
|
||||
),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
server.notify_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 {
|
||||
@ -2233,7 +2372,10 @@ fn handle_ban(
|
||||
if server.editable_settings().banlist.contains_key(&uuid) {
|
||||
server.notify_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 {
|
||||
server
|
||||
@ -2247,10 +2389,13 @@ fn handle_ban(
|
||||
});
|
||||
server.notify_client(
|
||||
client,
|
||||
ServerGeneral::server_msg(ChatType::CommandInfo, format!(
|
||||
"Added {} to the banlist with reason: {}",
|
||||
target_alias, reason
|
||||
)),
|
||||
ServerGeneral::server_msg(
|
||||
ChatType::CommandInfo,
|
||||
format!(
|
||||
"Added {} to the banlist with reason: {}",
|
||||
target_alias, reason
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
// If the player is online kick them
|
||||
@ -2266,10 +2411,10 @@ fn handle_ban(
|
||||
} else {
|
||||
server.notify_client(
|
||||
client,
|
||||
ServerGeneral::server_msg(ChatType::CommandError, format!(
|
||||
"Unable to determine UUID for username \"{}\"",
|
||||
target_alias
|
||||
)),
|
||||
ServerGeneral::server_msg(
|
||||
ChatType::CommandError,
|
||||
format!("Unable to determine UUID for username \"{}\"", target_alias),
|
||||
),
|
||||
)
|
||||
}
|
||||
} else {
|
||||
@ -2303,15 +2448,18 @@ fn handle_unban(
|
||||
});
|
||||
server.notify_client(
|
||||
client,
|
||||
ServerGeneral::server_msg(ChatType::CommandInfo, format!("{} was successfully unbanned", username)),
|
||||
ServerGeneral::server_msg(
|
||||
ChatType::CommandInfo,
|
||||
format!("{} was successfully unbanned", username),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
server.notify_client(
|
||||
client,
|
||||
ServerGeneral::server_msg(ChatType::CommandError, format!(
|
||||
"Unable to determine UUID for username \"{}\"",
|
||||
username
|
||||
)),
|
||||
ServerGeneral::server_msg(
|
||||
ChatType::CommandError,
|
||||
format!("Unable to determine UUID for username \"{}\"", username),
|
||||
),
|
||||
)
|
||||
}
|
||||
} else {
|
||||
|
@ -16,8 +16,8 @@ use common::{
|
||||
lottery::Lottery,
|
||||
outcome::Outcome,
|
||||
rtsim::RtSimEntity,
|
||||
uid::{Uid, UidAllocator},
|
||||
terrain::{Block, TerrainGrid},
|
||||
uid::{Uid, UidAllocator},
|
||||
vol::ReadVol,
|
||||
Damage, DamageSource, Explosion, GroupTarget, RadiusEffect,
|
||||
};
|
||||
@ -227,8 +227,10 @@ pub fn handle_destroy(server: &mut Server, entity: EcsEntity, cause: HealthSourc
|
||||
| HealthSource::Heal { by: _ }
|
||||
| HealthSource::Unknown => KillSource::Other,
|
||||
};
|
||||
state
|
||||
.notify_players(ServerGeneral::server_msg(comp::ChatType::Kill(kill_source, *uid), "".to_string()));
|
||||
state.notify_players(ServerGeneral::server_msg(
|
||||
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) {
|
||||
client.send_fallible(ServerGeneral::server_msg(
|
||||
ChatType::Meta,
|
||||
"Invite failed, pending invites plus current group size have reached \
|
||||
the group size limit"
|
||||
"Invite failed, pending invites plus current group size have reached the \
|
||||
group size limit"
|
||||
.to_owned(),
|
||||
));
|
||||
}
|
||||
|
@ -55,18 +55,17 @@ use common::{
|
||||
recipe::default_recipe_book,
|
||||
resources::TimeOfDay,
|
||||
rtsim::RtSimEntity,
|
||||
uid::Uid,
|
||||
terrain::TerrainChunkSize,
|
||||
uid::Uid,
|
||||
vol::{ReadVol, RectVolSize},
|
||||
};
|
||||
use common_net::{
|
||||
msg::{
|
||||
ClientType, DisconnectReason, ServerGeneral, ServerInfo, ServerInit, ServerMsg, WorldMapMsg,
|
||||
},
|
||||
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 metrics::{PhysicsMetrics, ServerMetrics, StateTickMetrics, TickMetrics};
|
||||
use network::{Network, Pid, ProtocolAddr};
|
||||
@ -1013,60 +1012,77 @@ impl Server {
|
||||
command.execute(self, entity, args);
|
||||
} else {
|
||||
let plugin_manager = self.state.ecs().read_resource::<PluginMgr>();
|
||||
let rs = plugin_manager.execute_event(&format!("on_command_{}",&kwd), &plugin_api::event::ChatCommandEvent {
|
||||
command: kwd.clone(),
|
||||
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]"))).into()
|
||||
let rs = plugin_manager.execute_event(
|
||||
&format!("on_command_{}", &kwd),
|
||||
&plugin_api::event::ChatCommandEvent {
|
||||
command: kwd.clone(),
|
||||
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 {
|
||||
Ok(e) => {
|
||||
if e.is_empty() {
|
||||
self.notify_client(
|
||||
entity,
|
||||
ServerGeneral::server_msg(ChatType::CommandError, format!(
|
||||
"Unknown command '/{}'.\nType '/help' for available commands",
|
||||
kwd
|
||||
))
|
||||
ServerGeneral::server_msg(
|
||||
ChatType::CommandError,
|
||||
format!(
|
||||
"Unknown command '/{}'.\nType '/help' for available commands",
|
||||
kwd
|
||||
),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
e.into_iter().for_each(|e| {
|
||||
match e {
|
||||
Ok(e) => {
|
||||
if !e.is_empty() {
|
||||
self.notify_client(
|
||||
entity,
|
||||
ServerGeneral::server_msg(ChatType::CommandInfo, e.join("\n")),
|
||||
);
|
||||
}
|
||||
},
|
||||
Err(e) => {
|
||||
e.into_iter().for_each(|e| match e {
|
||||
Ok(e) => {
|
||||
if !e.is_empty() {
|
||||
self.notify_client(
|
||||
entity,
|
||||
ServerGeneral::server_msg(ChatType::CommandError, format!(
|
||||
"Error occurred while executing command '/{}'.\n{}",
|
||||
kwd,
|
||||
e
|
||||
)),
|
||||
ServerGeneral::server_msg(
|
||||
ChatType::CommandInfo,
|
||||
e.join("\n"),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
Err(e) => {
|
||||
self.notify_client(
|
||||
entity,
|
||||
ServerGeneral::server_msg(
|
||||
ChatType::CommandError,
|
||||
format!(
|
||||
"Error occurred while executing command '/{}'.\n{}",
|
||||
kwd, e
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
Err(e) => {
|
||||
error!(?e, "Can't execute command {} {}",kwd,args);
|
||||
error!(?e, "Can't execute command {} {}", kwd, args);
|
||||
self.notify_client(
|
||||
entity,
|
||||
ServerGeneral::server_msg(ChatType::CommandError, format!(
|
||||
"Internal error while executing '/{}'.\nContact the server administrator",
|
||||
kwd
|
||||
))
|
||||
ServerGeneral::server_msg(
|
||||
ChatType::CommandError,
|
||||
format!(
|
||||
"Internal error while executing '/{}'.\nContact the server \
|
||||
administrator",
|
||||
kwd
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -13,8 +13,8 @@ use common::{
|
||||
region::{Event as RegionEvent, RegionMap},
|
||||
resources::TimeOfDay,
|
||||
span,
|
||||
uid::Uid,
|
||||
terrain::TerrainChunkSize,
|
||||
uid::Uid,
|
||||
vol::RectVolSize,
|
||||
};
|
||||
use common_net::{msg::ServerGeneral, sync::CompSyncPackage};
|
||||
|
@ -7,7 +7,9 @@ use common::{
|
||||
span,
|
||||
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 std::sync::atomic::Ordering;
|
||||
use tracing::{debug, error, warn};
|
||||
|
@ -10,8 +10,8 @@ use common::{
|
||||
comp::{Ori, Pos, Vel},
|
||||
region::{region_in_vd, regions_in_vd, Event as RegionEvent, RegionMap},
|
||||
span,
|
||||
uid::Uid,
|
||||
terrain::TerrainChunkSize,
|
||||
uid::Uid,
|
||||
vol::RectVolSize,
|
||||
};
|
||||
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 energy = client_state.ecs().read_storage::<common::comp::Energy>();
|
||||
let buffs = client_state.ecs().read_storage::<common::comp::Buffs>();
|
||||
let uid_allocator = client_state
|
||||
.ecs()
|
||||
.read_resource::<UidAllocator>();
|
||||
let uid_allocator = client_state.ecs().read_resource::<UidAllocator>();
|
||||
|
||||
// Keep track of the total number of widget ids we are using for buffs
|
||||
let mut total_buff_count = 0;
|
||||
|
@ -5,11 +5,7 @@ use super::{
|
||||
};
|
||||
use crate::ui::{fonts::Fonts, img_ids};
|
||||
use client::{self, Client};
|
||||
use common::{
|
||||
comp,
|
||||
terrain::TerrainChunkSize,
|
||||
vol::RectVolSize,
|
||||
};
|
||||
use common::{comp, terrain::TerrainChunkSize, vol::RectVolSize};
|
||||
use common_net::msg::world_msg::SiteKind;
|
||||
use conrod_core::{
|
||||
color, position,
|
||||
|
@ -62,12 +62,12 @@ use common::{
|
||||
BuffKind,
|
||||
},
|
||||
span,
|
||||
uid::Uid,
|
||||
terrain::TerrainChunk,
|
||||
uid::Uid,
|
||||
util::srgba_to_linear,
|
||||
vol::RectRasterableVol,
|
||||
};
|
||||
use common_net::msg::{PresenceKind, Notification};
|
||||
use common_net::msg::{Notification, PresenceKind};
|
||||
use conrod_core::{
|
||||
text::cursor::Index,
|
||||
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_notification(&mut self, msg: Notification) {
|
||||
self.new_notifications.push_back(msg);
|
||||
}
|
||||
pub fn new_notification(&mut self, msg: Notification) { self.new_notifications.push_back(msg); }
|
||||
|
||||
pub fn scale_change(&mut self, scale_change: ScaleChange) -> ScaleMode {
|
||||
let scale_mode = match scale_change {
|
||||
|
Loading…
Reference in New Issue
Block a user