syndi 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +12 -0
  3. data/CHANGELOG.md +0 -0
  4. data/Gemfile +8 -0
  5. data/INSTALL.md +86 -0
  6. data/LICENSE +28 -0
  7. data/README.md +104 -0
  8. data/Rakefile +26 -0
  9. data/WINDOWS.md +64 -0
  10. data/bin/syndi +102 -0
  11. data/bin/syndi-conf +47 -0
  12. data/conf/example.yml +101 -0
  13. data/docs/Events.md +103 -0
  14. data/docs/Upgrade.md +16 -0
  15. data/ext/csyndi/events.c +50 -0
  16. data/ext/csyndi/extconf.rb +20 -0
  17. data/ext/csyndi/integer.c +53 -0
  18. data/ext/csyndi/libauto.c +37 -0
  19. data/ext/csyndi/logger.c +228 -0
  20. data/include/syndi/csyndi.h +38 -0
  21. data/include/syndi/events.h +19 -0
  22. data/include/syndi/integer.h +17 -0
  23. data/include/syndi/logger.h +57 -0
  24. data/include/syndi.h +22 -0
  25. data/lib/syndi/actress.rb +12 -0
  26. data/lib/syndi/api/events.rb +170 -0
  27. data/lib/syndi/api/object.rb +29 -0
  28. data/lib/syndi/api/plugin.rb +155 -0
  29. data/lib/syndi/api.rb +7 -0
  30. data/lib/syndi/bot.rb +270 -0
  31. data/lib/syndi/config.rb +113 -0
  32. data/lib/syndi/configure/cli.rb +23 -0
  33. data/lib/syndi/configure/generator.rb +410 -0
  34. data/lib/syndi/configure.rb +19 -0
  35. data/lib/syndi/dsl/base.rb +74 -0
  36. data/lib/syndi/dsl/irc.rb +13 -0
  37. data/lib/syndi/events.rb +114 -0
  38. data/lib/syndi/irc/common.rb +63 -0
  39. data/lib/syndi/irc/library.rb +89 -0
  40. data/lib/syndi/irc/object/channel.rb +21 -0
  41. data/lib/syndi/irc/object/entity.rb +90 -0
  42. data/lib/syndi/irc/object/message.rb +99 -0
  43. data/lib/syndi/irc/object/user.rb +139 -0
  44. data/lib/syndi/irc/protocol/numerics.rb +60 -0
  45. data/lib/syndi/irc/protocol.rb +164 -0
  46. data/lib/syndi/irc/sasl/diffie_hellman.rb +36 -0
  47. data/lib/syndi/irc/sasl/mech/dh_blowfish.rb +83 -0
  48. data/lib/syndi/irc/sasl/mech/plain.rb +39 -0
  49. data/lib/syndi/irc/sasl/mech.rb +15 -0
  50. data/lib/syndi/irc/server.rb +301 -0
  51. data/lib/syndi/irc/state/channel_manager.rb +6 -0
  52. data/lib/syndi/irc/state/support.rb +142 -0
  53. data/lib/syndi/irc/state/user_manager.rb +6 -0
  54. data/lib/syndi/irc/std/commands.rb +99 -0
  55. data/lib/syndi/irc/std/numerics.rb +216 -0
  56. data/lib/syndi/irc.rb +8 -0
  57. data/lib/syndi/jewel/specification.rb +121 -0
  58. data/lib/syndi/jewel/util.rb +27 -0
  59. data/lib/syndi/jewel.rb +5 -0
  60. data/lib/syndi/rubyext/string.rb +10 -0
  61. data/lib/syndi/verbosity.rb +10 -0
  62. data/lib/syndi/version.rb +38 -0
  63. data/lib/syndi.rb +129 -0
  64. data/spec/helper.rb +32 -0
  65. data/spec/syndi/events_spec.rb +43 -0
  66. data/tasks/compile.rake +15 -0
  67. data/tasks/install.rake +10 -0
  68. data/tasks/package.rake +13 -0
  69. data/tasks/spec.rake +12 -0
  70. metadata +101 -13
