civility 2 → 3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/lib/civility.rb +33 -70
- data/lib/civility/gmr.rb +86 -0
- metadata +53 -2
- metadata.gz.sig +2 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 961441008c19039aec77918332dc3cf6d4b61311
|
4
|
+
data.tar.gz: 8521738ff666ecdd6056d813e629d48d9d0749c2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 49ed95a2664faa60d21a9752eb46d432600a0459bd3cb4a2c15fd2021cd088d208fe7ca2a8528e8423bf4882c86acdb76e94d6ece9fbeaf0050a095de0ddec99
|
7
|
+
data.tar.gz: 28fc93c4ff0b164980efe64ef44bf3d2f3cd940477619ef05582ddccf7bc1a7e00c4a7d7788432a59debb22927b896a37eba9df4aa4a6c6f7677bf43dc4a10d7
|
checksums.yaml.gz.sig
ADDED
Binary file
|
data.tar.gz.sig
ADDED
Binary file
|
data/lib/civility.rb
CHANGED
@@ -5,38 +5,38 @@ require 'yaml'
|
|
5
5
|
require 'thor'
|
6
6
|
|
7
7
|
class Civility < Thor
|
8
|
-
VERSION = '
|
8
|
+
VERSION = '3'
|
9
9
|
SAVE_DIRECTORY = "/Documents/Aspyr/Sid\ Meier\'s\ Civilization\ 5/Saves/hotseat/"
|
10
10
|
FILE_PREFIX = 'civility'
|
11
11
|
FILE_EXT = 'Civ5Save'
|
12
|
-
API = 'http://multiplayerrobot.com/api/Diplomacy/'
|
13
12
|
CONFIG_FILE = '.civility.yml'
|
14
13
|
|
15
14
|
def initialize(*args)
|
16
15
|
@config = load_config
|
16
|
+
@gmr = Civility::GMR.new(auth_key, user_id) if auth_key
|
17
17
|
super(*args)
|
18
18
|
end
|
19
19
|
|
20
20
|
desc 'auth', 'Save auth key'
|
21
|
-
def auth(
|
22
|
-
if
|
23
|
-
|
24
|
-
puts "Grab your Authentication Key from #{
|
25
|
-
system('open',
|
21
|
+
def auth(auth_key = nil)
|
22
|
+
if auth_key.nil?
|
23
|
+
auth_url = Civility::GMR.auth_url
|
24
|
+
puts "Grab your Authentication Key from #{auth_url}"
|
25
|
+
system('open', auth_url)
|
26
26
|
else
|
27
|
+
@gmr = Civility::GMR.new(auth_key)
|
27
28
|
@config[:version] = VERSION
|
28
|
-
@config[:auth] =
|
29
|
+
@config[:auth] = auth_key
|
29
30
|
@config[:user] = user
|
30
31
|
self.config = @config
|
31
32
|
puts "Hello, #{user['PersonaName']}, your auth is all configured!"
|
32
33
|
end
|
33
34
|
end
|
34
35
|
|
35
|
-
desc
|
36
|
+
desc 'games', 'List your current games'
|
36
37
|
def games
|
37
38
|
return missing_auth_error unless auth_key
|
38
|
-
|
39
|
-
output_games(games)
|
39
|
+
output_games sync_games
|
40
40
|
end
|
41
41
|
|
42
42
|
desc 'play', 'Download a game to play'
|
@@ -45,10 +45,11 @@ class Civility < Thor
|
|
45
45
|
return missing_auth_error unless auth_key
|
46
46
|
game = game_by_name(name)
|
47
47
|
return missing_game_error(name) unless game
|
48
|
-
path =
|
49
|
-
|
48
|
+
path = save_path(game)
|
49
|
+
data = @gmr.download(game['GameId'])
|
50
|
+
save_file(path, data)
|
50
51
|
puts "Saved #{game['Name']} to #{path}"
|
51
|
-
|
52
|
+
sync_games
|
52
53
|
end
|
53
54
|
|
54
55
|
desc 'complete', 'Upload a completed turn'
|
@@ -57,9 +58,8 @@ class Civility < Thor
|
|
57
58
|
return missing_auth_error unless auth_key
|
58
59
|
game = game_by_name(name)
|
59
60
|
return missing_game_error(name) unless game
|
60
|
-
path =
|
61
|
-
response =
|
62
|
-
response = JSON.parse(response)
|
61
|
+
path = save_path(game)
|
62
|
+
response = @gmr.upload(game['CurrentTurn']['TurnId'], File.read(path))
|
63
63
|
case response['ResultType']
|
64
64
|
when 0
|
65
65
|
puts "UnexpectedError: #{response}"
|
@@ -76,14 +76,13 @@ class Civility < Thor
|
|
76
76
|
|
77
77
|
private
|
78
78
|
|
79
|
-
def
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
response['Games']
|
79
|
+
def sync_games
|
80
|
+
games = @gmr.games
|
81
|
+
self.config = @config.merge(games: games, updated_at: Time.now.to_i)
|
82
|
+
games
|
84
83
|
end
|
85
84
|
|
86
|
-
def
|
85
|
+
def save_path(game)
|
87
86
|
"#{Dir.home}#{SAVE_DIRECTORY}#{FILE_PREFIX}-#{normalize(game['Name'])}-#{game['GameId']}.#{FILE_EXT}"
|
88
87
|
end
|
89
88
|
|
@@ -100,73 +99,35 @@ class Civility < Thor
|
|
100
99
|
end
|
101
100
|
|
102
101
|
def output_games(games)
|
103
|
-
|
102
|
+
games.each do |game|
|
104
103
|
turn = (user_id == game['CurrentTurn']['UserId'] ? " and it's your turn" : '')
|
105
104
|
puts "#{game['Name']} with #{game['Players'].size} other players#{turn}"
|
106
105
|
end
|
107
|
-
puts "
|
106
|
+
puts "\nIf your games are missing, try again"
|
108
107
|
end
|
109
108
|
|
110
109
|
def game_by_name(name)
|
111
110
|
name = normalize(name)
|
112
|
-
games_list.find {|game| normalize(game['Name']) == name}
|
111
|
+
games_list.find { |game| normalize(game['Name']) == name }
|
113
112
|
end
|
114
113
|
|
115
114
|
def user
|
116
|
-
|
117
|
-
response = get('GetGamesAndPlayers', {authKey: auth_key, playerIDText: user_id})
|
118
|
-
players = JSON.parse(response)['Players']
|
119
|
-
user_from_players(user_id, players)
|
120
|
-
end
|
121
|
-
|
122
|
-
def user_from_players(user_id, players)
|
123
|
-
user_id = user_id.to_i
|
124
|
-
players.find {|player| player['SteamID'] == user_id }
|
115
|
+
@gmr.user
|
125
116
|
end
|
126
117
|
|
127
118
|
def normalize(name)
|
128
119
|
name.downcase.strip.gsub(/[^\w]/, '')
|
129
120
|
end
|
130
121
|
|
131
|
-
def
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
fail error_message(response) unless response.code == '200'
|
136
|
-
response.body
|
137
|
-
end
|
138
|
-
|
139
|
-
def file(method, params, path)
|
140
|
-
uri = URI.parse("#{API}#{method}")
|
141
|
-
uri.query = URI.encode_www_form(params)
|
142
|
-
f = open(path, "wb")
|
143
|
-
Net::HTTP.start(uri.host) do |http|
|
144
|
-
http.request_get(uri.request_uri) do |response|
|
145
|
-
fail error_message(response) unless response.code == '200'
|
146
|
-
response.read_body do |segment|
|
147
|
-
f.write(segment)
|
148
|
-
end
|
149
|
-
end
|
150
|
-
end
|
151
|
-
ensure
|
152
|
-
f.close()
|
153
|
-
end
|
154
|
-
|
155
|
-
def upload_file(method, params, path)
|
156
|
-
uri = URI.parse("#{API}#{method}")
|
157
|
-
uri.query = URI.encode_www_form(params)
|
158
|
-
data = File.read(path)
|
159
|
-
http = Net::HTTP.new(uri.host)
|
160
|
-
request = Net::HTTP::Post.new(uri.request_uri)
|
161
|
-
request.body = data
|
162
|
-
response = http.request(request)
|
163
|
-
fail error_message(response) unless response.code == '200'
|
164
|
-
response.body
|
122
|
+
def save_file(path, data)
|
123
|
+
file = open(path, 'wb')
|
124
|
+
file.write(data)
|
125
|
+
file.close
|
165
126
|
end
|
166
127
|
|
167
128
|
def load_config
|
168
129
|
if config_file?
|
169
|
-
@config = YAML
|
130
|
+
@config = YAML.load_file config_path
|
170
131
|
else
|
171
132
|
self.config = {}
|
172
133
|
end
|
@@ -201,3 +162,5 @@ class Civility < Thor
|
|
201
162
|
File.exist?(config_path)
|
202
163
|
end
|
203
164
|
end
|
165
|
+
|
166
|
+
require 'civility/gmr'
|
data/lib/civility/gmr.rb
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require 'uri'
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
class Civility
|
6
|
+
class GMR
|
7
|
+
API_BASE = 'http://multiplayerrobot.com/api/Diplomacy'
|
8
|
+
|
9
|
+
def initialize(auth_key, user_id = nil)
|
10
|
+
@auth_key = auth_key
|
11
|
+
@user_id = user_id
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.auth_url
|
15
|
+
'http://multiplayerrobot.com/download'
|
16
|
+
end
|
17
|
+
|
18
|
+
def user(user_id = nil)
|
19
|
+
user_id = current_user_id if user_id.nil?
|
20
|
+
code, response = get('GetGamesAndPlayers', playerIDText: user_id)
|
21
|
+
fail "Unable to get user #{response}" if code != 200
|
22
|
+
data = JSON.parse(response)
|
23
|
+
data['Players'].find { |player| player['SteamID'].to_i == user_id.to_i }
|
24
|
+
end
|
25
|
+
|
26
|
+
def games
|
27
|
+
code, response = get('GetGamesAndPlayers', playerIDText: current_user_id)
|
28
|
+
fail "Unable to get games #{response}" if code != 200
|
29
|
+
data = JSON.parse(response)
|
30
|
+
data['Games']
|
31
|
+
end
|
32
|
+
|
33
|
+
def download(game_id)
|
34
|
+
code, response = get('GetLatestSaveFileBytes', gameId: game_id)
|
35
|
+
fail "Unable to download file #{response}" if code != 200
|
36
|
+
response
|
37
|
+
end
|
38
|
+
|
39
|
+
def upload(turn_id, save_file)
|
40
|
+
code, response = post('SubmitTurn', save_file, turnId: turn_id)
|
41
|
+
fail "Unable to upload file #{response}" if code != 200
|
42
|
+
JSON.parse(response)
|
43
|
+
end
|
44
|
+
|
45
|
+
# TODO: Implement a method shortcut method to get a game turn_id
|
46
|
+
# def turn_id(game_id)
|
47
|
+
# end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
attr_reader :auth_key
|
52
|
+
|
53
|
+
def api_url(path)
|
54
|
+
URI.parse([API_BASE, path].join('/'))
|
55
|
+
end
|
56
|
+
|
57
|
+
def current_user_id
|
58
|
+
return @user_id if @user_id
|
59
|
+
|
60
|
+
code, response = get('AuthenticateUser')
|
61
|
+
fail 'Unable to get current_user_id' if code != 200
|
62
|
+
@user_id = response.to_i
|
63
|
+
end
|
64
|
+
|
65
|
+
def get(path, params = {})
|
66
|
+
uri = api_url path
|
67
|
+
uri.query = encode_params_with_auth(params)
|
68
|
+
response = Net::HTTP.get_response(uri)
|
69
|
+
[response.code.to_i, response.body]
|
70
|
+
end
|
71
|
+
|
72
|
+
def post(path, body, params = {})
|
73
|
+
uri = api_url path
|
74
|
+
uri.query = encode_params_with_auth(params)
|
75
|
+
http = Net::HTTP.new(uri.host)
|
76
|
+
request = Net::HTTP::Post.new(uri.request_uri)
|
77
|
+
request.body = body
|
78
|
+
response = http.request(request)
|
79
|
+
[response.code.to_i, response.body]
|
80
|
+
end
|
81
|
+
|
82
|
+
def encode_params_with_auth(params)
|
83
|
+
URI.encode_www_form(params.merge(authKey: auth_key))
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
metadata
CHANGED
@@ -1,13 +1,35 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: civility
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '
|
4
|
+
version: '3'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Abraham Williams
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
|
-
cert_chain:
|
10
|
+
cert_chain:
|
11
|
+
- |
|
12
|
+
-----BEGIN CERTIFICATE-----
|
13
|
+
MIIDaDCCAlCgAwIBAgIBATANBgkqhkiG9w0BAQUFADA9MRAwDgYDVQQDDAdhYnJh
|
14
|
+
aGFtMRUwEwYKCZImiZPyLGQBGRYFYWJyYWgxEjAQBgoJkiaJk/IsZAEZFgJhbTAe
|
15
|
+
Fw0xNjA0MDMwMDQ1NTJaFw0xNzA0MDMwMDQ1NTJaMD0xEDAOBgNVBAMMB2FicmFo
|
16
|
+
YW0xFTATBgoJkiaJk/IsZAEZFgVhYnJhaDESMBAGCgmSJomT8ixkARkWAmFtMIIB
|
17
|
+
IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApXVVnxC9MKHSypbIpX1dn9Vn
|
18
|
+
5XFdaj/2p54cmHkmjPj+Exqsmckev3jRkFGYERs9mO23wn1mzvaH9d9R/N+/fN7E
|
19
|
+
ewMRBJEnI2WjnpZuhaLRDqjxAeQuOH9FkA7gpRxs1/alTjHt7gYP/LGdY+jpYILA
|
20
|
+
PSu8ntrjXJPdRomDrRCwGM81X4nfo4ScU0kXb2grLnreLx/i9k5st6WW83TpQahy
|
21
|
+
7QqNUYNn26cnv4eHW5UiVI+m/Vyg/L6c3If7yh9baOIQaQ5VhweZg9l9O7D3IKNz
|
22
|
+
U/KSsRQnzrRWNeiNCEMB37JWezmBHk4CscRwu9rlKWDumPVBQijHekzJyO8BCwID
|
23
|
+
AQABo3MwcTAJBgNVHRMEAjAAMAsGA1UdDwQEAwIEsDAdBgNVHQ4EFgQUt5dCnQLt
|
24
|
+
AQ44CELhWtUmNkDUWiMwGwYDVR0RBBQwEoEQYWJyYWhhbUBhYnJhaC5hbTAbBgNV
|
25
|
+
HRIEFDASgRBhYnJhaGFtQGFicmFoLmFtMA0GCSqGSIb3DQEBBQUAA4IBAQB2wxY4
|
26
|
+
lZUPVgl6lTeaVDF0lWLUek0/rVKt7e/K39cvys3gmvA5sx1Z95fE4FxzOYtPWJDQ
|
27
|
+
pVBlhwFiYdqmn6aiG9d/qSB455JgcD8JNlEFSo++lEOubprh7/yO+r5fmAiilujm
|
28
|
+
tnMd3rBF4uYV9jRGGe3spVMji4wwJwlNcQ9uYIAT/ZmP0H9cBZCDtw/KrKBXEjvm
|
29
|
+
VENYG5VyzjxrDQqEc9Kzy8GCzcKBcwypgTX8+sYL+GKEUe3P1E8eKa83B7XWmMG7
|
30
|
+
EsiR9eCvovV79dCUTm5EBRWaqa7DIAXh+oEHOaAP2btcuDT/kJlg9/YG12YDdX82
|
31
|
+
U6jGnAwybOW/iArJ
|
32
|
+
-----END CERTIFICATE-----
|
11
33
|
date: 2016-02-23 00:00:00.000000000 Z
|
12
34
|
dependencies:
|
13
35
|
- !ruby/object:Gem::Dependency
|
@@ -38,6 +60,34 @@ dependencies:
|
|
38
60
|
- - "~>"
|
39
61
|
- !ruby/object:Gem::Version
|
40
62
|
version: '0'
|
63
|
+
- !ruby/object:Gem::Dependency
|
64
|
+
name: rspec
|
65
|
+
requirement: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - "~>"
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '3'
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - "~>"
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '3'
|
77
|
+
- !ruby/object:Gem::Dependency
|
78
|
+
name: webmock
|
79
|
+
requirement: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - "~>"
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '1'
|
84
|
+
type: :development
|
85
|
+
prerelease: false
|
86
|
+
version_requirements: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - "~>"
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: '1'
|
41
91
|
description: Civility is the easiest way to manage your Civ5 hotseat games hosted
|
42
92
|
on Giant Multiplayer Robot
|
43
93
|
email: abraham@abrah.am
|
@@ -48,6 +98,7 @@ extra_rdoc_files: []
|
|
48
98
|
files:
|
49
99
|
- bin/civility
|
50
100
|
- lib/civility.rb
|
101
|
+
- lib/civility/gmr.rb
|
51
102
|
homepage: https://github.com/abraham/civility
|
52
103
|
licenses:
|
53
104
|
- MIT
|
metadata.gz.sig
ADDED