muby 0.6.6

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.
Files changed (38) hide show
  1. data/LICENSE +339 -0
  2. data/bin/muby +37 -0
  3. data/contrib/aardmud.org_4000/README.txt +39 -0
  4. data/contrib/aardmud.org_4000/aard-config.rb +234 -0
  5. data/contrib/aardmud.org_4000/aard-helpers.rb +464 -0
  6. data/contrib/aardmud.org_4000/aliases/aard-aliases.rb +205 -0
  7. data/contrib/aardmud.org_4000/gags/aard-gags.rb +182 -0
  8. data/contrib/aardmud.org_4000/misc/aard-affects.rb +252 -0
  9. data/contrib/aardmud.org_4000/misc/aard-know.rb +147 -0
  10. data/contrib/aardmud.org_4000/misc/aard-poznai_sebia.rb +191 -0
  11. data/contrib/aardmud.org_4000/misc/aard-prompts.rb +65 -0
  12. data/contrib/aardmud.org_4000/misc/aard-status_toggling.rb +156 -0
  13. data/contrib/aardmud.org_4000/misc/aard_consider_substitutions.rb +319 -0
  14. data/contrib/aardmud.org_4000/speedwalks/aard-sw-areas-hero.rb +86 -0
  15. data/contrib/aardmud.org_4000/speedwalks/aard-sw-areas-newbie.rb +98 -0
  16. data/contrib/aardmud.org_4000/speedwalks/aard-sw-areas-noble.rb +170 -0
  17. data/contrib/aardmud.org_4000/speedwalks/aard-sw-areas-vidblain.rb +88 -0
  18. data/contrib/aardmud.org_4000/speedwalks/aard-sw-areas.rb +850 -0
  19. data/contrib/aardmud.org_4000/speedwalks/aard-sw-clans.rb +43 -0
  20. data/contrib/aardmud.org_4000/speedwalks/aard-sw-guilds.rb +13 -0
  21. data/contrib/aardmud.org_4000/speedwalks/aard-sw.rb +45 -0
  22. data/contrib/aardmud.org_4000/triggers/aard-triggers-items.rb +254 -0
  23. data/contrib/aardmud.org_4000/triggers/aard-triggers.rb +227 -0
  24. data/contrib/sy/cce.rb +120 -0
  25. data/lib/muby.rb +15 -0
  26. data/lib/muby/application.rb +66 -0
  27. data/lib/muby/completer.rb +62 -0
  28. data/lib/muby/configuration.rb +379 -0
  29. data/lib/muby/connection.rb +332 -0
  30. data/lib/muby/displayer.rb +60 -0
  31. data/lib/muby/help.rb +88 -0
  32. data/lib/muby/helper_methods.rb +46 -0
  33. data/lib/muby/inputwindow.rb +173 -0
  34. data/lib/muby/logger.rb +28 -0
  35. data/lib/muby/outputwindow.rb +189 -0
  36. data/lib/muby/style.rb +142 -0
  37. data/lib/muby/user_methods.rb +463 -0
  38. metadata +90 -0
