XDCC-Fetch 1.386

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. data/COPYING +23 -0
  2. data/XDCC-Fetch.rbw +54 -0
  3. data/doc/ark.png +0 -0
  4. data/doc/connect_established.png +0 -0
  5. data/doc/index.html +300 -0
  6. data/doc/mega_ark.png +0 -0
  7. data/doc/package.png +0 -0
  8. data/doc/package_unknown.png +0 -0
  9. data/doc/shot1.png +0 -0
  10. data/doc/shot1_mini.png +0 -0
  11. data/doc/shot2.png +0 -0
  12. data/doc/shot2_mini.png +0 -0
  13. data/doc/xdccfetch.css +155 -0
  14. data/icons/ark.png +0 -0
  15. data/icons/ark_big.png +0 -0
  16. data/icons/camera_test.png +0 -0
  17. data/icons/cancel.png +0 -0
  18. data/icons/connect_creating.png +0 -0
  19. data/icons/connect_established.png +0 -0
  20. data/icons/connect_failed.png +0 -0
  21. data/icons/connect_no.png +0 -0
  22. data/icons/edit_add.png +0 -0
  23. data/icons/edit_remove.png +0 -0
  24. data/icons/exit.png +0 -0
  25. data/icons/fileclose.png +0 -0
  26. data/icons/folder_inbox.png +0 -0
  27. data/icons/idea.png +0 -0
  28. data/icons/mega_ark.png +0 -0
  29. data/icons/messagebox_critical.png +0 -0
  30. data/icons/messagebox_info.png +0 -0
  31. data/icons/messagebox_warning.png +0 -0
  32. data/icons/messagebox_warning_small.png +0 -0
  33. data/icons/package.png +0 -0
  34. data/icons/package_favourite.png +0 -0
  35. data/icons/package_unknown.png +0 -0
  36. data/src/Console/Console_Parser.rb +71 -0
  37. data/src/Console/XDCC_Pack_Match_Template.rb +29 -0
  38. data/src/Console/xdcc-fetch.rb +123 -0
  39. data/src/GUI/About_Dialog.rb +50 -0
  40. data/src/GUI/Application_Builder.rb +280 -0
  41. data/src/GUI/Context_Menu.rb +81 -0
  42. data/src/GUI/Custom_Tabs.rb +60 -0
  43. data/src/GUI/Dialog_Box.rb +116 -0
  44. data/src/GUI/Download_Finished_Box.rb +41 -0
  45. data/src/GUI/Empty_Text_Field_Handler.rb +86 -0
  46. data/src/GUI/Gui_Logic.rb +629 -0
  47. data/src/GUI/Icon_Loader.rb +58 -0
  48. data/src/GUI/Main_Window.rb +227 -0
  49. data/src/GUI/Packet_Item.rb +171 -0
  50. data/src/GUI/Packet_List.rb +145 -0
  51. data/src/GUI/Speed_Widget.rb +101 -0
  52. data/src/GUI/Talk_Back.rb +118 -0
  53. data/src/GUI/Toggle_Button.rb +56 -0
  54. data/src/Network/CTCP_Handler.rb +61 -0
  55. data/src/Network/DCC_File.rb +323 -0
  56. data/src/Network/DCC_Parser.rb +71 -0
  57. data/src/Network/IPAddr_Ext.rb +76 -0
  58. data/src/Network/IRC_Message.rb +161 -0
  59. data/src/Network/IRC_Server.rb +273 -0
  60. data/src/Network/IRC_Server_Respond_Map.rb +223 -0
  61. data/src/Network/IRC_User.rb +58 -0
  62. data/src/Network/TCP_Connection.rb +168 -0
  63. data/src/Network/XDCC_Announcement.rb +120 -0
  64. data/src/Network/XDCC_Announcement_Storage.rb +167 -0
  65. data/src/Network/XDCC_Download_Handler.rb +412 -0
  66. data/src/Network/XDCC_Pack.rb +58 -0
  67. data/src/Network/XDCC_Parser.rb +253 -0
  68. data/src/Translations/README +61 -0
  69. data/src/Translations/check_translations +83 -0
  70. data/src/Translations/de.rb +140 -0
  71. data/src/Translations/en.rb +145 -0
  72. data/src/Utilities/Configuration.rb +91 -0
  73. data/src/Utilities/Events.rb +87 -0
  74. data/src/Utilities/Globals.rb +138 -0
  75. data/src/Utilities/PrettyException.rb +1091 -0
  76. data/src/Utilities/Recursive_Open_Struct.rb +159 -0
  77. data/src/Utilities/Timer.rb +71 -0
  78. metadata +135 -0
