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