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,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
+
26
+ require 'src/Network/IRC_Message.rb'
27
+
28
+ # Represents a user on irc
29
+ class IRC_User
30
+ attr_accessor :name, :user, :host
31
+ attr_reader :irc_server
32
+
33
+ def initialize(name, irc_server)
34
+ @name = name
35
+ @user = nil
36
+ @host = nil
37
+ @irc_server = irc_server
38
+ end
39
+
40
+ # Send a private message to the user
41
+ def send(message)
42
+ @irc_server.send(IRC_Message.new("PRIVMSG", @name, message))
43
+ end
44
+
45
+ # Send a private notice to the user
46
+ def notice(message)
47
+ @irc_server.send(IRC_Message.new("NOTICE", @name, message))
48
+ end
49
+
50
+ def to_s
51
+ "#{@name}!#{@user}@#{@host}"
52
+ end
53
+
54
+ # Equals the nick of this user the given string?
55
+ def has_name?(other_name)
56
+ self.name.downcase == other_name.downcase
57
+ end
58
+ end
@@ -0,0 +1,168 @@
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 'socket'
27
+ require 'resolv-replace'
28
+ require 'src/Utilities/Events.rb'
29
+ require 'timeout'
30
+
31
+ # Provides businesslogic for handling a TCP client connection.
32
+ # Supports text based and binary based connections through wrapping the actual receive
33
+ # and send procedure.
34
+ class TCP_Connection
35
+ include Event_Publisher
36
+
37
+ attr_reader :address, :port
38
+ attr_accessor :proc_recv, :proc_send
39
+
40
+
41
+ # -- connectable events
42
+
43
+ # On socket connection established. Args: none
44
+ ON_CONNECTED = Event_Publisher.next_global_eventID
45
+ # On socket connection closed remotely. Args: none
46
+ ON_CLOSED = Event_Publisher.next_global_eventID
47
+ # On socket error. Args: error message
48
+ ON_ERROR = Event_Publisher.next_global_eventID
49
+ # On data received. Args: data
50
+ ON_DATA = Event_Publisher.next_global_eventID
51
+ # All events packaged in one
52
+ ON_ALL_EVENTS = ON_CONNECTED + ON_CLOSED + ON_DATA + ON_ERROR
53
+
54
+ def initialize(proc_recv, proc_send)
55
+ @proc_recv = proc_recv
56
+ @proc_send = proc_send
57
+ @socket = nil
58
+ @recv_thread = nil
59
+ init_events
60
+ end
61
+
62
+ # Open connection to the specified server and port
63
+ def open(address, port)
64
+ @address = address
65
+ @port = port
66
+
67
+ if !self.connected?
68
+ # Spawn a thread responsible for handling initial connection
69
+ # That way, the the main thread is not blocked if connection cannot be
70
+ # established
71
+ connect_thread = Thread.new do
72
+ if @address && @port
73
+ begin
74
+ timeout($cfg.network.tcp.connect_timeout) {
75
+ @socket = TCPSocket.new(@address, @port)
76
+ }
77
+ self.fire_event(ON_CONNECTED)
78
+ # Setup the required receive thread which reads from the connection
79
+ @recv_thread = Thread.new do
80
+ begin
81
+ while data = self.proc_recv.call(@socket)
82
+ self.fire_event(ON_DATA, data) unless data.length == 0
83
+ end
84
+ self.close
85
+ self.fire_event(ON_CLOSED)
86
+ rescue IOError, Errno::ECONNRESET, Errno::ENOTSOCK, SocketError => err
87
+ self.fire_event(ON_ERROR, err.to_s)
88
+ end
89
+ end
90
+ rescue TimeoutError => err
91
+ self.fire_event(ON_ERROR, $cfg.text.network.tcp.err_con_timeout)
92
+ rescue IOError, Errno::ECONNREFUSED, Errno::EHOSTUNREACH, Errno::ENETUNREACH, Errno::ETIMEDOUT, SocketError => err
93
+ self.close
94
+ self.fire_event(ON_ERROR, err.to_s)
95
+ end
96
+ else
97
+ self.fire_event(ON_ERROR, $cfg.text.network.tcp.err_con_no_remote)
98
+ end
99
+ end
100
+ else
101
+ # Already connected
102
+ self.fire_event(ON_ERROR, $cfg.text.network.tcp.err_con_active)
103
+ end
104
+ # Lower priority of connect thread. This may help higher level applications to increase there response time
105
+ connect_thread.priority = $cfg.network.tcp.connect_thread_priority
106
+ end
107
+
108
+ # Send data to socket
109
+ def send(data)
110
+ begin
111
+ @proc_send.call(@socket, data) if self.connected?
112
+ rescue Exception => err
113
+ self.fire_event(ON_ERROR, err.to_s)
114
+ self.close
115
+ end
116
+ end
117
+
118
+ # Immediate shutdown the connection
119
+ def close
120
+ begin
121
+ @socket.close
122
+ rescue Exception
123
+ end
124
+ end
125
+
126
+ # Wait for the connection to close
127
+ def wait
128
+ if self.connected?
129
+ @recv_thread.join
130
+ else
131
+ self.fire_event(ON_ERROR, $cfg.text.network.tcp.err_con_closed)
132
+ end
133
+ end
134
+
135
+ # Is connection established?
136
+ def connected?
137
+ @socket && !@socket.closed?
138
+ end
139
+
140
+ # Generate a line based TCPConnection object. That is, data is received
141
+ # whenever \r\n is received.
142
+ def TCP_Connection.text
143
+ recv_proc = proc do |socket|
144
+ data = socket.gets("\r\n")
145
+ end
146
+
147
+ send_proc = proc do |socket, data|
148
+ socket.puts(data)
149
+ end
150
+ TCP_Connection.new(recv_proc, send_proc)
151
+ end
152
+
153
+ # Generate a TCPConnection object, capable of handling binary data packets.
154
+ def TCP_Connection.binary
155
+ recv_proc = proc do |socket|
156
+ data = socket.recv(16384)
157
+ (data.length > 0) ? data : nil
158
+ end
159
+
160
+ send_proc = proc do |socket, data|
161
+ socket.print(data)
162
+ end
163
+ TCP_Connection.new(recv_proc, send_proc)
164
+ end
165
+ end
166
+
167
+
168
+
@@ -0,0 +1,120 @@
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/XDCC_Pack.rb'
27
+ require 'src/Network/IRC_Message.rb'
28
+
29
+ # An XDCC_Announcement represents an complete offering of an xdcc bot. This includes info about the current bot status as
30
+ # well as the offered packs.
31
+ class XDCC_Announcement
32
+
33
+ # The irc_user offering
34
+ attr_reader :irc_user_bot
35
+ #nr of packs offered, nr of available slots, nr of slots open and the targets this announcement was found at
36
+ # Nr of packs in announcement
37
+ attr_accessor :pack_cnt
38
+ # Total number of slots
39
+ attr_accessor :slot_cnt
40
+ # Number of slots available
41
+ attr_accessor :openslot_cnt
42
+ # Total number of queue slots
43
+ attr_accessor :queue_cnt
44
+ # Number of open queue positions
45
+ attr_accessor :openqueue_cnt
46
+ # Array of channels or nicknames, this announcement was sent to
47
+ attr_accessor :targets
48
+ # Type of announcement (FULL or MEDIUM)
49
+ attr_reader :ann_type
50
+ # Array of XDCC_Packs belonging to this announcement
51
+ attr_reader :packs
52
+
53
+ # -- Constants
54
+ ANN_FULL = 0
55
+ ANN_MINIMAL = 1
56
+
57
+ # Initialize with the bot which offers
58
+ def initialize(irc_user_bot, type=ANN_FULL)
59
+ @pack_cnt = -1
60
+ @irc_user_bot = irc_user_bot
61
+ @packs = Array.new
62
+ @openslot_cnt = -1
63
+ @slot_cnt = -1
64
+ @queue_cnt = -1
65
+ @openqueue_cnt = -1
66
+ @ann_type = type
67
+ end
68
+
69
+ # Has parsing completed
70
+ def completed?
71
+ @packs.length == @pack_cnt
72
+ end
73
+
74
+ # Does this announcement contain queue information
75
+ def has_queue_info?
76
+ @queue_cnt != -1
77
+ end
78
+
79
+ # Returns a human readable representation of this announcement as string
80
+ def to_s
81
+ s = "XDCC_Announcement: #{@irc_user_bot.name} | nr of packs: #{@pack_cnt} | open slots: #{@openslot_cnt}/#{@slot_cnt} | queue: #{@openqueue_cnt}/#{@queue_cnt}\r\n"
82
+ @packs.each do |pack|
83
+ s += "#{pack}\r\n"
84
+ end
85
+ s
86
+ end
87
+
88
+ # Returns a xdcc representation of this announcement as array of irc_messages.
89
+ # If channel is not given, the channelname is taken from the targets.
90
+ def to_irc(channel=nil)
91
+ channel = @targets[0] unless channel
92
+ a = []
93
+ a << IRC_Message.new("PRIVMSG", channel, "\002**\002 #{@pack_cnt} packs \002\002 #{@openslot_cnt} of #{@slot_cnt} slots open")
94
+ a << IRC_Message.new("PRIVMSG", channel, "\002**\002 Bandwidth usage ...")
95
+ a << IRC_Message.new("PRIVMSG", channel, "\002**\002 To request a file, type \"/msg ....")
96
+ @packs.each do |pack|
97
+ a << pack.to_irc(channel)
98
+ end
99
+ a << IRC_Message.new("PRIVMSG", channel, "Total Offered: 1.1 MB Total Transferred: 2.13 MB")
100
+ end
101
+
102
+ # Determines equality of this xdcc_announcement and the given xdcc_announcement.
103
+ def ==(ann)
104
+ @irc_user_bot == ann.irc_user_bot &&
105
+ @pack_cnt == ann.pack_cnt &&
106
+ @slot_cnt == ann.pack_cnt &&
107
+ @openslot_cnt == ann.openslot_cnt &&
108
+ @packs == ann.packs
109
+ end
110
+ end
111
+
112
+ #<mybotDCC> ** 4 packs ** 20 of 20 slots open, Record: 3543.1KB/s
113
+ #<mybotDCC> ** Bandwidth Usage ** Current: 0.0KB/s, Record: 9.5KB/s
114
+ #<mybotDCC> ** To request a file, type "/msg mybotDCC xdcc send #x" **
115
+ #<mybotDCC> ** To request details, type "/msg mybotDCC xdcc info #x" **
116
+ #<mybotDCC> #1 2x [1.0M] Setup-NettalkIRCD.exe
117
+ #<mybotDCC> #2 1x [ 93K] XDCC-FetchGUI-nightly.zip
118
+ #<mybotDCC> #3 1x [ <1K] wscite162.zip
119
+ #<mybotDCC> #4 0x [ <1K] sometext.txt
120
+ #<mybotDCC> Total Offered: 1.1 MB Total Transferred: 2.13 MB
@@ -0,0 +1,167 @@
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 'thread'
27
+ require 'src/Utilities/Events.rb'
28
+ require 'src/Network/IRC_Server.rb'
29
+ require 'src/Network/XDCC_Parser.rb'
30
+
31
+ class XDCC_Announcement_Storage
32
+ include Event_Publisher
33
+
34
+ # -- Connectable events
35
+
36
+ # Whenever a new(unknown, updated) announcement is available. Args: xdcc_announcement
37
+ ON_ANNOUNCEMENT_NEW = Event_Publisher.next_global_eventID
38
+ # Whenever a known announcement is lost, due to user quit or announcement update. Args: xdcc_announcement
39
+ ON_ANNOUNCEMENT_LOST = Event_Publisher.next_global_eventID
40
+
41
+ # Initialize with the given XDCC_Parser
42
+ def initialize(xdcc_parser)
43
+ @mutex = Mutex.new
44
+ @bot_announcement = Hash.new
45
+ @irc_servers = Array.new
46
+ @parser = xdcc_parser
47
+ @parser.connect_to_events(XDCC_Parser::ON_ANNOUNCEMENT, self)
48
+ self.init_events
49
+ end
50
+
51
+ # Clear up, prepare for deallocation
52
+ def shutdown
53
+ @parser.disconnect_from_events(XDCC_Parser::ON_ANNOUNCEMENT, self)
54
+ self.shutdown_events
55
+ end
56
+
57
+ # Handle a XDCC_Announcement
58
+ # Basically decides, if it is unknown or known and based on this, takes the appropriate actions
59
+ def handle_announcement(ann)
60
+ @mutex.synchronize do
61
+ # Check if we've already subsribed at the irc_server the ann was broadcasted on
62
+ if !@irc_servers.include?(ann.irc_user_bot.irc_server)
63
+ @irc_servers.push(ann.irc_user_bot.irc_server)
64
+ ann.irc_user_bot.irc_server.connect_to_events(IRC_Server::ON_USER_QUIT|
65
+ IRC_Server::ON_USER_PART|
66
+ IRC_Server::ON_USER_KICK|
67
+ IRC_Server::ON_SERVER_DISCONNECTED,
68
+ self)
69
+ end
70
+
71
+ # Check if it is an unknown bot
72
+ if !@bot_announcement.include?(ann.irc_user_bot)
73
+ self.handle_new_announcement(ann)
74
+ else
75
+ self.handle_existing_announcement(ann)
76
+ end
77
+ end
78
+ end
79
+
80
+ # Handles an unknown XDCC_Announcement.
81
+ # Broadcasts an ON_ANNOUNCEMENT_NEW event
82
+ def handle_new_announcement(ann)
83
+ @bot_announcement[ann.irc_user_bot] = ann
84
+ self.fire_event(ON_ANNOUNCEMENT_NEW, ann)
85
+ end
86
+
87
+ # Handles a known XDCC_Announcement.
88
+ # An ON_ANNOUNCEMENT_UPDATE is being broadcasted if the XDCC_Announcement changed.
89
+ def handle_existing_announcement(ann)
90
+ # Check if announcement has updated
91
+ if @bot_announcement[ann.irc_user_bot] != ann
92
+ self.fire_event(ON_ANNOUNCEMENT_LOST, @bot_announcement[ann.irc_user_bot])
93
+ self.fire_event(ON_ANNOUNCEMENT_NEW, ann)
94
+ @bot_announcement[ann.irc_user_bot] = ann
95
+ end
96
+ end
97
+
98
+ # Handles a user quit message.
99
+ # A ON_ANNOUNCEMENT_LOST is thrown, if the user quitting used to offer XDCC_Packs.
100
+ def handle_user_quit(irc_user)
101
+ @mutex.synchronize do
102
+ ann = @bot_announcement.delete(irc_user)
103
+ self.fire_event(ON_ANNOUNCEMENT_LOST, ann) if ann
104
+ end
105
+ end
106
+
107
+ # When disconnected from server, all announcements found on this server
108
+ # are treated as lost. the server itself is not killed.
109
+ def handle_server_disconnect(irc_server)
110
+ @mutex.synchronize do
111
+ @bot_announcement.delete_if do |bot, ann|
112
+ ret = (bot.irc_server == irc_server)
113
+ self.fire_event(ON_ANNOUNCEMENT_LOST, ann) if ret
114
+ ret
115
+ end
116
+ end
117
+ end
118
+
119
+ # When a user is kicked from a certain channel. Possible announcements
120
+ # belonging to that user are being treated as lost. If the user is
121
+ # ourself, all announcements found on that channel are being treated as lost
122
+ def handle_channel_left(irc_server, channelname, irc_user)
123
+ if irc_server.me.has_name?(irc_user.name)
124
+ # We have been forced to leave channel
125
+ chan = channelname.downcase
126
+ @mutex.synchronize do
127
+ @bot_announcement.delete_if do |bot, ann|
128
+ # Although announcement may be broadcasted in multiple channels,
129
+ # we only check the first so far
130
+ # TODO: check if announcement was broadcasted in other chans (we know)
131
+ # too. If we are in such a chan, don't kill announcement
132
+ ret = (ann.targets[0].downcase == chan)
133
+ self.fire_event(ON_ANNOUNCEMENT_LOST, ann) if ret
134
+ ret
135
+ end
136
+ end
137
+ else
138
+ # User (potential bot has been kicked)
139
+ username = irc_user.name.downcase
140
+ @mutex.synchronize do
141
+ @bot_announcement.delete_if do |bot, ann|
142
+ ret = (bot.name.downcase == username)
143
+ self.fire_event(ON_ANNOUNCEMENT_LOST, ann) if ret
144
+ ret
145
+ end
146
+ end
147
+ end
148
+ end
149
+
150
+ # Handle incoming events
151
+ def on_event(caller, event, eventargs)
152
+ case event
153
+ when XDCC_Parser::ON_ANNOUNCEMENT
154
+ self.handle_announcement(eventargs[0])
155
+
156
+ when IRC_Server::ON_USER_QUIT
157
+ self.handle_user_quit(eventargs[0])
158
+
159
+ when IRC_Server::ON_SERVER_DISCONNECTED
160
+ self.handle_server_disconnect(caller)
161
+
162
+ when IRC_Server::ON_USER_KICK, IRC_Server::ON_USER_PART
163
+ self.handle_channel_left(caller, eventargs[1], eventargs[0])
164
+ end
165
+ end
166
+ end
167
+