Implemented ladders

This commit is contained in:
2019-05-24 13:00:27 +10:00
parent 683ab95d63
commit 1ad4a14b35
7 changed files with 163 additions and 3 deletions
+2 -1
View File
@@ -12,7 +12,8 @@ let excluded = [ //messages that should not be logged
'Not enough scientists', 'Not enough scientists',
'Not enough time has passed', 'Not enough time has passed',
'Profile sent' 'Profile sent',
'Ladder sent'
]; ];
const log = (msg, ...args) => { const log = (msg, ...args) => {
+1 -1
View File
@@ -198,7 +198,7 @@ footer {
} }
} }
/* profile page */ /* flexbox tables */
.table { .table {
flex: 1; flex: 1;
display: flex; display: flex;
+1
View File
@@ -37,6 +37,7 @@ app.post('/profilerequest', profiles.profileRequest(connection));
app.post('/recruit', profiles.recruit(connection)); app.post('/recruit', profiles.recruit(connection));
app.post('/train', profiles.train(connection)); app.post('/train', profiles.train(connection));
app.post('/untrain', profiles.untrain(connection)); app.post('/untrain', profiles.untrain(connection));
app.post('/ladderrequest', profiles.ladderRequest(connection));
profiles.runGoldTick(connection); profiles.runGoldTick(connection);
//static directories //static directories
+12 -1
View File
@@ -356,6 +356,16 @@ const untrain = (connection) => (req, res) => {
}); });
} }
const ladderRequest = (connection) => (req, res) => {
let query = 'SELECT username, soldiers, recruits, gold FROM accounts JOIN profiles ON accounts.id = profiles.accountId ORDER BY soldiers DESC, recruits DESC, gold DESC LIMIT ?, ?;';
connection.query(query, [req.body.start, req.body.length], (err, results) => {
if (err) throw err;
res.status(200).json(results);
log('Ladder sent', req.body.start, req.body.length, results);
});
}
const runGoldTick = (connection) => { const runGoldTick = (connection) => {
let goldTickJob = new CronJob('0 */30 * * * *', () => { let goldTickJob = new CronJob('0 */30 * * * *', () => {
let query = 'UPDATE profiles SET gold = gold + recruits;'; let query = 'UPDATE profiles SET gold = gold + recruits;';
@@ -375,5 +385,6 @@ module.exports = {
recruit: recruit, recruit: recruit,
train: train, train: train,
untrain: untrain, untrain: untrain,
runGoldTick: runGoldTick runGoldTick: runGoldTick,
ladderRequest: ladderRequest
} }
+2
View File
@@ -4,6 +4,7 @@ import { BrowserRouter, Switch, Route } from 'react-router-dom';
//include pages //include pages
import Home from './pages/home.jsx'; import Home from './pages/home.jsx';
import Profile from './pages/profile.jsx'; import Profile from './pages/profile.jsx';
import Ladder from './pages/ladder.jsx';
import PasswordReset from './pages/password_reset.jsx' import PasswordReset from './pages/password_reset.jsx'
import PageNotFound from './pages/page_not_found.jsx'; import PageNotFound from './pages/page_not_found.jsx';
@@ -23,6 +24,7 @@ export default class App extends React.Component {
<Switch> <Switch>
<Route exact path='/' component={Home} /> <Route exact path='/' component={Home} />
<Route path='/profile' component={Profile} /> <Route path='/profile' component={Profile} />
<Route path='/ladder' component={Ladder} />
<Route path='/passwordreset' component={PasswordReset} /> <Route path='/passwordreset' component={PasswordReset} />
<Route path='*' component={PageNotFound} /> <Route path='*' component={PageNotFound} />
</Switch> </Switch>
+79
View File
@@ -0,0 +1,79 @@
import React from 'react';
import CommonLinks from '../panels/common_links.jsx';
import PagedLadder from '../panels/paged_ladder.jsx';
class Ladder extends React.Component {
constructor(props) {
super(props);
this.state = {
start: 0,
length: 50,
fetch: null
};
}
componentDidUpdate() {
this.state.fetch();
}
render() {
let ButtonHeader = this.buttonHeader.bind(this);
return (
<div className='page'>
<h1 style={{textAlign: 'center', fontSize: '50px', margin: '30px'}}>KINGDOM BATTLES!</h1>
<div className='sidePanelPage'>
<div className='sidePanel'>
<CommonLinks />
</div>
<div className='mainPanel'>
<ButtonHeader />
<PagedLadder start={this.state.start} length={this.state.length} getFetch={this.getFetch.bind(this)} onReceived={this.onReceived.bind(this)} />
<ButtonHeader />
</div>
</div>
</div>
);
}
buttonHeader() {
return (
<div className='table'>
<div className='row'>
<button className='col' onClick={this.decrement.bind(this)}>{'< Back'}</button>
<div className='col' />
<div className='col' />
<button className='col' onClick={this.increment.bind(this)}>{'Next >'}</button>
</div>
</div>
);
}
increment() {
this.setState({
start: this.state.start + this.state.length
});
}
decrement() {
this.setState({
start: Math.max(0, this.state.start - this.state.length)
});
}
//bound callbacks
getFetch(fn) {
this.setState({ fetch: fn });
}
onReceived(data) {
if (data.length === 0) {
this.decrement();
}
}
}
export default Ladder;
+66
View File
@@ -0,0 +1,66 @@
import React from 'react';
import { withRouter, Link } from 'react-router-dom';
import PropTypes from 'prop-types';
class PagedLadder extends React.Component {
constructor(props) {
super(props);
this.state = {
data: {}
}
if (props.getFetch) {
props.getFetch(this.fetchLadder.bind(this));
}
this.fetchLadder();
}
render() {
return (
<div className='table'>
<div className='row'>
<p className='col'>Username</p>
<p className='col'>Soldiers</p>
<p className='col'>Recruits</p>
<p className='col'>Gold</p>
</div>
{Object.keys(this.state.data).map((key) => <div key={key} className={'row'}> <Link to={`/profile?username=${this.state.data[key].username}`} className={'col'}>{this.state.data[key].username}</Link><p className={'col'}>{this.state.data[key].soldiers}</p><p className={'col'}>{this.state.data[key].recruits}</p><p className={'col'}>{this.state.data[key].gold}</p><hr /></div> )}
</div>
);
}
fetchLadder(start = this.props.start, length = this.props.length) {
//build the XHR
let xhr = new XMLHttpRequest();
xhr.onreadystatechange = () => {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
let data = JSON.parse(xhr.responseText);
this.setState({data: data});
if (this.props.onReceived) {
this.props.onReceived(data);
}
}
}
}
xhr.open('POST', '/ladderrequest', true);
xhr.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
xhr.send(JSON.stringify({
start: start,
length: length
}));
}
}
PagedLadder.propTypes = {
start: PropTypes.number.isRequired,
length: PropTypes.number.isRequired,
getFetch: PropTypes.func,
onReceived: PropTypes.func
};
export default withRouter(PagedLadder);