OSDN Git Service

* [shogi-server]
authorbeatles <beatles@b8c68f68-1e22-0410-b08e-880e1f8202b4>
Wed, 17 Jun 2009 14:44:24 +0000 (14:44 +0000)
committerbeatles <beatles@b8c68f68-1e22-0410-b08e-880e1f8202b4>
Wed, 17 Jun 2009 14:44:24 +0000 (14:44 +0000)
  - If a new game matched between two players is not started within
    a certain time (default 120 seconds) (i.e. the agree_waiting or
    start_waiting state lasts too long), the Server REJECTs the game.
    (Closes: #14425)

changelog
shogi_server/game.rb
shogi_server/player.rb

index 1e6ecc7..e3337c1 100644 (file)
--- a/changelog
+++ b/changelog
@@ -1,3 +1,11 @@
+2009-06-17 Daigo Moriwaki <daigo at debian dot org>
+
+       * [shogi-server]
+         - If a new game matched between two players is not started within
+           a certain time (default 120 seconds) (i.e. the agree_waiting or
+           start_waiting state lasts too long), the Server REJECTs the game.
+           (Closes: #14425)
+
 2009-06-15 Daigo Moriwaki <daigo at debian dot org>
 
        * [shogi-server]
index 0dc3746..0134ddd 100644 (file)
@@ -255,9 +255,13 @@ class GameResultSennichiteDraw < GameResultDraw
 end
 
 class Game
+  # When this duration passes after this object instanciated (i.e.
+  # the agree_waiting or start_waiting state lasts too long),
+  # the game will be rejected by the Server.
+  WAITING_EXPIRATION = 120 # seconds
+
   @@mutex = Mutex.new
   @@time  = 0
-
   def initialize(game_name, player0, player1)
     @monitors = Array::new
     @game_name = game_name
@@ -287,11 +291,13 @@ class Game
                   $league.event, @game_name, 
                   @sente.name, @gote.name, issue_current_time)
     
-    now = Time.now
+    # The time when this Game instance was created.
+    # Don't be confused with @start_time when the game was started to play.
+    @prepared_time = Time.now 
     log_dir_name = File.join($league.dir, 
-                             now.strftime("%Y"),
-                             now.strftime("%m"),
-                             now.strftime("%d"))
+                             @prepared_time.strftime("%Y"),
+                             @prepared_time.strftime("%m"),
+                             @prepared_time.strftime("%d"))
     FileUtils.mkdir_p(log_dir_name) unless File.exist?(log_dir_name)
     @logfile = File.join(log_dir_name, @game_id + ".csa")
 
@@ -310,7 +316,7 @@ class Game
   end
   attr_accessor :game_name, :total_time, :byoyomi, :sente, :gote, :game_id, :board, :current_player, :next_player, :fh, :monitors
   attr_accessor :last_move, :current_turn
-  attr_reader   :result
+  attr_reader   :result, :prepared_time
 
   def rated?
     @sente.rated? && @gote.rated?
@@ -586,6 +592,14 @@ END Game_Summary
 EOM
     return str
   end
+
+  def prepared_expire?
+    if @prepared_time && (@prepared_time + WAITING_EXPIRATION < Time.now)
+      return true
+    end
+
+    return false
+  end
   
   private
   
index 5b5d7ea..fc19cd8 100644 (file)
@@ -285,6 +285,12 @@ class Player < BasicPlayer
           if (@status == "game")
             s = @game.handle_one_move(str, self)
             return if (s && @protocol == LoginCSA::PROTOCOL)
+          elsif ["agree_waiting", "start_waiting"].include?(@status) 
+            if @game.prepared_expire?
+              log_warning("#{@status} lasted too long. This play has been expired.")
+              @game.reject("the Server (timed out)")
+              return if (@protocol == LoginCSA::PROTOCOL)
+            end
           end
         when :exception
           log_error("Failed to receive a message from #{@name}.")