civility 1
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 +7 -0
- data/bin/civility +5 -0
- data/lib/civility.rb +195 -0
- metadata +61 -0
checksums.yaml
ADDED
@@ -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
|
data/bin/civility
ADDED
data/lib/civility.rb
ADDED
@@ -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: []
|