mod_spox 0.0.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.
Files changed (191) hide show
  1. data/CHANGELOG +2 -0
  2. data/INSTALL +9 -0
  3. data/README +33 -0
  4. data/bin/mod_spox +60 -0
  5. data/data/mod_spox/extras/Tester.rb +14 -0
  6. data/data/mod_spox/plugins/Authenticator.rb +245 -0
  7. data/data/mod_spox/plugins/BotNick.rb +18 -0
  8. data/data/mod_spox/plugins/Initializer.rb +41 -0
  9. data/data/mod_spox/plugins/Joiner.rb +13 -0
  10. data/data/mod_spox/plugins/Parter.rb +22 -0
  11. data/data/mod_spox/plugins/PluginLoader.rb +136 -0
  12. data/data/mod_spox/plugins/Ponger.rb +14 -0
  13. data/data/mod_spox/plugins/Quitter.rb +14 -0
  14. data/lib/mod_spox/Action.rb +73 -0
  15. data/lib/mod_spox/BaseConfig.rb +48 -0
  16. data/lib/mod_spox/Bot.rb +472 -0
  17. data/lib/mod_spox/BotConfig.rb +54 -0
  18. data/lib/mod_spox/ConfigurationWizard.rb +178 -0
  19. data/lib/mod_spox/Database.rb +25 -0
  20. data/lib/mod_spox/Exceptions.rb +35 -0
  21. data/lib/mod_spox/Helpers.rb +35 -0
  22. data/lib/mod_spox/Loader.rb +79 -0
  23. data/lib/mod_spox/Logger.rb +31 -0
  24. data/lib/mod_spox/MessageFactory.rb +73 -0
  25. data/lib/mod_spox/Monitors.rb +59 -0
  26. data/lib/mod_spox/Pipeline.rb +148 -0
  27. data/lib/mod_spox/Plugin.rb +18 -0
  28. data/lib/mod_spox/PluginManager.rb +105 -0
  29. data/lib/mod_spox/Pool.rb +50 -0
  30. data/lib/mod_spox/Socket.rb +171 -0
  31. data/lib/mod_spox/Timer.rb +138 -0
  32. data/lib/mod_spox/handlers/BadNick.rb +16 -0
  33. data/lib/mod_spox/handlers/Bounce.rb +15 -0
  34. data/lib/mod_spox/handlers/Created.rb +16 -0
  35. data/lib/mod_spox/handlers/Handler.rb +31 -0
  36. data/lib/mod_spox/handlers/Invite.rb +19 -0
  37. data/lib/mod_spox/handlers/Join.rb +30 -0
  38. data/lib/mod_spox/handlers/Kick.rb +24 -0
  39. data/lib/mod_spox/handlers/LuserChannels.rb +16 -0
  40. data/lib/mod_spox/handlers/LuserClient.rb +16 -0
  41. data/lib/mod_spox/handlers/LuserMe.rb +14 -0
  42. data/lib/mod_spox/handlers/LuserOp.rb +16 -0
  43. data/lib/mod_spox/handlers/LuserUnknown.rb +16 -0
  44. data/lib/mod_spox/handlers/Mode.rb +47 -0
  45. data/lib/mod_spox/handlers/Motd.rb +30 -0
  46. data/lib/mod_spox/handlers/MyInfo.rb +21 -0
  47. data/lib/mod_spox/handlers/Names.rb +54 -0
  48. data/lib/mod_spox/handlers/Nick.rb +24 -0
  49. data/lib/mod_spox/handlers/NickInUse.rb +16 -0
  50. data/lib/mod_spox/handlers/Notice.rb +32 -0
  51. data/lib/mod_spox/handlers/Part.rb +19 -0
  52. data/lib/mod_spox/handlers/Ping.rb +16 -0
  53. data/lib/mod_spox/handlers/Pong.rb +16 -0
  54. data/lib/mod_spox/handlers/Privmsg.rb +27 -0
  55. data/lib/mod_spox/handlers/Quit.rb +21 -0
  56. data/lib/mod_spox/handlers/Topic.rb +29 -0
  57. data/lib/mod_spox/handlers/Welcome.rb +34 -0
  58. data/lib/mod_spox/handlers/Who.rb +60 -0
  59. data/lib/mod_spox/handlers/Whois.rb +63 -0
  60. data/lib/mod_spox/handlers/YourHost.rb +17 -0
  61. data/lib/mod_spox/messages/incoming/BadNick.rb +15 -0
  62. data/lib/mod_spox/messages/incoming/Bounce.rb +17 -0
  63. data/lib/mod_spox/messages/incoming/Created.rb +14 -0
  64. data/lib/mod_spox/messages/incoming/Invite.rb +20 -0
  65. data/lib/mod_spox/messages/incoming/Join.rb +18 -0
  66. data/lib/mod_spox/messages/incoming/Kick.rb +25 -0
  67. data/lib/mod_spox/messages/incoming/LuserChannels.rb +14 -0
  68. data/lib/mod_spox/messages/incoming/LuserClient.rb +23 -0
  69. data/lib/mod_spox/messages/incoming/LuserMe.rb +17 -0
  70. data/lib/mod_spox/messages/incoming/LuserOp.rb +14 -0
  71. data/lib/mod_spox/messages/incoming/LuserUnknown.rb +14 -0
  72. data/lib/mod_spox/messages/incoming/Message.rb +22 -0
  73. data/lib/mod_spox/messages/incoming/Mode.rb +41 -0
  74. data/lib/mod_spox/messages/incoming/Motd.rb +17 -0
  75. data/lib/mod_spox/messages/incoming/MyInfo.rb +23 -0
  76. data/lib/mod_spox/messages/incoming/Names.rb +23 -0
  77. data/lib/mod_spox/messages/incoming/Nick.rb +25 -0
  78. data/lib/mod_spox/messages/incoming/NickInUse.rb +14 -0
  79. data/lib/mod_spox/messages/incoming/Notice.rb +8 -0
  80. data/lib/mod_spox/messages/incoming/Part.rb +20 -0
  81. data/lib/mod_spox/messages/incoming/Ping.rb +17 -0
  82. data/lib/mod_spox/messages/incoming/Pong.rb +8 -0
  83. data/lib/mod_spox/messages/incoming/Privmsg.rb +64 -0
  84. data/lib/mod_spox/messages/incoming/Quit.rb +17 -0
  85. data/lib/mod_spox/messages/incoming/Topic.rb +20 -0
  86. data/lib/mod_spox/messages/incoming/TopicInfo.rb +20 -0
  87. data/lib/mod_spox/messages/incoming/Welcome.rb +26 -0
  88. data/lib/mod_spox/messages/incoming/Who.rb +17 -0
  89. data/lib/mod_spox/messages/incoming/Whois.rb +47 -0
  90. data/lib/mod_spox/messages/incoming/YourHost.rb +17 -0
  91. data/lib/mod_spox/messages/internal/BotInitialized.rb +11 -0
  92. data/lib/mod_spox/messages/internal/ChangeNick.rb +15 -0
  93. data/lib/mod_spox/messages/internal/Connected.rb +20 -0
  94. data/lib/mod_spox/messages/internal/ConnectionFailed.rb +23 -0
  95. data/lib/mod_spox/messages/internal/Disconnected.rb +8 -0
  96. data/lib/mod_spox/messages/internal/Disconnecting.rb +8 -0
  97. data/lib/mod_spox/messages/internal/EstablishConnection.rb +22 -0
  98. data/lib/mod_spox/messages/internal/HaltBot.rb +8 -0
  99. data/lib/mod_spox/messages/internal/NickRequest.rb +8 -0
  100. data/lib/mod_spox/messages/internal/NickResponse.rb +14 -0
  101. data/lib/mod_spox/messages/internal/PluginLoadRequest.rb +20 -0
  102. data/lib/mod_spox/messages/internal/PluginLoadResponse.rb +16 -0
  103. data/lib/mod_spox/messages/internal/PluginModuleRequest.rb +13 -0
  104. data/lib/mod_spox/messages/internal/PluginModuleResponse.rb +17 -0
  105. data/lib/mod_spox/messages/internal/PluginReload.rb +8 -0
  106. data/lib/mod_spox/messages/internal/PluginRequest.rb +17 -0
  107. data/lib/mod_spox/messages/internal/PluginResponse.rb +20 -0
  108. data/lib/mod_spox/messages/internal/PluginUnloadRequest.rb +8 -0
  109. data/lib/mod_spox/messages/internal/PluginUnloadResponse.rb +8 -0
  110. data/lib/mod_spox/messages/internal/Request.rb +15 -0
  111. data/lib/mod_spox/messages/internal/Response.rb +15 -0
  112. data/lib/mod_spox/messages/internal/Shutdown.rb +8 -0
  113. data/lib/mod_spox/messages/internal/SignaturesUpdate.rb +8 -0
  114. data/lib/mod_spox/messages/internal/StatusRequest.rb +9 -0
  115. data/lib/mod_spox/messages/internal/StatusResponse.rb +17 -0
  116. data/lib/mod_spox/messages/internal/TimerAdd.rb +27 -0
  117. data/lib/mod_spox/messages/internal/TimerClear.rb +8 -0
  118. data/lib/mod_spox/messages/internal/TimerRemove.rb +15 -0
  119. data/lib/mod_spox/messages/internal/TimerResponse.rb +26 -0
  120. data/lib/mod_spox/messages/internal/TriggersUpdate.rb +8 -0
  121. data/lib/mod_spox/messages/outgoing/Admin.rb +15 -0
  122. data/lib/mod_spox/messages/outgoing/Away.rb +10 -0
  123. data/lib/mod_spox/messages/outgoing/ChannelMode.rb +25 -0
  124. data/lib/mod_spox/messages/outgoing/Connect.rb +24 -0
  125. data/lib/mod_spox/messages/outgoing/Die.rb +9 -0
  126. data/lib/mod_spox/messages/outgoing/Info.rb +15 -0
  127. data/lib/mod_spox/messages/outgoing/Invite.rb +19 -0
  128. data/lib/mod_spox/messages/outgoing/Ison.rb +15 -0
  129. data/lib/mod_spox/messages/outgoing/Join.rb +19 -0
  130. data/lib/mod_spox/messages/outgoing/Kick.rb +23 -0
  131. data/lib/mod_spox/messages/outgoing/Kill.rb +19 -0
  132. data/lib/mod_spox/messages/outgoing/Links.rb +19 -0
  133. data/lib/mod_spox/messages/outgoing/List.rb +19 -0
  134. data/lib/mod_spox/messages/outgoing/Lusers.rb +19 -0
  135. data/lib/mod_spox/messages/outgoing/Motd.rb +16 -0
  136. data/lib/mod_spox/messages/outgoing/Names.rb +20 -0
  137. data/lib/mod_spox/messages/outgoing/Nick.rb +16 -0
  138. data/lib/mod_spox/messages/outgoing/Notice.rb +11 -0
  139. data/lib/mod_spox/messages/outgoing/Oper.rb +19 -0
  140. data/lib/mod_spox/messages/outgoing/Part.rb +19 -0
  141. data/lib/mod_spox/messages/outgoing/Pass.rb +16 -0
  142. data/lib/mod_spox/messages/outgoing/Ping.rb +10 -0
  143. data/lib/mod_spox/messages/outgoing/Pong.rb +17 -0
  144. data/lib/mod_spox/messages/outgoing/Privmsg.rb +19 -0
  145. data/lib/mod_spox/messages/outgoing/Quit.rb +10 -0
  146. data/lib/mod_spox/messages/outgoing/Rehash.rb +9 -0
  147. data/lib/mod_spox/messages/outgoing/Restart.rb +9 -0
  148. data/lib/mod_spox/messages/outgoing/ServList.rb +19 -0
  149. data/lib/mod_spox/messages/outgoing/Simple.rb +12 -0
  150. data/lib/mod_spox/messages/outgoing/Squery.rb +19 -0
  151. data/lib/mod_spox/messages/outgoing/Squit.rb +19 -0
  152. data/lib/mod_spox/messages/outgoing/Stats.rb +18 -0
  153. data/lib/mod_spox/messages/outgoing/Summon.rb +23 -0
  154. data/lib/mod_spox/messages/outgoing/Time.rb +15 -0
  155. data/lib/mod_spox/messages/outgoing/Topic.rb +19 -0
  156. data/lib/mod_spox/messages/outgoing/Trace.rb +15 -0
  157. data/lib/mod_spox/messages/outgoing/Unaway.rb +9 -0
  158. data/lib/mod_spox/messages/outgoing/User.rb +23 -0
  159. data/lib/mod_spox/messages/outgoing/UserHost.rb +15 -0
  160. data/lib/mod_spox/messages/outgoing/UserMode.rb +19 -0
  161. data/lib/mod_spox/messages/outgoing/Users.rb +15 -0
  162. data/lib/mod_spox/messages/outgoing/Version.rb +16 -0
  163. data/lib/mod_spox/messages/outgoing/Who.rb +19 -0
  164. data/lib/mod_spox/messages/outgoing/WhoWas.rb +23 -0
  165. data/lib/mod_spox/messages/outgoing/Whois.rb +19 -0
  166. data/lib/mod_spox/migration/001_create_auths.rb +13 -0
  167. data/lib/mod_spox/migration/001_create_channel.rb +13 -0
  168. data/lib/mod_spox/migration/001_create_channel_modes.rb +13 -0
  169. data/lib/mod_spox/migration/001_create_config.rb +13 -0
  170. data/lib/mod_spox/migration/001_create_nick_channels.rb +13 -0
  171. data/lib/mod_spox/migration/001_create_nick_modes.rb +13 -0
  172. data/lib/mod_spox/migration/001_create_nicks.rb +13 -0
  173. data/lib/mod_spox/migration/001_create_servers.rb +13 -0
  174. data/lib/mod_spox/migration/001_create_settings.rb +13 -0
  175. data/lib/mod_spox/migration/001_create_signatures.rb +13 -0
  176. data/lib/mod_spox/migration/001_create_triggers.rb +13 -0
  177. data/lib/mod_spox/models/Auth.rb +79 -0
  178. data/lib/mod_spox/models/AuthGroup.rb +15 -0
  179. data/lib/mod_spox/models/Channel.rb +47 -0
  180. data/lib/mod_spox/models/ChannelMode.rb +14 -0
  181. data/lib/mod_spox/models/Config.rb +31 -0
  182. data/lib/mod_spox/models/Group.rb +13 -0
  183. data/lib/mod_spox/models/Nick.rb +110 -0
  184. data/lib/mod_spox/models/NickChannel.rb +43 -0
  185. data/lib/mod_spox/models/NickMode.rb +18 -0
  186. data/lib/mod_spox/models/Server.rb +12 -0
  187. data/lib/mod_spox/models/Setting.rb +40 -0
  188. data/lib/mod_spox/models/Signature.rb +30 -0
  189. data/lib/mod_spox/models/Trigger.rb +9 -0
  190. data/lib/mod_spox/rfc2812.rb +171 -0
  191. metadata +261 -0
