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,412 @@
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/DCC_File.rb'
27
+ require 'src/Utilities/Events.rb'
28
+ require 'src/Utilities/Timer.rb'
29
+
30
+ require 'digest/md5'
31
+
32
+ # Handles all downloads from a single bot.
33
+ # Only one pack at a time is allowed to be downloaded/queued from/at the bot. However,
34
+ # more than one pack may be added to the handler, which in turn will be stored in a local queue
35
+ # and be processed when a download finished/was cancelled.
36
+ #
37
+ # Supports the generation of md5 sums on the fly. However, md5 is unavailable for resumed
38
+ # packs, as (of now) ruby does not support marshaling of md5 objects. Therefore, md5 context
39
+ # generation would require running through the entire (partly) downloaded file. As this would be
40
+ # to time consuming, md5 support has been disabled for resumed packs. However, as soon as marshaling
41
+ # md5 objects is supported in ruby, md5 support may come available for resumed packs.
42
+ #
43
+ # Handling multiple packs simultaneously from a single bot is very challenging, since the bot's
44
+ # status messages don't provide enough differentiation characteristics in order to assign them
45
+ # to a single pack. Thats why only one pack is allowed at a time.
46
+ class XDCC_Download_Handler
47
+ include Event_Publisher
48
+
49
+ # Timer used for detecting various stalled cases
50
+ @@timer = Timer.new(3)
51
+
52
+ # The xdcc bot we are dealing with
53
+ attr_reader :irc_user_bot
54
+ # Current XDCC_Pack
55
+ attr_reader :current_pack
56
+ # Current XDCC_Pack status
57
+ attr_reader :current_pack_status
58
+ # Real filename of where pack is downloaded to
59
+ attr_reader :current_pack_filename
60
+ # ipaddr of bot we are connecting to
61
+
62
+ # -- Connectable events
63
+
64
+ # Before the Handler shuts down. Args: none
65
+ ON_SHUTDOWN = Event_Publisher.next_global_eventID
66
+
67
+ # When a pack gets requested. Args: pack
68
+ ON_PACK_REQUESTED = Event_Publisher.next_global_eventID
69
+
70
+ # When a pack is queued locally, because another pack is already in progress.
71
+ # Also triggered if an update of the local queue happens.
72
+ # Args: pack, local queue position, local queue length
73
+ ON_QUEUED_LOCALLY = Event_Publisher.next_global_eventID
74
+
75
+ # When no free slots are available and the item gets remotely queued.
76
+ # Also triggered if an update of the remote queue happens
77
+ # Args: pack, (remote queue position||nil)
78
+ ON_QUEUED_REMOTELY = Event_Publisher.next_global_eventID
79
+
80
+ # Whenever a download started. Args: pack, filename where pack data is stored to
81
+ ON_DOWNLOAD_STARTED = Event_Publisher.next_global_eventID
82
+
83
+ # Whenever a download finished. Args: pack
84
+ ON_DOWNLOAD_FINISHED = Event_Publisher.next_global_eventID
85
+
86
+ # When we receive a delayed md5 status. Args: pack, md5status
87
+ ON_MD5_STATUS = Event_Publisher.next_global_eventID
88
+
89
+ # Whenever a download failed. Args: pack, errormessage?
90
+ ON_DOWNLOAD_FAILED = Event_Publisher.next_global_eventID
91
+
92
+ # Every timespan_download_progress seconds (update of progress).
93
+ # Args: pack, percent completed, nr of bytes received, nr of kilo bytes per second
94
+ ON_DOWNLOAD_PROGRESS = Event_Publisher.next_global_eventID
95
+
96
+ # All events packed in one
97
+ ON_ALL_EVENTS = ON_SHUTDOWN|
98
+ ON_PACK_REQUESTED|
99
+ ON_QUEUED_LOCALLY|
100
+ ON_QUEUED_REMOTELY|
101
+ ON_DOWNLOAD_STARTED|
102
+ ON_DOWNLOAD_FINISHED|
103
+ ON_DOWNLOAD_FAILED|
104
+ ON_DOWNLOAD_PROGRESS|
105
+ ON_MD5_STATUS
106
+
107
+ # -- Other constants
108
+
109
+ # MD5 is disabled in the settings
110
+ MD5_DISABLED = 0
111
+
112
+ # MD5 is enabled, but we are waiting for a delayed md5 checksum message
113
+ # MD5 is enabled, but pack was resumed
114
+ MD5_UNAVAILABLE = 1
115
+
116
+ # MD5 checksum matches the transferred data
117
+ MD5_OK = 2
118
+
119
+ # MD5 checksum failed to match transferred data
120
+ MD5_FAILED = 3
121
+
122
+
123
+ # Initialize with irc_user_bot
124
+ def initialize(irc_user_bot)
125
+ @mutex = Mutex.new # Mutex used to synchronize
126
+ @irc_user_bot = irc_user_bot
127
+ @server = irc_user_bot.irc_server # The server the bot is on
128
+ @current_pack = nil # Pack which has the focus of the handler
129
+ @current_pack_status = -1 # Status of current pack. -1 indicates no status yet. Else one of the following:
130
+ # ON_PACK_REQUESTED, ON_QUEUED_REMOTELY, ON_DOWNLOAD_STARTED,
131
+ # ON_DOWNLOAD_FINISHED
132
+ @current_pack_md5 = nil # MD5 object used for computation of md5 checksum for current_pack
133
+ @last_packs = Array.new # The packs we have dealt last with. Earlier packs are at the beginning of the queue
134
+ @request_timestamp = nil # The time the pack was requested
135
+ @delay_timestamp = nil # Timestamp when pack was delayed
136
+ @delay_timeout = nil # Timeout (secs) to pass by before requesting next pack
137
+ @current_download_path = nil # Path where to store the current pack
138
+ @current_request_cnt = 0 # Number of times this pack was requested
139
+
140
+ @local_pack_queue = Array.new # Locally queued packs. Each element is a 2 element array of [pack, downloadpath]
141
+
142
+ @server.connect_to_events(IRC_Server::ON_USER_MESSAGE |
143
+ IRC_Server::ON_USER_QUIT|
144
+ IRC_Server::ON_SERVER_DISCONNECTED,
145
+ self)
146
+
147
+ @server.dcc_parser.connect_to_events(DCC_Parser::ON_DCC_SEND, self)
148
+ # Only one TCP connection is used per bot
149
+ @dcc_con = DCC_File.new
150
+ @dcc_con.connect_to_events(DCC_File::ON_ALL_EVENTS, self)
151
+ @@timer.connect_to_events(Timer::ON_TIMER, self)
152
+ self.init_events
153
+ end
154
+
155
+ # Disconnect from events, close all file/socket handles
156
+ def shutdown
157
+ @dcc_con.close
158
+ @irc_user_bot.irc_server.disconnect_from_events(
159
+ IRC_Server::ON_USER_MESSAGE |
160
+ IRC_Server::ON_USER_QUIT|
161
+ IRC_Server::ON_SERVER_DISCONNECTED, self)
162
+ @server.dcc_parser.disconnect_from_events(DCC_Parser::ON_DCC_SEND, self)
163
+ @@timer.disconnect_from_events(Timer::ON_TIMER, self)
164
+ end
165
+
166
+ # Add a pack to download and it's destination directory (without trailing deliminator)
167
+ def add_pack(xdcc_pack, path)
168
+ @mutex.synchronize do
169
+ if !@current_pack && @local_pack_queue.empty?
170
+ self.request_pack(xdcc_pack, path)
171
+ else
172
+ self.queue_pack(xdcc_pack, path)
173
+ end
174
+ end
175
+ end
176
+
177
+ # Request the given pack and set internal stati
178
+ def request_pack(xdcc_pack, path)
179
+ @request_timestamp = Time.now
180
+ @current_request_cnt += 1
181
+ @current_pack = xdcc_pack
182
+ @current_pack_status = ON_PACK_REQUESTED
183
+ @current_download_path = path
184
+ @irc_user_bot.send("XDCC SEND ##{@current_pack.pack_nr}")
185
+ self.fire_event(ON_PACK_REQUESTED, @current_pack)
186
+ end
187
+
188
+ # Queue pack locally
189
+ def queue_pack(xdcc_pack, path)
190
+ @local_pack_queue << [xdcc_pack, path]
191
+ self.local_queue_change
192
+ end
193
+
194
+ # Prepare next pack (if there is one) for download.
195
+ # If delay != 0, preparation of next pack will be delayed at least
196
+ # delay seconds (depending on the timer)
197
+ def next_pack(delay=0)
198
+ @mutex.synchronize do
199
+ # Enqueue all packs that have completed downloading and are waiting for
200
+ # an md5 checksum from bot
201
+ if $cfg.network.xdcc.enable_md5 && @current_pack_status == ON_DOWNLOAD_FINISHED && @current_pack_md5
202
+ @last_packs << [@current_pack, @current_pack_md5]
203
+ end
204
+ @current_pack_md5 = nil
205
+ end
206
+ if delay > 0
207
+ # Delayed request of next pack
208
+ @delay_timestamp = Time.now
209
+ @delay_timeout = delay
210
+ return
211
+ else
212
+ @delay_timestamp = nil
213
+ end
214
+ @current_request_cnt = 0
215
+ if !@local_pack_queue.empty?
216
+ pack, path = @local_pack_queue.delete_at(0)
217
+ self.request_pack(pack, path)
218
+ # Update remaining queue positions
219
+ self.local_queue_change
220
+ else
221
+ @mutex.synchronize do
222
+ @current_pack = nil
223
+ @current_pack_status = -1
224
+ @current_download_path = nil
225
+ end
226
+ end
227
+ end
228
+
229
+ # Reset handler to empty state
230
+ # There should not be any reason for this method to be called from outside
231
+ def empty_state!
232
+ @mutex.synchronize do
233
+ @current_pack = nil
234
+ @current_pack_status = -1
235
+ @current_download_path = nil
236
+ @delay_timestamp = nil
237
+ @local_pack_queue.clear
238
+ end
239
+ end
240
+
241
+ # Is the handler in empty state? (i.e contains no packs to download)
242
+ def empty_state?
243
+ @mutex.synchronize do
244
+ !@current_pack && @current_pack_status == -1
245
+ end
246
+ end
247
+
248
+ # Inform all ON_QUEUED_LOCALLY listeners that there was
249
+ # an update in the local queue
250
+ def local_queue_change
251
+ length = @local_pack_queue.length
252
+ @local_pack_queue.each_with_index do |pack_info, index|
253
+ self.fire_event(ON_QUEUED_LOCALLY, pack_info[0], index + 1, length)
254
+ end
255
+ end
256
+
257
+ # Cancel the specified pack using the given reason.
258
+ # This works for packs that have one of the following stati:
259
+ # ON_QUEUED_LOCALLY, ON_QUEUED_REMOTELY, ON_DOWNLOAD_STARTED
260
+ def cancel_pack(xdcc_pack, reason=$cfg.text.network.xdcc.cancel_download_default)
261
+ pack = nil
262
+ nextpack = false
263
+ @mutex.synchronize do
264
+ if xdcc_pack == @current_pack
265
+ pack = @current_pack
266
+ # Check if remotely queued
267
+ if @current_pack_status == ON_QUEUED_REMOTELY
268
+ @irc_user_bot.send("XDCC REMOVE")
269
+ @current_pack_status = ON_DOWNLOAD_FAILED if pack
270
+ self.fire_event(ON_DOWNLOAD_FAILED, pack, reason) if pack
271
+ nextpack = true
272
+ # Check if download started
273
+ elsif @current_pack_status == ON_DOWNLOAD_STARTED
274
+ @dcc_con.close if pack
275
+ @current_pack_status = ON_DOWNLOAD_FAILED if pack
276
+ self.fire_event(ON_DOWNLOAD_FAILED, pack, reason) if pack
277
+ nextpack = true
278
+ elsif @current_pack_status == ON_PACK_REQUESTED
279
+ @dcc_con.close if pack
280
+ @current_pack_status = ON_DOWNLOAD_FAILED if pack
281
+ self.fire_event(ON_DOWNLOAD_FAILED, pack, reason) if pack
282
+ nextpack = true
283
+ end
284
+ else
285
+ # Check locally queued packs
286
+ @local_pack_queue.delete_if do |p|
287
+ ret = p[0] == xdcc_pack
288
+ pack = xdcc_pack if ret
289
+ self.fire_event(ON_DOWNLOAD_FAILED, pack, reason) if ret
290
+ ret
291
+ end
292
+ # Update local queue
293
+ self.local_queue_change if pack
294
+ end
295
+ end
296
+ if next_pack
297
+ self.next_pack(5)
298
+ end
299
+ end
300
+
301
+ # Deal with delayed md5 checksum received from bot
302
+ def handle_delayed_md5(received_md5)
303
+ if !@last_packs.empty?
304
+ pack, md5 = @last_packs.delete_at(0)
305
+ return if !md5
306
+ md5_ok = (md5.hexdigest == received_md5)
307
+ self.fire_event(ON_MD5_STATUS, pack, md5_ok ? MD5_OK : MD5_FAILED)
308
+ end
309
+ end
310
+
311
+ # Event handler
312
+ def on_event(caller, event, eventargs)
313
+ case event
314
+ when IRC_Server::ON_USER_MESSAGE
315
+ # Check for private bot message
316
+ if (@irc_user_bot != eventargs[0] || !@server.me.has_name?(eventargs[2][0]))
317
+ return
318
+ end
319
+ irc_msg = eventargs[3]
320
+ message = eventargs[1]
321
+ # Prolly a status update of the bot
322
+ if status = $cfg.network.xdcc.queue_add_regexp.match(message)
323
+ # Pack has been added to the remote queue.
324
+ @current_pack_status = ON_QUEUED_REMOTELY
325
+ self.fire_event(ON_QUEUED_REMOTELY, @current_pack, status[1].to_i, nil)
326
+ elsif status = $cfg.network.xdcc.queue_full_regexp.match(message)
327
+ # Queue is full, enqueue current pack and wait before requesting next pack
328
+ self.add_pack(@current_pack, @current_download_path)
329
+ self.next_pack($cfg.network.xdcc.queue_full_wait)
330
+ elsif status = $cfg.network.xdcc.is_queued_regexp.match(message)
331
+ # This shouldn't ever occur...
332
+ @mutex.synchronize do
333
+ @current_pack_status = ON_DOWNLOAD_FAILED
334
+ end
335
+ self.fire_event(ON_DOWNLOAD_FAILED, @current_pack, $cfg.text.network.xdcc.err_pack_already_requested)
336
+ self.next_pack($cfg.network.xdcc.is_queued_wait)
337
+ elsif status = $cfg.network.xdcc.max_queued_regexp.match(message)
338
+ # As shouldn't this...
339
+ @mutex.synchronize do
340
+ @current_pack_status = ON_DOWNLOAD_FAILED
341
+ end
342
+ self.fire_event(ON_DOWNLOAD_FAILED, @current_pack, $cfg.text.network.xdcc.err_max_packs_requested)
343
+ self.next_pack($cfg.network.xdcc.max_queued_wait)
344
+ elsif status = $cfg.network.xdcc.queue_update_regexp.match(message)
345
+ # Remote queue position update
346
+ @mutex.synchronize do
347
+ @current_pack_status = ON_QUEUED_REMOTELY
348
+ end
349
+ self.fire_event(ON_QUEUED_REMOTELY, @current_pack, status[1].to_i, status[2].to_i)
350
+ elsif status = $cfg.network.xdcc.md5_regexp.match(message)
351
+ handle_delayed_md5(status[1])
352
+ elsif status = $cfg.network.xdcc.punish_slowness_regexp.match(message)
353
+ self.fire_event(ON_DOWNLOAD_FAILED, @current_pack, $cfg.text.network.xdcc.err_punish_slowness)
354
+ self.next_pack(5)
355
+ end
356
+
357
+
358
+ when DCC_File::ON_DCC_ESTABLISHED
359
+ @mutex.synchronize do
360
+ @current_pack_status = ON_DOWNLOAD_STARTED
361
+ end
362
+ self.fire_event(ON_DOWNLOAD_STARTED, @current_pack)
363
+
364
+ when DCC_File::ON_DCC_ERROR
365
+ @mutex.synchronize do
366
+ @current_pack_status = ON_DOWNLOAD_FAILED
367
+ end
368
+ self.fire_event(ON_DOWNLOAD_FAILED, @current_pack, eventargs[0])
369
+ # Give bot some time to close connection, before requesting next pack
370
+ self.next_pack($cfg.network.xdcc.con_error_wait)
371
+
372
+ when DCC_File::ON_DCC_COMPLETED
373
+ @mutex.synchronize do
374
+ @current_pack_status = ON_DOWNLOAD_FINISHED
375
+ @current_pack_md5 = eventargs[0]
376
+ end
377
+ self.fire_event(ON_DOWNLOAD_FINISHED, @current_pack)
378
+ self.fire_event(ON_MD5_STATUS, @current_pack, $cfg.network.xdcc.enable_md5 ? MD5_UNAVAILABLE : MD5_DISABLED)
379
+ self.next_pack
380
+
381
+ when DCC_File::ON_DCC_PROGRESS
382
+ self.fire_event(ON_DOWNLOAD_PROGRESS, @current_pack, eventargs[0], eventargs[1], eventargs[2])
383
+
384
+ when DCC_Parser::ON_DCC_SEND
385
+ if (eventargs[0].irc_user == @irc_user_bot && (@current_pack_status == ON_PACK_REQUESTED ||
386
+ @current_pack_status == ON_QUEUED_REMOTELY))
387
+ @dcc_con.get(eventargs[0], @current_download_path)
388
+ end
389
+
390
+ when Timer::ON_TIMER
391
+ if @delay_timestamp
392
+ # Next pack has been delayed. Check for end of delay.
393
+ self.next_pack if eventargs[0] - @delay_timestamp >= @delay_timeout
394
+ end
395
+
396
+ @mutex.synchronize do
397
+ if @current_pack_status == ON_PACK_REQUESTED
398
+ if (eventargs[0] - @request_timestamp > $cfg.network.xdcc.request_timeout)
399
+ if $cfg.network.xdcc.no_max_rerequests || (@current_request_cnt < $cfg.network.xdcc.max_rerequests)
400
+ # No XDCC answer within specified interval. Rerequest pack
401
+ self.request_pack(@current_pack, @current_download_path)
402
+ else
403
+ @current_pack_status = ON_DOWNLOAD_FAILED
404
+ self.fire_event(ON_DOWNLOAD_FAILED, @current_pack, $cfg.text.network.xdcc.err_no_answer)
405
+ self.next_pack(20)
406
+ end
407
+ end
408
+ end
409
+ end
410
+ end
411
+ end
412
+ end
@@ -0,0 +1,58 @@
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
+ require 'src/Network/IRC_Message.rb'
26
+
27
+ # An XDCC_Pack represents a file to download in the XDCC pseudo protocol.
28
+ class XDCC_Pack
29
+ # Bot, which offered pack
30
+ attr_reader :irc_user_bot
31
+ # Pack number, number of downloads, size, and pack name
32
+ attr_accessor :pack_nr, :download_cnt, :size, :name
33
+
34
+ # Initialize with the bot, which offers the pack, irc_server the bot is on
35
+ def initialize(irc_user_bot)
36
+ @irc_user_bot = irc_user_bot
37
+ end
38
+
39
+ # Returns a human readable representation of this pack as string
40
+ def to_s
41
+ "#{@pack_nr} | #{@download_cnt} | #{@size} | #{@name}"
42
+ end
43
+
44
+ # Returns a xdcc representation of this pack as an IRC_Message.
45
+ # Channel is the target channel
46
+ def to_irc(channel)
47
+ IRC_Message.new("PRIVMSG", channel, "\002##{@pack_nr} \002 #{@download_cnt}x [#{@size}] #{@name}")
48
+ end
49
+
50
+ # Equality based on irc_bot, pack number and pack name
51
+ # Download count is not included
52
+ def ==(pack)
53
+ return false unless pack
54
+ @irc_user_bot == pack.irc_user_bot &&
55
+ @pack_nr == pack.pack_nr &&
56
+ @name == pack.name
57
+ end
58
+ end