Merge branch 'release/1.4.5'
This commit is contained in:
commit
1a41f95ed9
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "mnml-client",
|
||||
"version": "1.4.4",
|
||||
"version": "1.4.5",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
|
||||
@ -53,7 +53,7 @@ aside {
|
||||
border-color: forestgreen;
|
||||
}
|
||||
|
||||
&:active, &:focus {
|
||||
&:active, &:focus, &.enabled {
|
||||
background: forestgreen;
|
||||
color: black;
|
||||
border-color: forestgreen;
|
||||
|
||||
@ -286,3 +286,9 @@ li {
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
}
|
||||
|
||||
#clipboard {
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
padding: 0px;
|
||||
}
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "mnml-client",
|
||||
"version": "1.4.4",
|
||||
"version": "1.4.5",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
@ -29,6 +29,7 @@
|
||||
"preact-compat": "^3.19.0",
|
||||
"preact-context": "^1.1.3",
|
||||
"preact-redux": "^2.1.0",
|
||||
"query-string": "^6.8.3",
|
||||
"react-string-replace": "^0.4.4",
|
||||
"react-stripe-elements": "^3.0.0",
|
||||
"redux": "^4.0.0"
|
||||
|
||||
@ -19,6 +19,7 @@ export const setConstructRename = value => ({ type: 'SET_CONSTRUCT_RENAME', valu
|
||||
export const setGame = value => ({ type: 'SET_GAME', 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 });
|
||||
export const setInstance = value => ({ type: 'SET_INSTANCE', value });
|
||||
export const setInstances = value => ({ type: 'SET_INSTANCES', value });
|
||||
export const setItemEquip = value => ({ type: 'SET_ITEM_EQUIP', value });
|
||||
|
||||
@ -2,7 +2,7 @@ const anime = require('animejs').default;
|
||||
|
||||
const { TIMES } = require('../../constants');
|
||||
|
||||
function Banish(id) {
|
||||
function Banish(id, idle) {
|
||||
return anime({
|
||||
targets: [document.getElementById(id)],
|
||||
scaleY: 0,
|
||||
@ -11,6 +11,8 @@ function Banish(id) {
|
||||
delay: TIMES.TARGET_DELAY_MS,
|
||||
duration: TIMES.TARGET_DURATION_MS * 0.45,
|
||||
direction: 'alternate',
|
||||
begin: idle.pause,
|
||||
complete: idle.play,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -2,7 +2,7 @@ const anime = require('animejs').default;
|
||||
|
||||
const { TIMES } = require('../../constants');
|
||||
|
||||
function Invert(id) {
|
||||
function Invert(id, idle) {
|
||||
return anime({
|
||||
targets: [document.getElementById(id)],
|
||||
rotate: 180,
|
||||
@ -10,6 +10,8 @@ function Invert(id) {
|
||||
duration: TIMES.TARGET_DURATION_MS * 0.45,
|
||||
easing: 'easeInOutElastic',
|
||||
direction: 'alternate',
|
||||
begin: idle.pause,
|
||||
complete: idle.play,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -2,15 +2,17 @@ const anime = require('animejs').default;
|
||||
|
||||
const { TIMES } = require('../../constants');
|
||||
|
||||
function sourceCast(id, direction) {
|
||||
function sourceCast(id, direction, idle) {
|
||||
const { x, y } = direction;
|
||||
return anime({
|
||||
targets: [document.getElementById(id)],
|
||||
translateX: [0, x * 200],
|
||||
translateY: [0, y * 200],
|
||||
translateX: x * window.screen.width * 0.15,
|
||||
translateY: y * window.screen.height * 0.15,
|
||||
easing: 'easeInOutElastic',
|
||||
direction: 'alternate',
|
||||
duration: TIMES.SOURCE_DURATION_MS,
|
||||
begin: idle.pause,
|
||||
complete: idle.play,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -37,75 +37,10 @@ class ConstructAvatar extends Component {
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
const { animSource, animTarget, construct } = this.props;
|
||||
|
||||
// back to idle
|
||||
if (!animTarget && !animSource) {
|
||||
if (!this.idle) {
|
||||
this.idle = idleAnimation(this.props.construct.id);
|
||||
return this.animations.push(this.idle);
|
||||
}
|
||||
|
||||
return this.idle.play();
|
||||
}
|
||||
|
||||
const isSource = animSource && animSource.constructId === construct.id;
|
||||
|
||||
const selectAnim = () => {
|
||||
if (isSource) {
|
||||
console.warn(construct.name, animSource);
|
||||
return sourceCast(animSource.constructId, animSource.direction);
|
||||
}
|
||||
|
||||
switch (animTarget.skill) {
|
||||
case 'banish': return banish(construct.id);
|
||||
case 'invert': return invert(construct.id);
|
||||
default: return null;
|
||||
}
|
||||
};
|
||||
|
||||
const anim = selectAnim();
|
||||
if (!anim) return false;
|
||||
|
||||
this.idle.pause();
|
||||
this.animations.push(anim);
|
||||
return true;
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
const { animSource, animTarget, construct } = this.props;
|
||||
|
||||
// back to idle
|
||||
if (!animTarget && !animSource) {
|
||||
if (!this.idle) {
|
||||
this.idle = idleAnimation(this.props.construct.id);
|
||||
return this.animations.push(this.idle);
|
||||
}
|
||||
return this.idle.play();
|
||||
}
|
||||
|
||||
const isSource = animSource && animSource.constructId === construct.id;
|
||||
|
||||
const selectAnim = () => {
|
||||
if (isSource) {
|
||||
return sourceCast(animSource.constructId, animSource.direction);
|
||||
}
|
||||
|
||||
switch (animTarget.skill) {
|
||||
case 'Banish': return banish(construct.id);
|
||||
case 'Invert': return invert(construct.id);
|
||||
default: return null;
|
||||
}
|
||||
};
|
||||
|
||||
const anim = selectAnim();
|
||||
if (!anim) return false;
|
||||
|
||||
this.idle.pause();
|
||||
this.animations.push(anim);
|
||||
return true;
|
||||
}
|
||||
|
||||
resetAnimations() {
|
||||
for (let i = this.animations.length - 1; i >= 0; i--) {
|
||||
this.animations[i].reset();
|
||||
@ -132,23 +67,18 @@ class ConstructAvatar extends Component {
|
||||
// this is the source
|
||||
if (animSource && animSource.constructId === construct.id) {
|
||||
// console.warn(construct.name, 'should update')
|
||||
return true;
|
||||
return sourceCast(animSource.constructId, animSource.direction, this.idle);
|
||||
}
|
||||
|
||||
// this is the target
|
||||
if (animTarget && animTarget.constructId.includes(construct.id)) {
|
||||
// console.warn(construct.name, 'should update')
|
||||
return true;
|
||||
switch (animTarget.skill) {
|
||||
case 'Banish': return banish(construct.id, this.idle);
|
||||
case 'Invert': return invert(construct.id, this.idle);
|
||||
default: return null;
|
||||
}
|
||||
}
|
||||
|
||||
// we were previously doing src anim
|
||||
const prevSrc = this.props.animSource && this.props.animSource.constructId === construct.id;
|
||||
if (prevSrc && !animSource) return true;
|
||||
|
||||
const prevTarget = this.props.animTarget && this.props.animTarget.constructId.includes(construct.id);
|
||||
if (prevTarget && !animTarget) return true;
|
||||
|
||||
// console.warn(construct.name, 'not updating');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -76,7 +76,9 @@ function Controls(args) {
|
||||
background: displayColour,
|
||||
};
|
||||
|
||||
const timer = (
|
||||
const timer = instance.phase !== 'InProgress'
|
||||
? null
|
||||
: (
|
||||
<div class="timer-container">
|
||||
<div class="timer" style={timerStyles} > </div>
|
||||
</div>
|
||||
|
||||
@ -1,11 +1,14 @@
|
||||
const preact = require('preact');
|
||||
const { connect } = require('preact-redux');
|
||||
|
||||
const { errorToast, infoToast } = require('../utils');
|
||||
|
||||
const addState = connect(
|
||||
function receiveState(state) {
|
||||
const {
|
||||
ws,
|
||||
instances,
|
||||
invite,
|
||||
} = state;
|
||||
|
||||
function sendInstanceState(id) {
|
||||
@ -20,12 +23,18 @@ const addState = connect(
|
||||
ws.sendInstanceQueue();
|
||||
}
|
||||
|
||||
function sendInstanceInvite() {
|
||||
ws.sendInstanceInvite();
|
||||
}
|
||||
|
||||
return {
|
||||
instances,
|
||||
invite,
|
||||
|
||||
sendInstanceState,
|
||||
sendInstanceQueue,
|
||||
sendInstancePractice,
|
||||
sendInstanceInvite,
|
||||
};
|
||||
}
|
||||
);
|
||||
@ -33,10 +42,12 @@ const addState = connect(
|
||||
function JoinButtons(args) {
|
||||
const {
|
||||
instances,
|
||||
invite,
|
||||
|
||||
sendInstanceState,
|
||||
sendInstanceQueue,
|
||||
sendInstancePractice,
|
||||
sendInstanceInvite,
|
||||
} = args;
|
||||
|
||||
if (instances.length) {
|
||||
@ -55,6 +66,48 @@ function JoinButtons(args) {
|
||||
);
|
||||
}
|
||||
|
||||
const inviteBtn = () => {
|
||||
if (!invite) {
|
||||
return (
|
||||
<button
|
||||
class='pvp ready'
|
||||
onClick={() => sendInstanceInvite()}
|
||||
type="submit">
|
||||
Invite
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
||||
function copyClick(e) {
|
||||
const link = `${document.location.origin}#join=${invite}`;
|
||||
const textArea = document.createElement('textarea', { id: '#clipboard' });
|
||||
textArea.value = link;
|
||||
document.body.appendChild(textArea);
|
||||
textArea.focus();
|
||||
textArea.select();
|
||||
|
||||
try {
|
||||
document.execCommand('copy');
|
||||
infoToast('Invite link copied.');
|
||||
} catch (err) {
|
||||
console.error('link copy error', err);
|
||||
errorToast('Invite link copy error.');
|
||||
}
|
||||
|
||||
document.body.removeChild(textArea);
|
||||
return true;
|
||||
}
|
||||
|
||||
return (
|
||||
<button
|
||||
class='pvp ready enabled'
|
||||
onClick={copyClick}
|
||||
type="submit">
|
||||
Copy Link
|
||||
</button>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<aside class='play-ctrl'>
|
||||
<div class="timer-container"></div>
|
||||
@ -65,6 +118,7 @@ function JoinButtons(args) {
|
||||
type="submit">
|
||||
PVP
|
||||
</button>
|
||||
{inviteBtn()}
|
||||
<button
|
||||
class='practice ready'
|
||||
onClick={() => sendInstancePractice()}
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
const querystring = require('query-string');
|
||||
|
||||
const eachSeries = require('async/eachSeries');
|
||||
const sample = require('lodash/sample');
|
||||
|
||||
@ -168,9 +170,20 @@ function registerEvents(store) {
|
||||
return store.dispatch(actions.setInstances(v));
|
||||
}
|
||||
|
||||
function setInvite(code) {
|
||||
if (!code) return store.dispatch(actions.setInvite(null));
|
||||
|
||||
navigator.clipboard.writeText(code).then(() => {
|
||||
notify(`your invite code ${code} was copied to the clipboard.`);
|
||||
}, () => {});
|
||||
|
||||
return store.dispatch(actions.setInvite(code));
|
||||
}
|
||||
|
||||
function setInstance(v) {
|
||||
const { account, instance, ws } = store.getState();
|
||||
if (v) {
|
||||
setInvite(null);
|
||||
const player = v.players.find(p => p.id === account.id);
|
||||
store.dispatch(actions.setPlayer(player));
|
||||
|
||||
@ -272,6 +285,16 @@ function registerEvents(store) {
|
||||
} */
|
||||
// setup / localstorage
|
||||
|
||||
function urlHashChange() {
|
||||
const { ws } = store.getState();
|
||||
const cmds = querystring.parse(location.hash);
|
||||
|
||||
if (cmds.join) ws.sendInstanceJoin(cmds.join);
|
||||
return true;
|
||||
}
|
||||
|
||||
window.addEventListener('hashchange', urlHashChange, false);
|
||||
|
||||
return {
|
||||
clearCombiner,
|
||||
clearConstructRename,
|
||||
@ -289,12 +312,15 @@ function registerEvents(store) {
|
||||
setEmail,
|
||||
setInstance,
|
||||
setItemInfo,
|
||||
setInvite,
|
||||
setPing,
|
||||
setShop,
|
||||
setTeam,
|
||||
setSubscription,
|
||||
setWs,
|
||||
|
||||
urlHashChange,
|
||||
|
||||
notify,
|
||||
};
|
||||
}
|
||||
|
||||
@ -31,6 +31,7 @@ module.exports = {
|
||||
constructRename: createReducer(null, 'SET_CONSTRUCT_RENAME'),
|
||||
game: createReducer(null, 'SET_GAME'),
|
||||
email: createReducer(null, 'SET_EMAIL'),
|
||||
invite: createReducer(null, 'SET_INVITE'),
|
||||
info: createReducer(null, 'SET_INFO'),
|
||||
instance: createReducer(null, 'SET_INSTANCE'),
|
||||
instances: createReducer([], 'SET_INSTANCES'),
|
||||
|
||||
@ -126,6 +126,14 @@ function createSocket(events) {
|
||||
send(['InstanceQueue', {}]);
|
||||
}
|
||||
|
||||
function sendInstanceInvite() {
|
||||
send(['InstanceInvite', {}]);
|
||||
}
|
||||
|
||||
function sendInstanceJoin(code) {
|
||||
send(['InstanceJoin', { code }]);
|
||||
}
|
||||
|
||||
function sendInstanceReady(instanceId) {
|
||||
send(['InstanceReady', { instance_id: instanceId }]);
|
||||
}
|
||||
@ -239,6 +247,9 @@ function createSocket(events) {
|
||||
|
||||
QueueRequested: () => events.notify('pvp queue request received'),
|
||||
QueueJoined: () => events.notify('you have joined the pvp queue'),
|
||||
InviteRequested: () => events.notify('pvp queue request received'),
|
||||
Invite: code => events.setInvite(code),
|
||||
Joining: () => events.notify('searching for instance...'),
|
||||
|
||||
Error: errHandler,
|
||||
};
|
||||
@ -284,6 +295,8 @@ function createSocket(events) {
|
||||
sendPing();
|
||||
sendItemInfo();
|
||||
|
||||
events.urlHashChange();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -318,6 +331,7 @@ function createSocket(events) {
|
||||
ws.addEventListener('message', onMessage);
|
||||
ws.addEventListener('error', onError);
|
||||
ws.addEventListener('close', onClose);
|
||||
|
||||
return ws;
|
||||
}
|
||||
|
||||
@ -338,6 +352,8 @@ function createSocket(events) {
|
||||
sendInstancePractice,
|
||||
sendInstanceQueue,
|
||||
sendInstanceState,
|
||||
sendInstanceInvite,
|
||||
sendInstanceJoin,
|
||||
|
||||
sendVboxAccept,
|
||||
sendVboxApply,
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "mnml-ops",
|
||||
"version": "1.4.4",
|
||||
"version": "1.4.5",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "mnml"
|
||||
version = "1.4.4"
|
||||
version = "1.4.5"
|
||||
authors = ["ntr <ntr@smokestack.io>"]
|
||||
|
||||
[dependencies]
|
||||
|
||||
@ -12,6 +12,7 @@ use account;
|
||||
use account::Account;
|
||||
use game;
|
||||
use instance;
|
||||
use names;
|
||||
|
||||
use pg::{Db, PgPool};
|
||||
use rpc::RpcMessage;
|
||||
@ -54,6 +55,9 @@ pub enum Event {
|
||||
|
||||
// client events
|
||||
Queue(Id),
|
||||
Invite(Id),
|
||||
Join(Id, String),
|
||||
Joined(Id),
|
||||
}
|
||||
|
||||
struct WsClient {
|
||||
@ -62,6 +66,7 @@ struct WsClient {
|
||||
tx: Sender<RpcMessage>,
|
||||
subs: HashSet<Uuid>,
|
||||
pvp: bool,
|
||||
invite: Option<String>,
|
||||
}
|
||||
|
||||
impl Events {
|
||||
@ -115,7 +120,7 @@ impl Events {
|
||||
None => None,
|
||||
};
|
||||
|
||||
let client = WsClient { id, tx, account: account_id, subs: HashSet::new(), pvp: false };
|
||||
let client = WsClient { id, tx, account: account_id, subs: HashSet::new(), pvp: false, invite: None };
|
||||
self.clients.insert(id, client);
|
||||
|
||||
info!("clients={:?}", self.clients.len());
|
||||
@ -223,6 +228,59 @@ impl Events {
|
||||
info!("joined game queue id={:?} account={:?}", requester.id, requester.account);
|
||||
return Ok(());
|
||||
},
|
||||
|
||||
Event::Invite(id) => {
|
||||
// check whether request is valid
|
||||
let c = self.clients.get_mut(&id)
|
||||
.ok_or(format_err!("connection not found id={:?}", id))?;
|
||||
|
||||
if let None = c.account {
|
||||
return Err(err_msg("cannot join pvp queue anonymously"));
|
||||
}
|
||||
|
||||
let code = names::name().split_whitespace().collect::<Vec<&str>>().join("-");
|
||||
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(());
|
||||
},
|
||||
|
||||
Event::Join(id, code) => {
|
||||
// check whether request is valid
|
||||
let c = self.clients.get(&id)
|
||||
.ok_or(format_err!("connection not found id={:?}", id))?;
|
||||
|
||||
if let None = c.account {
|
||||
return Err(err_msg("cannot join pvp queue anonymously"));
|
||||
}
|
||||
|
||||
info!("pvp join request id={:?} account={:?} code={:?}", c.id, c.account, code);
|
||||
|
||||
let inv = self.clients.iter()
|
||||
.filter(|(_id, c)| c.invite.is_some())
|
||||
.find(|(_id, c)| match c.invite {
|
||||
Some(ref c) => *c == code,
|
||||
None => false,
|
||||
})
|
||||
.map(|(_id, c)| PvpRequest { id: c.id, account: c.account.unwrap(), tx: c.tx.clone() })
|
||||
.ok_or(format_err!("invite not found code={:?}", code))?;
|
||||
|
||||
let join = PvpRequest { id: c.id, account: c.account.unwrap(), tx: c.tx.clone() };
|
||||
|
||||
self.warden.send(GameEvent::Match((join, inv)))?;
|
||||
return Ok(());
|
||||
},
|
||||
|
||||
Event::Joined(id) => {
|
||||
// check whether request is valid
|
||||
let c = self.clients.get_mut(&id)
|
||||
.ok_or(format_err!("connection not found id={:?}", id))?;
|
||||
|
||||
c.pvp = false;
|
||||
c.invite = None;
|
||||
return Ok(());
|
||||
},
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -117,7 +117,7 @@ pub fn shapes_write(id: Uuid) -> Result<Uuid, Error> {
|
||||
(ConstructShapes::Circle, 10),
|
||||
(ConstructShapes::Line, 10),
|
||||
(ConstructShapes::V, 10),
|
||||
// (ConstructShapes::Tri, 3),
|
||||
(ConstructShapes::Tri, 10),
|
||||
// (ConstructShapes::Plus, 5),
|
||||
(ConstructShapes::Blank, 1),
|
||||
];
|
||||
@ -155,6 +155,9 @@ pub fn shapes_write(id: Uuid) -> Result<Uuid, Error> {
|
||||
let size = rng.gen_range(20.0, 50.0);
|
||||
write!(&mut svg, "<rect fill=\"{fill}\" x=\"-{x}\" y=\"-{y}\" width=\"{width}\" height=\"{height}\" transform=\"translate({x_t}, {y_t}) rotate({rotation})\" />",
|
||||
fill = colour, x = size / 2.0, y = size / 2.0, width = size, height = size, x_t = x_translate, y_t = y_translate, rotation = rotation)?;
|
||||
if scalar == 0.0 && rng.gen_bool(0.5) {
|
||||
continue;
|
||||
}
|
||||
write!(&mut svg, "<rect fill=\"{fill}\" x=\"-{x}\" y=\"-{y}\" width=\"{width}\" height=\"{height}\" transform=\"translate({x_t}, {y_t}) rotate({rotation})\" />",
|
||||
fill = colour, x = size / 2.0, y = size / 2.0, width = size, height = size, x_t = -x_translate, y_t = -y_translate, rotation = rotation)?;
|
||||
},
|
||||
@ -163,6 +166,9 @@ pub fn shapes_write(id: Uuid) -> Result<Uuid, Error> {
|
||||
let b = rng.gen_range(20.0, 50.0);
|
||||
write!(&mut svg, "<polygon fill=\"{fill}\" x=\"{x}\" y=\"{y}\" points=\"{x0} {y0}, {x1} {y1}, {x2} {y2}\" transform=\"translate({x_translate}, {y_translate}) rotate({rotation})\" />",
|
||||
fill = colour, x = -b / 2.0, y = h / 2.0, x0 = -b / 2.0, y0 = -h / 2.0, x1 = 0, y1 = b / 2.0, x2 = b / 2.0, y2 = -h / 2.0, rotation = rotation, x_translate = x_translate, y_translate = y_translate)?;
|
||||
if scalar == 0.0 && rng.gen_bool(0.5) {
|
||||
continue;
|
||||
}
|
||||
write!(&mut svg, "<polygon fill=\"{fill}\" x=\"{x}\" y=\"{y}\" points=\"{x0} {y0}, {x1} {y1}, {x2} {y2}\" transform=\"translate({x_translate}, {y_translate}) rotate({rotation})\" />",
|
||||
fill = colour, x = -b / 2.0, y = h / 2.0, x0 = -b / 2.0, y0 = -h / 2.0, x1 = 0, y1 = b / 2.0, x2 = b / 2.0, y2 = -h / 2.0, rotation = rotation + 180, x_translate = -x_translate, y_translate = -y_translate)?;
|
||||
},
|
||||
@ -178,6 +184,9 @@ pub fn shapes_write(id: Uuid) -> Result<Uuid, Error> {
|
||||
let height = rng.gen_range(20.0, 50.0);
|
||||
write!(&mut svg, "<rect fill=\"{fill}\" x=\"-{x}\" y=\"-{y}\" width=\"{width}\" height=\"{height}\" transform=\"translate({x_t}, {y_t}) rotate({rotation})\" />",
|
||||
fill = colour, x = width / 2.0, y = height / 2.0, width = width, height = height, x_t = x_translate, y_t = y_translate, rotation = rotation)?;
|
||||
if scalar == 0.0 && rng.gen_bool(0.5) {
|
||||
continue;
|
||||
}
|
||||
write!(&mut svg, "<rect fill=\"{fill}\" x=\"-{x}\" y=\"-{y}\" width=\"{width}\" height=\"{height}\" transform=\"translate({x_t}, {y_t}) rotate({rotation})\" />",
|
||||
fill = colour, x = width / 2.0, y = height / 2.0, width = width, height = height, x_t = -x_translate, y_t = -y_translate, rotation = rotation)?;
|
||||
},
|
||||
@ -188,11 +197,30 @@ pub fn shapes_write(id: Uuid) -> Result<Uuid, Error> {
|
||||
|
||||
write!(&mut svg, "<polyline fill=\"none\" stroke=\"{fill}\" stroke-width=\"{width}\" x=\"{x}\" y=\"{y}\" points=\"{x0} {y0}, {x1} {y1}, {x2} {y2}\" transform=\"translate({x_translate}, {y_translate}) rotate({rotation})\" />",
|
||||
fill = colour, width = width, x = -b / 2.0, y = h / 2.0, x0 = -b / 2.0, y0 = -h / 2.0, x1 = 0, y1 = b / 2.0, x2 = b / 2.0, y2 = -h / 2.0, rotation = rotation, x_translate = x_translate, y_translate = y_translate)?;
|
||||
if scalar == 0.0 && rng.gen_bool(0.5) {
|
||||
continue;
|
||||
}
|
||||
write!(&mut svg, "<polyline fill=\"none\" stroke=\"{fill}\" stroke-width=\"{width}\" x=\"{x}\" y=\"{y}\" points=\"{x0} {y0}, {x1} {y1}, {x2} {y2}\" transform=\"translate({x_translate}, {y_translate}) rotate({rotation})\" />",
|
||||
fill = colour, width = width, x = -b / 2.0, y = h / 2.0, x0 = -b / 2.0, y0 = -h / 2.0, x1 = 0, y1 = b / 2.0, x2 = b / 2.0, y2 = -h / 2.0, rotation = rotation + 180, x_translate = -x_translate, y_translate = -y_translate)?;
|
||||
},
|
||||
ConstructShapes::Tri => {
|
||||
let width = rng.gen_range(2.0, 4.0);
|
||||
let length = rng.gen_range(12.5, 25.0);
|
||||
|
||||
let x0 = (0.0 as f64).cos() * length;
|
||||
let y0 = (0.0 as f64).sin() * length;
|
||||
let x1 = ((f64::consts::PI * 2.0) / 3.0).cos() * length;
|
||||
let y1 = ((f64::consts::PI * 2.0) / 3.0).sin() * length;
|
||||
let x2 = ((f64::consts::PI * 4.0) / 3.0).cos() * length;
|
||||
let y2 = ((f64::consts::PI * 4.0) / 3.0).sin() * length;
|
||||
|
||||
write!(&mut svg, "<path stroke=\"{fill}\" stroke-width=\"{width}\" d=\"M{x0} {y0}L 0 0 M{x1} {y1}L 0 0 M{x2} {y2}L 0 0 \" transform=\"translate({x_translate}, {y_translate}) rotate({rotation})\" />",
|
||||
fill = colour, width = width, x0 = x0, y0 = y0, x1 = x1, y1 = y1, x2 = x2, y2 = y2, rotation = rotation, x_translate = x_translate, y_translate = y_translate)?;
|
||||
if scalar == 0.0 && rng.gen_bool(0.5) {
|
||||
continue;
|
||||
}
|
||||
write!(&mut svg, "<path stroke=\"{fill}\" stroke-width=\"{width}\" d=\"M{x0} {y0}L 0 0 M{x1} {y1}L 0 0 M{x2} {y2}L 0 0 \" transform=\"translate({x_translate}, {y_translate}) rotate({rotation})\" />",
|
||||
fill = colour, width = width, x0 = x0, y0 = y0, x1 = x1, y1 = y1, x2 = x2, y2 = y2, rotation = rotation, x_translate = -x_translate, y_translate = -y_translate)?;
|
||||
},
|
||||
ConstructShapes::Plus => {
|
||||
|
||||
|
||||
@ -62,6 +62,10 @@ pub enum RpcMessage {
|
||||
QueueJoined(()),
|
||||
QueueCancelled(()),
|
||||
|
||||
InviteRequested(()),
|
||||
Invite(String),
|
||||
Joining(()),
|
||||
|
||||
Error(String),
|
||||
}
|
||||
|
||||
@ -91,6 +95,8 @@ pub enum RpcRequest {
|
||||
SubscriptionState {},
|
||||
EmailState {},
|
||||
|
||||
InstanceInvite {},
|
||||
InstanceJoin { code: String },
|
||||
InstanceQueue {},
|
||||
InstancePractice {},
|
||||
InstanceAbandon { instance_id: Uuid },
|
||||
@ -136,21 +142,27 @@ impl Connection {
|
||||
None => return Err(err_msg("auth required")),
|
||||
};
|
||||
|
||||
// evented but authorization required
|
||||
match v {
|
||||
RpcRequest::InstanceQueue {} => {
|
||||
self.events.send(Event::Queue(self.id))?;
|
||||
return Ok(RpcMessage::QueueRequested(()));
|
||||
},
|
||||
_ => (),
|
||||
};
|
||||
|
||||
// all good, let's make a tx and process
|
||||
let mut tx = db.transaction()?;
|
||||
|
||||
let request = v.clone();
|
||||
|
||||
let response = match v {
|
||||
// evented but authorization required
|
||||
RpcRequest::InstanceQueue {} => {
|
||||
self.events.send(Event::Queue(self.id))?;
|
||||
Ok(RpcMessage::QueueRequested(()))
|
||||
},
|
||||
RpcRequest::InstanceInvite {} => {
|
||||
self.events.send(Event::Invite(self.id))?;
|
||||
Ok(RpcMessage::InviteRequested(()))
|
||||
},
|
||||
RpcRequest::InstanceJoin { code } => {
|
||||
self.events.send(Event::Join(self.id, code))?;
|
||||
Ok(RpcMessage::Joining(()))
|
||||
},
|
||||
_ => {
|
||||
// all good, let's make a tx and process
|
||||
let mut tx = db.transaction()?;
|
||||
|
||||
let res = match v {
|
||||
RpcRequest::AccountState {} =>
|
||||
Ok(RpcMessage::AccountState(account.clone())),
|
||||
RpcRequest::AccountConstructs {} =>
|
||||
@ -228,6 +240,9 @@ impl Connection {
|
||||
};
|
||||
|
||||
tx.commit()?;
|
||||
res
|
||||
}
|
||||
};
|
||||
|
||||
info!("request={:?} account={:?} duration={:?}", request, account.name, begin.elapsed());
|
||||
|
||||
|
||||
@ -90,6 +90,10 @@ impl Warden {
|
||||
fn on_match(&mut self, pair: Pair) -> Result<(), Error> {
|
||||
info!("received pair={:?}", pair);
|
||||
|
||||
// clear pvp status
|
||||
self.events.send(Event::Joined(pair.0.id))?;
|
||||
self.events.send(Event::Joined(pair.1.id))?;
|
||||
|
||||
let db = self.pool.get()?;
|
||||
let mut tx = db.transaction()?;
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user