Class: TinyIRC::IRCSocket

Inherits:
Object
  • Object
show all
Defined in:
lib/tinyirc/ircsocket.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(bot, name, opts) ⇒ IRCSocket

Returns a new instance of IRCSocket.



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# File 'lib/tinyirc/ircsocket.rb', line 6

def initialize(bot, name, opts)
  @bot  = bot
  @name = name
  @host = opts['host'] || '127.0.0.1'
  @port = opts['port'] || 6667
  @nick = opts['nick'] || 'TinyBot'
  @user = opts['user'] || @nick
  @pass = opts['pass'] || nil
  @rnam = opts['rnam'] || 'An IRC bot in Ruby'
  @autojoin = opts['autojoin'] || []
  @prefix = opts['prefix'] || bot.prefix || '!'
  
  @reconnects = 0
  @running = false
  @last_write = Time.now

  @mtx = Mutex.new
  @log = ParticleLog.new("!#{name}", ParticleLog::INFO)
  @log.level_table[ParticleLog::IO] = 'IRC'
  @log.important "Hello, #{name}!"

  @sock = nil
  @queue = Queue.new
  @usercache = TinyIRC::UserCache.new
end

Instance Attribute Details

#autojoinObject

Returns the value of attribute autojoin.



2
3
4
# File 'lib/tinyirc/ircsocket.rb', line 2

def autojoin
  @autojoin
end

#botObject

Returns the value of attribute bot.



3
4
5
# File 'lib/tinyirc/ircsocket.rb', line 3

def bot
  @bot
end

#hostObject

Returns the value of attribute host.



2
3
4
# File 'lib/tinyirc/ircsocket.rb', line 2

def host
  @host
end

#last_writeObject

Returns the value of attribute last_write.



3
4
5
# File 'lib/tinyirc/ircsocket.rb', line 3

def last_write
  @last_write
end

#logObject (readonly)

Returns the value of attribute log.



4
5
6
# File 'lib/tinyirc/ircsocket.rb', line 4

def log
  @log
end

#mtxObject (readonly)

Returns the value of attribute mtx.



4
5
6
# File 'lib/tinyirc/ircsocket.rb', line 4

def mtx
  @mtx
end

#nameObject

Returns the value of attribute name.



2
3
4
# File 'lib/tinyirc/ircsocket.rb', line 2

def name
  @name
end

#nickObject

Returns the value of attribute nick.



2
3
4
# File 'lib/tinyirc/ircsocket.rb', line 2

def nick
  @nick
end

#passObject

Returns the value of attribute pass.



2
3
4
# File 'lib/tinyirc/ircsocket.rb', line 2

def pass
  @pass
end

#portObject

Returns the value of attribute port.



2
3
4
# File 'lib/tinyirc/ircsocket.rb', line 2

def port
  @port
end

#prefixObject

Returns the value of attribute prefix.



2
3
4
# File 'lib/tinyirc/ircsocket.rb', line 2

def prefix
  @prefix
end

#queueObject (readonly)

Returns the value of attribute queue.



4
5
6
# File 'lib/tinyirc/ircsocket.rb', line 4

def queue
  @queue
end

#reconnectsObject

Returns the value of attribute reconnects.



3
4
5
# File 'lib/tinyirc/ircsocket.rb', line 3

def reconnects
  @reconnects
end

#rnamObject

Returns the value of attribute rnam.



2
3
4
# File 'lib/tinyirc/ircsocket.rb', line 2

def rnam
  @rnam
end

#runningObject

Returns the value of attribute running.



3
4
5
# File 'lib/tinyirc/ircsocket.rb', line 3

def running
  @running
end

#sockObject (readonly)

Returns the value of attribute sock.



4
5
6
# File 'lib/tinyirc/ircsocket.rb', line 4

def sock
  @sock
end

#userObject

Returns the value of attribute user.



2
3
4
# File 'lib/tinyirc/ircsocket.rb', line 2

def user
  @user
end

#usercacheObject (readonly)

Returns the value of attribute usercache.



4
5
6
# File 'lib/tinyirc/ircsocket.rb', line 4

def usercache
  @usercache
end

Class Method Details

.process_colors(string) ⇒ Object



173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
# File 'lib/tinyirc/ircsocket.rb', line 173

