butler 1.8.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.
- data/CHANGELOG +4 -0
- data/GPL.txt +340 -0
- data/LICENSE.txt +52 -0
- data/README +37 -0
- data/Rakefile +334 -0
- data/bin/botcontrol +230 -0
- data/data/butler/config_template.yaml +4 -0
- data/data/butler/dialogs/backup.rb +19 -0
- data/data/butler/dialogs/botcontrol.rb +4 -0
- data/data/butler/dialogs/config.rb +1 -0
- data/data/butler/dialogs/create.rb +53 -0
- data/data/butler/dialogs/delete.rb +3 -0
- data/data/butler/dialogs/en/backup.yaml +6 -0
- data/data/butler/dialogs/en/botcontrol.yaml +5 -0
- data/data/butler/dialogs/en/create.yaml +11 -0
- data/data/butler/dialogs/en/delete.yaml +2 -0
- data/data/butler/dialogs/en/help.yaml +17 -0
- data/data/butler/dialogs/en/info.yaml +13 -0
- data/data/butler/dialogs/en/list.yaml +4 -0
- data/data/butler/dialogs/en/notyetimplemented.yaml +2 -0
- data/data/butler/dialogs/en/rename.yaml +3 -0
- data/data/butler/dialogs/en/start.yaml +3 -0
- data/data/butler/dialogs/en/sync_plugins.yaml +3 -0
- data/data/butler/dialogs/en/uninstall.yaml +5 -0
- data/data/butler/dialogs/en/unknown_command.yaml +2 -0
- data/data/butler/dialogs/help.rb +11 -0
- data/data/butler/dialogs/info.rb +27 -0
- data/data/butler/dialogs/interactive.rb +1 -0
- data/data/butler/dialogs/list.rb +10 -0
- data/data/butler/dialogs/notyetimplemented.rb +1 -0
- data/data/butler/dialogs/rename.rb +4 -0
- data/data/butler/dialogs/selectbot.rb +2 -0
- data/data/butler/dialogs/start.rb +5 -0
- data/data/butler/dialogs/sync_plugins.rb +30 -0
- data/data/butler/dialogs/uninstall.rb +17 -0
- data/data/butler/dialogs/unknown_command.rb +1 -0
- data/data/butler/plugins/core/logout.rb +41 -0
- data/data/butler/plugins/core/plugins.rb +134 -0
- data/data/butler/plugins/core/privilege.rb +103 -0
- data/data/butler/plugins/core/user.rb +166 -0
- data/data/butler/plugins/dev/eval.rb +64 -0
- data/data/butler/plugins/dev/nometa.rb +14 -0
- data/data/butler/plugins/dev/onhandlers.rb +93 -0
- data/data/butler/plugins/dev/raw.rb +36 -0
- data/data/butler/plugins/dev/rawlog.rb +77 -0
- data/data/butler/plugins/games/eightball.rb +54 -0
- data/data/butler/plugins/games/mastermind.rb +174 -0
- data/data/butler/plugins/irc/action.rb +36 -0
- data/data/butler/plugins/irc/join.rb +38 -0
- data/data/butler/plugins/irc/notice.rb +36 -0
- data/data/butler/plugins/irc/part.rb +38 -0
- data/data/butler/plugins/irc/privmsg.rb +36 -0
- data/data/butler/plugins/irc/quit.rb +36 -0
- data/data/butler/plugins/operator/deop.rb +41 -0
- data/data/butler/plugins/operator/devoice.rb +41 -0
- data/data/butler/plugins/operator/limit.rb +47 -0
- data/data/butler/plugins/operator/op.rb +41 -0
- data/data/butler/plugins/operator/voice.rb +41 -0
- data/data/butler/plugins/public/help.rb +69 -0
- data/data/butler/plugins/public/login.rb +72 -0
- data/data/butler/plugins/public/usage.rb +49 -0
- data/data/butler/plugins/service/clones.rb +56 -0
- data/data/butler/plugins/service/define.rb +47 -0
- data/data/butler/plugins/service/log.rb +183 -0
- data/data/butler/plugins/service/svn.rb +91 -0
- data/data/butler/plugins/util/cycle.rb +98 -0
- data/data/butler/plugins/util/load.rb +41 -0
- data/data/butler/plugins/util/pong.rb +29 -0
- data/data/butler/strings/random/acknowledge.en.yaml +5 -0
- data/data/butler/strings/random/gratitude.en.yaml +3 -0
- data/data/butler/strings/random/hello.en.yaml +4 -0
- data/data/butler/strings/random/ignorance.en.yaml +7 -0
- data/data/butler/strings/random/ignorance_about.en.yaml +3 -0
- data/data/butler/strings/random/insult.en.yaml +3 -0
- data/data/butler/strings/random/rejection.en.yaml +12 -0
- data/data/man/botcontrol.1 +17 -0
- data/lib/access.rb +187 -0
- data/lib/access/admin.rb +16 -0
- data/lib/access/privilege.rb +122 -0
- data/lib/access/role.rb +102 -0
- data/lib/access/savable.rb +18 -0
- data/lib/access/user.rb +180 -0
- data/lib/access/yamlbase.rb +126 -0
- data/lib/butler.rb +188 -0
- data/lib/butler/bot.rb +247 -0
- data/lib/butler/control.rb +93 -0
- data/lib/butler/dialog.rb +64 -0
- data/lib/butler/initialvalues.rb +40 -0
- data/lib/butler/irc/channel.rb +135 -0
- data/lib/butler/irc/channels.rb +96 -0
- data/lib/butler/irc/client.rb +351 -0
- data/lib/butler/irc/hostmask.rb +53 -0
- data/lib/butler/irc/message.rb +184 -0
- data/lib/butler/irc/parser.rb +125 -0
- data/lib/butler/irc/parser/commands.rb +83 -0
- data/lib/butler/irc/parser/generic.rb +343 -0
- data/lib/butler/irc/socket.rb +378 -0
- data/lib/butler/irc/string.rb +186 -0
- data/lib/butler/irc/topic.rb +15 -0
- data/lib/butler/irc/user.rb +265 -0
- data/lib/butler/irc/users.rb +112 -0
- data/lib/butler/plugin.rb +249 -0
- data/lib/butler/plugin/configproxy.rb +35 -0
- data/lib/butler/plugin/mapper.rb +85 -0
- data/lib/butler/plugin/matcher.rb +55 -0
- data/lib/butler/plugin/onhandlers.rb +70 -0
- data/lib/butler/plugin/trigger.rb +58 -0
- data/lib/butler/plugins.rb +147 -0
- data/lib/butler/version.rb +17 -0
- data/lib/cloptions.rb +217 -0
- data/lib/cloptions/adapters.rb +24 -0
- data/lib/cloptions/switch.rb +132 -0
- data/lib/configuration.rb +223 -0
- data/lib/dialogline.rb +296 -0
- data/lib/dialogline/localizations.rb +24 -0
- data/lib/durations.rb +57 -0
- data/lib/event.rb +295 -0
- data/lib/event/at.rb +64 -0
- data/lib/event/every.rb +56 -0
- data/lib/event/timed.rb +112 -0
- data/lib/installer.rb +75 -0
- data/lib/iterator.rb +34 -0
- data/lib/log.rb +68 -0
- data/lib/log/comfort.rb +85 -0
- data/lib/log/converter.rb +23 -0
- data/lib/log/entry.rb +152 -0
- data/lib/log/fakeio.rb +55 -0
- data/lib/log/file.rb +54 -0
- data/lib/log/filereader.rb +81 -0
- data/lib/log/forward.rb +49 -0
- data/lib/log/methods.rb +39 -0
- data/lib/log/nolog.rb +18 -0
- data/lib/log/splitter.rb +26 -0
- data/lib/ostructfixed.rb +26 -0
- data/lib/ruby/array/columnize.rb +38 -0
- data/lib/ruby/dir/mktree.rb +28 -0
- data/lib/ruby/enumerable/join.rb +13 -0
- data/lib/ruby/exception/detailed.rb +24 -0
- data/lib/ruby/file/append.rb +11 -0
- data/lib/ruby/file/write.rb +11 -0
- data/lib/ruby/hash/zip.rb +15 -0
- data/lib/ruby/kernel/bench.rb +15 -0
- data/lib/ruby/kernel/daemonize.rb +42 -0
- data/lib/ruby/kernel/non_verbose.rb +17 -0
- data/lib/ruby/kernel/safe_fork.rb +18 -0
- data/lib/ruby/range/stepped.rb +11 -0
- data/lib/ruby/string/arguments.rb +72 -0
- data/lib/ruby/string/chunks.rb +15 -0
- data/lib/ruby/string/post_arguments.rb +44 -0
- data/lib/ruby/string/unescaped.rb +17 -0
- data/lib/scheduler.rb +164 -0
- data/lib/scriptfile.rb +101 -0
- data/lib/templater.rb +86 -0
- data/test/cloptions.rb +134 -0
- data/test/cv.rb +28 -0
- data/test/irc/client.rb +85 -0
- data/test/irc/client_login.txt +53 -0
- data/test/irc/client_subscribe.txt +8 -0
- data/test/irc/message.rb +30 -0
- data/test/irc/messages.txt +64 -0
- data/test/irc/parser.rb +13 -0
- data/test/irc/profile_parser.rb +12 -0
- data/test/irc/users.rb +28 -0
- metadata +256 -0
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
#--
|
|
2
|
+
# Copyright 2007 by Stefan Rusterholz.
|
|
3
|
+
# All rights reserved.
|
|
4
|
+
# See LICENSE.txt for permissions.
|
|
5
|
+
#++
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
trigger "eval"
|
|
10
|
+
|
|
11
|
+
@state = Array.new(10)
|
|
12
|
+
class <<self
|
|
13
|
+
attr_accessor :state
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def previous(*n)
|
|
17
|
+
n.empty? ? plugin.state : plugin.state[*n]
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def _0; previous(0); end
|
|
21
|
+
def _1; previous(1); end
|
|
22
|
+
def _2; previous(2); end
|
|
23
|
+
def _3; previous(3); end
|
|
24
|
+
def _4; previous(4); end
|
|
25
|
+
def _5; previous(5); end
|
|
26
|
+
def _6; previous(6); end
|
|
27
|
+
def _7; previous(7); end
|
|
28
|
+
def _8; previous(8); end
|
|
29
|
+
def _9; previous(9); end
|
|
30
|
+
|
|
31
|
+
def on_trigger
|
|
32
|
+
begin
|
|
33
|
+
result = eval(@message.post_arguments[1])
|
|
34
|
+
plugin.state.unshift(result)
|
|
35
|
+
plugin.state.pop
|
|
36
|
+
rescue Exception => e
|
|
37
|
+
answer(:exception, :exception => e)
|
|
38
|
+
else
|
|
39
|
+
answer(">> "+result.inspect[0,300].split(/\n/).first(3).join("\n"))
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
__END__
|
|
44
|
+
---
|
|
45
|
+
:revision:
|
|
46
|
+
:plugin: 1
|
|
47
|
+
:summary:
|
|
48
|
+
en: Let butler eval a piece of code.
|
|
49
|
+
:about:
|
|
50
|
+
:mail: "apeiros@gmx.net"
|
|
51
|
+
:version: "1.0.0"
|
|
52
|
+
:author: "Stefan Rusterholz"
|
|
53
|
+
:strings:
|
|
54
|
+
:exception:
|
|
55
|
+
en: |
|
|
56
|
+
Exception <%= exception.class %> '<%= exception.message %>' in:
|
|
57
|
+
<%= exception.backtrace.first(3).join("\n") %>
|
|
58
|
+
:usage:
|
|
59
|
+
en: |
|
|
60
|
+
![b]eval![o] *![c(blue)]code![o]
|
|
61
|
+
:help:
|
|
62
|
+
en:
|
|
63
|
+
"": |
|
|
64
|
+
Let butler eval a piece of code.
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
#--
|
|
2
|
+
# Copyright 2007 by Stefan Rusterholz.
|
|
3
|
+
# All rights reserved.
|
|
4
|
+
# See LICENSE.txt for permissions.
|
|
5
|
+
#++
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
extend OnHandlers
|
|
10
|
+
|
|
11
|
+
configuration(
|
|
12
|
+
"active" => false
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
trigger "onhandlers"
|
|
16
|
+
|
|
17
|
+
def on_trigger
|
|
18
|
+
if @message.arguments[1] && @message.arguments[1].downcase == "on" then
|
|
19
|
+
plugin.config["active"] = true
|
|
20
|
+
else
|
|
21
|
+
plugin.config["active"] = false
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def on_join(listener, user, channel)
|
|
26
|
+
debug("on_join triggered, #{user} joined #{channel}") if plugin.config["active"]
|
|
27
|
+
end
|
|
28
|
+
def on_privmsg(listener, user, text)
|
|
29
|
+
debug("on_privmsg triggered, #{user} wrote #{text}") if plugin.config["active"]
|
|
30
|
+
end
|
|
31
|
+
def on_notice(listener, user, text)
|
|
32
|
+
debug("on_notice triggered, #{user} wrote #{text}") if plugin.config["active"]
|
|
33
|
+
end
|
|
34
|
+
def on_nick(listener, user, old_nick)
|
|
35
|
+
debug("on_nick triggered, #{user} changed his nick from #{old_nick}") if plugin.config["active"]
|
|
36
|
+
end
|
|
37
|
+
def on_topic(listener, user, channel, topic)
|
|
38
|
+
debug("on_topic triggered, #{user} changed topic of #{channel} to #{topic}") if plugin.config["active"]
|
|
39
|
+
end
|
|
40
|
+
def on_part(listener, user, channel)
|
|
41
|
+
debug("on_part triggered, #{user} parted #{channel}") if plugin.config["active"]
|
|
42
|
+
end
|
|
43
|
+
def on_quit(listener, user, reason)
|
|
44
|
+
debug("on_quit triggered, #{user} has quit with #{reason}") if plugin.config["active"]
|
|
45
|
+
end
|
|
46
|
+
def on_kick(listener)
|
|
47
|
+
debug("on_kick triggered with #{@message}") if plugin.config["active"]
|
|
48
|
+
end
|
|
49
|
+
def on_kill(listener)
|
|
50
|
+
debug("on_kill triggered with #{@message}") if plugin.config["active"]
|
|
51
|
+
end
|
|
52
|
+
def on_kline(listener)
|
|
53
|
+
debug("on_kline triggered with #{@message}") if plugin.config["active"]
|
|
54
|
+
end
|
|
55
|
+
def on_invocation(listener)
|
|
56
|
+
debug("on_invocation triggered with #{@message}") if plugin.config["active"]
|
|
57
|
+
end
|
|
58
|
+
def on_ban(listener, *masks)
|
|
59
|
+
debug("on_ban triggered with #{@message}") if plugin.config["active"]
|
|
60
|
+
end
|
|
61
|
+
def on_unban(listener, *masks)
|
|
62
|
+
debug("on_unban triggered with #{@message}") if plugin.config["active"]
|
|
63
|
+
end
|
|
64
|
+
def on_op(listener, *users)
|
|
65
|
+
debug("on_op triggered with #{@message}") if plugin.config["active"]
|
|
66
|
+
end
|
|
67
|
+
def on_deop(listener, *users)
|
|
68
|
+
debug("on_deop triggered with #{@message}") if plugin.config["active"]
|
|
69
|
+
end
|
|
70
|
+
def on_voice(listener, *users)
|
|
71
|
+
debug("on_voice triggered with #{@message}") if plugin.config["active"]
|
|
72
|
+
end
|
|
73
|
+
def on_devoice(listener, *users)
|
|
74
|
+
debug("on_devoice triggered with #{@message}") if plugin.config["active"]
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
__END__
|
|
78
|
+
---
|
|
79
|
+
:revision:
|
|
80
|
+
:plugin: 1
|
|
81
|
+
:summary:
|
|
82
|
+
en: Testing all possible on_handlers
|
|
83
|
+
:about:
|
|
84
|
+
:mail: "apeiros@gmx.net"
|
|
85
|
+
:version: "1.0.0"
|
|
86
|
+
:author: "Stefan Rusterholz"
|
|
87
|
+
:strings:
|
|
88
|
+
:usage:
|
|
89
|
+
en: "This plugin does not offer a specific interface."
|
|
90
|
+
:help:
|
|
91
|
+
en:
|
|
92
|
+
"": |
|
|
93
|
+
This plugin is meant for diagnostic purposes only.
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
#--
|
|
2
|
+
# Copyright 2007 by Stefan Rusterholz.
|
|
3
|
+
# All rights reserved.
|
|
4
|
+
# See LICENSE.txt for permissions.
|
|
5
|
+
#++
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
trigger "raw"
|
|
10
|
+
|
|
11
|
+
def on_trigger
|
|
12
|
+
return answer(usage) if @message.arguments.length < 2
|
|
13
|
+
@butler.irc.write(@message.post_arguments[1])
|
|
14
|
+
answer(:sent)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
__END__
|
|
18
|
+
---
|
|
19
|
+
:revision:
|
|
20
|
+
:plugin: 1
|
|
21
|
+
:summary:
|
|
22
|
+
en: Let butler send a raw message to the server.
|
|
23
|
+
:about:
|
|
24
|
+
:mail: "apeiros@gmx.net"
|
|
25
|
+
:version: "1.0.0"
|
|
26
|
+
:author: "Stefan Rusterholz"
|
|
27
|
+
:strings:
|
|
28
|
+
:sent:
|
|
29
|
+
en: Sent the raw message
|
|
30
|
+
:usage:
|
|
31
|
+
en: |
|
|
32
|
+
![b]raw![o] *![c(blue)]raw-message![o])
|
|
33
|
+
:help:
|
|
34
|
+
en:
|
|
35
|
+
"": |
|
|
36
|
+
Let butler send a raw message to the server.
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
#--
|
|
2
|
+
# Copyright 2007 by Stefan Rusterholz.
|
|
3
|
+
# All rights reserved.
|
|
4
|
+
# See LICENSE.txt for permissions.
|
|
5
|
+
#++
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
configuration(
|
|
10
|
+
"active" => true
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
@logfile = nil
|
|
14
|
+
|
|
15
|
+
def self.on_load(*a)
|
|
16
|
+
@logfile = File.open(@butler.path.log+"/rawlog.txt", "a")
|
|
17
|
+
@logfile.sync = true
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def self.on_unload(*a)
|
|
21
|
+
@logfile.close
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
subscribe(nil, 10) { |listener, message|
|
|
25
|
+
if @config["active"] && @logfile then
|
|
26
|
+
@logfile.puts("#{Time.now.strftime('%F %T')}> #{message.raw}")
|
|
27
|
+
end
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
trigger "rawlog"
|
|
31
|
+
|
|
32
|
+
def on_trigger
|
|
33
|
+
arg = @message.arguments[1] && @message.arguments[1].downcase
|
|
34
|
+
case arg
|
|
35
|
+
when nil
|
|
36
|
+
usage
|
|
37
|
+
|
|
38
|
+
when _(:on)
|
|
39
|
+
plugin.config["active"] = true
|
|
40
|
+
answer(:activated)
|
|
41
|
+
|
|
42
|
+
when _(:off)
|
|
43
|
+
plugin.config["active"] = false
|
|
44
|
+
answer(:deactivated)
|
|
45
|
+
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
__END__
|
|
50
|
+
---
|
|
51
|
+
:revision:
|
|
52
|
+
:configuration: 1
|
|
53
|
+
:summary:
|
|
54
|
+
en: |
|
|
55
|
+
Writes all messages butler receives into a raw log.
|
|
56
|
+
:about:
|
|
57
|
+
:mail: "apeiros@gmx.net"
|
|
58
|
+
:version: "1.0.0"
|
|
59
|
+
:author: "Stefan Rusterholz"
|
|
60
|
+
:strings:
|
|
61
|
+
:on:
|
|
62
|
+
en: "on"
|
|
63
|
+
:off:
|
|
64
|
+
en: "off"
|
|
65
|
+
:activated:
|
|
66
|
+
en: |
|
|
67
|
+
Activated raw logging
|
|
68
|
+
:deactivated:
|
|
69
|
+
en: |
|
|
70
|
+
Deactivated raw logging
|
|
71
|
+
:usage:
|
|
72
|
+
en: |
|
|
73
|
+
![b]rawlog![o] ('on' | 'off')
|
|
74
|
+
:help:
|
|
75
|
+
en:
|
|
76
|
+
"": |
|
|
77
|
+
Writes all messages butler receives into a raw log.
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
#--
|
|
2
|
+
# Copyright 2007 by Stefan Rusterholz.
|
|
3
|
+
# All rights reserved.
|
|
4
|
+
# See LICENSE.txt for permissions.
|
|
5
|
+
#++
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
trigger "8ball"
|
|
10
|
+
|
|
11
|
+
Answers = [:yes, :no, :notgood, :signs_yes, :signs_no, :why_ask, :unclear]
|
|
12
|
+
|
|
13
|
+
def on_trigger
|
|
14
|
+
return answer(usage) if @message.arguments.length < 2
|
|
15
|
+
answer = Answers[rand(Answers.length)]
|
|
16
|
+
@butler.irc.action(_(:shake), message.channel ? message.channel : message.from)
|
|
17
|
+
sleep(1.5)
|
|
18
|
+
answer(answer)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
__END__
|
|
22
|
+
---
|
|
23
|
+
:revision:
|
|
24
|
+
:plugin: 1
|
|
25
|
+
:summary:
|
|
26
|
+
en: Ask butler a question and get an answer from the magic eightball.
|
|
27
|
+
:about:
|
|
28
|
+
:mail: "apeiros@gmx.net"
|
|
29
|
+
:version: "1.0.0"
|
|
30
|
+
:author: "Stefan Rusterholz"
|
|
31
|
+
:strings:
|
|
32
|
+
:shake:
|
|
33
|
+
en: 'Shakes the magic 8-ball...'
|
|
34
|
+
:yes:
|
|
35
|
+
en: 'Yes.'
|
|
36
|
+
:no:
|
|
37
|
+
en: 'no.'
|
|
38
|
+
:notgood:
|
|
39
|
+
en: 'Outlook is not so good.'
|
|
40
|
+
:signs_yes:
|
|
41
|
+
en: 'All signs point to yes.'
|
|
42
|
+
:signs no:
|
|
43
|
+
en: 'All signs point to no.'
|
|
44
|
+
:why_ask:
|
|
45
|
+
en: 'Why the hell are you asking me?'
|
|
46
|
+
:unclear:
|
|
47
|
+
en: 'The answer is unclear.'
|
|
48
|
+
:usage:
|
|
49
|
+
en: |
|
|
50
|
+
![b]8ball![o] *![c(blue)]question![o]
|
|
51
|
+
:help:
|
|
52
|
+
en:
|
|
53
|
+
"": |
|
|
54
|
+
Ask butler a question and get an answer from the magic eightball.
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
#--
|
|
2
|
+
# Copyright 2007 by Stefan Rusterholz.
|
|
3
|
+
# All rights reserved.
|
|
4
|
+
# See LICENSE.txt for permissions.
|
|
5
|
+
#++
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
require 'abbrev'
|
|
10
|
+
|
|
11
|
+
Stone = "![c(%s),(%s)]<>![r]"
|
|
12
|
+
None = "![c(red),(red)]<>![r]"
|
|
13
|
+
Wrong = "![c(blue),(blue)]<>![r]"
|
|
14
|
+
Correct = "![c(green),(green)]<>![r]"
|
|
15
|
+
|
|
16
|
+
trigger(
|
|
17
|
+
"en" => "mastermind",
|
|
18
|
+
"de" => "mastermind"
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
def on_trigger
|
|
22
|
+
case message.arguments.first.downcase
|
|
23
|
+
when _(:colors)
|
|
24
|
+
message.answer(_(:colors))
|
|
25
|
+
when _(:rules)
|
|
26
|
+
message.answer(_(:rules))
|
|
27
|
+
when _(:stop)
|
|
28
|
+
game = MasterGame[message.from]
|
|
29
|
+
game.stop if game
|
|
30
|
+
when _(:start)
|
|
31
|
+
game = MasterGame.new
|
|
32
|
+
message.dialog(self, game) # timeout after 10min
|
|
33
|
+
else
|
|
34
|
+
message.answer(_(:illegal))
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
class MasterGame < Butler::Dialog
|
|
39
|
+
reminder 10.minutes, :reminder
|
|
40
|
+
timeout 15.minutes, :timeout
|
|
41
|
+
|
|
42
|
+
def initialize(stones=5, difficulty=:easy)
|
|
43
|
+
@game = Mastermind.new(stones, difficulty)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def dialog(responder, message, *data)
|
|
47
|
+
case message.arguments[1]
|
|
48
|
+
when _(:colors)
|
|
49
|
+
message.answer(_(:colors))
|
|
50
|
+
when _(:rules)
|
|
51
|
+
message.answer(_(:rules))
|
|
52
|
+
when _(:stop)
|
|
53
|
+
game = MasterGame[message.from]
|
|
54
|
+
game.stop if game
|
|
55
|
+
when _(:start)
|
|
56
|
+
game = MasterGame.new
|
|
57
|
+
message.dialog(game) # timeout after 10min
|
|
58
|
+
else
|
|
59
|
+
if stones = map_stones(*message.arguments) then
|
|
60
|
+
@game.try_stones(*stones)
|
|
61
|
+
else
|
|
62
|
+
message.answer(_(:illegal))
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def reminder(user)
|
|
68
|
+
_(:reminder)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def timout(*a)
|
|
72
|
+
_(:timeout)
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
class Mastermind
|
|
77
|
+
attr_reader :stones
|
|
78
|
+
attr_reader :amount
|
|
79
|
+
attr_reader :turns
|
|
80
|
+
attr_reader :mode
|
|
81
|
+
|
|
82
|
+
Colors = [:red, :green, :blue, :yellow, :orange, :pink, :black]
|
|
83
|
+
|
|
84
|
+
def initialize(amount, mode=:easy)
|
|
85
|
+
@stones = Array.new(amount) { Colors[rand(Colors.length)] }
|
|
86
|
+
@amount = amount
|
|
87
|
+
@mode = mode
|
|
88
|
+
@turns = 0
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def try_stones(*stones)
|
|
92
|
+
@turns += 1
|
|
93
|
+
return true if stones == @stones
|
|
94
|
+
|
|
95
|
+
if @mode == :difficult then
|
|
96
|
+
correct, wrong, none = 0, 0, 0
|
|
97
|
+
@stones.zip(stones) { |a, b|
|
|
98
|
+
if a == b then
|
|
99
|
+
correct += 1
|
|
100
|
+
elsif @stones.include?(b) then
|
|
101
|
+
wrong += 1
|
|
102
|
+
else
|
|
103
|
+
none += 1
|
|
104
|
+
end
|
|
105
|
+
}
|
|
106
|
+
[:correct]*correct + [:wrong]*wrong + [:none]*none
|
|
107
|
+
else
|
|
108
|
+
feedback = []
|
|
109
|
+
@stones.zip(stones) { |a, b|
|
|
110
|
+
if a == b then
|
|
111
|
+
feedback << :correct
|
|
112
|
+
elsif @stones.include?(b) then
|
|
113
|
+
feedback << :wrong
|
|
114
|
+
else
|
|
115
|
+
feedback << :none
|
|
116
|
+
end
|
|
117
|
+
}
|
|
118
|
+
feedback
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
__END__
|
|
124
|
+
---
|
|
125
|
+
:revision:
|
|
126
|
+
:plugin: 1
|
|
127
|
+
:about:
|
|
128
|
+
:mail: "apeiros@gmx.net"
|
|
129
|
+
:version: "1.2.0"
|
|
130
|
+
:author: "Stefan Rusterholz"
|
|
131
|
+
:description:
|
|
132
|
+
en: "Mastermind - the game for brainsters"
|
|
133
|
+
:strings:
|
|
134
|
+
:red:
|
|
135
|
+
en: red
|
|
136
|
+
de: rot
|
|
137
|
+
:green:
|
|
138
|
+
en: green
|
|
139
|
+
de: grün
|
|
140
|
+
:blue:
|
|
141
|
+
en: blue
|
|
142
|
+
de: blau
|
|
143
|
+
:yellow:
|
|
144
|
+
en: yellow
|
|
145
|
+
de: gelb
|
|
146
|
+
:orange:
|
|
147
|
+
en: orange
|
|
148
|
+
de: orange
|
|
149
|
+
:pink:
|
|
150
|
+
en: pink
|
|
151
|
+
de: pink
|
|
152
|
+
:black:
|
|
153
|
+
en: black
|
|
154
|
+
de: black
|
|
155
|
+
:rules:
|
|
156
|
+
en: |
|
|
157
|
+
The rules are simple: try to guess the color combination of the stones.
|
|
158
|
+
If you place a stone correct in color and location, it will display a white stone in that position.
|
|
159
|
+
If you place a stone whichs color appears on another location, it will display a black stone in that position.
|
|
160
|
+
The target is it, to get the combination in as little tries as possible.
|
|
161
|
+
:illegal:
|
|
162
|
+
de: |
|
|
163
|
+
Unbekannter Befehl. Benutzen Sie:
|
|
164
|
+
mm (regeln|farben|start|stop|<steine>)
|
|
165
|
+
Steine: ... (jede eindeutige Abkürzung funktioniert).
|
|
166
|
+
:reminder:
|
|
167
|
+
en: |
|
|
168
|
+
Sie haben noch ein laufendes Mastermind-Spiel.
|
|
169
|
+
Benutzen Sie 'mm stop' um das Spiel zu beenden.
|
|
170
|
+
de: |
|
|
171
|
+
Sie haben noch ein laufendes Mastermind-Spiel.
|
|
172
|
+
Benutzen Sie 'mm stop' um das Spiel zu beenden.
|
|
173
|
+
:stop:
|
|
174
|
+
de: "Spiel gestoppt, die richtige Lösung wäre gewesen: <%= stones %>"
|