Added server and map votes

This commit is contained in:
Chris Blanchard 2015-07-29 14:50:39 +01:00
parent 673402ed26
commit 934b707434
11 changed files with 405 additions and 29 deletions

16
config/data/maps.json Normal file
View file

@ -0,0 +1,16 @@
{
"maps": [
{"id": 1, "name" : "ns2_veil"},
{"id": 2, "name" : "ns2_tram"},
{"id": 3, "name" : "ns2_summit"},
{"id": 4, "name" : "ns2_prison"},
{"id": 5, "name" : "ns2_nexus"},
{"id": 6, "name" : "ns2_mineral"},
{"id": 7, "name" : "ns2_jambi"},
{"id": 8, "name" : "ns2_fracture"},
{"id": 9, "name" : "ns2_docking2"},
{"id": 10, "name" : "ns2_descent"},
{"id": 11, "name" : "ns2_caged"},
{"id": 12, "name" : "ns2_biodome"}
]
}

58
config/data/servers.json Normal file
View file

@ -0,0 +1,58 @@
{
"servers":[
{
"id":102,
"name":"Wraith::NSL::Amsterdam#1",
"description":"OwnerisFurs",
"ip":"89.105.209.250",
"dns":"89.105.209.250",
"port":27020,
"password":"ns2nsl"
},
{
"id":103,
"name":"NSLMatch-London#2",
"description":"OwnerisUWE",
"ip":"85.236.102.73",
"dns":"85.236.102.73",
"port":27215,
"password":"ns2nsl"
},
{
"id":104,
"name":"NSLMatch-Paris[NS2FR.com]",
"description":"OwnerisMGS AdminisSephy",
"ip":"62.210.206.58",
"dns":"62.210.206.58",
"port":27023,
"password":"ns2nsl"
},
{
"id":106,
"name":"r/ns2pugs#3::Toronto",
"description":"OwnerisKaneh",
"ip":"158.85.65.172",
"dns":"158.85.65.172",
"port":27017,
"password":"pug"
},
{
"id":107,
"name":"r/ns2pugs#1::Dallas",
"description":"OwnerisKaneh",
"ip":"50.91.73.146",
"dns":"50.91.73.146",
"port":27015,
"password":"pug"
},
{
"id":109,
"name":"NSLMatch-NJ USA-(loMe's)",
"description":"loMeisOwner",
"ip":"107.191.36.140",
"dns":"107.191.36.140",
"port":40000,
"password":"ns2nsl"
}
]
}

View file

@ -11,14 +11,20 @@
* Client API
* gather:join - Assigns user to gather
* gather:vote - Assigns vote to map, leader or server
* gather:leave - Leave gather
* gather:select - Select player for team
* gather:select:confirm - Confirm selected team
* gather:refresh - Refresh gather for client
*
*/
var Map = require("./map");
var Server = require("./server");
var Gather = require("./gather");
var gather = new Gather();
// ***** Generate Test Users *****
var helper = require("./helper");
// var helper = require("./helper");
// helper.createTestUsers({ gather: gather });
module.exports = function (namespace) {
@ -26,7 +32,9 @@ module.exports = function (namespace) {
namespace.sockets.forEach(function (socket) {
socket.emit("gather:refresh", {
gather: gather.toJson(),
currentGatherer: gather.getGatherer(socket._user)
currentGatherer: gather.getGatherer(socket._user),
maps: Map.list,
servers: Server.list
});
});
};
@ -93,6 +101,15 @@ module.exports = function (namespace) {
if (data.leader) {
gather.selectLeader(socket._user, data.leader.candidate);
}
if (data.map) {
gather.voteForMap(socket._user, data.map.id);
}
if (data.server) {
gather.voteForServer(socket._user, data.server.id);
}
refreshGather();
});

View file

