comboy-autumn 3.1
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.
- data/README.textile +1192 -0
- data/autumn.gemspec +25 -0
- data/bin/autumn +27 -0
- data/lib/autumn.rb +2 -0
- data/lib/autumn/authentication.rb +290 -0
- data/lib/autumn/channel_leaf.rb +107 -0
- data/lib/autumn/coder.rb +166 -0
- data/lib/autumn/console_boot.rb +9 -0
- data/lib/autumn/ctcp.rb +250 -0
- data/lib/autumn/daemon.rb +207 -0
- data/lib/autumn/datamapper_hacks.rb +290 -0
- data/lib/autumn/foliater.rb +231 -0
- data/lib/autumn/formatting.rb +236 -0
- data/lib/autumn/generator.rb +231 -0
- data/lib/autumn/genesis.rb +191 -0
- data/lib/autumn/inheritable_attributes.rb +162 -0
- data/lib/autumn/leaf.rb +738 -0
- data/lib/autumn/log_facade.rb +49 -0
- data/lib/autumn/misc.rb +87 -0
- data/lib/autumn/script.rb +74 -0
- data/lib/autumn/speciator.rb +165 -0
- data/lib/autumn/stem.rb +919 -0
- data/lib/autumn/stem_facade.rb +176 -0
- data/resources/daemons/Anothernet.yml +3 -0
- data/resources/daemons/AustHex.yml +29 -0
- data/resources/daemons/Bahamut.yml +67 -0
- data/resources/daemons/Dancer.yml +3 -0
- data/resources/daemons/GameSurge.yml +3 -0
- data/resources/daemons/IRCnet.yml +3 -0
- data/resources/daemons/Ithildin.yml +7 -0
- data/resources/daemons/KineIRCd.yml +56 -0
- data/resources/daemons/PTlink.yml +6 -0
- data/resources/daemons/QuakeNet.yml +20 -0
- data/resources/daemons/RFC1459.yml +158 -0
- data/resources/daemons/RFC2811.yml +16 -0
- data/resources/daemons/RFC2812.yml +36 -0
- data/resources/daemons/RatBox.yml +25 -0
- data/resources/daemons/Ultimate.yml +24 -0
- data/resources/daemons/Undernet.yml +6 -0
- data/resources/daemons/Unreal.yml +110 -0
- data/resources/daemons/_Other.yml +7 -0
- data/resources/daemons/aircd.yml +33 -0
- data/resources/daemons/bdq-ircd.yml +3 -0
- data/resources/daemons/hybrid.yml +38 -0
- data/resources/daemons/ircu.yml +67 -0
- data/resources/daemons/tr-ircd.yml +8 -0
- data/skel/Rakefile +135 -0
- data/skel/config/global.yml +2 -0
- data/skel/config/seasons/testing/database.yml +7 -0
- data/skel/config/seasons/testing/leaves.yml +7 -0
- data/skel/config/seasons/testing/season.yml +2 -0
- data/skel/config/seasons/testing/stems.yml +9 -0
- data/skel/leaves/administrator/README +20 -0
- data/skel/leaves/administrator/controller.rb +67 -0
- data/skel/leaves/administrator/views/autumn.txt.erb +1 -0
- data/skel/leaves/administrator/views/reload.txt.erb +11 -0
- data/skel/leaves/insulter/README +17 -0
- data/skel/leaves/insulter/controller.rb +65 -0
- data/skel/leaves/insulter/views/about.txt.erb +1 -0
- data/skel/leaves/insulter/views/help.txt.erb +1 -0
- data/skel/leaves/insulter/views/insult.txt.erb +1 -0
- data/skel/leaves/scorekeeper/README +34 -0
- data/skel/leaves/scorekeeper/config.yml +2 -0
- data/skel/leaves/scorekeeper/controller.rb +104 -0
- data/skel/leaves/scorekeeper/helpers/general.rb +64 -0
- data/skel/leaves/scorekeeper/models/channel.rb +12 -0
- data/skel/leaves/scorekeeper/models/person.rb +14 -0
- data/skel/leaves/scorekeeper/models/pseudonym.rb +11 -0
- data/skel/leaves/scorekeeper/models/score.rb +14 -0
- data/skel/leaves/scorekeeper/tasks/stats.rake +17 -0
- data/skel/leaves/scorekeeper/views/about.txt.erb +1 -0
- data/skel/leaves/scorekeeper/views/change.txt.erb +5 -0
- data/skel/leaves/scorekeeper/views/history.txt.erb +11 -0
- data/skel/leaves/scorekeeper/views/points.txt.erb +5 -0
- data/skel/leaves/scorekeeper/views/usage.txt.erb +1 -0
- data/skel/script/console +34 -0
- data/skel/script/daemon +29 -0
- data/skel/script/destroy +48 -0
- data/skel/script/generate +48 -0
- data/skel/script/server +15 -0
- metadata +170 -0
@@ -0,0 +1,20 @@
|
|
1
|
+
= Administrator: An Autumn Leaf
|
2
|
+
|
3
|
+
<b>Version 1.0 (Jul 8, 2008)</b>
|
4
|
+
|
5
|
+
Author:: Tim Morgan (mailto:riscfuture@gmail.com)
|
6
|
+
Copyright:: Copyright (c)2008 Tim Morgan
|
7
|
+
License:: Distributed under the same terms as Ruby.
|
8
|
+
|
9
|
+
This leaf allows the owner of the IRC bot to perform administrative commands on
|
10
|
+
the bot, such as quitting or reloading it. In order to protect such commands
|
11
|
+
from abuse, this bot uses the Authenticator module. The Authenticator method
|
12
|
+
that is used is specified by the +authentication+ option. For more information,
|
13
|
+
see the *Authentication* section of the README.
|
14
|
+
|
15
|
+
== Usage
|
16
|
+
|
17
|
+
!autumn:: Displays information about the version of Autumn that is running this
|
18
|
+
leaf (unprotected command).
|
19
|
+
!quit:: Terminates the stem on which the message was received.
|
20
|
+
!reload:: Reloads all source files of all leaves, and all their view files.
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# Controller for the Administrator leaf.
|
2
|
+
|
3
|
+
class Controller < Autumn::Leaf
|
4
|
+
|
5
|
+
# Typing this command reloads all source code for all leaves and support
|
6
|
+
# files, allowing you to make "on-the-fly" changes without restarting the
|
7
|
+
# process. It does this by reloading the source files defining the classes.
|
8
|
+
#
|
9
|
+
# If you supply the configuration name of a leaf, only that leaf is reloaded.
|
10
|
+
#
|
11
|
+
# This command does not reload the YAML configuration files, only the source
|
12
|
+
# code.
|
13
|
+
|
14
|
+
def reload_command(stem, sender, reply_to, msg)
|
15
|
+
var :leaves => Hash.new
|
16
|
+
if msg then
|
17
|
+
if Foliater.instance.leaves.include?(msg) then
|
18
|
+
begin
|
19
|
+
Foliater.instance.hot_reload Foliater.instance.leaves[msg]
|
20
|
+
rescue
|
21
|
+
logger.error "Error when reloading #{msg}:"
|
22
|
+
logger.error $!
|
23
|
+
var(:leaves)[msg] = $!.to_s
|
24
|
+
else
|
25
|
+
var(:leaves)[msg] = false
|
26
|
+
end
|
27
|
+
logger.info "#{msg}: Reloaded"
|
28
|
+
else
|
29
|
+
var :not_found => msg
|
30
|
+
end
|
31
|
+
else
|
32
|
+
Foliater.instance.leaves.each do |name, leaf|
|
33
|
+
begin
|
34
|
+
Foliater.instance.hot_reload leaf
|
35
|
+
rescue
|
36
|
+
logger.error "Error when reloading #{name}:"
|
37
|
+
logger.error $!
|
38
|
+
var(:leaves)[name] = $!.to_s
|
39
|
+
else
|
40
|
+
var(:leaves)[name] = false
|
41
|
+
end
|
42
|
+
logger.info "#{name}: Reloaded"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
ann :reload_command, :protected => true
|
47
|
+
|
48
|
+
# Typing this command will cause the Stem to exit.
|
49
|
+
|
50
|
+
def quit_command(stem, sender, reply_to, msg)
|
51
|
+
stem.quit
|
52
|
+
end
|
53
|
+
ann :quit_command, :protected => true
|
54
|
+
|
55
|
+
# Typing this command will display information about the version of Autumn
|
56
|
+
# that is running this leaf.
|
57
|
+
|
58
|
+
def autumn_command(stem, sender, reply_to, msg)
|
59
|
+
var :version => AUTUMN_VERSION
|
60
|
+
end
|
61
|
+
|
62
|
+
# Suppress the !commands command; don't want to publicize the administrative
|
63
|
+
# features.
|
64
|
+
|
65
|
+
def commands_command(stem, sender, reply_to, msg)
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
Autumn version <%= var :version %>, an IRC bot framework for Ruby (http://github.com/RISCfuture/autumn).
|
@@ -0,0 +1,11 @@
|
|
1
|
+
<% if var(:not_found) %>
|
2
|
+
There is no leaf named <%= var :not_found %>.
|
3
|
+
<% else %>
|
4
|
+
<% var(:leaves).each do |leaf, error| %>
|
5
|
+
<% if error %>
|
6
|
+
<%= leaf %> couldn't be reloaded: <%= error %>
|
7
|
+
<% else %>
|
8
|
+
<%= leaf %> was reloaded successfully.
|
9
|
+
<% end %>
|
10
|
+
<% end %>
|
11
|
+
<% end %>
|
@@ -0,0 +1,17 @@
|
|
1
|
+
= Insulter: An Autumn Leaf
|
2
|
+
|
3
|
+
<b>Version 1.0 (Jul 4, 2008)</b>
|
4
|
+
|
5
|
+
Author:: Tim Morgan (mailto:riscfuture@gmail.com)
|
6
|
+
Copyright:: Copyright (c)2008 Tim Morgan
|
7
|
+
License:: Distributed under the same terms as Ruby. Portions of this content
|
8
|
+
are copyright (c)1996 Main Strike Telecommunications, Inc.
|
9
|
+
|
10
|
+
A simple Autumn Leaf that generates faux-Shakespearean insults. This leaf
|
11
|
+
required no database and no additional gems beyond that of a normal Autumn
|
12
|
+
install.
|
13
|
+
|
14
|
+
== Usage
|
15
|
+
|
16
|
+
!insult [name]:: The bot lets fly a barbarous insult against [name], whose very
|
17
|
+
spirit will thenceforth be crushed into a negligible pulp.
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# Controller and model for the Insulter leaf; maintains the list of insult
|
2
|
+
# substrings and chooses from them randomly.
|
3
|
+
|
4
|
+
class Controller < Autumn::Leaf
|
5
|
+
|
6
|
+
# Insults the unfortunate argument of this command.
|
7
|
+
|
8
|
+
def insult_command(stem, sender, reply_to, msg)
|
9
|
+
if msg.nil? then render :help
|
10
|
+
else insult msg.capitalize end
|
11
|
+
end
|
12
|
+
|
13
|
+
# Displays information about the leaf.
|
14
|
+
|
15
|
+
def about_command(stem, sender, reply_to, msg)
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
ADJECTIVES = [
|
21
|
+
'an artless', 'a bawdy', 'a beslubbering', 'a bootless', 'a churlish',
|
22
|
+
'a clouted', 'a cockered', 'a craven', 'a currish', 'a dankish',
|
23
|
+
'a dissembling', 'a droning', 'an errant', 'a fawning', 'a fobbing',
|
24
|
+
'a frothy', 'a froward', 'a gleeking', 'a goatish', 'a gorbellied',
|
25
|
+
'an impertinent', 'an infectious', 'a jarring', 'a loggerheaded',
|
26
|
+
'a lumpish', 'a mammering', 'a mangled', 'a mewling', 'a paunchy',
|
27
|
+
'a pribbling', 'a puking', 'a puny', 'a qualling', 'a rank', 'a reeky',
|
28
|
+
'a roguish', 'a ruttish', 'a saucy', 'a spleeny', 'a spongy', 'a surly',
|
29
|
+
'a tottering', 'an unmuzzled', 'a vain', 'a venomed', 'a villainous',
|
30
|
+
'a warped', 'a wayward', 'a weedy', 'a yeasty'
|
31
|
+
]
|
32
|
+
|
33
|
+
PARTICIPLES = [
|
34
|
+
'base-court', 'bat-fowling', 'beef-witted', 'beetle-headed', 'boil-brained',
|
35
|
+
'clapper-clawed', 'clay-brained', 'common-kissing', 'crook-pated',
|
36
|
+
'dismal-dreaming', 'dizzy-eyed', 'doghearted', 'dread-bolted',
|
37
|
+
'earth-vexing', 'elf-skinned', 'fat-kidneyed', 'fen-sucked', 'flap-mouthed',
|
38
|
+
'fly-bitten', 'folly-fallen', 'fool-born', 'full-gorged', 'guts-griping',
|
39
|
+
'half-faced', 'hasty-witted', 'hedge-born', 'hell-hated', 'idle-headed',
|
40
|
+
'ill-breeding', 'ill-nurtured', 'knotty-pated', 'milk-livered',
|
41
|
+
'motley-minded', 'onion-eyed', 'plume-plucked', 'pottle-deep', 'pox-marked',
|
42
|
+
'reeling-ripe', 'rough-hewn', 'rude-growing', 'rump-fed', 'shard-borne',
|
43
|
+
'sheep-biting', 'spur-galled', 'swag-bellied', 'tardy-gaited',
|
44
|
+
'tickle-brained', 'toad-spotted', 'urchin-snouted', 'weather-bitten'
|
45
|
+
]
|
46
|
+
|
47
|
+
NOUNS = [
|
48
|
+
'apple-john', 'baggage', 'barnacle', 'bladder', 'boar-pig', 'bugbear',
|
49
|
+
'bum-bailey', 'canker-blossom', 'clack-dish', 'clotpole', 'codpiece',
|
50
|
+
'coxcomb', 'death-token', 'dewberry', 'flap-dragon', 'flax-wench',
|
51
|
+
'flirt-gill', 'foot-licker', 'fustilarian', 'giglet', 'gudgeon', 'haggard',
|
52
|
+
'harpy', 'hedge-pig', 'horn-beast', 'hugger-mugger', 'joithead', 'lewdster',
|
53
|
+
'lout', 'maggot-pie', 'malt-worm', 'mammet', 'measle', 'minnow',
|
54
|
+
'miscreant', 'moldwarp', 'mumble-news', 'nut-hook', 'pigeon-egg', 'pignut',
|
55
|
+
'pumpion', 'puttock', 'ratsbane', 'scut', 'skainsmate', 'strumpet',
|
56
|
+
'varlet', 'vassal', 'wagtail', 'whey-face'
|
57
|
+
]
|
58
|
+
|
59
|
+
def insult(victim)
|
60
|
+
var :adjective => ADJECTIVES.pick
|
61
|
+
var :participle => PARTICIPLES.pick
|
62
|
+
var :noun => NOUNS.pick
|
63
|
+
var :victim => victim
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
Insulter version 1.0 (7-4-08) by Tim Morgan: An Autumn Leaf. Insults copyright (c)1996 Main Strike Telecommunications, Inc.
|
@@ -0,0 +1 @@
|
|
1
|
+
Type "!insult Ted" to crush Ted's spirit with a devastating insult.
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= var :victim %>, thou art <%= var :adjective %> <%= var :participle %> <%= var :noun %>!
|
@@ -0,0 +1,34 @@
|
|
1
|
+
= Scorekeeper: An Autumn Leaf
|
2
|
+
|
3
|
+
<b>Version 3.0 (Jul 4, 2008)</b>
|
4
|
+
|
5
|
+
Author:: Tim Morgan (mailto:riscfuture@gmail.com)
|
6
|
+
Copyright:: Copyright (c)2007-2008 Tim Morgan
|
7
|
+
License:: Distributed under the same terms as Ruby.
|
8
|
+
|
9
|
+
An Autumn Leaf used for an in-channel scorekeeping system. This can operate both
|
10
|
+
as an open or closed score system. (In the former, new members are automatically
|
11
|
+
added when they receive points; in the latter, only authorized members can give
|
12
|
+
and receive points.)
|
13
|
+
|
14
|
+
Scorekeeper is a database-backed leaf. It requires the DataMapper gem
|
15
|
+
(http://www.datamapper.org) in order to run. The database stores channels and
|
16
|
+
their members, and each member's point history.
|
17
|
+
|
18
|
+
Scorekeeper supports pseudonyms. Entries in the +pseudonyms+ table can be used
|
19
|
+
to help ensure that the correct person's points are changed even when the sender
|
20
|
+
uses a nickname or abbreviation.
|
21
|
+
|
22
|
+
Scorekeeper takes one custom configuration option, +scoring+, which can be
|
23
|
+
either "open" or "closed". A closed system only allows a specified set of users
|
24
|
+
to receive and give points. An open system allows anyone to award points to
|
25
|
+
anyone.
|
26
|
+
|
27
|
+
== Usage
|
28
|
+
|
29
|
+
!points [name]:: Get a person's score
|
30
|
+
!points [name] [+|-][number] [reason]:: Change a person's score (you must have a
|
31
|
+
"+" or a "-"). A reason is optional.
|
32
|
+
!points [name] history:: Return some recent history of that person's score.
|
33
|
+
!points [name] history [time period]:: Selects history from a time period.
|
34
|
+
!points [name] history [sender]:: Selects point changes from a sender.
|
@@ -0,0 +1,104 @@
|
|
1
|
+
require 'dm-ar-finders'
|
2
|
+
|
3
|
+
begin
|
4
|
+
gem 'chronic'
|
5
|
+
require 'chronic'
|
6
|
+
rescue Gem::LoadError
|
7
|
+
# Install the "chronic" gem for more robust date parsing
|
8
|
+
end
|
9
|
+
|
10
|
+
# Controller for the Scorekeeper leaf. This class contains only the methods
|
11
|
+
# directly relating to IRC. Other methods are stored in the helper and model
|
12
|
+
# classes.
|
13
|
+
|
14
|
+
class Controller < Autumn::Leaf
|
15
|
+
|
16
|
+
# Displays an about message.
|
17
|
+
|
18
|
+
def about_command(stem, sender, reply_to, msg)
|
19
|
+
end
|
20
|
+
|
21
|
+
# Displays the current point totals, or modifies someone's score, depending on
|
22
|
+
# the message provided with the command.
|
23
|
+
|
24
|
+
def points_command(stem, sender, reply_to, msg)
|
25
|
+
if msg.nil? or msg.empty? then
|
26
|
+
var :totals => totals(stem, reply_to)
|
27
|
+
elsif msg =~ /^(\w+)\s+history\s*(.*)$/ then
|
28
|
+
parse_history stem, reply_to, $1, $2
|
29
|
+
render :history
|
30
|
+
elsif msg =~ /^(\w+)\s+([\+\-]\d+)\s*(.*)$/ then
|
31
|
+
parse_change stem, reply_to, sender, $1, $2.to_i, $3
|
32
|
+
render :change
|
33
|
+
else
|
34
|
+
render :usage
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def points(stem, channel)
|
41
|
+
chan = Channel.find_or_create :server => server_identifier(stem), :name => channel
|
42
|
+
scores = chan.scores.all
|
43
|
+
scores.inject(Hash.new(0)) { |hsh, score| hsh[score.receiver.name] += score.change; hsh }
|
44
|
+
end
|
45
|
+
|
46
|
+
def totals(stem, channel)
|
47
|
+
points(stem, channel).sort { |a,b| b.last <=> a.last }
|
48
|
+
end
|
49
|
+
|
50
|
+
def parse_change(stem, channel, sender, victim, delta, note)
|
51
|
+
giver = find_person(stem, sender[:nick])
|
52
|
+
receiver = find_person(stem, victim)
|
53
|
+
if giver.nil? and options[:scoring] == 'open' then
|
54
|
+
giver ||= Person.create :server => server_identifier(stem), :name => sender[:nick]
|
55
|
+
end
|
56
|
+
if receiver.nil? and options[:scoring] == 'open' then
|
57
|
+
receiver ||= Person.create :server => server_identifier(stem), :name => find_in_channel(stem, channel, victim)
|
58
|
+
end
|
59
|
+
unless authorized?(giver, receiver)
|
60
|
+
var :unauthorized => true
|
61
|
+
var :receiver => receiver.nil? ? victim : receiver.name
|
62
|
+
return
|
63
|
+
end
|
64
|
+
change_points stem, channel, giver, receiver, delta, note
|
65
|
+
var :giver => giver
|
66
|
+
var :receiver => receiver
|
67
|
+
var :delta => delta
|
68
|
+
end
|
69
|
+
|
70
|
+
def parse_history(stem, channel, subject, argument)
|
71
|
+
date = argument.empty? ? nil : parse_date(argument)
|
72
|
+
scores = Array.new
|
73
|
+
|
74
|
+
chan = Channel.first(:name => channel)
|
75
|
+
person = find_person(stem, subject)
|
76
|
+
if person.nil? then
|
77
|
+
var :person => subject
|
78
|
+
var :no_history => true
|
79
|
+
return
|
80
|
+
end
|
81
|
+
|
82
|
+
if date then
|
83
|
+
start, stop = find_range(date)
|
84
|
+
scores = chan.scores.all(:conditions => [ "receiver_id = ? AND created_at >= ? AND created_at < ?", person.id, start, stop ], :order => [ :created_at.desc ], :limit => 5)
|
85
|
+
#TODO is there a way to scope by both channel and receiver?
|
86
|
+
elsif argument.empty? then
|
87
|
+
scores = chan.scores.all(:conditions => [ "receiver_id = ?", person.id ], :order => [ :created_at.desc ], :limit => 5)
|
88
|
+
#TODO is there a way to scope by both channel and receiver?
|
89
|
+
else
|
90
|
+
giver = find_person(stem, argument)
|
91
|
+
if giver.nil? then
|
92
|
+
var :giver => argument
|
93
|
+
var :receiver => person
|
94
|
+
var :no_giver_history => true
|
95
|
+
return
|
96
|
+
end
|
97
|
+
scores = chan.scores.all(:conditions => [ "receiver_id = ? AND giver_id = ?", person.id, giver.id ], :order => [ :created_at.desc ], :limit => 5)
|
98
|
+
#TODO is there a way to scope by channel, receiver, and giver?
|
99
|
+
end
|
100
|
+
var :receiver => person
|
101
|
+
var :giver => giver
|
102
|
+
var :scores => scores
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# Utility methods used by Scorekeeper.
|
2
|
+
|
3
|
+
module GeneralHelper
|
4
|
+
def parse_date(str)
|
5
|
+
date = nil
|
6
|
+
begin
|
7
|
+
date = Chronic.parse(str, :context => :past, :guess => false)
|
8
|
+
rescue NameError
|
9
|
+
begin
|
10
|
+
date = Date.parse(str)
|
11
|
+
rescue ArgumentError
|
12
|
+
end
|
13
|
+
end
|
14
|
+
return date
|
15
|
+
end
|
16
|
+
|
17
|
+
def find_range(date)
|
18
|
+
start = nil
|
19
|
+
stop = nil
|
20
|
+
if date.kind_of? Range then
|
21
|
+
start = date.first
|
22
|
+
stop = date.last
|
23
|
+
elsif date.kind_of? Time then
|
24
|
+
start = date.to_date
|
25
|
+
stop = date.to_date + 1
|
26
|
+
else
|
27
|
+
start = date
|
28
|
+
stop = date + 1
|
29
|
+
end
|
30
|
+
return start, stop
|
31
|
+
end
|
32
|
+
|
33
|
+
def find_person(stem, nick)
|
34
|
+
Person.all(:server => server_identifier(stem)).each do |person|
|
35
|
+
return person if person.name.downcase == normalize(nick) or person.pseudonyms.collect { |pn| pn.name.downcase }.include? normalize(nick)
|
36
|
+
end
|
37
|
+
return nil
|
38
|
+
end
|
39
|
+
|
40
|
+
def find_in_channel(stem, channel, victim)
|
41
|
+
stem.channel_members[channel].each do |name, privilege|
|
42
|
+
return normalize(name, false) if normalize(name) == normalize(victim)
|
43
|
+
end
|
44
|
+
return victim
|
45
|
+
end
|
46
|
+
|
47
|
+
def normalize(nick, dc=true)
|
48
|
+
dc ? nick.downcase.split(/\|/)[0] : nick.split(/\|/)[0]
|
49
|
+
end
|
50
|
+
|
51
|
+
def authorized?(giver, receiver)
|
52
|
+
giver and receiver and giver.authorized? and giver.name != receiver.name
|
53
|
+
end
|
54
|
+
|
55
|
+
def change_points(stem, channel, giver, receiver, delta, note=nil)
|
56
|
+
return if delta.zero?
|
57
|
+
chan = Channel.find_or_create :server => server_identifier(stem), :name => channel
|
58
|
+
chan.scores.create :giver => giver, :receiver => receiver, :change => delta, :note => note
|
59
|
+
end
|
60
|
+
|
61
|
+
def server_identifier(stem)
|
62
|
+
"#{stem.server}:#{stem.port}"
|
63
|
+
end
|
64
|
+
end
|