From b0537d758ba79c6a7120ddab575fdcd880f4a243 Mon Sep 17 00:00:00 2001 From: Mashy Date: Thu, 17 Oct 2019 11:30:00 +1000 Subject: [PATCH 01/23] changelog --- CHANGELOG.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d8674203..01150a92 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,22 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). +## [1.5.6] - 2019-10-17 +We've updated the UI during the vbox / buy phase to give a better indication of valid actions. + +### Changed + - Borders for skill combo's represent the base colours. + - Heal (GG) has a green border, Siphon (BG) has an alternating blue / green border etc. + - Borders are shown for items in inventory and as equipped skills during both phases. + + - Improvements to making item combo's + - If you select an item in your inventory it will now highlight other items that are valid for combining. + - This includes items that can be bought and in your inventory. + + - Improved the indicator for where to click for equipping and buying items where its valid. + - Now slowly flashes between black and grey, previously changed the border once. + + ## [1.5.5] - 2019-10-15 ### Changed * Purge From dd1085a6d40d1c0694644c7c4dd0741dea23c1b3 Mon Sep 17 00:00:00 2001 From: ntr Date: Thu, 17 Oct 2019 13:54:30 +1100 Subject: [PATCH 02/23] redact game and instance states --- WORKLOG.md | 4 +++- server/src/events.rs | 12 +++++++++++- server/src/game.rs | 15 +++++++++++++-- server/src/instance.rs | 8 ++++++++ server/src/player.rs | 18 ++++++++++++++++++ server/src/rpc.rs | 35 +++++++++++++++++++++++++++-------- 6 files changed, 80 insertions(+), 12 deletions(-) diff --git a/WORKLOG.md b/WORKLOG.md index 4aa80673..1bc09a79 100644 --- a/WORKLOG.md +++ b/WORKLOG.md @@ -16,6 +16,9 @@ * can't reset password without knowing password =\ * Invert recharge + * serde serialize privatise + * chat + ## SOON * equip from shop (buy and equip without putting in your inventory) for bases @@ -23,7 +26,6 @@ * bot game grind * ACP * essential - * serde serialize privatise * msg pane / chatwheel * audio * treats diff --git a/server/src/events.rs b/server/src/events.rs index 9902991e..62ae470c 100644 --- a/server/src/events.rs +++ b/server/src/events.rs @@ -171,7 +171,17 @@ impl Events { for (client_id, client) in self.clients.iter() { if client.subs.contains(&id) { subs += 1; - match client.tx.send(msg.clone()) { + + let redacted = match client.account { + Some(a) => match msg { + RpcMessage::InstanceState(ref i) => RpcMessage::InstanceState(i.clone().redact(a)), + RpcMessage::GameState(ref i) => RpcMessage::GameState(i.clone().redact(a)), + _ => msg.clone(), + } + None => msg.clone(), + }; + + match client.tx.send(redacted) { Ok(_) => (), Err(e) => { warn!("unable to send msg to client err={:?}", e); diff --git a/server/src/game.rs b/server/src/game.rs index 1938b778..af4746ed 100644 --- a/server/src/game.rs +++ b/server/src/game.rs @@ -62,6 +62,17 @@ impl Game { }; } + pub fn redact(mut self, account: Uuid) -> Game { + self.players = self.players.into_iter() + .map(|p| p.redact(account)) + .collect(); + + self.stack + .retain(|s| s.source_player_id == account); + + self + } + pub fn set_time_control(&mut self, tc: TimeControl) -> &mut Game { self.time_control = tc; self.phase_end = Some(tc.lobby_timeout()); @@ -631,8 +642,8 @@ pub fn game_write(tx: &mut Transaction, game: &Game) -> Result<(), Error> { return Ok(()); } -pub fn game_state(tx: &mut Transaction, _account: &Account, id: Uuid) -> Result { - return game_get(tx, id) +pub fn game_state(tx: &mut Transaction, account: &Account, id: Uuid) -> Result { + Ok(game_get(tx, id)?.redact(account.id)) } pub fn game_get(tx: &mut Transaction, id: Uuid) -> Result { diff --git a/server/src/instance.rs b/server/src/instance.rs index 9731f879..b170d9ce 100644 --- a/server/src/instance.rs +++ b/server/src/instance.rs @@ -126,6 +126,14 @@ impl Instance { } } + pub fn redact(mut self, account: Uuid) -> Instance { + self.players = self.players.into_iter() + .map(|p| p.redact(account)) + .collect(); + + self + } + fn phase_timed_out(&self) -> bool { match self.phase_end { Some(t) => Utc::now().signed_duration_since(t).num_milliseconds() > 0, diff --git a/server/src/player.rs b/server/src/player.rs index c2c79110..d1394777 100644 --- a/server/src/player.rs +++ b/server/src/player.rs @@ -103,6 +103,24 @@ impl Player { } } + pub fn redact(mut self, account: Uuid) -> Player { + // all g + if account == self.id { + return self; + } + + // remove vbox + self.vbox = Vbox::new(); + + // hide skills + for construct in self.constructs.iter_mut() { + construct.skills = vec![]; + construct.specs = vec![]; + } + + self + } + pub fn set_bot(mut self, bot: bool) -> Player { self.bot = bot; self diff --git a/server/src/rpc.rs b/server/src/rpc.rs index 141f6ee8..ade45081 100644 --- a/server/src/rpc.rs +++ b/server/src/rpc.rs @@ -257,6 +257,25 @@ impl Connection { }, } } + + // this is where last minute processing happens + // use it to modify outgoing messages, update subs, serialize in some way... + fn send(&self, msg: RpcMessage) -> Result<(), Error> { + let msg = match self.account { + Some(ref a) => match msg { + RpcMessage::InstanceState(v) => RpcMessage::InstanceState(v.redact(a.id)), + RpcMessage::AccountInstances(v) => + RpcMessage::AccountInstances(v.into_iter().map(|i| i.redact(a.id)).collect()), + RpcMessage::GameState(v) => RpcMessage::GameState(v.redact(a.id)), + _ => msg, + }, + None => msg, + }; + + self.ws.send(msg).unwrap(); + + Ok(()) + } } // we unwrap everything in here cause really @@ -272,7 +291,7 @@ impl Handler for Connection { // if user logged in do some prep work if let Some(ref a) = self.account { - self.ws.send(RpcMessage::AccountState(a.clone())).unwrap(); + self.send(RpcMessage::AccountState(a.clone())).unwrap(); self.events.send(Event::Subscribe(self.id, a.id)).unwrap(); // check if they have an image that needs to be generated @@ -283,23 +302,23 @@ impl Handler for Connection { // send account constructs let account_constructs = account::constructs(&mut tx, a).unwrap(); - self.ws.send(RpcMessage::AccountConstructs(account_constructs)).unwrap(); + self.send(RpcMessage::AccountConstructs(account_constructs)).unwrap(); // get account instances // and send them to the client let account_instances = account::account_instances(&mut tx, a).unwrap(); - self.ws.send(RpcMessage::AccountInstances(account_instances)).unwrap(); + self.send(RpcMessage::AccountInstances(account_instances)).unwrap(); let shop = mtx::account_shop(&mut tx, &a).unwrap(); - self.ws.send(RpcMessage::AccountShop(shop)).unwrap(); + self.send(RpcMessage::AccountShop(shop)).unwrap(); let team = account::team(&mut tx, &a).unwrap(); - self.ws.send(RpcMessage::AccountTeam(team)).unwrap(); + self.send(RpcMessage::AccountTeam(team)).unwrap(); // tx should do nothing tx.commit().unwrap(); } else { - self.ws.send(RpcMessage::Demo(demo().unwrap())).unwrap(); + self.send(RpcMessage::Demo(demo().unwrap())).unwrap(); } Ok(()) @@ -327,11 +346,11 @@ impl Handler for Connection { _ => (), }; - self.ws.send(reply).unwrap(); + self.send(reply).unwrap(); }, Err(e) => { warn!("{:?}", e); - self.ws.send(RpcMessage::Error(e.to_string())).unwrap(); + self.send(RpcMessage::Error(e.to_string())).unwrap(); }, }; }, From 3104c841df31f499bb3677b6cdb60244a2b2d907 Mon Sep 17 00:00:00 2001 From: ntr Date: Thu, 17 Oct 2019 15:14:38 +1100 Subject: [PATCH 03/23] chat wip --- client/assets/styles/player.less | 6 +- client/src/actions.jsx | 1 + client/src/components/chat.jsx | 70 ++++++++++++++++++++ client/src/components/instance.ctrl.btns.jsx | 16 ++++- client/src/components/instance.ctrl.jsx | 13 +++- client/src/reducers.jsx | 1 + 6 files changed, 103 insertions(+), 4 deletions(-) create mode 100644 client/src/components/chat.jsx diff --git a/client/assets/styles/player.less b/client/assets/styles/player.less index 03465f16..4eb448d9 100644 --- a/client/assets/styles/player.less +++ b/client/assets/styles/player.less @@ -45,5 +45,9 @@ grid-area: msg; color: @white; } - } + +.chat { + justify-content: flex-end; +} + diff --git a/client/src/actions.jsx b/client/src/actions.jsx index 85b113de..f43d8a6c 100644 --- a/client/src/actions.jsx +++ b/client/src/actions.jsx @@ -11,6 +11,7 @@ export const setAnimText = value => ({ type: 'SET_ANIM_TEXT', value }); export const setDemo = value => ({ type: 'SET_DEMO', value }); +export const setChatShow = value => ({ type: 'SET_CHAT_SHOW', value }); export const setActiveItem = value => ({ type: 'SET_ACTIVE_VAR', value }); export const setActiveSkill = (constructId, skill) => ({ type: 'SET_ACTIVE_SKILL', value: constructId ? { constructId, skill } : null }); export const setCombiner = value => ({ type: 'SET_COMBINER', value: Array.from(value) }); diff --git a/client/src/components/chat.jsx b/client/src/components/chat.jsx new file mode 100644 index 00000000..05292096 --- /dev/null +++ b/client/src/components/chat.jsx @@ -0,0 +1,70 @@ +const preact = require('preact'); +const { connect } = require('preact-redux'); + +const actions = require('../actions'); + +const addState = connect( + function receiveState(state) { + const { + ws, + chatShow, + instance, + } = state; + + function sendChat(i) { + // return ws.sendChat(i); + } + + return { + instance, + chatShow, + + sendChat, + }; + }, + + function receiveDispatch(dispatch) { + function setChatShow(v) { + dispatch(actions.setChatShow(v)); + } + + return { + setChatShow, + }; + } +); + +function Chat(args) { + const { + instance, + chatShow, + + sendChat, + setChatShow, + } = args; + + const chat = [ + 'gl', + 'hf', + 'gg', + 'thx', + 'nice', + 'hmm', + 'ok', + '...', + ]; + + function onClick(i) { + sendChat(i); + setChatShow(false); + return true; + } + + return ( +
+ {chat.map((c, i) => )} +
+ ); +} + +module.exports = addState(Chat); diff --git a/client/src/components/instance.ctrl.btns.jsx b/client/src/components/instance.ctrl.btns.jsx index f1ca2be5..443bc03d 100644 --- a/client/src/components/instance.ctrl.btns.jsx +++ b/client/src/components/instance.ctrl.btns.jsx @@ -7,6 +7,7 @@ const addState = connect( function receiveState(state) { const { ws, + chatShow, instance, } = state; @@ -21,19 +22,32 @@ const addState = connect( return { instance, + chatShow, sendAbandon, sendReady, }; }, + + function receiveDispatch(dispatch) { + function setChatShow(v) { + dispatch(actions.setChatShow(v)); + } + + return { + setChatShow, + }; + } ); function InstanceCtrlBtns(args) { const { instance, + chatShow, sendAbandon, sendReady, + setChatShow, } = args; const finished = instance && instance.phase === 'Finished'; @@ -49,7 +63,7 @@ function InstanceCtrlBtns(args) { return (
- +
); diff --git a/client/src/components/instance.ctrl.jsx b/client/src/components/instance.ctrl.jsx index aa4e2670..5d8b30ba 100644 --- a/client/src/components/instance.ctrl.jsx +++ b/client/src/components/instance.ctrl.jsx @@ -1,20 +1,24 @@ const preact = require('preact'); const { connect } = require('preact-redux'); -const actions = require('../actions'); const PlayerBox = require('./player.box'); +const Chat = require('./chat'); const InstanceCtrlBtns = require('./instance.ctrl.btns'); const InstanceCtrlTopBtns = require('./instance.ctrl.top.btns'); +const actions = require('../actions'); + const addState = connect( function receiveState(state) { const { ws, instance, account, + chatShow, } = state; return { + chatShow, instance, account, }; @@ -25,6 +29,7 @@ function Controls(args) { const { account, instance, + chatShow, } = args; if (!instance) return false; @@ -58,13 +63,17 @@ function Controls(args) { ); + const bottom = chatShow + ? + : ; + return ( diff --git a/client/src/reducers.jsx b/client/src/reducers.jsx index 9268918d..c24519e3 100644 --- a/client/src/reducers.jsx +++ b/client/src/reducers.jsx @@ -24,6 +24,7 @@ module.exports = { demo: createReducer(null, 'SET_DEMO'), + chatShow: createReducer(null, 'SET_CHAT_SHOW'), combiner: createReducer([], 'SET_COMBINER'), constructs: createReducer([], 'SET_CONSTRUCTS'), constructEditId: createReducer(null, 'SET_CONSTRUCT_EDIT_ID'), From b896a7ee42ba81315e8e9d54de38ade097c9e880 Mon Sep 17 00:00:00 2001 From: Mashy Date: Thu, 17 Oct 2019 16:25:31 +1000 Subject: [PATCH 04/23] skill info on hover in effect box --- WORKLOG.md | 3 +-- client/assets/styles/game.less | 12 +++++++++ client/src/actions.jsx | 1 + client/src/components/game.construct.jsx | 33 +++++++++++++++++++++--- client/src/components/skill.btn.jsx | 15 +++++++++-- client/src/reducers.jsx | 1 + 6 files changed, 57 insertions(+), 8 deletions(-) diff --git a/WORKLOG.md b/WORKLOG.md index 4aa80673..fc056a15 100644 --- a/WORKLOG.md +++ b/WORKLOG.md @@ -3,10 +3,8 @@ *PRODUCTION* -* border colours for skills e.g. strike red border, slay half red half green * rename vbox to shop * combat phase info system -* drag and drop buy / equip / unequip items * mobile styles * mobile info page @@ -71,6 +69,7 @@ $$$ * Highlight (dota) colour * fx colours + styles +* ??? (PROBS NOT) drag and drop buy / equip / unequip items ??? * modules * troll life -> dmg * prince of peace diff --git a/client/assets/styles/game.less b/client/assets/styles/game.less index 4f22174a..415174ff 100644 --- a/client/assets/styles/game.less +++ b/client/assets/styles/game.less @@ -204,6 +204,7 @@ .resolving-skill { grid-area: target; + text-align: center; align-self: center; height: auto; svg { @@ -213,6 +214,17 @@ } } +.skill-description { + padding-left: 1em; + padding-right: 1em; + text-align: center; + svg { + display: inline; + height: 1em; + margin-right: 0.1em + } +} + /* some stupid bug in chrome makes it fill the entire screen */ @media screen and (-webkit-min-device-pixel-ratio:0) { #targeting { diff --git a/client/src/actions.jsx b/client/src/actions.jsx index 85b113de..01b1cd88 100644 --- a/client/src/actions.jsx +++ b/client/src/actions.jsx @@ -18,6 +18,7 @@ export const setConstructEditId = value => ({ type: 'SET_CONSTRUCT_EDIT_ID', val export const setConstructs = value => ({ type: 'SET_CONSTRUCTS', value }); export const setConstructRename = value => ({ type: 'SET_CONSTRUCT_RENAME', value }); export const setGame = value => ({ type: 'SET_GAME', value }); +export const setGameInfo = value => ({ type: 'SET_GAME_INFO', value }); export const setInfo = value => ({ type: 'SET_INFO', value }); export const setEmail = value => ({ type: 'SET_EMAIL', value }); export const setInvite = value => ({ type: 'SET_INVITE', value }); diff --git a/client/src/components/game.construct.jsx b/client/src/components/game.construct.jsx index 34349422..204e5bda 100644 --- a/client/src/components/game.construct.jsx +++ b/client/src/components/game.construct.jsx @@ -2,10 +2,12 @@ const { connect } = require('preact-redux'); const { Component } = require('preact'); const preact = require('preact'); const range = require('lodash/range'); +const reactStringReplace = require('react-string-replace'); const { STATS } = require('../utils'); const { ConstructAvatar, ConstructText } = require('./construct'); const shapes = require('./shapes'); +const { INFO } = require('./../constants'); const SkillBtn = require('./skill.btn'); @@ -19,6 +21,9 @@ const addState = connect( animFocus, animating, animText, + + gameInfo, + itemInfo, } = state; function selectSkillTarget(targetConstructId) { @@ -40,6 +45,9 @@ const addState = connect( animText, activeSkill, selectSkillTarget, + + gameInfo, + itemInfo, }; } ); @@ -77,6 +85,9 @@ class GameConstruct extends Component { selectSkillTarget, animFocus, animText, + + gameInfo, + itemInfo, } = this.props; const ko = construct.green_life.value === 0 ? 'ko' : ''; @@ -96,9 +107,23 @@ class GameConstruct extends Component { let crypSkills =
; if (player) crypSkills = (
{skills}
); - const effects = construct.effects.length - ? construct.effects.map(c =>
{c.effect} - {c.duration}T
) - : null; + + const effectBox = () => { + if (gameInfo && gameInfo.constructId === construct.id) { + const fullInfo = itemInfo.items.find(k => k.item === gameInfo.skill) || INFO[gameInfo.skill]; + const regEx = /(RedPower|BluePower|GreenPower|RedLife|BlueLife|GreenLife|SpeedStat)/; + const infoDescription = reactStringReplace(fullInfo.description, regEx, match => shapes[match]()); + return ( +
+

{gameInfo.skill}

+
{infoDescription}
+
); + } + const effects = construct.effects.length + ? construct.effects.map(c =>
{c.effect} - {c.duration}T
) + : null; + return (
{effects}
); + } return (
{crypSkills} -
{effects}
+ {effectBox()}
{stats}
diff --git a/client/src/components/skill.btn.jsx b/client/src/components/skill.btn.jsx index 32baa084..f8fdcc7e 100644 --- a/client/src/components/skill.btn.jsx +++ b/client/src/components/skill.btn.jsx @@ -23,7 +23,11 @@ const addState = connect( dispatch(actions.setActiveSkill(constructId, skill)); } - return { setActiveSkill }; + function setGameInfo(info) { + dispatch(actions.setGameInfo(info)); + } + + return { setActiveSkill, setGameInfo }; } ); @@ -35,13 +39,18 @@ function Skill(props) { i, activeSkill, setActiveSkill, + setGameInfo, } = props; if (!game) return false; const s = construct.skills[i]; const ko = construct.green_life.value === 0 ? 'ko' : ''; - + + function hoverInfo(e, info) { + e.stopPropagation(); + return setGameInfo(info); + } if (!s || !game) { return ( )} + {chatWheel.map((c, i) => )}
); } diff --git a/client/src/components/instance.ctrl.jsx b/client/src/components/instance.ctrl.jsx index 5d8b30ba..b025d239 100644 --- a/client/src/components/instance.ctrl.jsx +++ b/client/src/components/instance.ctrl.jsx @@ -13,6 +13,7 @@ const addState = connect( const { ws, instance, + instanceChat, account, chatShow, } = state; @@ -20,6 +21,7 @@ const addState = connect( return { chatShow, instance, + instanceChat, account, }; }, @@ -29,6 +31,7 @@ function Controls(args) { const { account, instance, + instanceChat, chatShow, } = args; @@ -65,14 +68,14 @@ function Controls(args) { const bottom = chatShow ? - : ; + : ; return (
); } return (
-
 
+
{chat || '\u00A0'}
{scoreText()}
{player.name}
diff --git a/client/src/events.jsx b/client/src/events.jsx index 07a8262b..0083e0bb 100644 --- a/client/src/events.jsx +++ b/client/src/events.jsx @@ -212,6 +212,14 @@ function registerEvents(store) { return store.dispatch(actions.setInstance(v)); } + function setInstanceChat(v) { + return store.dispatch(actions.setInstanceChat(v)); + } + + function setChatWheel(v) { + return store.dispatch(actions.setChatWheel(v)); + } + function setItemInfo(v) { return store.dispatch(actions.setItemInfo(v)); } @@ -318,12 +326,14 @@ function registerEvents(store) { setAccountInstances, setActiveItem, setActiveSkill, + setChatWheel, setDemo, setConstructList, setNewConstruct, setGame, setEmail, setInstance, + setInstanceChat, setItemInfo, setInvite, setPing, diff --git a/client/src/reducers.jsx b/client/src/reducers.jsx index c24519e3..24ced707 100644 --- a/client/src/reducers.jsx +++ b/client/src/reducers.jsx @@ -25,6 +25,8 @@ module.exports = { demo: createReducer(null, 'SET_DEMO'), chatShow: createReducer(null, 'SET_CHAT_SHOW'), + chatWheel: createReducer([], 'SET_CHAT_WHEEL'), + combiner: createReducer([], 'SET_COMBINER'), constructs: createReducer([], 'SET_CONSTRUCTS'), constructEditId: createReducer(null, 'SET_CONSTRUCT_EDIT_ID'), @@ -34,6 +36,7 @@ module.exports = { invite: createReducer(null, 'SET_INVITE'), info: createReducer(null, 'SET_INFO'), instance: createReducer(null, 'SET_INSTANCE'), + instanceChat: createReducer(null, 'SET_INSTANCE_CHAT'), instances: createReducer([], 'SET_INSTANCES'), itemEquip: createReducer(null, 'SET_ITEM_EQUIP'), itemInfo: createReducer({ combos: [], items: [] }, 'SET_ITEM_INFO'), diff --git a/client/src/socket.jsx b/client/src/socket.jsx index ec174322..818f8a53 100644 --- a/client/src/socket.jsx +++ b/client/src/socket.jsx @@ -67,6 +67,10 @@ function createSocket(events) { send(['InstanceState', { instance_id: instanceId }]); } + function sendInstanceChat(instanceId, index) { + send(['InstanceChat', { instance_id: instanceId, index }]); + } + function sendVboxAccept(instanceId, group, index) { send(['VboxAccept', { instance_id: instanceId, group, index }]); events.clearInstance(); @@ -253,8 +257,11 @@ function createSocket(events) { QueueJoined: () => events.notify('you have joined the pvp queue'), InviteRequested: () => events.notify('pvp queue request received'), Invite: code => events.setInvite(code), + InstanceChat: chat => events.setInstanceChat(chat), + ChatWheel: wheel => events.setChatWheel(wheel), Joining: () => events.notify('searching for instance...'), + Processing: () => true, Error: errHandler, }; @@ -358,6 +365,7 @@ function createSocket(events) { sendInstanceState, sendInstanceInvite, sendInstanceJoin, + sendInstanceChat, sendVboxAccept, sendVboxApply, diff --git a/server/src/account.rs b/server/src/account.rs index 11776a4b..56921e2c 100644 --- a/server/src/account.rs +++ b/server/src/account.rs @@ -65,6 +65,19 @@ pub fn select(db: &Db, id: Uuid) -> Result { Account::try_from(row) } +pub fn chat_wheel(_db: &Db, _id: Uuid) -> Result, Error> { + return Ok(vec![ + "gl".to_string(), + "hf".to_string(), + "gg".to_string(), + "thx".to_string(), + "nice".to_string(), + "hmm".to_string(), + "ok".to_string(), + "...".to_string(), + ]) +} + pub fn select_name(db: &Db, name: &String) -> Result { let query = " SELECT id, name, balance, subscribed, img diff --git a/server/src/events.rs b/server/src/events.rs index 7064313c..3b24200c 100644 --- a/server/src/events.rs +++ b/server/src/events.rs @@ -58,7 +58,9 @@ pub enum Event { Invite(Id), Join(Id, String), Joined(Id), - Chat(Id, Uuid, String) + + Chat(Id, Uuid, String), + ChatClear(Id, Uuid), } struct WsClient { @@ -66,6 +68,7 @@ struct WsClient { account: Option, tx: Sender, subs: HashSet, + chat: Option<(Uuid, String)>, pvp: bool, invite: Option, } @@ -121,7 +124,15 @@ impl Events { None => None, }; - let client = WsClient { id, tx, account: account_id, subs: HashSet::new(), pvp: false, invite: None }; + let client = WsClient { id, + tx, + account: account_id, + subs: HashSet::new(), + pvp: false, + invite: None, + chat: None, + }; + self.clients.insert(id, client); info!("clients={:?}", self.clients.len()); @@ -216,7 +227,7 @@ impl Events { } // create the req for the already queued opponent - if let Some(opp_req) = match self.clients.iter_mut().find(|(_c_id, c)| c.pvp) { + 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.account.unwrap(), tx: q.tx.clone() }) @@ -292,6 +303,52 @@ impl Events { return Ok(()); }, + Event::Chat(id, instance, msg) => { + // set the chat state of this connection + { + let c = self.clients.get_mut(&id) + .ok_or(format_err!("connection not found id={:?}", id))?; + + if c.chat.is_some() { + return Err(err_msg("you must wait")); + } + + c.chat = Some((instance, msg)); + } + + // now collect all listeners of this instance + + let chat_state: HashMap = self.clients.iter() + .filter(|(_id, c)| c.account.is_some()) + .filter(|(_id, c)| match c.chat { + Some(ref chat) => chat.0 == instance, + None => false, + }) + .map(|(_id, c)| (c.account.unwrap(), c.chat.clone().unwrap().1)) + .collect(); + + return self.event(Event::Push(instance, RpcMessage::InstanceChat(chat_state))); + }, + + Event::ChatClear(id, instance) => { + { + match self.clients.get_mut(&id) { + Some(c) => c.chat = None, + None => (), + }; + } + + let chat_state: HashMap = self.clients.iter() + .filter(|(_id, c)| c.account.is_some()) + .filter(|(_id, c)| match c.chat { + Some(ref chat) => chat.0 == instance, + None => false, + }) + .map(|(_id, c)| (c.account.unwrap(), c.chat.clone().unwrap().1)) + .collect(); + + return self.event(Event::Push(instance, RpcMessage::InstanceChat(chat_state))); + } } } } diff --git a/server/src/instance.rs b/server/src/instance.rs index b170d9ce..4f4ae29e 100644 --- a/server/src/instance.rs +++ b/server/src/instance.rs @@ -1,4 +1,5 @@ use std::fs::File; +use std::collections::{HashMap}; use uuid::Uuid; @@ -31,6 +32,8 @@ enum InstancePhase { Finished, } +pub type ChatState = HashMap; + #[derive(Debug,Clone,Serialize,Deserialize)] struct Round { game_id: Option, diff --git a/server/src/rpc.rs b/server/src/rpc.rs index 860b89ce..2dfb9589 100644 --- a/server/src/rpc.rs +++ b/server/src/rpc.rs @@ -1,5 +1,7 @@ use std::time::{Instant}; -use std::thread::spawn; +use std::thread::{spawn, sleep}; +use std::time; + use std::str; use uuid::Uuid; @@ -21,7 +23,7 @@ use account; use construct::{Construct}; use events::{Event}; use game::{Game, game_state, game_skill, game_skill_clear, game_ready}; -use instance::{Instance, instance_state, instance_practice, instance_ready, instance_abandon, demo}; +use instance::{Instance, ChatState, instance_state, instance_practice, instance_ready, instance_abandon, demo}; use item::{Item, ItemInfoCtr, item_info}; use mtx; use mail; @@ -50,6 +52,8 @@ pub enum RpcMessage { ItemInfo(ItemInfoCtr), InstanceState(Instance), + InstanceChat(ChatState), + ChatWheel(Vec), EmailState(Option), SubscriptionState(Option), @@ -66,6 +70,8 @@ pub enum RpcMessage { Invite(String), Joining(()), + Processing(()), + Error(String), } @@ -102,6 +108,7 @@ pub enum RpcRequest { InstanceAbandon { instance_id: Uuid }, InstanceReady { instance_id: Uuid }, InstanceState { instance_id: Uuid }, + InstanceChat { instance_id: Uuid, index: usize }, VboxAccept { instance_id: Uuid, group: usize, index: usize }, VboxDiscard { instance_id: Uuid }, @@ -164,21 +171,22 @@ impl Connection { return Err(err_msg("subscribe to unlock chat")) } - let chat = vec![ - "gl", - "hf", - "gg", - "thx", - "nice", - "hmm", - "ok", - "...", - ]; + let wheel = account::chat_wheel(&db, account.id)?; - self.events.send(Event::Chat(self.id, instance_id, chat[index]))?; + if let Some(c) = wheel.get(index) { + self.events.send(Event::Chat(self.id, instance_id, c.to_string()))?; + } else { + return Err(err_msg("invalid chat index")); + } - // evnts sends to subs - Ok(RpcMessage::Joining(())) + let events_tx = self.events.clone(); + let id = self.id; + spawn(move || { + sleep(time::Duration::from_secs(3)); + events_tx.send(Event::ChatClear(id, instance_id)).unwrap(); + }); + + Ok(RpcMessage::Processing(())) }, _ => { // all good, let's make a tx and process @@ -337,6 +345,9 @@ impl Handler for Connection { let team = account::team(&mut tx, &a).unwrap(); self.send(RpcMessage::AccountTeam(team)).unwrap(); + let wheel = account::chat_wheel(&db, a.id).unwrap(); + self.send(RpcMessage::ChatWheel(wheel)).unwrap(); + // tx should do nothing tx.commit().unwrap(); } else { From 4b216775cd6c68e028262b97d887b59425b1ae83 Mon Sep 17 00:00:00 2001 From: ntr Date: Fri, 18 Oct 2019 15:43:08 +1100 Subject: [PATCH 14/23] game btns --- client/src/components/game.ctrl.btns.jsx | 12 ++++++++++-- client/src/components/instance.ctrl.btns.jsx | 5 ++++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/client/src/components/game.ctrl.btns.jsx b/client/src/components/game.ctrl.btns.jsx index 30513961..bac13a4b 100644 --- a/client/src/components/game.ctrl.btns.jsx +++ b/client/src/components/game.ctrl.btns.jsx @@ -45,7 +45,14 @@ const addState = connect( dispatch(actions.setInstance(null)); } - return { quit }; + function setChatShow(v) { + dispatch(actions.setChatShow(v)); + } + + return { + setChatShow, + quit, + }; } ); @@ -57,6 +64,7 @@ function GameCtrlBtns(args) { getInstanceState, sendGameSkillClear, sendReady, + setChatShow, quit, } = args; @@ -73,7 +81,7 @@ function GameCtrlBtns(args) { return (
- + {finished ? quitBtn : readyBtn}
diff --git a/client/src/components/instance.ctrl.btns.jsx b/client/src/components/instance.ctrl.btns.jsx index 443bc03d..ecfded9c 100644 --- a/client/src/components/instance.ctrl.btns.jsx +++ b/client/src/components/instance.ctrl.btns.jsx @@ -9,6 +9,7 @@ const addState = connect( ws, chatShow, instance, + account, } = state; function sendReady() { @@ -23,6 +24,7 @@ const addState = connect( return { instance, chatShow, + account, sendAbandon, sendReady, @@ -44,6 +46,7 @@ function InstanceCtrlBtns(args) { const { instance, chatShow, + account, sendAbandon, sendReady, @@ -63,7 +66,7 @@ function InstanceCtrlBtns(args) { return (
- +
); From aa5b76551f71184faa40d421a300cbb1926206b7 Mon Sep 17 00:00:00 2001 From: ntr Date: Fri, 18 Oct 2019 15:51:45 +1100 Subject: [PATCH 15/23] fix game btns --- client/src/components/chat.jsx | 5 ++++- client/src/components/game.ctrl.btns.jsx | 6 ++++++ client/src/components/game.ctrl.jsx | 17 ++++++++++++++--- 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/client/src/components/chat.jsx b/client/src/components/chat.jsx index f5f0a826..323d55c6 100644 --- a/client/src/components/chat.jsx +++ b/client/src/components/chat.jsx @@ -10,6 +10,7 @@ const addState = connect( chatShow, chatWheel, instance, + game, } = state; function sendInstanceChat(instance, i) { @@ -18,6 +19,7 @@ const addState = connect( return { instance, + game, chatShow, chatWheel, @@ -39,6 +41,7 @@ const addState = connect( function Chat(args) { const { instance, + game, chatShow, chatWheel, @@ -47,7 +50,7 @@ function Chat(args) { } = args; function onClick(i) { - sendInstanceChat(instance.id, i); + sendInstanceChat(instance ? instance.id : game && game.id, i); setChatShow(false); return true; } diff --git a/client/src/components/game.ctrl.btns.jsx b/client/src/components/game.ctrl.btns.jsx index bac13a4b..671e9d62 100644 --- a/client/src/components/game.ctrl.btns.jsx +++ b/client/src/components/game.ctrl.btns.jsx @@ -8,6 +8,8 @@ const addState = connect( const { ws, game, + account, + chatShow, animating, } = state; @@ -30,6 +32,8 @@ const addState = connect( return { game, + account, + chatShow, sendAbandon, sendGameSkillClear, sendReady, @@ -60,6 +64,8 @@ function GameCtrlBtns(args) { const { game, animating, + account, + chatShow, getInstanceState, sendGameSkillClear, diff --git a/client/src/components/game.ctrl.jsx b/client/src/components/game.ctrl.jsx index f4f778e1..4d7de121 100644 --- a/client/src/components/game.ctrl.jsx +++ b/client/src/components/game.ctrl.jsx @@ -4,6 +4,7 @@ const { connect } = require('preact-redux'); const actions = require('../actions'); const PlayerBox = require('./player.box'); +const Chat = require('./chat'); const GameCtrlButtons = require('./game.ctrl.btns'); const GameCtrlTopButtons = require('./game.ctrl.btns.top'); @@ -13,12 +14,16 @@ const addState = connect( animating, game, account, + chatShow, + instanceChat, } = state; return { animating, game, account, + chatShow, + instanceChat, }; }, ); @@ -28,6 +33,8 @@ function Controls(args) { animating, account, game, + chatShow, + instanceChat, } = args; if (!game) return false; @@ -37,7 +44,7 @@ function Controls(args) { const zero = Date.parse(game.phase_start); const now = animating ? zero : Date.now(); const end = Date.parse(game.phase_end); - + const timerPct = game.phase_end ? ((now - zero) / (end - zero) * 100) : 100; @@ -61,13 +68,17 @@ function Controls(args) {
); + const bottom = chatShow + ? + : ; + return ( From 65bc2ac729fc58dbf1b1e4399bea1f6fac7752f0 Mon Sep 17 00:00:00 2001 From: ntr Date: Fri, 18 Oct 2019 15:53:46 +1100 Subject: [PATCH 16/23] v1.6.0 --- VERSION | 2 +- acp/package.json | 2 +- client/package.json | 2 +- ops/package.json | 2 +- server/Cargo.toml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/VERSION b/VERSION index 03082db7..ce6a70b9 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.5.6 \ No newline at end of file +1.6.0 \ No newline at end of file diff --git a/acp/package.json b/acp/package.json index a9ffeccf..f7dc99f5 100644 --- a/acp/package.json +++ b/acp/package.json @@ -1,6 +1,6 @@ { "name": "mnml-client", - "version": "1.5.6", + "version": "1.6.0", "description": "", "main": "index.js", "scripts": { diff --git a/client/package.json b/client/package.json index 9d22f205..6eb572dd 100644 --- a/client/package.json +++ b/client/package.json @@ -1,6 +1,6 @@ { "name": "mnml-client", - "version": "1.5.6", + "version": "1.6.0", "description": "", "main": "index.js", "scripts": { diff --git a/ops/package.json b/ops/package.json index 673c03d7..50a73702 100755 --- a/ops/package.json +++ b/ops/package.json @@ -1,6 +1,6 @@ { "name": "mnml-ops", - "version": "1.5.6", + "version": "1.6.0", "description": "", "main": "index.js", "scripts": { diff --git a/server/Cargo.toml b/server/Cargo.toml index 4285bf4c..3c9043f3 100644 --- a/server/Cargo.toml +++ b/server/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mnml" -version = "1.5.6" +version = "1.6.0" authors = ["ntr "] [dependencies] From c0be03f0e3e70f074c2cb00c1aaf66ab4bfbb74b Mon Sep 17 00:00:00 2001 From: ntr Date: Fri, 18 Oct 2019 16:08:05 +1100 Subject: [PATCH 17/23] don't internal error msg spam --- server/src/events.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/src/events.rs b/server/src/events.rs index 3b24200c..df53a60f 100644 --- a/server/src/events.rs +++ b/server/src/events.rs @@ -310,7 +310,7 @@ impl Events { .ok_or(format_err!("connection not found id={:?}", id))?; if c.chat.is_some() { - return Err(err_msg("you must wait")); + return Ok(()); } c.chat = Some((instance, msg)); From 05855af04a461f817cfea661fae56e31782cf254 Mon Sep 17 00:00:00 2001 From: Mashy Date: Fri, 18 Oct 2019 15:11:57 +1000 Subject: [PATCH 18/23] siphon & slay have green power scaling --- CHANGELOG.md | 2 +- client/src/utils.jsx | 8 ++++---- server/src/item.rs | 6 ++++-- server/src/skill.rs | 24 +++++++++++++----------- 4 files changed, 22 insertions(+), 18 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e6f4521c..2bd6ef7e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). ### Changed - Made available skill / effect information during the combat phase. - Highlighting a skill replace the effect area with the skill description including speed multiplier. - - Highlighting an effect with replace the targetting arrow / anim skill text with effect info. + - Highlighting an effect will replace the targetting arrow / anim skill text with effect info. - You can now preview combinations before you create them - After selecting the three items for a combo hover over the combine button for info diff --git a/client/src/utils.jsx b/client/src/utils.jsx index 140ff26a..ca66fd54 100644 --- a/client/src/utils.jsx +++ b/client/src/utils.jsx @@ -249,9 +249,9 @@ function effectInfo(i) { if (s === 'DecayTick+') return 45; if (s === 'DecayTick++') return 70; - if (s === 'SiphonTick') return 40; - if (s === 'SiphonTick+') return 50; - if (s === 'SiphonTick++') return 60; + if (s === 'SiphonTick') return 20; + if (s === 'SiphonTick+') return 25; + if (s === 'SiphonTick++') return 30; if (s === 'TriageTick') return 75; if (s === 'TriageTick+') return 110; @@ -289,7 +289,7 @@ function effectInfo(i) { case 'Absorb': return 'If construct takes damage, Absorption will be applied increasing RedPower and BluePower based on damage taken.'; case 'Absorption': return `Increasing construct RedPower and BluePower by ${i.meta[1]}`; case 'Triage': return `Construct will be healed for ${multiplier(i.tick.skill)}% of caster's GreenPower each turn.`; - case 'Siphon': return `Construct will take ${multiplier(i.tick.skill)}% of caster's BluePower as blue damage each turn, healing the caster.`; + case 'Siphon': return `Construct will take ${multiplier(i.tick.skill)}% of caster's BluePower + GreenPower as blue damage each turn, healing the caster.`; default: return 'Missing Effect Text'; } diff --git a/server/src/item.rs b/server/src/item.rs index 95734c38..763e17c2 100644 --- a/server/src/item.rs +++ b/server/src/item.rs @@ -850,7 +850,8 @@ impl Item { Item::Slay| Item::SlayPlus | Item::SlayPlusPlus => format!( - "Deals {:?}% RedPower as red damage and provides self healing based on damage dealt.", + "Deals {:?}% RedPower + {:?}% GreenPower as red damage and provides self healing based on damage dealt.", + self.into_skill().unwrap().multiplier(), self.into_skill().unwrap().multiplier()), Item::Sleep| @@ -884,7 +885,8 @@ impl Item { Item::Siphon| Item::SiphonPlus | Item::SiphonPlusPlus => format!( - "Deals {:?}% BluePower as blue damage each turn and heals caster based on damage dealt. Lasts {:?}T.", + "Deals {:?}% BluePower + {:?}% GreenPower as blue damage each turn and heals caster based on damage dealt. Lasts {:?}T.", + self.into_skill().unwrap().effect()[0].get_skill().unwrap().multiplier(), self.into_skill().unwrap().effect()[0].get_skill().unwrap().multiplier(), self.into_skill().unwrap().effect()[0].get_duration()), diff --git a/server/src/skill.rs b/server/src/skill.rs index 5af07155..6431d39d 100644 --- a/server/src/skill.rs +++ b/server/src/skill.rs @@ -757,13 +757,13 @@ impl Skill { Skill::HealPlus => 185, //GG Skill::HealPlusPlus => 270, //GG - Skill::SiphonTick=> 40, // GB - Skill::SiphonTickPlus => 50, - Skill::SiphonTickPlusPlus => 60, + Skill::SiphonTick=> 20, // GB + Skill::SiphonTickPlus => 25, + Skill::SiphonTickPlusPlus => 30, - Skill::Slay=> 70, // RG - Skill::SlayPlus => 115, - Skill::SlayPlusPlus => 180, + Skill::Slay=> 40, // RG + Skill::SlayPlus => 60, + Skill::SlayPlusPlus => 90, Skill::Strike=> 90, //RR Skill::StrikePlus => 140, @@ -1471,7 +1471,7 @@ fn restrict(source: &mut Construct, target: &mut Construct, mut results: Resolut } fn slay(source: &mut Construct, target: &mut Construct, mut results: Resolutions, skill: Skill) -> Resolutions { - let amount = source.red_power().pct(skill.multiplier()); + let amount = source.red_power().pct(skill.multiplier()) + source.green_power().pct(skill.multiplier()); let slay_events = target.deal_red_damage(skill, amount); for e in slay_events { @@ -1732,7 +1732,7 @@ fn siphon(source: &mut Construct, target: &mut Construct, mut results: Resolutio } fn siphon_tick(source: &mut Construct, target: &mut Construct, mut results: Resolutions, skill: Skill) -> Resolutions { - let amount = source.blue_power().pct(skill.multiplier()); + let amount = source.blue_power().pct(skill.multiplier()) + source.green_power().pct(skill.multiplier()); let siphon_events = target.deal_blue_damage(skill, amount); for e in siphon_events { @@ -2037,13 +2037,14 @@ mod tests { .named(&"camel".to_string()); x.blue_power.force(256); + x.green_power.force(220); x.green_life.force(1024); x.green_life.reduce(512); let mut results = resolve(Skill::Siphon, &mut x, &mut y, vec![]); assert!(y.affected(Effect::Siphon)); - assert!(x.green_life() == (512 + 256.pct(Skill::SiphonTick.multiplier()))); + assert!(x.green_life() == (512 + 256.pct(Skill::SiphonTick.multiplier()) + 220.pct(Skill::SiphonTick.multiplier()))); let Resolution { source: _, target: _, event, stages: _ } = results.remove(0); match event { @@ -2053,14 +2054,15 @@ mod tests { let Resolution { source: _, target: _, event, stages: _ } = results.remove(0); match event { - Event::Damage { amount, skill: _, mitigation: _, colour: _} => assert_eq!(amount, 256.pct(Skill::SiphonTick.multiplier())), + Event::Damage { amount, skill: _, mitigation: _, colour: _} => assert_eq!(amount, 256.pct(Skill::SiphonTick.multiplier()) + + 220.pct(Skill::SiphonTick.multiplier())), _ => panic!("not damage siphon"), }; let Resolution { source: _, target, event, stages: _ } = results.remove(0); match event { Event::Healing { amount, skill: _, overhealing: _ } => { - assert_eq!(amount, 256.pct(Skill::SiphonTick.multiplier())); + assert_eq!(amount, 256.pct(Skill::SiphonTick.multiplier()) + 220.pct(Skill::SiphonTick.multiplier())); assert_eq!(target.id, x.id); }, _ => panic!("not healing"), From 0dc272df9640db1d9d0b1e4cf7a02f0eeb3fcadb Mon Sep 17 00:00:00 2001 From: Mashy Date: Fri, 18 Oct 2019 15:16:59 +1000 Subject: [PATCH 19/23] changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2bd6ef7e..a9c00e91 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,10 @@ This project adheres to [Semantic Versioning](http://semver.org/). - You can now preview combinations before you create them - After selecting the three items for a combo hover over the combine button for info + - Damage formula for Slay and Siphon reworked + - Slay now deals red damage based RedPower and GreenPower. Previously only based on RedPower. + - Siphon now deals blue damage based BluePower and GreenPower. Previously only based on BluePower. + ## [1.5.6] - 2019-10-17 We've updated the UI during the vbox / buy phase to give a better indication of valid actions. From 0ee39111cbcd5c115e97239a0d54e6c39808d337 Mon Sep 17 00:00:00 2001 From: ntr Date: Fri, 18 Oct 2019 17:14:11 +1100 Subject: [PATCH 20/23] fix random broken styles --- CHANGELOG.md | 5 ++++- client/assets/styles/footer.less | 1 + client/assets/styles/game.less | 1 - client/assets/styles/styles.less | 4 ++-- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a9c00e91..06e1a152 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,10 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). -## [1.5.7] - 2019-10-18 +## [1.6.0] - 2019-10-18 +### Added +- Subscriber chat! + ### Changed - Made available skill / effect information during the combat phase. - Highlighting a skill replace the effect area with the skill description including speed multiplier. diff --git a/client/assets/styles/footer.less b/client/assets/styles/footer.less index cf9b6012..96791e70 100644 --- a/client/assets/styles/footer.less +++ b/client/assets/styles/footer.less @@ -3,6 +3,7 @@ footer { flex-flow: row wrap; grid-area: footer; margin: 0; + z-index: 10; button { margin: 0; diff --git a/client/assets/styles/game.less b/client/assets/styles/game.less index 909a088a..ef445028 100644 --- a/client/assets/styles/game.less +++ b/client/assets/styles/game.less @@ -123,7 +123,6 @@ button { width: 100%; height: 2em; - height: 25%; margin-right: 1em; } button.active { diff --git a/client/assets/styles/styles.less b/client/assets/styles/styles.less index 7150057e..1cb6f712 100644 --- a/client/assets/styles/styles.less +++ b/client/assets/styles/styles.less @@ -14,7 +14,7 @@ html body { -ms-user-select: none; overflow-x: hidden; - // overflow-y: hidden; + overflow-y: hidden; } #mnml { @@ -26,7 +26,7 @@ html body { /* stops inspector going skitz*/ overflow-x: hidden; - // overflow-y: hidden; + overflow-y: hidden; } // @media (min-width: 1921px) { From 8f99e07e811cf57481d97e6c78a1f692ab89781c Mon Sep 17 00:00:00 2001 From: Mashy Date: Fri, 18 Oct 2019 16:18:33 +1000 Subject: [PATCH 21/23] flash quit / back button --- client/assets/styles/controls.less | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/client/assets/styles/controls.less b/client/assets/styles/controls.less index ef8fbdeb..b2eb2337 100644 --- a/client/assets/styles/controls.less +++ b/client/assets/styles/controls.less @@ -132,10 +132,16 @@ aside { flex: 0; } - .ready, .quit { + .ready { flex: 1; font-size: 200%; } + + .quit { + flex: 1; + font-size: 200%; + animation: co 0.75s cubic-bezier(0, 0, 1, 1) 0s infinite alternate; + } } .abandon:not([disabled]) { From d1866a4fda76ffe4c8e88b7efee346c0ebdfd9bc Mon Sep 17 00:00:00 2001 From: ntr Date: Fri, 18 Oct 2019 17:21:01 +1100 Subject: [PATCH 22/23] only send chat clear after a msg --- server/src/events.rs | 8 ++++++++ server/src/rpc.rs | 7 ------- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/server/src/events.rs b/server/src/events.rs index df53a60f..294cfb03 100644 --- a/server/src/events.rs +++ b/server/src/events.rs @@ -1,4 +1,6 @@ use std::collections::{HashMap, HashSet}; +use std::thread::{spawn, sleep}; +use std::time; // Db Commons use uuid::Uuid; @@ -314,6 +316,12 @@ impl Events { } c.chat = Some((instance, msg)); + + let events_tx = self.tx.clone(); + spawn(move || { + sleep(time::Duration::from_secs(3)); + events_tx.send(Event::ChatClear(id, instance)).unwrap(); + }); } // now collect all listeners of this instance diff --git a/server/src/rpc.rs b/server/src/rpc.rs index 2dfb9589..3194c1d4 100644 --- a/server/src/rpc.rs +++ b/server/src/rpc.rs @@ -179,13 +179,6 @@ impl Connection { return Err(err_msg("invalid chat index")); } - let events_tx = self.events.clone(); - let id = self.id; - spawn(move || { - sleep(time::Duration::from_secs(3)); - events_tx.send(Event::ChatClear(id, instance_id)).unwrap(); - }); - Ok(RpcMessage::Processing(())) }, _ => { From 525ad5770767973dce4834615a2276be790558fa Mon Sep 17 00:00:00 2001 From: ntr Date: Fri, 18 Oct 2019 17:40:18 +1100 Subject: [PATCH 23/23] changelog --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 06e1a152..287876ae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,9 @@ This project adheres to [Semantic Versioning](http://semver.org/). - Slay now deals red damage based RedPower and GreenPower. Previously only based on RedPower. - Siphon now deals blue damage based BluePower and GreenPower. Previously only based on BluePower. +### Fixed +- Matchmaking bug where server matches you with yourself + ## [1.5.6] - 2019-10-17 We've updated the UI during the vbox / buy phase to give a better indication of valid actions.