Class: Lich::Common::Script
- Inherits:
-
Object
- Object
- Lich::Common::Script
- Defined in:
- lib/common/script.rb
Overview
This class manages the execution of scripts.
Direct Known Subclasses
Constant Summary collapse
- @@elevated_script_start =
Starts an elevated script with the given arguments.
proc { |args| if args.empty? # fixme: error next nil elsif args[0].class == String script_name = args[0] if args[1] if args[1].class == String script_args = args[1] if args[2] if args[2].class == Hash = args[2] else # fixme: error next nil end end elsif args[1].class == Hash = args[1] script_args = ([:args] || String.new) else # fixme: error next nil end else = Hash.new end elsif args[0].class == Hash = args[0] if [:name] script_name = [:name] else # fixme: error next nil end script_args = ([:args] || String.new) end # fixme: look in wizard script directory # fixme: allow subdirectories? file_list = Dir.children(File.join(SCRIPT_DIR, "custom")).sort_by { |fn| fn.sub(/[.](lic|rb|cmd|wiz)$/, '') }.map { |s| s.prepend("/custom/") } + Dir.children(SCRIPT_DIR).sort_by { |fn| fn.sub(/[.](lic|rb|cmd|wiz)$/, '') } if (file_name = (file_list.find { |val| val =~ /^(?:\/custom\/)?#{Regexp.escape(script_name)}\.(?:lic|rb|cmd|wiz)(?:\.gz|\.Z)?$/ || val =~ /^(?:\/custom\/)?#{Regexp.escape(script_name)}\.(?:lic|rb|cmd|wiz)(?:\.gz|\.Z)?$/i } || file_list.find { |val| val =~ /^(?:\/custom\/)?#{Regexp.escape(script_name)}[^.]+\.(?i:lic|rb|cmd|wiz)(?:\.gz|\.Z)?$/ } || file_list.find { |val| val =~ /^(?:\/custom\/)?#{Regexp.escape(script_name)}[^.]+\.(?:lic|rb|cmd|wiz)(?:\.gz|\.Z)?$/i })) script_name = file_name.sub(/\..{1,3}$/, '') end if file_name.nil? respond "--- Lich: could not find script '#{script_name}' in directory #{SCRIPT_DIR} or #{SCRIPT_DIR}/custom" next nil end if ([:force] != true) and (Script.running + Script.hidden).find { |s| s.name =~ /^#{Regexp.escape(script_name.sub('/custom/', ''))}$/i } respond "--- Lich: #{script_name} is already running (use #{$clean_lich_char}force [scriptname] if desired)." next nil end begin if file_name =~ /\.(?:cmd|wiz)(?:\.gz)?$/i trusted = false script_obj = WizardScript.new("#{SCRIPT_DIR}/#{file_name}", script_args) else if script_obj.labels.length > 1 trusted = false else trusted = true end script_obj = Script.new(:file => "#{SCRIPT_DIR}/#{file_name}", :args => script_args, :quiet => [:quiet]) end if trusted script_binding = TRUSTED_SCRIPT_BINDING.call else script_binding = Scripting.new.script end rescue respond "--- Lich: error: #{$!}\n\t#{$!.backtrace.join("\n\t")}" next nil end unless script_obj respond "--- Lich: error: failed to start script (#{script_name})" next nil end script_obj.quiet = true if [:quiet] new_thread = Thread.new { 100.times { break if Script.current == script_obj; sleep 0.01 } if (script = Script.current) eval('script = Script.current', script_binding, script.name) Thread.current.priority = 1 respond("--- Lich: #{script.name} active.") unless script.quiet if trusted begin eval(script.labels[script.current_label].to_s, script_binding, script.name) rescue SystemExit nil rescue SyntaxError respond "--- Lich: error: #{$!}\n\t#{$!.backtrace[0..1].join("\n\t")}" Lich.log "error: #{$!}\n\t#{$!.backtrace.join("\n\t")}" rescue ScriptError respond "--- Lich: error: #{$!}\n\t#{$!.backtrace[0..1].join("\n\t")}" Lich.log "error: #{$!}\n\t#{$!.backtrace.join("\n\t")}" rescue NoMemoryError respond "--- Lich: error: #{$!}\n\t#{$!.backtrace[0..1].join("\n\t")}" Lich.log "error: #{$!}\n\t#{$!.backtrace.join("\n\t")}" rescue LoadError respond "--- Lich: error: #{$!}\n\t#{$!.backtrace[0..1].join("\n\t")}" Lich.log "error: #{$!}\n\t#{$!.backtrace.join("\n\t")}" rescue SecurityError respond "--- Lich: error: #{$!}\n\t#{$!.backtrace[0..1].join("\n\t")}" Lich.log "error: #{$!}\n\t#{$!.backtrace.join("\n\t")}" rescue ThreadError respond "--- Lich: error: #{$!}\n\t#{$!.backtrace[0..1].join("\n\t")}" Lich.log "error: #{$!}\n\t#{$!.backtrace.join("\n\t")}" rescue SystemStackError respond "--- Lich: error: #{$!}\n\t#{$!.backtrace[0..1].join("\n\t")}" Lich.log "error: #{$!}\n\t#{$!.backtrace.join("\n\t")}" rescue StandardError # Exception if $! == JUMP retry if Script.current.get_next_label != JUMP_ERROR respond "--- label error: `#{Script.current.jump_label}' was not found, and no `LabelError' label was found!" respond $!.backtrace.first Lich.log "label error: `#{Script.current.jump_label}' was not found, and no `LabelError' label was found!\n\t#{$!.backtrace.join("\n\t")}" Script.current.kill else respond "--- Lich: error: #{$!}\n\t#{$!.backtrace[0..1].join("\n\t")}" Lich.log "error: #{$!}\n\t#{$!.backtrace.join("\n\t")}" end rescue respond "--- Lich: error: #{$!}\n\t#{$!.backtrace[0..1].join("\n\t")}" Lich.log "error: #{$!}\n\t#{$!.backtrace.join("\n\t")}" ensure Script.current.kill end else begin while (script = Script.current) and script.current_label proc { foo = script.labels[script.current_label]; eval(foo, script_binding, script.name, 1) }.call Script.current.get_next_label end rescue SystemExit nil rescue SyntaxError respond "--- Lich: error: #{$!}\n\t#{$!.backtrace[0..1].join("\n\t")}" Lich.log "error: #{$!}\n\t#{$!.backtrace.join("\n\t")}" rescue ScriptError respond "--- Lich: error: #{$!}\n\t#{$!.backtrace[0..1].join("\n\t")}" Lich.log "error: #{$!}\n\t#{$!.backtrace.join("\n\t")}" rescue NoMemoryError respond "--- Lich: error: #{$!}\n\t#{$!.backtrace[0..1].join("\n\t")}" Lich.log "error: #{$!}\n\t#{$!.backtrace.join("\n\t")}" rescue LoadError respond "--- Lich: error: #{$!}\n\t#{$!.backtrace[0..1].join("\n\t")}" Lich.log "error: #{$!}\n\t#{$!.backtrace.join("\n\t")}" rescue SecurityError respond "--- Lich: error: #{$!}\n\t#{$!.backtrace[0..1].join("\n\t")}" if (name = Script.current.name) respond "--- Lich: review this script (#{name}) to make sure it isn't malicious, and type #{$clean_lich_char}trust #{name}" end Lich.log "error: #{$!}\n\t#{$!.backtrace.join("\n\t")}" rescue ThreadError respond "--- Lich: error: #{$!}\n\t#{$!.backtrace[0..1].join("\n\t")}" Lich.log "error: #{$!}\n\t#{$!.backtrace.join("\n\t")}" rescue SystemStackError respond "--- Lich: error: #{$!}\n\t#{$!.backtrace[0..1].join("\n\t")}" Lich.log "error: #{$!}\n\t#{$!.backtrace.join("\n\t")}" rescue StandardError # Exception if $! == JUMP retry if Script.current.get_next_label != JUMP_ERROR respond "--- label error: `#{Script.current.jump_label}' was not found, and no `LabelError' label was found!" respond $!.backtrace.first Lich.log "label error: `#{Script.current.jump_label}' was not found, and no `LabelError' label was found!\n\t#{$!.backtrace.join("\n\t")}" Script.current.kill else respond "--- Lich: error: #{$!}\n\t#{$!.backtrace[0..1].join("\n\t")}" Lich.log "error: #{$!}\n\t#{$!.backtrace.join("\n\t")}" end rescue respond "--- Lich: error: #{$!}\n\t#{$!.backtrace[0..1].join("\n\t")}" Lich.log "error: #{$!}\n\t#{$!.backtrace.join("\n\t")}" ensure Script.current.kill end end else respond '--- error: out of cheese' end } script_obj.thread_group.add(new_thread) script_obj }
- @@elevated_exists =
Checks if an elevated script exists.
proc { |script_name| if script_name =~ /\\|\// nil elsif script_name =~ /\.(?:lic|lich|rb|cmd|wiz)(?:\.gz)?$/i File.exist?("#{SCRIPT_DIR}/#{script_name}") || File.exist?("#{SCRIPT_DIR}/custom/#{script_name}") else File.exist?("#{SCRIPT_DIR}/#{script_name}.lic") || File.exist?("#{SCRIPT_DIR}/custom/#{script_name}.lic") || File.exist?("#{SCRIPT_DIR}/#{script_name}.lich") || File.exist?("#{SCRIPT_DIR}/custom/#{script_name}.lich") || File.exist?("#{SCRIPT_DIR}/#{script_name}.rb") || File.exist?("#{SCRIPT_DIR}/custom/#{script_name}.rb") || File.exist?("#{SCRIPT_DIR}/#{script_name}.cmd") || File.exist?("#{SCRIPT_DIR}/custom/#{script_name}.cmd") || File.exist?("#{SCRIPT_DIR}/#{script_name}.wiz") || File.exist?("#{SCRIPT_DIR}/custom/#{script_name}.wiz") || File.exist?("#{SCRIPT_DIR}/#{script_name}.lic.gz") || File.exist?("#{SCRIPT_DIR}/custom/#{script_name}.lic.gz") || File.exist?("#{SCRIPT_DIR}/#{script_name}.rb.gz") || File.exist?("#{SCRIPT_DIR}/custom/#{script_name}.rb.gz") || File.exist?("#{SCRIPT_DIR}/#{script_name}.cmd.gz") || File.exist?("#{SCRIPT_DIR}/custom/#{script_name}.cmd.gz") || File.exist?("#{SCRIPT_DIR}/#{script_name}.wiz.gz") || File.exist?("#{SCRIPT_DIR}/custom/#{script_name}.wiz.gz") end }
- @@elevated_log =
Logs data from the current script to a log file.
proc { |data| if (script = Script.current) if script.name =~ /\\|\// nil else begin Dir.mkdir("#{LICH_DIR}/logs") unless File.exist?("#{LICH_DIR}/logs") File.open("#{LICH_DIR}/logs/#{script.name}.log", 'a') { |f| f.puts data } true rescue respond "--- Lich: error: Script.log: #{$!}" false end end else respond '--- error: Script.log: unable to identify calling script' false end }
- @@elevated_db =
Creates a new database for the current script.
proc { if (script = Script.current) if script.name =~ /^lich$/i respond '--- error: Script.db cannot be used by a script named lich' nil elsif script.class == ExecScript respond '--- error: Script.db cannot be used by exec scripts' nil else SQLite3::Database.new("#{DATA_DIR}/#{script.name.gsub(/\/|\\/, '_')}.db3") end else respond '--- error: Script.db called by an unknown script' nil end }
- @@elevated_open_file =
Note:
This proc will respond with an error message if the current script is restricted from opening files.
A proc that handles opening files with specific restrictions based on the current script.
proc { |ext, mode, _block| if (script = Script.current) if script.name =~ /^lich$/i respond '--- error: Script.open_file cannot be used by a script named lich' nil elsif script.name =~ /^entry$/i respond '--- error: Script.open_file cannot be used by a script named entry' nil elsif script.class == ExecScript respond '--- error: Script.open_file cannot be used by exec scripts' nil elsif ext.downcase == 'db3' SQLite3::Database.new("#{DATA_DIR}/#{script.name.gsub(/\/|\\/, '_')}.db3") # fixme: block gets elevated... why? # elsif block # File.open("#{DATA_DIR}/#{script.name.gsub(/\/|\\/, '_')}.#{ext.gsub(/\/|\\/, '_')}", mode, &block) else File.open("#{DATA_DIR}/#{script.name.gsub(/\/|\\/, '_')}.#{ext.gsub(/\/|\\/, '_')}", mode) end else respond '--- error: Script.open_file called by an unknown script' nil end }
- @@running =
Array.new
Instance Attribute Summary collapse
-
#at_exit_procs ⇒ Object
readonly
Returns the value of attribute at_exit_procs.
-
#command_line ⇒ Object
Returns the value of attribute command_line.
-
#current_label ⇒ Object
Returns the value of attribute current_label.
-
#die_with ⇒ Object
Returns the value of attribute die_with.
-
#downstream_buffer ⇒ Object
Returns the value of attribute downstream_buffer.
-
#file_name ⇒ Object
readonly
Returns the value of attribute file_name.
-
#hidden ⇒ Object
Returns the value of attribute hidden.
-
#ignore_pause ⇒ Object
Returns the value of attribute ignore_pause.
-
#jump_label ⇒ Object
Returns the value of attribute jump_label.
-
#label_order ⇒ Object
readonly
Returns the value of attribute label_order.
-
#match_stack_labels ⇒ Object
Returns the value of attribute match_stack_labels.
-
#match_stack_strings ⇒ Object
Returns the value of attribute match_stack_strings.
-
#name ⇒ Object
readonly
Returns the value of attribute name.
-
#no_echo ⇒ Object
Returns the value of attribute no_echo.
-
#no_kill_all ⇒ Object
Returns the value of attribute no_kill_all.
-
#no_pause_all ⇒ Object
Returns the value of attribute no_pause_all.
-
#paused ⇒ Object
Returns the value of attribute paused.
-
#quiet ⇒ Object
Returns the value of attribute quiet.
-
#safe ⇒ Object
readonly
Returns the value of attribute safe.
-
#silent ⇒ Object
Returns the value of attribute silent.
-
#unique_buffer ⇒ Object
Returns the value of attribute unique_buffer.
-
#upstream_buffer ⇒ Object
Returns the value of attribute upstream_buffer.
-
#vars ⇒ Object
readonly
Returns the value of attribute vars.
-
#want_downstream ⇒ Object
Returns the value of attribute want_downstream.
-
#want_downstream_xml ⇒ Object
Returns the value of attribute want_downstream_xml.
-
#want_script_output ⇒ Object
Returns the value of attribute want_script_output.
-
#want_upstream ⇒ Object
Returns the value of attribute want_upstream.
-
#watchfor ⇒ Object
Returns the value of attribute watchfor.
Class Method Summary collapse
-
.at_exit(&block) ⇒ Boolean
Registers a block to be executed at exit for the current script.
-
.clear_exit_procs ⇒ Boolean
Clears all exit procs for the current script.
-
.current ⇒ Script?
Retrieves the current script.
-
.db ⇒ Object
Retrieves the database connection using the elevated mechanism.
-
.distrust(_script_name) ⇒ Boolean
Distrusts a script by returning false, as no actual distrust mechanism is implemented in this version.
-
.exists?(script_name) ⇒ Boolean
Checks if a script exists by name.
-
.exit! ⇒ Boolean
Exits the current script.
-
.hidden ⇒ Array
Lists all running scripts that are hidden.
-
.index ⇒ Array
Retrieves the index of running scripts.
-
.kill(name) ⇒ Boolean
Kills a running script by name.
-
.list ⇒ Array
Lists all currently running scripts.
-
.list_trusted ⇒ Array<String>
Lists trusted scripts, which will always return an empty array in this version.
-
.log(data) ⇒ void
Logs data using the elevated logging mechanism.
-
.namescript_incoming(line) ⇒ void
Sends a new downstream line to all running scripts.
-
.new_downstream(line) ⇒ void
Sends a new downstream line to all running scripts that want it.
-
.new_downstream_xml(line) ⇒ void
Sends a new downstream XML line to all running scripts that want it.
-
.new_script_output(line) ⇒ void
Sends a new script output line to all running scripts that want it.
-
.new_upstream(line) ⇒ void
Sends a new upstream line to all running scripts that want it.
-
.open_file(ext, mode = 'r', &block) ⇒ void
Opens a file with the specified extension and mode using the elevated mechanism.
-
.pause(name = nil) ⇒ Script, Boolean
Pauses a running script by name.
-
.paused?(name) ⇒ Boolean?
Checks if a script is paused by name.
-
.run(*args) ⇒ void
Runs a script with the given arguments.
-
.running ⇒ Array
Lists all running scripts that are not hidden.
-
.running?(name) ⇒ Boolean
Checks if a script with the given name is currently running.
-
.self ⇒ Script
Retrieves the current script.
-
.start(*args) ⇒ void
Starts a new script with the given arguments.
-
.trust(_script_name) ⇒ Boolean
Trusts a script by returning true, as no actual trust mechanism is implemented in this version.
-
.unpause(name) ⇒ Boolean
Unpauses a running script by name.
-
.version(script_name, script_version_required = nil) ⇒ Gem::Version?
The version of the script or nil if not found.
Instance Method Summary collapse
-
#at_exit(&block) ⇒ Boolean
Registers a block to be executed at script exit.
-
#clear ⇒ Array
Clears the downstream buffer and returns its contents.
-
#clear_exit_procs ⇒ Boolean
Clears all exit procedures registered with at_exit.
-
#exit ⇒ void
Exits the script by calling kill.
-
#exit! ⇒ void
Exits the script and clears exit procedures.
-
#feedme_upstream ⇒ void
Toggles the upstream feed state.
-
#get_next_label ⇒ String?
Retrieves the next label in the label order.
-
#gets ⇒ String, false
Retrieves the next item from the downstream buffer.
-
#gets? ⇒ String?
Checks if there is an item available in the downstream buffer.
-
#has_thread?(t) ⇒ Boolean
Checks if a specific thread is part of the thread group.
-
#initialize(args) ⇒ void
constructor
Initializes a new instance of the class.
-
#instance_eval(*_a) ⇒ nil
Returns nil for any evaluated instance.
-
#instance_variable_get(*_a) ⇒ nil
Returns nil for any instance variable.
-
#kill ⇒ String
Kills the current script and cleans up resources.
-
#labels ⇒ Hash
Returns the labels hash.
-
#match_stack_add(label, string) ⇒ void
Adds a label and string to the match stack.
-
#match_stack_clear ⇒ void
Clears the match stack.
-
#pause ⇒ void
Pauses the script if it is not already paused.
-
#paused? ⇒ Boolean
Checks if the script is currently paused.
-
#safe? ⇒ Boolean
Checks if the script is in a safe state.
-
#thread_group ⇒ ThreadGroup
Returns the thread group associated with the script.
-
#to_s ⇒ String
Returns the string representation of the script.
-
#unique_gets ⇒ String
Retrieves the next item from the unique buffer.
-
#unique_gets? ⇒ String?
Checks if there is an item available in the unique buffer.
-
#unpause ⇒ void
Unpauses the script if it is currently paused.
-
#upstream_gets ⇒ String
Retrieves the next item from the upstream buffer.
-
#upstream_gets? ⇒ String?
Checks if there is an item available in the upstream buffer.
Constructor Details
#initialize(args) ⇒ void
Initializes a new instance of the class.
885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 |
# File 'lib/common/script.rb', line 885 def initialize(args) @file_name = args[:file] @name = /.*[\/\\]+([^\.]+)\./.match(@file_name).captures.first if args[:args].class == String if args[:args].empty? @vars = Array.new else @vars = [args[:args]] @vars.concat(args[:args].scan(/[^\s"]*(?<!\\)"(?:\\"|[^"])+(?<!\\)"[^\s]*|(?:\\"|[^"\s])+/).collect { |s| s.gsub(/(?<!\\)"/, '').gsub('\\"', '"') }) end elsif args[:args].class == Array unless (args[:args].nil? || args[:args].empty?) @vars = [args[:args].join(" ")] @vars.concat args[:args] else @vars = Array.new end else @vars = Array.new end @quiet = (args[:quiet] ? true : false) @downstream_buffer = LimitedArray.new @want_downstream = true @want_downstream_xml = false @want_script_output = false @upstream_buffer = LimitedArray.new @want_upstream = false @unique_buffer = LimitedArray.new @watchfor = Hash.new @at_exit_procs = Array.new @die_with = Array.new @paused = false @hidden = false @no_pause_all = false @no_kill_all = false @silent = false @safe = false @no_echo = false @match_stack_labels = Array.new @match_stack_strings = Array.new @label_order = Array.new @labels = Hash.new @killer_mutex = Mutex.new @ignore_pause = false data = nil if @file_name =~ /\.gz$/i begin Zlib::GzipReader.open(@file_name) { |f| data = f.readlines.collect { |line| line.chomp } } rescue respond "--- Lich: error reading script file (#{@file_name}): #{$!}" # return nil end else begin File.open(@file_name) { |f| data = f.readlines.collect { |line| line.chomp } } rescue respond "--- Lich: error reading script file (#{@file_name}): #{$!}" # return nil end end @quiet = true if data[0] =~ /^[\t\s]*#?[\t\s]*(?:quiet|hush)$/i @current_label = '~start' @labels[@current_label] = String.new @label_order.push(@current_label) for line in data if line =~ /^([\d_\w]+):$/ @current_label = $1 @label_order.push(@current_label) @labels[@current_label] = String.new else @labels[@current_label].concat "#{line}\n" end end data = nil @current_label = @label_order[0] @thread_group = ThreadGroup.new @@running.push(self) # return self end |
Instance Attribute Details
#at_exit_procs ⇒ Object (readonly)
Returns the value of attribute at_exit_procs.
|
# File 'lib/common/script.rb', line 350
|
#command_line ⇒ Object
Returns the value of attribute command_line.
409 410 411 |
# File 'lib/common/script.rb', line 409 def command_line @command_line end |
#current_label ⇒ Object
Returns the value of attribute current_label.
409 410 411 |
# File 'lib/common/script.rb', line 409 def current_label @current_label end |
#die_with ⇒ Object
Returns the value of attribute die_with.
409 410 411 |
# File 'lib/common/script.rb', line 409 def die_with @die_with end |
#downstream_buffer ⇒ Object
Returns the value of attribute downstream_buffer.
409 410 411 |
# File 'lib/common/script.rb', line 409 def downstream_buffer @downstream_buffer end |
#file_name ⇒ Object (readonly)
Returns the value of attribute file_name.
|
# File 'lib/common/script.rb', line 350
|
#hidden ⇒ Object
Returns the value of attribute hidden.
409 410 411 |
# File 'lib/common/script.rb', line 409 def hidden @hidden end |
#ignore_pause ⇒ Object
Returns the value of attribute ignore_pause.
409 410 411 |
# File 'lib/common/script.rb', line 409 def ignore_pause @ignore_pause end |
#jump_label ⇒ Object
Returns the value of attribute jump_label.
409 410 411 |
# File 'lib/common/script.rb', line 409 def jump_label @jump_label end |
#label_order ⇒ Object (readonly)
Returns the value of attribute label_order.
|
# File 'lib/common/script.rb', line 350
|
#match_stack_labels ⇒ Object
Returns the value of attribute match_stack_labels.
409 410 411 |
# File 'lib/common/script.rb', line 409 def match_stack_labels @match_stack_labels end |
#match_stack_strings ⇒ Object
Returns the value of attribute match_stack_strings.
409 410 411 |
# File 'lib/common/script.rb', line 409 def match_stack_strings @match_stack_strings end |
#name ⇒ Object (readonly)
Returns the value of attribute name.
|
# File 'lib/common/script.rb', line 350
|
#no_echo ⇒ Object
Returns the value of attribute no_echo.
409 410 411 |
# File 'lib/common/script.rb', line 409 def no_echo @no_echo end |
#no_kill_all ⇒ Object
Returns the value of attribute no_kill_all.
409 410 411 |
# File 'lib/common/script.rb', line 409 def no_kill_all @no_kill_all end |
#no_pause_all ⇒ Object
Returns the value of attribute no_pause_all.
409 410 411 |
# File 'lib/common/script.rb', line 409 def no_pause_all @no_pause_all end |
#paused ⇒ Object
Returns the value of attribute paused.
409 410 411 |
# File 'lib/common/script.rb', line 409 def paused @paused end |
#quiet ⇒ Object
Returns the value of attribute quiet.
409 410 411 |
# File 'lib/common/script.rb', line 409 def quiet @quiet end |
#safe ⇒ Object (readonly)
Returns the value of attribute safe.
|
# File 'lib/common/script.rb', line 350
|
#silent ⇒ Object
Returns the value of attribute silent.
409 410 411 |
# File 'lib/common/script.rb', line 409 def silent @silent end |
#unique_buffer ⇒ Object
Returns the value of attribute unique_buffer.
409 410 411 |
# File 'lib/common/script.rb', line 409 def unique_buffer @unique_buffer end |
#upstream_buffer ⇒ Object
Returns the value of attribute upstream_buffer.
409 410 411 |
# File 'lib/common/script.rb', line 409 def upstream_buffer @upstream_buffer end |
#vars ⇒ Object (readonly)
Returns the value of attribute vars.
|
# File 'lib/common/script.rb', line 350
|
#want_downstream ⇒ Object
Returns the value of attribute want_downstream.
409 410 411 |
# File 'lib/common/script.rb', line 409 def want_downstream @want_downstream end |
#want_downstream_xml ⇒ Object
Returns the value of attribute want_downstream_xml.
409 410 411 |
# File 'lib/common/script.rb', line 409 def want_downstream_xml @want_downstream_xml end |
#want_script_output ⇒ Object
Returns the value of attribute want_script_output.
409 410 411 |
# File 'lib/common/script.rb', line 409 def want_script_output @want_script_output end |
#want_upstream ⇒ Object
Returns the value of attribute want_upstream.
409 410 411 |
# File 'lib/common/script.rb', line 409 def want_upstream @want_upstream end |
#watchfor ⇒ Object
Returns the value of attribute watchfor.
409 410 411 |
# File 'lib/common/script.rb', line 409 def watchfor @watchfor end |
Class Method Details
.at_exit(&block) ⇒ Boolean
Registers a block to be executed at exit for the current script.
685 686 687 688 689 690 691 692 |
# File 'lib/common/script.rb', line 685 def Script.at_exit(&block) if (script = Script.current) script.at_exit(&block) else respond "--- Lich: error: Script.at_exit: can't identify calling script" return false end end |
.clear_exit_procs ⇒ Boolean
Clears all exit procs for the current script.
699 700 701 702 703 704 705 706 |
# File 'lib/common/script.rb', line 699 def Script.clear_exit_procs if (script = Script.current) script.clear_exit_procs else respond "--- Lich: error: Script.clear_exit_procs: can't identify calling script" return false end end |
.current ⇒ Script?
Retrieves the current script.
470 471 472 473 474 475 476 477 |
# File 'lib/common/script.rb', line 470 def Script.current if (script = @@running.find { |s| s.has_thread?(Thread.current) }) sleep 0.2 while script.paused? and not script.ignore_pause script else nil end end |
.db ⇒ Object
Retrieves the database connection using the elevated mechanism.
663 664 665 |
# File 'lib/common/script.rb', line 663 def Script.db @@elevated_db.call end |
.distrust(_script_name) ⇒ Boolean
Distrusts a script by returning false, as no actual distrust mechanism is implemented in this version.
808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 |
# File 'lib/common/script.rb', line 808 def Script.distrust(script_name) begin there = Lich.db.get_first_value('SELECT name FROM trusted_scripts WHERE name=?;', [script_name.encode('UTF-8')]) rescue SQLite3::BusyException sleep 0.1 retry end if there begin Lich.db.execute('DELETE FROM trusted_scripts WHERE name=?;', [script_name.encode('UTF-8')]) rescue SQLite3::BusyException sleep 0.1 retry end true else false end end |
.exists?(script_name) ⇒ Boolean
Checks if a script exists by name.
581 582 583 |
# File 'lib/common/script.rb', line 581 def Script.exists?(script_name) @@elevated_exists.call(script_name) end |
.exit! ⇒ Boolean
Exits the current script.
713 714 715 716 717 718 719 720 |
# File 'lib/common/script.rb', line 713 def Script.exit! if (script = Script.current) script.exit! else respond "--- Lich: error: Script.exit!: can't identify calling script" return false end end |
.hidden ⇒ Array
Lists all running scripts that are hidden.
758 759 760 761 762 763 764 |
# File 'lib/common/script.rb', line 758 def Script.hidden list = Array.new for script in @@running list.push(script) if script.hidden end return list end |
.index ⇒ Array
Retrieves the index of running scripts.
749 750 751 |
# File 'lib/common/script.rb', line 749 def Script.index Script.running end |
.kill(name) ⇒ Boolean
Kills a running script by name.
552 553 554 555 556 557 558 559 |
# File 'lib/common/script.rb', line 552 def Script.kill(name) if (s = (@@running.find { |i| i.name == name }) || (@@running.find { |i| i.name =~ /^#{name}$/i })) s.kill true else false end end |
.list ⇒ Array
Lists all currently running scripts.
461 462 463 |
# File 'lib/common/script.rb', line 461 def Script.list @@running.dup end |
.list_trusted ⇒ Array<String>
Lists trusted scripts, which will always return an empty array in this version.
834 835 836 837 838 839 840 841 842 843 |
# File 'lib/common/script.rb', line 834 def Script.list_trusted list = Array.new begin Lich.db.execute('SELECT name FROM trusted_scripts;').each { |name| list.push(name[0]) } rescue SQLite3::BusyException sleep 0.1 retry end list end |
.log(data) ⇒ void
This method returns an undefined value.
Logs data using the elevated logging mechanism.
654 655 656 |
# File 'lib/common/script.rb', line 654 def Script.log(data) @@elevated_log.call(data) end |
.namescript_incoming(line) ⇒ void
This method returns an undefined value.
Sends a new downstream line to all running scripts.
772 773 774 |
# File 'lib/common/script.rb', line 772 def Script.namescript_incoming(line) Script.new_downstream(line) end |
.new_downstream(line) ⇒ void
This method returns an undefined value.
Sends a new downstream line to all running scripts that want it.
615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 |
# File 'lib/common/script.rb', line 615 def Script.new_downstream(line) @@running.each { |script| script.downstream_buffer.push(line.chomp) if script.want_downstream unless script.watchfor.empty? script.watchfor.each_pair { |trigger, action| if line =~ trigger new_thread = Thread.new { sleep 0.011 until Script.current begin action.call rescue echo "watchfor error: #{$!}" end } script.thread_group.add(new_thread) end } end } end |
.new_downstream_xml(line) ⇒ void
This method returns an undefined value.
Sends a new downstream XML line to all running scripts that want it.
591 592 593 594 595 |
# File 'lib/common/script.rb', line 591 def Script.new_downstream_xml(line) for script in @@running script.downstream_buffer.push(line.chomp) if script.want_downstream_xml end end |
.new_script_output(line) ⇒ void
This method returns an undefined value.
Sends a new script output line to all running scripts that want it.
642 643 644 645 646 |
# File 'lib/common/script.rb', line 642 def Script.new_script_output(line) for script in @@running script.downstream_buffer.push(line.chomp) if script.want_script_output end end |
.new_upstream(line) ⇒ void
This method returns an undefined value.
Sends a new upstream line to all running scripts that want it.
603 604 605 606 607 |
# File 'lib/common/script.rb', line 603 def Script.new_upstream(line) for script in @@running script.upstream_buffer.push(line.chomp) if script.want_upstream end end |
.open_file(ext, mode = 'r', &block) ⇒ void
This method returns an undefined value.
Opens a file with the specified extension and mode using the elevated mechanism.
675 676 677 |
# File 'lib/common/script.rb', line 675 def Script.open_file(ext, mode = 'r', &block) @@elevated_open_file.call(ext, mode, block) end |
.pause(name = nil) ⇒ Script, Boolean
Pauses a running script by name.
517 518 519 520 521 522 523 524 525 526 527 528 529 |
# File 'lib/common/script.rb', line 517 def Script.pause(name = nil) if name.nil? Script.current.pause Script.current else if (s = (@@running.find { |i| (i.name == name) and not i.paused? }) || (@@running.find { |i| (i.name =~ /^#{name}$/i) and not i.paused? })) s.pause true else false end end end |
.paused?(name) ⇒ Boolean?
Checks if a script is paused by name.
567 568 569 570 571 572 573 |
# File 'lib/common/script.rb', line 567 def Script.paused?(name) if (s = (@@running.find { |i| i.name == name }) || (@@running.find { |i| i.name =~ /^#{name}$/i })) s.paused? else nil end end |
.run(*args) ⇒ void
This method returns an undefined value.
Runs a script with the given arguments.
495 496 497 498 499 |
# File 'lib/common/script.rb', line 495 def Script.run(*args) if (s = @@elevated_script_start.call(args)) sleep 0.1 while @@running.include?(s) end end |
.running ⇒ Array
Lists all running scripts that are not hidden.
736 737 738 739 740 741 742 |
# File 'lib/common/script.rb', line 736 def Script.running list = Array.new for script in @@running list.push(script) unless script.hidden end return list end |
.running?(name) ⇒ Boolean
Checks if a script with the given name is currently running.
507 508 509 |
# File 'lib/common/script.rb', line 507 def Script.running?(name) @@running.any? { |i| (i.name =~ /^#{name}$/i) } end |
.self ⇒ Script
Retrieves the current script.
727 728 729 |
# File 'lib/common/script.rb', line 727 def Script.self Script.current end |
.start(*args) ⇒ void
This method returns an undefined value.
Starts a new script with the given arguments.
485 486 487 |
# File 'lib/common/script.rb', line 485 def Script.start(*args) @@elevated_script_start.call(args) end |
.trust(_script_name) ⇒ Boolean
Trusts a script by returning true, as no actual trust mechanism is implemented in this version.
785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 |
# File 'lib/common/script.rb', line 785 def Script.trust(script_name) # fixme: case sensitive blah blah if not caller.any? { |c| c =~ /eval|run/ } begin Lich.db.execute('INSERT OR REPLACE INTO trusted_scripts(name) values(?);', [script_name.encode('UTF-8')]) rescue SQLite3::BusyException sleep 0.1 retry end true else respond '--- error: scripts may not trust scripts' false end end |
.unpause(name) ⇒ Boolean
Unpauses a running script by name.
537 538 539 540 541 542 543 544 |
# File 'lib/common/script.rb', line 537 def Script.unpause(name) if (s = (@@running.find { |i| (i.name == name) and i.paused? }) || (@@running.find { |i| (i.name =~ /^#{name}$/i) and i.paused? })) s.unpause true else false end end |
.version(script_name, script_version_required = nil) ⇒ Gem::Version?
Returns the version of the script or nil if not found.
419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 |
# File 'lib/common/script.rb', line 419 def Script.version(script_name, script_version_required = nil) script_name = script_name.sub(/[.](lic|rb|cmd|wiz)$/, '') file_list = Dir.children(File.join(SCRIPT_DIR, "custom")).sort_by { |fn| fn.sub(/[.](lic|rb|cmd|wiz)$/, '') }.map { |s| s.prepend("/custom/") } + Dir.children(SCRIPT_DIR).sort_by { |fn| fn.sub(/[.](lic|rb|cmd|wiz)$/, '') } if (file_name = (file_list.find { |val| val =~ /^(?:\/custom\/)?#{Regexp.escape(script_name)}\.(?:lic|rb|cmd|wiz)(?:\.gz|\.Z)?$/ || val =~ /^(?:\/custom\/)?#{Regexp.escape(script_name)}\.(?:lic|rb|cmd|wiz)(?:\.gz|\.Z)?$/i } || file_list.find { |val| val =~ /^(?:\/custom\/)?#{Regexp.escape(script_name)}[^.]+\.(?i:lic|rb|cmd|wiz)(?:\.gz|\.Z)?$/ } || file_list.find { |val| val =~ /^(?:\/custom\/)?#{Regexp.escape(script_name)}[^.]+\.(?:lic|rb|cmd|wiz)(?:\.gz|\.Z)?$/i })) script_name = file_name.sub(/\..{1,3}$/, '') end if file_name.nil? respond "--- Lich: could not find script '#{script_name}' in directory #{SCRIPT_DIR}" return nil end script_version = '0.0.0' script_data = File.open("#{SCRIPT_DIR}/#{file_name}", 'r').read if script_data =~ /^=begin\r?\n?(.+?)^=end/m comments = $1.split("\n") else comments = [] script_data.split("\n").each { |line| if line =~ /^[\t\s]*#/ comments.push(line) elsif line !~ /^[\t\s]*$/ break end } end for line in comments if line =~ /^[\s\t#]*version:[\s\t]*([\w,\s\.\d]+)/i script_version = $1.sub(/\s\(.*?\)/, '').strip end end if script_version_required Gem::Version.new(script_version) < Gem::Version.new(script_version_required) else Gem::Version.new(script_version) end end |
Instance Method Details
#at_exit(&block) ⇒ Boolean
Registers a block to be executed at script exit.
1005 1006 1007 1008 1009 1010 1011 1012 1013 |
# File 'lib/common/script.rb', line 1005 def at_exit(&block) if block @at_exit_procs.push(block) return true else respond '--- warning: Script.at_exit called with no code block' return false end end |
#clear ⇒ Array
Clears the downstream buffer and returns its contents.
1155 1156 1157 1158 1159 |
# File 'lib/common/script.rb', line 1155 def clear to_return = @downstream_buffer.dup @downstream_buffer.clear to_return end |
#clear_exit_procs ⇒ Boolean
Clears all exit procedures registered with at_exit.
1020 1021 1022 1023 |
# File 'lib/common/script.rb', line 1020 def clear_exit_procs @at_exit_procs.clear true end |
#exit ⇒ void
This method returns an undefined value.
Exits the script by calling kill.
1030 1031 1032 |
# File 'lib/common/script.rb', line 1030 def exit kill end |
#exit! ⇒ void
This method returns an undefined value.
Exits the script and clears exit procedures.
1039 1040 1041 1042 |
# File 'lib/common/script.rb', line 1039 def exit! @at_exit_procs.clear kill end |
#feedme_upstream ⇒ void
This method returns an undefined value.
Toggles the upstream feed state.
1266 1267 1268 |
# File 'lib/common/script.rb', line 1266 def feedme_upstream @want_upstream = !@want_upstream end |
#get_next_label ⇒ String?
Retrieves the next label in the label order.
1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 |
# File 'lib/common/script.rb', line 1131 def get_next_label if !@jump_label @current_label = @label_order[@label_order.index(@current_label) + 1] else if (label = @labels.keys.find { |val| val =~ /^#{@jump_label}$/ }) @current_label = label elsif (label = @labels.keys.find { |val| val =~ /^#{@jump_label}$/i }) @current_label = label elsif (label = @labels.keys.find { |val| val =~ /^labelerror$/i }) @current_label = label else @current_label = nil return JUMP_ERROR end @jump_label = nil @current_label end end |
#gets ⇒ String, false
Retrieves the next item from the downstream buffer.
1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 |
# File 'lib/common/script.rb', line 1175 def gets # fixme: no xml gets if @want_downstream or @want_downstream_xml or @want_script_output sleep 0.05 while @downstream_buffer.empty? @downstream_buffer.shift else echo 'this script is set as unique but is waiting for game data...' sleep 2 false end end |
#gets? ⇒ String?
Checks if there is an item available in the downstream buffer.
1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 |
# File 'lib/common/script.rb', line 1192 def gets? if @want_downstream or @want_downstream_xml or @want_script_output if @downstream_buffer.empty? nil else @downstream_buffer.shift end else echo 'this script is set as unique but is waiting for game data...' sleep 2 false end end |
#has_thread?(t) ⇒ Boolean
Checks if a specific thread is part of the thread group.
1084 1085 1086 |
# File 'lib/common/script.rb', line 1084 def has_thread?(t) @thread_group.list.include?(t) end |
#instance_eval(*_a) ⇒ nil
Returns nil for any evaluated instance.
1058 |
# File 'lib/common/script.rb', line 1058 def instance_eval(*_a); nil; end |
#instance_variable_get(*_a) ⇒ nil
Returns nil for any instance variable.
1050 |
# File 'lib/common/script.rb', line 1050 def instance_variable_get(*_a); nil; end |
#kill ⇒ String
Kills the current script and cleans up resources.
971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 |
# File 'lib/common/script.rb', line 971 def kill Thread.new { @killer_mutex.synchronize { if @@running.include?(self) begin @thread_group.list.dup.each { |t| unless t == Thread.current t.kill rescue nil end } @thread_group.add(Thread.current) @die_with.each { |script_name| Script.kill(script_name) } @paused = false @at_exit_procs.each { |p| report_errors { p.call } } @die_with = @at_exit_procs = @downstream_buffer = @upstream_buffer = @match_stack_labels = @match_stack_strings = nil @@running.delete(self) respond("--- Lich: #{@name} has exited.") unless @quiet GC.start rescue respond "--- Lich: error: #{$!}" Lich.log "error: #{$!}\n\t#{$!.backtrace.join("\n\t")}" end end } } @name end |
#labels ⇒ Hash
Returns the labels hash.
1065 1066 1067 |
# File 'lib/common/script.rb', line 1065 def labels @labels end |
#match_stack_add(label, string) ⇒ void
This method returns an undefined value.
Adds a label and string to the match stack.
1277 1278 1279 1280 |
# File 'lib/common/script.rb', line 1277 def match_stack_add(label, string) @match_stack_labels.push(label) @match_stack_strings.push(string) end |
#match_stack_clear ⇒ void
This method returns an undefined value.
Clears the match stack.
1287 1288 1289 1290 |
# File 'lib/common/script.rb', line 1287 def match_stack_clear @match_stack_labels.clear @match_stack_strings.clear end |
#pause ⇒ void
This method returns an undefined value.
Pauses the script if it is not already paused.
1093 1094 1095 1096 1097 1098 1099 1100 |
# File 'lib/common/script.rb', line 1093 def pause if @paused == true respond "--- Lich: #{@name} is already paused." else respond "--- Lich: #{@name} paused." @paused = true end end |
#paused? ⇒ Boolean
Checks if the script is currently paused.
1121 1122 1123 |
# File 'lib/common/script.rb', line 1121 def paused? @paused end |
#safe? ⇒ Boolean
Checks if the script is in a safe state.
1257 1258 1259 |
# File 'lib/common/script.rb', line 1257 def safe? @safe end |
#thread_group ⇒ ThreadGroup
Returns the thread group associated with the script.
1074 1075 1076 |
# File 'lib/common/script.rb', line 1074 def thread_group @thread_group end |
#to_s ⇒ String
Returns the string representation of the script.
1166 1167 1168 |
# File 'lib/common/script.rb', line 1166 def to_s @name end |
#unique_gets ⇒ String
Retrieves the next item from the unique buffer.
1234 1235 1236 1237 |
# File 'lib/common/script.rb', line 1234 def unique_gets sleep 0.05 while @unique_buffer.empty? @unique_buffer.shift end |
#unique_gets? ⇒ String?
Checks if there is an item available in the unique buffer.
1244 1245 1246 1247 1248 1249 1250 |
# File 'lib/common/script.rb', line 1244 def unique_gets? if @unique_buffer.empty? nil else @unique_buffer.shift end end |
#unpause ⇒ void
This method returns an undefined value.
Unpauses the script if it is currently paused.
1107 1108 1109 1110 1111 1112 1113 1114 |
# File 'lib/common/script.rb', line 1107 def unpause if @paused == true respond "--- Lich: #{@name} unpaused." @paused = false else respond "--- Lich: #{@name} is not paused." end end |
#upstream_gets ⇒ String
Retrieves the next item from the upstream buffer.
1211 1212 1213 1214 |
# File 'lib/common/script.rb', line 1211 def upstream_gets sleep 0.05 while @upstream_buffer.empty? @upstream_buffer.shift end |
#upstream_gets? ⇒ String?
Checks if there is an item available in the upstream buffer.
1221 1222 1223 1224 1225 1226 1227 |
# File 'lib/common/script.rb', line 1221 def upstream_gets? if @upstream_buffer.empty? nil else @upstream_buffer.shift end end |