@@ -0,0 +1,114 @@
1
+ # Copyright (c) 2013, Autumn Perrault, et al. All rights reserved.
2
+ # This free software is distributed under the FreeBSD license (see LICENSE).
3
+
4
+ require 'syndi/verbosity'
5
+
6
+ module Syndi
7
+
8
+ # A simple event management system, designed particularly for Syndi.
9
+ #
10
+ # @!attribute [r] events
11
+ # @return [Hash{Symbol => Array<Syndi::Events::Listener>}] The collection of events and associated listeners.
12
+ class Events
13
+
14
+ attr_reader :events
15
+
16
+ def initialize
17
+ @events = Hash.new
18
+ end
19
+
20
+ # Create a new listener on a given +event+, which will have the given
21
+ # block attached and executed upon the event's occurrence.
22
+ #
23
+ # @param [Symbol] event The event which to await.
24
+ # @param [Integer] priority The priority this listener should have in the hook
25
+ # execution procedure. Must be 1-5 with 1 being of utmost priority.
26
+ #
27
+ # @yield [...] The parameters passed when the event was broadcasted. This varies
28
+ # by event. See the official event reference for Syndi events.
29
+ #
30
+ # @return [Syndi::Events::Listener] The listener.
31
+ def on event, priority = 3, &prc
32
+ @events[event] ||= Array.new
33
+
34
+ if priority < 1 || priority > 5
35
+ raise ArgumentError, "invalid event priority specified"
36
+ end
37
+
38
+ hook = Listener.new self, event, priority, prc
39
+ @events[event] << hook
40
+ hook
41
+ end
42
+
43
+ # This will broadcast the given +event+, executing each listener and passing
44
+ # to it the parameters supplied here, respecting priority and operating in a
45
+ # thread.
46
+ #
47
+ # @param [Symbol] event
48
+ # @param [...] parameters The arguments to be passed to each listener.
49
+ def emit event, *parameters
50
+ if @events[event]
51
+
52
+ # collect the listeners with respect to priority
53
+ one = @events.collect { |hook| (hook.priority == 1 ? hook : nil) }.compact
54
+ two = @events.collect { |hook| (hook.priority == 2 ? hook : nil) }.compact
55
+ three = @events.collect { |hook| (hook.priority == 3 ? hook : nil) }.compact
56
+ four = @events.collect { |hook| (hook.priority == 4 ? hook : nil) }.compact
57
+ five = @events.collect { |hook| (hook.priority == 5 ? hook : nil) }.compact
58
+
59
+ Syndi.log.verbose "event *#{event}* is being broadcasted on #{self}", VNOISY
60
+
61
+ # spawn a thread and perform the executions
62
+ Thread.new do
63
+ begin
64
+ # cease if status ever becomes false/nil
65
+ status = true
66
+
67
+ one.each { |code| status = code.call parameters if status }
68
+ two.each { |code| status = code.call parameters if status }
69
+ three.each { |code| status = code.call parameters if status }
70
+ four.each { |code| status = code.call parameters if status }
71
+ five.each { |code| status = code.call parameters if status }
72
+ rescue => e
73
+ # catch thread errors
74
+ Syndi.log.error "A listener to a broadcast of #{event} on #{self} caused an exception to rise (#{e})", true
75
+ end
76
+ end
77
+
78
+ end
79
+ end
80
+
81
+ def inspect
82
+ "<#Syndi::Events: obj_id=#{object_id} event_count=#{@events.length}>"
83
+ end
84
+ alias_method :to_s, :inspect
85
+
86
+ # A class which represents a listener.
87
+ class Listener
88
+ attr_reader :event, :priority, :code
89
+
90
+ def initialize sys, event, priority, prc
91
+ @sys = sys
92
+ @event = event
93
+ @priority = priority
94
+ @code = prc
95
+
96
+ Syndi.log.verbose "new listener spawned and attached to #{event}: #{self}", VNOISY
97
+ end
98
+
99
+ def deaf
100
+ @sys.events[event].delete self
101
+ end
102
+
103
+ def inspect
104
+ "<#Syndi::Events::Listener: sys=#@sys event=#@event priority=#@priority proc={#@code}>"
105
+ end
106
+ alias_method :to_s, :inspect
107
+
108
+ end
109
+
110
+ end
111
+
112
+ end
113
+
114
+ # vim: set ts=4 sts=2 sw=2 et:
@@ -0,0 +1,63 @@
1
+ # Copyright (c) 2013, Autumn Perrault, et al. All rights reserved.
2
+ # This free software is distributed under the FreeBSD license (see LICENSE).
3
+
4
+ module Syndi
5
+
6
+ module IRC
7
+
8
+ # A class which manages such common IRC functions as syndijoining channels,
9
+ # and identifying to services the traditional PRIVMSG way.
10
+ class Common
11
+
12
+ # Construct a new common function handler.
13
+ #
14
+ # @param [Syndi::IRC::Library] lib The IRC library instance.
15
+ def initialize lib
16
+ @lib = lib
17
+ $m.events.on :die, &method(:do_die)
18
+ @lib.events.on :connected, &method(:do_syndijoin)
19
+ end
20
+
21
+ # Automatically identify with services the traditional way, which is
22
+ # to say by a /msg.
23
+ #
24
+ # @param [Syndi::IRC::Server] irc The IRC connection.
25
+ def do_identify irc
26
+ if $m.conf['irc'][irc.s]['nickIdentify']
27
+
28
+ # Assume the service is NickServ if not specified
29
+ service = $m.conf['irc'][irc.s]['nickIdentify']['service'] || 'NickServ'
30
+ # and assume the command is IDENTIFY if not specified
31
+ command = $m.conf['irc'][irc.s]['nickIdentify']['command'] || 'IDENTIFY'
32
+
33
+ # we can't actually /msg anyone yet.....
34
+ end
35
+ end
36
+
37
+ # Automatically join IRC channels upon connection.
38
+ #
39
+ # @param [Syndi::IRC::Server] irc The IRC connection.
40
+ def do_syndijoin irc
41
+ if $m.conf['irc'][irc.s]['syndijoin']
42
+
43
+ $m.conf['irc'][irc.s]['syndijoin'].each do |chan|
44
+ irc.join(chan['name'], chan['key']||nil)
45
+ end
46
+
47
+ end
48
+ end
49
+
50
+ # Disconnect from servers on termination.
51
+ #
52
+ # @param [String] reason Reason for termination.
53
+ def do_die reason
54
+ @lib.connections.each { |net, irc| irc.disconnect reason }
55
+ end
56
+
57
+ end # class Common
58
+
59
+ end # module IRC
60
+
61
+ end # module Syndi
62
+
63
+ # vim: set ts=4 sts=2 sw=2 et:
@@ -0,0 +1,89 @@
1
+ # Copyright (c) 2013, Autumn Perrault, et al. All rights reserved.
2
+ # This free software is distributed under the FreeBSD license (see LICENSE).
3
+
4
+ require 'syndi/irc/server'
5
+ require 'syndi/irc/object/entity'
6
+ require 'syndi/irc/object/channel'
7
+ require 'syndi/irc/object/user'
8
+ require 'syndi/irc/protocol'
9
+ require 'syndi/irc/common'
10
+
11
+ module Syndi
12
+
13
+ module IRC
14
+
15
+ # The base of the IRC framework.
16
+ #
17
+ # @!attribute [r] events
18
+ # @return [Syndi::API::Events] The IRC event system.
19
+ #
20
+ # @!attribute [r] connections
21
+ # @return [Hash{String => Syndi::IRC::Server}] Collection of IRC connections.
22
+ class Library
23
+
24
+ attr_reader :events, :connections
25
+
26
+ def initialize
27
+
28
+ # Initialize our event system.
29
+ @events = Syndi::API::Events.new
30
+ # Prepare our collection of IRC server connections.
31
+ @connections = Hash.new
32
+
33
+ # Be ready to accept data.
34
+ $m.events.on :net_receive, 1, &method(:receive)
35
+
36
+ # Start connections when Syndi is started.
37
+ $m.events.on :start, &method(:start)
38
+
39
+ # Parse data.
40
+ @parser = Syndi::IRC::Protocol.new self
41
+
42
+ # Handle common functions.
43
+ @common = Syndi::IRC::Common.new self
44
+
45
+ end # def initialize
46
+
47
+ # Process incoming network data.
48
+ #
49
+ # @param [Object] socket_object The socket object, which in the case of
50
+ # ourselves should be an {Syndi::IRC::Server}, or we won't handle it.
51
+ def receive socket_object
52
+ if socket_object.instance_of? Syndi::IRC::Server
53
+ socket_object.recv
54
+ end
55
+ end
56
+
57
+ # Initiate IRC connections.
58
+ def start
59
+
60
+ # Iterate through each IRC server in the config, and connect to it.
61
+ $m.conf['irc'].each do |name, hash|
62
+ begin
63
+ # Configure the IRC instance.
64
+ @connections[name] = Syndi::IRC::Server.new(name) do |c|
65
+ c.address = hash['address']
66
+ c.port = hash['port']
67
+ c.nick = hash['nickname'][0]
68
+ c.user = hash['username']
69
+ c.real = hash['realName']
70
+ c.ssl = hash['useSSL']
71
+ end
72
+
73
+ # Connect.
74
+ $m.sockets << @connections[name]
75
+ @connections[name].connect
76
+ rescue => e
77
+ $m.error("Connection to #{name} failed: #{e}", false, e.backtrace)
78
+ end
79
+ end
80
+
81
+ end # def start
82
+
83
+ end # class Library
84
+
85
+ end # module IRC
86
+
87
+ end # module Syndi
88
+
89
+ # vim: set ts=4 sts=2 sw=2 et:
@@ -0,0 +1,21 @@
1
+ # Copyright (c) 2013, Autumn Perrault, et al. All rights reserved.
2
+ # This free software is distributed under the FreeBSD license (see LICENSE).
3
+
4
+ # Namespace: IRC
5
+ module IRC
6
+
7
+ # Namespace: Object
8
+ module Object
9
+
10
+ # A class which represents an individual IRC channel, its associated
11
+ # properties, the users which it contains, and methods to interact with it.
12
+ class Channel
13
+
14
+
15
+ end # class Channel
16
+
17
+ end # module Object
18
+
19
+ end # module IRC
20
+
21
+ # vim: set ts=4 sts=2 sw=2 et:
@@ -0,0 +1,90 @@
1
+ # Copyright (c) 2013, Autumn Perrault, et al. All rights reserved.
2
+ # This free software is distributed under the FreeBSD license (see LICENSE).
3
+
4
+ module Syndi
5
+
6
+ module IRC
7
+
8
+ module Object
9
+
10
+ # A superclass which represents an IRC 'entity'; i.e., a channel or user.
11
+ # It acts as a base for {Syndi::IRC::Object::User} and {Syndi::IRC::Object::Channel}.
12
+ #
13
+ # @api IRC
14
+ # @since 4.0.0
15
+ # @author noxgirl
16
+ #
17
+ # @!attribute [r] irc
18
+ # @return [Syndi::IRC::Server] The IRC server on which this entity exists.
19
+ #
20
+ # @!attribute [r] name
21
+ # @return [String] The name of the entity.
22
+ class Entity
23
+
24
+ attr_reader :irc, :name
25
+
26
+ # New instance.
27
+ #
28
+ # @param [Syndi::IRC::Server] irc The server.
29
+ # @param [Symbol] type Either +:channel+ or +:user+.
30
+ # @param [String] name The name of this entity (nickname or channel name).
31
+ def initialize(irc, type, name)
32
+ @irc = irc
33
+ @entity_type = type
34
+ @name = name
35
+ end
36
+
37
+ # @return [true, false] Whether we're a channel.
38
+ def channel?
39
+ @entity_type == :channel ? true : false
40
+ end
41
+
42
+ # @return [true, false] Whether we're a user.
43
+ def user?
44
+ @entity_type == :user ? true : false
45
+ end
46
+
47
+ # Send a message to this entity. This will additionally divide messages
48
+ # which are too long into multiple messages.
49
+ #
50
+ # This will call irc:onMsg with +self+ and +message+.
51
+ #
52
+ # @param [String] message The message.
53
+ # @param [true, false] notice Whether this should be a /notice as opposed
54
+ # to a /msg.
55
+ def msg(message, notice=false)
56
+
57
+ command = (notice == false ? 'PRIVMSG' : 'NOTICE')
58
+ len = ":#{@irc.nick}!#{@irc.user}@#{@irc.mask} #{command} #@name :".length
59
+ raw = ":#{@irc.nick}!#{@irc.user}@#{@irc.mask} #{command} #@name :#{message}\r\n"
60
+
61
+ if raw.length > 512
62
+
63
+ msgs = []
64
+ nmessage = message
65
+ until raw.length <= 512
66
+ msgs << nmessage.slice!(0, 512-len)
67
+ raw = ":#{@irc.nick}!#{@irc.user}@#{@irc.mask} #{command} #@name :#{nmessage}\r\n"
68
+ end
69
+
70
+ msgs.each { |m| @irc.snd "#{command} #@name :#{m}" }
71
+
72
+ else
73
+ @irc.snd "#{command} #@name :#{message}"
74
+ end
75
+
76
+ $m.events.call 'irc:onMsg', self, message
77
+
78
+ end # def msg
79
+
80
+ def to_s; @name; end
81
+
82
+ end # class Entity
83
+
84
+ end # module Object
85
+
86
+ end # module IRC
87
+
88
+ end # module Syndi
89
+
90
+ # vim: set ts=4 sts=2 sw=2 et:
@@ -0,0 +1,99 @@
1
+ # Copyright (c) 2013, Autumn Perrault, et al. All rights reserved.
2
+ # This free software is distributed under the FreeBSD license (see LICENSE).
3
+
4
+ # Namespace: IRC
5
+ module IRC
6
+
7
+ # Namespace: Object
8
+ module Object
9
+
10
+ # A class which represents an IRC message, its associated properties, and
11
+ # offers methods for working with the message.
12
+ #
13
+ # @since 4.0.0
14
+ # @author noxgirl
15
+ # @api IRC
16
+ #
17
+ # @!attribute [r] irc
18
+ # @return [IRC::Server] The server on which the message was received.
19
+ #
20
+ # @!attribute [r] sender
21
+ # @return [IRC::Object::User] The user from whom the message was received.
22
+ #
23
+ # @!attribute [r] body
24
+ # @return [Array<String>] The body of the message, divided into elements by its spaces.
25
+ #
26
+ # @!attribute [r] nature
27
+ # @return [Symbol] The nature of the message, +:notice+ or +:msg+.
28
+ #
29
+ # @!attribute [r] channel
30
+ # @return [nil] If this message was received privately and not through a channel, this is nil.
31
+ # @return [IRC::Object::Channel] If it was received through a channel, the channel in question.
32
+ # @see #in_channel?
33
+ class Message
34
+
35
+ attr_reader :irc, :sender, :body, :nature, :channel
36
+
37
+ # Process a new message.
38
+ #
39
+ # @param [IRC::Server] irc The server on which the message was received.
40
+ # @param [IRC::Object::User] sender The user from whom the message was received.
41
+ # @param [String] body The body of the message.
42
+ # @param [Symbol] nature The nature of the message: either a +:notice+ or a +:msg+.
43
+ # @param [IRC::Object::Channel] channel If it was received through a channel, the channel.
44
+ #
45
+ # @example
46
+ # message = IRC::Object::Message.new(irc, user, body, :msg, channel)
47
+ def initialize(irc, sender, body, nature=:notice, channel=nil)
48
+
49
+ @irc = irc
50
+ @sender = sender
51
+ @body = body
52
+ @nature = nature
53
+ @channel = channel
54
+
55
+ end
56
+
57
+ # Reply to this message.
58
+ #
59
+ # @param [String] msg The message with which to reply.
60
+ # @param [true, false] in_channel If the response should be in-channel (assuming it was received in a channel), specify +true+.
61
+ # If it should be private regardless of where it was received, specify +false+.
62
+ #
63
+ # @note Essentially reply() exists to simplify the API.
64
+ # Rather than necessitating that commands use endless, illegible conditional
65
+ # nests to determine what to do, reply() is available so the API will just
66
+ # use some common sense to do it for them.
67
+ #
68
+ # @example
69
+ # msg.reply("The bar is of foo, indeed.", true)
70
+ #
71
+ # @todo Unfinished.
72
+ def reply(msg, in_channel)
73
+
74
+ case [@channel.nil, in_channel, @nature]
75
+
76
+ # Respond in-channel if this was sent to a channel *and* in_channel
77
+ # is specified as true.
78
+ when false, true, :msg
79
+ irc.msg(@channel, msg)
80
+
81
+ # Likewise for channel notices.
82
+ when false, true, :notice
83
+
84
+ end
85
+
86
+ end
87
+
88
+ # Checks whether the message was received through a channel.
89
+ #
90
+ # @return [true, false]
91
+ def in_channel?; @channel.nil?; end
92
+
93
+ end # class Message
94
+
95
+ end # module Object
96
+
97
+ end # module IRC
98
+
99
+ # vim: set ts=4 sts=2 sw=2 et:
@@ -0,0 +1,139 @@
1
+ # Copyright (c) 2013, Autumn Perrault, et al. All rights reserved.
2
+ # This free software is distributed under the FreeBSD license (see LICENSE).
3
+
4
+ module Syndi
5
+
6
+ # Namespace: IRC
7
+ module IRC
8
+
9
+ # Namespace: Object
10
+ module Object
11
+
12
+ # A class which represents an individual user on IRC, and which provides
13
+ # useful data regarding said user, and methods using which to interact
14
+ # with the user.
15
+ #
16
+ # @api IRC
17
+ # @since 4.0.0
18
+ # @author noxgirl
19
+ #
20
+ # @!attribute irc
21
+ # @return [Syndi::IRC::Server] The server on which the user is located.
22
+ #
23
+ # @!attribute nick
24
+ # @return [String] The user's nickname.
25
+ #
26
+ # @!attribute user
27
+ # @return [String] If known, the user's username or ident.
28
+ # @return [nil] If unknown.
29
+ # @see #user_known?
30
+ #
31
+ # @!attribute host
32
+ # @return [String] If known, the user's hostname or mask.
33
+ # @return [nil] If unknown.
34
+ # @see #host_known?
35
+ #
36
+ # @!attribute account
37
+ # @return [String] If the user is logged in, their account name.
38
+ # @see #logged_in?
39
+ #
40
+ # @!attribute away
41
+ # @return [true] If the user is away.
42
+ # @return [false] If the user is present.
43
+ class User < Entity
44
+
45
+ attr_reader :nick, :user, :host, :account, :away
46
+
47
+ # Process a new user.
48
+ #
49
+ # @param [Syndi::IRC::Server] irc The server the user is on.
50
+ # @param [String] nickname The user's nickname.
51
+ # @param [String] username The user's username or ident.
52
+ # @param [String] hostname The user's hostname or mask.
53
+ # @param [true, false] away Whether the user is away: +true+ or +false+.
54
+ #
55
+ # @example
56
+ # user = Syndi::IRC::Object::User.new(irc, 'missfoo', 'cowmilk', 'the.night.is.lovely', false)
57
+ def initialize(irc, nickname, username=nil, hostname=nil, away=false)
58
+
59
+ super(irc, :user, nickname) # Entity#initialize
60
+ @nick = nickname
61
+ @user = username
62
+ @host = hostname
63
+ @away = away
64
+ @account = nil
65
+
66
+ end
67
+
68
+ # If the user logs into an account, this is used to specify the name of
69
+ # the account with which ze has identified.
70
+ #
71
+ # @param [String] accountname The name of the account.
72
+ #
73
+ # @example
74
+ # user.login('root')
75
+ def login(accountname)
76
+ unless accountname.nil?
77
+ @account = accountname
78
+ end
79
+ end
80
+
81
+ # If the user logs out of hir account, this is used to update their
82
+ # logged-in status.
83
+ def logout
84
+ @account = nil
85
+ end
86
+
87
+ # Update the user's known away status.
88
+ #
89
+ # @param [true, false] new The user's new away status, which should be +true+ or +false+.
90
+ def away=(new)
91
+ if new == true or new == false
92
+ @away = new
93
+ end
94
+ end
95
+
96
+ # Update the user's known hostname or mask.
97
+ #
98
+ # @param [String] new The user's new hostname.
99
+ def host=(new); @host = new unless new.nil?; end
100
+
101
+ # Update the user's known nickname.
102
+ #
103
+ # @param [String] new The user's new nickname.
104
+ def nick=(new); @nick = new unless new.nil?; end
105
+
106
+ # Update the user's known username or ident.
107
+ #
108
+ # @param [String] new The user's new username.
109
+ def user=(new); @user = new unless new.nil?; end
110
+
111
+ # This will check whether the user's username is known.
112
+ #
113
+ # @return [true] If known.
114
+ # @return [false] If Unknown.
115
+ def user_known?; @user.nil? ? false : true; end
116
+
117
+ # This will check whether the user's hostname is known.
118
+ #
119
+ # @return [true] If known.
120
+ # @return [false] If Unknown.
121
+ def host_known?; @host.nil? ? false : true; end
122
+
123
+ # This will check whether the user is logged in.
124
+ #
125
+ # @return [true] If known.
126
+ # @return [false] If Unknown.
127
+ def logged_in?; @account.nil? ? false : true; end
128
+
129
+ def inspect; "#<Syndi::IRC::Object::User: irc=#@irc nick=#@nick account=#@account>"; end
130
+
131
+ end # class User
132
+
133
+ end # module Object
134
+
135
+ end # module IRC
136
+
137
+ end # module Syndi
138
+
139
+ # vim: set ts=4 sts=2 sw=2 et:
@@ -0,0 +1,60 @@
1
+ # Copyright (c) 2013, Autumn Perrault, et al. All rights reserved.
2
+ # This free software is distributed under the FreeBSD license (see LICENSE).
3
+
4
+ require 'syndi/irc/std/numerics'
5
+
6
+ module Syndi
7
+
8
+ module IRC
9
+
10
+ class Protocol
11
+
12
+ # An extension of {Syndi::IRC::Protocol}, which parses numerics.
13
+ module Numerics
14
+ include Syndi::IRC::Std::Numerics
15
+
16
+ # RPL_WELCOME
17
+ define_method("on_#{RPL_WELCOME}") do |irc, raw, params|
18
+ $m.info "Successfully connected to #{irc} IRC network!" # log
19
+ end
20
+
21
+ # RPL_MYINFO
22
+ define_method("on_#{RPL_MYINFO}") do |irc, raw, params|
23
+ irc.supp.server_name = params[3]
24
+ end
25
+
26
+ # RPL_ISUPPORT
27
+ define_method("on_#{RPL_ISUPPORT}") do |irc, raw, params|
28
+ irc.supp.isupport(irc, params[3..-5].join(' ')) # process the isupport data
29
+ unless irc.supp.connected
30
+ irc.supp.connected = true
31
+ $m.irc.events.call :connected, irc # emit the :connected event
32
+ end
33
+ end
34
+
35
+ # RPL_SASLSUCCESS
36
+ define_method("on_#{RPL_SASLSUCCESS}") do |irc, raw, params|
37
+ $m.info "SASL authentication on #{irc} succeeded!"
38
+ irc.cap_end
39
+ end
40
+
41
+ # ERR_SASLFAIL
42
+ define_method("on_#{ERR_SASLFAIL}") do |irc, raw, params|
43
+ if irc.supp.sasl_method == :dh_blowfish
44
+ irc.authenticate # try again with the PLAIN mechanism
45
+ else
46
+ # ope, failed
47
+ $m.error "SASL authentication on #{irc} failed: received ERR_SASLFAIL from server."
48
+ irc.cap_end
49
+ end
50
+ end
51
+
52
+ end # class Numerics
53
+
54
+ end # class Protocol
55
+
56
+ end # module IRC
57
+
58
+ end # module Syndi
59
+
60
+ # vim: set ts=4 sts=2 sw=2 et: