XDCC-Fetch 1.386

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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