@@ -0,0 +1,73 @@
1
+ module ModSpox
2
+
3
+ class Action
4
+
5
+ # timer:: Timer the action is being added to
6
+ # period:: number of seconds between runs
7
+ # data:: data to be available for the action
8
+ # once:: only run the action once
9
+ # &func:: block of code to run
10
+ # Create a new Action
11
+ def initialize(timer, period, data=nil, once=false, &func)
12
+ @period = period.to_f
13
+ @func = func
14
+ @data = data
15
+ @once = once
16
+ @due = false
17
+ @timer = timer
18
+ @completed = false
19
+ @wait_remaining = @period
20
+ end
21
+
22
+ # amount:: number of seconds passed
23
+ # Decrement wait time by given number of seconds
24
+ def tick(amount)
25
+ @wait_remaining = @wait_remaining - amount
26
+ end
27
+
28
+ # Returns true if action is due to run
29
+ def due?
30
+ @wait_remaining <= 0
31
+ end
32
+
33
+ # Returns the remaining number of seconds
34
+ def remaining
35
+ @wait_remaining <= 0 ? 0 : @wait_remaining
36
+ end
37
+
38
+ # new_time:: number of seconds between runs
39
+ # Resets the wait time between runs
40
+ def reset_period(new_time)
41
+ @period = new_time.to_f
42
+ @wait_remaining = @period
43
+ @timer.wakeup
44
+ end
45
+
46
+ # Returns if the Action has completed all its runs
47
+ def is_complete?
48
+ @completed
49
+ end
50
+
51
+ # Used for scheduling with Timer. Resets its internal
52
+ # timer and returns itself
53
+ def schedule
54
+ @wait_remaining = @period
55
+ return self
56
+ end
57
+
58
+ # Runs the function block of the action
59
+ def run
60
+ begin
61
+ unless @data.nil?
62
+ @func.call(@data)
63
+ else
64
+ @func.call
65
+ end
66
+ rescue Object => boom
67
+ Logger.log("Action generated an exception during run: #{boom}\n#{boom.backtrace.join("\n")}", 10)
68
+ end
69
+ @completed = true if @once
70
+ end
71
+ end
72
+
73
+ end
@@ -0,0 +1,48 @@
1
+ module ModSpox
2
+
3
+ class BaseConfig
4
+
5
+ # file_path:: path to configuration file
6
+ # Creates new BaseConfig
7
+ def initialize(file_path)
8
+ @config = Hash.new
9
+ @file_path = file_path
10
+ parse_configuration
11
+ end
12
+
13
+ # name:: key of config item wanted
14
+ # Provides access to configuration data
15
+ def [](name)
16
+ name = name.to_sym unless name.is_a?(Symbol)
17
+ raise Exceptions::UnknownKey.new("Configuration has no value named: #{name.to_s}") unless @config.has_key?(name)
18
+ return @config[name]
19
+ end
20
+
21
+ def []=(key, value)
22
+ key = key.to_sym unless key.is_a?(Symbol)
23
+ @config[key] = value
24
+ end
25
+
26
+ # Parses the configuration file into a usable Hash
27
+ def parse_configuration
28
+ return unless File.exists?(BotConfig[:userconfigpath])
29
+ IO.readlines(BotConfig[:userconfigpath]).each{|line|
30
+ if(line =~ /^(\S+)\s*=\s*(\S*)\s*$/)
31
+ @config[$1.to_sym] = $2
32
+ end
33
+ }
34
+ end
35
+
36
+ # Writes the configuration file out to the provided file_path
37
+ # during initialization
38
+ def write_configuration
39
+ file = File.open(BotConfig[:userconfigpath], 'w')
40
+ @config.each_pair{|k,v|
41
+ file.puts("#{k.to_s}=#{v}")
42
+ }
43
+ file.close
44
+ end
45
+
46
+ end
47
+
48
+ end
@@ -0,0 +1,472 @@
1
+ module ModSpox
2
+
3
+ class Bot
4
+
5
+ # bot timer
6
+ attr_reader :timer
7
+
8
+ # message pipeline
9
+ attr_reader :pipeline
10
+
11
+ # plugin manager
12
+ attr_reader :plugin_manager
13
+
14
+ # message factory
15
+ attr_reader :factory
16
+
17
+ # Create a Bot
18
+ def initialize
19
+ Logger.severity($VERBOSITY)
20
+ Logger.fd
21
+ clean_models
22
+ @start_time = Time.now
23
+ @pipeline = Pipeline.new
24
+ @timer = Timer.new(@pipeline)
25
+ @config = BaseConfig.new(BotConfig[:userconfigpath])
26
+ @factory = MessageFactory.new(@pipeline)
27
+ @socket = nil
28
+ @plugin_manager = PluginManager.new(@pipeline)
29
+ @shutdown = false
30
+ @socket = nil
31
+ @nick = nil
32
+ @thread = Thread.current
33
+ hook_pipeline
34
+ end
35
+
36
+ # Run the bot
37
+ def run
38
+ trap('SIGTERM'){ Logger.log("Caught SIGTERM"); Thread.current.exit }
39
+ trap('SIGKILL'){ Logger.log("Caught SIGKILL"); Thread.current.exit }
40
+ trap('SIGINT'){ Logger.log("Caught SIGINT"); Thread.current.exit }
41
+ trap('SIGQUIT'){ Logger.log("Caught SIGQUIT"); Thread.current.exit }
42
+ until @shutdown do
43
+ @timer.start
44
+ @pipeline << Messages::Internal::BotInitialized.new
45
+ begin
46
+ Thread.stop
47
+ rescue Object => boom
48
+ Logger.log("Caught exception: #{boom}")
49
+ end
50
+ shutdown
51
+ end
52
+ end
53
+
54
+ # Shut the bot down
55
+ def shutdown
56
+ @shutdown = true
57
+ @plugin_manager.destroy_plugins
58
+ @thread.run
59
+ @timer.stop
60
+ @timer.destroy
61
+ @factory.destroy
62
+ @pipeline << Messages::Internal::Shutdown.new
63
+ sleep(0.1)
64
+ @pipeline.destroy
65
+ @socket.shutdown unless @socket.nil?
66
+ clean_models
67
+ end
68
+
69
+ # Reload the bot (basically a restart)
70
+ def reload
71
+ @thread.run
72
+ end
73
+
74
+ # message:: Messages::Internal::EstablishConnection message
75
+ # Initialize connection to IRC server
76
+ def bot_connect(message)
77
+ Logger.log("Received a connection command", 10)
78
+ begin
79
+ @socket = Socket.new(self, message.server, message.port)
80
+ @socket.connect
81
+ @pipeline << Messages::Internal::Connected.new(message.server, message.port)
82
+ rescue Object => boom
83
+ Logger.log("Failed connection to server: #{boom}")
84
+ @pipeline << Messages::Internal::ConnectionFailed.new(message.server, message.port)
85
+ end
86
+ end
87
+
88
+ # message:: Messages::Internal::StatusRequest message
89
+ # Returns the current status of the bot
90
+ def status(message)
91
+ @pipeline << Messages::Internal::StatusResponse(message.requester, stats)
92
+ end
93
+
94
+ # Returns status of the bot in a formatted string
95
+ def stats
96
+ return ["Uptime: #{Helpers::format_seconds(@start_time - Time.now)}",
97
+ "Plugins: #{@plugins.plugins.size} loaded",
98
+ "Lines sent: #{@socket.sent}",
99
+ "Lines received: #{@socket.received}"].join(' ')
100
+ end
101
+
102
+ # Adds hooks to pipeline for processing messages
103
+ def hook_pipeline
104
+ {:Outgoing_Admin => :admin, :Outgoing_Away => :away,
105
+ :Outgoing_ChannelMode => :chanmode, :Outgoing_Connect => :connect,
106
+ :Outgoing_Die => :die, :Outgoing_Info => :info,
107
+ :Outgoing_Invite => :invite, :Outgoing_Ison => :ison,
108
+ :Outgoing_Join => :join, :Outgoing_Kick => :kick,
109
+ :Outgoing_Kill => :kill, :Outgoing_Links => :links,
110
+ :Outgoing_List => :list, :Outgoing_Lusers => :lusers,
111
+ :Outgoing_Motd => :motd, :Outgoing_Names => :names,
112
+ :Outgoing_Nick => :nick, :Outgoing_Notice => :notice,
113
+ :Outgoing_Oper => :oper, :Outgoing_Part => :part,
114
+ :Outgoing_Pass => :pass, :Outgoing_Ping => :ping,
115
+ :Outgoing_Pong => :pong, :Outgoing_Privmsg => :privmsg,
116
+ :Outgoing_Quit => :quit, :Outgoing_Rehash => :rehash,
117
+ :Outgoing_ServList => :servlist, :Outgoing_Squery => :squery,
118
+ :Outgoing_Squit => :squit, :Outgoing_Stats => :stats,
119
+ :Outgoing_Summon => :summon, :Outgoing_Time => :time,
120
+ :Outgoing_Topic => :topic, :Outgoing_Trace => :trace,
121
+ :Outgoing_Unaway => :unaway, :Outgoing_User => :user,
122
+ :Outgoing_UserHost => :userhost, :Outgoing_UserMode => :usermode,
123
+ :Outgoing_Users => :users, :Outgoing_Version => :version,
124
+ :Outgoing_Who => :who, :Outgoing_WhoWas => :whowas,
125
+ :Outgoing_Whois => :whois, :Internal_EstablishConnection => :bot_connect,
126
+ :Internal_StatusRequest => :status, :Internal_ChangeNick => :set_nick,
127
+ :Internal_NickRequest => :get_nick, :Internal_HaltBot => :halt,
128
+ :Internal_Disconnected => :disconnected, :Internal_TimerClear => :clear_timer
129
+ }.each_pair{ |type,method| @pipeline.hook(self, method, type) }
130
+ end
131
+
132
+ # message:: Messages::Internal::TimerClear
133
+ # Clear all actions from timer
134
+ def clear_timer(message)
135
+ @timer.clear
136
+ end
137
+
138
+ # message:: Messages::Internal::Disconnected
139
+ # Disconnect the bot from the IRC server
140
+ def disconnected(message)
141
+ @socket.shutdown
142
+ @socket = nil
143
+ end
144
+
145
+ # Stop the bot
146
+ def halt(message)
147
+ @shutdown = true
148
+ @thread.run
149
+ end
150
+
151
+ # message:: Messages::Internal::ChangeNick message
152
+ # Changes the bot's nick to the given nick
153
+ def set_nick(message)
154
+ @nick = message.new_nick
155
+ end
156
+
157
+ # message:: Messages::Internal::NickRequest
158
+ # Sends the bot's nick to plugins
159
+ def get_nick(message)
160
+ @pipeline << Messages::Internal::NickResponse(message.requester, @nick)
161
+ end
162
+
163
+ # message:: Messages::Outgoing::Pass message
164
+ # Sends PASS message to server
165
+ def pass(message)
166
+ @socket << "PASS #{message.password}"
167
+ end
168
+
169
+ # message:: Messages::Outgoing::Nick message
170
+ # Sends NICK message to server
171
+ def nick(message)
172
+ nick = message.nick.is_a?(Models::Nick) ? message.nick.nick : message.nick
173
+ @socket << "NICK #{nick}"
174
+ end
175
+
176
+ # message:: Messages::Outgoing::User message
177
+ # Sends USER message to server
178
+ def user(message)
179
+ @socket << "USER #{message.username} #{message.mode} * :#{message.real_name}"
180
+ end
181
+
182
+ # message:: Messages::Outgoing::Oper message
183
+ # Sends Oper message to server
184
+ def oper(message)
185
+ @socket << "OPER #{message.name} #{message.password}"
186
+ end
187
+
188
+ # message:: Messages::Outgoing::UserMode message
189
+ # Sends MODE message to server
190
+ def user_mode(message)
191
+ raise Exceptions::InvalidValue.new('Mode must be in the form of: [+-][a-z]+') unless message.mode =~ /^[+\-][a-z]+$/
192
+ nick = message.nick.is_a?(Models::Nick) ? message.nick.nick : message.nick
193
+ @socket << "MODE #{nick} #{message.mode}"
194
+ end
195
+
196
+ # message:: Messages::Outgoing::Quit message
197
+ # Sends QUIT message to server
198
+ def quit(message)
199
+ @socket << "QUIT :#{message.message}"
200
+ end
201
+
202
+ # message:: Messages::Outgoing::Squit message
203
+ # Sends SQUIT message to server
204
+ def squit(message)
205
+ @socket << "SQUIT #{message.server} :#{message.comment}"
206
+ end
207
+
208
+ # message:: Messages::Outgoing::Join message
209
+ # Sends JOIN message to server
210
+ def join(message)
211
+ channel = message.channel.is_a?(Models::Channel) ? message.channel.name : message.channel
212
+ @socket << "JOIN #{channel} #{message.key}"
213
+ end
214
+
215
+ # message:: Messages::Outgoing::Part message
216
+ # Sends PART message to server
217
+ def part(message)
218
+ channel = message.channel.is_a?(Models::Channel) ? message.channel.name : message.channel
219
+ @socket << "PART #{channel} :#{message.reason}"
220
+ end
221
+
222
+ # message:: Messages::Outgoing::ChannelMode message
223
+ # Sends MODE message to server
224
+ def channel_mode(message)
225
+ target = message.target
226
+ channel = message.channel
227
+ target = target.nick if target.is_a?(Models::Nick)
228
+ channel = channel.name if channel.is_a?(Models::Channel)
229
+ @socket << "MODE #{channel} #{message.mode} #{target}"
230
+ end
231
+
232
+ # message:: Messages::Outgoing::Topic message
233
+ # Sends TOPIC message to server
234
+ def topic(message)
235
+ channel = message.channel.is_a?(Models::Channel) ? message.channel.name : message.channel
236
+ @socket << "TOPIC #{channel} :#{message.topic}"
237
+ end
238
+
239
+ # message:: Messages::Outgoing::Names message
240
+ # Sends NAMES message to server
241
+ def names(message)
242
+ channel = message.channel.is_a?(Models::Channel) ? message.channel.name : message.channel
243
+ @socket << "NAMES #{channel} #{message.target}"
244
+ end
245
+
246
+ # message:: Messages::Outgoing::List message
247
+ # Sends LIST message to server
248
+ def list(message)
249
+ channel = message.channel.is_a?(Models::Channel) ? message.channel.name : message.channel
250
+ @socket << "LIST #{channel}"
251
+ end
252
+
253
+ # message:: Messages::Outgoing::Invite message
254
+ # Sends INVITE message to server
255
+ def invite(message)
256
+ nick = message.nick.is_a?(Models::Nick) ? message.nick.nick : message.nick
257
+ channel = message.channel.is_a?(Models::Channel) ? message.channel.name : message.channel
258
+ @socket << "INVITE #{nick} #{channel}"
259
+ end
260
+
261
+ # message:: Messages::Outgoing::Kick message
262
+ # Sends KICK message to server
263
+ def kick(message)
264
+ nick = message.nick.is_a?(Models::Nick) ? message.nick.nick : message.nick
265
+ channel = message.channel.is_a?(Models::Channel) ? message.channel.name : message.channel
266
+ @socket << "KICK #{channel} #{nick} :#{message.reason}"
267
+ end
268
+
269
+ # message:: Messages::Outgoing::Privmsg message
270
+ # Sends PRIVMSG message to server
271
+ def privmsg(message)
272
+ target = message.target.name if message.target.is_a?(Models::Channel)
273
+ target = message.target.nick if message.target.is_a?(Models::Nick)
274
+ target = message.target unless target
275
+ @socket << "PRIVMSG #{target} :#{message.message}"
276
+ end
277
+
278
+ # message:: Messages::Outgoing::Notice message
279
+ # Sends NOTICE message to server
280
+ def notice(message)
281
+ target = message.target.name if message.target.is_a?(Models::Channel)
282
+ target = message.target.nick if message.target.is_a?(Models::Nick)
283
+ @socket << "NOTICE #{target} :#{message}"
284
+ end
285
+
286
+ # message:: Messages::Outgoing::Motd message
287
+ # Sends MOTD message to server
288
+ def motd(message)
289
+ @socket << "MOTD #{message.target}"
290
+ end
291
+
292
+ # message:: Messages::Outgoing::Lusers message
293
+ # Sends LUSERS message to server
294
+ def lusers(message)
295
+ @socket << "LUSERS #{message.mask} #{message.target}"
296
+ end
297
+
298
+ # message:: Messages::Outgoing::Version message
299
+ # Sends VERSION message to server
300
+ def version(message)
301
+ @socket << "VERSION #{message.target}"
302
+ end
303
+
304
+ # message:: Messages::Outgoing::Stats message
305
+ # Sends STATS message to server
306
+ def stats(message)
307
+ raise Exceptions::InvalidValue.new('Query must be a single character') unless message.query =~ /^[a-z]$/
308
+ @socket << "STATS #{message.query} #{message.target}"
309
+ end
310
+
311
+ # message:: Messages::Outgoing::Links message
312
+ # Sends LINKS message to server
313
+ def links(message)
314
+ @socket << "LIST #{message.server} #{message.mask}"
315
+ end
316
+
317
+ # message:: Messages::Outgoing::Time message
318
+ # Sends TIME message to server
319
+ def time(message)
320
+ @socket << "TIME #{message.target}"
321
+ end
322
+
323
+ # message:: Messages::Outgoing::Connect message
324
+ # Sends CONNECT message to server
325
+ def connect(message)
326
+ @socket << "CONNECT #{message.target_server} #{message.port} #{message.remote_server}"
327
+ end
328
+
329
+ # message:: Messages::Outgoing::Trace message
330
+ # Sends TRACE message to server
331
+ def trace(message)
332
+ @socket << "TRACE #{message.target}"
333
+ end
334
+
335
+ # message:: Messages::Outgoing::Admin message
336
+ # Sends ADMIN message to server
337
+ def admin(message)
338
+ @socket << "ADMIN #{message.target}"
339
+ end
340
+
341
+ # message:: Messages::Outgoing::Info message
342
+ # Sends INFO message to server
343
+ def info(message)
344
+ @socket << "INFO #{message.target}"
345
+ end
346
+
347
+ # message:: Messages::Outgoing::ServList message
348
+ # Sends SERVLIST message to server
349
+ def servlist(message)
350
+ @socket << "SERVLIST #{message.mask} #{message.type}"
351
+ end
352
+
353
+ # message:: Messages::Outgoing::Squery message
354
+ # Sends SQUERY message to server
355
+ def squery(message)
356
+ @socket << "SQUERY #{message.service_name} #{message.message}"
357
+ end
358
+
359
+ # message:: Messages::Outgoing::Who message
360
+ # Sends WHO message to server
361
+ def who(message)
362
+ o = message.only_ops ? 'o' : ''
363
+ @socket << "WHO #{message.mask} #{o}"
364
+ end
365
+
366
+ # message:: Messages::Outgoing::Whois message
367
+ # Sends WHOIS message to server
368
+ def whois(message)
369
+ nick = message.nick.is_a?(Models::Nick) ? message.nick.nick : message.nick
370
+ @socket << "WHOIS #{message.target_server} #{nick}"
371
+ end
372
+
373
+ # message:: Messages::Outgoing::WhoWas message
374
+ # Sends WHOWAS message to server
375
+ def whowas(message)
376
+ nick = message.nick.is_a?(Models::Nick) ? message.nick.nick : message.nick
377
+ @socket << "WHOWAS #{message.nick} #{message.count} #{message.target}"
378
+ end
379
+
380
+ # message:: Messages::Outgoing::Kill message
381
+ # Sends KILL message to server
382
+ def kill(message)
383
+ nick = message.nick.is_a?(Models::Nick) ? message.nick.nick : message.nick
384
+ @socket << "KILL #{nick} :#{message.comment}"
385
+ end
386
+
387
+ # message:: Messages::Outgoing::Ping message
388
+ # Sends PING message to server
389
+ def ping(message)
390
+ @socket << "PING #{message.message}"
391
+ end
392
+
393
+ # message:: Messages::Outgoing::Pong message
394
+ # Sends PONG message to server
395
+ def pong(message)
396
+ @socket << "PONG #{message.server} #{message.string.nil? ? '' : ":#{message.string}"}"
397
+ end
398
+
399
+ # message:: Messages::Outgoing::Away message
400
+ # Sends AWAY message to server
401
+ def away(message)
402
+ @socket << "AWAY :#{message.message}"
403
+ end
404
+
405
+ # message:: Messages::Outgoing::Unaway message
406
+ # Sends AWAY message to server
407
+ def unaway(message)
408
+ @socket << "AWAY"
409
+ end
410
+
411
+ # message:: Messages::Outgoing::Rehash message
412
+ # Sends REHASH message to server
413
+ def rehash(message)
414
+ @socket << "REHASH"
415
+ end
416
+
417
+ # message:: Messages::Outgoing::Die message
418
+ # Sends DIE message to server
419
+ def die(message)
420
+ @socket << "DIE"
421
+ end
422
+
423
+ # message:: Messages::Outgoing::Restart message
424
+ # Sends RESTART message to server
425
+ def restart(message)
426
+ @socket << "RESTART"
427
+ end
428
+
429
+ # message:: Messages::Outgoing::Summon message
430
+ # Sends SUMMON message to server
431
+ def summon(message)
432
+ nick = message.nick.is_a?(Models::Nick) ? message.nick.nick : message.nick
433
+ channel = message.channel.is_a?(Models::Channel) ? message.channel.name : message.channel
434
+ @socket << "SUMMON #{nick} #{message.target} #{channel}"
435
+ end
436
+
437
+ # message:: Messages::Outgoing::Users message
438
+ # Sends USERS message to server
439
+ def users(message)
440
+ @socket << "USERS #{message.target}"
441
+ end
442
+
443
+ def wallops
444
+ end
445
+
446
+ # message:: Messages::Outgoing::UserHost message
447
+ # Sends USERHOST message to server
448
+ def userhost(message)
449
+ nick = message.nick.is_a?(Models::Nick) ? message.nick.nick : message.nick
450
+ @socket << "USERHOST #{nick}"
451
+ end
452
+
453
+ # message:: Messages::Outgoing::Ison message
454
+ # Sends ISON message to server
455
+ def ison(message)
456
+ nick = message.nick.is_a?(Models::Nick) ? message.nick.nick : message.nick
457
+ @socket << "ISON #{nick}"
458
+ end
459
+
460
+ private
461
+
462
+ # Cleans information from models to avoid
463
+ # stale values
464
+ def clean_models
465
+ Models::Nick.clean
466
+ Models::Channel.clean
467
+ Models::NickChannel.destroy_all
468
+ Models::Signature.delete_all
469
+ end
470
+ end
471
+
472
+ end
@@ -0,0 +1,54 @@
1
+ module ModSpox
2
+
3
+ class BotConfig
4
+
5
+ @@config = nil
6
+
7
+ # Populates all important paths. This does not need to
8
+ # be explicitly called though nothing bad will happen if
9
+ # it is. Keys available are:
10
+ # :basepath => path to gem directory
11
+ # :libpath => path to lib directory
12
+ # :datapath => path to data directory
13
+ # :pluginpath => path to plugin directory
14
+ # :pluginextraspath => path to extra functionality plugins
15
+ # :userpath => path to mod_spox directory in user's home directory
16
+ # :userpluginpath => path to user's plugin directory
17
+ # :userconfigpath => path to the user configuration file
18
+ def self.populate
19
+ gemname, gem = Gem.source_index.find{|name, spec|
20
+ spec.name == 'mod_spox' && spec.version.version = $BOTVERSION
21
+ }
22
+ if(gem)
23
+ p = gem.full_gem_path
24
+ up = Etc.getpwnam(Etc.getlogin).dir
25
+ @@config = {:basepath => p,
26
+ :libpath => "#{p}/lib/mod_spox",
27
+ :datapath => "#{p}/data/mod_spox",
28
+ :pluginpath => "#{p}/data/mod_spox/plugins",
29
+ :pluginextraspath => "#{p}/data/mod_spox/extras",
30
+ :userpath => "#{up}/.mod_spox",
31
+ :userpluginpath => "#{up}/.mod_spox/plugins",
32
+ :userconfigpath => "#{up}/.mod_spox/config"}
33
+ [@@config[:userpath], @@config[:userpluginpath]].each do |path|
34
+ Dir.mkdir(path) unless File.exists?(path)
35
+ end
36
+ else
37
+ p gem
38
+ p gemname
39
+ raise Exceptions::InstallationError.new('Failed to find mod_spox gem')
40
+ end
41
+ end
42
+
43
+ # name:: Name of the path string you would like
44
+ # Provides access to important path values
45
+ def self.[](name)
46
+ BotConfig.populate unless @@config
47
+ name = name.to_sym unless name.is_a?(Symbol)
48
+ raise Exceptions::UnknownKey.new("Failed to find given key: #{name}") unless @@config.has_key?(name)
49
+ return @@config[name]
50
+ end
51
+
52
+ end
53
+
54
+ end