--- a/gameServer2/Cargo.toml Fri Jul 20 22:14:20 2018 +0300
+++ b/gameServer2/Cargo.toml Sat Jul 21 02:13:55 2018 +0300
@@ -14,3 +14,6 @@
proptest = "0.8"
base64 = "0.9"
bitflags = "1.0"
+serde = "1.0"
+serde_yaml = "0.7"
+serde_derive = "1.0"
--- a/gameServer2/src/main.rs Fri Jul 20 22:14:20 2018 +0300
+++ b/gameServer2/src/main.rs Sat Jul 21 02:13:55 2018 +0300
@@ -13,6 +13,9 @@
extern crate env_logger;
#[macro_use] extern crate proptest;
#[macro_use] extern crate bitflags;
+extern crate serde;
+extern crate serde_yaml;
+#[macro_use] extern crate serde_derive;
//use std::io::*;
//use rand::Rng;
--- a/gameServer2/src/server/client.rs Fri Jul 20 22:14:20 2018 +0300
+++ b/gameServer2/src/server/client.rs Sat Jul 21 02:13:55 2018 +0300
@@ -7,6 +7,9 @@
const IS_READY = 0b0000_0100;
const IS_IN_GAME = 0b0000_1000;
const IS_JOINED_MID_GAME = 0b0001_0000;
+
+ const NONE = 0b0000_0000;
+ const DEFAULT = Self::NONE.bits;
}
}
@@ -28,7 +31,7 @@
room_id: None,
nick: String::new(),
protocol_number: 0,
- flags: ClientFlags::empty(),
+ flags: ClientFlags::DEFAULT,
teams_in_game: 0,
team_indices: Vec::new(),
clan: None,
--- a/gameServer2/src/server/handlers/inroom.rs Fri Jul 20 22:14:20 2018 +0300
+++ b/gameServer2/src/server/handlers/inroom.rs Sat Jul 21 02:13:55 2018 +0300
@@ -12,7 +12,10 @@
actions::{Action, Action::*}
};
use utils::is_name_illegal;
-use std::mem::swap;
+use std::{
+ mem::swap, fs::{File, OpenOptions},
+ io::{Read, Write, Result, Error, ErrorKind}
+};
use base64::{encode, decode};
use super::common::rnd_reply;
@@ -91,6 +94,18 @@
}
}
+fn read_file(filename: &str) -> Result<String> {
+ let mut reader = File::open(filename)?;
+ let mut result = String::new();
+ reader.read_to_string(&mut result)?;
+ Ok(result)
+}
+
+fn write_file(filename: &str, content: &str) -> Result<()> {
+ let mut writer = OpenOptions::new().create(true).write(true).open(filename)?;
+ writer.write_all(content.as_bytes())
+}
+
pub fn handle(server: &mut HWServer, client_id: ClientId, room_id: RoomId, message: HWProtocolMessage) {
use protocol::messages::HWProtocolMessage::*;
match message {
@@ -281,6 +296,48 @@
server.rooms[room_id].save_config(name, location);
server.react(client_id, actions);
}
+ SaveRoom(filename) => {
+ let actions = if server.clients[client_id].is_admin() {
+ match server.rooms[room_id].get_saves() {
+ Ok(text) => match write_file(&filename, &text) {
+ Ok(_) => vec![server_chat("Room configs saved successfully.".to_string())
+ .send_self().action()],
+ Err(e) => {
+ warn!("Error while writing the config file \"{}\": {}", filename, e);
+ vec![Warn("Unable to save the room configs.".to_string())]
+ }
+ }
+ Err(e) => {
+ warn!("Error while serializing the room configs: {}", e);
+ vec![Warn("Unable to serialize the room configs.".to_string())]
+ }
+ }
+ } else {
+ Vec::new()
+ };
+ server.react(client_id, actions);
+ }
+ LoadRoom(filename) => {
+ let actions = if server.clients[client_id].is_admin() {
+ match read_file(&filename) {
+ Ok(text) => match server.rooms[room_id].set_saves(&text) {
+ Ok(_) => vec![server_chat("Room configs loaded successfully.".to_string())
+ .send_self().action()],
+ Err(e) => {
+ warn!("Error while deserializing the room configs: {}", e);
+ vec![Warn("Unable to deserialize the room configs.".to_string())]
+ }
+ }
+ Err(e) => {
+ warn!("Error while reading the config file \"{}\": {}", filename, e);
+ vec![Warn("Unable to load the room configs.".to_string())]
+ }
+ }
+ } else {
+ Vec::new()
+ };
+ server.react(client_id, actions);
+ }
Delete(name) => {
let actions = if !server.rooms[room_id].delete_config(&name) {
vec![Warn(format!("Save doesn't exist: {}", name))]
--- a/gameServer2/src/server/room.rs Fri Jul 20 22:14:20 2018 +0300
+++ b/gameServer2/src/server/room.rs Sat Jul 21 02:13:55 2018 +0300
@@ -5,23 +5,25 @@
coretypes::{ClientId, RoomId, TeamInfo, GameCfg, GameCfg::*, Voting},
client::{HWClient}
};
+use serde::{Serialize, Deserialize};
+use serde_yaml;
const MAX_HEDGEHOGS_IN_ROOM: u8 = 64;
const MAX_TEAMS_IN_ROOM: u8 = 8;
-#[derive(Clone)]
+#[derive(Clone, Serialize, Deserialize)]
struct Ammo {
name: String,
settings: Option<String>
}
-#[derive(Clone)]
+#[derive(Clone, Serialize, Deserialize)]
struct Scheme {
name: String,
settings: Option<Vec<String>>
}
-#[derive(Clone)]
+#[derive(Clone, Serialize, Deserialize)]
struct RoomConfig {
feature_size: u32,
map_type: String,
@@ -109,6 +111,7 @@
}
}
+#[derive(Serialize, Deserialize)]
pub struct RoomSave {
pub location: String,
config: RoomConfig
@@ -352,6 +355,17 @@
self.saves.remove(name).is_some()
}
+ pub fn get_saves(&self) -> Result<String, serde_yaml::Error> {
+ serde_yaml::to_string(&(&self.greeting, &self.saves))
+ }
+
+ pub fn set_saves(&mut self, text: &str) -> Result<(), serde_yaml::Error> {
+ serde_yaml::from_str::<(String, HashMap<String, RoomSave>)>(text).map(|(greeting, saves)| {
+ self.greeting = greeting;
+ self.saves = saves;
+ })
+ }
+
pub fn team_info(owner: &HWClient, team: &TeamInfo) -> Vec<String> {
let mut info = vec![
team.name.clone(),