goshrine_bot 0.1.11 → 0.1.13

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -24,6 +24,18 @@ The GTP protocol is documented here: http://www.lysator.liu.se/~gunnar/gtp/
24
24
 
25
25
  * Run goshrine_bot botname
26
26
 
27
+ == ADVANCED CONFIGURATION:
28
+
29
+ In addition to the options listed above, there are some other configuration options that allow you avoid having your bot shut down for idle, and to limit the maximum number of games your bot will play at a time.
30
+
31
+ local_gnugo:
32
+ :login: gnugo
33
+ :password: testpass
34
+ :gtp_cmd_line: gnugo --mode gtp --level 10
35
+ :idle_shutdown_timeout: 10
36
+ :maximum_concurrent_games: 1
37
+ :debug: false
38
+
27
39
  == TROUBLESHOOTING:
28
40
 
29
41
  Look for a file named something like gtp_08e03daa.log. An exit status of 255 means that your program could not be found.
@@ -33,6 +45,10 @@ Look for a file named something like gtp_08e03daa.log. An exit status of 255 me
33
45
  * json
34
46
  * eventmachine
35
47
 
48
+ == THANKS:
49
+
50
+ Thanks to Gareth Davies for improvements that allow goshrine_bot to run pachi (and likely other bots as well).
51
+
36
52
  == LICENSE:
37
53
 
38
54
  (The MIT License)
data/Rakefile CHANGED
@@ -6,7 +6,7 @@
6
6
 
7
7
  require 'rake'
8
8
  require 'rspec/core/rake_task'
9
- require 'rake/gempackagetask'
9
+ require 'rubygems/package_task'
10
10
 
11
11
  task :default => :spec
12
12
 
@@ -16,7 +16,7 @@ end
16
16
 
17
17
  load(File.join(File.dirname(__FILE__), "goshrine_bot.gemspec"))
18
18
 
19
- Rake::GemPackageTask.new(SPEC) do |package|
19
+ Gem::PackageTask.new(SPEC) do |package|
20
20
  # do nothing: I just need a gem but this block is required
21
21
  end
22
22
 
data/goshrine_bot.gemspec CHANGED
@@ -21,7 +21,7 @@ SPEC = Gem::Specification.new do |s|
21
21
  END_DESCRIPTION
22
22
 
23
23
  s.add_dependency('eventmachine', '>= 0.12.10')
24
- s.add_dependency('em-http-request', '>= 1.0.0.beta.3')
24
+ s.add_dependency('em-http-request', '>= 0.3')
25
25
  s.add_dependency('faye', '>= 0.6.0')
26
26
  s.add_dependency('json', '>= 1.5.0')
27
27
 
@@ -4,11 +4,9 @@ module GoshrineBot
4
4
 
5
5
  class Client
6
6
 
7
- class << self
8
- end
9
-
10
7
  def initialize(options)
11
8
  @base_url = URI::parse(options[:server_url])
9
+ GoshrineRequest.base_url = @base_url
12
10
  @options = options
13
11
  @password = options[:password]
14
12
  @login = options[:login]
@@ -27,8 +25,8 @@ module GoshrineBot
27
25
 
28
26
  def login(&blk)
29
27
  # login
