OSDN Git Service

Changed log messages and levels.
[shogi-server/shogi-server.git] / shogi_server / command.rb
index b8ffb9b..b09b95a 100644 (file)
@@ -1,7 +1,7 @@
 ## $Id$
 
 ## Copyright (C) 2004 NABEYA Kenichi (aka nanami@2ch)
-## Copyright (C) 2007-2008 Daigo Moriwaki (daigo at debian dot org)
+## Copyright (C) 2007-2012 Daigo Moriwaki (daigo at debian dot org)
 ##
 ## This program is free software; you can redistribute it and/or modify
 ## it under the terms of the GNU General Public License as published by
@@ -69,6 +69,9 @@ module ShogiServer
         my_sente_str = $3
         cmd = GameChallengeCommand.new(str, player, 
                                        command_name, game_name, my_sente_str)
+      when /^%%(GAME|CHALLENGE)\s+(\S+)/
+        msg = "A turn identifier is required"
+        cmd = ErrorCommand.new(str, player, msg)
       when /^%%CHAT\s+(.+)/
         message = $1
         cmd = ChatCommand.new(str, player, message, $league.players)
@@ -102,6 +105,11 @@ module ShogiServer
           nth_move = $3.to_i
         end
         cmd = ForkCommand.new(str, player, source_game, new_buoy_game, nth_move)
+      when /^%%FORK\s+(\S+)$/
+        source_game   = $1
+        new_buoy_game = nil
+        nth_move      = nil
+        cmd = ForkCommand.new(str, player, source_game, new_buoy_game, nth_move)
       when /^\s*$/
         cmd = SpaceCommand.new(str, player)
       when /^%%%[^%]/
@@ -489,7 +497,16 @@ module ShogiServer
 
     def call
       if (! Login::good_game_name?(@game_name))
-        @player.write_safe(sprintf("##[ERROR] bad game name\n"))
+        @player.write_safe(sprintf("##[ERROR] bad game name: %s.\n", @game_name))
+        if (/^(.+)-\d+-\d+$/ =~ @game_name)
+          if Login::good_identifier?($1)
+            # do nothing
+          else
+            @player.write_safe(sprintf("##[ERROR] invalid identifiers are found or too many characters are used.\n"))
+          end
+        else
+          @player.write_safe(sprintf("##[ERROR] game name should consist of three parts like game-1500-60.\n"))
+        end
         return :continue
       elsif ((@player.status == "connected") || (@player.status == "game_waiting"))
         ## continue
@@ -540,9 +557,7 @@ module ShogiServer
               return :continue
             end
             buoy.decrement_count(buoy_game)
-            options = {:sente_time => buoy_game.sente_time,
-                       :gote_time  => buoy_game.gote_time}
-            Game::new(@player.game_name, @player, rival, board, options)
+            Game::new(@player.game_name, @player, rival, board)
           end
         else
           klass = Login.handicapped_game_name?(@game_name) || Board
@@ -676,9 +691,9 @@ module ShogiServer
   # Command for an error
   #
   class ErrorCommand < Command
-    def initialize(str, player)
-      super
-      @msg = nil
+    def initialize(str, player, msg=nil)
+      super(str, player)
+      @msg = msg || "unknown command"
     end
     attr_reader :msg
 
@@ -686,7 +701,7 @@ module ShogiServer
       cmd = @str.chomp
       # Aim to hide a possible password
       cmd.gsub!(/LOGIN\s*(\w+)\s+.*/i, 'LOGIN \1...')
-      @msg = "##[ERROR] unknown command %s\n" % [cmd]
+      @msg = "##[ERROR] %s: %s\n" % [@msg, cmd]
       @player.write_safe(@msg)
       log_error(@msg)
       return :continue
@@ -702,16 +717,6 @@ module ShogiServer
       @game_name = game_name
       @moves     = moves
       @count     = count
