mod_spox 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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