def self.process_colors(string)
  string
    .gsub("%C%",     "%C?")
    .gsub(",%",      ",?")
    .gsub("%C",      "\x03")
    .gsub("%B",      "\x02")
    .gsub("%I",      "\x10")
    .gsub("%U",      "\x1F")
    .gsub("%N",      "\x0F")
    .gsub("?WHITE",  "0")
    .gsub("?BLACK",  "1")
    .gsub("?BLUE",   "2")
    .gsub("?GREEN",  "3")
    .gsub("?RED",    "4")
    .gsub("?BROWN",  "5")
    .gsub("?PURPLE", "6")
    .gsub("?ORANGE", "7")
    .gsub("?YELLOW", "8")
    .gsub("?LGREEN", "9")
    .gsub("?CYAN"  , "10")
    .gsub("?LCYAN",  "11")
    .gsub("?LBLUE",  "12")
    .gsub("?PINK",   "13")
    .gsub("?GREY",   "14")
    .gsub("?LGREY",  "15")
end

.ssplit(string) ⇒ Object



160
161
162
163
164
165
166
167
168
169
170
171
# File 'lib/tinyirc/ircsocket.rb', line 160

def self.ssplit(string)
  out = []
  arr = string.split("\n\r")
  arr.each do |i|
    items = i.scan(/.{,399}/)
    items.delete('')
    items.each do |i2|
      out << i2
    end
  end
  out
end

Instance Method Details

#authenticateObject



56
57
58
59
60
# File 'lib/tinyirc/ircsocket.rb', line 56

def authenticate
  direct_write "PASS #{@pass}" if @pass
  direct_write "NICK #{@nick}"
  direct_write "USER #{@user} 0 * :#{@rnam}"
end

#connect(reconnect = false) ⇒ Object



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/tinyirc/ircsocket.rb', line 32

def connect(reconnect=false)
  @log.important 'Connecting...'
  @mtx.synchronize do
    begin
      @sock = TCPSocket.new @host, @port
      @running = true
      @bot.handle_event type: :connect, socket: self
      Thread.new do
        authenticate
      end
    rescue => e
      @log.error "#{e.class.name} - #{e.message}"
      @bot.handle_event type: :disconnect, socket: self
    end
  end
end

#ctcp(target, message) ⇒ Object



212
213
214
# File 'lib/tinyirc/ircsocket.rb', line 212

def ctcp(target, message)
  write("PRIVMSG #{target} :\x01#{self.class.process_colors(message)}\x01")
end

#del_group(host, name) ⇒ Object



123
124
125
# File 'lib/tinyirc/ircsocket.rb', line 123

def del_group(host, name)
  @bot.db.execute('DELETE FROM groupinfo WHERE server=? AND host=? AND name=?', [@name, host, name])
end

#direct_write(msg) ⇒ Object



62
63
64
65
# File 'lib/tinyirc/ircsocket.rb', line 62

def direct_write(msg)
  log.io "W> #{msg}"
  @sock.write "#{msg}\r\n"
end

#disconnectObject



49
50
51
52
53
54
# File 'lib/tinyirc/ircsocket.rb', line 49

def disconnect
  @mtx.synchronize do
    @running = false
    sock.close
  end
end

#has_group(host, name) ⇒ Object



127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/tinyirc/ircsocket.rb', line 127

def has_group(host, name)
  if (@bot.db.execute(
    'SELECT EXISTS(SELECT 1 FROM groupinfo WHERE server=? AND host=? AND name="admin" LIMIT 1)',
    [@name, host]
  ).flatten[0] == 0) then
    @bot.db.execute(
      'SELECT EXISTS(SELECT 1 FROM groupinfo WHERE server=? AND host=? AND name=? LIMIT 1)',
      [@name, host, name]
    ).flatten[0] == 1
  else
    true
  end
end

#has_perm(host, name) ⇒ Object



75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/tinyirc/ircsocket.rb', line 75

