OSDN Git Service

* [shogi-server]
[shogi-server/shogi-server.git] / shogi_server / login.rb
1 ## $Id$
2
3 ## Copyright (C) 2004 NABEYA Kenichi (aka nanami@2ch)
4 ## Copyright (C) 2007-2008 Daigo Moriwaki (daigo at debian dot org)
5 ##
6 ## This program is free software; you can redistribute it and/or modify
7 ## it under the terms of the GNU General Public License as published by
8 ## the Free Software Foundation; either version 2 of the License, or
9 ## (at your option) any later version.
10 ##
11 ## This program is distributed in the hope that it will be useful,
12 ## but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 ## GNU General Public License for more details.
15 ##
16 ## You should have received a copy of the GNU General Public License
17 ## along with this program; if not, write to the Free Software
18 ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
20 module ShogiServer # for a namespace
21
22 ######################################################
23 # Processes the LOGIN command.
24 #
25 class Login
26   def Login.good_login?(str)
27     tokens = str.split
28     if (((tokens.length == 3) || 
29         ((tokens.length == 4) && tokens[3] == "x1")) &&
30         (tokens[0] == "LOGIN") &&
31         (good_identifier?(tokens[1])))
32       return true
33     else
34       return false
35     end
36   end
37
38   def Login.good_game_name?(str)
39     if ((str =~ /^(.+)-\d+-\d+$/) && (good_identifier?($1)))
40       return true
41     else
42       return false
43     end
44   end
45
46   def Login.good_identifier?(str)
47     if str =~ /\A[\w\d_@\-\.]{1,#{Max_Identifier_Length}}\z/
48       return true
49     else
50       return false
51     end
52   end
53
54   def Login.factory(str, player)
55     (login, player.name, password, ext) = str.chomp.split
56     if ext
57       return Loginx1.new(player, password)
58     else
59       return LoginCSA.new(player, password)
60     end
61   end
62
63   attr_reader :player
64   
65   # the first command that will be executed just after LOGIN.
66   # If it is nil, the default process will be started.
67   attr_reader :csa_1st_str
68
69   def initialize(player, password)
70     @player = player
71     @csa_1st_str = nil
72     parse_password(password)
73   end
74
75   def process
76     @player.write_safe(sprintf("LOGIN:%s OK\n", @player.name))
77     log_message(sprintf("user %s run in %s mode", @player.name, @player.protocol))
78   end
79
80   def incorrect_duplicated_player(str)
81     @player.write_safe("LOGIN:incorrect\n")
82     @player.write_safe(sprintf("username %s is already connected\n", @player.name)) if (str.split.length >= 4)
83     sleep 3 # wait for sending the above messages.
84     @player.name = "%s [duplicated]" % [@player.name]
85     @player.finish
86   end
87 end
88
89 ######################################################
90 # Processes LOGIN for the CSA standard mode.
91 #
92 class LoginCSA < Login
93   PROTOCOL = "CSA"
94
95   def initialize(player, password)
96     @gamename = nil
97     super
98     @player.protocol = PROTOCOL
99   end
100
101   def parse_password(password)
102     if Login.good_game_name?(password)
103       @gamename = password
104       @player.set_password(nil)
105     elsif password.split(",").size > 1
106       @gamename, *trip = password.split(",")
107       @player.set_password(trip.join(","))
108     else
109       @player.set_password(password)
110       @gamename = Default_Game_Name
111     end
112     @gamename = self.class.good_game_name?(@gamename) ? @gamename : Default_Game_Name
113   end
114
115   def process
116     super
117     @csa_1st_str = "%%GAME #{@gamename} *"
118   end
119 end
120
121 ######################################################
122 # Processes LOGIN for the extented mode.
123 #
124 class Loginx1 < Login
125   PROTOCOL = "x1"
126
127   def initialize(player, password)
128     super
129     @player.protocol = PROTOCOL
130   end
131   
132   def parse_password(password)
133     @player.set_password(password)
134   end
135
136   def process
137     super
138     @player.write_safe(sprintf("##[LOGIN] +OK %s\n", PROTOCOL))
139   end
140 end
141
142 end # ShogiServer