## $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
@name = nil
@password = nil
@rate = 0
+ @estimated_rate = 0
@win = 0
@loss = 0
@last_game_win = false
+ @rating_group = nil
+ @modified_at = nil
@sente = nil
+ @game_name = ""
end
# Idetifier of the player in the rating system
# Score in the rating sysem
attr_accessor :rate
+ # Estimated rate for unrated player (rate == 0)
+ # But this value is not persisted and cleared when player logs off.
+ attr_accessor :estimated_rate
+
# Number of games for win and loss in the rating system
attr_accessor :win, :loss
# true for Sente; false for Gote
attr_accessor :sente
+ # game name
+ attr_accessor :game_name
+
def is_human?
return [%r!_human$!, %r!_human@!].any? do |re|
re.match(@name)
@player_id = @password = nil
end
end
+
+ def set_sente_from_str(str)
+ case str
+ when "+" then @sente = true
+ when "-" then @sente = false
+ else
+ # str should be "*"
+ @sente = nil
+ end
+ end
end
@protocol = nil # CSA or x1
@eol = eol || "\m" # favorite eol code
@game = nil
- @game_name = ""
@mytime = 0 # set in start method also
@socket_buffer = []
@main_thread = Thread::current
end
attr_accessor :socket, :status
- attr_accessor :protocol, :eol, :game, :mytime, :game_name
+ attr_accessor :protocol, :eol, :game, :mytime
attr_accessor :main_thread
attr_reader :socket_buffer
log_debug("Terminating %s's write thread..." % [@name])
if @write_thread && @write_thread.alive?
write_safe(nil)
+ Thread.pass # help the write_thread to terminate
end
- @player_logger.close if @player_logger
log_debug("done.")
rescue
log_message(sprintf("user %s finish failed", @name))
end
#
+ # Wait for the write thread to finish.
+ # This method should be called just before this instance will be freed.
+ #
+ def wait_write_thread_finish(msec=1000)
+ while msec > 0 && @write_thread && @write_thread.alive?
+ sleep 0.1; msec -= 0.1
+ end
+ @player_logger.close if @player_logger
+ end
+
+ #
# Note that sending a message is included in the giant lock.
#
def write_safe(str)
def run(csa_1st_str=nil)
while ( csa_1st_str ||
str = gets_safe(@socket, (@socket_buffer.empty? ? Default_Timeout : 1)) )
+ time = Time.now
log(:info, :in, str) if str && str.instance_of?(String)
$mutex.lock
begin
end
str.chomp! if (str.class == String) # may be strip! ?
- cmd = ShogiServer::Command.factory(str, self)
+ delay = Time.now - time
+ if delay > 5
+ log_warning("Detected a long delay: %.2f sec" % [delay])
+ end
+ cmd = ShogiServer::Command.factory(str, self, time)
case cmd.call
when :return
return
# do nothing
else
# TODO never reach
+ log_error("Detected a wrong return value for %s" % [cmd])
end
ensure
$mutex.unlock
end
end # enf of while
+ log_warning("%s's socket was suddenly closed" % [@name])
end # def run
end # class