def has_perm(host, name)
  if (@bot.db.execute(
    'SELECT EXISTS(SELECT 1 FROM groupinfo WHERE server=? AND host=? AND name="admin" LIMIT 1)',
    [@name, host]
  ).flatten[0] == 1)
    return true
  end

  groups = @bot.db.execute("SELECT name FROM groupinfo WHERE server=? AND host=?", [@name, host])
  groups = groups.flatten.to_set
  groups << 'world'
  
  def where(gname)
    s = gname.split('/', 2)
    if s.length == 1
      @bot.groups[gname]
    elsif s.length == 2
      return nil unless @bot.plugins.include? s[0]
      @bot.plugins[s[0]].groups[gname]
    else
      nil
    end

  end

  groups.each do |gname|
    w = where(gname)
    next unless w
    w.perms.each do |perm|
      if perm == TinyIRC::Permission.new(*TinyIRC::Permission.parse(name))
        return true
      end
    end
  end

  false
end

#inspectObject



71
72
73
# File 'lib/tinyirc/ircsocket.rb', line 71

def inspect
  "#<TinyIRC::IRCSocket @name=#{@name.inspect}>"
end

#join(chan, key = nil) ⇒ Object



148
149
150
151
152
153
154
# File 'lib/tinyirc/ircsocket.rb', line 148

def join(chan, key = nil)
  if key
    write "JOIN #{chan} #{key}"
  else
    write "JOIN #{chan}"
  end
end

#kick(channel, target, reason = 'Bye!') ⇒ Object



224
225
226
# File 'lib/tinyirc/ircsocket.rb', line 224

def kick(channel, target, reason = 'Bye!')
  write("KICK #{channel} #{target} :#{reason}")
end

#list_groups(host) ⇒ Object



141
142
143
144
145
146
# File 'lib/tinyirc/ircsocket.rb', line 141

def list_groups(host)
  @bot.db.execute(
    'SELECT name FROM groupinfo WHERE server=? AND host=?',
    [@name, host]
  ).flatten
end

#mode(channel, params) ⇒ Object



220
221
222
# File 'lib/tinyirc/ircsocket.rb', line 220

def mode(channel, params)
  write("MODE #{channel} #{params}")
end

#nctcp(target, message) ⇒ Object



216
217
218
# File 'lib/tinyirc/ircsocket.rb', line 216

def nctcp(target, message)
  write("NOTICE #{target} :\x01#{self.class.process_colors(message)}\x01")
end

#notice(target, message) ⇒ Object



206
207
208
209
210
# File 'lib/tinyirc/ircsocket.rb', line 206

def notice(target, message)
  self.class.ssplit(self.class.process_colors(message)).each do |m|
    write("NOTICE #{target} :\u200B#{m}")
  end
end

#part(chan, reason = 'Bye') ⇒ Object



156
157
158
# File 'lib/tinyirc/ircsocket.rb', line 156

def part(chan, reason = 'Bye')
  write "PART #{chan} :#{reason}"
end

#privmsg(target, message) ⇒ Object



200
201
202
203
204
# File 'lib/tinyirc/ircsocket.rb', line 200

def privmsg(target, message)
  self.class.ssplit(self.class.process_colors(message)).each do |m|
    write("PRIVMSG #{target} :\u200B#{m}")
  end
end

#remove(channel, target, reason = 'Bye!') ⇒ Object



228
229
230
# File 'lib/tinyirc/ircsocket.rb', line 228

def remove(channel, target, reason = 'Bye!')
  write("REMOVE #{channel} #{target} :#{reason}")
end

#set_group(host, name) ⇒ Object



113
114
115
116
117
118
119
120
121
# File 'lib/tinyirc/ircsocket.rb', line 113

def set_group(host, name)
  res = @bot.db.execute(
    'SELECT EXISTS(SELECT 1 FROM groupinfo WHERE server=? AND host=? AND name=? LIMIT 1)',
    [@name, host, name]
  ).flatten[0]
  if res == 0
    @bot.db.execute('INSERT INTO groupinfo (server, host, name) VALUES (?, ?, ?)', [@name, host, name])
  end
end

#where(gname) ⇒ Object



87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/tinyirc/ircsocket.rb', line 87

def where(gname)
  s = gname.split('/', 2)
  if s.length == 1
    @bot.groups[gname]
  elsif s.length == 2
    return nil unless @bot.plugins.include? s[0]
    @bot.plugins[s[0]].groups[gname]
  else
    nil
  end

end

#write(msg) ⇒ Object



67
68
69
# File 'lib/tinyirc/ircsocket.rb', line 67

def write(msg)
  @queue.push msg
end