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,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