Created
November 6, 2009 17:57
-
-
Save agesome/228144 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| require "socket" | |
| class Asgard | |
| def initialize | |
| @bm = BackendMaster.new | |
| @bm.run_backend(IRCBackend.new('irc.cluenet.org', 6667, 'Asgard')) | |
| @bm.gather_stacks | |
| end | |
| def run | |
| sent = false | |
| connected = false | |
| while true | |
| Kernel::sleep(0.5) | |
| if (l = @bm.line) | |
| if not sent and @bm.connected?('irc.cluenet.org') | |
| @bm.group_j('irc.cluenet.org', 'asgard') | |
| sent = true | |
| end | |
| puts(l.inspect) | |
| end | |
| end | |
| end | |
| end | |
| class BackendMaster | |
| def initialize | |
| @backends = [] | |
| @services = [] | |
| @threads = [] | |
| @cstack = [] | |
| end | |
| def run_backend(backend) | |
| @backends << backend | |
| @services << 'irc.cluenet.org' | |
| @threads << Thread.new { @backends.last.run } | |
| end | |
| def gather_stacks | |
| Thread.new do | |
| while true | |
| Kernel::sleep(0.1) | |
| @backends.each do |b| | |
| $mstack.synchronize { @cstack += b.stack } | |
| end | |
| end | |
| end | |
| end | |
| def line | |
| $mstack.synchronize { return @cstack.shift } | |
| end | |
| def message(service, recipient, text) | |
| s = @backends[@services.index(service)] | |
| if recipient['@'] | |
| r = recipient.split('@') | |
| if not r[0].empty? | |
| s.message('@' + r[1], "#{r[0]}: " + text) | |
| else | |
| s.message('@' + r[1], text) | |
| end | |
| else | |
| s.message(recipient, text) | |
| end | |
| end | |
| def server(service, text) | |
| b = @backends[@services.index(service)] | |
| b.server(text) | |
| end | |
| def connected?(service) | |
| b = @backends[@services.index(service)] | |
| return b.connected? | |
| end | |
| def group_j(service, group) | |
| b = @backends[@services.index(service)] | |
| b.group_j(group) | |
| end | |
| end | |
| =begin | |
| a backend class should know about: | |
| -recipients | |
| -sources | |
| -services | |
| =end | |
| =begin | |
| outcoming message format: | |
| -target service | |
| -target recipient | |
| -text | |
| if recipient is in a channel, recipient format is <nick>@<channel> | |
| =end | |
| =begin | |
| incoming message format: | |
| -sender nick | |
| -sender ident | |
| -destination | |
| -message text | |
| =end | |
| class IRCBackend | |
| def initialize(service, port, nick) | |
| @socket = TCPSocket.new(service, port) | |
| @socket.puts("NICK #{nick}") | |
| @socket.puts("USER #{nick} localhost #{service} :#{nick} bot.") | |
| # stack of parsed messages | |
| @stack = [] | |
| @connected = false | |
| end | |
| def run | |
| @socket.each_line do |line| | |
| puts("<< #{line}") | |
| if line['PING'] | |
| server(line.gsub('PING', 'PONG')) | |
| @connected = true | |
| else | |
| if (l = parse(line)) | |
| $mstack.synchronize { @stack << l } | |
| end | |
| end | |
| end | |
| end | |
| # << :[email protected] PRIVMSG #asgard :hey Asgard :P | |
| # << :[email protected] PRIVMSG Asgard :hey :P | |
| def parse(l) | |
| r = {} | |
| s = l.split(' ') | |
| if s[1] == 'PRIVMSG' | |
| puts("Parsing: #{l}") | |
| r[:n] = s[0][1..s[0].index('!')] | |
| puts(r[:n]) | |
| r[:i] = s[0][s[0].index('!')..s[0].length] | |
| r[:s] = s[2] | |
| r[:m] = s[2..s.lenght].flatten | |
| return r | |
| else | |
| return nil | |
| end | |
| end | |
| # a message to recipient | |
| def message(recipient, text) | |
| puts(">> #{text}") | |
| if recipient[0] == '@' | |
| recipient[0] = '#' | |
| end | |
| @socket.puts("PRIVMSG #{recipient} :#{text}") | |
| end | |
| # raw server message | |
| def server(text) | |
| puts(">> #{text}") | |
| @socket.puts(text) | |
| end | |
| def group_j(group) | |
| server("JOIN \##{group}") | |
| end | |
| def group_l(group) | |
| server("PART \##{group}") | |
| end | |
| def stack | |
| # clear stack reference, then return stack | |
| r = @stack | |
| @stack = [] | |
| $mstack.synchronize { return r } | |
| end | |
| def close | |
| @sock.close | |
| end | |
| def connected? | |
| return @connected | |
| end | |
| end | |
| if __FILE__ == $PROGRAM_NAME | |
| $mstack = Mutex.new | |
| a = Asgard.new | |
| a.run | |
| end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment