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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9b0f74580880b0d37770465bf37e82dc32218f26
4
- data.tar.gz: da8899ef0175eb9a1baf87abb25ac9478f95b4c7
3
+ metadata.gz: 961441008c19039aec77918332dc3cf6d4b61311
4
+ data.tar.gz: 8521738ff666ecdd6056d813e629d48d9d0749c2
5
5
  SHA512:
6
- metadata.gz: e2ac60210ac526e0366b8065fb6dbdf903cabb490a52a7b8572e7f776147faf0aac6c29db0eaa04fc0f966ed6a19e5cf2244ddd0de768d0604dd77f7eca95844
7
- data.tar.gz: ea43b7945ecbbdfe43b27f90bb5994a2d99af93709741dc63545bb3e96b4496f53d5e833551f30dd8edea083348f9d32e86955874f058f026214f03b6dbaf1c2
6
+ metadata.gz: 49ed95a2664faa60d21a9752eb46d432600a0459bd3cb4a2c15fd2021cd088d208fe7ca2a8528e8423bf4882c86acdb76e94d6ece9fbeaf0050a095de0ddec99
7
+ data.tar.gz: 28fc93c4ff0b164980efe64ef44bf3d2f3cd940477619ef05582ddccf7bc1a7e00c4a7d7788432a59debb22927b896a37eba9df4aa4a6c6f7677bf43dc4a10d7
Binary file
Binary file
@@ -5,38 +5,38 @@ require 'yaml'
5
5
  require 'thor'
6
6
 
7
7
  class Civility < Thor
8
- VERSION = '2'
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(key = nil)
22
- if key.nil?
23
- url = 'http://multiplayerrobot.com/download'
24
- puts "Grab your Authentication Key from #{url}"
25
- system('open', url)
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] = key
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 "games", "List your current games"
36
+ desc 'games', 'List your current games'
36
37
  def games
37
38
  return missing_auth_error unless auth_key
38
- games = api_games
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 = game_path(game)
49
- file('GetLatestSaveFileBytes', {authKey: auth_key, gameID: game['GameId']}, path)
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
- api_games
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 = game_path(game)
61
- response = upload_file('SubmitTurn', {authKey: auth_key, turnId: game['CurrentTurn']['TurnId']}, path)
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 api_games
80
- response = get('GetGamesAndPlayers', {authKey: auth_key, playerIDText: user_id})
81
- response = JSON.parse(response)
82
- self.config = @config.merge(games: response['Games'], updated_at: Time.now.to_i)
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 game_path(game)
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
- for game in games
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 "If your games are missing, try again" if games.size == 0
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
- user_id = get('AuthenticateUser', {authKey: auth_key})
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 get(method, params)
132
- uri = URI.join(API, method)
133
- uri.query = URI.encode_www_form(params)
134
- response = Net::HTTP.get_response(uri)
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::load_file config_path
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'
@@ -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: '2'
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
@@ -0,0 +1,2 @@
1
+ ��X�;� 1�C���U���&S^������;f�.��Jҡ�5ˇt
2
+ ��mz<3�K���뙕����i��jmxAWD���L%��{ȇ^�c��I����]�����I�8иq<�$��P��� >�u�&�뮯Z�� ���i�F�3�͂�+�) �. �Ҙj~g�Y������gM�]��g3��g̎�5������P� ��5�7���;�v�)^�7�n%'�+�䵕ٲ�3����� �igBV����8*0��E