-      @sente_time = nil
-      @gote_time  = nil
-    end
-
-    # ForkCommand may call this method to set remaining time of both
-    # players.
-    #
-    def set_initial_time(sente_time, gote_time)
-      @sente_time = sente_time
-      @gote_time  = gote_time
     end
 
     def call
@@ -741,7 +746,7 @@ module ShogiServer
         raise WrongMoves
       end
 
-      buoy_game = BuoyGame.new(@game_name, @moves, @player.name, @count, @sente_time, @gote_time)
+      buoy_game = BuoyGame.new(@game_name, @moves, @player.name, @count)
       buoy.add_game(buoy_game)
       @player.write_safe(sprintf("##[SETBUOY] +OK\n"))
       log_info("A buoy game was created: %s by %s" % [@game_name, @player.name])
@@ -769,11 +774,7 @@ module ShogiServer
       # found two players: p1 and p2
       log_info("Starting a buoy game: %s with %s and %s" % [@game_name, p1.name, p2.name])
       buoy.decrement_count(buoy_game)
-
-      # remaining time for ForkCommand
-      options = {:sente_time => buoy_game.sente_time,
-                 :gote_time  => buoy_game.gote_time}
-      game = Game::new(@game_name, p1, p2, board, options)
+      game = Game::new(@game_name, p1, p2, board)
       return :continue
 
     rescue WrongMoves => e
@@ -830,6 +831,7 @@ module ShogiServer
         @player.write_safe("##[GETBUOYCOUNT] %s\n" % [buoy_game.count])
       end
       @player.write_safe("##[GETBUOYCOUNT] +OK\n")
+      return :continue
     end
   end
 
@@ -846,6 +848,28 @@ module ShogiServer
       @new_buoy_game = new_buoy_game
       @nth_move      = nth_move # may be nil
     end
+    attr_reader :new_buoy_game
+
+    def decide_new_buoy_game_name
+      name       = nil
+      total_time = nil
+      byo_time   = nil
+
+      if @source_game.split("+").size >= 2 &&
+         /^([^-]+)-(\d+)-(\d+)/ =~ @source_game.split("+")[1]
+        name       = $1
+        total_time = $2
+        byo_time   = $3
+      end
+      if name == nil || total_time == nil || byo_time == nil
+        @player.write_safe(sprintf("##[ERROR] wrong source game name to make a new buoy game name: %s\n", @source_game))
+        log_error "Received a wrong source game name to make a new buoy game name: %s from %s." % [@source_game, @player.name]
+        return :continue
+      end
+      @new_buoy_game = "buoy_%s_%d-%s-%s" % [name, @nth_move, total_time, byo_time]
+      @player.write_safe(sprintf("##[FORK]: new buoy game name: %s\n", @new_buoy_game))
+      @player.write_safe("##[FORK] +OK\n")
+    end
 
     def call
       game = $league.games[@source_game]
@@ -855,17 +879,23 @@ module ShogiServer
         return :continue
       end
 
-      moves = game.read_moves
+      moves = game.read_moves # [["+7776FU","T2"],["-3334FU","T5"]]
       @nth_move = moves.size - 1 unless @nth_move
       if @nth_move > moves.size or @nth_move < 1
         @player.write_safe(sprintf("##[ERROR] number of moves to fork is out of range: %s.\n", moves.size))
         log_error "Number of moves to fork is out of range: %s [%s]" % [@nth_move, @player.name]
         return :continue
       end
-      new_moves = moves[0...@nth_move]
+      new_moves_str = ""
+      moves[0...@nth_move].each do |m|
+        new_moves_str << m.join(",")
+      end
+
+      unless @new_buoy_game
+        decide_new_buoy_game_name
+      end
 
-      buoy_cmd = SetBuoyCommand.new(@str, @player, @new_buoy_game, new_moves.join(""), 1)
-      buoy_cmd.set_initial_time(game.sente.mytime, game.gote.mytime)
+      buoy_cmd = SetBuoyCommand.new(@str, @player, @new_buoy_game, new_moves_str, 1)
       return buoy_cmd.call
     end
   end