+
+ class Floodgate
+ class << self
+ def game_name?(str)
+ return /^floodgate-\d+-\d+$/.match(str) ? true : false
+ end
+ end
+
+ def initialize(league)
+ @league = league
+ @next_time = nil
+ charge
+ end
+
+ def run
+ @thread = Thread.new do
+ Thread.pass
+ while (true)
+ begin
+ sleep(10)
+ next if Time.now < @next_time
+ @league.reload
+ match_game
+ charge
+ rescue Exception => ex
+ # ignore errors
+ log_error("[in Floodgate's thread] #{ex} #{ex.backtrace}")
+ end
+ end
+ end
+ end
+
+ def shutdown
+ @thread.kill if @thread
+ end
+
+ # private
+
+ def charge
+ now = Time.now
+ if now.min < 30
+ @next_time = Time.mktime(now.year, now.month, now.day, now.hour, 30)
+ else
+ @next_time = Time.mktime(now.year, now.month, now.day, now.hour) + 3600
+ end
+ # for test
+ # if now.sec < 30
+ # @next_time = Time.mktime(now.year, now.month, now.day, now.hour, now.min, 30)
+ # else
+ # @next_time = Time.mktime(now.year, now.month, now.day, now.hour, now.min) + 60
+ # end
+ end
+
+ def match_game
+ players = @league.find_all_players do |pl|
+ pl.status == "game_waiting" &&
+ Floodgate.game_name?(pl.game_name) &&
+ pl.sente == nil
+ end
+ log_warning("DEBUG: %s" % [File.join(File.dirname(__FILE__), "pairing.rb")])
+ load File.join(File.dirname(__FILE__), "pairing.rb")
+ Pairing.default_pairing.match(players)
+ end
+ end # class Floodgate
+
+ #
+ # This manages those players who have their player_id.
+ # Since mk_rate mainly updates the yaml file, basically,
+ # this only reads data. But this writes some properties.
+ # TODO Such data should be facoted out to another file
+ #
+ class Persistent
+ def initialize(filename)
+ @db = YAML::Store.new(filename)
+ @db.transaction do |pstore|
+ @db['players'] ||= Hash.new
+ end
+ end
+
+ #
+ # trancaction=true means read only
+ #
+ def each_group(transaction=false)
+ @db.transaction(transaction) do
+ groups = @db["players"] || Hash.new
+ groups.each do |group, players|
+ yield group,players
+ end
+ end
+ end
+
+ def load_player(player)
+ return unless player.player_id
+
+ hash = nil
+ each_group(true) do |group, players|
+ hash = players[player.player_id]
+ break if hash
+ end
+ return unless hash
+
+ # a current user
+ player.name = hash['name']
+ player.rate = hash['rate'] || 0
+ player.modified_at = hash['last_modified']
+ player.rating_group = hash['rating_group']
+ player.win = hash['win'] || 0
+ player.loss = hash['loss'] || 0
+ player.last_game_win = hash['last_game_win'] || false
+ end
+
+ def save(player)
+ return unless player.player_id
+
+ each_group do |group, players|
+ hash = players[player.player_id]
+ if hash
+ # write only this property.
+ # the others are updated by ./mk_rate
+ hash['last_game_win'] = player.last_game_win
+ break
+ end
+ end
+ end
+
+ def get_players
+ players = []
+ each_group(true) do |group, players_hash|
+ players << players_hash.keys
+ end
+ return players.flatten.collect do |player_id|
+ p = BasicPlayer.new
+ p.player_id = player_id
+ load_player(p)
+ p
+ end
+ end
+ end # class Persistent
+