@ -141,6 +141,22 @@ Gather.prototype.toJson = function () {
}
};
Gather.prototype.voteForMap = function (voter, mapId) {
this.gatherers.forEach(function (gatherer, index, array) {
if (gatherer.id === voter.id) {
array[index].mapVote = mapId;
}
});
};
Gather.prototype.voteForServer = function (voter, serverId) {
this.gatherers.forEach(function (gatherer, index, array) {
if (gatherer.id === voter.id) {
array[index].serverVote = serverId;
}
});
};
// Returns an array of IDs representing votes for leaders
Gather.prototype.leaderVotes = function () {
var self = this;

View file

@ -1,13 +1,14 @@
"use strict";
/*
* Implements Map
*
* Will eventually pull maps off ENSL API
*/
var fs = require("fs");
var path = require("path");
var source = JSON.parse(fs.readFileSync(path.join(__dirname, "../../config/data/maps.json")));
var mapList = source.maps;
function Map () {
}
module.exports = Map;
Map.list = mapList;
module.exports = Map;

View file

@ -1,13 +1,14 @@
"use strict";
/*
* Implements Server
*
* Will eventually pull servers off ENSL API
*/
var fs = require("fs");
var path = require("path");
var source = JSON.parse(fs.readFileSync(path.join(__dirname, "../../config/data/servers.json")));
var serverList = source.servers;
function Server () {
}
module.exports = Server;
Server.list = serverList;
module.exports = Server;

View file

@ -303,6 +303,114 @@ var GatherActions = React.createClass({
}
});
var ServerVoting = React.createClass({
handleServerVote: function (e) {
e.preventDefault();
socket.emit("gather:vote", {
server: {
id: parseInt(e.target.value, 10)
}
});
},
votesForServer: function (server) {
return this.props.gather.gatherers.reduce(function (acc, gatherer) {
if (server.id === gatherer.serverVote) acc++;
return acc;
}, 0);
},
render: function () {
var self = this;
var servers = self.props.servers.map(function (server) {
var voteButton;
if (self.props.currentGatherer.serverVote === server.id) {
voteButton = (<button
data-disabled="true"
className="btn btn-xs btn-success">
Voted</button>)
} else {
voteButton = (<button
onClick={self.handleServerVote}
value={server.id}
className="btn btn-xs btn-primary">
Vote</button>);
}
return (
<tr>
<td className="col-md-6">{server.name}</td>
<td className="col-md-3">{self.votesForServer(server)} Votes</td>
<td className="col-md-3 text-right">
{voteButton}
</td>
</tr>
);
});
return (
<div className="panel panel-default">
<div className="panel-heading">
Server Voting
</div>
<table id="serverVoteTable" className="table table-condensed table-hover voting-table">
{servers}
</table>
</div>
);
}
})
var MapVoting = React.createClass({
handleMapVote: function (e) {
e.preventDefault();
socket.emit("gather:vote", {
map: {
id: parseInt(e.target.value, 10)
}
});
},
votesForMap: function (map) {
return this.props.gather.gatherers.reduce(function (acc, gatherer) {
if (map.id === gatherer.mapVote) acc++;
return acc;
}, 0);
},
render: function () {
var self = this;
var maps = self.props.maps.map(function (map) {
var voteButton;
if (self.props.currentGatherer.mapVote === map.id) {
voteButton = (<button
data-disabled="true"
className="btn btn-xs btn-success">
Voted</button>)
} else {
voteButton = (<button
onClick={self.handleMapVote}
value={map.id}
className="btn btn-xs btn-primary">
Vote</button>);
}
return (
<tr>
<td className="col-md-6">{map.name}</td>
<td className="col-md-3">{self.votesForMap(map)} Votes</td>
<td className="col-md-3 text-right">
{voteButton}
</td>
</tr>
);
});
return (
<div className="panel panel-default">
<div className="panel-heading">
Map Voting
</div>
<table className="table table-condensed table-hover voting-table">
{maps}
</table>
</div>
);
}
})
var Gather = React.createClass({
getDefaultProps: function () {
return {
@ -314,10 +422,7 @@ var Gather = React.createClass({
componentDidMount: function () {
var self = this;
socket.on("gather:refresh", function (data) {
self.setProps({
gather: data.gather,
currentGatherer: data.currentGatherer
});
self.setProps(data);
});
},
@ -326,7 +431,22 @@ var Gather = React.createClass({
return (<h1>Gather Completed! Now restart the app</h1>);
}
var voting;
if (this.props.currentGatherer) {
voting = (
<div className="panel-body">
<div className="row">
<div className="col-md-6">
<MapVoting {...this.props} />
</div>
<div className="col-md-6">
<ServerVoting {...this.props} />
</div>
</div>
</div>
);
}
var gatherTeams;
if (this.props.gather.state === 'selection') {
gatherTeams = <GatherTeams gather={this.props.gather} />
@ -339,6 +459,7 @@ var Gather = React.createClass({
</div>
<GatherProgress gather={this.props.gather} />
<Gatherers gather={this.props.gather} currentGatherer={this.props.currentGatherer} />
{voting}
{gatherTeams}
<GatherActions {...this.props} />
</div>

View file

@ -18,6 +18,7 @@ var userCache = {};
var User = require("./user");
var winston = require("winston");
var enslClient = require("../ensl/client")();
var _ = require("lodash");
module.exports = function (namespace) {
var refreshUsers = function (socket) {
@ -54,12 +55,10 @@ module.exports = function (namespace) {
socket.on('users:online', function () {
socket._user.online = true;
refreshUsers();
});
socket.on('users:away', function () {
socket._user.online = false;
refreshUsers();
});
socket.on("users:authorize", function (data) {

View file

@ -31,7 +31,7 @@
}
.online {
background: #FF9900;
background: #0C0;
}
.afk {
@ -42,8 +42,6 @@
background: #CCC;
}
.no-bottom {
margin-bottom: 0px !important;
padding-bottom: 0px !important;
@ -52,3 +50,7 @@
.join-hero {
padding: 80px 0px;
}
.voting-table {
font-size: 90%;
}

View file

@ -303,6 +303,114 @@ var GatherActions = React.createClass({displayName: "GatherActions",
}
});
var ServerVoting = React.createClass({displayName: "ServerVoting",
handleServerVote: function (e) {
e.preventDefault();
socket.emit("gather:vote", {
server: {
id: parseInt(e.target.value, 10)
}
});
},
votesForServer: function (server) {
return this.props.gather.gatherers.reduce(function (acc, gatherer) {
if (server.id === gatherer.serverVote) acc++;
return acc;
}, 0);
},
render: function () {
var self = this;
var servers = self.props.servers.map(function (server) {
var voteButton;
if (self.props.currentGatherer.serverVote === server.id) {
voteButton = (React.createElement("button", {
"data-disabled": "true",
className: "btn btn-xs btn-success"},
"Voted"))
} else {
voteButton = (React.createElement("button", {
onClick: self.handleServerVote,
value: server.id,
className: "btn btn-xs btn-primary"},
"Vote"));
}
return (
React.createElement("tr", null,
React.createElement("td", {className: "col-md-6"}, server.name),
React.createElement("td", {className: "col-md-3"}, self.votesForServer(server), " Votes"),
React.createElement("td", {className: "col-md-3 text-right"},
voteButton
)
)
);
});
return (
React.createElement("div", {className: "panel panel-default"},
React.createElement("div", {className: "panel-heading"},
"Server Voting"
),
React.createElement("table", {id: "serverVoteTable", className: "table table-condensed table-hover voting-table"},
servers
)
)
);
}
})
var MapVoting = React.createClass({displayName: "MapVoting",
handleMapVote: function (e) {
e.preventDefault();
socket.emit("gather:vote", {
map: {
id: parseInt(e.target.value, 10)
}
});
},
votesForMap: function (map) {
return this.props.gather.gatherers.reduce(function (acc, gatherer) {
if (map.id === gatherer.mapVote) acc++;
return acc;
}, 0);
},
render: function () {
var self = this;
var maps = self.props.maps.map(function (map) {
var voteButton;
if (self.props.currentGatherer.mapVote === map.id) {
voteButton = (React.createElement("button", {
"data-disabled": "true",
className: "btn btn-xs btn-success"},
"Voted"))
} else {
voteButton = (React.createElement("button", {
onClick: self.handleMapVote,
value: map.id,
className: "btn btn-xs btn-primary"},
"Vote"));
}
return (
React.createElement("tr", null,
React.createElement("td", {className: "col-md-6"}, map.name),
React.createElement("td", {className: "col-md-3"}, self.votesForMap(map), " Votes"),
React.createElement("td", {className: "col-md-3 text-right"},
voteButton
)
)
);
});
return (
React.createElement("div", {className: "panel panel-default"},
React.createElement("div", {className: "panel-heading"},
"Map Voting"
),
React.createElement("table", {className: "table table-condensed table-hover voting-table"},
maps
)
)
);
}
})
var Gather = React.createClass({displayName: "Gather",
getDefaultProps: function () {
return {
@ -314,10 +422,7 @@ var Gather = React.createClass({displayName: "Gather",
componentDidMount: function () {
var self = this;
socket.on("gather:refresh", function (data) {
self.setProps({
gather: data.gather,
currentGatherer: data.currentGatherer
});
self.setProps(data);
});
},
@ -326,7 +431,22 @@ var Gather = React.createClass({displayName: "Gather",
return (React.createElement("h1", null, "Gather Completed! Now restart the app"));
}
var voting;
if (this.props.currentGatherer) {
voting = (
React.createElement("div", {className: "panel-body"},
React.createElement("div", {className: "row"},
React.createElement("div", {className: "col-md-6"},
React.createElement(MapVoting, React.__spread({}, this.props))
),
React.createElement("div", {className: "col-md-6"},
React.createElement(ServerVoting, React.__spread({}, this.props))
)
)
)
);
}
var gatherTeams;
if (this.props.gather.state === 'selection') {
gatherTeams = React.createElement(GatherTeams, {gather: this.props.gather})
@ -339,6 +459,7 @@ var Gather = React.createClass({displayName: "Gather",
),
React.createElement(GatherProgress, {gather: this.props.gather}),
React.createElement(Gatherers, {gather: this.props.gather, currentGatherer: this.props.currentGatherer}),
voting,
gatherTeams,
React.createElement(GatherActions, React.__spread({}, this.props))
)

View file

@ -365,6 +365,30 @@ describe("Gather Model:", function () {
});
});
describe("voteForMap", function () {
beforeEach(function() {
gather.addGatherer(user);
});
it ("assigns map vote to gatherer", function () {
var mapId = 1;
gather.voteForMap(user, mapId);
var gatherer = gather.getGatherer(user);
assert.equal(gatherer.mapVote, mapId);
});
});
describe("voteForServer", function () {
beforeEach(function() {
gather.addGatherer(user);
});
it ("assigns map vote to gatherer", function () {
var serverId = 1;
gather.voteForServer(user, serverId);
var gatherer = gather.getGatherer(user);
assert.equal(gatherer.serverVote, serverId);
});
});
describe("confirmTeam", function () {
var leader;
beforeEach(function () {