Updated changelog, fmt and clippy fixes

This commit is contained in:
Joshua Barretto 2020-12-13 17:40:15 +00:00
parent 9284aed8bd
commit 023888f560
28 changed files with 457 additions and 257 deletions

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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};

View File

@ -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;

View File

@ -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 {

View File

@ -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;

View File

@ -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,
}

View File

@ -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`

View File

@ -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,
};

View File

@ -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;

View File

@ -7,7 +7,7 @@ pub enum PluginError {
Toml(toml::de::Error),
NoConfig,
NoSuchModule,
PluginModuleError(PluginModuleError)
PluginModuleError(PluginModuleError),
}
#[derive(Debug)]

View File

@ -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)?)
}

View File

@ -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);
},
}
}
}

View File

@ -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()

View File

@ -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)]

View File

@ -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 {

View File

@ -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 {

View File

@ -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(),
));
}
}

View File

@ -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(),
));
}

View File

@ -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
),
),
);
}
},
}
}
}

View File

@ -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};

View File

@ -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};

View File

@ -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;

View File

@ -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;

View File

@ -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,

View File

@ -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 {