Class: Lich::Common::Script

Inherits:
Object
  • Object
show all
Defined in:
documented/common/script.rb

Overview

Represents a script that can be executed within the Lich engine.

This class manages the execution state, variables, and script flow.

See Also:

  • for script execution details.

Direct Known Subclasses

ExecScript, WizardScript

Defined Under Namespace

Classes: JumpError

Constant Summary collapse

JUMP =
JumpError.exception('JUMP')
JUMP_ERROR =
JumpError.exception('JUMP_ERROR')
@@elevated_script_start =
proc { |args|
  if args.empty?
    # fixme: error
    next nil
  elsif args[0].is_a?(String)
    script_name = args[0]
    if args[1]
      if args[1].is_a?(String)
        script_args = args[1]
        if args[2]
          if args[2].is_a?(Hash)
            options = args[2]
          else
            # fixme: error
            next nil
          end
        end
      elsif args[1].is_a?(Hash)
        options = args[1]
        script_args = (options[:args] || String.new)
      else
        # fixme: error
        next nil
      end
    else
      options = Hash.new
    end
  elsif args[0].is_a?(Hash)
    options = args[0]
    if options[:name]
      script_name = options[:name]
    else
      # fixme: error
      next nil
    end
    script_args = (options[:args] || String.new)
  end
   # fixme: look in wizard script directory
  # Build file list: custom/ root, then custom/ subdirectories, then SCRIPT_DIR root
  custom_base = File.join(SCRIPT_DIR, "custom")
  custom_dirs = []
  if File.directory?(custom_base)
    custom_dirs << custom_base
    Dir.children(custom_base).sort.each do |child|
      child_path = File.join(custom_base, child)
      custom_dirs << child_path if File.directory?(child_path)
    end
  end
  file_list = custom_dirs.flat_map { |dir|
    prefix = dir.sub(SCRIPT_DIR, '')
    Dir.children(dir)
       .select { |f| f =~ /\.(lic|rb|cmd|wiz)(\.(gz|Z))?$/i }
       .sort_by { |fn| fn.sub(/\.[^.]+$/, '') }
       .map { |s| "#{prefix}/#{s}" }
  } + 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 (options[:force] != true) and (Script.running + Script.hidden).find { |s| s.name =~ /^#{Regexp.escape(script_name.sub(%r{/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 => options[: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 options[: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.custom? ? 'custom/' : ''}#{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 JumpError
          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 StandardError
          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 JumpError
          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 StandardError
          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 =
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 =
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 =
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.is_a?(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 =
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.is_a?(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

Instance Method Summary collapse

Constructor Details

#initialize(args) ⇒ Script

Returns a new instance of Script.



639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
# File 'documented/common/script.rb', line 639

def initialize(args)
  @file_name = args[:file]
  @name = /.*[\/\\]+([^\.]+)\./.match(@file_name).captures.first
  @custom = (/.*[\/\\]+(custom)[\/\\]+[^\.]+\./.match(@file_name).captures.nil? ? false : true)
  if args[:args].is_a?(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].is_a?(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
  @downstream_buffer.max_size = 400
  @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
  @killed_externally = false
  @kill_source = nil
  @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_procsObject (readonly)

Returns the value of attribute at_exit_procs.



310
311
312
# File 'documented/common/script.rb', line 310

def at_exit_procs
  @at_exit_procs
end

#command_lineObject

Returns the value of attribute command_line.



311
312
313
# File 'documented/common/script.rb', line 311

def command_line
  @command_line
end

#current_labelObject

Returns the value of attribute current_label.



311
312
313
# File 'documented/common/script.rb', line 311

def current_label
  @current_label
end

#die_withObject

Returns the value of attribute die_with.



311
312
313
# File 'documented/common/script.rb', line 311

def die_with
  @die_with
end

#downstream_bufferObject

Returns the value of attribute downstream_buffer.



311
312
313
# File 'documented/common/script.rb', line 311

def downstream_buffer
  @downstream_buffer
end

#file_nameObject (readonly)

Returns the value of attribute file_name.



310
311
312
# File 'documented/common/script.rb', line 310

def file_name
  @file_name
end

#hiddenObject

Returns the value of attribute hidden.



311
312
313
# File 'documented/common/script.rb', line 311

def hidden
  @hidden
end

#ignore_pauseObject

Returns the value of attribute ignore_pause.



311
312
313
# File 'documented/common/script.rb', line 311

def ignore_pause
  @ignore_pause
end

#jump_labelObject

Returns the value of attribute jump_label.



311
312
313
# File 'documented/common/script.rb', line 311

def jump_label
  @jump_label
end

#kill_sourceObject

Returns the value of attribute kill_source.



311
312
313
# File 'documented/common/script.rb', line 311

def kill_source
  @kill_source
end

#killed_externallyObject

Returns the value of attribute killed_externally.



311
312
313
# File 'documented/common/script.rb', line 311

def killed_externally
  @killed_externally
end

#label_orderObject (readonly)

Returns the value of attribute label_order.



310
311
312
# File 'documented/common/script.rb', line 310

def label_order
  @label_order
end

#match_stack_labelsObject

Returns the value of attribute match_stack_labels.



311
312
313
# File 'documented/common/script.rb', line 311

def match_stack_labels
  @match_stack_labels
end

#match_stack_stringsObject

Returns the value of attribute match_stack_strings.



311
312
313
# File 'documented/common/script.rb', line 311

def match_stack_strings
  @match_stack_strings
end

#nameObject (readonly)

Returns the value of attribute name.



310
311
312
# File 'documented/common/script.rb', line 310

def name
  @name
end

#no_echoObject

Returns the value of attribute no_echo.



311
312
313
# File 'documented/common/script.rb', line 311

def no_echo
  @no_echo
end

#no_kill_allObject

Returns the value of attribute no_kill_all.



311
312
313
# File 'documented/common/script.rb', line 311

def no_kill_all
  @no_kill_all
end

#no_pause_allObject

Returns the value of attribute no_pause_all.



311
312
313
# File 'documented/common/script.rb', line 311

def no_pause_all
  @no_pause_all
end

#pausedObject

Returns the value of attribute paused.



311
312
313
# File 'documented/common/script.rb', line 311

def paused
  @paused
end

#quietObject

Returns the value of attribute quiet.



311
312
313
# File 'documented/common/script.rb', line 311

def quiet
  @quiet
end

#safeObject (readonly)

Returns the value of attribute safe.



310
311
312
# File 'documented/common/script.rb', line 310

def safe
  @safe
end

#silentObject

Returns the value of attribute silent.



311
312
313
# File 'documented/common/script.rb', line 311

def silent
  @silent
end

#unique_bufferObject

Returns the value of attribute unique_buffer.



311
312
313
# File 'documented/common/script.rb', line 311

def unique_buffer
  @unique_buffer
end

#upstream_bufferObject

Returns the value of attribute upstream_buffer.



311
312
313
# File 'documented/common/script.rb', line 311

def upstream_buffer
  @upstream_buffer
end

#varsObject (readonly)

Returns the value of attribute vars.



310
311
312
# File 'documented/common/script.rb', line 310

def vars
  @vars
end

#want_downstreamObject

Returns the value of attribute want_downstream.



311
312
313
# File 'documented/common/script.rb', line 311

def want_downstream
  @want_downstream
end

#want_downstream_xmlObject

Returns the value of attribute want_downstream_xml.



311
312
313
# File 'documented/common/script.rb', line 311

def want_downstream_xml
  @want_downstream_xml
end

#want_script_outputObject

Returns the value of attribute want_script_output.



311
312
313
# File 'documented/common/script.rb', line 311

def want_script_output
  @want_script_output
end

#want_upstreamObject

Returns the value of attribute want_upstream.



311
312
313
# File 'documented/common/script.rb', line 311

def want_upstream
  @want_upstream
end

#watchforObject

Returns the value of attribute watchfor.



311
312
313
# File 'documented/common/script.rb', line 311

def watchfor
  @watchfor
end

Instance Method Details

#at_exit(&block) ⇒ Object



758
759
760
761
762
763
764
765
766
# File 'documented/common/script.rb', line 758

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

#clearObject



839
840
841
842
843
# File 'documented/common/script.rb', line 839

def clear
  to_return = @downstream_buffer.dup
  @downstream_buffer.clear
  to_return
end

#clear_exit_procsObject



768
769
770
771
# File 'documented/common/script.rb', line 768

def clear_exit_procs
  @at_exit_procs.clear
  true
end

#custom?Boolean

Returns:

  • (Boolean)


919
920
921
# File 'documented/common/script.rb', line 919

def custom?
  @custom
end

#exitObject



773
774
775
# File 'documented/common/script.rb', line 773

def exit
  kill
end

#exit!Object



777
778
779
780
# File 'documented/common/script.rb', line 777

def exit!
  @at_exit_procs.clear
  kill
end

#feedme_upstreamObject



905
906
907
# File 'documented/common/script.rb', line 905

def feedme_upstream
  @want_upstream = !@want_upstream
end

#get_next_labelObject



820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
# File 'documented/common/script.rb', line 820

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

#getsObject



849
850
851
852
853
854
855
856
857
858
859
# File 'documented/common/script.rb', line 849

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?Boolean

Returns:

  • (Boolean)


861
862
863
864
865
866
867
868
869
870
871
872
873
# File 'documented/common/script.rb', line 861

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

Returns:

  • (Boolean)


794
795
796
# File 'documented/common/script.rb', line 794

def has_thread?(t)
  @thread_group.list.include?(t)
end

#instance_eval(*_a) ⇒ Object



784
# File 'documented/common/script.rb', line 784

def instance_eval(*_a);         nil; end

#instance_variable_get(*_a) ⇒ Object



782
# File 'documented/common/script.rb', line 782

def instance_variable_get(*_a); nil; end

#killObject



723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
# File 'documented/common/script.rb', line 723

def kill
  source = @kill_source || caller[0..2]
  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)
          unless @quiet
            if @killed_externally
              respond("--- Lich: #{@custom ? 'custom/' : ''}#{@name} was killed. (#{source.first})")
            else
              respond("--- Lich: #{@custom ? 'custom/' : ''}#{@name} has exited.")
            end
          end
          GC.start
        rescue
          respond "--- Lich: error: #{$!}"
          Lich.log "error: #{$!}\n\t#{$!.backtrace.join("\n\t")}"
        end
      end
    }
  }
  @name
end

#labelsObject



786
787
788
# File 'documented/common/script.rb', line 786

def labels
  @labels
end

#match_stack_add(label, string) ⇒ Object



909
910
911
912
# File 'documented/common/script.rb', line 909

def match_stack_add(label, string)
  @match_stack_labels.push(label)
  @match_stack_strings.push(string)
end

#match_stack_clearObject



914
915
916
917
# File 'documented/common/script.rb', line 914

def match_stack_clear
  @match_stack_labels.clear
  @match_stack_strings.clear
end

#pauseObject



798
799
800
801
802
803
804
805
# File 'documented/common/script.rb', line 798

def pause
  if @paused == true
    respond "--- Lich: #{@name} is already paused."
  else
    respond "--- Lich: #{@name} paused."
    @paused = true
  end
end

#paused?Boolean

Returns:

  • (Boolean)


816
817
818
# File 'documented/common/script.rb', line 816

def paused?
  @paused
end

#safe?Boolean

Returns:

  • (Boolean)


901
902
903
# File 'documented/common/script.rb', line 901

def safe?
  @safe
end

#thread_groupObject



790
791
792
# File 'documented/common/script.rb', line 790

def thread_group
  @thread_group
end

#to_sObject



845
846
847
# File 'documented/common/script.rb', line 845

def to_s
  @name
end

#unique_getsObject



888
889
890
891
# File 'documented/common/script.rb', line 888

def unique_gets
  sleep 0.05 while @unique_buffer.empty?
  @unique_buffer.shift
end

#unique_gets?Boolean

Returns:

  • (Boolean)


893
894
895
896
897
898
899
# File 'documented/common/script.rb', line 893

def unique_gets?
  if @unique_buffer.empty?
    nil
  else
    @unique_buffer.shift
  end
end

#unpauseObject



807
808
809
810
811
812
813
814
# File 'documented/common/script.rb', line 807

def unpause
  if @paused == true
    respond "--- Lich: #{@name} unpaused."
    @paused = false
  else
    respond "--- Lich: #{@name} is not paused."
  end
end

#upstream_getsObject



875
876
877
878
# File 'documented/common/script.rb', line 875

def upstream_gets
  sleep 0.05 while @upstream_buffer.empty?
  @upstream_buffer.shift
end

#upstream_gets?Boolean

Returns:

  • (Boolean)


880
881
882
883
884
885
886
# File 'documented/common/script.rb', line 880

def upstream_gets?
  if @upstream_buffer.empty?
    nil
  else
    @upstream_buffer.shift
  end
end