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