30
- http = http_post('/sessions/create', {'login' => @login, 'password' => @password})
31
- http.callback {
28
+ request = GoshrineRequest.new('/sessions/create').post(:body => {'login' => @login, 'password' => @password})
29
+ request.callback { |http|
32
30
  if http.response_header.status == 401
33
31
  puts "Invalid Login or Password"
34
32
  EventMachine::stop
@@ -47,38 +45,14 @@ module GoshrineBot
47
45
  end
48
46
  end
49
47
  }
50
- http.errback {|response|
48
+ request.errback { |http|
51
49
  puts "Login failed (network issue?)";
52
50
  }
53
51
  end
54
-
55
- def http_post(path, data = nil)
56
- conn = EM::HttpRequest.new("#{@base_url}#{path}")
57
- conn.use CookiePersist
58
- headers = {'Accept' => 'application/json'}
59
-
60
- http = conn.post(:head => headers, :body => data)
61
-
62
- http.headers { |head|
63
- CookiePersist.cookies << head[EM::HttpClient::SET_COOKIE]
64
- }
65
- http
66
- end
67
-
68
- def http_get(path)
69
- conn = EM::HttpRequest.new("#{@base_url}#{path}")
70
- conn.use CookiePersist
71
-
72
- http = conn.get(:head => {'Accept' => 'application/json'})
73
-
74
- http.headers { |head|
75
- CookiePersist.cookies << head[EM::HttpClient::SET_COOKIE]
76
- }
77
- http
78
- end
79
-
52
+
80
53
  def subscribe
81
54
  @faye_client.subscribe("/user/private/" + @queue_id) do |m|
55
+ puts "msg"
82
56
  msg_type = m["type"]
83
57
  case msg_type
84
58
  when 'match_requested'
@@ -106,6 +80,7 @@ module GoshrineBot
106
80
  load_existing_games {
107
81
  if @options[:idle_shutdown_timeout] > 0
108
82
  EM::add_periodic_timer( @options[:idle_shutdown_timeout] ) {
83
+ puts "checking"
109
84
  @games.each do |token, game|
110
85
  game.idle_check(@options[:idle_shutdown_timeout])
111
86
  end
@@ -116,9 +91,9 @@ module GoshrineBot
116
91
  end
117
92
 
118
93
  def load_existing_games(&blk)
119
- http = http_get('/game/active')
120
- http.callback {
121
- #puts "Got #{response.inspect}"
94
+ request = GoshrineRequest.new('/game/active').get
95
+ request.callback { |http|
96
+ #puts "Got #{http.inspect}"
122
97
  games = JSON.parse(http.response)
123
98
  puts "#{games.count} game(s) in progress"
124
99
  games.each do |game_attrs|
@@ -147,12 +122,12 @@ module GoshrineBot
147
122
 
148
123
  def handle_match_accept(token)
149
124
  game = GameInProgress.new(self)
150
- http = http_get("/g/#{token}")
151
- http.callback {
125
+ request = GoshrineRequest.new("/g/#{token}")
126
+ request.callback { |http|
152
127
  attrs = JSON.parse(http.response)
153
128
  game.update_from_game_list(attrs)
154
129
  add_game(game)
155
- }
130
+ }
156
131
  end
157
132
 
158
133
  def handle_match_request(request)
@@ -161,8 +136,8 @@ module GoshrineBot
161
136
  game = GameInProgress.new(self)
162
137
  game.update_from_match_request(request)
163
138
  if max_games.nil? || active_games.count < max_games
164
- http = http_get("/match/accept?id=#{game.challenge_id}")
165
- http.callback {
139
+ request = GoshrineRequest.new("/match/accept?id=#{game.challenge_id}").get
140
+ request.callback { |http|
166
141
  attrs = JSON.parse(http.response)
167
142
  game.update_from_game_list(attrs)
168
143
  add_game(game)
@@ -171,7 +146,7 @@ module GoshrineBot
171
146
  count = max_games > 1 ? "#{max_games} games" : "1 game"
172
147
  reason = "#{@login} only plays #{count} at a time."
173
148
  puts "Rejecting match: #{reason}"
174
- http = http_get("/match/reject?id=#{game.challenge_id}&reason=#{URI.escape(reason)}")
149
+ GoshrineRequest.new("/match/reject?id=#{game.challenge_id}&reason=#{URI.escape(reason)}").get
175
150
  end
176
151
  end
177
152
 
@@ -23,23 +23,24 @@ class CookieHash < Hash #:nodoc:
23
23
  end
24
24
 
25
25
  class CookiePersist
26
- def self.cookies
26
+
27
+ def cookies
27
28
  Thread.current[:cookies] ||= []
28
29
  end
29
30
 
30
- def self.cookie_hash
31
+ def cookie_hash
31
32
  CookieHash.new.tap { |hsh|
32
33
  cookies.uniq.each { |c| hsh.add_cookies(c) }
33
34
  }
34
35
  end
35
36
 
36
- def self.request(head, body)
37
+ def request(client, head, body)
37
38
  head['cookie'] = cookie_hash.to_cookie_string
38
- #puts "Sending cookies: #{head['cookie']}"
39
39
  [head, body]
40
40
  end
41
41
 
42
- def self.response(resp)
42
+ def response(resp)
43
+ cookies << resp.response_header[EM::HttpClient::SET_COOKIE]
43
44
  resp
44
45
  end
45
46
  end
@@ -29,7 +29,7 @@ module GoshrineBot
29
29
  user_id = m["id"].to_i
30
30
  puts "User arrived (#{token}): #{m["login"]}"
31
31
  if state == 'new' && (user_id == black_player_id || user_id == white_player_id)
32
- http = @client.http_post("/game/#{token}/attempt_start")
32
+ GoshrineRequest.new("/game/#{token}/attempt_start").post
33
33
  end
34
34
  when 'game_started'
35
35
  self.state = "in-play"
@@ -102,7 +102,7 @@ module GoshrineBot
102
102
  puts "Got private game message: #{m.inspect}"
103
103
  case m["type"]
104
104
  when 'undo_requested'
105
- @client.http_post("/game/accept_undo/" + m["request_id"])
105
+ GoshrineReuqest.new("/game/accept_undo/" + m["request_id"]).post
106
106
  end
107
107
  end
108
108
 
@@ -157,7 +157,7 @@ module GoshrineBot
157
157
  end
158
158
 
159
159
  if state == 'new'
160
- http = @client.http_post("/game/#{token}/attempt_start")
160
+ GoshrineRequest.new("/game/#{token}/attempt_start").post
161
161
  end
162
162
 
163
163
  end
@@ -177,15 +177,16 @@ module GoshrineBot
177
177
  res.callback { |response_move|
178
178
  puts "Generated move: #{response_move} (#{token})"
179
179
  self.move_number += 1
180
+ request = nil
180
181
  if response_move.upcase == 'PASS'
181
- http = @client.http_post("/game/#{token}/pass")
182
+ request = GoshrineRequest.new("/game/#{token}/pass").post
182
183
  elsif response_move.upcase == 'RESIGN'
183
- http = @client.http_post("/game/#{token}/resign")
184
+ request = GoshrineRequest.new("/game/#{token}/resign").post
184
185
  else
185
186
  rgo_coord = gtp_coord_to_goshrine_coord(response_move.upcase, board_size)
186
- http = @client.http_post("/game/#{token}/move/#{rgo_coord}")
187
+ request = GoshrineRequest.new("/game/#{token}/move/#{rgo_coord}").post
187
188
  end
188
- http.callback {
189
+ request.callback { |http|
189
190
  if http.response_header.status == 200
190
191
  self.moves << [my_color, response_move]
191
192
  else
@@ -193,7 +194,7 @@ module GoshrineBot
193
194
  end
194
195
  }
195
196
  }
196
- end
197
+ end
197
198
 
198
199
  def start_engine
199
200
  gtp = GtpStdioClient.new(@client.gtp_cmd_line, "gtp_#{token}.log")
@@ -0,0 +1,45 @@
1
+ module GoshrineBot
2
+
3
+ class GoshrineRequest
4
+
5
+ def self.base_url=(url)
6
+ @@base_url = url
7
+ end
8
+
9
+ def initialize(path)
10
+ @url = "#{@@base_url}#{path}"
11
+ @conn = EventMachine::HttpRequest.new(@url)
12
+ @cookie_persist = CookiePersist.new
13
+ end
14
+
15
+ def do_http(verb,options)
16
+ puts "Sending"
17
+ options[:head] =
18
+ {'Accept' => 'application/json',
19
+ 'cookie' => @cookie_persist.cookie_hash.to_cookie_string}
20
+
21
+ http = @conn.send verb, options
22
+
23
+ defer = EM::DefaultDeferrable.new
24
+ http.callback {
25
+ puts "Persisting cookies"
26
+ @cookie_persist.cookies << http.response_header[EM::HttpClient::SET_COOKIE]
27
+ defer.succeed(http)
28
+ }
29
+ http.errback {
30
+ puts "failed goshrine request"
31
+ defer.fail(http)
32
+ }
33
+ defer
34
+ end
35
+
36
+ def post(options = {})
37
+ do_http(:post, options)
38
+ end
39
+
40
+ def get(options = {})
41
+ do_http(:get, options)
42
+ end
43
+ end
44
+
45
+ end
data/lib/goshrine_bot.rb CHANGED
@@ -7,7 +7,7 @@ require 'logger'
7
7
 
8
8
  module GoshrineBot
9
9
 
10
- VERSION = "0.1.11"
10
+ VERSION = "0.1.13"
11
11
 
12
12
  STDOUT.sync = true
13
13
 
@@ -15,6 +15,7 @@ module GoshrineBot
15
15
 
16
16
  %w[ client
17
17
  gtp_stdio_client
18
+ goshrine_request
18
19
  runner
19
20
  game
20
21
  cookies
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: goshrine_bot
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.11
4
+ version: 0.1.13
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-09-04 00:00:00.000000000Z
12
+ date: 2011-12-15 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: eventmachine
16
- requirement: &70281678905860 !ruby/object:Gem::Requirement
16
+ requirement: &70254337655960 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,21 +21,21 @@ dependencies:
21
21
  version: 0.12.10
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70281678905860
24
+ version_requirements: *70254337655960
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: em-http-request
27
- requirement: &70281678904480 !ruby/object:Gem::Requirement
27
+ requirement: &70254337655480 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
31
31
  - !ruby/object:Gem::Version
32
- version: 1.0.0.beta.3
32
+ version: '0.3'
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *70281678904480
35
+ version_requirements: *70254337655480
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: faye
38
- requirement: &70281678901700 !ruby/object:Gem::Requirement
38
+ requirement: &70254337655020 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: 0.6.0
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *70281678901700
46
+ version_requirements: *70254337655020
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: json
49
- requirement: &70281678900840 !ruby/object:Gem::Requirement
49
+ requirement: &70254337654560 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: 1.5.0
55
55
  type: :runtime
56
56
  prerelease: false
57
- version_requirements: *70281678900840
57
+ version_requirements: *70254337654560
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: rspec
60
- requirement: &70281678899680 !ruby/object:Gem::Requirement
60
+ requirement: &70254337654180 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ! '>='
@@ -65,7 +65,7 @@ dependencies:
65
65
  version: '0'
66
66
  type: :development
67
67
  prerelease: false
68
- version_requirements: *70281678899680
68
+ version_requirements: *70254337654180
69
69
  description: The GoShrine bot client is a library that allows you connect a local
70
70
  Go playing program that speaks GTP (like gnugo) to http://goshrine.com.
71
71
  email:
@@ -91,6 +91,7 @@ files:
91
91
  - lib/goshrine_bot/core_ext/hash.rb
92
92
  - lib/goshrine_bot/faye_auth_ext.rb
93
93
  - lib/goshrine_bot/game.rb
94
+ - lib/goshrine_bot/goshrine_request.rb
94
95
  - lib/goshrine_bot/gtp_stdio_client.rb
95
96
  - lib/goshrine_bot/runner.rb
96
97
  homepage: http://github.com/ps2/goshrine_bot
@@ -113,7 +114,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
113
114
  version: '0'
114
115
  requirements: []
115
116
  rubyforge_project:
116
- rubygems_version: 1.8.10
117
+ rubygems_version: 1.8.12
117
118
  signing_key:
118
119
  specification_version: 3
119
120
  summary: A client to connect GTP go programs to GoShrine