ircbot 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/MIT-LICENSE +20 -0
- data/README +47 -0
- data/Rakefile +56 -0
- data/bin/ircbot +50 -0
- data/lib/irc/agent.rb +177 -0
- data/lib/irc/client.rb +476 -0
- data/lib/irc/const.rb +242 -0
- data/lib/irc/irc.rb +324 -0
- data/lib/irc/localize.rb +260 -0
- data/lib/ircbot.rb +41 -0
- data/lib/ircbot/agent_manager.rb +89 -0
- data/lib/ircbot/config_client.rb +369 -0
- data/lib/ircbot/core_ext/digest.rb +14 -0
- data/lib/ircbot/core_ext/irc.rb +61 -0
- data/lib/ircbot/core_ext/rand-polimorphism.rb +23 -0
- data/lib/ircbot/core_ext/writefile.rb +45 -0
- data/lib/ircbot/framework.rb +50 -0
- data/lib/ircbot/ordered_hash.rb +91 -0
- data/lib/ircbot/reply_client.rb +328 -0
- metadata +82 -0
@@ -0,0 +1,61 @@
|
|
1
|
+
# Extension to ruby-irc-lib
|
2
|
+
|
3
|
+
module IRC
|
4
|
+
class AbnormalTerminated < Exception; end
|
5
|
+
|
6
|
+
class Connection
|
7
|
+
def sendNAMES (channel = nil)
|
8
|
+
# p [:sendNAMES, Message(CMD_NAMES, nil, nil, channel)]
|
9
|
+
send(Message(CMD_NAMES, nil, nil, channel))
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
class Message
|
14
|
+
def create_hash! (client)
|
15
|
+
unless @hash
|
16
|
+
@hash = {}
|
17
|
+
@hash[:client] = client
|
18
|
+
@hash[:type] = self.command
|
19
|
+
@hash[:prefix] = self.prefix
|
20
|
+
@hash[:from] = User::parse(self.prefix).nick
|
21
|
+
@hash[:str] = self .trailing
|
22
|
+
@hash[:string] = @hash[:str]
|
23
|
+
@hash[:to] = to = self .params[0]
|
24
|
+
@hash[:timestamp] = Time .now
|
25
|
+
|
26
|
+
unless to
|
27
|
+
case self .command
|
28
|
+
when CMD_JOIN, CMD_QUIT
|
29
|
+
@hash[:to] = to = @hash[:str]
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
if to != nil and to == client .nick
|
34
|
+
@hash[:to] = @hash[:from]
|
35
|
+
end
|
36
|
+
if client .is_a? Client
|
37
|
+
@client = client
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def [] (key) # key must be a symbol
|
43
|
+
@hash[key]
|
44
|
+
end
|
45
|
+
|
46
|
+
def []= (key, val)
|
47
|
+
@hash[key] = val
|
48
|
+
end
|
49
|
+
|
50
|
+
def reply (string, to = nil)
|
51
|
+
self[:reply] = string
|
52
|
+
if @client and string
|
53
|
+
@client .speak(self, to)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def previous
|
58
|
+
@client && @client .previous_message(self)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
#!/usr/local/bin/ruby
|
2
|
+
#
|
3
|
+
# rand-extension.rb
|
4
|
+
# Author:
|
5
|
+
# Created: Thu Nov 8 17:26:09 2001
|
6
|
+
|
7
|
+
|
8
|
+
# rand ��¿����
|
9
|
+
unless $__RAND_OVERRIDE__
|
10
|
+
$__RAND_OVERRIDE__ = true
|
11
|
+
alias :__rand__ :rand
|
12
|
+
def rand (obj)
|
13
|
+
case obj
|
14
|
+
when Array
|
15
|
+
index = __rand__(obj .size)
|
16
|
+
obj[index]
|
17
|
+
when Range
|
18
|
+
rand(obj .to_a)
|
19
|
+
else
|
20
|
+
__rand__(obj)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
#!/usr/local/bin/ruby
|
2
|
+
#
|
3
|
+
# writefile.rb
|
4
|
+
# Author: maiha@wota.jp
|
5
|
+
# Created: 2002/05/10 14:16:13
|
6
|
+
# Changed: 2010/01/02 20:42:25
|
7
|
+
|
8
|
+
=begin
|
9
|
+
== usage
|
10
|
+
ensure directories of a path exist before open it.
|
11
|
+
|
12
|
+
=== syntacs
|
13
|
+
File::open!(path, ...)
|
14
|
+
|
15
|
+
== sample
|
16
|
+
Dir["/tmp/**/*"] # => []
|
17
|
+
File .open!("/tmp/foo/ora", "w+")
|
18
|
+
Dir["/tmp/**/*"] # => ["/tmp/foo", "/tmp/foo/ora"]
|
19
|
+
|
20
|
+
== changes
|
21
|
+
* 2002/06/11 19:45:32
|
22
|
+
change interface: open(...,'w!') => open!(...)
|
23
|
+
=end
|
24
|
+
|
25
|
+
def File.open! (path, *args, &block)
|
26
|
+
dirname = File.dirname(path) + '/'
|
27
|
+
unless File.directory?(dirname)
|
28
|
+
dirs = []
|
29
|
+
dirname.scan(/\//) {dirs << $`}
|
30
|
+
dirs.shift
|
31
|
+
dirs.each do |dir|
|
32
|
+
unless directory?(dir)
|
33
|
+
Dir.mkdir(dir)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
open(path, *args, &block)
|
38
|
+
end
|
39
|
+
|
40
|
+
if $0 == __FILE__
|
41
|
+
path = "/tmp/a/b/c.txt"
|
42
|
+
File.open!(path, "w+") {|f| f.puts "[OK] Wrote to #{path}"}
|
43
|
+
puts File.read(path){}
|
44
|
+
File.unlink(path)
|
45
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module Ircbot
|
2
|
+
mattr_accessor :load_paths
|
3
|
+
self.load_paths = {}
|
4
|
+
|
5
|
+
class InvalidFilename < SecurityError; end
|
6
|
+
class FileNotFound < SecurityError; end
|
7
|
+
|
8
|
+
class Recover < RuntimeError
|
9
|
+
attr_reader :wait
|
10
|
+
|
11
|
+
def initialize(wait = 300)
|
12
|
+
@wait = wait
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
class << self
|
17
|
+
def root
|
18
|
+
@root || File.expand_path(Dir.pwd)
|
19
|
+
end
|
20
|
+
|
21
|
+
def root=(value)
|
22
|
+
@root = value
|
23
|
+
end
|
24
|
+
|
25
|
+
def push_path(type, path, file_glob = "**/*.rb")
|
26
|
+
load_paths[type] = [Pathname(path), file_glob]
|
27
|
+
end
|
28
|
+
|
29
|
+
def dir_for(type)
|
30
|
+
load_paths[type][0] or
|
31
|
+
raise RuntimeError, "directory not found: #{type}"
|
32
|
+
end
|
33
|
+
|
34
|
+
def glob_for(type)
|
35
|
+
load_paths[type][1]
|
36
|
+
end
|
37
|
+
|
38
|
+
def path_for(type, name)
|
39
|
+
name = name.to_s
|
40
|
+
raise InvalidFilename, name if name =~ %r{\.\.|~|/}
|
41
|
+
|
42
|
+
path = dir_for(type) + name
|
43
|
+
path.readable_real? or
|
44
|
+
raise FileNotFound, name
|
45
|
+
|
46
|
+
return path
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
@@ -0,0 +1,91 @@
|
|
1
|
+
## -*- coding: utf-8 -*-
|
2
|
+
# ordered_hash.rb
|
3
|
+
# Author:
|
4
|
+
# Created: Tue Jul 24 18:52:49 2001
|
5
|
+
|
6
|
+
class Ircbot::OrderedHash < Hash
|
7
|
+
def self.[] (*array)
|
8
|
+
size = array .size
|
9
|
+
if size % 2 == 0
|
10
|
+
hash = self .new
|
11
|
+
(size / 2) .times do |index|
|
12
|
+
key, value = array[index*2,2]
|
13
|
+
hash[key] = value
|
14
|
+
end
|
15
|
+
hash
|
16
|
+
else
|
17
|
+
super
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def initialize(*args)
|
22
|
+
super
|
23
|
+
@store_order = []
|
24
|
+
end
|
25
|
+
|
26
|
+
def []= (key, value)
|
27
|
+
unless self .has_key? key
|
28
|
+
@store_order << key
|
29
|
+
end
|
30
|
+
super
|
31
|
+
end
|
32
|
+
|
33
|
+
def keys
|
34
|
+
@store_order
|
35
|
+
end
|
36
|
+
|
37
|
+
def each
|
38
|
+
keys .each do |key|
|
39
|
+
yield(key, self[key])
|
40
|
+
end
|
41
|
+
end
|
42
|
+
alias :each_pair :each
|
43
|
+
|
44
|
+
def delete (key)
|
45
|
+
@store_order .delete(key)
|
46
|
+
super
|
47
|
+
end
|
48
|
+
|
49
|
+
def each_value
|
50
|
+
keys .each do |key|
|
51
|
+
yield(self[key])
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def collect
|
56
|
+
keys .collect do |key|
|
57
|
+
yield(key, self[key])
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def to_a
|
62
|
+
keys .collect do |key|
|
63
|
+
[key, self[key]]
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
# $B@hF,$KDI2C$9$k!#(B
|
68
|
+
def unshift (key, val)
|
69
|
+
self[key] = val
|
70
|
+
@store_order .delete key
|
71
|
+
@store_order .unshift key
|
72
|
+
val
|
73
|
+
end
|
74
|
+
|
75
|
+
# $B;XDj$5$l$?%-!<$r;}$DMWAG$NE:;z$rJV$9!#(B(Array#index $BAjEv$N5!G=(B)
|
76
|
+
def index_of_key (value)
|
77
|
+
keys .index value
|
78
|
+
end
|
79
|
+
|
80
|
+
def position (value)
|
81
|
+
keys .each_with_index do |key, i|
|
82
|
+
return i if self[key] == value
|
83
|
+
end
|
84
|
+
return nil
|
85
|
+
end
|
86
|
+
|
87
|
+
def index_of_value (value)
|
88
|
+
position(value)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
@@ -0,0 +1,328 @@
|
|
1
|
+
# -*- coding: euc-jp -*-
|
2
|
+
|
3
|
+
require 'ircbot/config_client'
|
4
|
+
|
5
|
+
module Ircbot
|
6
|
+
class ReplyClient < ConfigClient
|
7
|
+
DIGEST_MAX_SIZE = 400
|
8
|
+
REGEXP_REDIRECT = ">|��"
|
9
|
+
|
10
|
+
def myname_regexp_string
|
11
|
+
names = @mynames.join('|')
|
12
|
+
"(#{ names })"
|
13
|
+
end
|
14
|
+
|
15
|
+
def speak0 (to, obj, save = nil)
|
16
|
+
Thread.critical = true
|
17
|
+
message =
|
18
|
+
case obj
|
19
|
+
when String ; obj
|
20
|
+
when Array
|
21
|
+
array = obj.collect {|item| item.inspect}.join(', ')
|
22
|
+
"(#{obj.size})[#{array}]"
|
23
|
+
when Regexp ; "/#{obj.source}/"
|
24
|
+
else ; obj.inspect
|
25
|
+
end
|
26
|
+
|
27
|
+
message.split(/\n+/).each do |line|
|
28
|
+
buffer = line.digest(DIGEST_MAX_SIZE)
|
29
|
+
unless buffer.empty?
|
30
|
+
# ����������������
|
31
|
+
@message_queue.push([buffer, to])
|
32
|
+
|
33
|
+
# ��å��������֥������Ȥ�������ơ�@messages �˻Ĥ�
|
34
|
+
if save
|
35
|
+
# :AnnaChan!~anna@219-106-253-19.cust.bit-drive.ne.jp PRIVMSG #bot :test\r\n"
|
36
|
+
str = ":#{@nick}!~bot@localhost PRIVMSG #{@channel} :#{buffer}\r\n"
|
37
|
+
msg = Message::parse(str)
|
38
|
+
msg.create_hash!(self)
|
39
|
+
msg[:id] = add_message(msg)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
Thread.critical = false
|
44
|
+
end
|
45
|
+
|
46
|
+
def speak (msg, to = nil, log = nil)
|
47
|
+
speak0(to || msg[:to], msg[:reply], log)
|
48
|
+
end
|
49
|
+
|
50
|
+
def newAgent (name)
|
51
|
+
script = Ircbot.path_for(:cpi, "#{name}.cpi").read{}
|
52
|
+
eval(script, TOPLEVEL_BINDING)
|
53
|
+
|
54
|
+
rescue SecurityError => e
|
55
|
+
err = "#{e.class}: #{e}"
|
56
|
+
syslog(err, :error)
|
57
|
+
return err
|
58
|
+
end
|
59
|
+
|
60
|
+
# xxxAgent: Agent �� xxx ����
|
61
|
+
# ����: String (Agent �μ��̻�)
|
62
|
+
# ����: String (������)
|
63
|
+
|
64
|
+
# ����������Ȥο�����Ͽ
|
65
|
+
def registerAgent (name0)
|
66
|
+
# ex) name0="daiben(12345)"
|
67
|
+
name, arg = name0.split(/\s|\(/, 2) # ex) name="daiben"
|
68
|
+
arg = arg.to_s.delete(")").strip # ex) arg="12345"
|
69
|
+
|
70
|
+
err = nil
|
71
|
+
this = "registerAgent"
|
72
|
+
agent = @agents[name]
|
73
|
+
@agents_opt[name] = arg
|
74
|
+
|
75
|
+
# p [:debug, :registerAgent, name0, name, arg]
|
76
|
+
|
77
|
+
agent = newAgent(name)
|
78
|
+
case agent
|
79
|
+
when NilClass
|
80
|
+
err = "Agent plugin script return nil (will not be registerd)."
|
81
|
+
when String
|
82
|
+
err = agent
|
83
|
+
else
|
84
|
+
@agents[name] = AgentManager.new(name, agent, self, arg)
|
85
|
+
end
|
86
|
+
|
87
|
+
status = "#{this}(#{name})... #{err || 'OK.'}"
|
88
|
+
syslog(status, err ? :error : :normal)
|
89
|
+
return status
|
90
|
+
end
|
91
|
+
|
92
|
+
def startAgent (name0)
|
93
|
+
# ex) name0="daiben(12345)"
|
94
|
+
name, arg = name0.split(/\s|\(/, 2) # ex) name="daiben"
|
95
|
+
arg = arg.to_s.delete(")").strip # ex) arg="12345"
|
96
|
+
|
97
|
+
err = nil
|
98
|
+
this = "startAgent"
|
99
|
+
agent = @agents[name]
|
100
|
+
arg = @agents_opt[name] if arg.empty?
|
101
|
+
|
102
|
+
case agent
|
103
|
+
when NilClass
|
104
|
+
err = "no such agent."
|
105
|
+
when AgentManager
|
106
|
+
agent.start(arg)
|
107
|
+
else
|
108
|
+
err = "unknown agent type(#{agent.class})."
|
109
|
+
end
|
110
|
+
|
111
|
+
status = "#{this}(#{name})... #{err || 'OK.'}"
|
112
|
+
syslog(status, err ? :error : :normal)
|
113
|
+
return status
|
114
|
+
end
|
115
|
+
|
116
|
+
def removeAgent (name)
|
117
|
+
err = nil
|
118
|
+
this = "removeAgent"
|
119
|
+
agent = @agents[name]
|
120
|
+
|
121
|
+
case agent
|
122
|
+
when NilClass
|
123
|
+
err = "no such agent."
|
124
|
+
when AgentManager
|
125
|
+
agent.stop
|
126
|
+
@agents.delete(name)
|
127
|
+
else
|
128
|
+
err = "unknown agent type(#{agent.class})."
|
129
|
+
end
|
130
|
+
|
131
|
+
status = "#{this}(#{name})... #{err || 'OK.'}"
|
132
|
+
syslog(status, err ? :error : :normal)
|
133
|
+
return status
|
134
|
+
end
|
135
|
+
|
136
|
+
# Agent �κƵ�ư
|
137
|
+
def restartAgent (name)
|
138
|
+
err = nil
|
139
|
+
this = "restartAgent"
|
140
|
+
agent = @agents[name]
|
141
|
+
|
142
|
+
case agent
|
143
|
+
when NilClass
|
144
|
+
err = "no such agent."
|
145
|
+
when AgentManager
|
146
|
+
agent.stop
|
147
|
+
obj = newAgent(name)
|
148
|
+
case obj
|
149
|
+
when NilClass
|
150
|
+
err = "Agent plugin script return nil (will not be registerd)."
|
151
|
+
when String
|
152
|
+
err = agent
|
153
|
+
else
|
154
|
+
arg = @agents_opt[name]
|
155
|
+
agent = AgentManager.new(name, obj, self, arg)
|
156
|
+
@agents[name] = agent
|
157
|
+
agent.start
|
158
|
+
end
|
159
|
+
else
|
160
|
+
err = "unknown agent type(#{agent.class})."
|
161
|
+
end
|
162
|
+
|
163
|
+
status = "#{this}(#{name})... #{err || 'OK.'}"
|
164
|
+
syslog(status, err ? :error : :normal)
|
165
|
+
return status
|
166
|
+
end
|
167
|
+
|
168
|
+
def stopAgent (name)
|
169
|
+
err = nil
|
170
|
+
this = "stopAgent"
|
171
|
+
agent = @agents[name]
|
172
|
+
|
173
|
+
case agent
|
174
|
+
when NilClass
|
175
|
+
err = "no such agent."
|
176
|
+
when AgentManager
|
177
|
+
agent.stop
|
178
|
+
else
|
179
|
+
err = "unknown agent type(#{agent.class})."
|
180
|
+
end
|
181
|
+
|
182
|
+
status = "#{this}(#{name})... #{err || 'OK.'}"
|
183
|
+
syslog(status, err ? :error : :normal)
|
184
|
+
return status
|
185
|
+
end
|
186
|
+
|
187
|
+
def do_help (msg)
|
188
|
+
target = msg[:arg].to_s.strip
|
189
|
+
if target.empty?
|
190
|
+
# �ܥåȤΥإ�ס�cpi�������֤�
|
191
|
+
alives = 0
|
192
|
+
names = @agents.collect {|name, agent|
|
193
|
+
if agent.alive?
|
194
|
+
alives += 1
|
195
|
+
name = "*#{name}"
|
196
|
+
end
|
197
|
+
name
|
198
|
+
}.join(', ')
|
199
|
+
msg[:reply] = "#{@help}\ncpi(#{alives}/#{@agents.size}): #{names}"
|
200
|
+
speak(msg)
|
201
|
+
|
202
|
+
else
|
203
|
+
# ���̤� cpi �Υإ�פ��֤���
|
204
|
+
target = target.delete('()[] ')
|
205
|
+
@agents.each_pair do |name, agent|
|
206
|
+
next unless target == name
|
207
|
+
next unless (result = agent.apply_methods(msg, :do_help))
|
208
|
+
msg[:reply] = result
|
209
|
+
speak(msg)
|
210
|
+
end
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
def parse_command (msg)
|
215
|
+
case msg[:type].to_s
|
216
|
+
when CMD_PRIVMSG
|
217
|
+
case msg[:str].to_s
|
218
|
+
when /^\s*#{myname_regexp_string}\s*(\.\s*[^\s\(]+)/o
|
219
|
+
msg[:called] = $1
|
220
|
+
msg[:command] = $2
|
221
|
+
msg[:arg] = $'.to_s.strip
|
222
|
+
msg[:command].gsub!(/^\./, '') if msg[:command]
|
223
|
+
when /(#{REGEXP_REDIRECT})\s*#{myname_regexp_string}\s*(\.\s*[^\s\(]+)?\s*$/o
|
224
|
+
msg[:arg] = $`.to_s.strip
|
225
|
+
msg[:called] = $2
|
226
|
+
msg[:command] = $3
|
227
|
+
msg[:command].gsub!(/^\./, '') if msg[:command]
|
228
|
+
end
|
229
|
+
end
|
230
|
+
return msg
|
231
|
+
end
|
232
|
+
|
233
|
+
def distributeMessage (msg)
|
234
|
+
# prepare accessors for dummy agents
|
235
|
+
msg.create_hash!(self)
|
236
|
+
msg[:id] = add_message(msg)
|
237
|
+
msg = parse_command(msg)
|
238
|
+
|
239
|
+
# p [msg[:type], msg[:from], msg[:from].to_s.empty?, msg[:str]]
|
240
|
+
|
241
|
+
# �ȸ������ʥ�å�����(PING��)��̵��
|
242
|
+
if msg[:from].to_s.empty?
|
243
|
+
return nil
|
244
|
+
end
|
245
|
+
|
246
|
+
begin
|
247
|
+
# reserved commands
|
248
|
+
name = msg[:arg].to_s.sub(/\A\s*\(?\s*/, '')
|
249
|
+
name = name.sub(/\s*\)?\s*\Z/, '') unless name.include?('(')
|
250
|
+
|
251
|
+
case msg[:command].to_s
|
252
|
+
when /^restart$/
|
253
|
+
names = name.split(/\s*,?\s+/)
|
254
|
+
names = @agents.keys if names.empty?
|
255
|
+
names.each do |name|
|
256
|
+
msg.reply(restartAgent(name))
|
257
|
+
end
|
258
|
+
return nil
|
259
|
+
when /^register$/ ; msg.reply(registerAgent(name)); return msg.reply(startAgent(name))
|
260
|
+
when /^remove$/ ; return msg.reply(removeAgent(name))
|
261
|
+
when /^start$/ ; return msg.reply(startAgent(name))
|
262
|
+
when /^stop$/ ; return msg.reply(stopAgent(name))
|
263
|
+
when /^help$/ ; return do_help(msg)
|
264
|
+
end
|
265
|
+
|
266
|
+
case msg[:type].to_s
|
267
|
+
when CMD_JOIN ; each_agent {|agent| agent.apply_methods(msg, :do_join)}
|
268
|
+
when CMD_PART ; each_agent {|agent| agent.apply_methods(msg, :do_part)}
|
269
|
+
when CMD_PING ; each_agent {|agent| agent.apply_methods(msg, :do_ping)}
|
270
|
+
when RPL_NAMREPLY
|
271
|
+
# p [:debug, :get_CMD_NAMES]
|
272
|
+
each_agent {|agent| agent.apply_methods(msg, :do_names)}
|
273
|
+
when CMD_PRIVMSG
|
274
|
+
|
275
|
+
# �����νФ�
|
276
|
+
if @log
|
277
|
+
do_log(msg)
|
278
|
+
end
|
279
|
+
|
280
|
+
# do_log �����˸ƤӽФ���(�����������Ѥ�����Τ���)
|
281
|
+
message = nil
|
282
|
+
catch(:reply) {
|
283
|
+
if msg[:called]
|
284
|
+
each_agent do |agent|
|
285
|
+
next unless (message = agent.apply_methods(msg, :do_command))
|
286
|
+
throw :reply
|
287
|
+
end
|
288
|
+
else
|
289
|
+
each_agent do |agent|
|
290
|
+
next unless (message = agent.apply_methods(msg, :do_reply))
|
291
|
+
throw :reply
|
292
|
+
end
|
293
|
+
end
|
294
|
+
}
|
295
|
+
|
296
|
+
# Agent#do_log �θƤӽФ�
|
297
|
+
each_agent do |agent|
|
298
|
+
msg.reply(agent.apply_methods(msg, :do_log))
|
299
|
+
end
|
300
|
+
|
301
|
+
# ��ʬ��ȯ���Ͽ
|
302
|
+
if message != nil then
|
303
|
+
dummy = {}
|
304
|
+
dummy[:str] = message
|
305
|
+
dummy[:from] = @nick
|
306
|
+
dummy[:to] = @channels
|
307
|
+
each_agent { |agent|
|
308
|
+
msg.reply(agent.apply_methods(dummy, :do_log))
|
309
|
+
}
|
310
|
+
end
|
311
|
+
|
312
|
+
return msg.reply(message)
|
313
|
+
end
|
314
|
+
rescue Exception
|
315
|
+
syslog("distributeMessage: #{$!}(#{$@[0]})", :error)
|
316
|
+
end
|
317
|
+
end
|
318
|
+
end
|
319
|
+
end
|
320
|
+
|
321
|
+
|
322
|
+
if $0 == __FILE__
|
323
|
+
config = ARGV.shift or
|
324
|
+
raise "Specify your config file\nusage: #{$0} config/xxx.dat"
|
325
|
+
irc = IRC::ReplyClient.read_config(config)
|
326
|
+
irc.start
|
327
|
+
end
|
328
|
+
|