source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f8ebf5827e4ac4fd5946560e6a99776ea73b596d80898f357007317a7141e47"
+[[package]]
+name = "array-macro"
+version = "1.0.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "06e97b4e522f9e55523001238ac59d13a8603af57f69980de5d8de4bbbe8ada6"
+
[[package]]
name = "arrayvec"
version = "0.5.2"
"cfg-if 1.0.0",
]
+[[package]]
+name = "enum-map"
+version = "0.6.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4187999839f4ae8be35cf185d1381aa8dc32d2f5951349cc37ae49ebc4781855"
+dependencies = [
+ "array-macro",
+ "enum-map-derive",
+ "serde",
+]
+
+[[package]]
+name = "enum-map-derive"
+version = "0.4.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e5c450cf304c9e18d45db562025a14fb1ca0f5c769b6f609309f81d4c31de455"
+dependencies = [
+ "proc-macro2 1.0.24",
+ "quote 1.0.8",
+ "syn 1.0.57",
+]
+
[[package]]
name = "env_logger"
version = "0.8.2"
"delegate 0.5.0",
"derive_more",
"either",
+ "enum-map",
"failure",
"fehler",
"flexi_logger",
delegate = "0.5"
derive_more = "0.99"
either = "1"
+enum-map = { version = "0.6", features = [ "serde" ] }
failure = "0.1.8" # for pwd
fehler = "1"
flexi_logger = { version = "0.16", features = [ "specfile" ] }
load: String,
log: Vec<SessionFormattedLogEntry>,
sse_url_prefix: String,
+ links: Vec<(LinkKind, Html)>,
}
#[derive(Debug,Serialize)]
nick : gpl.nick.clone(),
sse_url_prefix,
ptoken: form.ptoken.clone(),
+ links: ig.links.iter().map(|(k,v)| (k.clone(), v.clone())).collect(),
load : serde_json::to_string(&DataLoad {
players: load_players,
last_log_ts: timestamp_abbrev.unwrap_or_default(),
#[throws(AE)]
fn setup_table(_ma: &MainOpts, spec: &TableSpec) -> Vec<MGI> {
- let TableSpec { players, player_perms, acl } = spec;
+ let TableSpec { players, player_perms, acl, links } = spec;
let mut player_perms = player_perms.clone()
.unwrap_or(PLAYER_DEFAULT_PERMS.iter().cloned().collect());
player_perms.extend(PLAYER_ALWAYS_PERMS.iter());
)}
}
+//---------- set-link ----------
+
+mod set_link {
+
+ use super::*;
+
+ #[derive(Default,Debug)]
+ struct Args {
+ table_name: String,
+ kind: LinkKind,
+ url: Option<String>,
+ }
+
+ fn subargs(sa: &mut Args) -> ArgumentParser {
+ use argparse::*;
+ let mut ap = ArgumentParser::new();
+ ap.refer(&mut sa.table_name).required()
+ .add_argument("TABLE-NAME",Store,"table name");
+ ap.refer(&mut sa.kind).required()
+ .add_argument("LINK-KIND",Store,"link kind");
+ ap.refer(&mut sa.url)
+ .add_argument("URL",Store,"url (or empty for none)");
+ ap
+ }
+
+ fn call(_sc: &Subcommand, ma: MainOpts, args: Vec<String>) ->Result<(),AE> {
+ let args = parse_args::<Args,_>(args, &subargs, &ok_id, None);
+ let mut chan = access_game(&ma, &args.table_name)?;
+
+ let mut insns = vec![];
+
+ }
+
+ inventory::submit!{Subcommand(
+ "set-link",
+ "Set one of the info links visible from within the game",
+ call,
+ )}
+}
+
//---------- join-game ----------
mod join_game {
UpdatePlayer { player: PlayerId, details: MgmtPlayerDetails },
LeaveGame(PlayerId),
+ SetLinks(HashMap<LinkKind,String>),
+ RemoveLink { kind: LinkKind, url: String },
+ SetLink { kind: LinkKind, url: String },
+
ClearLog,
SetACL { acl: Acl<TablePermission> },
// RemovePlayer { player: PlayerId }, todo, does a special setacl
pub struct MgmtGameResponseGameInfo {
pub table_size: Pos,
pub players: SecondarySlotMap<PlayerId, MgmtPlayerInfo>,
+ pub links: Vec<(LinkKind, String>),
}
#[derive(Debug,Clone,Serialize,Deserialize)]
#[derive(Debug,Clone)]
pub struct InstanceRef (Arc<Mutex<InstanceContainer>>);
-type LinksTable = HashMap<LinkKind, Html>;
+pub type LinksTable = EnumMap<LinkKind, Option<Html>>;
pub struct Instance {
pub name: Arc<InstanceName>,
pub links: LinksTable,
}
-#[derive(Copy,Clone,Debug,Eq,PartialEq,Ord,PartialOrd,Hash)]
-#[derive(Serialize,Deserialize)]
-pub enum LinkKind {
- Voice,
- Info,
-}
-
pub struct PlayerRecord {
pub u: PlayerUpdates,
pub ipl: IPlayerState,
pub use boolinator::Boolinator as _;
pub use delegate::delegate;
pub use either::{Either, Left, Right};
+pub use enum_map::{Enum, EnumMap};
pub use fehler::{throw, throws};
pub use flexi_logger::{self, LogSpecification};
pub use fs2::FileExt;
// game specs
+use std::collections::hash_map::HashMap;
use std::collections::hash_set::HashSet;
use std::fmt::Debug;
use std::hash::Hash;
+use enum_map::Enum;
use fehler::throws;
use index_vec::{define_index_type, IndexVec};
use num_derive::{FromPrimitive, ToPrimitive};
#[serde(default)] pub players: Vec<TablePlayerSpec>,
pub player_perms: Option<HashSet<TablePermission>>,
#[serde(default)] pub acl: Acl<TablePermission>,
+ #[serde(default)] pub links: HashMap<LinkKind, String>,
}
#[derive(Debug,Serialize,Deserialize)]
Super,
}
+#[derive(Copy,Clone,Debug,Eq,PartialEq,Ord,PartialOrd,Hash)]
+#[derive(Enum,Serialize,Deserialize)]
+pub enum LinkKind {
+ Voice,
+ Info,
+}
+
//---------- player accesses, should perhaps be in commands.rs ----------
#[derive(Debug,Serialize,Deserialize)]
<div>
{{ m::nick() }} |
{{ m::status() }}<br/>
- </div><div>
+ </div>
+{%- for l in links -%}
+{%- if l.first -%}
+ <div>
+{%- else -%}
+|
+{%- endif -%}
+<a href="{{ l.1 }}">{{ l.0 }}</a>
+xxx core should be in some other .tera file so we can reuse it on update
+{%- if l.last -%}
+ </div>
+{%- endif -%}
+{%- endfor -%}
+ <div>
<a href="/p?{{ ptoken }}">switch to portrait view</a> |
{{ m::zoom() }}
</div><div>
<div class="upper">
{{ m::nick() }}
|
-{{ m::wresting() }}
+g{{ m::wresting() }}
|
{{ m::status() }}
|