Module: Lich::Common::Frontend
- Defined in:
- documented/common/front-end.rb,
documented/common/front-end.rb
Overview
Frontend registry and capabilities system for client identification.
Manages a registry of game frontends (e.g., Wrayth, Saga, Wizard) with their capabilities and discovery metadata. Scripts query this module to check frontend features and access the current client identity.
Constant Summary collapse
- PLATFORM_KEYS =
Canonical platform identifiers used in discovery and launch plans.
%i[darwin linux windows unsupported].freeze
- ORIGIN_SENTINEL =
"\x1f"- SAGA_LICH_LAUNCH_ENVIRONMENT =
Environment variables passed to Saga during launch via the launcher adapter.
Tokens like
%host%,%port%, and%key%are substituted by the launcher with values from the connection context. { 'SAGA_LICH_MODE' => '1', 'SAGA_LICH_HOST' => '%host%', 'SAGA_LICH_PORT' => '%port%', 'SAGA_LICH_KEY' => '%key%' }.freeze
- CLIENT_STRING =
--- Client String ----------------------------------------- Default client string (Wrayth identity) sent during handshake
"/FE:WRAYTH /VERSION:1.0.1.28 /P:WIN_UNKNOWN /XML"- XML_FRONTENDS =
--- Backward-Compatible Constants ------------------------- These arrays are derived from the registry for backward compatibility. External code may still reference these constants directly.
frontends_with_capability(:xml).freeze
- GSL_FRONTENDS =
Deprecated: list of frontends supporting GSL.
For backward compatibility. New code should call
.frontends_with_capability(:gsl)or check a specific frontend with.has_capability?(name, :gsl). frontends_with_capability(:gsl).freeze
- STREAM_FRONTENDS =
Deprecated: list of frontends supporting XML streams.
For backward compatibility. New code should call
.frontends_with_capability(:streams)or check a specific frontend with.has_capability?(name, :streams). frontends_with_capability(:streams).freeze
- MONO_FRONTENDS =
Deprecated: list of frontends supporting monospace rendering.
For backward compatibility. New code should call
.frontends_with_capability(:mono)or check a specific frontend with.has_capability?(name, :mono). frontends_with_capability(:mono).freeze
- SENTINEL_FRONTENDS =
Deprecated: list of frontends supporting sentinel tags.
For backward compatibility. New code should call
.frontends_with_capability(:sentinel)or check a specific frontend with.has_capability?(name, :sentinel). frontends_with_capability(:sentinel).freeze
Class Method Summary collapse
-
.canonical_name(frontend_name) ⇒ String
Returns the stable catalog identifier for a frontend or alias.
-
.cleanup_session_file ⇒ void
Deletes the session descriptor file if it exists.
-
.client ⇒ Object
Accessor for the current frontend identity ($frontend global).
-
.client=(value) ⇒ Object
Setter for the current frontend identity.
-
.create_session_file(name, host, port, display_session: true) ⇒ void
Writes a session descriptor to a temporary file for detachable clients.
-
.definition_for(frontend_name) ⇒ Hash
Returns an immutable catalog definition for a registered frontend.
-
.definitions(gui_selectable: nil) ⇒ Array<Hash>
Returns immutable catalog definitions, optionally restricted to those intended for the graphical launcher.
-
.detect_pid ⇒ Integer?
Detect and store the frontend process ID Uses various methods depending on how Lich was launched.
-
.detect_platform ⇒ Symbol
Detect the current platform.
-
.display_name(frontend_name) ⇒ String
Returns the catalog display name, with a stable fallback for legacy saved entries that predate the catalog.
-
.ensure_windows_modules ⇒ Object
Ensure Windows modules are loaded (they're defined at top level).
-
.frontends_with_capability(capability) ⇒ Array<String>
Returns all frontends that have a specific capability.
-
.has_capability?(frontend_name, capability) ⇒ Boolean
Checks if a frontend has a specific capability.
-
.init_from_parent(parent_pid) ⇒ Integer?
Initialize PID from parent process (for Warlock).
-
.metadata_for(frontend_name, key) ⇒ Object?
Retrieves a metadata value for a given frontend.
-
.native_windows_runtime? ⇒ Boolean
Native user32 bindings require a Windows MRI ABI, not merely a Windows host.
-
.pid ⇒ Integer?
Get the current frontend PID.
-
.pid=(value) ⇒ Integer
Set the frontend PID.
-
.platform_key ⇒ Symbol
Returns the canonical platform key used by frontend discovery and launch-plan metadata.
-
.player_id_tag(player_id) ⇒ Object
Build the
re-emit tag for a detachable client (e.g. Saga). -
.refocus ⇒ Boolean
Refocus the frontend window.
-
.refocus_callback ⇒ Proc
Create a callback for GTK windows to refocus on click.
-
.refocus_linux(pid) ⇒ Object
Linux refocus implementation.
-
.refocus_macos(pid) ⇒ Object
macOS refocus implementation.
-
.refocus_windows(pid) ⇒ Object
Windows refocus implementation.
-
.register(name, capabilities: [], metadata: {}) ⇒ Object
Registers a frontend with its capabilities and metadata.
-
.registered_frontends ⇒ Array<String>
Returns every recognized frontend name: canonical catalog identifiers followed by their accepted aliases.
-
.resolve_linux_pid(pid) ⇒ Object
Linux-specific PID resolution.
-
.resolve_pid(pid) ⇒ Integer
Resolve PID by walking up process tree to find window owner.
-
.resolve_windows_pid(pid) ⇒ Object
Windows-specific PID resolution.
-
.send_handshake(version_string) ⇒ Object
Send version string, ready signals, and setup commands to the game server.
-
.session_file_location ⇒ String?
Returns the path to the session descriptor file, or nil if not yet created.
-
.set_from_client(pid) ⇒ Integer
Set PID from a detachable frontend such as Profanity or Saga.
-
.supports_gsl?(fe = $frontend) ⇒ Boolean
Checks whether a frontend supports GSL (game scripting language).
-
.supports_mono?(fe = $frontend) ⇒ Boolean
Checks whether a frontend supports monospace rendering.
-
.supports_room_window?(fe = $frontend) ⇒ Boolean
Checks whether a frontend supports a dedicated room window.
-
.supports_sentinel?(fe = $frontend) ⇒ Boolean
Checks whether a frontend supports sentinel tags (detachable client protocol).
-
.supports_streams?(fe = $frontend) ⇒ Boolean
Checks whether a frontend supports XML stream output.
-
.supports_xml?(fe = $frontend) ⇒ Boolean
Checks whether a frontend supports XML protocol.
-
.validate_platform_key!(key) ⇒ Symbol
Validates a canonical platform key used by discovery and launch plans.
-
.windows_parent_pid(wmi, pid) ⇒ Object
Get parent process ID on Windows.
-
.windows_platform? ⇒ Boolean
Returns whether the current host is classified as Windows.
Class Method Details
.canonical_name(frontend_name) ⇒ String
Returns the stable catalog identifier for a frontend or alias. Unknown values are normalized but are not registered.
125 126 127 128 |
# File 'documented/common/front-end.rb', line 125 def self.canonical_name(frontend_name) key = frontend_name.to_s.downcase @aliases.fetch(key, key) end |
.cleanup_session_file ⇒ void
This method returns an undefined value.
Deletes the session descriptor file if it exists.
Called during shutdown to clean up temporary launch artifacts.
550 551 552 553 |
# File 'documented/common/front-end.rb', line 550 def self.cleanup_session_file return if @session_file.nil? File.delete(@session_file) if File.exist? @session_file end |
.client ⇒ Object
Accessor for the current frontend identity ($frontend global)
484 485 486 |
# File 'documented/common/front-end.rb', line 484 def self.client $frontend end |
.client=(value) ⇒ Object
Setter for the current frontend identity
489 490 491 |
# File 'documented/common/front-end.rb', line 489 def self.client=(value) $frontend = value end |
.create_session_file(name, host, port, display_session: true) ⇒ void
This method returns an undefined value.
Writes a session descriptor to a temporary file for detachable clients.
Creates the directory structure under the system temp folder
($TMPDIR/simutronics/sessions/) and writes a JSON file with the session
details. Used by launcher adapters to hand off connection info to frontends
like Saga.
525 526 527 528 529 530 531 532 533 534 |
# File 'documented/common/front-end.rb', line 525 def self.create_session_file(name, host, port, display_session: true) return if name.nil? FileUtils.mkdir_p @tmp_session_dir @session_file = File.join(@tmp_session_dir, "%s.session" % name.downcase.capitalize) session_descriptor = { name: name, host: host, port: port }.to_json puts "writing session descriptor to %s\n%s" % [@session_file, session_descriptor] if display_session File.open(@session_file, "w") do |fd| fd << session_descriptor end end |
.definition_for(frontend_name) ⇒ Hash
Returns an immutable catalog definition for a registered frontend.
Accepted inputs are a non-empty String or Symbol naming an existing registry entry. Invalid or unknown identifiers raise ArgumentError. This method performs no discovery and persists nothing.
161 162 163 164 165 166 167 168 169 170 171 172 173 |
# File 'documented/common/front-end.rb', line 161 def self.definition_for(frontend_name) key = canonical_name(frontend_name) raise ArgumentError, 'frontend name must not be empty' if key.empty? raise ArgumentError, "unknown frontend: #{frontend_name}" unless @registry.key?(key) @definitions[key] ||= Lich::Util.deep_freeze( { id: key, capabilities: @registry.fetch(key)[:capabilities].to_a, metadata: deep_copy(@registry.fetch(key)[:metadata]) } ) end |
.definitions(gui_selectable: nil) ⇒ Array<Hash>
Returns immutable catalog definitions, optionally restricted to those intended for the graphical launcher.
180 181 182 183 184 185 186 187 |
# File 'documented/common/front-end.rb', line 180 def self.definitions(gui_selectable: nil) definitions = @registry.keys.map { |name| definition_for(name) } return definitions if gui_selectable.nil? definitions.select do |definition| definition.dig(:metadata, :gui_selectable) == gui_selectable end end |
.detect_pid ⇒ Integer?
Detect and store the frontend process ID Uses various methods depending on how Lich was launched
613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 |
# File 'documented/common/front-end.rb', line 613 def self.detect_pid # Return existing PID if already set current_pid = self.pid return current_pid if current_pid && current_pid > 0 # Try to detect based on launch method # This is a fallback for cases where init wasn't called parent_pid = Process.ppid resolved_pid = resolve_pid(parent_pid) if resolved_pid && resolved_pid > 0 self.pid = resolved_pid Lich.log "Frontend PID detected (fallback): #{resolved_pid}" if defined?(Lich.log) resolved_pid else Lich.log "Failed to detect frontend PID" if defined?(Lich.log) nil end end |
.detect_platform ⇒ Symbol
Detect the current platform
665 666 667 668 |
# File 'documented/common/front-end.rb', line 665 def self.detect_platform key = platform_key key == :darwin ? :macos : key end |
.display_name(frontend_name) ⇒ String
Returns the catalog display name, with a stable fallback for legacy saved entries that predate the catalog.
224 225 226 227 228 |
# File 'documented/common/front-end.rb', line 224 def self.display_name(frontend_name) definition_for(frontend_name).dig(:metadata, :display_name) || frontend_name.to_s.capitalize rescue ArgumentError frontend_name.to_s.capitalize end |
.ensure_windows_modules ⇒ Object
Ensure Windows modules are loaded (they're defined at top level)
853 854 855 856 857 |
# File 'documented/common/front-end.rb', line 853 def self.ensure_windows_modules return false unless native_windows_runtime? defined?(::Win32Enum) && defined?(::WinAPI) end |
.frontends_with_capability(capability) ⇒ Array<String>
Returns all frontends that have a specific capability.
240 241 242 243 244 245 246 |
# File 'documented/common/front-end.rb', line 240 def self.frontends_with_capability(capability) canonical = @registry.select { |_name, data| data[:capabilities].include?(capability.to_sym) }.keys aliases = @aliases.filter_map do |alias_name, name| alias_name if canonical.include?(name) end canonical + aliases end |
.has_capability?(frontend_name, capability) ⇒ Boolean
Checks if a frontend has a specific capability.
134 135 136 137 138 139 |
# File 'documented/common/front-end.rb', line 134 def self.has_capability?(frontend_name, capability) return false if frontend_name.nil? entry = @registry[canonical_name(frontend_name)] entry ? entry[:capabilities].include?(capability.to_sym) : false end |
.init_from_parent(parent_pid) ⇒ Integer?
Initialize PID from parent process (for Warlock)
573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 |
# File 'documented/common/front-end.rb', line 573 def self.init_from_parent(parent_pid) Lich.log "=== Frontend.init_from_parent called ===" Lich.log "Parent process PID: #{parent_pid}" # Let's see what process this actually is on Windows if windows_platform? begin require 'win32ole' wmi = WIN32OLE.connect('winmgmts://') rows = wmi.ExecQuery("SELECT Name, ProcessId FROM Win32_Process WHERE ProcessId=#{parent_pid}") row = rows.each.first rescue nil if row Lich.log "Parent process name: #{row.Name}" end rescue StandardError, LoadError => e Lich.log "Could not get parent process name: #{e.}" end end resolved_pid = resolve_pid(parent_pid) Lich.log "resolve_pid(#{parent_pid}) returned: #{resolved_pid}" self.pid = resolved_pid Lich.log "Frontend PID set to: #{self.pid}" resolved_pid end |
.metadata_for(frontend_name, key) ⇒ Object?
Retrieves a metadata value for a given frontend.
145 146 147 148 149 150 |
# File 'documented/common/front-end.rb', line 145 def self.(frontend_name, key) return nil if frontend_name.nil? entry = @registry[canonical_name(frontend_name)] entry && entry[:metadata][key] end |
.native_windows_runtime? ⇒ Boolean
Native user32 bindings require a Windows MRI ABI, not merely a Windows host.
31 32 33 |
# File 'documented/common/front-end.rb', line 31 def self.native_windows_runtime? OS.host_os.to_s.match?(/mingw|mswin/i) end |
.pid ⇒ Integer?
Get the current frontend PID
559 560 561 |
# File 'documented/common/front-end.rb', line 559 def self.pid @pid_mutex.synchronize { @frontend_pid } end |
.pid=(value) ⇒ Integer
Set the frontend PID
566 567 568 569 |
# File 'documented/common/front-end.rb', line 566 def self.pid=(value) value = value.to_i @pid_mutex.synchronize { @frontend_pid = value } end |
.platform_key ⇒ Symbol
Returns the canonical platform key used by frontend discovery and launch-plan metadata.
193 194 195 196 197 198 199 |
# File 'documented/common/front-end.rb', line 193 def self.platform_key return :darwin if OS.mac? return :linux if OS.linux? return :windows if OS.windows? :unsupported end |
.player_id_tag(player_id) ⇒ Object
Build the
Lich consumes the game's one-time
Returns the tag string only when player_id is a bare numeric id (the form the game sends). Returns nil otherwise, so callers skip emitting an empty or malformed tag before login has populated the id.
476 477 478 479 480 481 |
# File 'documented/common/front-end.rb', line 476 def self.player_id_tag(player_id) id = player_id.to_s return nil unless id =~ /\A\d+\z/ "<playerID id='#{id}'/>" end |
.refocus ⇒ Boolean
Refocus the frontend window
635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 |
# File 'documented/common/front-end.rb', line 635 def self.refocus pid = self.pid return false unless pid && pid > 0 case detect_platform when :windows refocus_windows(pid) when :macos refocus_macos(pid) when :linux refocus_linux(pid) else false end end |
.refocus_callback ⇒ Proc
Create a callback for GTK windows to refocus on click
653 654 655 656 657 658 659 660 661 |
# File 'documented/common/front-end.rb', line 653 def self.refocus_callback proc { if defined?(GLib) && GLib.respond_to?(:Idle) GLib::Idle.add(50) { self.refocus; false } else self.refocus end } end |
.refocus_linux(pid) ⇒ Object
Linux refocus implementation
836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 |
# File 'documented/common/front-end.rb', line 836 def self.refocus_linux(pid) return false unless system('which xdotool > /dev/null 2>&1') _stdout, stderr, status = Open3.capture3('xdotool', 'search', '--pid', pid.to_s, 'windowactivate') if status.success? true else Lich.log "Error refocusing Linux: #{stderr}" if defined?(Lich.log) false end rescue => e Lich.log "Error refocusing Linux: #{e}" if defined?(Lich.log) false end |
.refocus_macos(pid) ⇒ Object
macOS refocus implementation
818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 |
# File 'documented/common/front-end.rb', line 818 def self.refocus_macos(pid) return false unless system('which osascript > /dev/null 2>&1') script = %{tell application "System Events" to set frontmost of (first process whose unix id is #{pid}) to true} _stdout, stderr, status = Open3.capture3('osascript', '-e', script) if status.success? true else Lich.log "Error refocusing macOS: #{stderr}" if defined?(Lich.log) false end rescue => e Lich.log "Error refocusing macOS: #{e}" if defined?(Lich.log) false end |
.refocus_windows(pid) ⇒ Object
Windows refocus implementation
779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 |
# File 'documented/common/front-end.rb', line 779 def self.refocus_windows(pid) ensure_windows_modules hwnd_buf = Fiddle::Pointer.malloc(Fiddle::SIZEOF_VOIDP) enum_cb = Fiddle::Closure::BlockCaller.new( Fiddle::TYPE_INT, [Fiddle::TYPE_VOIDP, Fiddle::TYPE_LONG] ) do |hwnd, _| next 1 if ::WinAPI.IsWindowVisible(hwnd).zero? pid_tmp = [0].pack('L') ::WinAPI.GetWindowThreadProcessId(hwnd, pid_tmp) win_pid = pid_tmp.unpack1('L') if win_pid == pid hwnd_buf[0, Fiddle::SIZEOF_VOIDP] = [hwnd].pack('L!') 0 # stop enumeration else 1 # continue enumeration end end ::WinAPI.EnumWindows(enum_cb, 0) hwnd = hwnd_buf[0, Fiddle::SIZEOF_VOIDP].unpack1('L!') if hwnd != 0 ::WinAPI.SetForegroundWindow(hwnd) true else Lich.log "Frontend window for PID #{pid} not found" if defined?(Lich.log) false end rescue => e Lich.log "Error refocusing Windows: #{e}" if defined?(Lich.log) false end |
.register(name, capabilities: [], metadata: {}) ⇒ Object
Registers a frontend with its capabilities and metadata.
109 110 111 112 113 114 115 116 117 118 |
# File 'documented/common/front-end.rb', line 109 def self.register(name, capabilities: [], metadata: {}) key = name.to_s.downcase raise ArgumentError, 'frontend name must not be empty' if key.empty? entry = (@registry[key] ||= { capabilities: Set.new, metadata: {} }) entry[:capabilities].merge(capabilities.map(&:to_sym)) entry[:metadata].merge!(deep_copy()) Array([:aliases]).each { |alias_name| @aliases[alias_name.to_s.downcase] = key } @definitions.delete(key) end |
.registered_frontends ⇒ Array<String>
Returns every recognized frontend name: canonical catalog identifiers followed by their accepted aliases.
233 234 235 |
# File 'documented/common/front-end.rb', line 233 def self.registered_frontends @registry.keys + @aliases.keys end |
.resolve_linux_pid(pid) ⇒ Object
Linux-specific PID resolution
753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 |
# File 'documented/common/front-end.rb', line 753 def self.resolve_linux_pid(pid) return pid unless system('which xdotool > /dev/null 2>&1') p = pid 16.times do # Check if this process has a window return p if system("xdotool search --pid #{p} >/dev/null 2>&1") # Walk up to parent process begin status = File.read("/proc/#{p}/status") parent = status[/PPid:\s+(\d+)/, 1].to_i rescue parent = 0 end return pid if parent.zero? || parent == p p = parent end pid # fallback rescue => e Lich.log "Error resolving Linux PID: #{e}" if defined?(Lich.log) pid end |
.resolve_pid(pid) ⇒ Integer
Resolve PID by walking up process tree to find window owner
673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 |
# File 'documented/common/front-end.rb', line 673 def self.resolve_pid(pid) pid = pid.to_i return pid if pid <= 0 # Return as-is if invalid # Use the FrontendPID resolver logic case detect_platform when :windows resolve_windows_pid(pid) when :linux resolve_linux_pid(pid) else # macOS/other: PID usually already owns the window pid end end |
.resolve_windows_pid(pid) ⇒ Object
Windows-specific PID resolution
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 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 |
# File 'documented/common/front-end.rb', line 690 def self.resolve_windows_pid(pid) Lich.log "=== resolve_windows_pid starting with PID: #{pid} ===" ensure_windows_modules require 'win32ole' rescue (return pid) begin wmi = WIN32OLE.connect('winmgmts://') p = pid 16.times do # Get process name for debugging rows = wmi.ExecQuery("SELECT Name FROM Win32_Process WHERE ProcessId=#{p}") row = rows.each.first rescue nil process_name = row ? row.Name : "unknown" Lich.log " Process name: #{process_name}" # Check if this process owns any visible window found = false cb = Fiddle::Closure::BlockCaller.new( Fiddle::TYPE_INT, [Fiddle::TYPE_VOIDP, Fiddle::TYPE_LONG] ) do |hwnd, _| next 1 if ::Win32Enum.IsWindowVisible(hwnd).zero? buf = [0].pack('L') ::Win32Enum.GetWindowThreadProcessId(hwnd, buf) if buf.unpack1('L') == p found = true Lich.log " Found visible window for PID #{p}" 0 # stop enumeration else 1 # continue enumeration end end ::Win32Enum.EnumWindows(cb, 0) if found Lich.log " Stopping at PID #{p} (#{process_name}) - has visible window" return p end # Walk up to parent process parent = windows_parent_pid(wmi, p) break if parent.nil? || parent.zero? || parent == p p = parent end rescue => e Lich.log "ERROR in resolve_windows_pid: #{e}" end Lich.log "Fallback: returning original PID #{pid}" pid end |
.send_handshake(version_string) ⇒ Object
Send version string, ready signals, and setup commands to the game server. Used during login handshake for wizard/avalon/frostbite frontends.
495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 |
# File 'documented/common/front-end.rb', line 495 def self.send_handshake(version_string) $_CLIENTBUFFER_.push(version_string.dup) Game._puts(version_string) 2.times do sleep 0.3 $_CLIENTBUFFER_.push("#{$cmd_prefix}\r\n") Game._puts($cmd_prefix) end ["#{$cmd_prefix}_injury 2", "#{$cmd_prefix}_flag Display Inventory Boxes 1", "#{$cmd_prefix}_flag Display Dialog Boxes 0"].each do |cmd| $_CLIENTBUFFER_.push(cmd) Game._puts(cmd) end end |
.session_file_location ⇒ String?
Returns the path to the session descriptor file, or nil if not yet created.
540 541 542 |
# File 'documented/common/front-end.rb', line 540 def self.session_file_location @session_file end |
.set_from_client(pid) ⇒ Integer
Set PID from a detachable frontend such as Profanity or Saga.
604 605 606 607 608 |
# File 'documented/common/front-end.rb', line 604 def self.set_from_client(pid) self.pid = pid Lich.log "Frontend PID set from client: #{pid}" if defined?(Lich.log) pid end |
.supports_gsl?(fe = $frontend) ⇒ Boolean
Checks whether a frontend supports GSL (game scripting language).
422 423 424 |
# File 'documented/common/front-end.rb', line 422 def self.supports_gsl?(fe = $frontend) has_capability?(fe, :gsl) end |
.supports_mono?(fe = $frontend) ⇒ Boolean
Checks whether a frontend supports monospace rendering.
442 443 444 |
# File 'documented/common/front-end.rb', line 442 def self.supports_mono?(fe = $frontend) has_capability?(fe, :mono) end |
.supports_room_window?(fe = $frontend) ⇒ Boolean
Checks whether a frontend supports a dedicated room window.
452 453 454 |
# File 'documented/common/front-end.rb', line 452 def self.supports_room_window?(fe = $frontend) has_capability?(fe, :room_window) end |
.supports_sentinel?(fe = $frontend) ⇒ Boolean
Checks whether a frontend supports sentinel tags (detachable client protocol).
462 463 464 |
# File 'documented/common/front-end.rb', line 462 def self.supports_sentinel?(fe = $frontend) has_capability?(fe, :sentinel) end |
.supports_streams?(fe = $frontend) ⇒ Boolean
Checks whether a frontend supports XML stream output.
432 433 434 |
# File 'documented/common/front-end.rb', line 432 def self.supports_streams?(fe = $frontend) has_capability?(fe, :streams) end |
.supports_xml?(fe = $frontend) ⇒ Boolean
Checks whether a frontend supports XML protocol.
412 413 414 |
# File 'documented/common/front-end.rb', line 412 def self.supports_xml?(fe = $frontend) has_capability?(fe, :xml) end |
.validate_platform_key!(key) ⇒ Symbol
Validates a canonical platform key used by discovery and launch plans.
206 207 208 209 210 |
# File 'documented/common/front-end.rb', line 206 def self.validate_platform_key!(key) return key if PLATFORM_KEYS.include?(key) raise ArgumentError, "invalid platform key: #{key.inspect}" end |
.windows_parent_pid(wmi, pid) ⇒ Object
Get parent process ID on Windows
746 747 748 749 750 |
# File 'documented/common/front-end.rb', line 746 def self.windows_parent_pid(wmi, pid) rows = wmi.ExecQuery("SELECT ParentProcessId FROM Win32_Process WHERE ProcessId=#{pid}") row = rows.each.first rescue nil row ? row.ParentProcessId.to_i : 0 end |
.windows_platform? ⇒ Boolean
Returns whether the current host is classified as Windows.
215 216 217 |
# File 'documented/common/front-end.rb', line 215 def self.windows_platform? platform_key == :windows end |