@@ -0,0 +1,46 @@
1
+
2
+ module Muby
3
+
4
+ module HelperMethods
5
+
6
+ def execute(command, *args)
7
+ execute_with_verbosity(:debug, command, *args)
8
+ end
9
+
10
+ def execute_with_verbosity(verbosity, command, *args)
11
+ begin
12
+ result = nil
13
+ if Proc === command
14
+ result = command.call(*args[0...(command.arity)])
15
+ elsif String === command
16
+ result = eval(command)
17
+ elsif Symbol === command
18
+ method = self.method(command)
19
+ args = args[0...(method.arity)]
20
+ result = method.call(*args)
21
+ elsif Array === command
22
+ method = self.method(command.first)
23
+ args = (command[1..-1] + args)[0...(method.arity)]
24
+ result = method.call(*args)
25
+ else
26
+ result = command
27
+ end
28
+ unless result.nil?
29
+ case result
30
+ when String
31
+ Muby::OutputWindow.get_instance.show(verbosity, result)
32
+ else
33
+ Muby::OutputWindow.get_instance.show(verbosity, result.inspect)
34
+ end
35
+ end
36
+ result
37
+ rescue SystemExit => ex
38
+ quit
39
+ rescue Exception => e
40
+ exception(e)
41
+ end
42
+ end
43
+
44
+ end
45
+
46
+ end
@@ -0,0 +1,173 @@
1
+
2
+ require 'pathname'
3
+
4
+ #
5
+ # The fancy window that gets our input.
6
+ #
7
+ # The class handles everything to do with
8
+ # the input window itself, the user callable
9
+ # methods are in the UserMethods module.
10
+ #
11
+ # All commands entered with conf.escape_character will be eval'd in
12
+ # this class scope.
13
+ #
14
+ class Muby::InputWindow
15
+
16
+ include Muby::Logger
17
+ include Muby::Configurable
18
+ include Muby::Displayer
19
+ include Muby::UserMethods
20
+ include Muby::Styled
21
+ include Muby::HelperMethods
22
+
23
+ @@instance = nil
24
+
25
+ def self.get_instance
26
+ @@instance ||= Muby::InputWindow.new
27
+ end
28
+
29
+ attr_reader :history
30
+
31
+ #
32
+ # Start working!
33
+ #
34
+ def go
35
+ # Init all the default values
36
+ @buffer = ""
37
+ @cursorPosition = 0
38
+ @history = []
39
+ @historyPointer = nil
40
+ @connection = nil
41
+ @statusLine = ""
42
+ @messageLine = ""
43
+ @recent_escape = []
44
+ @handle_mode = :append_buffer!
45
+
46
+ # Init the input box
47
+ @inputBorder = Ncurses.newwin(height, width, top, left)
48
+ @inputBorder.box(0,0)
49
+ @inputBorder.keypad(true)
50
+ @inputBorder.refresh
51
+
52
+ # Init the window itself
53
+ @inputWindow = Ncurses.newwin(height - 2, width - 2, top + 1, left + 1)
54
+ @inputWindow.keypad(true)
55
+ @inputWindow.scrollok(true)
56
+ @inputWindow.nodelay(true)
57
+ @inputWindow.refresh
58
+
59
+ help unless conf.user_edited_config_file
60
+ end
61
+
62
+ def left
63
+ execute_with_verbosity(:trace, conf.input_window_geometry[:left])
64
+ end
65
+
66
+ def top
67
+ execute_with_verbosity(:trace, conf.input_window_geometry[:top])
68
+ end
69
+
70
+ def width
71
+ execute_with_verbosity(:trace, conf.input_window_geometry[:width])
72
+ end
73
+
74
+ def height
75
+ execute_with_verbosity(:trace, conf.input_window_geometry[:height])
76
+ end
77
+
78
+ #
79
+ # Update the input box, redrawing borders and text etc.
80
+ #
81
+ def update
82
+ @inputBorder.box(0,0)
83
+ @inputBorder.mvwprintw(0,1,"%s", @statusLine)
84
+ @inputBorder.mvwprintw(height - 1, 1, "%s", @messageLine)
85
+ @inputBorder.refresh
86
+
87
+ @inputWindow.werase
88
+ row = 0
89
+ col = @cursorPosition
90
+ while col > width - 2
91
+ row = row + 1
92
+ col = col - width - 2
93
+ end
94
+ @inputWindow.mvwprintw(row,col,"%s", @buffer[@cursorPosition,@buffer.size - @cursorPosition])
95
+ @inputWindow.mvwprintw(0,0,"%s", @buffer[0, @cursorPosition])
96
+ @inputWindow.refresh
97
+ end
98
+
99
+ #
100
+ # Save our history into the history file.
101
+ #
102
+ def saveHistory
103
+ # This should be wrapped in something else, which checks for sanity (writability)
104
+ dir = Pathname.new(conf.history_file).parent
105
+ dir.mkpath unless dir.exist?
106
+ file = Pathname.new(conf.history_file)
107
+ file.open("w") do |output|
108
+ Marshal.dump(@history, output)
109
+ end
110
+ end
111
+
112
+ #
113
+ # Load our history from the history file.
114
+ #
115
+ def loadHistory
116
+ begin
117
+ if FileTest.readable?(conf.history_file)
118
+ info("Reading history file")
119
+ Kernel::open(conf.history_file) do |input|
120
+ @history = Marshal.load(input.read)
121
+ end
122
+ @history.each do |line|
123
+ Muby::Completer.get_instance.store(line)
124
+ end if conf.feed_completer_with_history
125
+ end
126
+ rescue Exception => e
127
+ exception(e)
128
+ end
129
+ @history ||= []
130
+ end
131
+
132
+ def handle(c, hash)
133
+ # Echo the keycode we got if we have conf.echo_keycodes == true (good for setting up conf.key_commands)
134
+ if conf.echo_keycodes && c != Ncurses.const_get("ERR")
135
+ info(c.to_s)
136
+ end
137
+ if hash.include?(c)
138
+ value = hash[c]
139
+ if Hash === value
140
+ c = @inputWindow.wgetch
141
+ if value.include?(c)
142
+ handle(c, value)
143
+ else
144
+ handle(c, conf.key_commands)
145
+ end
146
+ else
147
+ execute(value, self, Muby::OutputWindow.get_instance, c)
148
+ end
149
+ elsif 0 < c && c < 265
150
+ method = self.method(@handle_mode)
151
+ method.call(c)
152
+ end
153
+ end
154
+
155
+ #
156
+ # Just keep listening to the keyboard input.
157
+ #
158
+ def process
159
+ loadHistory
160
+ conf.startup_triggers.each do |trigger|
161
+ execute(trigger, self, Muby::OutputWindow.get_instance)
162
+ end
163
+ # We need to check one key at a time due to triggers and conf.key_commands
164
+ while c = @inputWindow.wgetch
165
+ if c == Ncurses.const_get("ERR")
166
+ sleep(0.01)
167
+ else
168
+ handle(c, conf.key_commands)
169
+ end
170
+ end # while c = @inputWindow.wgetch
171
+ end # def process
172
+
173
+ end # class InputWindow
@@ -0,0 +1,28 @@
1
+ #
2
+ # A simple logger that logs to whatever logfiles you have defined
3
+ # in your preferences.
4
+ #
5
+ module Muby::Logger
6
+
7
+ include Muby::Configurable
8
+
9
+ #
10
+ # Logs everything that gets read from the remote connection.
11
+ #
12
+ def log_input(c)
13
+ if conf.input_logfile
14
+ conf.input_logfile.write(c)
15
+ conf.input_logfile.flush
16
+ end
17
+ end
18
+
19
+ #
20
+ # Logs everything that gets sent to the remote connection.
21
+ #
22
+ def log_output(c)
23
+ if conf.output_logfile
24
+ conf.output_logfile.write(c)
25
+ conf.output_logfile.flush
26
+ end
27
+ end
28
+ end # module Logger
@@ -0,0 +1,189 @@
1
+ #
2
+ # The class that controls what we see.
3
+ #
4
+ class Muby::OutputWindow
5
+
6
+ include Muby::Logger
7
+ include Muby::Configurable
8
+ include Muby::HelperMethods
9
+ include Muby::Displayer
10
+
11
+ attr_reader :scrollback, :size, :outputBuffer
12
+
13
+ @@instance = nil
14
+
15
+ def self.get_instance
16
+ @@instance ||= Muby::OutputWindow.new
17
+ end
18
+
19
+ def initialize
20
+ @ready = false
21
+ end
22
+
23
+ def ready?
24
+ @ready
25
+ end
26
+
27
+ #
28
+ # Start working!
29
+ #
30
+ def go
31
+ @scrollback = 0
32
+ @waitBuffer = []
33
+ @lines = 0
34
+
35
+ @outputBuffer = Ncurses.newpad(conf.output_buffer, width)
36
+ @outputBuffer.wclear
37
+ @outputBuffer.scrollok(true)
38
+ @outputBuffer.idlok(true)
39
+ defaultAttributes = Muby::Style.new(conf.default_attributes, conf.default_colors[0], conf.default_colors[1])
40
+ defaultAttributes.affect(@outputBuffer)
41
+ # Prepare the output window:
42
+ @outputBuffer.mvprintw(conf.output_buffer - 1, 0, "\n")
43
+
44
+ show_version
45
+ refresh
46
+
47
+ @ready = true
48
+ end
49
+
50
+ def reload!
51
+ @left = nil
52
+ @top = nil
53
+ @width = nil
54
+ @height = nil
55
+ end
56
+
57
+ def left
58
+ @left ||= execute_with_verbosity(:trace, conf.output_window_geometry[:left])
59
+ end
60
+
61
+ def top
62
+ @top ||= execute_with_verbosity(:trace, conf.output_window_geometry[:top])
63
+ end
64
+
65
+ def width
66
+ @width ||= execute_with_verbosity(:trace, conf.output_window_geometry[:width])
67
+ end
68
+
69
+ def height
70
+ @height ||= execute_with_verbosity(:trace, conf.output_window_geometry[:height])
71
+ end
72
+
73
+ def show_version
74
+ print("
75
+ .--.--.--. .--.
76
+ : :--.--: : .--.--.
77
+ : : : : : : '-: : :
78
+ : : : : : : : : ' :
79
+ '--'--'--'-----'----'--. :
80
+ The Ruby MUD Client : :
81
+ ------------------- '--'
82
+ Version #{Muby::VERSION}
83
+ ")
84
+ end
85
+
86
+ #
87
+ # Refresh the output buffer (if we have scrolled etc)
88
+ #
89
+ def refresh
90
+ @outputBuffer.prefresh(conf.output_buffer - (height * (@scrollback + 1)), 0, top, left, height - 1, width)
91
+ end
92
+
93
+ #
94
+ # Scroll up, and give the user a message about it.
95
+ #
96
+ def scroll_up(inputWindow)
97
+ if @scrollback * height < conf.output_buffer &&
98
+ @scrollback * height < @lines
99
+ @scrollback += 1
100
+ # BUG: set_message_line is in userMethods.
101
+ # No, its not a bug.
102
+ inputWindow.set_message_line("SCROLLED - I/O PAUSED")
103
+ refresh
104
+ end
105
+ end
106
+
107
+ #
108
+ # Scroll down again.
109
+ #
110
+ def scroll_down(inputWindow)
111
+ if @scrollback > 0
112
+ @scrollback -= 1
113
+ if @scrollback == 0
114
+ # BUG:
115
+ # No
116
+ inputWindow.set_message_line("")
117
+ unless @waitBuffer.empty?
118
+ print(*@waitBuffer)
119
+ @waitBuffer = []
120
+ end
121
+ end
122
+ end
123
+ refresh
124
+ end
125
+
126
+ def timestamp(message)
127
+ if conf.timestamp && @recent_linebreak
128
+ Time.new.strftime(conf.timeformat) + "\t" + message
129
+ else
130
+ message
131
+ end
132
+ end
133
+
134
+ def show(level, message)
135
+ if conf.display?(level)
136
+ to_print = [message, "\n"]
137
+ if level_attributes = conf.send("#{level}_attributes")
138
+ level_colors = conf.send("#{level}_colors")
139
+ style = Muby::Style.new(level_attributes, level_colors[0], level_colors[1])
140
+ oldStyle = Muby::Style.extract(@outputBuffer)
141
+ to_print = [style] + to_print + [oldStyle]
142
+ end
143
+
144
+ print_on_newline(*to_print)
145
+ end
146
+ end
147
+
148
+ def print_on_newline(*info)
149
+ if @recent_linebreak
150
+ print(*info)
151
+ else
152
+ print(*(["\n"] + info))
153
+ end
154
+ end
155
+
156
+ #
157
+ # Print an info Array to the outputBuffer.
158
+ #
159
+ # Will print text as is, and add any Styles encountered to the outputBuffer.
160
+ #
161
+ def print(*info)
162
+ if @scrollback == 0
163
+ info.each do |e|
164
+ if String === e
165
+ rest = e
166
+ while (match = rest.match(/^([^\r\n]*)([\r\n]*)(.*)$/m))
167
+ to_print = match[1]
168
+ linebreak = match[2]
169
+ rest = match[3]
170
+
171
+ break if to_print.empty? and linebreak.empty?
172
+
173
+ @outputBuffer.printw("%s", timestamp(to_print) + linebreak)
174
+
175
+ @recent_linebreak = !linebreak.empty?
176
+ @lines += 1 unless linebreak.empty?
177
+ end
178
+ elsif Muby::Style === e
179
+ e.affect(@outputBuffer)
180
+ end
181
+ end
182
+ else
183
+ @waitBuffer += info
184
+ end
185
+ refresh
186
+ nil
187
+ end
188
+
189
+ end # class OutputWindow
@@ -0,0 +1,142 @@
1
+ module Muby
2
+
3
+ #
4
+ # The encapsulation of all the ncurses horror.
5
+ #
6
+ class Style
7
+
8
+ include Muby::Logger
9
+ include Muby::Configurable
10
+
11
+ attr_reader :attributes, :color1, :color2
12
+
13
+ class ColorPair
14
+ @@instances = []
15
+ @@initialized = false
16
+ def self.init_pairs
17
+ unless @@initialized
18
+ 1.upto(Ncurses.COLOR_PAIRS - 1) do |n|
19
+ @@instances << ColorPair.new(n)
20
+ end
21
+ @@initialized = true
22
+ end
23
+ end
24
+ def self.get_pair(fg, bg)
25
+ init_pairs
26
+
27
+ found = @@instances.find do |color|
28
+ color.bg == bg && color.fg == fg
29
+ end
30
+
31
+ found = @@instances.find do |color|
32
+ color.bg.nil? && color.fg.nil?
33
+ end unless found
34
+
35
+ found = @@instances.sort do |c1, c2|
36
+ c1.used_at <=> c2.used_at
37
+ end.first unless found
38
+
39
+ found.use(fg, bg)
40
+
41
+ found
42
+ end
43
+
44
+ attr_accessor :bg, :fg, :number, :used_at
45
+
46
+ def initialize(number)
47
+ @number = number
48
+ @used_at = Time.new
49
+ end
50
+
51
+ def to_i
52
+ Ncurses.COLOR_PAIR(@number)
53
+ end
54
+
55
+ def use(fg, bg)
56
+ @used_at = Time.new
57
+ if (bg != @bg || fg != @fg)
58
+ @bg = bg
59
+ @fg = fg
60
+ Ncurses.init_pair(@number, @fg, @bg)
61
+ end
62
+ end
63
+ end
64
+
65
+ def initialize(attributes, color1, color2, toAdd = false)
66
+ @attributes = attributes
67
+ @color1 = color1
68
+ @color2 = color2
69
+ @toAdd = toAdd
70
+ end
71
+
72
+ #
73
+ # Get a Style instance from a window (so we can save it and restore it)
74
+ #
75
+ def self.extract(window)
76
+ tmp = []
77
+ oldAttributes = []
78
+ oldAttribute = 0
79
+ oldColorPair = []
80
+ oldColor1 = []
81
+ oldColor2 = []
82
+
83
+ window.wattr_get(oldAttributes,oldColorPair,tmp)
84
+ oldAttribute = oldAttributes[0] ^ Ncurses.COLOR_PAIR(oldColorPair[0])
85
+ Ncurses.pair_content(oldColorPair[0], oldColor1, oldColor2)
86
+
87
+ Muby::Style.new(oldAttribute, oldColor1[0], oldColor2[0])
88
+ end
89
+
90
+ #
91
+ # Affect the window, either overwriting its style or adding to it.
92
+ #
93
+ def affect(window)
94
+ if @toAdd
95
+ window.wattron(to_int(window))
96
+ else
97
+ window.wattrset(to_int(window))
98
+ end
99
+ end
100
+
101
+ def get_color_value(fg, bg)
102
+ Muby::Style::ColorPair.get_pair(fg, bg).to_i
103
+ end
104
+
105
+ #
106
+ # Get an int representation of this style, to send to ncurses.
107
+ #
108
+ def to_int(window)
109
+ oldAttributes = self.class.extract(window)
110
+ color1 = @color1 == :copy ? oldAttributes.color1 : @color1 || conf.default_colors[0]
111
+ color2 = @color2 == :copy ? oldAttributes.color2 : @color2 || conf.default_colors[1]
112
+ @attributes | get_color_value(color1, color2)
113
+ end
114
+
115
+ end # class Style
116
+
117
+ module Styled
118
+ unless defined?(RED)
119
+ RED = Muby::Style.new(0, Ncurses.const_get("COLOR_RED"), :copy, true)
120
+ BLACK = Muby::Style.new(0, Ncurses.const_get("COLOR_BLACK"), :copy, true)
121
+ GREEN = Muby::Style.new(0, Ncurses.const_get("COLOR_GREEN"), :copy, true)
122
+ YELLOW = Muby::Style.new(0, Ncurses.const_get("COLOR_YELLOW"), :copy, true)
123
+ MAGENTA = Muby::Style.new(0, Ncurses.const_get("COLOR_MAGENTA"), :copy, true)
124
+ BLUE = Muby::Style.new(0, Ncurses.const_get("COLOR_BLUE"), :copy, true)
125
+ CYAN = Muby::Style.new(0, Ncurses.const_get("COLOR_CYAN"), :copy, true)
126
+ WHITE = Muby::Style.new(0, Ncurses.const_get("COLOR_WHITE"), :copy, true)
127
+
128
+ BOLD = Muby::Style.new(Ncurses.const_get("A_BOLD"), :copy, :copy, true)
129
+ DIM = Muby::Style.new(Ncurses.const_get("A_DIM"), :copy, :copy, true)
130
+ UNDERLINE = Muby::Style.new(Ncurses.const_get("A_UNDERLINE"), :copy, :copy, true)
131
+ BLINK = Muby::Style.new(Ncurses.const_get("A_BLINK"), :copy, :copy, true)
132
+ REVERSE = Muby::Style.new(Ncurses.const_get("A_REVERSE"), :copy, :copy, true)
133
+ INVIS = Muby::Style.new(Ncurses.const_get("A_INVIS"), :copy, :copy, true)
134
+ STANDOUT = Muby::Style.new(Ncurses.const_get("A_STANDOUT"), :copy, :copy, true)
135
+ PROTECT = Muby::Style.new(Ncurses.const_get("A_PROTECT"), :copy, :copy, true)
136
+ ALTCHARSET = Muby::Style.new(Ncurses.const_get("A_ALTCHARSET"), :copy, :copy, true)
137
+ CHARTEXT = Muby::Style.new(Ncurses.const_get("A_CHARTEXT"), :copy, :copy, true)
138
+
139
+ NORMAL = Muby::Style.new(Ncurses.const_get("A_NORMAL"), :copy, :copy, false)
140
+ end
141
+ end
142
+ end