spox-mod_spox 0.3.1
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.
- data/CHANGELOG +174 -0
- data/INSTALL +15 -0
- data/LICENSE +674 -0
- data/README.rdoc +73 -0
- data/bin/mod_spox +112 -0
- data/data/mod_spox/extras/AOLSpeak.rb +257 -0
- data/data/mod_spox/extras/AutoKick.rb +152 -0
- data/data/mod_spox/extras/AutoMode.rb +122 -0
- data/data/mod_spox/extras/AutoRejoin.rb +37 -0
- data/data/mod_spox/extras/Bash.rb +55 -0
- data/data/mod_spox/extras/Bouncer.rb +220 -0
- data/data/mod_spox/extras/Bullshit.rb +19 -0
- data/data/mod_spox/extras/Bytes.rb +11 -0
- data/data/mod_spox/extras/Confess.rb +244 -0
- data/data/mod_spox/extras/DCC.rb +182 -0
- data/data/mod_spox/extras/DevWatch.rb +153 -0
- data/data/mod_spox/extras/DownForEveryoneOrJustMe.rb +47 -0
- data/data/mod_spox/extras/EightBall.rb +33 -0
- data/data/mod_spox/extras/FML.rb +35 -0
- data/data/mod_spox/extras/FloodKicker.rb +129 -0
- data/data/mod_spox/extras/Fortune.rb +76 -0
- data/data/mod_spox/extras/GoogleIt.rb +13 -0
- data/data/mod_spox/extras/Headers.rb +59 -0
- data/data/mod_spox/extras/Karma.rb +302 -0
- data/data/mod_spox/extras/Locator.rb +44 -0
- data/data/mod_spox/extras/Logger.rb +182 -0
- data/data/mod_spox/extras/LolSpeak.rb +21 -0
- data/data/mod_spox/extras/NickServ.rb +84 -0
- data/data/mod_spox/extras/PhpCli.rb +308 -0
- data/data/mod_spox/extras/PhpFuncLookup.rb +297 -0
- data/data/mod_spox/extras/Pinger.rb +11 -0
- data/data/mod_spox/extras/Quotes.rb +79 -0
- data/data/mod_spox/extras/RegexTracker.rb +158 -0
- data/data/mod_spox/extras/Roulette.rb +267 -0
- data/data/mod_spox/extras/RubyCli.rb +93 -0
- data/data/mod_spox/extras/Search.rb +49 -0
- data/data/mod_spox/extras/Seen.rb +150 -0
- data/data/mod_spox/extras/Slashdot.rb +35 -0
- data/data/mod_spox/extras/SlashdotHeadlineGenerator.rb +500 -0
- data/data/mod_spox/extras/Talk.rb +32 -0
- data/data/mod_spox/extras/Topten.rb +103 -0
- data/data/mod_spox/extras/TracTicket.rb +66 -0
- data/data/mod_spox/extras/Translate.rb +132 -0
- data/data/mod_spox/extras/Twitter.rb +458 -0
- data/data/mod_spox/extras/UrbanDictionary.rb +55 -0
- data/data/mod_spox/extras/Weather.rb +55 -0
- data/data/mod_spox/plugins/Authenticator.rb +289 -0
- data/data/mod_spox/plugins/Banner.rb +585 -0
- data/data/mod_spox/plugins/BotNick.rb +18 -0
- data/data/mod_spox/plugins/Helper.rb +49 -0
- data/data/mod_spox/plugins/Initializer.rb +35 -0
- data/data/mod_spox/plugins/Joiner.rb +23 -0
- data/data/mod_spox/plugins/Nicker.rb +14 -0
- data/data/mod_spox/plugins/Parter.rb +23 -0
- data/data/mod_spox/plugins/Permissions.rb +60 -0
- data/data/mod_spox/plugins/PluginLoader.rb +180 -0
- data/data/mod_spox/plugins/Ponger.rb +70 -0
- data/data/mod_spox/plugins/PoolConfig.rb +52 -0
- data/data/mod_spox/plugins/Quitter.rb +15 -0
- data/data/mod_spox/plugins/Servers.rb +57 -0
- data/data/mod_spox/plugins/Status.rb +31 -0
- data/data/mod_spox/plugins/Triggers.rb +85 -0
- data/lib/mod_spox/BaseConfig.rb +51 -0
- data/lib/mod_spox/Bot.rb +604 -0
- data/lib/mod_spox/BotConfig.rb +65 -0
- data/lib/mod_spox/ConfigurationWizard.rb +180 -0
- data/lib/mod_spox/Database.rb +51 -0
- data/lib/mod_spox/Exceptions.rb +84 -0
- data/lib/mod_spox/Helpers.rb +122 -0
- data/lib/mod_spox/Loader.rb +60 -0
- data/lib/mod_spox/Logger.rb +37 -0
- data/lib/mod_spox/MessageFactory.rb +112 -0
- data/lib/mod_spox/Pipeline.rb +207 -0
- data/lib/mod_spox/Plugin.rb +97 -0
- data/lib/mod_spox/PluginHolder.rb +22 -0
- data/lib/mod_spox/PluginManager.rb +257 -0
- data/lib/mod_spox/PriorityQueue.rb +69 -0
- data/lib/mod_spox/Socket.rb +201 -0
- data/lib/mod_spox/Sockets.rb +226 -0
- data/lib/mod_spox/Timer.rb +60 -0
- data/lib/mod_spox/Version.rb +14 -0
- data/lib/mod_spox/handlers/BadNick.rb +19 -0
- data/lib/mod_spox/handlers/Bounce.rb +24 -0
- data/lib/mod_spox/handlers/Created.rb +27 -0
- data/lib/mod_spox/handlers/Handler.rb +39 -0
- data/lib/mod_spox/handlers/Invite.rb +28 -0
- data/lib/mod_spox/handlers/Join.rb +38 -0
- data/lib/mod_spox/handlers/Kick.rb +36 -0
- data/lib/mod_spox/handlers/LuserChannels.rb +19 -0
- data/lib/mod_spox/handlers/LuserClient.rb +18 -0
- data/lib/mod_spox/handlers/LuserMe.rb +16 -0
- data/lib/mod_spox/handlers/LuserOp.rb +19 -0
- data/lib/mod_spox/handlers/LuserUnknown.rb +19 -0
- data/lib/mod_spox/handlers/Mode.rb +62 -0
- data/lib/mod_spox/handlers/Motd.rb +38 -0
- data/lib/mod_spox/handlers/MyInfo.rb +24 -0
- data/lib/mod_spox/handlers/Names.rb +86 -0
- data/lib/mod_spox/handlers/Nick.rb +50 -0
- data/lib/mod_spox/handlers/NickInUse.rb +19 -0
- data/lib/mod_spox/handlers/Notice.rb +35 -0
- data/lib/mod_spox/handlers/Part.rb +39 -0
- data/lib/mod_spox/handlers/Ping.rb +25 -0
- data/lib/mod_spox/handlers/Pong.rb +23 -0
- data/lib/mod_spox/handlers/Privmsg.rb +39 -0
- data/lib/mod_spox/handlers/Quit.rb +29 -0
- data/lib/mod_spox/handlers/Topic.rb +38 -0
- data/lib/mod_spox/handlers/Welcome.rb +30 -0
- data/lib/mod_spox/handlers/Who.rb +83 -0
- data/lib/mod_spox/handlers/Whois.rb +117 -0
- data/lib/mod_spox/handlers/YourHost.rb +20 -0
- data/lib/mod_spox/messages/Messages.rb +6 -0
- data/lib/mod_spox/messages/incoming/BadNick.rb +16 -0
- data/lib/mod_spox/messages/incoming/Bounce.rb +18 -0
- data/lib/mod_spox/messages/incoming/Created.rb +15 -0
- data/lib/mod_spox/messages/incoming/Invite.rb +21 -0
- data/lib/mod_spox/messages/incoming/Join.rb +19 -0
- data/lib/mod_spox/messages/incoming/Kick.rb +26 -0
- data/lib/mod_spox/messages/incoming/LuserChannels.rb +15 -0
- data/lib/mod_spox/messages/incoming/LuserClient.rb +24 -0
- data/lib/mod_spox/messages/incoming/LuserMe.rb +18 -0
- data/lib/mod_spox/messages/incoming/LuserOp.rb +15 -0
- data/lib/mod_spox/messages/incoming/LuserUnknown.rb +15 -0
- data/lib/mod_spox/messages/incoming/Message.rb +22 -0
- data/lib/mod_spox/messages/incoming/Mode.rb +42 -0
- data/lib/mod_spox/messages/incoming/Motd.rb +18 -0
- data/lib/mod_spox/messages/incoming/MyInfo.rb +24 -0
- data/lib/mod_spox/messages/incoming/Names.rb +24 -0
- data/lib/mod_spox/messages/incoming/Nick.rb +26 -0
- data/lib/mod_spox/messages/incoming/NickInUse.rb +15 -0
- data/lib/mod_spox/messages/incoming/Notice.rb +9 -0
- data/lib/mod_spox/messages/incoming/Part.rb +21 -0
- data/lib/mod_spox/messages/incoming/Ping.rb +18 -0
- data/lib/mod_spox/messages/incoming/Pong.rb +9 -0
- data/lib/mod_spox/messages/incoming/Privmsg.rb +90 -0
- data/lib/mod_spox/messages/incoming/Quit.rb +18 -0
- data/lib/mod_spox/messages/incoming/Topic.rb +21 -0
- data/lib/mod_spox/messages/incoming/TopicInfo.rb +21 -0
- data/lib/mod_spox/messages/incoming/Welcome.rb +27 -0
- data/lib/mod_spox/messages/incoming/Who.rb +18 -0
- data/lib/mod_spox/messages/incoming/Whois.rb +49 -0
- data/lib/mod_spox/messages/incoming/YourHost.rb +18 -0
- data/lib/mod_spox/messages/internal/BotInitialized.rb +11 -0
- data/lib/mod_spox/messages/internal/ChangeNick.rb +15 -0
- data/lib/mod_spox/messages/internal/Connected.rb +20 -0
- data/lib/mod_spox/messages/internal/ConnectionFailed.rb +23 -0
- data/lib/mod_spox/messages/internal/DCCListener.rb +12 -0
- data/lib/mod_spox/messages/internal/DCCRequest.rb +12 -0
- data/lib/mod_spox/messages/internal/DCCSocket.rb +19 -0
- data/lib/mod_spox/messages/internal/Disconnected.rb +8 -0
- data/lib/mod_spox/messages/internal/Disconnecting.rb +8 -0
- data/lib/mod_spox/messages/internal/EstablishConnection.rb +22 -0
- data/lib/mod_spox/messages/internal/HaltBot.rb +8 -0
- data/lib/mod_spox/messages/internal/NickRequest.rb +9 -0
- data/lib/mod_spox/messages/internal/NickResponse.rb +15 -0
- data/lib/mod_spox/messages/internal/PluginLoadRequest.rb +21 -0
- data/lib/mod_spox/messages/internal/PluginLoadResponse.rb +17 -0
- data/lib/mod_spox/messages/internal/PluginModuleRequest.rb +14 -0
- data/lib/mod_spox/messages/internal/PluginModuleResponse.rb +18 -0
- data/lib/mod_spox/messages/internal/PluginReload.rb +18 -0
- data/lib/mod_spox/messages/internal/PluginRequest.rb +18 -0
- data/lib/mod_spox/messages/internal/PluginResponse.rb +21 -0
- data/lib/mod_spox/messages/internal/PluginUnloadRequest.rb +9 -0
- data/lib/mod_spox/messages/internal/PluginUnloadResponse.rb +9 -0
- data/lib/mod_spox/messages/internal/PluginsReady.rb +10 -0
- data/lib/mod_spox/messages/internal/QueueSocket.rb +8 -0
- data/lib/mod_spox/messages/internal/Reconnect.rb +8 -0
- data/lib/mod_spox/messages/internal/Request.rb +15 -0
- data/lib/mod_spox/messages/internal/Response.rb +15 -0
- data/lib/mod_spox/messages/internal/Shutdown.rb +8 -0
- data/lib/mod_spox/messages/internal/SignaturesUpdate.rb +8 -0
- data/lib/mod_spox/messages/internal/StatusRequest.rb +10 -0
- data/lib/mod_spox/messages/internal/StatusResponse.rb +18 -0
- data/lib/mod_spox/messages/internal/TimerAdd.rb +36 -0
- data/lib/mod_spox/messages/internal/TimerClear.rb +16 -0
- data/lib/mod_spox/messages/internal/TimerRemove.rb +23 -0
- data/lib/mod_spox/messages/internal/TimerResponse.rb +34 -0
- data/lib/mod_spox/messages/internal/TriggersUpdate.rb +8 -0
- data/lib/mod_spox/messages/internal/UnqueueSocket.rb +8 -0
- data/lib/mod_spox/messages/outgoing/Admin.rb +15 -0
- data/lib/mod_spox/messages/outgoing/Away.rb +11 -0
- data/lib/mod_spox/messages/outgoing/ChannelMode.rb +25 -0
- data/lib/mod_spox/messages/outgoing/Connect.rb +24 -0
- data/lib/mod_spox/messages/outgoing/Die.rb +9 -0
- data/lib/mod_spox/messages/outgoing/Info.rb +15 -0
- data/lib/mod_spox/messages/outgoing/Invite.rb +19 -0
- data/lib/mod_spox/messages/outgoing/Ison.rb +15 -0
- data/lib/mod_spox/messages/outgoing/Join.rb +19 -0
- data/lib/mod_spox/messages/outgoing/Kick.rb +23 -0
- data/lib/mod_spox/messages/outgoing/Kill.rb +19 -0
- data/lib/mod_spox/messages/outgoing/Links.rb +19 -0
- data/lib/mod_spox/messages/outgoing/List.rb +19 -0
- data/lib/mod_spox/messages/outgoing/Lusers.rb +19 -0
- data/lib/mod_spox/messages/outgoing/Motd.rb +16 -0
- data/lib/mod_spox/messages/outgoing/Names.rb +20 -0
- data/lib/mod_spox/messages/outgoing/Nick.rb +16 -0
- data/lib/mod_spox/messages/outgoing/Notice.rb +12 -0
- data/lib/mod_spox/messages/outgoing/Oper.rb +19 -0
- data/lib/mod_spox/messages/outgoing/Part.rb +19 -0
- data/lib/mod_spox/messages/outgoing/Pass.rb +16 -0
- data/lib/mod_spox/messages/outgoing/Ping.rb +11 -0
- data/lib/mod_spox/messages/outgoing/Pong.rb +17 -0
- data/lib/mod_spox/messages/outgoing/Privmsg.rb +43 -0
- data/lib/mod_spox/messages/outgoing/Quit.rb +11 -0
- data/lib/mod_spox/messages/outgoing/Raw.rb +16 -0
- data/lib/mod_spox/messages/outgoing/Rehash.rb +9 -0
- data/lib/mod_spox/messages/outgoing/Restart.rb +9 -0
- data/lib/mod_spox/messages/outgoing/ServList.rb +19 -0
- data/lib/mod_spox/messages/outgoing/Simple.rb +12 -0
- data/lib/mod_spox/messages/outgoing/Squery.rb +19 -0
- data/lib/mod_spox/messages/outgoing/Squit.rb +19 -0
- data/lib/mod_spox/messages/outgoing/Stats.rb +18 -0
- data/lib/mod_spox/messages/outgoing/Summon.rb +23 -0
- data/lib/mod_spox/messages/outgoing/Time.rb +15 -0
- data/lib/mod_spox/messages/outgoing/Topic.rb +19 -0
- data/lib/mod_spox/messages/outgoing/Trace.rb +15 -0
- data/lib/mod_spox/messages/outgoing/Unaway.rb +9 -0
- data/lib/mod_spox/messages/outgoing/User.rb +23 -0
- data/lib/mod_spox/messages/outgoing/UserHost.rb +15 -0
- data/lib/mod_spox/messages/outgoing/UserMode.rb +19 -0
- data/lib/mod_spox/messages/outgoing/Users.rb +15 -0
- data/lib/mod_spox/messages/outgoing/Version.rb +16 -0
- data/lib/mod_spox/messages/outgoing/Who.rb +23 -0
- data/lib/mod_spox/messages/outgoing/WhoWas.rb +23 -0
- data/lib/mod_spox/messages/outgoing/Whois.rb +19 -0
- data/lib/mod_spox/migrations/001_initialize_models.rb +115 -0
- data/lib/mod_spox/migrations/002_persistent_sigs.rb +14 -0
- data/lib/mod_spox/migrations/003_auth_restructure.rb +31 -0
- data/lib/mod_spox/migrations/004_mode_index_fix.rb +18 -0
- data/lib/mod_spox/migrations/005_nick_mode_nopark.rb +18 -0
- data/lib/mod_spox/models/Auth.rb +65 -0
- data/lib/mod_spox/models/AuthMask.rb +13 -0
- data/lib/mod_spox/models/Channel.rb +89 -0
- data/lib/mod_spox/models/Config.rb +30 -0
- data/lib/mod_spox/models/Group.rb +30 -0
- data/lib/mod_spox/models/Models.rb +4 -0
- data/lib/mod_spox/models/Nick.rb +195 -0
- data/lib/mod_spox/models/NickMode.rb +32 -0
- data/lib/mod_spox/models/Server.rb +27 -0
- data/lib/mod_spox/models/Setting.rb +52 -0
- data/lib/mod_spox/models/Signature.rb +52 -0
- data/lib/mod_spox/models/Trigger.rb +9 -0
- data/lib/mod_spox/rfc2812.rb +49 -0
- data/populate_gemspec.rb +15 -0
- data/tests/BotHolder.rb +24 -0
- data/tests/handlers/tc_BadNick.rb +21 -0
- data/tests/handlers/tc_Created.rb +24 -0
- data/tests/handlers/tc_Invite.rb +50 -0
- data/tests/handlers/tc_Join.rb +33 -0
- data/tests/handlers/tc_Kick.rb +32 -0
- data/tests/handlers/tc_Mode.rb +85 -0
- data/tests/handlers/tc_Names.rb +35 -0
- data/tests/handlers/tc_Nick.rb +55 -0
- data/tests/handlers/tc_Part.rb +44 -0
- data/tests/handlers/tc_Ping.rb +40 -0
- data/tests/handlers/tc_Pong.rb +28 -0
- data/tests/handlers/tc_Privmsg.rb +85 -0
- data/tests/handlers/tc_Quit.rb +40 -0
- data/tests/handlers/tc_Who.rb +50 -0
- data/tests/handlers/tc_Whois.rb +61 -0
- data/tests/models/tc_Auth.rb +39 -0
- data/tests/models/tc_Channel.rb +52 -0
- data/tests/models/tc_Config.rb +19 -0
- data/tests/models/tc_Nick.rb +144 -0
- data/tests/models/tc_NickMode.rb +40 -0
- data/tests/models/tc_Setting.rb +21 -0
- data/tests/models/tc_Signature.rb +14 -0
- data/tests/run_tests.rb +6 -0
- metadata +362 -0
@@ -0,0 +1,201 @@
|
|
1
|
+
['iconv',
|
2
|
+
'mod_spox/Logger',
|
3
|
+
'mod_spox/Exceptions',
|
4
|
+
'mod_spox/messages/internal/Connected',
|
5
|
+
'mod_spox/messages/internal/Disconnected',
|
6
|
+
'mod_spox/models/Models',
|
7
|
+
'mod_spox/Pipeline',
|
8
|
+
'mod_spox/PriorityQueue'].each{|f|require f}
|
9
|
+
|
10
|
+
module ModSpox
|
11
|
+
|
12
|
+
class Socket
|
13
|
+
|
14
|
+
attr_reader :sent
|
15
|
+
attr_reader :received
|
16
|
+
attr_reader :burst
|
17
|
+
attr_reader :burst_in
|
18
|
+
attr_reader :delay
|
19
|
+
attr_reader :server
|
20
|
+
attr_reader :port
|
21
|
+
attr_reader :socket
|
22
|
+
attr_reader :connected_at
|
23
|
+
|
24
|
+
# factory:: MessageFactory to parse messages
|
25
|
+
# server:: Server to connect to
|
26
|
+
# port:: Port number to connect to
|
27
|
+
# delay:: Number of seconds to delay between bursts
|
28
|
+
# burst_in:: Number of seconds allowed to burst
|
29
|
+
# burst:: Number of lines allowed to be sent within the burst_in time limit
|
30
|
+
# Create a new Socket
|
31
|
+
def initialize(bot, server=nil, port=nil, delay=2, burst_in=2, burst=4)
|
32
|
+
@pool = bot.pool
|
33
|
+
@factory = bot.factory
|
34
|
+
@pipeline = bot.pipeline
|
35
|
+
@dcc = bot.dcc_sockets
|
36
|
+
@server = server
|
37
|
+
@port = port
|
38
|
+
@sent = 0
|
39
|
+
@received = 0
|
40
|
+
@delay = delay.to_f > 0 ? delay.to_f : 2.0
|
41
|
+
@burst = burst.to_i > 0 ? burst.to_i : 4
|
42
|
+
@burst_in = 2
|
43
|
+
@kill = false
|
44
|
+
@time_check = nil
|
45
|
+
@check_burst = 0
|
46
|
+
@pause = false
|
47
|
+
@sendq = PriorityQueue.new
|
48
|
+
@lock = Mutex.new
|
49
|
+
@connected_at = nil
|
50
|
+
@empty_lines = 0
|
51
|
+
@max_empty = 5
|
52
|
+
@servers = Array.new
|
53
|
+
@connect_locker = Mutex.new
|
54
|
+
end
|
55
|
+
|
56
|
+
# Connects to the IRC server
|
57
|
+
def connect
|
58
|
+
return unless @connect_locker.try_lock
|
59
|
+
begin
|
60
|
+
populate_servers if @servers.empty?
|
61
|
+
s = @servers.pop
|
62
|
+
@server = s.host
|
63
|
+
@port = s.port.to_i
|
64
|
+
Logger.info("Establishing connection to #{@server}:#{@port}")
|
65
|
+
@socket = TCPSocket.new(@server, @port)
|
66
|
+
@socket.setsockopt(::Socket::SOL_SOCKET, ::Socket::SO_KEEPALIVE, true)
|
67
|
+
@empty_lines = 0
|
68
|
+
s.connected = true
|
69
|
+
s.save
|
70
|
+
@connected_at = Time.now
|
71
|
+
@pipeline << Messages::Internal::Connected.new(@server, @port)
|
72
|
+
ensure
|
73
|
+
@connect_locker.unlock
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
# new_delay:: Seconds to delay between bursts
|
78
|
+
# Resets the delay
|
79
|
+
def delay=(new_delay)
|
80
|
+
raise Exceptions::InvalidValue('Send delay must be a positive number') unless new_delay.to_f > 0
|
81
|
+
@delay = new_delay.to_f
|
82
|
+
end
|
83
|
+
|
84
|
+
# new_burst:: Number of lines allowed in burst
|
85
|
+
# Resets the burst
|
86
|
+
def burst=(new_burst)
|
87
|
+
raise Exceptions::InvalidValue('Burst value must be a positive number') unless new_burst.to_i > 0
|
88
|
+
@burst = new_burst
|
89
|
+
end
|
90
|
+
|
91
|
+
# new_burst_in:: Number of seconds allowed to burst
|
92
|
+
# Resets the burst_in
|
93
|
+
def burst_in=(new_burst_in)
|
94
|
+
raise Exceptions::InvalidValue('Burst in value must be positive') unless new_burst_in.to_i > 0
|
95
|
+
@burst_in = new_burst_in
|
96
|
+
end
|
97
|
+
|
98
|
+
# message:: String to send to server
|
99
|
+
# Sends a string to the IRC server
|
100
|
+
def puts(message)
|
101
|
+
write(message)
|
102
|
+
end
|
103
|
+
|
104
|
+
# message:: String to send to server
|
105
|
+
# Sends a string to the IRC server
|
106
|
+
def write(message)
|
107
|
+
return if message.nil?
|
108
|
+
begin
|
109
|
+
@socket.puts(message + "\n")
|
110
|
+
@socket.flush
|
111
|
+
Logger.info("<< #{message}")
|
112
|
+
@last_send = Time.new
|
113
|
+
@sent += 1
|
114
|
+
@check_burst += 1
|
115
|
+
@time_check = Time.now.to_i if @time_check.nil?
|
116
|
+
rescue Object => boom
|
117
|
+
Logger.warn("Failed to write message to server. #{boom}")
|
118
|
+
@pipeline << Messages::Internal::Disconnected.new
|
119
|
+
raise Exceptions::Disconnected.new
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
# string:: string to be processed
|
124
|
+
# Process a string
|
125
|
+
def process(string)
|
126
|
+
string.strip!
|
127
|
+
Logger.info(">> #{string}")
|
128
|
+
if(string[0,5] == 'ERROR')
|
129
|
+
@pipeline << Messages::Internal::Disconnected.new
|
130
|
+
raise Exceptions::Disconnected.new
|
131
|
+
end
|
132
|
+
@received += 1
|
133
|
+
@factory << string
|
134
|
+
end
|
135
|
+
|
136
|
+
# message:: String to be sent to server
|
137
|
+
# Queues a message up to be sent to the IRC server
|
138
|
+
def <<(message)
|
139
|
+
@sendq.direct_queue(message)
|
140
|
+
@pool.process{ processor }
|
141
|
+
end
|
142
|
+
|
143
|
+
# target:: Target for outgoing message
|
144
|
+
# message:: Message to send
|
145
|
+
# This queues a message to be sent out of a prioritized
|
146
|
+
# queue. This allows for even message distribution rather
|
147
|
+
# than only on target at a time being flooded.
|
148
|
+
def prioritize_message(target, message)
|
149
|
+
@sendq.priority_queue(target, message)
|
150
|
+
@pool.process{ processor }
|
151
|
+
end
|
152
|
+
|
153
|
+
# Starts the thread for sending messages to the server
|
154
|
+
def processor
|
155
|
+
return unless @lock.try_lock
|
156
|
+
did_write = false
|
157
|
+
begin
|
158
|
+
loop do
|
159
|
+
write(@sendq.pop)
|
160
|
+
did_write = true
|
161
|
+
if((Time.now.to_i - @time_check) > @burst_in)
|
162
|
+
@time_check = nil
|
163
|
+
@check_burst = 0
|
164
|
+
elsif((Time.now.to_i - @time_check) <= @burst_in && @check_burst >= @burst)
|
165
|
+
Logger.warn("Burst limit hit. Output paused for: #{@delay} seconds")
|
166
|
+
sleep(@delay)
|
167
|
+
@time_check = nil
|
168
|
+
@check_burst = 0
|
169
|
+
end
|
170
|
+
end
|
171
|
+
rescue Exceptions::EmptyQueue => boom
|
172
|
+
Logger.info('Socket reached an empty queue.')
|
173
|
+
ensure
|
174
|
+
@lock.unlock
|
175
|
+
@pool.process{ processor } if did_write
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
# restart:: Reconnect after closing connection
|
180
|
+
# Closes connection to IRC server
|
181
|
+
def shutdown(restart=false)
|
182
|
+
@socket.close unless @socket.nil? || @socket.closed?
|
183
|
+
@kill = true
|
184
|
+
server = Models::Server.find_or_create(:host => @server, :port => @port)
|
185
|
+
server.connected = false
|
186
|
+
server.save
|
187
|
+
sleep(0.1)
|
188
|
+
connect if restart
|
189
|
+
end
|
190
|
+
|
191
|
+
private
|
192
|
+
|
193
|
+
def populate_servers
|
194
|
+
Models::Server.reverse_order(:priority).each{|s|
|
195
|
+
@servers << s
|
196
|
+
}
|
197
|
+
end
|
198
|
+
|
199
|
+
end
|
200
|
+
|
201
|
+
end
|
@@ -0,0 +1,226 @@
|
|
1
|
+
['ipaddr',
|
2
|
+
'iconv',
|
3
|
+
'mod_spox/Bot',
|
4
|
+
'mod_spox/Pipeline',
|
5
|
+
'mod_spox/MessageFactory',
|
6
|
+
'mod_spox/Socket',
|
7
|
+
'mod_spox/messages/internal/DCCSocket',
|
8
|
+
'mod_spox/messages/outgoing/Privmsg'
|
9
|
+
].each{|f| require f}
|
10
|
+
|
11
|
+
require 'spockets'
|
12
|
+
|
13
|
+
module ModSpox
|
14
|
+
|
15
|
+
class Sockets
|
16
|
+
|
17
|
+
attr_reader :irc_socket
|
18
|
+
|
19
|
+
def initialize(bot)
|
20
|
+
@bot = bot
|
21
|
+
@irc_socket = nil
|
22
|
+
@dcc_sockets = []
|
23
|
+
@mapped_sockets = {}
|
24
|
+
@spockets = Spockets::Spockets.new(:pool => bot.pool)
|
25
|
+
@listening_dcc = []
|
26
|
+
@dcc_ports = {:start => 49152, :end => 65535}
|
27
|
+
@dcc_wait = 30
|
28
|
+
@pipeline = bot.pipeline
|
29
|
+
@factory = bot.factory
|
30
|
+
@pipeline.hook(self, :check_dcc, :Incoming_Privmsg)
|
31
|
+
@pipeline.hook(self, :return_socket, :Internal_DCCRequest)
|
32
|
+
@pipeline.hook(self, :dcc_listener, :Internal_DCCListener)
|
33
|
+
@pipeline.hook(self, :disconnect_irc, :Internal_Disconnected)
|
34
|
+
@pipeline.hook(self, :queue_messages, :Internal_QueueSocket)
|
35
|
+
@pipeline.hook(self, :unqueue_messages, :Internal_UnqueueSocket)
|
36
|
+
@queues = {:irc => Queue.new, :dcc => Queue.new}
|
37
|
+
@queue_messages = false
|
38
|
+
end
|
39
|
+
|
40
|
+
# server:: IRC server string
|
41
|
+
# port:: IRC port
|
42
|
+
# Connect to the given IRC server
|
43
|
+
def irc_connect(server=nil, port=nil)
|
44
|
+
if(@irc_socket.nil?)
|
45
|
+
@irc_socket = Socket.new(@bot, server, port)
|
46
|
+
@irc_socket.connect
|
47
|
+
@spockets.add(@irc_socket.socket){|string| process_irc_string(string)}
|
48
|
+
@spockets.on_close(@irc_socket.socket){ irc_reconnect }
|
49
|
+
else
|
50
|
+
irc_reconnect
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def irc_reconnect
|
55
|
+
unless(@irc_socket.nil?)
|
56
|
+
disconnect_irc
|
57
|
+
@spockets.remove(@irc_socket.socket) if @spockets.include?(@irc_socket)
|
58
|
+
@irc_socket.shutdown(true)
|
59
|
+
@spockets.add(@irc_socket.socket){|string| process_irc_string(string)}
|
60
|
+
else
|
61
|
+
irc_connect
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def <<(message)
|
66
|
+
if(message =~ /::(\S+)::\s:(.+)$/)
|
67
|
+
id = $1.to_i
|
68
|
+
message = $2 + "\r\n"
|
69
|
+
sock_info = @mapped_sockets[id]
|
70
|
+
sock_info[:socket] << message
|
71
|
+
else
|
72
|
+
@irc_socket << message
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def prioritize_message(target, message)
|
77
|
+
@irc_socket.prioritize_message(target, message)
|
78
|
+
end
|
79
|
+
|
80
|
+
# message:: ModSpox::Messages::Incoming::Privmsg
|
81
|
+
# Checks if incoming message is a request to
|
82
|
+
# start a DCC chat session and builds the connection
|
83
|
+
def check_dcc(message)
|
84
|
+
if(message.is_ctcp? && message.ctcp_type == 'DCC')
|
85
|
+
if(message.message =~ /^CHAT chat (\S+) (\S+)/)
|
86
|
+
if(message.source.in_group?('dcc') || message.source.in_group?('admin'))
|
87
|
+
ip = IPAddr.new($1.to_i, Object::Socket::AF_INET).to_s
|
88
|
+
port = $2.to_i
|
89
|
+
build_connection(ip, port, message.source)
|
90
|
+
else
|
91
|
+
Logger.warn("Error: #{message.source.nick} is attempting to establish DCC connection without permission.")
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
# message:: ModSpox::Messages::Internal::DCCRequest
|
98
|
+
# Returns the DCC Socket requested in a ModSpox::Messages::Internal::DCCSocket
|
99
|
+
# message.
|
100
|
+
def return_socket(message)
|
101
|
+
socket = nick = nil
|
102
|
+
if(@mapped_socks.has_key?(message.socket_id))
|
103
|
+
socket = @mapped_socks[message.socket_id][:socket]
|
104
|
+
nick = @mapped_socks[message.socket_id][:nick]
|
105
|
+
end
|
106
|
+
@pipeline << Messages::Internal::DCCSocket.new(message.socket_id, nick, socket)
|
107
|
+
end
|
108
|
+
|
109
|
+
# message:: ModSpox::Messages::Internal::DCCListener
|
110
|
+
# Sets up a new socket for a user to connect to. Helpful
|
111
|
+
# if the user wants a DCC chat session but is firewalled
|
112
|
+
def dcc_listener(message)
|
113
|
+
Thread.new do
|
114
|
+
me = Models::Nick.filter(:botnick => true).first
|
115
|
+
return if me.nil?
|
116
|
+
port = rand(@dcc_ports[:end] - @dcc_ports[:start]) + @dcc_ports[:start]
|
117
|
+
socket = Object::Socket.new(Object::Socket::AF_INET, Object::Socket::SOCK_STREAM, 0)
|
118
|
+
addr = Object::Socket.pack_sockaddr_in(port, me.address)
|
119
|
+
socket.bind(addr)
|
120
|
+
client = nil
|
121
|
+
addrinfo = nil
|
122
|
+
cport = nil
|
123
|
+
cip = nil
|
124
|
+
begin
|
125
|
+
Timeout::timeout(@dcc_wait) do
|
126
|
+
@pipeline << Messages::Outgoing::Privmsg.new(message.nick, "CHAT chat #{IPAddr.new(me.address).to_i} #{port}", false, true, 'DCC')
|
127
|
+
socket.listen(5)
|
128
|
+
client, addrinfo = socket.accept
|
129
|
+
cport, cip = Object::Socket.unpack_sockaddr_in(addrinfo)
|
130
|
+
end
|
131
|
+
Logger.info("New DCC socket created for #{message.nick.nick} has connected from: #{cip}:#{cport}")
|
132
|
+
@dcc_sockets << client
|
133
|
+
@mapped_sockets[client.object_id] = {:socket => client, :nick => message.nick}
|
134
|
+
@spockets.add(socket){|string| process_dcc_string(string, socket)}
|
135
|
+
rescue Timeout::Error => boom
|
136
|
+
Logger.warn("Timeout reached waiting for #{message.nick.nick} to connect to DCC socket. Closing.")
|
137
|
+
client.close
|
138
|
+
rescue Object => boom
|
139
|
+
Logger.warn("Unknown error encountered while building DCC listener for: #{message.nick.nick}. Error: #{boom}")
|
140
|
+
client.close
|
141
|
+
ensure
|
142
|
+
socket.close
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
# Shuts down all active sockets
|
148
|
+
def shutdown
|
149
|
+
@spockets.clear
|
150
|
+
@irc_socket.shutdown
|
151
|
+
@dcc_sockets.each do |sock|
|
152
|
+
close_dcc(sock)
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
def disconnect_irc(m=nil)
|
157
|
+
@spockets.remove(@irc_socket.socket) if @spockets.include?(@irc_socket.socket)
|
158
|
+
end
|
159
|
+
|
160
|
+
def unqueue_messages(m)
|
161
|
+
@queue_messages = false
|
162
|
+
flush_queues
|
163
|
+
end
|
164
|
+
|
165
|
+
def queue_messages(m)
|
166
|
+
@queue_messages = true
|
167
|
+
end
|
168
|
+
|
169
|
+
private
|
170
|
+
|
171
|
+
# ip:: IP address to connect to
|
172
|
+
# port:: Port to connect to
|
173
|
+
# nick:: Nick this connection is associated with
|
174
|
+
# Builds a DCC connection to given location
|
175
|
+
def build_connection(ip, port, nick)
|
176
|
+
begin
|
177
|
+
socket = TCPSocket.new(ip, port)
|
178
|
+
@spockets.add(socket){|string| process_dcc_string(string, socket)}
|
179
|
+
@mapped_sockets[socket.object_id] = {:socket => socket, :nick => nick}
|
180
|
+
@dcc_sockets << socket
|
181
|
+
Logger.info("New DCC connection established to #{nick.nick} on #{ip}:#{port}")
|
182
|
+
rescue Object => boom
|
183
|
+
Logger.warn("DCC connection to #{nick.nick} on #{ip}:#{port} failed. #{boom}")
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
def close_dcc(sock)
|
188
|
+
@spockets.remove(sock)
|
189
|
+
@dcc_sockets.delete(sock)
|
190
|
+
@mapped_sockets.delete(sock.object_id)
|
191
|
+
end
|
192
|
+
|
193
|
+
def process_irc_string(string)
|
194
|
+
if(@queue_messages)
|
195
|
+
@queues[:irc] << string
|
196
|
+
else
|
197
|
+
@irc_socket.process(string)
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
def process_dcc_string(string, socket)
|
202
|
+
if(@queue_messages)
|
203
|
+
@queues[:dcc] = {:string => string, :socket => socket}
|
204
|
+
else
|
205
|
+
Logger.info("DCC >> #{string}")
|
206
|
+
if(socket.closed? || string.nil?)
|
207
|
+
socket.close
|
208
|
+
close_dcc(socket)
|
209
|
+
else
|
210
|
+
@pipeline << Messages::Incoming::Privmsg.new(string, @mapped_sockets[socket.object_id][:nick], "::#{sock.object_id}::", string)
|
211
|
+
end
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
def flush_queues
|
216
|
+
until(@queues[:irc].empty?)
|
217
|
+
process_irc_string(@queues[:irc].pop)
|
218
|
+
end
|
219
|
+
until(@queues[:dcc].empty?)
|
220
|
+
con = @queues[:dcc].pop
|
221
|
+
process_dcc_string(con[:string], con[:socket])
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
end
|
226
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
['mod_spox/Logger',
|
2
|
+
'mod_spox/Pipeline',
|
3
|
+
'mod_spox/messages/internal/TimerResponse'].each{|f|require f}
|
4
|
+
|
5
|
+
module ModSpox
|
6
|
+
|
7
|
+
class Timer
|
8
|
+
|
9
|
+
# timer:: ActionTimer to use
|
10
|
+
# pipeline:: Message pipeline
|
11
|
+
# Creates a timer handler for interactions
|
12
|
+
# with the ActionTimer
|
13
|
+
def initialize(timer, pipeline)
|
14
|
+
@pipeline = pipeline
|
15
|
+
@timer = timer
|
16
|
+
{:Internal_TimerAdd => :add_message,
|
17
|
+
:Internal_TimerRemove => :remove_message,
|
18
|
+
:Internal_TimerClear => :clear}.each_pair do |type,method|
|
19
|
+
@pipeline.hook(self, method, type)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# message:: TimerAdd message
|
24
|
+
# Add a recurring code block
|
25
|
+
def add_message(message)
|
26
|
+
Logger.info("New block is being added to the timer")
|
27
|
+
begin
|
28
|
+
action = @timer.add(message.period, message.once, message.data, message.requester, &message.block)
|
29
|
+
@pipeline << Messages::Internal::TimerResponse.new(message.requester, action, true, message.id)
|
30
|
+
rescue Object => boom
|
31
|
+
Logger.error("Failed to add new block to timer: #{boom}")
|
32
|
+
@pipeline << Messages::Internal::TimerResponse.new(message.requester, nil, false, message.id)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# message:: TimerRemove message
|
37
|
+
# Remove an action from the timer
|
38
|
+
def remove_message(message)
|
39
|
+
@timer.remove(message.action)
|
40
|
+
Logger.info("Action has been removed from the Timer")
|
41
|
+
@pipeline << Messages::Internal::TimerResponse.new(nil, message.action, false, message.id)
|
42
|
+
end
|
43
|
+
|
44
|
+
# Clears all actions in the timer's queue
|
45
|
+
def clear(message=nil)
|
46
|
+
if(message.nil? || message.plugin.nil?)
|
47
|
+
@timer.clear
|
48
|
+
else
|
49
|
+
@timer.clear(message.plugin)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
# stop the timer
|
54
|
+
def stop
|
55
|
+
@timer.stop
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module ModSpox
|
2
|
+
@botversion='0.3.1'
|
3
|
+
@botcodename='potato shotgun'
|
4
|
+
@verbosity = 0
|
5
|
+
@mod_spox_path = nil
|
6
|
+
@daemon_bot = false
|
7
|
+
@logto = nil
|
8
|
+
@loglevel = :fatal
|
9
|
+
@jdbc = false
|
10
|
+
class << self
|
11
|
+
attr_reader :botversion, :botcodename
|
12
|
+
attr_accessor :verbosity, :mod_spox_path, :daemon_bot, :logto, :loglevel, :jdbc
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'mod_spox/handlers/Handler'
|
2
|
+
require 'mod_spox/messages/incoming/BadNick'
|
3
|
+
module ModSpox
|
4
|
+
module Handlers
|
5
|
+
class BadNick < Handler
|
6
|
+
def initialize(handlers)
|
7
|
+
handlers[RFC[:ERR_ERRONEOUSNICKNAME][:value]] = self
|
8
|
+
end
|
9
|
+
def process(string)
|
10
|
+
if(string =~ /#{RFC[:ERR_ERRONEOUSNICKNAME][:value]}\s\S+\s(\S+)\s:/)
|
11
|
+
return Messages::Incoming::BadNick.new(string, $1)
|
12
|
+
else
|
13
|
+
Logger.warn('Failed to process RPL_ERRORONEOUSNICK message')
|
14
|
+
return nil
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'mod_spox/handlers/Handler'
|
2
|
+
require 'mod_spox/messages/incoming/Bounce'
|
3
|
+
module ModSpox
|
4
|
+
module Handlers
|
5
|
+
class Bounce < Handler
|
6
|
+
def initialize(handlers)
|
7
|
+
handlers[RFC[:RPL_BOUNCE][:value]] = self
|
8
|
+
end
|
9
|
+
|
10
|
+
def process(string)
|
11
|
+
begin
|
12
|
+
orig = string.dup
|
13
|
+
2.times{string.slice!(0..string.index(' '))}
|
14
|
+
server = string.slice!(0..string.index(',')-1)
|
15
|
+
string.slice!(0..string.index(' ',4))
|
16
|
+
return Messages::Incoming::Bounce.new(orig, server, string)
|
17
|
+
rescue Object => boom
|
18
|
+
Logger.error("Failed to parse BOUNCE message: #{orig}")
|
19
|
+
raise Exceptions::GeneralException.new(boom)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'mod_spox/handlers/Handler'
|
2
|
+
require 'mod_spox/messages/incoming/Created'
|
3
|
+
require 'time'
|
4
|
+
module ModSpox
|
5
|
+
module Handlers
|
6
|
+
class Created < Handler
|
7
|
+
def initialize(handlers)
|
8
|
+
handlers[RFC[:RPL_CREATED][:value]] = self
|
9
|
+
end
|
10
|
+
# :not.configured 003 spox :This server was created Tue Mar 24 2009 at 15:42:36 PDT'
|
11
|
+
def process(string)
|
12
|
+
string = string.dup
|
13
|
+
begin
|
14
|
+
orig = string.dup
|
15
|
+
2.times{string.slice!(0..string.index(':'))}
|
16
|
+
4.times{string.slice!(0..string.index(' '))}
|
17
|
+
time = Time.parse(string)
|
18
|
+
time = nil if Time.now == time
|
19
|
+
return time.nil? ? nil : Messages::Incoming::Created.new(orig, time)
|
20
|
+
rescue Object => boom
|
21
|
+
Logger.error("Failed to parse RPL_CREATED message: #{orig}")
|
22
|
+
raise Exceptions::GeneralException.new(boom)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'mod_spox/rfc2812'
|
2
|
+
require 'mod_spox/Helpers'
|
3
|
+
require 'mod_spox/Exceptions'
|
4
|
+
module ModSpox
|
5
|
+
module Handlers
|
6
|
+
|
7
|
+
class Handler
|
8
|
+
|
9
|
+
# handlers:: array of handlers
|
10
|
+
# initialize handler and add self to available
|
11
|
+
# handlers
|
12
|
+
def initialize(handlers)
|
13
|
+
raise Exceptions::NotImplemented.new('Method has not been implemented')
|
14
|
+
end
|
15
|
+
|
16
|
+
# data:: string of data
|
17
|
+
# Process the string and create the proper object
|
18
|
+
def process(data)
|
19
|
+
raise Exceptions::NotImplemented.new('Method has not been implemented')
|
20
|
+
end
|
21
|
+
|
22
|
+
# data:: any expected data
|
23
|
+
# Preprocessing allows for actions to be taken
|
24
|
+
# while messages are still in a synchronized state
|
25
|
+
def preprocess(data)
|
26
|
+
end
|
27
|
+
|
28
|
+
protected
|
29
|
+
|
30
|
+
# deprecated. here basically so old handlers
|
31
|
+
# don't break
|
32
|
+
def find_model(string)
|
33
|
+
Helpers.find_model(string)
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'mod_spox/handlers/Handler'
|
2
|
+
require 'mod_spox/messages/incoming/Invite'
|
3
|
+
module ModSpox
|
4
|
+
module Handlers
|
5
|
+
class Invite < Handler
|
6
|
+
def initialize(handlers)
|
7
|
+
handlers[:INVITE] = self
|
8
|
+
end
|
9
|
+
# :spax!~spox@host INVITE spox :#m
|
10
|
+
def process(string)
|
11
|
+
orig = string.dup
|
12
|
+
string = string.dup
|
13
|
+
begin
|
14
|
+
string.slice!(0)
|
15
|
+
source = find_model(string.slice!(0..string.index('!')-1))
|
16
|
+
2.times{ string.slice!(0..string.index(' ')) }
|
17
|
+
target = find_model(string.slice!(0..string.index(' ')-1))
|
18
|
+
string.slice!(0..string.index(':'))
|
19
|
+
channel = find_model(string.strip)
|
20
|
+
return Messages::Incoming::Invite.new(orig, source, target, channel)
|
21
|
+
rescue Object => boom
|
22
|
+
Logger.error("Failed to parse INVITE message: #{orig}")
|
23
|
+
raise Exceptions::GeneralException.new(boom)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'mod_spox/handlers/Handler'
|
2
|
+
require 'mod_spox/messages/incoming/Join'
|
3
|
+
module ModSpox
|
4
|
+
module Handlers
|
5
|
+
class Join < Handler
|
6
|
+
def initialize(handlers)
|
7
|
+
handlers[:JOIN] = self
|
8
|
+
end
|
9
|
+
|
10
|
+
# :mod_spox!~mod_spox@host JOIN :#m
|
11
|
+
|
12
|
+
def process(string)
|
13
|
+
orig = string.dup
|
14
|
+
string = string.dup
|
15
|
+
begin
|
16
|
+
string.slice!(0)
|
17
|
+
source = string.slice!(0..string.index(' ')-1)
|
18
|
+
string.slice!(0..string.index(':'))
|
19
|
+
channel = find_model(string.strip)
|
20
|
+
nick = find_model(source.slice(0..source.index('!')-1))
|
21
|
+
nick.source = source.dup
|
22
|
+
source.slice!(0..source.index('!'))
|
23
|
+
nick.username = source.slice!(0..source.index('@')-1)
|
24
|
+
source.slice!(0)
|
25
|
+
nick.address = source.slice!(0..source.size)
|
26
|
+
nick.visible = true
|
27
|
+
nick.save_changes
|
28
|
+
channel.add_nick(nick)
|
29
|
+
channel.save
|
30
|
+
return Messages::Incoming::Join.new(orig, channel, nick)
|
31
|
+
rescue Object => boom
|
32
|
+
Logger.warn("Failed to parse JOIN message: #{orig}")
|
33
|
+
raise Exceptions::GeneralException.new(boom)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|