Merge branch 'master' into 191_player_to_player_dm

This commit is contained in:
tommy 2019-07-17 13:53:10 -04:00
commit 3c6fb7a3ec
28 changed files with 191 additions and 58 deletions

1
.gitignore vendored
View File

@ -31,5 +31,6 @@
# Veloren
*.rar
*.log
settings.ron
run.sh
screenshots

11
Cargo.lock generated
View File

@ -2688,7 +2688,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "uvth"
version = "3.1.0"
version = "3.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"crossbeam-channel 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
@ -2731,7 +2731,7 @@ dependencies = [
"log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
"specs 0.14.3 (registry+https://github.com/rust-lang/crates.io-index)",
"uvth 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"uvth 3.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"vek 0.9.8 (registry+https://github.com/rust-lang/crates.io-index)",
"veloren-common 0.2.0",
]
@ -2766,9 +2766,12 @@ version = "0.2.0"
dependencies = [
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
"ron 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"scan_fmt 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.94 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.94 (registry+https://github.com/rust-lang/crates.io-index)",
"specs 0.14.3 (registry+https://github.com/rust-lang/crates.io-index)",
"uvth 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"uvth 3.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"vek 0.9.8 (registry+https://github.com/rust-lang/crates.io-index)",
"veloren-common 0.2.0",
"veloren-world 0.2.0",
@ -3329,7 +3332,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
"checksum user32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4ef4711d107b21b410a3a974b1204d9accc8b10dad75d8324b5d755de1617d47"
"checksum utf8-ranges 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9d50aa7650df78abf942826607c62468ce18d9019673d4a2ebe1865dbb96ffde"
"checksum uvth 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "58dde8b476ec1613a6a233a0a472a1b9e4f61e779022028d795f7a49dcd0c311"
"checksum uvth 3.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e59a167890d173eb0fcd7a1b99b84dc05c521ae8d76599130b8e19bef287abbf"
"checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a"
"checksum vek 0.9.8 (registry+https://github.com/rust-lang/crates.io-index)" = "1c95e5c5c123ecdb4a1a27a590f053a6c6de4b6ea696f4f0ef99054ead450258"
"checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd"

BIN
assets/voxygen/element/icons/orc_f.png (Stored with Git LFS)

Binary file not shown.

BIN
assets/voxygen/element/icons/orc_m.png (Stored with Git LFS)

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -6,6 +6,8 @@ pub enum Error {
ServerWentMad,
ServerTimeout,
ServerShutdown,
TooManyPlayers,
//TODO: InvalidAlias,
Other(String),
}

View File

@ -9,7 +9,7 @@ pub use specs::Entity as EcsEntity;
use common::{
comp,
msg::{ClientMsg, ClientState, ServerInfo, ServerMsg},
msg::{ClientMsg, ClientState, ServerError, ServerInfo, ServerMsg},
net::PostBox,
state::State,
terrain::{block::Block, chonk::ChonkMetrics, TerrainChunk, TerrainChunkSize},
@ -73,6 +73,9 @@ impl Client {
.ok_or(Error::ServerWentMad)?;
(state, entity, server_info)
}
Some(ServerMsg::Error(ServerError::TooManyPlayers)) => {
return Err(Error::TooManyPlayers)
}
_ => return Err(Error::ServerWentMad),
};
@ -361,8 +364,12 @@ impl Client {
if new_msgs.len() > 0 {
for msg in new_msgs {
match msg {
ServerMsg::InitialSync { .. } => return Err(Error::ServerWentMad),
ServerMsg::Error(e) => match e {
ServerError::TooManyPlayers => return Err(Error::ServerWentMad),
//TODO: ServerError::InvalidAlias => return Err(Error::InvalidAlias),
},
ServerMsg::Shutdown => return Err(Error::ServerShutdown),
ServerMsg::InitialSync { .. } => return Err(Error::ServerWentMad),
ServerMsg::Ping => self.postbox.send_message(ClientMsg::Pong),
ServerMsg::Pong => {
self.last_ping_delta = Instant::now()

View File

@ -19,7 +19,6 @@ impl Player {
pub fn is_valid(&self) -> bool {
self.alias.chars().all(|c| c.is_alphanumeric() || c == '_')
&& self.alias.len() <= MAX_ALIAS_LEN
// TODO: Check view distance here based on server config too
}
}

View File

@ -5,7 +5,7 @@ pub mod server;
// Reexports
pub use self::client::ClientMsg;
pub use self::ecs_packet::{EcsCompPacket, EcsResPacket};
pub use self::server::{RequestStateError, ServerInfo, ServerMsg};
pub use self::server::{RequestStateError, ServerError, ServerInfo, ServerMsg};
#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
pub enum ClientState {

View File

@ -41,6 +41,13 @@ pub enum ServerMsg {
key: Vec2<i32>,
chunk: Box<TerrainChunk>,
},
Error(ServerError),
Disconnect,
Shutdown,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ServerError {
TooManyPlayers,
//TODO: InvalidAlias,
}

View File

@ -9,4 +9,4 @@ server = { package = "veloren-server", path = "../server" }
common = { package = "veloren-common", path = "../common" }
log = "0.4"
pretty_env_logger = "0.3"
pretty_env_logger = "0.3"

View File

@ -1,6 +1,6 @@
use common::clock::Clock;
use log::info;
use server::{Event, Input, Server};
use server::{Event, Input, Server, ServerSettings};
use std::time::Duration;
const TPS: u64 = 30;
@ -14,8 +14,11 @@ fn main() {
// Set up an fps clock
let mut clock = Clock::start();
// Load settings
let settings = ServerSettings::load();
// Create server
let mut server = Server::new().expect("Failed to create server instance!");
let mut server = Server::new(settings).expect("Failed to create server instance!");
loop {
let events = server

View File

@ -14,3 +14,6 @@ vek = "0.9"
uvth = "3.1.0"
lazy_static = "1.3.0"
scan_fmt = "0.1.3"
ron = "0.5.1"
serde = "1.0"
serde_derive = "1.0"

View File

@ -41,6 +41,10 @@ impl Clients {
}
}
pub fn len(&mut self) -> usize {
self.clients.len()
}
pub fn add(&mut self, entity: EcsEntity, client: Client) {
self.clients.insert(entity, client);
}

View File

@ -124,6 +124,12 @@ lazy_static! {
"/msg <alias> : Send a message to another player",
handle_msg,
),
ChatCommand::new(
"killnpcs",
"{}",
"/killnpcs : Kill the NPCs",
handle_killnpcs,
),
];
}
@ -414,6 +420,23 @@ fn kind_to_body(kind: NpcKind) -> comp::Body {
}
}
fn handle_killnpcs(server: &mut Server, entity: EcsEntity, _args: String, _action: &ChatCommand) {
let ecs = server.state.ecs();
let mut stats = ecs.write_storage::<comp::Stats>();
let players = ecs.read_storage::<comp::Player>();
let mut count = 0;
for (stats, ()) in (&mut stats, !&players).join() {
count += 1;
stats.health.set_to(0, comp::HealthSource::Command);
}
let text = if count > 0 {
format!("Destroyed {} NPCs.", count)
} else {
"No NPCs on server.".to_string()
};
server.clients.notify(entity, ServerMsg::Chat(text));
}
fn handle_msg(server: &mut Server, entity: EcsEntity, args: String, action: &ChatCommand) {
let opt_alias = scan_fmt!(&args, action.arg_fmt, String);
match opt_alias {
@ -468,3 +491,4 @@ fn handle_msg(server: &mut Server, entity: EcsEntity, args: String, action: &Cha
.notify(entity, ServerMsg::Chat(String::from(action.help_string))),
}
}

View File

@ -4,9 +4,10 @@ pub mod client;
pub mod cmd;
pub mod error;
pub mod input;
pub mod settings;
// Reexports
pub use crate::{error::Error, input::Input};
pub use crate::{error::Error, input::Input, settings::ServerSettings};
use crate::{
client::{Client, Clients},
@ -14,9 +15,9 @@ use crate::{
};
use common::{
comp,
msg::{ClientMsg, ClientState, RequestStateError, ServerInfo, ServerMsg},
msg::{ClientMsg, ClientState, RequestStateError, ServerError, ServerInfo, ServerMsg},
net::PostOffice,
state::{State, TerrainChange, Uid},
state::{State, TerrainChange, TimeOfDay, Uid},
terrain::{block::Block, TerrainChunk, TerrainChunkSize, TerrainMap},
vol::VolSize,
vol::Vox,
@ -36,8 +37,6 @@ use world::World;
const CLIENT_TIMEOUT: f64 = 20.0; // Seconds
const DEFAULT_WORLD_SEED: u32 = 1337;
pub enum Event {
ClientConnected {
entity: EcsEntity,
@ -66,19 +65,20 @@ pub struct Server {
chunk_rx: mpsc::Receiver<(Vec2<i32>, TerrainChunk)>,
pending_chunks: HashSet<Vec2<i32>>,
server_settings: ServerSettings,
server_info: ServerInfo,
}
impl Server {
/// Create a new `Server` bound to the default socket.
#[allow(dead_code)]
pub fn new() -> Result<Self, Error> {
Self::bind(SocketAddr::from(([0; 4], 59003)))
pub fn new(settings: ServerSettings) -> Result<Self, Error> {
Self::bind(settings.address, settings)
}
/// Create a new server bound to the given socket.
#[allow(dead_code)]
pub fn bind<A: Into<SocketAddr>>(addrs: A) -> Result<Self, Error> {
pub fn bind<A: Into<SocketAddr>>(addrs: A, settings: ServerSettings) -> Result<Self, Error> {
let (chunk_tx, chunk_rx) = mpsc::channel();
let mut state = State::default();
@ -86,9 +86,12 @@ impl Server {
.ecs_mut()
.add_resource(SpawnPoint(Vec3::new(16_384.0, 16_384.0, 380.0)));
// Set starting time for the server.
state.ecs_mut().write_resource::<TimeOfDay>().0 = settings.start_time;
let this = Self {
state,
world: Arc::new(World::generate(DEFAULT_WORLD_SEED)),
world: Arc::new(World::generate(settings.world_seed)),
postoffice: PostOffice::bind(addrs.into())?,
clients: Clients::empty(),
@ -101,9 +104,10 @@ impl Server {
pending_chunks: HashSet::new(),
server_info: ServerInfo {
name: "Server name".to_owned(),
description: "This is the best Veloren server.".to_owned(),
name: settings.server_name.clone(),
description: settings.server_description.clone(),
},
server_settings: settings,
};
Ok(this)
@ -356,16 +360,20 @@ impl Server {
last_ping: self.state.get_time(),
};
// Return the state of the current world (all of the components that Sphynx tracks).
client.notify(ServerMsg::InitialSync {
ecs_state: self.state.ecs().gen_state_package(),
entity_uid: self.state.ecs().uid_from_entity(entity).unwrap().into(), // Can't fail.
server_info: self.server_info.clone(),
});
if self.server_settings.max_players <= self.clients.len() {
client.notify(ServerMsg::Error(ServerError::TooManyPlayers));
} else {
// Return the state of the current world (all of the components that Sphynx tracks).
client.notify(ServerMsg::InitialSync {
ecs_state: self.state.ecs().gen_state_package(),
entity_uid: self.state.ecs().uid_from_entity(entity).unwrap().into(), // Can't fail.
server_info: self.server_info.clone(),
});
frontend_events.push(Event::ClientConnected { entity });
}
self.clients.add(entity, client);
frontend_events.push(Event::ClientConnected { entity });
}
Ok(frontend_events)

65
server/src/settings.rs Normal file
View File

@ -0,0 +1,65 @@
use serde_derive::{Deserialize, Serialize};
use std::{fs, io::prelude::*, net::SocketAddr, path::PathBuf};
#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(default)]
pub struct ServerSettings {
pub address: SocketAddr,
pub max_players: usize,
pub world_seed: u32,
//pub pvp_enabled: bool,
pub server_name: String,
pub server_description: String,
//pub login_server: whatever
pub start_time: f64,
}
impl Default for ServerSettings {
fn default() -> Self {
Self {
address: SocketAddr::from(([0; 4], 59003)),
world_seed: 1337,
server_name: "Server name".to_owned(),
server_description: "This is the best Veloren server.".to_owned(),
max_players: 16,
start_time: 0.0,
}
}
}
impl ServerSettings {
pub fn load() -> Self {
let path = ServerSettings::get_settings_path();
if let Ok(file) = fs::File::open(path) {
match ron::de::from_reader(file) {
Ok(x) => x,
Err(e) => {
log::warn!("Failed to parse setting file! Fallback to default. {}", e);
Self::default()
}
}
} else {
let default_settings = Self::default();
match default_settings.save_to_file() {
Err(e) => log::error!("Failed to create default setting file! {}", e),
_ => {}
}
default_settings
}
}
pub fn save_to_file(&self) -> std::io::Result<()> {
let path = ServerSettings::get_settings_path();
let mut config_file = fs::File::create(path)?;
let s: &str = &ron::ser::to_string_pretty(self, ron::ser::PrettyConfig::default()).unwrap();
config_file.write_all(s.as_bytes()).unwrap();
Ok(())
}
fn get_settings_path() -> PathBuf {
PathBuf::from(r"settings.ron")
}
}

View File

@ -104,10 +104,10 @@ impl<'a> From<&'a comp::humanoid::Body> for SkeletonAttr {
},
neck_height: match (body.race, body.body_type) {
(Orc, Male) => -2.0,
(Orc, Female) => -2.0,
(Human, Male) => -0.5,
(Orc, Female) => 0.0,
(Human, Male) => -0.75,
(Human, Female) => -2.0,
(Elf, Male) => -0.5,
(Elf, Male) => -0.75,
(Elf, Female) => -1.25,
(Dwarf, Male) => -0.0,
(Dwarf, Female) => -1.0,
@ -117,11 +117,11 @@ impl<'a> From<&'a comp::humanoid::Body> for SkeletonAttr {
(Danari, Female) => -0.5,
},
neck_forward: match (body.race, body.body_type) {
(Orc, Male) => 1.0,
(Orc, Female) => -1.0,
(Orc, Male) => 0.0,
(Orc, Female) => -2.0,
(Human, Male) => 0.0,
(Human, Female) => -1.0,
(Elf, Male) => 1.25,
(Elf, Male) => 0.0,
(Elf, Female) => -0.5,
(Dwarf, Male) => 2.0,
(Dwarf, Female) => 0.0,

View File

@ -20,6 +20,7 @@ pub enum Error {
// Parsing/host name resolution successful but could not connect.
ConnectionFailed(ClientError),
ClientCrashed,
ServerIsFull,
}
// Used to asynchronously parse the server address, resolve host names,
@ -76,6 +77,10 @@ impl ClientInit {
ClientError::Network(_) => {
last_err = Some(Error::ConnectionFailed(err))
}
ClientError::TooManyPlayers => {
last_err = Some(Error::ServerIsFull);
break;
}
// TODO: Handle errors?
_ => panic!(
"Unexpected non-network error when creating client: {:?}",

View File

@ -64,6 +64,7 @@ impl PlayState for MainMenuState {
self.main_menu_ui.login_error(
match err {
InitError::BadAddress(_) | InitError::NoAddress => "Server not found",
InitError::ServerIsFull => "Server is Full!",
InitError::ConnectionFailed(_) => "Connection failed",
InitError::ClientCrashed => "Client crashed",
}

View File

@ -309,7 +309,7 @@ impl MainMenuUi {
.w_h(400.0, 300.0)
.set(self.ids.servers_frame, ui_widgets);
let net_settings = &global_state.settings.networking;
let ref mut net_settings = global_state.settings.networking;
// TODO: Draw scroll bar or remove it.
let (mut items, _scrollbar) = List::flow_down(net_settings.servers.len())
@ -344,8 +344,8 @@ impl MainMenuUi {
)
.was_clicked()
{
// TODO: Set as current server address
self.server_address = net_settings.servers[item.i].clone();
net_settings.default_server = item.i;
}
}

View File

@ -153,7 +153,7 @@ impl FigureModelCache {
let (name, offset) = match (race, body_type) {
(Human, Male) => (
"figure/head/head_human_male.vox",
Vec3::new(-7.0, -5.5, -2.25),
Vec3::new(-7.0, -5.0, -2.25),
),
(Human, Female) => (
"figure/head/head_human_female.vox",
@ -177,11 +177,11 @@ impl FigureModelCache {
),
(Orc, Male) => (
"figure/head/head_orc_male.vox",
Vec3::new(-8.0, -6.0, -2.75),
Vec3::new(-8.0, -5.0, -2.50),
),
(Orc, Female) => (
"figure/head/head_orc_female.vox",
Vec3::new(-8.0, -5.5, -2.75),
Vec3::new(-8.0, -8.0, -3.5),
),
(Undead, Male) => (
"figure/head/head_undead_male.vox",

View File

@ -101,7 +101,7 @@ impl Default for NetworkingSettings {
fn default() -> Self {
Self {
username: "Username".to_string(),
servers: vec!["server.veloren.net".to_string()],
servers: vec!["server.veloren.net:38889".to_string()],
default_server: 0,
}
}

View File

@ -2,7 +2,7 @@ use client::Client;
use common::clock::Clock;
use log::info;
use portpicker::pick_unused_port;
use server::{Event, Input, Server};
use server::{Event, Input, Server, ServerSettings};
use std::{
net::SocketAddr,
sync::mpsc::{channel, Receiver, Sender, TryRecvError},
@ -36,7 +36,8 @@ impl Singleplayer {
));
// Create server
let server = Server::bind(sock.clone()).expect("Failed to create server instance!");
let server = Server::bind(sock.clone(), ServerSettings::default())
.expect("Failed to create server instance!");
let server = match client {
Some(client) => server.with_thread_pool(client.thread_pool().clone()),