-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit eed0ce0
Showing
18 changed files
with
921 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
* text=auto |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
eGMR-darwin-x64/* | ||
node_modules/* |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
{ | ||
"saveFile": "", | ||
"authKey": "" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
html, | ||
body { | ||
padding: 0; | ||
margin: 0; | ||
} | ||
|
||
body { | ||
font-family: -apple-system, 'Helvetica Neue', Helvetica, sans-serif; | ||
} | ||
|
||
.center-text { | ||
text-align: center; | ||
} | ||
|
||
.black { | ||
color: black; | ||
} | ||
|
||
.white { | ||
color: white; | ||
} | ||
|
||
.player-list { | ||
list-style: none; | ||
} | ||
|
||
.player-item { | ||
display: inline; | ||
} | ||
|
||
.small { | ||
width: 32px; | ||
height: 32px; | ||
} | ||
.xsmall { | ||
width: 16px; | ||
height: 16px; | ||
} | ||
|
||
.medium { | ||
width: 64px; | ||
height: 64px; | ||
} | ||
|
||
.large { | ||
width: 128px; | ||
height: 128px; | ||
} | ||
|
||
#settings { | ||
|
||
} | ||
|
||
#browse-button { | ||
width: 20%; | ||
} | ||
|
||
#browse-text { | ||
width: 75%; | ||
} |
Large diffs are not rendered by default.
Oops, something went wrong.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
'use strict' | ||
let request = require('request') | ||
let async = require('async') | ||
let JSONbig = require('json-bigint'); | ||
let _ = require('lodash') | ||
let EventEmitter = require('events').EventEmitter | ||
let util = require('util') | ||
let fs = require('fs') | ||
let Config = require('./config/gmr.json') | ||
|
||
module.exports = GMR | ||
|
||
util.inherits(GMR, EventEmitter) | ||
|
||
let host = 'http://multiplayerrobot.com/api/Diplomacy/' | ||
|
||
function GMR () { | ||
let self = this | ||
|
||
this.authKey = Config.authKey | ||
this.saveFile = Config.saveFile | ||
|
||
this.playerId | ||
this.games | ||
this.players | ||
|
||
this.authenticateUser = function (authKey, callback) { | ||
let uri = `${host}AuthenticateUser?authKey=${self.authKey}` | ||
return request.get(uri, {timeout: 1000}, (err, res, body) => { | ||
if (err) return callback(err) | ||
return callback(null, body) | ||
}) | ||
} | ||
|
||
this.getGamesAndPlayers = function (playerIds, authKey, callback) { | ||
if (false === _.isArray(playerIds)) { | ||
playerIds = [playerIds] | ||
} | ||
let uri = `${host}GetGamesAndPlayers?playerIDText=${playerIds.join('_')}&authKey=${self.authKey}` | ||
return request.get(uri, {timeout: 5000}, (err, res, body) => { | ||
if (err) return callback(err) | ||
return callback(null, body) | ||
}) | ||
} | ||
|
||
} | ||
|
||
|
||
GMR.prototype.fetchInfo = function (callback) { | ||
let self = this | ||
return async.series([ | ||
function auth (callback) { | ||
self.authenticateUser(self.authKey, (err, id) => { | ||
if (err) return callback (err) | ||
self.playerId = id | ||
return callback(null) | ||
}) | ||
}, | ||
function getGames (callback) { | ||
self.getGamesAndPlayers(self.playerId, self.authKey, (err, gamesAndPlayers) => { | ||
if (err) return callback (err) | ||
self.games = JSONbig.parse(gamesAndPlayers).Games | ||
_.forEach(self.games, game => { | ||
game.CurrentTurn.UserId = game.CurrentTurn.UserId.toString() | ||
_.forEach(game.Players, player => { | ||
player.UserId = player.UserId.toString() | ||
// Normalize TurnOrder such that current player's turn order is 0, second is 1, etc. | ||
player.TurnOrder = (player.TurnOrder - game.CurrentTurn.PlayerNumber + game.Players.length ) % game.Players.length | ||
}) | ||
}) | ||
|
||
return callback(null) | ||
}) | ||
}, | ||
function getPlayers (callback) { | ||
let playerIds = _(self.games).pluck('Players').flatten() | ||
.pluck('UserId').unique().filter(n => n !== 0) | ||
.value() | ||
self.getGamesAndPlayers(playerIds, self.authKey, (err, gamesAndPlayers) => { | ||
if (err) return callback (err) | ||
|
||
self.players = _.reduce(JSONbig.parse(gamesAndPlayers).Players, (ps, p) => { | ||
p.SteamID = p.SteamID.toString() | ||
p.AvatarUrl = p.AvatarUrl.split('.jpg')[0]+'_full.jpg' // better picture | ||
ps[p.SteamID] = p | ||
return ps | ||
}, {}) | ||
return callback(null) | ||
}) | ||
} | ||
], (err) => { | ||
if (err) return callback(err) | ||
return callback(null, { | ||
players: self.players, | ||
games: self.games | ||
}) | ||
}) | ||
} | ||
|
||
GMR.prototype.getPlayerId = function () { | ||
console.log(this.playerId) | ||
return this.playerId | ||
} | ||
|
||
GMR.prototype.getPlayers = function () { | ||
console.log(this.players) | ||
return this.players | ||
} | ||
|
||
GMR.prototype.getGames = function () { | ||
console.log(this.games) | ||
return this.games | ||
} | ||
|
||
GMR.prototype.getGameSave = function (gameId, callback) { | ||
let uri = `${host}GetLatestSaveFileBytes?authKey=${this.authKey}&gameId=${gameId}` | ||
|
||
return request(uri).pipe(fs.createWriteStream(this.saveFile)) | ||
.on('error', (err) => callback(err)) | ||
.on('finish', callback) | ||
} | ||
|
||
GMR.prototype.uploadGameSave = function (turnId, callback) { | ||
let uri = `${host}SubmitTurn?authKey=${this.authKey}&turnId=${turnId}` | ||
return fs.createReadStream(this.saveFile) | ||
.pipe(request.post(uri)) | ||
.on('error', (err) => callback(err)) | ||
.on('response', function(response) { | ||
console.log(response.statusCode) | ||
console.log(response) | ||
}) | ||
.on('end', callback) | ||
} | ||
|
||
GMR.prototype.getSettings = function () { | ||
return { | ||
saveFile: this.saveFile, | ||
authKey: this.authKey | ||
} | ||
} | ||
|
||
GMR.prototype.setSettings = function (settings) { | ||
this.saveFile = settings.saveFile | ||
this.authKey = settings.authKey | ||
return fs.writeFileSync(__dirname + '/config/gmr.json', JSON.stringify(settings, null, 2)) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
<!doctype html> | ||
<html ng-app="eGMR"> | ||
<head> | ||
<meta charset="utf-8"> | ||
<title>GMR Client</title> | ||
<link rel="stylesheet" href="css/index.css"> | ||
<link rel="stylesheet" href="css/photon.min.css"> | ||
<script type="text/javascript"> | ||
require('./js/index.js'); | ||
</script> | ||
</head> | ||
<body> | ||
<div ng-controller = "GlobalController as globalCtrl" class="window"> | ||
<div class="window-content"> | ||
<div class="pane-group"> | ||
<div ng-controller = "GameListController as gamesCtrl" class="pane-sm sidebar"> | ||
<ul class="list-group"> | ||
<li class="list-group-header"> | ||
<input class="form-control" ng-model="search" type="text" placeholder="Search for a game"> | ||
</li> | ||
<li class="list-group-header"> | ||
<h4>My turn</h4> | ||
</li> | ||
<li ng-repeat="game in games|filter:{Name: search, CurrentTurn: {UserId: playerId}}" ng-click="setSelectedGame(game)" ng-class="{active: game.GameId === selectedGame.GameId}" class="list-group-item"> | ||
<img class="small img-circle media-object pull-left" ng-src="{{players[game.CurrentTurn.UserId].AvatarUrl}}"> | ||
<div class="media-body"> | ||
<h5>{{game.Name}}</h5> | ||
<p> | ||
<img ng-repeat="player in game.Players | filter:filterPlayers(game) | orderBy:'TurnOrder'" class="xsmall img-circle media-object pull-left" ng-src="{{players[player.UserId].AvatarUrl}}"> | ||
</p> | ||
</div> | ||
</li> | ||
<li class="list-group-header"> | ||
<h4>Other games</h4> | ||
</li> | ||
<li ng-repeat="game in games|filter:{Name: search, CurrentTurn: {UserId: '!'+playerId}}" ng-click="setSelectedGame(game)" ng-class="{active: game.GameId === selectedGame.GameId && !isSettingsSelected}" class="list-group-item"> | ||
<img class="small img-circle media-object pull-left" ng-src="{{players[game.CurrentTurn.UserId].AvatarUrl}}"> | ||
<div class="media-body"> | ||
<h5>{{game.Name}}</h5> | ||
<p> | ||
<img ng-repeat="player in game.Players | filter:filterPlayers(game) | orderBy:'TurnOrder'" class="xsmall img-circle media-object pull-left" ng-src="{{players[player.UserId].AvatarUrl}}"> | ||
</p> | ||
</div> | ||
</li> | ||
<li id="settings" ng-click="showSettings()" class="list-group-item" ng-class="{active: isSettingsSelected}"> | ||
<h4><span class="icon icon-cog"></span>Settings</h4> | ||
</li> | ||
</ul> | ||
</div> | ||
<div class="pane" ng-hide="isSettingsSelected" ng-controller = "GameInfoController as gameCtrl"> | ||
<h1 class="center-text">{{selectedGame.Name}}</h1> | ||
<div class="center-text"> | ||
<img class="large img-circle media-object" ng-src="{{players[selectedGame.CurrentTurn.UserId].AvatarUrl}}"> | ||
<div class="center-text"> | ||
<button ng-show="selectedGame.CurrentTurn.UserId===playerId" ng-click="downloadSave()" class="btn btn-large btn-default"><i class="black icon icon-down-circled"></i>Download</button> | ||
<button ng-show="selectedGame.CurrentTurn.UserId===playerId" ng-click="uploadSave()"class="btn btn-large btn-primary"><i class="white icon icon-up-circled"> </i> Upload</button> | ||
</div> | ||
<div ng-show="downloaded">Game has save been downloaded</div> | ||
<div ng-show="uploaded">Game has save been uploaded</div> | ||
</div> | ||
<div> | ||
<h3 class="center-text">{{timeRemaining}} remaining</h3> | ||
</div> | ||
<div class="center-text"> | ||
<ul class="player-list"> | ||
<li ng-repeat="player in selectedGame.Players | filter: filterPlayers | orderBy:'TurnOrder'" class="player-item"> | ||
<img class="medium img-circle media-object" ng-src="{{players[player.UserId].AvatarUrl}}"> | ||
</li> | ||
</ul> | ||
</div> | ||
<div ng-show="error" class="center-text"> | ||
An error occured: {{error}} | ||
</div> | ||
</div> | ||
<div class="pane" ng-show="isSettingsSelected" ng-controller="SettingsController as settingsCtrl"> | ||
<form> | ||
<div class="form-group"> | ||
<label>Authentication Key</label> | ||
<input ng-model="settings.authKey" class="form-control" placeholder="I42D4242N7DI"> | ||
</div> | ||
<div class="form-group"> | ||
<label>Hotseat Save Folder</label> | ||
<input id="browse-text" ng-model="settings.saveFile" class="form-control" placeholder="/Users/D/T/C"> | ||
<button ng-click="changeSaveFile()" id="browse-button" class="btn btn-form btn-default">Browse</button> | ||
</div> | ||
<div class="form-actions"> | ||
<button type="submit" ng-click="cancelSettings()" class="btn btn-form btn-default">Cancel</button> | ||
<button type="submit" ng-click="saveSettings()" class="btn btn-form btn-primary">Save</button> | ||
</div> | ||
</form> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
</body> | ||
</html> |
Oops, something went wrong.