@@ -0,0 +1,161 @@
1
+ # Copyright (c) 2004-2005, Christoph Heindl
2
+ # All rights reserved.
3
+ #
4
+ # Redistribution and use in source and binary forms, with or without modification,
5
+ # are permitted provided that the following conditions are met:
6
+ #
7
+ # * Redistributions of source code must retain the above copyright notice, this list
8
+ # of conditions and the following disclaimer.
9
+ # * Redistributions in binary form must reproduce the above copyright notice, this list
10
+ # of conditions and the following disclaimer in the documentation and/or other materials
11
+ # provided with the distribution.
12
+ # * Neither the name of Christoph Heindl nor the names of its contributors may be used to
13
+ # endorse or promote products derived from this software without specific prior written
14
+ # permission.
15
+ #
16
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
17
+ # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
18
+ # AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
19
+ # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20
+ # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21
+ # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
22
+ # IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
23
+ # OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24
+
25
+
26
+ # Provides a convient interface for dealing with generic IRC messages.
27
+ # Name of irc users is always downcased for simplicity
28
+ class IRC_Message
29
+ attr_accessor :name, :user, :host #prefix
30
+ attr_accessor :command #command
31
+ attr_reader :parameters #parameters
32
+
33
+ # Construct a IRC_Message based on a command and variable length
34
+ # command parameters
35
+ def initialize(command=nil, *params)
36
+ @name = nil
37
+ @user = nil
38
+ @parameters = Array.new
39
+ @command = command
40
+ @ctcp_reply = false
41
+ @ctcp_command = false
42
+ params.each do |param|
43
+ self.add_parameter(param)
44
+ end
45
+ end
46
+
47
+ # Add a parameter
48
+ # If parameter equals a ctcp message, appropriate actions (\001 is being removed and internal stati are set) are taken.
49
+ def add_parameter(param)
50
+ if @parameters.length < 14
51
+ if param =~ /^\001[^\001]*\001$/
52
+ param.gsub!(/\001/, "")
53
+ if @command == "PRIVMSG"
54
+ @ctcp_command = true
55
+ elsif @command == "NOTICE"
56
+ @ctcp_reply = true
57
+ end
58
+ end
59
+ @parameters.push(param)
60
+ end
61
+ end
62
+
63
+ # Is a message prefix available
64
+ def prefix?
65
+ @name || (@user && @host)
66
+ end
67
+
68
+ # Is message origin a user or server
69
+ def usermessage?
70
+ self.prefix? && @user && @host
71
+ end
72
+
73
+ # Are there any parameters
74
+ def parameters?
75
+ @parameters.length > 0
76
+ end
77
+
78
+ # Does the message contain a non-irc standard ctcp part
79
+ def ctcp?
80
+ @ctcp_repy || @ctcp_command
81
+ end
82
+
83
+ # Is the message a ctcp command?
84
+ def ctcp_command?
85
+ @ctcp_command
86
+ end
87
+
88
+ # Is the message a ctcp reply?
89
+ def ctcp_reply?
90
+ @ctcp_reply
91
+ end
92
+
93
+ # Assemble an irc-protocol conform message.
94
+ def to_s
95
+ s = ""
96
+ s += ":" + @name if self.prefix?
97
+ s += "!" + @user + "@" + @host if self.usermessage?
98
+ s += " " if self.prefix?
99
+ s += @command
100
+ parameters.each do |param|
101
+ s += " "
102
+ if param.include?(" ")
103
+ s += ":"
104
+ s += "\001" if self.ctcp?
105
+ s += param
106
+ s += "\001" if self.ctcp?
107
+ else
108
+ s += param
109
+ end
110
+ end
111
+ s += "\r\n"
112
+ end
113
+
114
+ # -- class methods
115
+
116
+ # Construct a IRC_Message object from a string. Returns a IRC_Message or nil on error
117
+ def IRC_Message.parse(str)
118
+ irc_msg = nil
119
+ #split string into [prefix] command [arguments]
120
+ str_no_crlf = str.chop
121
+ if mdMessage = $cfg.network.irc.msg_regexp.match(str_no_crlf)
122
+ irc_msg = IRC_Message.new
123
+ #parse prefix if available
124
+ if mdMessage[1] && mdPrefix = $cfg.network.irc.prefix_regexp.match(mdMessage[1])
125
+ irc_msg.name = mdPrefix[1]
126
+ irc_msg.user = mdPrefix[2] unless mdPrefix[2].empty?
127
+ irc_msg.host = mdPrefix[3] unless mdPrefix[3].empty?
128
+ end
129
+ #set command
130
+ irc_msg.command = mdMessage[2]
131
+ #parse parameters if available
132
+ if !mdMessage[3].empty?
133
+ # parameter is either a string enclosed by spaces or the remainding line if parameter
134
+ # starts with ':'
135
+ mdMessage[3].scan($cfg.network.irc.params_regexp) do |param|
136
+ # remove possible leading colons and trailing spaces and add to parameters
137
+ irc_msg.add_parameter(param.sub(/^:/, "").sub(/\s*$/, ""))
138
+ end
139
+ end
140
+ end
141
+ irc_msg
142
+ end
143
+
144
+ # Delete any color codes, font modes from the given str
145
+ # These control characters are based on the unofficial mirc implementation
146
+ # Returns clean version of message
147
+ # \002 => Bold
148
+ # \003[??][,??] => Forground color, background color
149
+ # \x0F => Switch back to plain mode
150
+ # \x16 => Reverse mode
151
+ # 0x1F => Underline
152
+ def IRC_Message.delete_control_codes(str)
153
+ str.gsub(/\002|\003(\d{1,2})?(,\d{1,2})?|\x0F|\x16|\x1F/, "")
154
+ end
155
+
156
+ # Deletes all trailing and leading spaces from a string
157
+ # Returns clean string
158
+ def IRC_Message.delete_spaces(str)
159
+ str.gsub(/^\s+|\s+$/, "")
160
+ end
161
+ end
@@ -0,0 +1,273 @@
1
+ # Copyright (c) 2004-2005, Christoph Heindl
2
+ # All rights reserved.
3
+ #
4
+ # Redistribution and use in source and binary forms, with or without modification,
5
+ # are permitted provided that the following conditions are met:
6
+ #
7
+ # * Redistributions of source code must retain the above copyright notice, this list
8
+ # of conditions and the following disclaimer.
9
+ # * Redistributions in binary form must reproduce the above copyright notice, this list
10
+ # of conditions and the following disclaimer in the documentation and/or other materials
11
+ # provided with the distribution.
12
+ # * Neither the name of Christoph Heindl nor the names of its contributors may be used to
13
+ # endorse or promote products derived from this software without specific prior written
14
+ # permission.
15
+ #
16
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
17
+ # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
18
+ # AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
19
+ # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20
+ # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21
+ # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
22
+ # IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
23
+ # OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24
+
25
+
26
+ require 'src/Network/TCP_Connection.rb'
27
+ require 'src/Network/IRC_Message.rb'
28
+ require 'src/Network/IRC_User.rb'
29
+ require 'src/Network/IRC_Server_Respond_Map.rb'
30
+ require 'src/Network/DCC_Parser.rb'
31
+ require 'src/Network/CTCP_Handler.rb'
32
+
33
+ # The IRC_Server class represents a connection to an irc server. It allows the caller to connect/disconnect to/from a
34
+ # server as well as register for various events. Administrative maintainance of connection is done automatically.
35
+ # The server also keeps a list of IRC_Users it encounters (on channel join, private message, etc..) up to date.
36
+ class IRC_Server
37
+ include IRC_Server_Respond_Map, Event_Publisher
38
+
39
+ # Corresponds to a irc_user object, which represents us. Nil before connection established
40
+ attr_reader :me
41
+ # Password, if any, used for registration
42
+ attr_reader :password
43
+ # DCC parser responsible for recognizing initial dcc requests
44
+ attr_reader :dcc_parser
45
+
46
+ # -- Connectable Events
47
+
48
+ # Whenever an irc message is received. Args: IRC_Message
49
+ ON_IRC_MESSAGE = Event_Publisher.next_global_eventID
50
+
51
+ # IRC registration with server complete. Args: none
52
+ ON_SERVER_REGISTERED = Event_Publisher.next_global_eventID
53
+ # When we quit from irc, or connection to server was lost. Args: errormessage or nil
54
+ ON_SERVER_DISCONNECTED = Event_Publisher.next_global_eventID
55
+ # When we connection to server has been established. Args: none
56
+ ON_SERVER_CONNECTED = Event_Publisher.next_global_eventID
57
+
58
+ # On user joined channel. Args: IRC_User, channel
59
+ ON_USER_JOIN = Event_Publisher.next_global_eventID
60
+ # On user left channel. Args: IRC_User, channel, partmessage[?]
61
+ ON_USER_PART = Event_Publisher.next_global_eventID
62
+ # Whenever someone is kicked from a channel. Args: IRC_User, channel, kickmessage[?]
63
+ ON_USER_KICK = Event_Publisher.next_global_eventID
64
+ # On user quit. Args: IRC_User, quitmessage[?]
65
+ ON_USER_QUIT = Event_Publisher.next_global_eventID
66
+ # On user changed its nick. Args: updated IRC_User, old nick
67
+ ON_USER_NICK = Event_Publisher.next_global_eventID
68
+ # Whenever changing a nick failed. Args: nickname, errormessage
69
+ ON_USER_NICK_ERROR = Event_Publisher.next_global_eventID
70
+ # On user sent a message. Args: IRC_User, message, target[+], raw IRC_Message
71
+ # This contains private messages and notices
72
+ ON_USER_MESSAGE = Event_Publisher.next_global_eventID
73
+
74
+ # On userlist of channel. Args: channel, [status, IRC_User][+]
75
+ ON_CHANNEL_USER_LIST = Event_Publisher.next_global_eventID
76
+ # On channel topic notification. Args: channelname, topic
77
+ ON_CHANNEL_TOPIC = Event_Publisher.next_global_eventID
78
+
79
+ # Whenever an unknown user appears. Args: IRC_User
80
+ ON_USER_APPEAR_CUSTOM = Event_Publisher.next_global_eventID
81
+ # Whenever a channel has been sucessfully joined by us. Args: channelname
82
+ ON_CHANNEL_JOIN_SUCCESS = Event_Publisher.next_global_eventID
83
+ # Whenever a channel join was unsuccessful. Args: channelname, errormessage
84
+ ON_CHANNEL_JOIN_ERROR = Event_Publisher.next_global_eventID
85
+
86
+ # All server side events packed in one
87
+ ON_ALL_SERVER_EVENTS = ON_SERVER_REGISTERED|
88
+ ON_SERVER_DISCONNECTED|
89
+ ON_SERVER_CONNECTED|
90
+ ON_IRC_MESSAGE
91
+
92
+
93
+ # All user events packaged in one
94
+ ON_ALL_USER_EVENTS = ON_USER_JOIN|
95
+ ON_USER_PART|
96
+ ON_USER_QUIT|
97
+ ON_USER_NICK|
98
+ ON_USER_KICK|
99
+ ON_USER_NICK_ERROR|
100
+ ON_USER_MESSAGE
101
+
102
+ # All channel events packaged in one
103
+ ON_ALL_CHANNEL_EVENTS = ON_CHANNEL_USER_LIST|
104
+ ON_CHANNEL_TOPIC
105
+
106
+ # All custom events packaged in one
107
+ ON_ALL_CUSTOM_EVENTS = ON_USER_APPEAR_CUSTOM|
108
+ ON_CHANNEL_JOIN_SUCCESS|
109
+ ON_CHANNEL_JOIN_ERROR
110
+
111
+ # All events packaged in one
112
+ ON_ALL_EVENTS = ON_ALL_SERVER_EVENTS|
113
+ ON_ALL_USER_EVENTS|
114
+ ON_ALL_CHANNEL_EVENTS|
115
+ ON_ALL_CUSTOM_EVENTS
116
+
117
+ def initialize
118
+ @tcp_con = nil
119
+ @registered = false
120
+ @command_queue = Array.new
121
+ @user_list = Hash.new
122
+ @me = nil
123
+ init_respond_map
124
+ self.init_events
125
+ @dcc_parser = DCC_Parser.new(self)
126
+ @ctcp_handler = CTCP_Handler.new(self)
127
+ end
128
+
129
+ # -- Connection Management
130
+
131
+ # Connect to specified server/port using the given user info
132
+ def connect(server, port, nick, user, password=nil)
133
+ if !self.connected?
134
+ #command queue is only allowed during the phase of registration
135
+ @command_queue.clear
136
+ @user_list.clear
137
+ @password = password
138
+ @me = IRC_User.new(nick, self)
139
+ @me.user = user
140
+ @user_list[@me.name.downcase] = @me
141
+ @tcp_con = TCP_Connection.text
142
+ @tcp_con.connect_to_events(TCP_Connection::ON_ALL_EVENTS, self)
143
+ @tcp_con.open(server, port)
144
+ end
145
+ end
146
+
147
+ # Disconnect from server using the given quit message
148
+ def disconnect(quitmessage="Using XDCC-Fetch")
149
+ if self.connected?
150
+ self.send(IRC_Message.new("QUIT", quitmessage))
151
+ @tcp_con.close if @tcp_con
152
+ end
153
+ end
154
+
155
+ # Send a IRC_Message to the server we are registered to.
156
+ # If not yet registered, command is added to the command queue
157
+ # and will be executed once we are registered
158
+ def send(irc_msg)
159
+ if self.registered?
160
+ @tcp_con.send(irc_msg.to_s)
161
+ else
162
+ @command_queue.push(irc_msg)
163
+ end
164
+ end
165
+
166
+ # -- Status queries
167
+
168
+ # Are we connected yet
169
+ def connected?
170
+ @tcp_con && @tcp_con.connected?
171
+ end
172
+
173
+ # Was registration successful
174
+ def registered?
175
+ self.connected? && @registered
176
+ end
177
+
178
+ # -- Channel management methods
179
+
180
+ def join(channel, password=nil)
181
+ msg = IRC_Message.new("JOIN")
182
+ msg.add_parameter(channel)
183
+ msg.add_parameter(password) if password
184
+ self.send(msg)
185
+ end
186
+
187
+ def part(channel)
188
+ self.send(IRC_Message.new("PART", channel))
189
+ end
190
+
191
+ # -- User management methods
192
+
193
+ # Update user_list by adding non-existant IRC_Users and/or
194
+ # modifying existing ones
195
+ def update_user_list(irc_msg)
196
+ user = nil
197
+ event = false
198
+ if irc_msg.prefix?
199
+ user = @user_list[irc_msg.name.downcase]
200
+ if !user
201
+ # new user detected
202
+ user = IRC_User.new(irc_msg.name, self)
203
+ @user_list[user.name.downcase] = user
204
+ event = true
205
+ end
206
+ user.user = irc_msg.user if irc_msg.user
207
+ user.host = irc_msg.host if irc_msg.host
208
+ if event
209
+ self.fire_event(ON_USER_APPEAR_CUSTOM, user)
210
+ end
211
+ end
212
+ user
213
+ end
214
+
215
+ # Add user by name
216
+ def add_user(name)
217
+ user = nil
218
+ user = @user_list[name.downcase]
219
+ if !user
220
+ # New user
221
+ user = IRC_User.new(irc_msg.name, self)
222
+ @user_list[name.downcase] = user
223
+ end
224
+ user
225
+ end
226
+
227
+ # Retrieve single user by given name
228
+ def get_user_by_name(username)
229
+ @user_list[username]
230
+ end
231
+
232
+ # Loop through all users and yield those users matching the given regexp
233
+ def scan_users_by_name(regexp)
234
+ @user_list.values.each do |user|
235
+ if user.name =~ regexp
236
+ yield user
237
+ end
238
+ end
239
+ end
240
+
241
+ # -- TCP_Connection notify methods
242
+
243
+ def on_event(caller, event, eventargs)
244
+ if caller == @tcp_con
245
+ case event
246
+ when TCP_Connection::ON_CONNECTED
247
+ # Try registering with service, using the parameters given
248
+ @tcp_con.send(IRC_Message.new("PASS", @password).to_s) if @password
249
+ @tcp_con.send(IRC_Message.new("NICK", @me.name).to_s)
250
+ @tcp_con.send(IRC_Message.new("USER", @me.user, "0", "*", "XDCC-Fetcher client").to_s)
251
+ self.fire_event(ON_SERVER_CONNECTED)
252
+
253
+ when TCP_Connection::ON_DATA
254
+ msg = IRC_Message.parse(eventargs[0])
255
+ # Find appropriate action for received data and respond appropriate
256
+ # See IRC_Server_Respond_Map
257
+ respond_to(msg)
258
+
259
+
260
+ when TCP_Connection::ON_CLOSED
261
+ @registered = false
262
+ @tcp_con.disconnect_from_events(TCP_Connection::ON_ALL_EVENTS, self) if @tcp_con
263
+ self.fire_event(ON_SERVER_DISCONNECTED, nil)
264
+
265
+ when TCP_Connection::ON_ERROR
266
+ @registered = false
267
+ @tcp_con.disconnect_from_events(TCP_Connection::ON_ALL_EVENTS, self) if @tcp_con
268
+ self.fire_event(ON_SERVER_DISCONNECTED, eventargs[0])
269
+
270
+ end
271
+ end
272
+ end
273
+ end
@@ -0,0 +1,223 @@
1
+ # Copyright (c) 2004-2005, Christoph Heindl
2
+ # All rights reserved.
3
+ #
4
+ # Redistribution and use in source and binary forms, with or without modification,
5
+ # are permitted provided that the following conditions are met:
6
+ #
7
+ # * Redistributions of source code must retain the above copyright notice, this list
8
+ # of conditions and the following disclaimer.
9
+ # * Redistributions in binary form must reproduce the above copyright notice, this list
10
+ # of conditions and the following disclaimer in the documentation and/or other materials
11
+ # provided with the distribution.
12
+ # * Neither the name of Christoph Heindl nor the names of its contributors may be used to
13
+ # endorse or promote products derived from this software without specific prior written
14
+ # permission.
15
+ #
16
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
17
+ # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
18
+ # AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
19
+ # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20
+ # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21
+ # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
22
+ # IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
23
+ # OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24
+
25
+
26
+ # The respond map is used within the context of the IRC_Server in order to react
27
+ # appropriate to the received command/query. The first array element has to be successfully
28
+ # matched (regexp) against the IRC_Message.command in order to execute the proc object,
29
+ # which equals the second array element
30
+ module IRC_Server_Respond_Map
31
+ def init_respond_map
32
+ @respond_map = [
33
+
34
+ # -- misc
35
+
36
+ # Any irc message
37
+ # Action: forward message to listeners
38
+ [
39
+ /.*/,
40
+ proc do |irc_msg|
41
+ self.fire_event(IRC_Server::ON_IRC_MESSAGE, irc_msg)
42
+ end
43
+ ],
44
+
45
+ # -- service messages
46
+
47
+ # PING
48
+ # Action: send PONG to server
49
+ [
50
+ /PING/i,
51
+ proc do |irc_msg|
52
+ # Do not enqueue message if not yet registered.
53
+ # Some servers do send a PING message as part of registration process.
54
+ @tcp_con.send(IRC_Message.new("PONG", irc_msg.parameters[0]).to_s)
55
+ end
56
+ ],
57
+
58
+ # -- channel management
59
+
60
+ # RPL_NAMREPLY
61
+ # Action: extract usernames and stati, forward to listeners, update user_list
62
+ [
63
+ /353/,
64
+ proc do |irc_msg|
65
+ channel = irc_msg.parameters[2]
66
+ users = irc_msg.parameters[3].scan(/([@+])?(\S+)/)
67
+ channel_users = []
68
+ # Store new users in irc_server user list
69
+ users.each do |user|
70
+ @user_list[user[1]] ||= IRC_User.new(user[1], self)
71
+ channel_users.push([user[0], @user_list[user[1]]])
72
+ end
73
+ self.fire_event(IRC_Server::ON_CHANNEL_USER_LIST, channel, channel_users)
74
+ end
75
+ ],
76
+
77
+ # RPL_ENDOFNAMES
78
+ # Action: trigger join channel success
79
+ [
80
+ /366/,
81
+ proc do |irc_msg|
82
+ self.fire_event(IRC_Server::ON_CHANNEL_JOIN_SUCCESS, irc_msg.parameters[1])
83
+ end
84
+ ],
85
+
86
+ # Error messages when joining a channel
87
+ #ERR_BANNEDFROMCHAN
88
+ #ERR_INVITEONLYCHAN ERR_BADCHANNELKEY
89
+ #ERR_CHANNELISFULL ERR_BADCHANMASK
90
+ #ERR_NOSUCHCHANNEL ERR_TOOMANYCHANNELS
91
+ [
92
+ /474|473|475|471|476|403|405/,
93
+ proc do |irc_msg|
94
+ self.fire_event(IRC_Server::ON_CHANNEL_JOIN_ERROR, irc_msg.parameters[1], irc_msg.parameters[2])
95
+ end
96
+ ],
97
+
98
+ # KICK
99
+ # Action: Inform listeners
100
+ [
101
+ /KICK/,
102
+ proc do |irc_msg|
103
+ irc_user = @user_list[irc_msg.parameters[1]]
104
+ if (irc_user)
105
+ self.fire_event(IRC_Server::ON_USER_KICK, irc_user, irc_msg.parameters[0], irc_msg.parameters[2])
106
+ end
107
+ end
108
+ ],
109
+
110
+ # -- user management
111
+
112
+ # JOIN
113
+ # Action: Update user_list, inform listeners
114
+ [
115
+ /JOIN/i,
116
+ proc do |irc_msg|
117
+ user = self.update_user_list(irc_msg)
118
+ self.fire_event(IRC_Server::ON_USER_JOIN, user, irc_msg.parameters[0])
119
+ end
120
+ ],
121
+
122
+ # PART
123
+ # Action: update user_list, inform listeners
124
+ [
125
+ /PART/i,
126
+ proc do |irc_msg|
127
+ user = self.update_user_list(irc_msg)
128
+ self.fire_event(
129
+ IRC_Server::ON_USER_PART,
130
+ user,
131
+ irc_msg.parameters[0],
132
+ irc_msg.parameters[1])
133
+ end
134
+ ],
135
+
136
+ # NICK
137
+ # Action: update user_list, inform listeners
138
+ [
139
+ /NICK/i,
140
+ proc do |irc_msg|
141
+ # Get user from user_list, possibly update data
142
+ user = self.update_user_list(irc_msg)
143
+ # Delete old user
144
+ new_user = @user_list.delete(user.name.downcase)
145
+ new_user.name = irc_msg.parameters[0]
146
+ @user_list[new_user.name.downcase] = new_user
147
+ self.fire_event(
148
+ IRC_Server::ON_USER_NICK,
149
+ new_user,
150
+ user.name)
151
+ end
152
+ ],
153
+
154
+ # NICK errors
155
+ # ERR_NONICKNAMEGIVEN
156
+ # ERR_ERRONEUSNICKNAME (invalid nickname)
157
+ # ERR_NICKNAMEINUSE
158
+ # ERR_NICKCOLLISION
159
+ [
160
+ /431|432|433|436/,
161
+ proc do |irc_msg|
162
+ self.fire_event(IRC_Server::ON_USER_NICK_ERROR, irc_msg.parameters[1], irc_msg.parameters[2])
163
+ end
164
+ ],
165
+
166
+
167
+
168
+ # QUIT
169
+ # Action: update user_list and inform listeners
170
+ [
171
+ /QUIT/i,
172
+ proc do |irc_msg|
173
+ user = @user_list.delete(irc_msg.name)
174
+ if user
175
+ self.fire_event(IRC_Server::ON_USER_QUIT, user, irc_msg.parameters[0])
176
+ end
177
+ end
178
+ ],
179
+
180
+ # PRIVMSG && NOTICE
181
+ # Action: inform listeners
182
+ [
183
+ /PRIVMSG|NOTICE/i,
184
+ proc do |irc_msg|
185
+ user = @user_list[irc_msg.name]
186
+ if !user
187
+ # private message from unknown user
188
+ user = IRC_User.new(irc_msg.name, self)
189
+ user.user = irc_msg.user
190
+ user.host = irc_msg.host
191
+ @user_list[user.name] = user
192
+ end
193
+ msg = irc_msg.parameters[-1]
194
+ targets = irc_msg.parameters[0..-2]
195
+ self.fire_event(IRC_Server::ON_USER_MESSAGE, user, msg, targets, irc_msg)
196
+ end
197
+ ],
198
+
199
+ # -- others
200
+
201
+ # RPL_WELCOME
202
+ # Action: mark irc_server registered and inform listeners. Send queued commands
203
+ [
204
+ /001/,
205
+ proc do |irc_msg|
206
+ @registered = true
207
+ self.fire_event(IRC_Server::ON_SERVER_REGISTERED)
208
+ @command_queue.each do |cmd|
209
+ self.send(cmd)
210
+ end
211
+ @command_queue.clear
212
+ end
213
+ ]
214
+ ]
215
+ end
216
+
217
+ def respond_to(msg)
218
+ @respond_map.each do |response|
219
+ response[1].call(msg) if msg.command =~ response[0]
220
+ end
221
+ end
222
+
223
+ end