muby 0.6.6

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