civility 1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. checksums.yaml +7 -0
  2. data/bin/civility +5 -0
  3. data/lib/civility.rb +195 -0
  4. metadata +61 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 1df76ba40aea50dec8f246b036906e5f27dc002d
4
+ data.tar.gz: e4e16a66f545ae76eb60c719170730853392f213
5
+ SHA512:
6
+ metadata.gz: eef89961b15e37fca9565cd636057f6012e2eb8132fea08d112ac2ffc235875212cbd06927042ab341e4cf4dcf2644d9f9a4f7df99de75d38a7e60e441d6ef76
7
+ data.tar.gz: f84cd67d695ec79d6ecf4adc4dae5a9658dce3b4e411b013e741ce9b8a97abd843d84f679f69d741f85825f3a9cdecd9f916736f31d60a5e02c66470a68a80f1
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require '/Users/abraham/dev/civility/lib/civility'
4
+
5
+ Civility.start(ARGV)
@@ -0,0 +1,195 @@
1
+ require 'net/http'
2
+ require 'uri'
3
+ require 'json'
4
+ require 'yaml'
5
+ require 'thor'
6
+
7
+ class Civility < Thor
8
+ VERSION = '1'
9
+ SAVE_DIRECTORY = "/Documents/Aspyr/Sid\ Meier\'s\ Civilization\ 5/Saves/hotseat/"
10
+ FILE_PREFIX = 'civility'
11
+ FILE_EXT = 'Civ5Save'
12
+ API = 'http://multiplayerrobot.com/api/Diplomacy/'
13
+ CONFIG_FILE = '.civility.yml'
14
+
15
+ def initialize(*args)
16
+ @config = load_config
17
+ super(*args)
18
+ end
19
+
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)
26
+ else
27
+ @config[:version] = VERSION
28
+ @config[:auth] = key
29
+ @config[:user] = user
30
+ self.config = @config
31
+ puts "Hello, #{user['PersonaName']}, your auth is all configured!"
32
+ end
33
+ end
34
+
35
+ desc "games", "List your current games"
36
+ def games
37
+ return missing_auth_error unless auth_key
38
+ response = get('GetGamesAndPlayers', {authKey: auth_key, playerIDText: user_id})
39
+ response = JSON.parse(response)
40
+ output_games(response['Games'])
41
+ self.config = @config.merge(games: response['Games'], updated_at: Time.now.to_i)
42
+ end
43
+
44
+ desc 'play', 'Download a game to play'
45
+ def play(name)
46
+ return missing_auth_error unless auth_key
47
+ game = game_by_name(name)
48
+ return missing_game_error unless game
49
+ path = game_path(game)
50
+ file('GetLatestSaveFileBytes', {authKey: auth_key, gameID: game['GameId']}, path)
51
+ puts "Saved #{game['Name']} to #{path}"
52
+ end
53
+
54
+ desc 'complete', 'Upload a completed turn'
55
+ def complete(name)
56
+ return missing_auth_error unless auth_key
57
+ game = game_by_name(name)
58
+ return missing_game_error unless game
59
+ path = game_path(game)
60
+ response = upload_file('SubmitTurn', {authKey: auth_key, turnId: game['CurrentTurn']['TurnId']}, path)
61
+ response = JSON.parse(response)
62
+ case response['ResultType']
63
+ when 0
64
+ puts "UnexpectedError: #{response}"
65
+ when 1
66
+ puts "You earned #{response['PointsEarned']} points completing #{game['Name']} from #{path}"
67
+ when 2
68
+ puts "It's not your turn"
69
+ when 3
70
+ puts 'You already submitted your turn'
71
+ else
72
+ puts 'UnexpectedError'
73
+ end
74
+ end
75
+
76
+ private
77
+
78
+ def game_path(game)
79
+ "#{Dir.home}#{SAVE_DIRECTORY}#{FILE_PREFIX}-#{normalize(game['Name'])}-#{game['GameId']}.#{FILE_EXT}"
80
+ end
81
+
82
+ def auth_key
83
+ @config[:auth]
84
+ end
85
+
86
+ def user_id
87
+ @config[:user]['SteamID']
88
+ end
89
+
90
+ def games_list
91
+ @config[:games]
92
+ end
93
+
94
+ def output_games(games)
95
+ for game in games
96
+ turn = (user_id == game['CurrentTurn']['UserId'] ? " and it's your turn" : '')
97
+ puts "#{game['Name']} with #{game['Players'].size} other players#{turn}"
98
+ end
99
+ puts "If your games are missing, try again" if games.size == 0
100
+ end
101
+
102
+ def game_by_name(name)
103
+ name = normalize(name)
104
+ games_list.find {|game| normalize(game['Name']) == name}
105
+ end
106
+
107
+ def user
108
+ user_id = get('AuthenticateUser', {authKey: auth_key})
109
+ response = get('GetGamesAndPlayers', {authKey: auth_key, playerIDText: user_id})
110
+ players = JSON.parse(response)['Players']
111
+ user_from_players(user_id, players)
112
+ end
113
+
114
+ def user_from_players(user_id, players)
115
+ user_id = user_id.to_i
116
+ players.find {|player| player['SteamID'] == user_id }
117
+ end
118
+
119
+ def normalize(name)
120
+ name.downcase.strip.gsub(/[^\w]/, '')
121
+ end
122
+
123
+ def get(method, params)
124
+ uri = URI.join(API, method)
125
+ uri.query = URI.encode_www_form(params)
126
+ response = Net::HTTP.get_response(uri)
127
+ fail error_message(response) unless response.code == '200'
128
+ response.body
129
+ end
130
+
131
+ def file(method, params, path)
132
+ uri = URI.parse("#{API}#{method}")
133
+ uri.query = URI.encode_www_form(params)
134
+ f = open(path, "wb")
135
+ Net::HTTP.start(uri.host) do |http|
136
+ http.request_get(uri.request_uri) do |response|
137
+ fail error_message(response) unless response.code == '200'
138
+ response.read_body do |segment|
139
+ f.write(segment)
140
+ end
141
+ end
142
+ end
143
+ ensure
144
+ f.close()
145
+ end
146
+
147
+ def upload_file(method, params, path)
148
+ uri = URI.parse("#{API}#{method}")
149
+ uri.query = URI.encode_www_form(params)
150
+ data = File.read(path)
151
+ http = Net::HTTP.new(uri.host)
152
+ request = Net::HTTP::Post.new(uri.request_uri)
153
+ request.body = data
154
+ response = http.request(request)
155
+ fail error_message(response) unless response.code == '200'
156
+ response.body
157
+ end
158
+
159
+ def load_config
160
+ if config_file?
161
+ @config = YAML::load_file config_path
162
+ else
163
+ self.config = {}
164
+ end
165
+ end
166
+
167
+ def error_message(response)
168
+ body = JSON.parse(response.body)
169
+ "Code: #{response.code}\nBody: #{body}"
170
+ rescue JSON::ParserError
171
+ "Unable to parse response\nCode: #{response.code}\nBody: #{response.body}"
172
+ end
173
+
174
+ def missing_game_error
175
+ puts 'Unable to find that game'
176
+ end
177
+
178
+ def missing_auth_error
179
+ puts 'Please run `civility auth` first'
180
+ end
181
+
182
+ def config=(settings)
183
+ File.open(config_path, 'w') do |file|
184
+ file.write settings.to_yaml
185
+ end
186
+ end
187
+
188
+ def config_path
189
+ "#{Dir.home}/#{CONFIG_FILE}"
190
+ end
191
+
192
+ def config_file?
193
+ File.exist?(config_path)
194
+ end
195
+ end
metadata ADDED
@@ -0,0 +1,61 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: civility
3
+ version: !ruby/object:Gem::Version
4
+ version: '1'
5
+ platform: ruby
6
+ authors:
7
+ - Abraham Williams
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-02-23 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: thor
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ description: Civility is the easiest way to manage your Civ5 hotseat games hosted
28
+ on Giant Multiplayer Robot
29
+ email: abraham@abrah.am
30
+ executables:
31
+ - civility
32
+ extensions: []
33
+ extra_rdoc_files: []
34
+ files:
35
+ - bin/civility
36
+ - lib/civility.rb
37
+ homepage: https://github.com/abraham/civility
38
+ licenses:
39
+ - MIT
40
+ metadata: {}
41
+ post_install_message:
42
+ rdoc_options: []
43
+ require_paths:
44
+ - lib
45
+ required_ruby_version: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: '0'
50
+ required_rubygems_version: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ requirements: []
56
+ rubyforge_project:
57
+ rubygems_version: 2.5.1
58
+ signing_key:
59
+ specification_version: 4
60
+ summary: The easiest way to manage your Civ5 hotseat games on GMR
61
+ test_files: []