diff --git a/VERSION b/VERSION index 44fdbc3a..f88cf52e 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.12.4 \ No newline at end of file +1.13.0 \ No newline at end of file diff --git a/WORKLOG.md b/WORKLOG.md index f504676b..73c8ea5b 100644 --- a/WORKLOG.md +++ b/WORKLOG.md @@ -5,6 +5,9 @@ _ntr_ * can't reset password without knowing password =\ * hard reload client on version change +decay reflected not applied +black out timer when game finished + * audio * animation effects * vbox combine / buy / equip etc diff --git a/acp/package.json b/acp/package.json index 8d5b3a7b..088c98c3 100644 --- a/acp/package.json +++ b/acp/package.json @@ -1,6 +1,6 @@ { "name": "mnml-client", - "version": "1.12.4", + "version": "1.13.0", "description": "", "main": "index.js", "scripts": { diff --git a/bin/deploy.sh b/bin/deploy.sh index dcf11a59..41ae49c3 100755 --- a/bin/deploy.sh +++ b/bin/deploy.sh @@ -27,6 +27,3 @@ ssh -q "$TARGET" ls -lah "$CLIENT_DIST_DIR" echo "restarting mnml service" ssh -q -t "$TARGET" sudo service mnml restart && sleep 1 && systemctl --no-pager status mnml - -echo "restarting nginx service" -ssh -q -t "$TARGET" sudo service nginx restart && sleep 1 && systemctl --no-pager status nginx diff --git a/client/package.json b/client/package.json index 93868dc0..2d2452b2 100644 --- a/client/package.json +++ b/client/package.json @@ -1,6 +1,6 @@ { "name": "mnml-client", - "version": "1.12.4", + "version": "1.13.0", "description": "", "main": "index.js", "scripts": { diff --git a/client/src/components/game.ctrl.jsx b/client/src/components/game.ctrl.jsx index 4d7de121..ccfb5904 100644 --- a/client/src/components/game.ctrl.jsx +++ b/client/src/components/game.ctrl.jsx @@ -45,7 +45,7 @@ function Controls(args) { const now = animating ? zero : Date.now(); const end = Date.parse(game.phase_end); - const timerPct = game.phase_end + const timerPct = game.phase_end || !game.phase == 'Finished' ? ((now - zero) / (end - zero) * 100) : 100; diff --git a/client/src/socket.jsx b/client/src/socket.jsx index 380625c0..b2240e4b 100644 --- a/client/src/socket.jsx +++ b/client/src/socket.jsx @@ -316,6 +316,7 @@ function createSocket(events) { case 'no constructs selected': return events.errorPrompt('select_constructs'); case 'node requirements not met': return events.errorPrompt('complete_nodes'); case 'construct at max skills (4)': return events.errorPrompt('max_skills'); + case 'instance missing': return window.location.reload(); default: return errorToast(error); diff --git a/core/Cargo.toml b/core/Cargo.toml index ebc9fe6b..2d5a2f48 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mnml_core" -version = "1.12.4" +version = "1.13.0" authors = ["ntr ", "mashy "] [dependencies] diff --git a/core/src/construct.rs b/core/src/construct.rs index 16572a8b..bd3c0afa 100644 --- a/core/src/construct.rs +++ b/core/src/construct.rs @@ -65,7 +65,7 @@ impl ConstructSkill { #[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)] pub enum EffectMeta { CastOnHit(Skill), // maybe needs source/target - CastTick { source: Uuid, target: Uuid, skill: Skill, speed: usize, amount: usize }, + CastTick { source: Uuid, target: Uuid, skill: Skill, speed: usize, amount: usize, id: Uuid }, AddedDamage(usize), Multiplier(usize), } @@ -100,12 +100,19 @@ impl ConstructEffect { pub fn get_skill(&self) -> Option { match self.meta { - Some(EffectMeta::CastTick { source: _, target: _, skill, speed: _, amount: _ }) => Some(skill), + Some(EffectMeta::CastTick { source: _, target: _, skill, speed: _, amount: _, id: _ }) => Some(skill), Some(EffectMeta::CastOnHit(s)) => Some(s), _ => None, } - } + + pub fn get_tick_id(&self) -> Option { + match self.meta { + Some(EffectMeta::CastTick { source: _, target: _, skill: _, speed: _, amount: _, id }) => Some(id), + _ => None, + } + } + } #[derive(Debug,Clone,Copy,PartialEq,Serialize,Deserialize)] @@ -561,7 +568,7 @@ impl Construct { fn tick_damage(&self, effect: Effect) -> usize { match self.effects.iter().find_map(|ce| match ce.effect == effect { true => match ce.meta { - Some(EffectMeta::CastTick { source: _, target: _, skill: _, speed: _, amount }) => Some(amount), + Some(EffectMeta::CastTick { source: _, target: _, skill: _, speed: _, amount, id: _ }) => Some(amount), _ => None, }, false => None, @@ -1033,8 +1040,6 @@ impl Construct { } pub fn damage_trigger_casts(&mut self, cast: &Cast, event: &Event) -> Vec { - if self.is_ko() { return vec![] } - match event { Event::Damage { construct: _, colour, amount: _, mitigation: _, display: _ } => { let mut casts = vec![]; @@ -1049,6 +1054,9 @@ impl Construct { }; } + // electrocute is a special case, so we only return after we check it when ko + if self.is_ko() { return casts } + if self.affected(Effect::Absorb) { let ConstructEffect { effect: _, duration: _, meta } = self.effects.iter().find(|e| e.effect == Effect::Absorb).unwrap(); diff --git a/core/src/effect.rs b/core/src/effect.rs index 14391d5b..549bb4aa 100644 --- a/core/src/effect.rs +++ b/core/src/effect.rs @@ -81,7 +81,7 @@ impl Effect { Skill::CounterAttackPlus, Skill::CounterAttackPlusPlus, ].contains(&skill), - + // these provide immunity for the ticks // the base skills will still resolve // but they have early return checks @@ -125,6 +125,12 @@ impl Effect { return false; } + // electrocute always goes off baybee + // even if you are stunned particularly + if [Skill::Electrocute, Skill::ElectrocutePlus, Skill::ElectrocutePlusPlus].contains(&skill) { + return false; + } + match self { Effect::Stun => true, Effect::Banish => true, diff --git a/core/src/game.rs b/core/src/game.rs index 5364013b..6a30e96f 100644 --- a/core/src/game.rs +++ b/core/src/game.rs @@ -428,8 +428,12 @@ impl Game { .cloned() .filter_map(|e| e.meta) .filter_map(move |m| match m { - EffectMeta::CastTick { source, target, skill, speed, amount: _ } => - Some(Cast::new(source, c.account, target, skill).set_speed(speed)), + EffectMeta::CastTick { source, target, skill, speed, amount: _, id } => + Some( + Cast::new(source, c.account, target, skill) + .set_speed(speed) + .set_id(id) + ), _ => None, }) ) @@ -506,6 +510,20 @@ impl Game { fn resolve(&mut self, cast: Cast) -> &mut Game { if self.finished() { return self } + // match tick skills with the effect on the target + // if no match is found the effect must have been removed during this turn + // and the skill should no longer resolve + if cast.skill.is_tick() { + let effect_match = self.construct(cast.target).effects.iter() + .filter_map(|ce| ce.get_tick_id()) + .find(|id| cast.id == *id) + .is_some(); + + if !effect_match { + return self; + } + } + // If the skill is disabled for source nothing else will happen if let Some(effects) = self.construct(cast.source).disabled(cast.skill) { self.add_resolution(&cast, &Event::Disable { construct: cast.source, effects }); @@ -1054,6 +1072,7 @@ mod tests { .learn(Skill::Block) .learn(Skill::Counter) .learn(Skill::Siphon) + .learn(Skill::Purify) .learn(Skill::Amplify) .learn(Skill::Stun) .learn(Skill::Ruin) @@ -1069,6 +1088,7 @@ mod tests { .learn(Skill::Block) .learn(Skill::Counter) .learn(Skill::Siphon) + .learn(Skill::Purify) .learn(Skill::Amplify) .learn(Skill::Stun) .learn(Skill::Block); @@ -1874,85 +1894,6 @@ mod tests { return; } - // #[test] - // fn tick_removal_test() { - // let mut game = create_test_game(); - - // let x_player = game.players[0].clone(); - // let y_player = game.players[1].clone(); - - // let x_construct = x_player.constructs[0].clone(); - // let y_construct = y_player.constructs[0].clone(); - - // // make the purify construct super fast so it beats out decay - // game.construct_by_id(y_construct.id).unwrap().speed.force(10000000); - - // game.construct_by_id(x_construct.id).unwrap().learn_mut(Skill::Decay); - // while game.construct_by_id(x_construct.id).unwrap().skill_on_cd(Skill::Decay).is_some() { - // game.construct_by_id(x_construct.id).unwrap().reduce_cooldowns(); - // } - - // game.construct_by_id(x_construct.id).unwrap().learn_mut(Skill::Siphon); - // while game.construct_by_id(x_construct.id).unwrap().skill_on_cd(Skill::Siphon).is_some() { - // game.construct_by_id(x_construct.id).unwrap().reduce_cooldowns(); - // } - - // game.construct_by_id(y_construct.id).unwrap().learn_mut(Skill::Purify); - // while game.construct_by_id(y_construct.id).unwrap().skill_on_cd(Skill::Purify).is_some() { - // game.construct_by_id(y_construct.id).unwrap().reduce_cooldowns(); - // } - - // // apply buff - // game.add_skill(x_player.id, x_construct.id, y_construct.id, Skill::Decay).unwrap(); - // game.player_ready(x_player.id).unwrap(); - // game.player_ready(y_player.id).unwrap(); - // game = game.resolve_phase_start(); - // assert!(game.construct_by_id(y_construct.id).unwrap().affected(Effect::Decay)); - - // let Resolution { source: _, target: _, Resolution, stages: _ } = game.Resolutions.last().unwrap().pop().unwrap(); - // match Resolution { - // Resolution::Damage { amount: _, skill, mitigation: _, colour: _ } => assert_eq!(skill, Skill::DecayTick), - // _ => panic!("not decay"), - // }; - - // game.Resolutions.clear(); - - // // remove - // game.add_skill(y_player.id, y_construct.id, y_construct.id, Skill::Purify).unwrap(); - // game.player_ready(x_player.id).unwrap(); - // game.player_ready(y_player.id).unwrap(); - // game = game.resolve_phase_start(); - - // while let Some(Resolution { source: _, target: _, Resolution, stages: _ }) = game.Resolutions.last().unwrap().pop() { - // match Resolution { - // Resolution::Damage { amount: _, skill: _, mitigation: _, colour: _ } => - // panic!("{:?} damage Resolution", Resolution), - // _ => (), - // } - // }; - - // game.add_skill(y_player.id, x_construct.id, y_construct.id, Skill::Siphon).unwrap(); - // game.player_ready(x_player.id).unwrap(); - // game.player_ready(y_player.id).unwrap(); - // game = game.resolve_phase_start(); - - // game.Resolutions.clear(); - - // game.add_skill(y_player.id, y_construct.id, y_construct.id, Skill::Purify).unwrap(); - // game.player_ready(x_player.id).unwrap(); - // game.player_ready(y_player.id).unwrap(); - // game = game.resolve_phase_start(); - - // while let Some(Resolution { source: _, target: _, Resolution, stages: _ }) = game.Resolutions.last().unwrap().pop() { - // match Resolution { - // Resolution::Damage { amount: _, skill: _, mitigation: _, colour: _ } => - // panic!("{:#?} {:#?} damage Resolution", game.Resolutions, Resolution), - // _ => (), - // } - // }; - - // } - #[test] fn upkeep_test() { let mut game = create_2v2_test_game(); @@ -2269,8 +2210,41 @@ mod tests { assert!(effect_events == 2); assert!(electrocute_dmg_events == 1); // second electrocute application deals no damage + } + #[test] + fn electrocute_ko_test() { + let mut game = create_2v2_test_game(); + let player_id = game.players[0].id; + let source = game.players[0].constructs[0].id; + let target = game.players[1].constructs[0].id; + game.players[1].constructs[0].blue_life.force(0); + game.players[1].constructs[0].green_life.force(1); + + game.resolve(Cast::new(source, player_id, target, Skill::Electrify)); + game.resolve(Cast::new(source, player_id, target, Skill::Blast)); + + let last = game.resolutions.len() - 1; + let resolutions = &game.resolutions[last]; + + // println!("{:#?}", resolutions); + + assert!(resolutions.iter().any(|r| match r.event { + Event::Damage { construct, colour, amount, mitigation: _, display: _ } => + r.skill == Skill::Electrocute && construct == source && amount > 0 && colour == Colour::Blue, + _ => false, + })); + + let effect_events = resolutions.iter().filter(|r| match r.event { + Event::Effect { construct, effect, duration: _, display: _ } => + construct == source && effect == Effect::Electrocute, + _ => false, + }).count(); + + // println!("{:?}", effect_events); + + assert!(effect_events == 1); } #[test] @@ -2524,4 +2498,38 @@ mod tests { assert_eq!(siphon_tick_dmg, siphon_dmg); assert_eq!(siphon_tick_speed, siphon_speed); } + + #[test] + fn tick_removal_test() { + let mut game = create_test_game(); + let player_id = game.players[0].id; + let opponent_id = game.players[1].id; + let source = game.players[0].constructs[0].id; + let target = game.players[1].constructs[0].id; + + game.add_skill(player_id, source, target, Skill::Siphon).unwrap(); + + game.player_ready(player_id).unwrap(); + game.player_ready(opponent_id).unwrap(); + + game = game.resolve_phase_start(); + + game.add_skill(player_id, source, target, Skill::Purify).unwrap(); + + game.player_ready(player_id).unwrap(); + game.player_ready(opponent_id).unwrap(); + + game = game.resolve_phase_start(); + + // println!("{:#?}", game.resolutions); + + let last = game.resolutions.len() - 1; + let resolutions = &game.resolutions[last]; + + // There should be no damage events on the target + assert!(resolutions.iter().any(|r| match r.event { + Event::Damage { construct: _, colour: _, amount: _, mitigation: _, display: _ } => true, + _ => false, + }) == false); + } } diff --git a/core/src/skill.rs b/core/src/skill.rs index 765b6930..0c7f2338 100644 --- a/core/src/skill.rs +++ b/core/src/skill.rs @@ -41,6 +41,15 @@ impl Cast { } } + // used for ticks to match + // a cast with an effect + pub fn set_id(self, id: Uuid) -> Cast { + Cast { + id, + ..self + } + } + pub fn resolve(self, game: &mut Game) { match self.skill { Skill::Attack => attack(self, game, Attack::Base), @@ -729,6 +738,13 @@ impl Skill { pub fn ko_castable(&self) -> bool { match self { + + // electrocute always goes off + Skill::Electrocute| + Skill::ElectrocutePlus | + Skill::ElectrocutePlusPlus | + + // ticks happen after death Skill::ElectrocuteTick | Skill::DecayTick | Skill::SiphonTick | @@ -1134,7 +1150,7 @@ fn siphon(cast: Cast, game: &mut Game, values: Siphon) { Action::Effect { construct: cast.target, effect: ConstructEffect { effect: Effect::Siphon, duration: values.duration(), meta: - Some(EffectMeta::CastTick { source: cast.source, target: cast.target, skill: Skill::SiphonTick, speed: cast.speed, amount }) }, + Some(EffectMeta::CastTick { id: Uuid::new_v4(), source: cast.source, target: cast.target, skill: Skill::SiphonTick, speed: cast.speed, amount }) }, } ); @@ -1729,7 +1745,7 @@ fn decay(cast: Cast, game: &mut Game, values: Decay) { Action::Effect { construct: cast.target, effect: ConstructEffect { effect: Effect::Decay, duration: values.decay_duration(), meta: - Some(EffectMeta::CastTick { source: cast.source, target: cast.target, skill: Skill::DecayTick, speed: cast.speed, amount }) }, + Some(EffectMeta::CastTick { id: Uuid::new_v4(), source: cast.source, target: cast.target, skill: Skill::DecayTick, speed: cast.speed, amount }) }, } ); @@ -1837,10 +1853,10 @@ fn electrocute(cast: Cast, game: &mut Game, values: Electrocute) { Action::Effect { construct: cast.target, effect: ConstructEffect { effect: Effect::Electrocute, duration: values.duration(), meta: - Some(EffectMeta::CastTick { source: cast.source, target: cast.target, skill: Skill::ElectrocuteTick, speed: cast.speed, amount }) }, + Some(EffectMeta::CastTick { id: Uuid::new_v4(), source: cast.source, target: cast.target, skill: Skill::ElectrocuteTick, speed: cast.speed, amount }) }, }, ); - + if !game.affected(cast.target, Effect::Electrocuted) { game.action(cast, Action::Damage { @@ -2362,7 +2378,7 @@ fn triage(cast: Cast, game: &mut Game, values: Triage) { Action::Effect { construct: cast.target, effect: ConstructEffect { effect: Effect::Triage, duration: values.duration(), meta: - Some(EffectMeta::CastTick { source: cast.source, target: cast.target, skill: Skill::TriageTick, speed: cast.speed, amount }) }, + Some(EffectMeta::CastTick { id: Uuid::new_v4(), source: cast.source, target: cast.target, skill: Skill::TriageTick, speed: cast.speed, amount }) }, } ); diff --git a/ops/package.json b/ops/package.json index 65521aeb..95ddbb39 100644 --- a/ops/package.json +++ b/ops/package.json @@ -1,6 +1,6 @@ { "name": "mnml-ops", - "version": "1.12.4", + "version": "1.13.0", "description": "", "main": "index.js", "scripts": { diff --git a/server/Cargo.toml b/server/Cargo.toml index 531b66a8..9107e872 100644 --- a/server/Cargo.toml +++ b/server/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mnml" -version = "1.12.4" +version = "1.13.0" authors = ["ntr "] [dependencies] diff --git a/server/src/events.rs b/server/src/events.rs index 8208c821..f7d5e0b2 100644 --- a/server/src/events.rs +++ b/server/src/events.rs @@ -17,7 +17,7 @@ use rpc::RpcMessage; use warden::{GameEvent}; pub type EventsTx = Sender; -type Id = Uuid; +type Id = usize; // this is pretty heavyweight // but it makes the ergonomics easy @@ -60,8 +60,13 @@ pub enum Event { ChatClear(Id, Uuid), } +// id and account are seperate +// multiple tabs etc can cause the same account to be connected twice +// so even though each client has the same subs etc +// they are treated independently struct WsClient { id: Id, + account: Uuid, tx: Sender, subs: HashSet, chat: Option<(Uuid, String)>, @@ -103,7 +108,9 @@ impl Events { Event::Connect(id, account, tx) => { info!("connect id={:?} account={:?}", id, account); - let client = WsClient { id, + let client = WsClient { + id, + account: account.id, tx, subs: HashSet::new(), pvp: false, @@ -163,8 +170,8 @@ impl Events { subs += 1; let redacted = match msg { - RpcMessage::InstanceState(ref i) => RpcMessage::InstanceState(i.clone().redact(client.id)), - RpcMessage::GameState(ref i) => RpcMessage::GameState(i.clone().redact(client.id)), + RpcMessage::InstanceState(ref i) => RpcMessage::InstanceState(i.clone().redact(client.account)), + RpcMessage::GameState(ref i) => RpcMessage::GameState(i.clone().redact(client.account)), _ => msg.clone(), }; @@ -203,7 +210,7 @@ impl Events { if let Some(opp_req) = match self.clients.iter_mut().find(|(c_id, c)| c.pvp && **c_id != id) { Some((q_id, q)) => { q.pvp = false; - Some(PvpRequest { id: *q_id, account: q.id, tx: q.tx.clone() }) + Some(PvpRequest { id: *q_id, account: q.account, tx: q.tx.clone() }) }, None => None, } { @@ -211,7 +218,7 @@ impl Events { let c = self.clients.get_mut(&id) .ok_or(format_err!("connection not found id={:?}", id))?; - let player_req = PvpRequest { id: c.id, account: c.id, tx: c.tx.clone() }; + let player_req = PvpRequest { id: c.id, account: c.account, tx: c.tx.clone() }; self.warden.send(GameEvent::Match((opp_req, player_req)))?; return Ok(()) @@ -221,7 +228,7 @@ impl Events { let requester = self.clients.get_mut(&id).unwrap(); requester.pvp = true; requester.tx.send(RpcMessage::QueueJoined(()))?; - info!("joined game queue id={:?} account={:?}", requester.id, requester.id); + info!("joined game queue id={:?} account={:?}", requester.id, requester.account); return Ok(()); }, @@ -231,7 +238,7 @@ impl Events { .ok_or(format_err!("connection not found id={:?}", id))?; let code = names::name().split_whitespace().collect::>().join("-"); - info!("pvp invite request id={:?} account={:?} code={:?}", c.id, c.id, code); + info!("pvp invite request id={:?} account={:?} code={:?}", c.id, c.account, code); c.invite = Some(code.clone()); c.tx.send(RpcMessage::Invite(code))?; return Ok(()); @@ -250,10 +257,10 @@ impl Events { Some(ref c) => *c == code, None => false, }) - .map(|(_id, c)| PvpRequest { id: c.id, account: c.id, tx: c.tx.clone() }) + .map(|(_id, c)| PvpRequest { id: c.id, account: c.account, tx: c.tx.clone() }) .ok_or(format_err!("invite expired code={:?}", code))?; - let join = PvpRequest { id: c.id, account: c.id, tx: c.tx.clone() }; + let join = PvpRequest { id: c.id, account: c.account, tx: c.tx.clone() }; self.warden.send(GameEvent::Match((join, inv)))?; return Ok(()); @@ -276,7 +283,7 @@ impl Events { c.pvp = false; c.tx.send(RpcMessage::QueueLeft(()))?; - info!("left game queue id={:?} account={:?}", c.id, c.id); + info!("left game queue id={:?} account={:?}", c.id, c.account); return Ok(()); }, @@ -307,7 +314,7 @@ impl Events { Some(ref chat) => chat.0 == instance, None => false, }) - .map(|(_id, c)| (c.id, c.chat.clone().unwrap().1)) + .map(|(_id, c)| (c.account, c.chat.clone().unwrap().1)) .collect(); return self.event(Event::Push(instance, RpcMessage::InstanceChat(chat_state))); @@ -326,7 +333,7 @@ impl Events { Some(ref chat) => chat.0 == instance, None => false, }) - .map(|(_id, c)| (c.id, c.chat.clone().unwrap().1)) + .map(|(_id, c)| (c.account, c.chat.clone().unwrap().1)) .collect(); return self.event(Event::Push(instance, RpcMessage::InstanceChat(chat_state))); diff --git a/server/src/lib.rs b/server/src/lib.rs index b8e9060c..0d955a53 100644 --- a/server/src/lib.rs +++ b/server/src/lib.rs @@ -109,6 +109,7 @@ pub fn start() { #[cfg(unix)] setup_logger().unwrap(); dotenv::from_path(Path::new("/etc/mnml/gs.conf")).ok(); + info!("starting server"); let pool = pg::create_pool(); let http_pool = pool.clone(); diff --git a/server/src/mail.rs b/server/src/mail.rs index 0322d31c..7e947582 100644 --- a/server/src/mail.rs +++ b/server/src/mail.rs @@ -248,8 +248,8 @@ pub fn set(tx: &mut Transaction, account: Uuid, email: &String) -> Result<(Uuid, let existing = tx.query(select_query, &[&id])?; let result = match existing.iter().next() { - Some(_) => tx.query(insert_query, &[&id, &account, &email, &confirm_token, &recover_token])?, - None => tx.query(update_query, &[&email, &confirm_token, &recover_token, &account])?, + Some(_) => tx.query(update_query, &[&email, &confirm_token, &recover_token, &account])?, + None => tx.query(insert_query, &[&id, &account, &email, &confirm_token, &recover_token])?, }; match result.iter().next() { diff --git a/server/src/rpc.rs b/server/src/rpc.rs index 8cc76d7b..dead4344 100644 --- a/server/src/rpc.rs +++ b/server/src/rpc.rs @@ -17,6 +17,8 @@ use crossbeam_channel::{unbounded, Sender as CbSender}; use ws::{Builder, CloseCode, Message, Handler, Request, Response, Settings, Sender as WsSender}; use ws::deflate::DeflateHandler; +use rand::prelude::*; + use account::{Account}; use account; use events::{Event}; @@ -132,11 +134,10 @@ pub trait User { } struct Connection { - pub id: Uuid, + pub id: usize, pub ws: CbSender, pool: PgPool, stripe: StripeClient, - // account: Option, user: Box, events: CbSender, } @@ -199,8 +200,7 @@ impl Handler for Connection { let db = self.pool.get().unwrap(); match account::from_token(&db, &cookie.value().to_string()) { Ok(a) => { - self.id = a.id; - self.user = Box::new(Authenticated::new(a, self.ws.clone(), self.events.clone(), self.pool.clone())); + self.user = Box::new(Authenticated::new(self.id, a, self.ws.clone(), self.events.clone(), self.pool.clone())); }, Err(_) => return unauth(), } @@ -243,12 +243,12 @@ pub fn start(pool: PgPool, events_tx: CbSender, stripe: StripeClient) { } }); + let mut rng = thread_rng(); let anon_account = Account::anonymous(); - let id = anon_account.id; DeflateHandler::new( Connection { - id, + id: rng.gen::(), ws: tx.clone(), pool: pool.clone(), stripe: stripe.clone(), diff --git a/server/src/user_authenticated.rs b/server/src/user_authenticated.rs index eb617178..63479119 100644 --- a/server/src/user_authenticated.rs +++ b/server/src/user_authenticated.rs @@ -1,7 +1,6 @@ use mnml_core::mob::anim_test_game; use mnml_core::item::item_info; use std::time::Instant; -use uuid::Uuid; use failure::Error; use failure::err_msg; @@ -44,7 +43,7 @@ use rpc::{RpcMessage, RpcRequest, User}; #[derive(Debug,Clone)] pub struct Authenticated { pub account: Account, - pub id: Uuid, + pub id: usize, events: CbSender, ws: CbSender, @@ -52,9 +51,9 @@ pub struct Authenticated { } impl Authenticated { - pub fn new(account: Account, ws: CbSender, events: CbSender, pool: PgPool) -> Authenticated { + pub fn new(id: usize, account: Account, ws: CbSender, events: CbSender, pool: PgPool) -> Authenticated { Authenticated { - id: account.id, + id, account, ws, events, @@ -81,10 +80,10 @@ impl User for Authenticated { // last minute processing let msg = match msg { - RpcMessage::InstanceState(v) => RpcMessage::InstanceState(v.redact(self.id)), + RpcMessage::InstanceState(v) => RpcMessage::InstanceState(v.redact(self.account.id)), RpcMessage::AccountInstances(v) => - RpcMessage::AccountInstances(v.into_iter().map(|i| i.redact(self.id)).collect()), - RpcMessage::GameState(v) => RpcMessage::GameState(v.redact(self.id)), + RpcMessage::AccountInstances(v.into_iter().map(|i| i.redact(self.account.id)).collect()), + RpcMessage::GameState(v) => RpcMessage::GameState(v.redact(self.account.id)), _ => msg, }; diff --git a/studios/package.json b/studios/package.json index d1e3c8ac..cff9af6b 100644 --- a/studios/package.json +++ b/studios/package.json @@ -1,6 +1,6 @@ { "name": "mnml-studios", - "version": "1.12.4", + "version": "1.13.0", "description": "", "main": "index.js", "scripts": {