syndi 0.0.1 → 0.1.0
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.
- checksums.yaml +4 -4
- data/.yardopts +12 -0
- data/CHANGELOG.md +0 -0
- data/Gemfile +8 -0
- data/INSTALL.md +86 -0
- data/LICENSE +28 -0
- data/README.md +104 -0
- data/Rakefile +26 -0
- data/WINDOWS.md +64 -0
- data/bin/syndi +102 -0
- data/bin/syndi-conf +47 -0
- data/conf/example.yml +101 -0
- data/docs/Events.md +103 -0
- data/docs/Upgrade.md +16 -0
- data/ext/csyndi/events.c +50 -0
- data/ext/csyndi/extconf.rb +20 -0
- data/ext/csyndi/integer.c +53 -0
- data/ext/csyndi/libauto.c +37 -0
- data/ext/csyndi/logger.c +228 -0
- data/include/syndi/csyndi.h +38 -0
- data/include/syndi/events.h +19 -0
- data/include/syndi/integer.h +17 -0
- data/include/syndi/logger.h +57 -0
- data/include/syndi.h +22 -0
- data/lib/syndi/actress.rb +12 -0
- data/lib/syndi/api/events.rb +170 -0
- data/lib/syndi/api/object.rb +29 -0
- data/lib/syndi/api/plugin.rb +155 -0
- data/lib/syndi/api.rb +7 -0
- data/lib/syndi/bot.rb +270 -0
- data/lib/syndi/config.rb +113 -0
- data/lib/syndi/configure/cli.rb +23 -0
- data/lib/syndi/configure/generator.rb +410 -0
- data/lib/syndi/configure.rb +19 -0
- data/lib/syndi/dsl/base.rb +74 -0
- data/lib/syndi/dsl/irc.rb +13 -0
- data/lib/syndi/events.rb +114 -0
- data/lib/syndi/irc/common.rb +63 -0
- data/lib/syndi/irc/library.rb +89 -0
- data/lib/syndi/irc/object/channel.rb +21 -0
- data/lib/syndi/irc/object/entity.rb +90 -0
- data/lib/syndi/irc/object/message.rb +99 -0
- data/lib/syndi/irc/object/user.rb +139 -0
- data/lib/syndi/irc/protocol/numerics.rb +60 -0
- data/lib/syndi/irc/protocol.rb +164 -0
- data/lib/syndi/irc/sasl/diffie_hellman.rb +36 -0
- data/lib/syndi/irc/sasl/mech/dh_blowfish.rb +83 -0
- data/lib/syndi/irc/sasl/mech/plain.rb +39 -0
- data/lib/syndi/irc/sasl/mech.rb +15 -0
- data/lib/syndi/irc/server.rb +301 -0
- data/lib/syndi/irc/state/channel_manager.rb +6 -0
- data/lib/syndi/irc/state/support.rb +142 -0
- data/lib/syndi/irc/state/user_manager.rb +6 -0
- data/lib/syndi/irc/std/commands.rb +99 -0
- data/lib/syndi/irc/std/numerics.rb +216 -0
- data/lib/syndi/irc.rb +8 -0
- data/lib/syndi/jewel/specification.rb +121 -0
- data/lib/syndi/jewel/util.rb +27 -0
- data/lib/syndi/jewel.rb +5 -0
- data/lib/syndi/rubyext/string.rb +10 -0
- data/lib/syndi/verbosity.rb +10 -0
- data/lib/syndi/version.rb +38 -0
- data/lib/syndi.rb +129 -0
- data/spec/helper.rb +32 -0
- data/spec/syndi/events_spec.rb +43 -0
- data/tasks/compile.rake +15 -0
- data/tasks/install.rake +10 -0
- data/tasks/package.rake +13 -0
- data/tasks/spec.rake +12 -0
- metadata +101 -13
data/lib/syndi/events.rb
ADDED
@@ -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:
|