Merge branch 'release/1.5.0'

This commit is contained in:
ntr 2019-09-22 20:28:59 +10:00
commit 2d4e6ef22a
36 changed files with 652 additions and 1286 deletions

View File

@ -1 +1 @@
1.4.8
1.5.0

View File

@ -1,6 +1,6 @@
{
"name": "mnml-client",
"version": "1.4.8",
"version": "1.5.0",
"description": "",
"main": "index.js",
"scripts": {

View File

@ -14,32 +14,32 @@ aside {
padding-left: 1em;
.instance-ctrl {
grid-template-rows: 1fr 1fr 1fr min-content;
}
.controls {
grid-area: controls;
display: grid;
grid-auto-rows: 1fr;
grid-template-areas:
"top"
"p0"
"p1"
"bottom";
.flex {
display: flex;
flex-flow: column;;
}
grid-template-rows: min-content 3fr 3fr 1fr;
grid-gap: 0.5em 0;
}
&.play-ctrl {
.controls {
grid-template-rows: 4fr 4fr 1fr;
}
}
// &.play-ctrl {
// .controls {
// grid-template-rows: 4fr 4fr 1fr;
// }
// }
// fix chrome being inconsistent
table {
height: 100%;
}
div {
text-align: right;
}
text-align: center;
button {
width: 100%;
@ -106,8 +106,20 @@ aside {
padding: 0 0.75em 0 0.75em;
}
.instance-ctrl-btns {
.instance-ctrl-btns, .game-ctrl-btns {
font-size: 50%;
display: flex;
flex-flow: column;
button {
flex: 0;
}
.ready, .quit {
flex: 1;
font-size: 200%;
}
}
.abandon:not([disabled]) {

View File

@ -195,15 +195,6 @@
}
.construct-list {
.avatar {
grid-area: avatar;
object-fit: contain;
background-size: contain;
background-repeat: no-repeat;
background-position: center;
// pointer-events: none;
}
.name {
grid-area: name;
margin-bottom: 0.5em;

View File

@ -2,29 +2,35 @@
.player-box {
display: grid;
grid-template-areas:
"score"
"msg"
"img"
"name"
"score"
"ctrl";
grid-template-rows: min-content 1fr min-content min-content min-content;
&.top {
grid-template-areas:
"ctrl"
"score"
"name"
"img"
"score";
"msg";
.img {
display: flex;
flex-flow: column;
justify-content: flex-end;
}
grid-template-rows: min-content min-content min-content 1fr min-content;
}
grid-template-rows: min-content 1fr min-content;
.score {
grid-area: score;
display: flex;
justify-content: space-around;
text-align: center;
span {
flex: 1;
}
}
.img {
@ -34,4 +40,10 @@
.ctrl {
grid-area: ctrl;
}
.msg {
grid-area: msg;
color: @white;
}
}

View File

@ -286,7 +286,7 @@ li {
.logo {
height: 2em;
background-image: url("../../src/components/svgs/mnml.2.svg");
background-image: url("../../src/components/svgs/menu.logo.svg");
background-size: contain;
background-repeat: no-repeat;
background-position: left;
@ -299,6 +299,15 @@ li {
background-position: center;
}
.avatar {
grid-area: avatar;
object-fit: contain;
background-size: contain;
background-repeat: no-repeat;
background-position: center;
// pointer-events: none;
}
#clipboard {
width: 1px;
height: 1px;

View File

@ -1,6 +1,6 @@
{
"name": "mnml-client",
"version": "1.4.8",
"version": "1.5.0",
"description": "",
"main": "index.js",
"scripts": {

View File

@ -0,0 +1,114 @@
const { Component } = require('preact');
const preact = require('preact');
const { connect } = require('preact-redux');
const idleAnimation = require('./anims/idle');
const wiggle = require('./anims/wiggle');
const addState = connect(
function receiveState(state) {
const {
ws,
account,
mtxActive,
} = state;
function sendMtxAccountApply() {
return ws.sendMtxAccountApply(mtxActive);
}
return {
account,
mtxActive,
sendMtxAccountApply,
};
}
);
class AccountAvatar extends Component {
constructor() {
super();
// The animation ids are a check to ensure that animations are not repeated
// When a new account animation is communicated with state it will have a corresponding Id
// which is a count of how many resoluttions have passed
this.animations = [];
this.resetAnimations = this.resetAnimations.bind(this);
}
render() {
const { account, mtxActive } = this.props;
const imgStyle = account.img
? { 'background-image': `url(/imgs/${account.img}.svg)`, cursor: mtxActive ? 'pointer' : '' }
: null;
return (
<div
class="img avatar"
id={account.id}
onMouseDown={this.onClick.bind(this)}
style={imgStyle}>
</div>
);
}
onClick() {
if (this.props.mtxActive) {
return this.props.sendMtxAccountApply();
}
return this.animations.push(wiggle(this.props.account.id, this.idle));
}
componentDidMount() {
this.idle = idleAnimation(this.props.account.id);
return this.animations.push(this.idle);
}
resetAnimations() {
for (let i = this.animations.length - 1; i >= 0; i--) {
this.animations[i].reset();
}
}
componentWillUnmount() {
this.resetAnimations();
}
// shouldComponentUpdate(newProps) {
// const { account } = newProps;
// if (account !== this.props.account) {
// return true;
// }
// return false;
// }
}
const StateAccountAvatar = addState(AccountAvatar);
function AccountBox(args) {
const {
account,
} = args;
// if (!isTop) {
// return (
// <div class='player-box top'>
// <div class="name">Processor</div>
// <div class="img avatar" id={account.img} style={imgStyle}></div>
// <div class="msg">&nbsp;</div>
// </div>
// );
// }
return (
<div class='player-box bottom'>
<div class="msg">&nbsp;</div>
<StateAccountAvatar />
<div class="name">{account.name}</div>
<div class="score">&nbsp;</div>
</div>
);
}
module.exports = addState(AccountBox);

View File

@ -38,7 +38,7 @@ function Controls(args) {
if (game) return <GameCtrl />;
if (instance) return <InstanceCtrl />;
if (nav === 'play' || !nav) return <PlayCtrl />
if (nav === 'play' || nav === 'shop' || !nav) return <PlayCtrl />
if (nav === 'team' || nav === 'account') return <TeamCtrl />
return false;

View File

@ -0,0 +1,83 @@
const preact = require('preact');
const { connect } = require('preact-redux');
const actions = require('../actions');
const addState = connect(
function receiveState(state) {
const {
ws,
game,
animating,
} = state;
function sendReady() {
document.activeElement.blur();
return ws.sendGameReady(game.id);
}
function getInstanceState() {
return ws.sendInstanceState(game.instance);
}
function sendGameSkillClear() {
return ws.sendGameSkillClear(game.id);
}
function sendAbandon() {
return ws.sendInstanceAbandon(game.instance);
}
return {
game,
sendAbandon,
sendGameSkillClear,
sendReady,
getInstanceState,
animating,
};
},
function receiveDispatch(dispatch) {
function quit() {
dispatch(actions.setNav('transition'));
dispatch(actions.setGame(null));
dispatch(actions.setInstance(null));
}
return { quit };
}
);
function GameCtrlBtns(args) {
const {
game,
animating,
getInstanceState,
sendGameSkillClear,
sendReady,
quit,
} = args;
if (!game) return false;
const finished = game.phase === 'Finish';
function quitClick() {
getInstanceState();
quit();
}
const readyBtn = <button disabled={animating} class="ready" onClick={() => sendReady()}>Ready</button>;
const quitBtn = <button disabled={animating} class="quit" onClick={quitClick}>Back</button>;
return (
<div class="game-ctrl-btns">
<button disabled={true} >Chat</button>
<button disabled={animating} onClick={sendGameSkillClear}>Clear</button>
{finished ? quitBtn : readyBtn}
</div>
);
}
module.exports = addState(GameCtrlBtns);

View File

@ -0,0 +1,64 @@
const preact = require('preact');
const { connect } = require('preact-redux');
const actions = require('../actions');
const addState = connect(
function receiveState(state) {
const {
ws,
game,
} = state;
function sendAbandon() {
return ws.sendInstanceAbandon(game.instance);
}
return {
game,
sendAbandon,
};
},
function receiveDispatch(dispatch) {
function leave() {
dispatch(actions.setNav('play'));
dispatch(actions.setGame(null));
dispatch(actions.setInstance(null));
}
return { leave };
}
);
function GameCtrlTopBtns(args) {
const {
game,
leave,
sendAbandon,
} = args;
const finished = game && game.phase === 'Finished';
const { abandonState } = this.state;
const abandonStateTrue = e => {
e.stopPropagation();
this.setState({ abandonState: true });
setTimeout(() => this.setState({ abandonState: false }), 2000);
};
const abandonClasses = `abandon ${abandonState ? 'confirming' : ''}`;
const abandonAction = abandonState ? sendAbandon : abandonStateTrue;
const abandonBtn = <button class={abandonClasses} disabled={finished} onClick={abandonAction}>Abandon</button>;
const leaveBtn = <button class='abandon confirming' onClick={leave}>Leave</button>;
return (
<div class="instance-ctrl-btns">
{finished ? leaveBtn : abandonBtn}
</div>
);
}
module.exports = addState(GameCtrlTopBtns);

View File

@ -4,80 +4,34 @@ const { connect } = require('preact-redux');
const actions = require('../actions');
const PlayerBox = require('./player.box');
const InstanceCtrlBtns = require('./instance.ctrl.btns');
const GameCtrlButtons = require('./game.ctrl.btns');
const GameCtrlTopButtons = require('./game.ctrl.btns.top');
const addState = connect(
function receiveState(state) {
const {
ws,
game,
account,
animating,
} = state;
function sendReady() {
document.activeElement.blur();
return ws.sendGameReady(game.id);
}
function getInstanceState() {
return ws.sendInstanceState(game.instance);
}
function sendGameSkillClear() {
return ws.sendGameSkillClear(game.id);
}
function sendAbandon() {
return ws.sendInstanceAbandon(game.instance);
}
return {
game,
sendAbandon,
sendGameSkillClear,
sendReady,
account,
getInstanceState,
animating,
};
},
function receiveDispatch(dispatch) {
function quit() {
dispatch(actions.setNav('transition'));
dispatch(actions.setGame(null));
dispatch(actions.setInstance(null));
}
return { quit };
}
);
function Controls(args) {
const {
account,
sendAbandon,
game,
animating,
sendGameSkillClear,
sendReady,
getInstanceState,
quit,
} = args;
if (!game) return false;
const { abandonState } = this.state;
const opponent = game.players.find(t => t.id !== account.id);
const player = game.players.find(t => t.id === account.id);
function quitClick() {
getInstanceState();
quit();
}
const zero = Date.parse(game.phase_start);
const now = Date.now();
const end = Date.parse(game.phase_end);
@ -104,30 +58,14 @@ function Controls(args) {
</div>
);
const readyBtn = <button disabled={animating} class="ready" onClick={() => sendReady()}>Ready</button>;
const quitBtn = <button disabled={animating} onClick={quitClick}>Back</button>;
const cancelAbandon = e => {
e.stopPropagation();
return this.setState({ abandonState: false });
};
const abandonStateTrue = e => {
e.stopPropagation();
this.setState({ abandonState: true });
};
const abandonClasses = `abandon ${abandonState ? 'confirming' : ''}`;
const abandonAction = abandonState ? sendAbandon : abandonStateTrue;
return (
<aside onClick={cancelAbandon}>
<aside>
{timer}
<div class="controls instance-ctrl">
<GameCtrlTopButtons />
<PlayerBox player={opponent}/>
{game.phase === 'Finish' ? quitBtn : readyBtn}
<PlayerBox player={player} isPlayer={true} />
<InstanceCtrlBtns />
<GameCtrlButtons />
</div>
</aside>
);

View File

@ -7,68 +7,41 @@ const addState = connect(
function receiveState(state) {
const {
ws,
game,
instance,
animating,
} = state;
function sendReady() {
document.activeElement.blur();
return ws.sendGameReady(game.id);
}
function sendGameSkillClear() {
return ws.sendGameSkillClear(game.id);
return ws.sendInstanceReady(instance.id);
}
function sendAbandon() {
const id = instance ? instance.id : game.instance;
return ws.sendInstanceAbandon(id);
return ws.sendInstanceAbandon(instance.id);
}
return {
game,
instance,
animating,
sendAbandon,
sendGameSkillClear,
sendReady,
};
},
);
function InstanceCtrlBtns(args) {
const {
sendAbandon,
animating,
sendGameSkillClear,
game,
instance,
sendAbandon,
sendReady,
} = args;
const finished = instance && instance.phase === 'Finished';
const { abandonState } = this.state;
const cancelAbandon = e => {
e.stopPropagation();
return this.setState({ abandonState: false });
};
const abandonStateTrue = e => {
e.stopPropagation();
this.setState({ abandonState: true });
setTimeout(() => this.setState({ abandonState: false }), 2000);
};
const abandonClasses = `abandon ${abandonState ? 'confirming' : ''}`;
const abandonAction = abandonState ? sendAbandon : abandonStateTrue;
return (
<div class="instance-ctrl-btns">
{game ? <button disabled={animating} onClick={sendGameSkillClear}>Clear</button> : null}
<button class={abandonClasses} disabled={animating || finished} onClick={abandonAction}>Abandon</button>
<button disabled={true} >Chat</button>
<button disabled={finished} class="ready" onClick={() => sendReady()}>Ready</button>
</div>
);
}

View File

@ -4,6 +4,7 @@ const { connect } = require('preact-redux');
const actions = require('../actions');
const PlayerBox = require('./player.box');
const InstanceCtrlBtns = require('./instance.ctrl.btns');
const InstanceCtrlTopBtns = require('./instance.ctrl.top.btns');
const addState = connect(
function receiveState(state) {
@ -11,44 +12,19 @@ const addState = connect(
ws,
instance,
account,
animating,
} = state;
function sendReady() {
document.activeElement.blur();
return ws.sendInstanceReady(instance.id);
}
function sendAbandon() {
return ws.sendInstanceAbandon(instance.id);
}
return {
sendAbandon,
instance,
sendReady,
account,
animating,
};
},
function receiveDispatch(dispatch) {
function leave() {
dispatch(actions.setNav('play'));
dispatch(actions.setGame(null));
dispatch(actions.setInstance(null));
}
return { leave };
}
);
function Controls(args) {
const {
account,
sendAbandon,
instance,
sendReady,
leave,
} = args;
if (!instance) return false;
@ -76,27 +52,19 @@ function Controls(args) {
background: displayColour,
};
const timer = instance.phase !== 'InProgress'
? null
: (
<div class="timer-container">
<div class="timer" style={timerStyles} >&nbsp;</div>
</div>
);
const ready = instance.phase !== 'Finished'
? <button class="ready" onClick={() => sendReady()}>Ready</button>
: <button class="ready" onClick={leave}>Leave</button>
const abandon = instance.phase !== 'Finished' ? sendAbandon : false;
const timer = (
<div class="timer-container">
<div class="timer" style={timerStyles} >&nbsp;</div>
</div>
);
return (
<aside>
{timer}
<div class="controls instance-ctrl">
<InstanceCtrlTopBtns />
<PlayerBox player={opponent} />
{ready}
<PlayerBox player={player} isPlayer={true} abandon={abandon}/>
<PlayerBox player={player} isPlayer={true} />
<InstanceCtrlBtns />
</div>
</aside>

View File

@ -0,0 +1,64 @@
const preact = require('preact');
const { connect } = require('preact-redux');
const actions = require('../actions');
const addState = connect(
function receiveState(state) {
const {
ws,
instance,
} = state;
function sendAbandon() {
return ws.sendInstanceAbandon(instance.id);
}
return {
instance,
sendAbandon,
};
},
function receiveDispatch(dispatch) {
function leave() {
dispatch(actions.setNav('play'));
dispatch(actions.setGame(null));
dispatch(actions.setInstance(null));
}
return { leave };
}
);
function InstanceTopBtns(args) {
const {
instance,
leave,
sendAbandon,
} = args;
const finished = instance && instance.phase === 'Finished';
const { abandonState } = this.state;
const abandonStateTrue = e => {
e.stopPropagation();
this.setState({ abandonState: true });
setTimeout(() => this.setState({ abandonState: false }), 2000);
};
const abandonClasses = `abandon ${abandonState ? 'confirming' : ''}`;
const abandonAction = abandonState ? sendAbandon : abandonStateTrue;
const abandonBtn = <button class={abandonClasses} disabled={finished} onClick={abandonAction}>Abandon</button>;
const leaveBtn = <button class='abandon confirming' onClick={leave}>Leave</button>;
return (
<div class="instance-ctrl-btns">
{finished ? leaveBtn : abandonBtn}
</div>
);
}
module.exports = addState(InstanceTopBtns);

View File

@ -3,6 +3,8 @@ const { connect } = require('preact-redux');
const { errorToast, infoToast } = require('../utils');
const AccountBox = require('./account.box');
const addState = connect(
function receiveState(state) {
const {
@ -50,17 +52,33 @@ function JoinButtons(args) {
sendInstanceInvite,
} = args;
const discordBtn = (
<button
class='discord-btn'
onClick={() => window.open('https://discord.gg/YJJgurM') }>
&nbsp;
</button>
);
if (instances.length) {
return (
<aside class='play-ctrl'>
<div class="timer-container"></div>
<div class="controls">
<button
class='pvp ready full'
onClick={() => sendInstanceState(instances[0].id)}
type="submit">
Rejoin
</button>
{discordBtn}
<div class="flex">
<div>&nbsp;</div>
</div>
<AccountBox />
<div class="instance-ctrl-btns">
<button disabled={true} >Chat</button>
<button
class='pvp ready full'
onClick={() => sendInstanceState(instances[0].id)}
type="submit">
Rejoin
</button>
</div>
</div>
</aside>
);
@ -112,24 +130,26 @@ function JoinButtons(args) {
<aside class='play-ctrl'>
<div class="timer-container"></div>
<div class="controls">
<button
class='pvp ready'
onClick={() => sendInstanceQueue()}
type="submit">
PVP
</button>
{inviteBtn()}
<button
class='practice ready'
onClick={() => sendInstancePractice()}
type="submit">
Learn
</button>
<button
class='discord-btn'
onClick={() => window.open('https://discord.gg/YJJgurM') }>
&nbsp;
</button>
{discordBtn}
<div class="flex">
<button
class='practice ready'
onClick={() => sendInstancePractice()}
type="submit">
Learn
</button>
{inviteBtn()}
</div>
<AccountBox />
<div class="instance-ctrl-btns">
<button disabled={true} >Chat</button>
<button
class='pvp ready'
onClick={() => sendInstanceQueue()}
type="submit">
PVP
</button>
</div>
</div>
</aside>
);

View File

@ -71,9 +71,9 @@ function Play(args) {
};
const availableMtx = (item, i) => (
<figure key={i} onClick={() => mtxBuy(item)} >
<figcaption>{item.variant}</figcaption>
<button disabled={account.balance < item.credits}>¤{item.credits}</button>
<figure key={i}>
<figcaption>Enable {item.variant}</figcaption>
<button onClick={() => mtxBuy(item)} disabled={account.balance < item.credits}>¤{item.credits}</button>
</figure>
);

View File

@ -1,54 +1,89 @@
const { Component } = require('preact');
const preact = require('preact');
const idleAnimation = require('./anims/idle');
const wiggle = require('./anims/wiggle');
class Img extends Component {
constructor() {
super();
// The animation ids are a check to ensure that animations are not repeated
// When a new account animation is communicated with state it will have a corresponding Id
// which is a count of how many resoluttions have passed
this.animations = [];
this.resetAnimations = this.resetAnimations.bind(this);
}
render() {
const { id, img } = this.props;
const imgStyle = img
? { 'background-image': `url(/imgs/${img}.svg)` }
: null;
return (
<div
class="img avatar"
id={id}
onMouseDown={this.onClick.bind(this)}
style={imgStyle}>
</div>
);
}
onClick() {
if (this.props.mtxActive) {
return this.props.sendMtxAccountApply();
}
return this.animations.push(wiggle(this.props.id, this.idle));
}
componentDidMount() {
this.idle = idleAnimation(this.props.id);
return this.animations.push(this.idle);
}
resetAnimations() {
for (let i = this.animations.length - 1; i >= 0; i--) {
this.animations[i].reset();
}
}
componentWillUnmount() {
this.resetAnimations();
}
}
function Scoreboard(args) {
const {
isPlayer,
ready,
player,
leave,
} = args;
const scoreText = () => {
if (player.score === 'Zero') return '▫▫▫';
if (player.score === 'One') return '■▫▫';
if (player.score === 'Two') return '■■▫';
if (player.score === 'Win') return '■■■';
if (player.score === 'Zero' || player.score === 'Lose') return [<span i={0}></span>, <span i={1}></span>, <span i={2}></span>];
if (player.score === 'One') return [<span i={0}></span>, <span i={1}></span>, <span i={2}></span>];
if (player.score === 'Two') return [<span i={0}></span>, <span i={1}></span>, <span i={2}></span>];
if (player.score === 'Win') return [<span i={0}></span>, <span i={1}></span>, <span i={2}></span>];
return '';
};
/*
let scoreText = () => {
if (player.score === 'Zero') return '▫▫▫▫';
if (player.score === 'One') return '■▫▫▫';
if (player.score === 'Two') return '■■▫▫';
if (player.score === 'Three') return '■■■▫';
if (player.score === 'Adv') return '■■■+';
if (player.score === 'Win') return '■■■■';
return '';
};
*/
if (!isPlayer) {
return (
<div class={`player-box top ${player.ready ? 'ready' : ''}`}>
<div class="ctrl">&nbsp;</div>
<div></div>
<div class="score">{scoreText()}</div>
<div class="img">
<div>{player.name}</div>
</div>
<div class="name">{player.name}</div>
<Img img={player.img} id={player.id} />
<div class="msg">&nbsp;</div>
</div>
);
}
return (
<div class={`player-box bottom ${player.ready ? 'ready' : ''}`}>
<div class="msg">&nbsp;</div>
<div class="score">{scoreText()}</div>
<div class="img">
<div>{player.name}</div>
</div>
<div class="ctrl">
{leave ? <button onClick={leave}>Leave</button> : null}
</div>
<div class="name">{player.name}</div>
<Img img={player.img} id={player.id} />
</div>
);
}

View File

Before

Width:  |  Height:  |  Size: 7.0 KiB

After

Width:  |  Height:  |  Size: 7.0 KiB

View File

@ -1,177 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="800mm"
height="500mm"
viewBox="0 0 800 500"
version="1.1"
id="svg16"
inkscape:version="0.92.1 r15371"
sodipodi:docname="mnml.3.svg"
inkscape:export-filename="/home/ntr/notes/mnml/logo.0.png"
inkscape:export-xdpi="33.290001"
inkscape:export-ydpi="33.290001">
<defs
id="defs10" />
<sodipodi:namedview
id="base"
pagecolor="#000000"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="1"
inkscape:pageshadow="2"
inkscape:zoom="0.31458958"
inkscape:cx="339.43091"
inkscape:cy="1053.2018"
inkscape:document-units="mm"
inkscape:current-layer="g1085"
showgrid="false"
inkscape:snap-grids="false"
inkscape:window-width="2560"
inkscape:window-height="1417"
inkscape:window-x="0"
inkscape:window-y="23"
inkscape:window-maximized="0">
<inkscape:grid
type="xygrid"
id="grid18"
color="#ff453f"
opacity="0.1254902"
empcolor="#ff453f"
empopacity="0.25098039"
spacingx="13.229167"
spacingy="13.229167"
originx="-318.50419"
originy="-300.77664" />
</sodipodi:namedview>
<metadata
id="metadata13">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-318.50418,503.77662)">
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:202.02764893px;line-height:1.25;font-family:Jura;-inkscape-font-specification:'Jura, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#f5f5f5;fill-opacity:1;stroke:none;stroke-width:94.70045471;stroke-miterlimit:4;stroke-dasharray:none"
x="324.63995"
y="-321.57922"
id="text22"><tspan
sodipodi:role="line"
id="tspan20"
x="324.63995"
y="-321.57922"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:202.02764893px;font-family:Jura;-inkscape-font-specification:'Jura, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#f5f5f5;fill-opacity:1;stroke:none;stroke-width:94.70045471;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0">mnml.gg</tspan></text>
<g
id="g1085"
transform="translate(-3.5762787e-6,282.74713)">
<g
style="fill:none;stroke:#f5f5f5;stroke-width:5.92435312;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
transform="matrix(0.61133548,0,0,0.61133548,658.17325,-455.06409)"
id="g936">
<polygon
style="fill:none;stroke:#f5f5f5;stroke-width:5.92435312;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
points="190,190 10,190 100,10 "
id="polygon920" />
<polygon
style="fill:none;stroke:#f5f5f5;stroke-width:5.92435312;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
points="160,170 40,170 100,50 "
id="polygon922" />
<polygon
style="fill:none;stroke:#f5f5f5;stroke-width:5.92435312;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
points="130,150 70,150 100,90 "
id="polygon924" />
</g>
<g
style="fill:none;stroke:#f5f5f5;stroke-width:5.62481165;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
transform="matrix(0.62354979,0,0,0.62354979,333.74058,-457.40471)"
id="g986">
<rect
style="fill:none;stroke:#f5f5f5;stroke-width:5.62481165;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
x="10"
y="10"
width="180"
height="180"
id="rect970" />
<rect
style="fill:none;stroke:#f5f5f5;stroke-width:5.62481165;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
x="40"
y="40"
width="120"
height="120"
id="rect972" />
<rect
style="fill:none;stroke:#f5f5f5;stroke-width:5.62481165;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
x="70"
y="70"
width="60"
height="60"
id="rect974" />
</g>
<g
style="fill:none;stroke:#f5f5f5;stroke-width:5.62481165;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
transform="matrix(0.61285479,0,0,0.61285479,981.23264,-456.33521)"
id="g1136">
<circle
style="fill:none;stroke:#f5f5f5;stroke-width:5.62481165;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
r="30"
cx="100"
cy="100"
id="ellipse1120" />
<circle
style="fill:none;stroke:#f5f5f5;stroke-width:5.62481165;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
r="60"
cx="100"
cy="100"
id="ellipse1122" />
<circle
style="fill:none;stroke:#f5f5f5;stroke-width:5.62481165;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
r="90"
cx="100"
cy="100"
id="ellipse1124" />
</g>
<circle
style="fill:none;stroke:#a52a2a;stroke-width:4;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
r="22.942408"
cx="360.85284"
cy="-498.49799"
id="circle1125" />
<circle
id="circle1132"
cy="-498.49799"
cx="564.80573"
r="22.942408"
style="fill:none;stroke:#1ff01f;stroke-width:4;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<circle
style="fill:none;stroke:#3050f8;stroke-width:4;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
r="22.942408"
cx="768.75867"
cy="-498.49799"
id="circle1134" />
</g>
<path
style="fill:none;stroke:#f5f5fa;stroke-width:5.29166651;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 337.00836,-261.44316 h 476.24812 l 66.30344,66.30345 h 219.95898"
id="path1152"
inkscape:connector-curvature="0" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 7.1 KiB

View File

@ -1,177 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="800mm"
height="500mm"
viewBox="0 0 800 500"
version="1.1"
id="svg16"
inkscape:version="0.92.1 r15371"
sodipodi:docname="mnml.4.svg"
inkscape:export-filename="/home/ntr/Dropbox/mnml/mnml.4.png"
inkscape:export-xdpi="33.290001"
inkscape:export-ydpi="33.290001">
<defs
id="defs10" />
<sodipodi:namedview
id="base"
pagecolor="#000000"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="1"
inkscape:pageshadow="2"
inkscape:zoom="0.22244843"
inkscape:cx="763.22194"
inkscape:cy="952.76605"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:snap-grids="false"
inkscape:window-width="2560"
inkscape:window-height="1417"
inkscape:window-x="0"
inkscape:window-y="23"
inkscape:window-maximized="0">
<inkscape:grid
type="xygrid"
id="grid18"
color="#ff453f"
opacity="0.1254902"
empcolor="#ff453f"
empopacity="0.25098039"
spacingx="13.229167"
spacingy="13.229167"
originx="-318.50419"
originy="-300.77663" />
</sodipodi:namedview>
<metadata
id="metadata13">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-318.50418,503.77661)">
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:179.92054749px;line-height:1.25;font-family:Jura;-inkscape-font-specification:'Jura, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#f5f5f5;fill-opacity:1;stroke:none;stroke-width:84.3377533;stroke-miterlimit:4;stroke-dasharray:none"
x="366.74548"
y="-214.34631"
id="text22"><tspan
sodipodi:role="line"
id="tspan20"
x="366.74548"
y="-214.34631"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:179.92054749px;font-family:Jura;-inkscape-font-specification:'Jura, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#f5f5f5;fill-opacity:1;stroke:none;stroke-width:84.3377533;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0">mnml.gg</tspan></text>
<g
id="g936"
transform="matrix(0.54443942,0,0,0.54443942,664.50223,-143.74083)"
style="fill:none;stroke:#f5f5f5;stroke-width:5.92435312;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1">
<polygon
id="polygon920"
points="10,190 100,10 190,190 "
style="fill:none;stroke:#f5f5f5;stroke-width:5.92435312;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<polygon
id="polygon922"
points="40,170 100,50 160,170 "
style="fill:none;stroke:#f5f5f5;stroke-width:5.92435312;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<polygon
id="polygon924"
points="70,150 100,90 130,150 "
style="fill:none;stroke:#f5f5f5;stroke-width:5.92435312;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
</g>
<g
id="g986"
transform="matrix(0.55531716,0,0,0.55531716,375.75615,-145.82532)"
style="fill:none;stroke:#f5f5f5;stroke-width:5.62481165;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1">
<rect
id="rect970"
height="180"
width="180"
y="10"
x="10"
style="fill:none;stroke:#f5f5f5;stroke-width:5.62481165;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<rect
id="rect972"
height="120"
width="120"
y="40"
x="40"
style="fill:none;stroke:#f5f5f5;stroke-width:5.62481165;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<rect
id="rect974"
height="60"
width="60"
y="70"
x="70"
style="fill:none;stroke:#f5f5f5;stroke-width:5.62481165;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
</g>
<g
id="g1136"
transform="matrix(0.54579247,0,0,0.54579247,952.02526,-144.87285)"
style="fill:none;stroke:#f5f5f5;stroke-width:5.62481165;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1">
<circle
id="ellipse1120"
cy="100"
cx="100"
r="30"
style="fill:none;stroke:#f5f5f5;stroke-width:5.62481165;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<circle
id="ellipse1122"
cy="100"
cx="100"
r="60"
style="fill:none;stroke:#f5f5f5;stroke-width:5.62481165;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<circle
id="ellipse1124"
cy="100"
cx="100"
r="90"
style="fill:none;stroke:#f5f5f5;stroke-width:5.62481165;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
</g>
<g
id="g5700"
transform="translate(61.243363,-7.5514839)">
<circle
style="fill:none;stroke:#a52a2a;stroke-width:8.4862175;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
r="48.673557"
cx="371.42084"
cy="-408.40045"
id="circle1125" />
<circle
id="circle1132"
cy="-408.40045"
cx="657.2608"
r="48.673557"
style="fill:none;stroke:#1ff01f;stroke-width:8.48621655;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<circle
style="fill:none;stroke:#3050f8;stroke-width:8.48621559;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
r="48.673557"
cx="943.10077"
cy="-407.21103"
id="circle1134" />
</g>
<path
style="fill:none;stroke:#f5f5fa;stroke-width:5.29166651;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 334.62953,307.09686 h 476.24812 l 66.30344,66.30345 h 219.95901"
id="path1152"
inkscape:connector-curvature="0" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 6.9 KiB

View File

@ -1,191 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="1400mm"
height="1000mm"
viewBox="0 0 1400 999.99999"
version="1.1"
id="svg16"
inkscape:version="0.92.1 r15371"
sodipodi:docname="mnml.horizontal.svg"
inkscape:export-filename="/home/ntr/notes/mnml/logo.1.png"
inkscape:export-xdpi="33.290001"
inkscape:export-ydpi="33.290001">
<defs
id="defs10">
<font
horiz-adv-x="1024"
id="font1681"
inkscape:label="font 1"
horiz-origin-x="0"
horiz-origin-y="0"
vert-origin-x="45"
vert-origin-y="90"
vert-adv-y="90">
<font-face
units-per-em="1024"
id="font-face1683"
font-family="jura book" />
<missing-glyph
d="M0,0h1000v1024h-1000z"
id="missing-glyph1685" />
</font>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#000000"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="1"
inkscape:pageshadow="2"
inkscape:zoom="0.31538333"
inkscape:cx="2645.6693"
inkscape:cy="1889.7638"
inkscape:document-units="mm"
inkscape:current-layer="g1189"
showgrid="false"
inkscape:snap-grids="false"
inkscape:window-width="2560"
inkscape:window-height="1417"
inkscape:window-x="0"
inkscape:window-y="23"
inkscape:window-maximized="0"
inkscape:measure-start="2425.38,406.879"
inkscape:measure-end="1249.73,1603.74"
inkscape:snap-to-guides="false"
inkscape:snap-global="false">
<inkscape:grid
type="xygrid"
id="grid18"
color="#ff453f"
opacity="0.1254902"
empcolor="#ff453f"
empopacity="0.25098039"
spacingx="13.229167"
spacingy="13.229167"
originx="-309.61983"
originy="-380.09401" />
</sodipodi:namedview>
<metadata
id="metadata13">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-309.61979,1083.094)">
<g
id="g1189"
transform="translate(1.1156274,26.93094)">
<g
id="g931"
transform="translate(271.63304,-379.93571)">
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:202.02764893px;line-height:1.25;font-family:Jura;-inkscape-font-specification:'Jura, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#f5f5f5;fill-opacity:1;stroke:none;stroke-width:94.70045471;stroke-miterlimit:4;stroke-dasharray:none"
x="293.90451"
y="-223.2944"
id="text22"><tspan
dx="0 0 0 20"
sodipodi:role="line"
id="tspan20"
x="293.90451"
y="-223.2944"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:202.02764893px;font-family:Jura;-inkscape-font-specification:'Jura, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#f5f5f5;fill-opacity:1;stroke:none;stroke-width:94.70045471;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0">mnml.gg</tspan></text>
<g
transform="translate(884.80779)"
id="g913">
<g
style="fill:none;stroke:#f5f5f5;stroke-width:9.80856895;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
transform="matrix(0.27710921,0,0,0.27710921,225.5806,-256.1823)"
id="g936">
<polygon
style="fill:none;stroke:#f5f5f5;stroke-width:9.80856895;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
points="100,10 190,190 10,190 "
id="polygon920" />
<polygon
style="fill:none;stroke:#f5f5f5;stroke-width:9.80856895;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
points="100,50 160,170 40,170 "
id="polygon922" />
<polygon
style="fill:none;stroke:#f5f5f5;stroke-width:9.80856895;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
points="100,90 130,150 70,150 "
id="polygon924" />
</g>
<g
style="fill:none;stroke:#f5f5f5;stroke-width:9.61643505;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
transform="matrix(0.28264577,0,0,0.28264577,224.68531,-351.621)"
id="g986">
<rect
style="fill:none;stroke:#f5f5f5;stroke-width:9.61643505;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
x="10"
y="10"
width="180"
height="180"
id="rect970" />
<rect
style="fill:none;stroke:#f5f5f5;stroke-width:9.61643505;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
x="40"
y="40"
width="120"
height="120"
id="rect972" />
<rect
style="fill:none;stroke:#f5f5f5;stroke-width:9.61643505;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
x="70"
y="70"
width="60"
height="60"
id="rect974" />
</g>
<g
style="fill:none;stroke:#f5f5f5;stroke-width:9.78425312;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
transform="matrix(0.27779788,0,0,0.27779788,224.73379,-164.16552)"
id="g1136">
<circle
style="fill:none;stroke:#f5f5f5;stroke-width:9.78425312;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
r="30"
cx="100"
cy="100"
id="ellipse1120" />
<circle
style="fill:none;stroke:#f5f5f5;stroke-width:9.78425312;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
r="60"
cx="100"
cy="100"
id="ellipse1122" />
<circle
style="fill:none;stroke:#f5f5f5;stroke-width:9.78425312;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
r="90"
cx="100"
cy="100"
id="ellipse1124" />
</g>
</g>
<path
sodipodi:nodetypes="cccc"
style="fill:none;stroke:#f5f5fa;stroke-width:5.29166651;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 310.05649,-185.15011 h 476.24812 l 66.30344,66.3036 h 236.61075"
id="path1152"
inkscape:connector-curvature="0" />
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 7.5 KiB

View File

@ -1,98 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="800mm"
height="350mm"
viewBox="0 0 800 350"
version="1.1"
id="svg16"
inkscape:version="0.92.1 r15371"
sodipodi:docname="mnml.line.svg"
inkscape:export-filename="/home/ntr/notes/mnml/logo.0.png"
inkscape:export-xdpi="33.290001"
inkscape:export-ydpi="33.290001">
<defs
id="defs10" />
<sodipodi:namedview
id="base"
pagecolor="#000000"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="1"
inkscape:pageshadow="2"
inkscape:zoom="0.33139063"
inkscape:cx="934.2462"
inkscape:cy="720.22548"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:snap-grids="false"
inkscape:window-width="2560"
inkscape:window-height="1417"
inkscape:window-x="0"
inkscape:window-y="23"
inkscape:window-maximized="0"
inkscape:showpageshadow="false"
showborder="true">
<inkscape:grid
type="xygrid"
id="grid18"
color="#ff453f"
opacity="0.1254902"
empcolor="#ff453f"
empopacity="0.25098039"
spacingx="13.229167"
spacingy="13.229167"
originx="-337.00838"
originy="-489.49389" />
</sodipodi:namedview>
<metadata
id="metadata13">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-337.00836,542.49388)">
<g
id="g1085"
transform="translate(-3.5762787e-6,282.74713)" />
<g
id="g1701"
transform="translate(1.5e-5,-47.027751)">
<text
id="text22"
y="-321.57922"
x="342.0285"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:202.02764893px;line-height:1.25;font-family:Jura;-inkscape-font-specification:'Jura, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#f5f5f5;fill-opacity:1;stroke:none;stroke-width:94.70045471;stroke-miterlimit:4;stroke-dasharray:none"
xml:space="preserve"><tspan
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:202.02764893px;font-family:Jura;-inkscape-font-specification:'Jura, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#f5f5f5;fill-opacity:1;stroke:none;stroke-width:94.70045471;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0"
y="-321.57922"
x="342.0285"
id="tspan20"
sodipodi:role="line">mnml.gg</tspan></text>
<path
inkscape:connector-curvature="0"
id="path1152"
d="m 355.75309,-261.44316 h 476.24812 l 66.30344,66.30345 h 219.95895"
style="fill:none;stroke:#f5f5fa;stroke-width:5.29166651;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 3.8 KiB

View File

@ -1,181 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="800mm"
height="800mm"
viewBox="0 0 800 800"
version="1.1"
id="svg16"
inkscape:version="0.92.1 r15371"
sodipodi:docname="mnml.plain.svg"
inkscape:export-filename="/home/ntr/Dropbox/mnml/mnml.discord.png"
inkscape:export-xdpi="33.290001"
inkscape:export-ydpi="33.290001">
<defs
id="defs10" />
<sodipodi:namedview
id="base"
pagecolor="#000000"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="1"
inkscape:pageshadow="2"
inkscape:zoom="0.22244843"
inkscape:cx="814.91932"
inkscape:cy="952.76605"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:snap-grids="false"
inkscape:window-width="2560"
inkscape:window-height="1417"
inkscape:window-x="0"
inkscape:window-y="23"
inkscape:window-maximized="0">
<inkscape:grid
type="xygrid"
id="grid18"
color="#ff453f"
opacity="0.1254902"
empcolor="#ff453f"
empopacity="0.25098039"
spacingx="13.229167"
spacingy="13.229167"
originx="-318.50419"
originy="-300.77663" />
</sodipodi:namedview>
<metadata
id="metadata13">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-318.50418,803.77661)">
<g
id="g5786"
transform="translate(-7.5725212e-6,-150)">
<text
id="text22"
y="-214.34631"
x="366.74548"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:179.92054749px;line-height:1.25;font-family:Jura;-inkscape-font-specification:'Jura, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#f5f5f5;fill-opacity:1;stroke:none;stroke-width:84.3377533;stroke-miterlimit:4;stroke-dasharray:none"
xml:space="preserve"><tspan
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:179.92054749px;font-family:Jura;-inkscape-font-specification:'Jura, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#f5f5f5;fill-opacity:1;stroke:none;stroke-width:84.3377533;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0"
y="-214.34631"
x="366.74548"
id="tspan20"
sodipodi:role="line">mnml.gg</tspan></text>
<g
style="fill:none;stroke:#f5f5f5;stroke-width:5.92435312;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
transform="matrix(0.54443942,0,0,0.54443942,664.50223,-143.74083)"
id="g936">
<polygon
style="fill:none;stroke:#f5f5f5;stroke-width:5.92435312;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
points="100,10 190,190 10,190 "
id="polygon920" />
<polygon
style="fill:none;stroke:#f5f5f5;stroke-width:5.92435312;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
points="100,50 160,170 40,170 "
id="polygon922" />
<polygon
style="fill:none;stroke:#f5f5f5;stroke-width:5.92435312;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
points="100,90 130,150 70,150 "
id="polygon924" />
</g>
<g
style="fill:none;stroke:#f5f5f5;stroke-width:5.62481165;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
transform="matrix(0.55531716,0,0,0.55531716,375.75615,-145.82532)"
id="g986">
<rect
style="fill:none;stroke:#f5f5f5;stroke-width:5.62481165;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
x="10"
y="10"
width="180"
height="180"
id="rect970" />
<rect
style="fill:none;stroke:#f5f5f5;stroke-width:5.62481165;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
x="40"
y="40"
width="120"
height="120"
id="rect972" />
<rect
style="fill:none;stroke:#f5f5f5;stroke-width:5.62481165;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
x="70"
y="70"
width="60"
height="60"
id="rect974" />
</g>
<g
style="fill:none;stroke:#f5f5f5;stroke-width:5.62481165;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
transform="matrix(0.54579247,0,0,0.54579247,952.02526,-144.87285)"
id="g1136">
<circle
style="fill:none;stroke:#f5f5f5;stroke-width:5.62481165;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
r="30"
cx="100"
cy="100"
id="ellipse1120" />
<circle
style="fill:none;stroke:#f5f5f5;stroke-width:5.62481165;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
r="60"
cx="100"
cy="100"
id="ellipse1122" />
<circle
style="fill:none;stroke:#f5f5f5;stroke-width:5.62481165;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
r="90"
cx="100"
cy="100"
id="ellipse1124" />
</g>
<g
transform="translate(61.243363,-7.5514839)"
id="g5700">
<circle
id="circle1125"
cy="-408.40045"
cx="371.42084"
r="48.673557"
style="fill:none;stroke:#a52a2a;stroke-width:8.4862175;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<circle
style="fill:none;stroke:#1ff01f;stroke-width:8.48621655;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
r="48.673557"
cx="657.2608"
cy="-408.40045"
id="circle1132" />
<circle
id="circle1134"
cy="-407.21103"
cx="943.10077"
r="48.673557"
style="fill:none;stroke:#3050f8;stroke-width:8.48621559;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
</g>
</g>
<path
style="fill:none;stroke:#f5f5fa;stroke-width:5.29166651;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 334.62953,307.09686 h 476.24812 l 66.30344,66.30345 h 219.95901"
id="path1152"
inkscape:connector-curvature="0" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 7.2 KiB

View File

@ -1,190 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="800mm"
height="500mm"
viewBox="0 0 800 500"
version="1.1"
id="svg16"
inkscape:version="0.92.1 r15371"
sodipodi:docname="mnml.svg"
inkscape:export-filename="/home/ntr/notes/mnml/logo.0.png"
inkscape:export-xdpi="33.290001"
inkscape:export-ydpi="33.290001">
<defs
id="defs10" />
<sodipodi:namedview
id="base"
pagecolor="#000000"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="1"
inkscape:pageshadow="2"
inkscape:zoom="0.31458958"
inkscape:cx="494.17573"
inkscape:cy="535.02564"
inkscape:document-units="mm"
inkscape:current-layer="g1189"
showgrid="true"
inkscape:snap-grids="false"
inkscape:window-width="2560"
inkscape:window-height="1417"
inkscape:window-x="0"
inkscape:window-y="23"
inkscape:window-maximized="0">
<inkscape:grid
type="xygrid"
id="grid18"
color="#ff453f"
opacity="0.1254902"
empcolor="#ff453f"
empopacity="0.25098039"
spacingx="13.229167"
spacingy="13.229167"
originx="-318.50419"
originy="-300.77664" />
</sodipodi:namedview>
<metadata
id="metadata13">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-318.50418,503.77662)">
<g
id="g1189"
transform="translate(1.1156274,26.93094)">
<g
id="g1010"
transform="translate(18.50418,-50.77662)">
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:202.02764893px;line-height:1.25;font-family:Jura;-inkscape-font-specification:'Jura, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#f5f5f5;fill-opacity:1;stroke:none;stroke-width:94.70045471;stroke-miterlimit:4;stroke-dasharray:none"
x="305.02014"
y="-159.79291"
id="text22"><tspan
sodipodi:role="line"
id="tspan20"
x="305.02014"
y="-159.79291"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:202.02764893px;font-family:Jura;-inkscape-font-specification:'Jura, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#f5f5f5;fill-opacity:1;stroke:none;stroke-width:94.70045471;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0">mnml.gg</tspan></text>
<g
id="g1150"
transform="translate(0,-13.758336)">
<g
style="fill:none;stroke:#f5f5f5;stroke-width:5.92435312;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
transform="matrix(0.61133548,0,0,0.61133548,638.55344,-417.46007)"
id="g936">
<polygon
style="fill:none;stroke:#f5f5f5;stroke-width:5.92435312;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
points="10,190 100,10 190,190 "
id="polygon920" />
<polygon
style="fill:none;stroke:#f5f5f5;stroke-width:5.92435312;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
points="40,170 100,50 160,170 "
id="polygon922" />
<polygon
style="fill:none;stroke:#f5f5f5;stroke-width:5.92435312;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
points="70,150 100,90 130,150 "
id="polygon924" />
</g>
<g
style="fill:none;stroke:#f5f5f5;stroke-width:5.62481165;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
transform="matrix(0.62354979,0,0,0.62354979,314.12077,-419.80069)"
id="g986">
<rect
style="fill:none;stroke:#f5f5f5;stroke-width:5.62481165;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
x="10"
y="10"
width="180"
height="180"
id="rect970" />
<rect
style="fill:none;stroke:#f5f5f5;stroke-width:5.62481165;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
x="40"
y="40"
width="120"
height="120"
id="rect972" />
<rect
style="fill:none;stroke:#f5f5f5;stroke-width:5.62481165;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
x="70"
y="70"
width="60"
height="60"
id="rect974" />
</g>
<g
style="fill:none;stroke:#f5f5f5;stroke-width:5.62481165;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
transform="matrix(0.61285479,0,0,0.61285479,961.61283,-418.73119)"
id="g1136">
<circle
style="fill:none;stroke:#f5f5f5;stroke-width:5.62481165;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
r="30"
cx="100"
cy="100"
id="ellipse1120" />
<circle
style="fill:none;stroke:#f5f5f5;stroke-width:5.62481165;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
r="60"
cx="100"
cy="100"
id="ellipse1122" />
<circle
style="fill:none;stroke:#f5f5f5;stroke-width:5.62481165;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
r="90"
cx="100"
cy="100"
id="ellipse1124" />
</g>
<flowRoot
transform="matrix(0.26458333,0,0,0.26458333,-1.1156274,-716.1726)"
style="font-style:normal;font-weight:normal;font-size:40px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"
id="flowRoot1191"
xml:space="preserve"><flowRegion
id="flowRegion1193"><rect
y="2484.8455"
x="1209.269"
height="507.98291"
width="2396.061"
id="rect1195" /></flowRegion><flowPara
style="fill:#f00000;fill-opacity:0;stroke:none;stroke-opacity:1"
id="flowPara1197">abstract strategy</flowPara></flowRoot> <text
id="text1201"
y="-36.125034"
x="455.61945"
style="font-style:normal;font-weight:normal;font-size:10.58333302px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332"
xml:space="preserve"><tspan
style="stroke-width:0.26458332"
y="-36.125034"
x="455.61945"
id="tspan1199"
sodipodi:role="line">v</tspan></text>
</g>
<path
style="fill:none;stroke:#f5f5fa;stroke-width:5.29166651;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 317.38855,-99.656848 h 476.24812 l 66.30344,66.303445 h 219.95899"
id="path1152"
inkscape:connector-curvature="0" />
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 8.1 KiB

View File

@ -150,6 +150,10 @@ function createSocket(events) {
}
}
function sendMtxAccountApply(mtx) {
send(['MtxAccountApply', { mtx }]);
}
function sendMtxBuy(mtx) {
send(['MtxBuy', { mtx }]);
}
@ -368,6 +372,7 @@ function createSocket(events) {
sendSubscriptionState,
sendSubscriptionEnding,
sendMtxAccountApply,
sendMtxApply,
sendMtxBuy,
sendMtxConstructSpawn,

View File

@ -0,0 +1,11 @@
const uuidv4 = require('uuid/v4');
// give everybody the shapes mtx
exports.up = async knex => {
await knex.raw(`
ALTER TABLE accounts
ADD COLUMN img UUID DEFAULT uuid_generate_v4();
`);
};
exports.down = async () => {};

View File

@ -1,6 +1,6 @@
{
"name": "mnml-ops",
"version": "1.4.8",
"version": "1.5.0",
"description": "",
"main": "index.js",
"scripts": {

View File

@ -1,6 +1,6 @@
[package]
name = "mnml"
version = "1.4.8"
version = "1.5.0"
authors = ["ntr <ntr@smokestack.io>"]
[dependencies]

View File

@ -14,6 +14,7 @@ use construct::{Construct, ConstructSkeleton, construct_spawn};
use instance::{Instance, instance_delete};
use mtx::{Mtx, FREE_MTX};
use pg::Db;
use img;
use failure::Error;
@ -24,6 +25,7 @@ static PASSWORD_MIN_LEN: usize = 11;
#[derive(Debug,Clone,Serialize,Deserialize)]
pub struct Account {
pub id: Uuid,
pub img: Uuid,
pub name: String,
pub balance: u32,
pub subscribed: bool,
@ -34,6 +36,7 @@ impl<'a> TryFrom<postgres::rows::Row<'a>> for Account {
fn try_from(row: postgres::rows::Row) -> Result<Self, Error> {
let id: Uuid = row.get("id");
let img: Uuid = row.get("img");
let db_balance: i64 = row.get("balance");
let balance = u32::try_from(db_balance)
@ -42,13 +45,13 @@ impl<'a> TryFrom<postgres::rows::Row<'a>> for Account {
let subscribed: bool = row.get("subscribed");
let name: String = row.get("name");
Ok(Account { id, name, balance, subscribed })
Ok(Account { id, name, balance, subscribed, img })
}
}
pub fn select(db: &Db, id: Uuid) -> Result<Account, Error> {
let query = "
SELECT id, name, balance, subscribed
SELECT id, name, balance, subscribed, img
FROM accounts
WHERE id = $1;
";
@ -64,7 +67,7 @@ pub fn select(db: &Db, id: Uuid) -> Result<Account, Error> {
pub fn select_name(db: &Db, name: &String) -> Result<Account, Error> {
let query = "
SELECT id, name, balance, subscribed
SELECT id, name, balance, subscribed, img
FROM accounts
WHERE name = $1;
";
@ -80,7 +83,7 @@ pub fn select_name(db: &Db, name: &String) -> Result<Account, Error> {
pub fn from_token(db: &Db, token: &String) -> Result<Account, Error> {
let query = "
SELECT id, name, subscribed, balance
SELECT id, name, balance, subscribed, img
FROM accounts
WHERE token = $1
AND token_expiry > now();
@ -97,7 +100,7 @@ pub fn from_token(db: &Db, token: &String) -> Result<Account, Error> {
pub fn login(tx: &mut Transaction, name: &String, password: &String) -> Result<Account, MnmlHttpError> {
let query = "
SELECT id, password, name, balance, subscribed
SELECT id, password, name, balance, subscribed, img
FROM accounts
WHERE name = $1
";
@ -125,8 +128,10 @@ pub fn login(tx: &mut Transaction, name: &String, password: &String) -> Result<A
return Err(MnmlHttpError::PasswordNotMatch);
}
Account::try_from(row)
.or(Err(MnmlHttpError::ServerError))
let account = Account::try_from(row)
.or(Err(MnmlHttpError::ServerError))?;
Ok(account)
}
pub fn new_token(tx: &mut Transaction, id: Uuid) -> Result<String, MnmlHttpError> {
@ -153,6 +158,23 @@ pub fn new_token(tx: &mut Transaction, id: Uuid) -> Result<String, MnmlHttpError
Ok(token)
}
pub fn new_img(tx: &mut Transaction, id: Uuid) -> Result<Account, Error> {
let query = "
UPDATE accounts
SET img = $1, updated_at = now()
WHERE id = $2
RETURNING id, password, name, balance, subscribed, img
";
let result = tx
.query(query, &[&Uuid::new_v4(), &id])?;
let row = result.iter().next()
.ok_or(format_err!("account not updated {:?}", id))?;
Account::try_from(row)
}
pub fn set_password(tx: &mut Transaction, id: Uuid, current: &String, password: &String) -> Result<String, MnmlHttpError> {
if password.len() < PASSWORD_MIN_LEN {
return Err(MnmlHttpError::PasswordUnacceptable);
@ -246,7 +268,7 @@ pub fn debit(tx: &mut Transaction, id: Uuid, debit: i64) -> Result<Account, Erro
UPDATE accounts
SET balance = balance - $1
WHERE id = $2
RETURNING id, name, balance, subscribed
RETURNING id, password, name, balance, subscribed, img
";
let result = tx
@ -256,15 +278,9 @@ pub fn debit(tx: &mut Transaction, id: Uuid, debit: i64) -> Result<Account, Erro
let row = result.iter().next()
.ok_or(format_err!("account not found {:?}", id))?;
let name: String = row.get(1);
let db_balance: i64 = row.get(2);
let balance = u32::try_from(db_balance)
.or(Err(format_err!("user {:?} has unparsable balance {:?}", id, db_balance)))?;
let subscribed: bool = row.get(3);
info!("account debited name={:?} debited={:?} balance={:?}", name, debit, balance);
Ok(Account { id, name: row.get(1), balance, subscribed })
let account = Account::try_from(row)?;
info!("account debited name={:?} debited={:?} balance={:?}", account.name, debit, account.balance);
Ok(account)
}
pub fn set_subscribed(tx: &mut Transaction, id: Uuid, subscribed: bool) -> Result<String, Error> {
@ -298,6 +314,7 @@ pub fn create(name: &String, password: &String, tx: &mut Transaction) -> Result<
}
let id = Uuid::new_v4();
let img = Uuid::new_v4();
let rounds = 8;
let password = hash(&password, rounds)?;
@ -308,13 +325,13 @@ pub fn create(name: &String, password: &String, tx: &mut Transaction) -> Result<
.collect();
let query = "
INSERT INTO accounts (id, name, password, token, token_expiry)
VALUES ($1, $2, $3, $4, now() + interval '1 week')
INSERT INTO accounts (id, name, password, token, token_expiry, img)
VALUES ($1, $2, $3, $4, now() + interval '1 week', $5)
RETURNING id, name;
";
let result = tx
.query(query, &[&id, &name, &password, &token])?;
.query(query, &[&id, &name, &password, &token, &img])?;
match result.iter().next() {
Some(row) => row,
@ -331,6 +348,8 @@ pub fn create(name: &String, password: &String, tx: &mut Transaction) -> Result<
.insert(tx)?;
}
img::shapes_write(img)?;
info!("registration account={:?}", name);
Ok(token)
@ -458,3 +477,15 @@ pub fn account_instances(tx: &mut Transaction, account: &Account) -> Result<Vec<
return Ok(list);
}
// all accounts have an image id but the img
// doesn't necessarily exist until they subscribe
pub fn img_check(account: &Account) -> Result<Uuid, Error> {
match account.subscribed {
true => match img::exists(account.img) {
true => Ok(account.img),
false => img::shapes_write(account.img)
},
false => Ok(account.img),
}
}

View File

@ -257,6 +257,10 @@ fn _hieroglyph() -> String {
return s;
}
pub fn exists(id: Uuid) -> bool {
std::path::Path::new(&format!("/var/lib/mnml/public/imgs/{}.svg", id)).exists()
}
#[cfg(test)]
mod tests {
use super::*;

View File

@ -719,8 +719,7 @@ pub fn instance_practice(tx: &mut Transaction, account: &Account) -> Result<Inst
.set_time_control(TimeControl::Practice)
.set_name(bot.name.clone())?;
let constructs = account::team(tx, account)?;
let player = Player::new(account.id, &account.name, constructs);
let player = Player::from_account(tx, account)?;
instance.add_player(player.clone())?;
instance.add_player(bot)?;
@ -740,8 +739,8 @@ pub fn pvp(tx: &mut Transaction, a: &Account, b: &Account) -> Result<Instance, E
instance = instance_create(tx, instance)?;
for account in [a, b].iter() {
let constructs = account::team(tx, account)?;
let player = player_create(tx, Player::new(account.id, &account.name, constructs), instance.id, account)?;
let acc_p = Player::from_account(tx, &account)?;
let player = player_create(tx, acc_p, instance.id, account)?;
instance.add_player(player)?;
}

View File

@ -167,6 +167,26 @@ pub fn apply(tx: &mut Transaction, account: &Account, variant: MtxVariant, const
account::team(tx, account)
}
pub fn account_apply(tx: &mut Transaction, account: &Account, variant: MtxVariant) -> Result<Account, Error> {
let mtx = select(tx, variant, account.id)?;
let cost = match mtx.variant {
MtxVariant::Rename => return Err(err_msg("rename not usable on account")),
_ => NEW_IMAGE_COST,
};
account::debit(tx, account.id, cost)?;
let account = account::new_img(tx, account.id)?;
match mtx.variant {
MtxVariant::Invader => img::invader_write(account.img)?,
MtxVariant::Molecular => img::molecular_write(account.img)?,
MtxVariant::Shapes => img::shapes_write(account.img)?,
_ => account.img,
};
Ok(account)
}
pub fn select(tx: &mut Transaction, variant: MtxVariant, account: Uuid) -> Result<Mtx, Error> {
let query = "
SELECT id, account, variant

View File

@ -6,6 +6,7 @@ use postgres::transaction::Transaction;
use failure::Error;
use failure::err_msg;
use account;
use account::Account;
use construct::{Construct, Colours};
use vbox::{Vbox};
@ -39,7 +40,7 @@ impl Score {
// _ => Score::Win,
// }
// Score::Adv => Score::Win,
_ => panic!("faulty score increment {:?}", self),
}
}
@ -56,6 +57,7 @@ impl Score {
#[derive(Debug,Clone,Serialize,Deserialize)]
pub struct Player {
pub id: Uuid,
pub img: Option<Uuid>,
pub name: String,
pub vbox: Vbox,
pub constructs: Vec<Construct>,
@ -66,9 +68,31 @@ pub struct Player {
}
impl Player {
pub fn from_account(tx: &mut Transaction, account: &Account) -> Result<Player, Error> {
let constructs = account::team(tx, account)?;
let img = match account.subscribed {
true => Some(account.img),
false => None,
};
Ok(Player {
id: account.id,
img,
name: account.name.clone(),
vbox: Vbox::new(),
constructs,
bot: false,
ready: false,
warnings: 0,
score: Score::Zero,
})
}
pub fn new(account: Uuid, name: &String, constructs: Vec<Construct>) -> Player {
Player {
id: account,
img: Some(account),
name: name.clone(),
vbox: Vbox::new(),
constructs,
@ -379,7 +403,7 @@ mod tests {
player.score = player.score.add_win(&Score::Zero);
player.score = player.score.add_win(&Score::Zero);
assert_eq!(player.score, Score::Win); // 40 / 0
// Bo7 tennis scoring
/*assert_eq!(player.score, Score::Three); // 40 / 0

View File

@ -230,6 +230,9 @@ impl Connection {
RpcRequest::MtxConstructApply { mtx, construct_id, name } =>
Ok(RpcMessage::AccountTeam(mtx::apply(&mut tx, account, mtx, construct_id, name)?)),
RpcRequest::MtxAccountApply { mtx } =>
Ok(RpcMessage::AccountState(mtx::account_apply(&mut tx, account, mtx)?)),
RpcRequest::MtxBuy { mtx } =>
Ok(RpcMessage::AccountShop(mtx::buy(&mut tx, account, mtx)?)),
@ -272,6 +275,9 @@ impl Handler for Connection {
self.ws.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
account::img_check(&a).unwrap();
let db = self.pool.get().unwrap();
let mut tx = db.transaction().unwrap();

View File

@ -1238,9 +1238,6 @@ impl Skill {
Skill::Reflect|
Skill::ReflectPlus |
Skill::ReflectPlusPlus |
Skill::Link|
Skill::LinkPlus |
Skill::LinkPlusPlus |
Skill::Triage|
Skill::TriagePlus |
Skill::TriagePlusPlus => true,