Module: Lich

Included in:
DragonRealms, Gemstone
Defined in:
documented/lich.rb,
documented/vars.rb,
documented/games.rb,
documented/stash.rb,
documented/update.rb,
documented/messaging.rb,
documented/util/opts.rb,
documented/util/util.rb,
documented/common/gtk.rb,
documented/common/hmr.rb,
documented/common/log.rb,
documented/magic-info.rb,
documented/common/vars.rb,
documented/gemstone/sk.rb,
documented/common/spell.rb,
documented/common/buffer.rb,
documented/common/script.rb,
documented/gemstone/disk.rb,
documented/gemstone/gift.rb,
documented/gemstone/psms.rb,
documented/common/account.rb,
documented/common/eaccess.rb,
documented/common/gameobj.rb,
documented/gemstone/claim.rb,
documented/gemstone/group.rb,
documented/gemstone/scars.rb,
documented/attributes/char.rb,
documented/common/db_store.rb,
documented/common/settings.rb,
documented/common/uservars.rb,
documented/common/watchfor.rb,
documented/gemstone/bounty.rb,
documented/gemstone/wounds.rb,
documented/attributes/stats.rb,
documented/common/front-end.rb,
documented/common/gui-login.rb,
documented/common/gui/state.rb,
documented/common/xmlparser.rb,
documented/gemstone/effects.rb,
documented/gemstone/infomon.rb,
documented/gemstone/injured.rb,
documented/gemstone/society.rb,
documented/attributes/skills.rb,
documented/attributes/spells.rb,
documented/common/map/map_dr.rb,
documented/common/map/map_gs.rb,
documented/gemstone/creature.rb,
documented/gemstone/currency.rb,
documented/gemstone/stowlist.rb,
documented/main/argv_options.rb,
documented/util/textstripper.rb,
documented/common/game-loader.rb,
documented/gemstone/armaments.rb,
documented/gemstone/critranks.rb,
documented/gemstone/psms/cman.rb,
documented/gemstone/psms/feat.rb,
documented/gemstone/readylist.rb,
documented/util/login_helpers.rb,
documented/common/limitedarray.rb,
documented/common/sharedbuffer.rb,
documented/common/upstreamhook.rb,
documented/gemstone/experience.rb,
documented/gemstone/psms/armor.rb,
documented/gemstone/spellranks.rb,
documented/util/memoryreleaser.rb,
documented/attributes/enhancive.rb,
documented/attributes/resources.rb,
documented/attributes/spellsong.rb,
documented/common/cli/cli_login.rb,
documented/common/gui/utilities.rb,
documented/gemstone/bounty/task.rb,
documented/gemstone/infomon/cli.rb,
documented/gemstone/psms/shield.rb,
documented/gemstone/psms/warcry.rb,
documented/gemstone/psms/weapon.rb,
documented/common/downstreamhook.rb,
documented/common/gui/components.rb,
documented/common/gui/yaml_state.rb,
documented/gemstone/psms/qstrike.rb,
documented/common/gui/theme_utils.rb,
documented/dragonrealms/drinfomon.rb,
documented/gemstone/bounty/parser.rb,
documented/gemstone/combat/parser.rb,
documented/gemstone/infomon/cache.rb,
documented/gemstone/combat/tracker.rb,
documented/gemstone/infomon/parser.rb,
documented/gemstone/infomon/status.rb,
documented/gemstone/psms/ascension.rb,
documented/common/gui/accessibility.rb,
documented/common/gui/conversion_ui.rb,
documented/gemstone/combat/defs/ucs.rb,
documented/common/cli/cli_conversion.rb,
documented/common/gui/authentication.rb,
documented/common/gui/game_selection.rb,
documented/common/socketconfigurator.rb,
documented/gemstone/combat/processor.rb,
documented/gemstone/infomon/currency.rb,
documented/common/gui/account_manager.rb,
documented/common/gui/login_tab_utils.rb,
documented/common/gui/password_change.rb,
documented/common/gui/password_cipher.rb,
documented/common/gui/saved_login_tab.rb,
documented/gemstone/infomon/xmlparser.rb,
documented/common/gui/manual_login_tab.rb,
documented/common/gui/password_manager.rb,
documented/common/gui/tab_communicator.rb,
documented/dragonrealms/commons/common.rb,
documented/gemstone/combat/defs/damage.rb,
documented/common/class_exts/stringproc.rb,
documented/common/cli/cli_orchestration.rb,
documented/common/gui/favorites_manager.rb,
documented/common/gui/parameter_objects.rb,
documented/common/settings/charsettings.rb,
documented/common/settings/gamesettings.rb,
documented/gemstone/combat/defs/attacks.rb,
documented/gemstone/infomon/activespell.rb,
documented/common/gui/account_manager_ui.rb,
documented/dragonrealms/commons/slackbot.rb,
documented/dragonrealms/drinfomon/drdefs.rb,
documented/dragonrealms/drinfomon/drroom.rb,
documented/dragonrealms/drinfomon/events.rb,
documented/gemstone/combat/defs/statuses.rb,
documented/common/settings/path_navigator.rb,
documented/common/settings/settings_proxy.rb,
documented/dragonrealms/drinfomon/drskill.rb,
documented/dragonrealms/drinfomon/drstats.rb,
documented/gemstone/armaments/armor_stats.rb,
documented/common/cli/cli_options_registry.rb,
documented/common/cli/cli_password_manager.rb,
documented/dragonrealms/drinfomon/drparser.rb,
documented/dragonrealms/drinfomon/drspells.rb,
documented/gemstone/armaments/shield_stats.rb,
documented/gemstone/armaments/weapon_stats.rb,
documented/gemstone/combat/async_processor.rb,
documented/common/settings/database_adapter.rb,
documented/gemstone/societies/order_of_voln.rb,
documented/common/gui/encryption_mode_change.rb,
documented/common/gui/master_password_change.rb,
documented/common/gui/master_password_prompt.rb,
documented/dragonrealms/commons/common-items.rb,
documented/dragonrealms/commons/common-money.rb,
documented/dragonrealms/commons/equipmanager.rb,
documented/common/gui/master_password_manager.rb,
documented/dragonrealms/commons/common-arcana.rb,
documented/dragonrealms/commons/common-travel.rb,
documented/dragonrealms/drinfomon/drvariables.rb,
documented/dragonrealms/commons/common-healing.rb,
documented/dragonrealms/commons/common-theurgy.rb,
documented/gemstone/societies/council_of_light.rb,
documented/common/class_exts/synchronizedsocket.rb,
documented/common/gui/master_password_prompt_ui.rb,
documented/dragonrealms/commons/common-crafting.rb,
documented/dragonrealms/commons/common-moonmage.rb,
documented/common/cli/cli_encryption_mode_change.rb,
documented/common/gui/windows_credential_manager.rb,
documented/dragonrealms/commons/common-summoning.rb,
documented/gemstone/armaments/weapon_stats_blunt.rb,
documented/gemstone/armaments/weapon_stats_edged.rb,
documented/dragonrealms/commons/common-validation.rb,
documented/gemstone/armaments/weapon_stats_hybrid.rb,
documented/gemstone/armaments/weapon_stats_ranged.rb,
documented/gemstone/armaments/weapon_stats_thrown.rb,
documented/gemstone/armaments/weapon_stats_natural.rb,
documented/gemstone/armaments/weapon_stats_polearm.rb,
documented/gemstone/armaments/weapon_stats_unarmed.rb,
documented/gemstone/societies/guardians_of_sunfist.rb,
documented/dragonrealms/commons/common-healing-data.rb,
documented/gemstone/armaments/weapon_stats_brawling.rb,
documented/gemstone/armaments/weapon_stats_runestave.rb,
documented/gemstone/armaments/weapon_stats_two_handed.rb

Overview

Provides utility functions for the Lich project.

Examples:

Usage

Lich::Common::GUI::WindowsCredentialManager.store_credential("target", "user", "pass")

Defined Under Namespace

Modules: Claim, Common, Currency, DragonRealms, GameBase, Gemstone, Main, Messaging, Resources, Stash, Unknown, Util

Constant Summary collapse

@@hosts_file =
nil
@@lich_db =
nil
@@last_warn_deprecated =
0
@@deprecated_log =
[]
@@display_lichid =

settings

nil
@@display_uid =

boolean

nil
@@display_exits =

boolean

nil
@@display_stringprocs =

boolean

nil
@@hide_uid_flag =

boolean

nil
@@track_autosort_state =

boolean

nil
@@track_dark_mode =

boolean

nil
@@track_layout_state =

boolean

nil
@@debug_messaging =

boolean

nil

Class Method Summary collapse

Class Method Details

.break_game_host_port(gamehost, gameport) ⇒ Array

Breaks the game host and port back to their original values based on known mappings.

Examples:

broken = Lich.break_game_host_port("storm.gs4.game.play.net", 10324)

Parameters:

  • gamehost (String)

    The game host to break.

  • gameport (Integer)

    The game port to break.

Returns:

  • (Array)

    The broken game host and port.



824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
# File 'documented/lich.rb', line 824

def Lich.break_game_host_port(gamehost, gameport)
  if (gamehost == 'storm.gs4.game.play.net') and (gameport.to_i == 10324)
    gamehost = 'gs4.simutronics.net'
    gameport = 10321
  elsif (gamehost == 'storm.gs4.game.play.net') and (gameport.to_i == 10124)
    gamehost = 'gs-plat.simutronics.net'
    gameport = 10121
  elsif (gamehost == 'storm.gs4.game.play.net') and (gameport.to_i == 10024)
    gamehost = 'gs3.simutronics.net'
    gameport = 4900
  elsif (gamehost == 'dr.simutronics.net') and (gameport.to_i == 11024)
    gamehost = 'prime.dr.game.play.net'
    gameport = 4901
  end
  [gamehost, gameport]
end

.class_eval(*_a) ⇒ Object



230
# File 'documented/lich.rb', line 230

def Lich.class_eval(*_a);         nil; end

.class_variable_get(*_a) ⇒ Object



228
# File 'documented/lich.rb', line 228

def Lich.class_variable_get(*_a); nil; end

.core_updated_with_lich_versionString

Retrieves the core updated with Lich version setting from the database.

Examples:

version = Lich.core_updated_with_lich_version

Returns:

  • (String)

    The version or nil if not found.



945
946
947
948
949
950
951
952
953
# File 'documented/lich.rb', line 945

def Lich.core_updated_with_lich_version
  begin
    val = Lich.db.get_first_value("SELECT value FROM lich_settings WHERE name='core_updated_with_lich_version';")
  rescue SQLite3::BusyException
    sleep 0.1
    retry
  end
  return val.to_s
end

.core_updated_with_lich_version=(val) ⇒ Object

Sets the core updated with Lich version in the database.

Examples:

Lich.core_updated_with_lich_version = "1.0.0"

Parameters:

  • val (String)

    The version to set.

Raises:

  • (SQLite3::BusyException)

    If the database is busy.



960
961
962
963
964
965
966
967
# File 'documented/lich.rb', line 960

def Lich.core_updated_with_lich_version=(val)
  begin
    Lich.db.execute("INSERT OR REPLACE INTO lich_settings(name,value) values('core_updated_with_lich_version',?);", [val.to_s.encode('UTF-8')])
  rescue SQLite3::BusyException
    sleep 0.1
    retry
  end
end

.dbObject



207
208
209
# File 'documented/lich.rb', line 207

def Lich.db
  @@lich_db ||= SQLite3::Database.new("#{DATA_DIR}/lich.db3")
end

.db_maint_due?(months = 6) ⇒ Boolean

Checks if the database maintenance is due based on the last maintenance timestamp.

Examples:

due = Lich.db_maint_due?(12)

Parameters:

  • months (Integer) (defaults to: 6)

    The number of months to check against (default is 6).

Returns:

  • (Boolean)

    True if maintenance is due, false otherwise.

Raises:

  • (StandardError)

    If there is an error parsing the timestamp.



57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'documented/lich.rb', line 57

def Lich.db_maint_due?(months = 6)
  last = Lich.db_maint_last_at
  return true if last.nil? || last.empty?
  begin
    cutoff = Time.now.utc - (months * 30 * 24 * 60 * 60)
    last_t = Time.parse(last) rescue nil
    return true if last_t.nil?
    last_t < cutoff
  rescue => e
    Lich.log "db_maint_due? parse error: #{e}"
    true
  end
end

.db_maint_last_atString?

Retrieves the last maintenance timestamp from the database.

Examples:

last_at = Lich.db_maint_last_at

Returns:

  • (String, nil)

    The last maintenance timestamp or nil if not found.

Raises:

  • (SQLite3::BusyException)

    If the database is busy.



19
20
21
22
23
24
25
26
27
28
29
30
# File 'documented/lich.rb', line 19

def Lich.db_maint_last_at
  ts = nil
  begin
    ts = Lich.db.get_first_value("SELECT value FROM lich_settings WHERE name='db_maint_last_at';")
  rescue SQLite3::BusyException
    sleep 0.1
    retry
  rescue => e
    Lich.log "db_maint_last_at error: #{e}"
  end
  ts
end

.db_maint_lock_pathString

Returns the path to the database maintenance lock file.

Examples:

path = Lich.db_maint_lock_path

Returns:

  • (String)

    The path to the maintenance lock file.



10
11
12
# File 'documented/lich.rb', line 10

def Lich.db_maint_lock_path
  File.join(DATA_DIR, 'lich.db3.maint.lock')
end

.db_maint_set!(iso_utc, note = '') ⇒ Object

Sets the last maintenance timestamp and note in the database.

Examples:

Lich.db_maint_set!(Time.now.utc.iso8601, "Maintenance completed")

Parameters:

  • iso_utc (String)

    The ISO 8601 formatted timestamp of the last maintenance.

  • note (String) (defaults to: '')

    An optional note regarding the maintenance.

Raises:

  • (SQLite3::BusyException)

    If the database is busy.



38
39
40
41
42
43
44
45
46
47
48
49
# File 'documented/lich.rb', line 38

def Lich.db_maint_set!(iso_utc, note = '')
  begin
    Lich.db.execute("CREATE TABLE IF NOT EXISTS lich_settings (name TEXT NOT NULL, value TEXT, PRIMARY KEY(name));")
    Lich.db.execute("INSERT OR REPLACE INTO lich_settings(name, value) VALUES('db_maint_last_at', ?);", [iso_utc])
    Lich.db.execute("INSERT OR REPLACE INTO lich_settings(name, value) VALUES('db_maint_last_note', ?);", [note.to_s.encode('UTF-8')])
  rescue SQLite3::BusyException
    sleep 0.1
    retry
  rescue => e
    Lich.log "db_maint_set! error: #{e}"
  end
end

.db_mutexMutex

Returns the mutex used for database operations.

Examples:

mutex = Lich.db_mutex

Returns:

  • (Mutex)

    The mutex for database access.



160
161
162
# File 'documented/lich.rb', line 160

def self.db_mutex
  @@db_mutex
end

.db_vacuum_if_due!(months: 6, lock_timeout_s: 0.5) ⇒ Symbol

Performs a VACUUM operation on the database if maintenance is due.

Examples:

result = Lich.db_vacuum_if_due!(months: 12)

Parameters:

  • months (Integer) (defaults to: 6)

    The number of months to check against (default is 6).

  • lock_timeout_s (Float) (defaults to: 0.5)

    The timeout for acquiring the lock (default is 0.5 seconds).

Returns:

  • (Symbol)

    A symbol indicating the result of the operation.

Raises:

  • (StandardError)

    If there is an error during the VACUUM operation.



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'documented/lich.rb', line 78

def Lich.db_vacuum_if_due!(months: 6, lock_timeout_s: 0.5)
  return :skipped_recent unless Lich.db_maint_due?(months)

  lock_path = Lich.db_maint_lock_path
  File.open(lock_path, File::RDWR | File::CREAT, 0o644) do |f|
    start = Time.now
    got = false
    begin
      got = f.flock(File::LOCK_EX | File::LOCK_NB)
    rescue => e
      Lich.log "db_maint flock error: #{e}"
    end
    unless got
      while (Time.now - start) < lock_timeout_s && !got
        sleep 0.1
        begin
          got = f.flock(File::LOCK_EX | File::LOCK_NB)
        rescue SystemCallError, IOError
          # Transient error acquiring lock on some filesystems; back off and retry.
          sleep 0.05
        end
      end
    end
    return :skipped_lock_held unless got

    begin
      page_count_before     = Lich.db.get_first_value('PRAGMA page_count;').to_i
      freelist_count_before = Lich.db.get_first_value('PRAGMA freelist_count;').to_i
    rescue SQLite3::BusyException
      Lich.log "db_maint: busy reading stats; skipping"
      return :skipped_busy
    end

    begin
      mode = Lich.db.get_first_value('PRAGMA journal_mode;')
      if mode && mode.to_s.strip.upcase == 'WAL'
        Lich.db.execute('PRAGMA wal_checkpoint(TRUNCATE);')
      end
    rescue SQLite3::SQLException => e
      Lich.log "db_maint: checkpoint skipped (#{e.class}: #{e.message})"
    end

    begin
      Lich.db.execute('VACUUM;')
    rescue SQLite3::BusyException => e
      Lich.log "db_maint: VACUUM busy; skipping (#{e.message})"
      return :skipped_busy
    rescue => e
      Lich.log "db_maint: VACUUM error: #{e}"
      return :error
    end

    page_count_after     = Lich.db.get_first_value('PRAGMA page_count;').to_i rescue 0
    freelist_count_after = Lich.db.get_first_value('PRAGMA freelist_count;').to_i rescue 0
    note = "VACUUM ok pages #{page_count_before}->#{page_count_after}, free #{freelist_count_before}->#{freelist_count_after}"
    Lich.db_maint_set!(Time.now.utc.iso8601, note)
    :vacuum_ok
  end
end

.debug_messagingBoolean

Retrieves the debug messaging setting from the database.

Examples:

debug_enabled = Lich.debug_messaging

Returns:

  • (Boolean)

    True if debug messaging is enabled, false otherwise.



846
847
848
849
850
851
852
853
854
855
856
857
858
# File 'documented/lich.rb', line 846

def Lich.debug_messaging
  if @@debug_messaging.nil?
    begin
      val = Lich.db.get_first_value("SELECT value FROM lich_settings WHERE name='debug_messaging';")
    rescue SQLite3::BusyException
      sleep 0.1
      retry
    end
    @@debug_messaging = (val.to_s =~ /on|true|yes/ ? true : false)
    Lich.debug_messaging = @@debug_messaging
  end
  return @@debug_messaging
end

.debug_messaging=(val) ⇒ Object

Sets the debug messaging setting in the database.

Examples:

Lich.debug_messaging = true

Parameters:

  • val (Boolean)

    The value to set for debug messaging.

Raises:

  • (SQLite3::BusyException)

    If the database is busy.



865
866
867
868
869
870
871
872
873
# File 'documented/lich.rb', line 865

def Lich.debug_messaging=(val)
  @@debug_messaging = (val.to_s =~ /on|true|yes/ ? true : false)
  begin
    Lich.db.execute("INSERT OR REPLACE INTO lich_settings(name,value) values('debug_messaging',?);", [@@debug_messaging.to_s.encode('UTF-8')])
  rescue SQLite3::BusyException
    sleep 0.1
    retry
  end
end

.deprecated(old_object = '', new_object = '', script_location = "#{Script.current.name || 'unknown'}", debug_log: true, fe_log: false, limit_log: true) ⇒ Object

Logs a deprecation warning for an old object.

Examples:

Lich.deprecated("old_method", "new_method")

Parameters:

  • old_object (String) (defaults to: '')

    The deprecated object name.

  • new_object (String) (defaults to: '')

    The new object name to use instead.

  • script_location (String) (defaults to: "#{Script.current.name || 'unknown'}")

    The location of the script where the deprecation occurred.

  • debug_log (Boolean) (defaults to: true)

    Whether to log the message for debugging (default is true).

  • fe_log (Boolean) (defaults to: false)

    Whether to log the message for front-end (default is false).

  • limit_log (Boolean) (defaults to: true)

    Whether to limit logging of the same message (default is true).



251
252
253
254
255
256
257
# File 'documented/lich.rb', line 251

def Lich.deprecated(old_object = '', new_object = '', script_location = "#{Script.current.name || 'unknown'}", debug_log: true, fe_log: false, limit_log: true)
  msg = "Deprecated call to #{old_object} used in #{script_location}. Please change to #{new_object} instead!"
  return if limit_log && @@deprecated_log.include?(msg)
  Lich.log(msg) if debug_log
  Lich::Messaging.msg("bold", msg) if fe_log
  @@deprecated_log.push(msg) unless @@deprecated_log.include?(msg)
end

.display_exitsBoolean

Retrieves the display exits setting from the database.

Examples:

display_enabled = Lich.display_exits

Returns:

  • (Boolean)

    True if display exits is enabled, false otherwise.



1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
# File 'documented/lich.rb', line 1006

def Lich.display_exits
  if @@display_exits.nil?
    begin
      val = Lich.db.get_first_value("SELECT value FROM lich_settings WHERE name='display_exits';")
    rescue SQLite3::BusyException
      sleep 0.1
      retry
    end
    val = false if val.nil? and XMLData.game != ""; # default false
    @@display_exits = (val.to_s =~ /on|true|yes/ ? true : false) if !val.nil?;
  end
  return @@display_exits
end

.display_exits=(val) ⇒ Object

Sets the display exits setting in the database.

Examples:

Lich.display_exits = true

Parameters:

  • val (Boolean)

    The value to set for display exits.

Raises:

  • (SQLite3::BusyException)

    If the database is busy.



1025
1026
1027
1028
1029
1030
1031
1032
1033
# File 'documented/lich.rb', line 1025

def Lich.display_exits=(val)
  @@display_exits = (val.to_s =~ /on|true|yes/ ? true : false)
  begin
    Lich.db.execute("INSERT OR REPLACE INTO lich_settings(name,value) values('display_exits',?);", [@@display_exits.to_s.encode('UTF-8')])
  rescue SQLite3::BusyException
    sleep 0.1
    retry
  end
end

.display_lichidBoolean

Retrieves the display Lich ID setting from the database.

Examples:

display_enabled = Lich.display_lichid

Returns:

  • (Boolean)

    True if display Lich ID is enabled, false otherwise.



879
880
881
882
883
884
885
886
887
888
889
890
891
# File 'documented/lich.rb', line 879

def Lich.display_lichid
  if @@display_lichid.nil?
    begin
      val = Lich.db.get_first_value("SELECT value FROM lich_settings WHERE name='display_lichid';")
    rescue SQLite3::BusyException
      sleep 0.1
      retry
    end
    val = (XMLData.game =~ /^GS/ ? true : false) if val.nil? and XMLData.game != ""; # default false if DR, otherwise default true
    @@display_lichid = (val.to_s =~ /on|true|yes/ ? true : false) if !val.nil?;
  end
  return @@display_lichid
end

.display_lichid=(val) ⇒ Object

Sets the display Lich ID setting in the database.

Examples:

Lich.display_lichid = false

Parameters:

  • val (Boolean)

    The value to set for display Lich ID.

Raises:

  • (SQLite3::BusyException)

    If the database is busy.



898
899
900
901
902
903
904
905
906
# File 'documented/lich.rb', line 898

def Lich.display_lichid=(val)
  @@display_lichid = (val.to_s =~ /on|true|yes/ ? true : false)
  begin
    Lich.db.execute("INSERT OR REPLACE INTO lich_settings(name,value) values('display_lichid',?);", [@@display_lichid.to_s.encode('UTF-8')])
  rescue SQLite3::BusyException
    sleep 0.1
    retry
  end
end

.display_stringprocsBoolean

Retrieves the display string procs setting from the database.

Examples:

display_enabled = Lich.display_stringprocs

Returns:

  • (Boolean)

    True if display string procs is enabled, false otherwise.



1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
# File 'documented/lich.rb', line 1039

def Lich.display_stringprocs
  if @@display_stringprocs.nil?
    begin
      val = Lich.db.get_first_value("SELECT value FROM lich_settings WHERE name='display_stringprocs';")
    rescue SQLite3::BusyException
      sleep 0.1
      retry
    end
    val = false if val.nil? and XMLData.game != ""; # default false
    @@display_stringprocs = (val.to_s =~ /on|true|yes/ ? true : false) if !val.nil?;
  end
  return @@display_stringprocs
end

.display_stringprocs=(val) ⇒ Object

Sets the display string procs setting in the database.

Examples:

Lich.display_stringprocs = true

Parameters:

  • val (Boolean)

    The value to set for display string procs.

Raises:

  • (SQLite3::BusyException)

    If the database is busy.



1058
1059
1060
1061
1062
1063
1064
1065
1066
# File 'documented/lich.rb', line 1058

def Lich.display_stringprocs=(val)
  @@display_stringprocs = (val.to_s =~ /on|true|yes/ ? true : false)
  begin
    Lich.db.execute("INSERT OR REPLACE INTO lich_settings(name,value) values('display_stringprocs',?);", [@@display_stringprocs.to_s.encode('UTF-8')])
  rescue SQLite3::BusyException
    sleep 0.1
    retry
  end
end

.display_uidBoolean

Retrieves the display UID setting from the database.

Examples:

display_enabled = Lich.display_uid

Returns:

  • (Boolean)

    True if display UID is enabled, false otherwise.



973
974
975
976
977
978
979
980
981
982
983
984
985
# File 'documented/lich.rb', line 973

def Lich.display_uid
  if @@display_uid.nil?
    begin
      val = Lich.db.get_first_value("SELECT value FROM lich_settings WHERE name='display_uid';")
    rescue SQLite3::BusyException
      sleep 0.1
      retry
    end
    val = (XMLData.game =~ /^GS/ ? true : false) if val.nil? and XMLData.game != ""; # default false if DR, otherwise default true
    @@display_uid = (val.to_s =~ /on|true|yes/ ? true : false) if !val.nil?;
  end
  return @@display_uid
end

.display_uid=(val) ⇒ Object

Sets the display UID setting in the database.

Examples:

Lich.display_uid = false

Parameters:

  • val (Boolean)

    The value to set for display UID.

Raises:

  • (SQLite3::BusyException)

    If the database is busy.



992
993
994
995
996
997
998
999
1000
# File 'documented/lich.rb', line 992

def Lich.display_uid=(val)
  @@display_uid = (val.to_s =~ /on|true|yes/ ? true : false)
  begin
    Lich.db.execute("INSERT OR REPLACE INTO lich_settings(name,value) values('display_uid',?);", [@@display_uid.to_s.encode('UTF-8')])
  rescue SQLite3::BusyException
    sleep 0.1
    retry
  end
end

.find_hosts_fileObject



635
636
637
638
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
# File 'documented/lich.rb', line 635

def Lich.find_hosts_file
  if defined?(Win32)
    begin
      key = Win32.RegOpenKeyEx(:hKey => Win32::HKEY_LOCAL_MACHINE, :lpSubKey => 'System\\CurrentControlSet\\Services\\Tcpip\\Parameters', :samDesired => Win32::KEY_READ)[:phkResult]
      hosts_path = Win32.RegQueryValueEx(:hKey => key, :lpValueName => 'DataBasePath')[:lpData]
    ensure
      Win32.RegCloseKey(:hKey => key) rescue nil
    end
    if hosts_path
      windir = (ENV['windir'] || ENV['SYSTEMROOT'] || 'c:\windows')
      hosts_path.gsub('%SystemRoot%', windir)
      hosts_file = "#{hosts_path}\\hosts"
      if File.exist?(hosts_file)
        return (@@hosts_file = hosts_file)
      end
    end
    if (windir = (ENV['windir'] || ENV['SYSTEMROOT'])) and File.exist?("#{windir}\\system32\\drivers\\etc\\hosts")
      return (@@hosts_file = "#{windir}\\system32\\drivers\\etc\\hosts")
    end

    for drive in ['C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']
      for windir in ['winnt', 'windows']
        if File.exist?("#{drive}:\\#{windir}\\system32\\drivers\\etc\\hosts")
          return (@@hosts_file = "#{drive}:\\#{windir}\\system32\\drivers\\etc\\hosts")
        end
      end
    end
  else # Linux/Mac
    if File.exist?('/etc/hosts')
      return (@@hosts_file = '/etc/hosts')
    elsif File.exist?('/private/etc/hosts')
      return (@@hosts_file = '/private/etc/hosts')
    end
  end
  return (@@hosts_file = false)
end

.fix_game_host_port(gamehost, gameport) ⇒ Array

Fixes the game host and port based on known mappings.

Examples:

fixed = Lich.fix_game_host_port("gs-plat.simutronics.net", 10121)

Parameters:

  • gamehost (String)

    The game host to fix.

  • gameport (Integer)

    The game port to fix.

Returns:

  • (Array)

    The fixed game host and port.



801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
# File 'documented/lich.rb', line 801

def Lich.fix_game_host_port(gamehost, gameport)
  if (gamehost == 'gs-plat.simutronics.net') and (gameport.to_i == 10121)
    gamehost = 'storm.gs4.game.play.net'
    gameport = 10124
  elsif (gamehost == 'gs3.simutronics.net') and (gameport.to_i == 4900)
    gamehost = 'storm.gs4.game.play.net'
    gameport = 10024
  elsif (gamehost == 'gs4.simutronics.net') and (gameport.to_i == 10321)
    gamehost = 'storm.gs4.game.play.net'
    gameport = 10324
  elsif (gamehost == 'prime.dr.game.play.net') and (gameport.to_i == 4901)
    gamehost = 'dr.simutronics.net'
    gameport = 11024
  end
  [gamehost, gameport]
end

.get_simu_launcherString?

Retrieves the command for launching the simulation based on the operating system.

Examples:

command = Lich.get_simu_launcher

Returns:

  • (String, nil)

    The launcher command or nil if not found.



350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
# File 'documented/lich.rb', line 350

def Lich.get_simu_launcher
  if defined?(Win32)
    begin
      launcher_key = Win32.RegOpenKeyEx(:hKey => Win32::HKEY_LOCAL_MACHINE, :lpSubKey => 'Software\\Classes\\Simutronics.Autolaunch\\Shell\\Open\\command', :samDesired => (Win32::KEY_ALL_ACCESS | Win32::KEY_WOW64_32KEY))[:phkResult]
      launcher_cmd = Win32.RegQueryValueEx(:hKey => launcher_key, :lpValueName => 'RealCommand')[:lpData]
      if launcher_cmd.nil? or launcher_cmd.empty?
        launcher_cmd = Win32.RegQueryValueEx(:hKey => launcher_key)[:lpData]
      end
      return launcher_cmd
    ensure
      Win32.RegCloseKey(:hKey => launcher_key) rescue nil
    end
  elsif defined?(Wine)
    launcher_cmd = Wine.registry_gets('HKEY_LOCAL_MACHINE\\Software\\Classes\\Simutronics.Autolaunch\\Shell\\Open\\command\\RealCommand')
    unless launcher_cmd and not launcher_cmd.empty?
      launcher_cmd = Wine.registry_gets('HKEY_LOCAL_MACHINE\\Software\\Classes\\Simutronics.Autolaunch\\Shell\\Open\\command\\')
    end
    return launcher_cmd
  else
    return nil
  end
end

.hide_uid_flagBoolean

Retrieves the hide UID flag setting from the database.

Examples:

hide_enabled = Lich.hide_uid_flag

Returns:

  • (Boolean)

    True if hide UID flag is enabled, false otherwise.



912
913
914
915
916
917
918
919
920
921
922
923
924
# File 'documented/lich.rb', line 912

def Lich.hide_uid_flag
  if @@hide_uid_flag.nil?
    begin
      val = Lich.db.get_first_value("SELECT value FROM lich_settings WHERE name='hide_uid_flag';")
    rescue SQLite3::BusyException
      sleep 0.1
      retry
    end
    val = false if val.nil? and XMLData.game != ""; # default false
    @@hide_uid_flag = (val.to_s =~ /on|true|yes/ ? true : false) if !val.nil?;
  end
  return @@hide_uid_flag
end

.hide_uid_flag=(val) ⇒ Object

Sets the hide UID flag setting in the database.

Examples:

Lich.hide_uid_flag = true

Parameters:

  • val (Boolean)

    The value to set for hide UID flag.

Raises:

  • (SQLite3::BusyException)

    If the database is busy.



931
932
933
934
935
936
937
938
939
# File 'documented/lich.rb', line 931

def Lich.hide_uid_flag=(val)
  @@hide_uid_flag = (val.to_s =~ /on|true|yes/ ? true : false)
  begin
    Lich.db.execute("INSERT OR REPLACE INTO lich_settings(name,value) values('hide_uid_flag',?);", [@@hide_uid_flag.to_s.encode('UTF-8')])
  rescue SQLite3::BusyException
    sleep 0.1
    retry
  end
end

.hosts_fileString, false

Retrieves the path to the hosts file used by the application.

Examples:

path = Lich.hosts_file

Returns:

  • (String, false)

    The path to the hosts file or false if not found.



630
631
632
633
# File 'documented/lich.rb', line 630

def Lich.hosts_file
  Lich.find_hosts_file if @@hosts_file.nil?
  return @@hosts_file
end

.init_dbObject



211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
# File 'documented/lich.rb', line 211

def Lich.init_db
  begin
    Lich.db.execute("CREATE TABLE IF NOT EXISTS script_setting (script TEXT NOT NULL, name TEXT NOT NULL, value BLOB, PRIMARY KEY(script, name));")
    Lich.db.execute("CREATE TABLE IF NOT EXISTS script_auto_settings (script TEXT NOT NULL, scope TEXT, hash BLOB, PRIMARY KEY(script, scope));")
    Lich.db.execute("CREATE TABLE IF NOT EXISTS lich_settings (name TEXT NOT NULL, value TEXT, PRIMARY KEY(name));")
    Lich.db.execute("CREATE TABLE IF NOT EXISTS uservars (scope TEXT NOT NULL, hash BLOB, PRIMARY KEY(scope));")
    if (RUBY_VERSION =~ /^2\.[012]\./)
      Lich.db.execute("CREATE TABLE IF NOT EXISTS trusted_scripts (name TEXT NOT NULL);")
    end
    Lich.db.execute("CREATE TABLE IF NOT EXISTS simu_game_entry (character TEXT NOT NULL, game_code TEXT NOT NULL, data BLOB, PRIMARY KEY(character, game_code));")
    Lich.db.execute("CREATE TABLE IF NOT EXISTS enable_inventory_boxes (player_id INTEGER NOT NULL, PRIMARY KEY(player_id));")
  rescue SQLite3::BusyException
    sleep 0.1
    retry
  end
end

.inventory_boxes(player_id) ⇒ Boolean

Checks if inventory boxes are enabled for the specified player.

Examples:

enabled = Lich.inventory_boxes(12345)

Parameters:

  • player_id (Integer)

    The ID of the player to check.

Returns:

  • (Boolean)

    True if inventory boxes are enabled, false otherwise.

Raises:

  • (SQLite3::BusyException)

    If the database is busy.



728
729
730
731
732
733
734
735
736
737
738
739
740
# File 'documented/lich.rb', line 728

def Lich.inventory_boxes(player_id)
  begin
    v = Lich.db.get_first_value('SELECT player_id FROM enable_inventory_boxes WHERE player_id=?;', [player_id.to_i])
  rescue SQLite3::BusyException
    sleep 0.1
    retry
  end
  if v
    true
  else
    false
  end
end

Links the Lich application to the Simutronics Auto Launcher (SAL).

Examples:

linked = Lich.link_to_sal

Returns:

  • (Boolean)

    True if linked successfully, false otherwise.



503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
# File 'documented/lich.rb', line 503

def Lich.link_to_sal
  if defined?(Win32)
    if Win32.admin?
      begin
        # fixme: 64 bit browsers?
        launcher_key = Win32.RegOpenKeyEx(:hKey => Win32::HKEY_LOCAL_MACHINE, :lpSubKey => 'Software\\Classes\\Simutronics.Autolaunch\\Shell\\Open\\command', :samDesired => (Win32::KEY_ALL_ACCESS | Win32::KEY_WOW64_32KEY))[:phkResult]
        r = Win32.RegQueryValueEx(:hKey => launcher_key, :lpValueName => 'RealCommand')
        if (r[:return] == 0) and not r[:lpData].empty?
          # already linked
          return true
        end

        r = Win32.GetModuleFileName
        unless r[:return] > 0
          # fixme
          return false
        end

        new_launcher_cmd = "\"#{r[:lpFilename]}\" \"#{File.expand_path($PROGRAM_NAME)}\" %1"
        r = Win32.RegQueryValueEx(:hKey => launcher_key)
        launcher_cmd = r[:lpData]
        r = Win32.RegSetValueEx(:hKey => launcher_key, :lpValueName => 'RealCommand', :dwType => Win32::REG_SZ, :lpData => launcher_cmd)
        return false unless (r == 0)

        r = Win32.RegSetValueEx(:hKey => launcher_key, :dwType => Win32::REG_SZ, :lpData => new_launcher_cmd)
        return (r == 0)
      ensure
        Win32.RegCloseKey(:hKey => launcher_key) rescue nil
      end
    else
      begin
        r = Win32.GetModuleFileName
        file = ((r[:return] > 0) ? r[:lpFilename] : 'rubyw.exe')
        params = "#{$PROGRAM_NAME.split(/\/|\\/).last} --link-to-sal"
        r = Win32.ShellExecuteEx(:lpVerb => 'runas', :lpFile => file, :lpDirectory => LICH_DIR.tr("/", "\\"), :lpParameters => params, :fMask => Win32::SEE_MASK_NOCLOSEPROCESS)
        if r[:return] > 0
          process_id = r[:hProcess]
          sleep 0.2 while Win32.GetExitCodeProcess(:hProcess => process_id)[:lpExitCode] == Win32::STILL_ACTIVE
          sleep 3
        else
          Win32.ShellExecute(:lpOperation => 'runas', :lpFile => file, :lpDirectory => LICH_DIR.tr("/", "\\"), :lpParameters => params)
          sleep 6
        end
      rescue
        Lich.msgbox(:message => $!)
      end
    end
  elsif defined?(Wine)
    launch_cmd = Wine.registry_gets('HKEY_LOCAL_MACHINE\\Software\\Classes\\Simutronics.Autolaunch\\Shell\\Open\\command\\')
    return false unless launch_cmd

    new_launch_cmd = "#{File.expand_path($PROGRAM_NAME)} --wine=#{Wine::BIN} --wine-prefix=#{Wine::PREFIX} %1"
    result = true
    if launch_cmd
      if launch_cmd =~ /lich/i
        $stdout.puts "--- warning: Lich appears to already be installed to the registry"
        Lich.log "warning: Lich appears to already be installed to the registry"
        Lich.log 'info: launch_cmd: ' + launch_cmd
      else
        result = result && Wine.registry_puts('HKEY_LOCAL_MACHINE\\Software\\Classes\\Simutronics.Autolaunch\\Shell\\Open\\command\\RealCommand', launch_cmd)
        result = result && Wine.registry_puts('HKEY_LOCAL_MACHINE\\Software\\Classes\\Simutronics.Autolaunch\\Shell\\Open\\command\\', new_launch_cmd)
      end
    end
    return result
  else
    return false
  end
end

Links the Lich application to the Simutronics Game Engine (SGE).

Examples:

linked = Lich.link_to_sge

Returns:

  • (Boolean)

    True if linked successfully, false otherwise.



377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
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
# File 'documented/lich.rb', line 377

def Lich.link_to_sge
  if defined?(Win32)
    if Win32.admin?
      begin
        launcher_key = Win32.RegOpenKeyEx(:hKey => Win32::HKEY_LOCAL_MACHINE, :lpSubKey => 'Software\\Simutronics\\Launcher', :samDesired => (Win32::KEY_ALL_ACCESS | Win32::KEY_WOW64_32KEY))[:phkResult]
        r = Win32.RegQueryValueEx(:hKey => launcher_key, :lpValueName => 'RealDirectory')
        if (r[:return] == 0) and not r[:lpData].empty?
          # already linked
          return true
        end

        r = Win32.GetModuleFileName
        unless r[:return] > 0
          # fixme
          return false
        end

        new_launcher_dir = "\"#{r[:lpFilename]}\" \"#{File.expand_path($PROGRAM_NAME)}\" "
        r = Win32.RegQueryValueEx(:hKey => launcher_key, :lpValueName => 'Directory')
        launcher_dir = r[:lpData]
        r = Win32.RegSetValueEx(:hKey => launcher_key, :lpValueName => 'RealDirectory', :dwType => Win32::REG_SZ, :lpData => launcher_dir)
        return false unless (r == 0)

        r = Win32.RegSetValueEx(:hKey => launcher_key, :lpValueName => 'Directory', :dwType => Win32::REG_SZ, :lpData => new_launcher_dir)
        return (r == 0)
      ensure
        Win32.RegCloseKey(:hKey => launcher_key) rescue nil
      end
    else
      begin
        r = Win32.GetModuleFileName
        file = ((r[:return] > 0) ? r[:lpFilename] : 'rubyw.exe')
        params = "#{$PROGRAM_NAME.split(/\/|\\/).last} --link-to-sge"
        r = Win32.ShellExecuteEx(:lpVerb => 'runas', :lpFile => file, :lpDirectory => LICH_DIR.tr("/", "\\"), :lpParameters => params, :fMask => Win32::SEE_MASK_NOCLOSEPROCESS)
        if r[:return] > 0
          process_id = r[:hProcess]
          sleep 0.2 while Win32.GetExitCodeProcess(:hProcess => process_id)[:lpExitCode] == Win32::STILL_ACTIVE
          sleep 3
        else
          Win32.ShellExecute(:lpOperation => 'runas', :lpFile => file, :lpDirectory => LICH_DIR.tr("/", "\\"), :lpParameters => params)
          sleep 6
        end
      rescue
        Lich.msgbox(:message => $!)
      end
    end
  elsif defined?(Wine)
    launch_dir = Wine.registry_gets('HKEY_LOCAL_MACHINE\\Software\\Simutronics\\Launcher\\Directory')
    return false unless launch_dir

    lich_launch_dir = "#{File.expand_path($PROGRAM_NAME)} --wine=#{Wine::BIN} --wine-prefix=#{Wine::PREFIX}  "
    result = true
    if launch_dir
      if launch_dir =~ /lich/i
        $stdout.puts "--- warning: Lich appears to already be installed to the registry"
        Lich.log "warning: Lich appears to already be installed to the registry"
        Lich.log 'info: launch_dir: ' + launch_dir
      else
        result = result && Wine.registry_puts('HKEY_LOCAL_MACHINE\\Software\\Simutronics\\Launcher\\RealDirectory', launch_dir)
        result = result && Wine.registry_puts('HKEY_LOCAL_MACHINE\\Software\\Simutronics\\Launcher\\Directory', lich_launch_dir)
      end
    end
    return result
  else
    return false
  end
end

.log(msg) ⇒ Object

Logs a message to standard error with a timestamp.

Examples:

Lich.log("This is a log message")

Parameters:

  • msg (String)

    The message to log.



238
239
240
# File 'documented/lich.rb', line 238

def Lich.log(msg)
  $stderr.puts "#{Time.now.strftime("%Y-%m-%d %H:%M:%S")}: #{msg}"
end

.method_missing(arg1, arg2 = '') ⇒ Object



190
191
192
193
194
195
196
# File 'documented/lich.rb', line 190

def Lich.method_missing(arg1, arg2 = '')
  if (Time.now.to_i - @@last_warn_deprecated) > 300
    respond "--- warning: Lich.* variables will stop working in a future version of Lich.  Use Vars.* (offending script: #{Script.current.name || 'unknown'})"
    @@last_warn_deprecated = Time.now.to_i
  end
  Vars.method_missing(arg1, arg2)
end

.modify_hosts(game_host) ⇒ Boolean

Modifies the hosts file to redirect the specified game host.

Examples:

success = Lich.modify_hosts("game.example.com")

Parameters:

  • game_host (String)

    The game host to redirect.

Returns:

  • (Boolean)

    True if the modification was successful, false otherwise.



677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
# File 'documented/lich.rb', line 677

def Lich.modify_hosts(game_host)
  if Lich.hosts_file and File.exist?(Lich.hosts_file)
    at_exit { Lich.restore_hosts }
    Lich.restore_hosts
    if File.exist?("#{Lich.hosts_file}.bak")
      return false
    end

    begin
      # copy hosts to hosts.bak
      File.open("#{Lich.hosts_file}.bak", 'w') { |hb| File.open(Lich.hosts_file) { |h| hb.write(h.read) } }
    rescue
      File.unlink("#{Lich.hosts_file}.bak") if File.exist?("#{Lich.hosts_file}.bak")
      return false
    end
    File.open(Lich.hosts_file, 'a') { |f| f.write "\r\n127.0.0.1\t\t#{game_host}" }
    return true
  else
    return false
  end
end

.module_eval(*_a) ⇒ Object



232
# File 'documented/lich.rb', line 232

def Lich.module_eval(*_a);        nil; end

.msgbox(args) ⇒ Symbol?

Displays a message box with the specified arguments.

Examples:

response = Lich.msgbox(message: "Are you sure?", title: "Confirmation", buttons: :yes_no)

Parameters:

  • args (Hash)

    The arguments for the message box, including :message, :title, :buttons, and :icon.

Returns:

  • (Symbol, nil)

    The response from the message box.



273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
# File 'documented/lich.rb', line 273

def Lich.msgbox(args)
  if defined?(Win32)
    if args[:buttons] == :ok_cancel
      buttons = Win32::MB_OKCANCEL
    elsif args[:buttons] == :yes_no
      buttons = Win32::MB_YESNO
    else
      buttons = Win32::MB_OK
    end
    if args[:icon] == :error
      icon = Win32::MB_ICONERROR
    elsif args[:icon] == :question
      icon = Win32::MB_ICONQUESTION
    elsif args[:icon] == :warning
      icon = Win32::MB_ICONWARNING
    else
      icon = 0
    end
    args[:title] ||= "Lich v#{LICH_VERSION}"
    r = Win32.MessageBox(:lpText => args[:message], :lpCaption => args[:title], :uType => (buttons | icon))
    if r == Win32::IDIOK
      return :ok
    elsif r == Win32::IDICANCEL
      return :cancel
    elsif r == Win32::IDIYES
      return :yes
    elsif r == Win32::IDINO
      return :no
    else
      return nil
    end
  elsif defined?(Gtk)
    if args[:buttons] == :ok_cancel
      buttons = Gtk::MessageDialog::BUTTONS_OK_CANCEL
    elsif args[:buttons] == :yes_no
      buttons = Gtk::MessageDialog::BUTTONS_YES_NO
    else
      buttons = Gtk::MessageDialog::BUTTONS_OK
    end
    if args[:icon] == :error
      type = Gtk::MessageDialog::ERROR
    elsif args[:icon] == :question
      type = Gtk::MessageDialog::QUESTION
    elsif args[:icon] == :warning
      type = Gtk::MessageDialog::WARNING
    else
      type = Gtk::MessageDialog::INFO
    end
    dialog = Gtk::MessageDialog.new(nil, Gtk::Dialog::MODAL, type, buttons, args[:message])
    args[:title] ||= "Lich v#{LICH_VERSION}"
    dialog.title = args[:title]
    response = nil
    dialog.run { |d_r|
      response = d_r
      dialog.destroy
    }
    if response == Gtk::Dialog::RESPONSE_OK
      return :ok
    elsif response == Gtk::Dialog::RESPONSE_CANCEL
      return :cancel
    elsif response == Gtk::Dialog::RESPONSE_YES
      return :yes
    elsif response == Gtk::Dialog::RESPONSE_NO
      return :no
    else
      return nil
    end
  elsif $stdout.isatty
    $stdout.puts(args[:message])
    return nil
  end
end

.mutex_lockObject

Locks the database mutex to ensure thread-safe access.

Examples:

Lich.mutex_lock

Raises:

  • (StandardError)

    If there is an error while locking the mutex.



168
169
170
171
172
173
174
175
# File 'documented/lich.rb', line 168

def self.mutex_lock
  begin
    self.db_mutex.lock unless self.db_mutex.owned?
  rescue StandardError
    respond "--- Lich: error: Lich.mutex_lock: #{$!}"
    Lich.log "error: Lich.mutex_lock: #{$!}\n\t#{$!.backtrace.join("\n\t")}"
  end
end

.mutex_unlockObject

Unlocks the database mutex to allow other threads access.

Examples:

Lich.mutex_unlock

Raises:

  • (StandardError)

    If there is an error while unlocking the mutex.



181
182
183
184
185
186
187
188
# File 'documented/lich.rb', line 181

def self.mutex_unlock
  begin
    self.db_mutex.unlock if self.db_mutex.owned?
  rescue StandardError
    respond "--- Lich: error: Lich.mutex_unlock: #{$!}"
    Lich.log "error: Lich.mutex_unlock: #{$!}\n\t#{$!.backtrace.join("\n\t")}"
  end
end

.restore_hostsObject

Restores the original hosts file from the backup.

Examples:

Lich.restore_hosts


702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
# File 'documented/lich.rb', line 702

def Lich.restore_hosts
  if Lich.hosts_file and File.exist?(Lich.hosts_file)
    begin
      # fixme: use rename instead?  test rename on windows
      if File.exist?("#{Lich.hosts_file}.bak")
        File.open("#{Lich.hosts_file}.bak") { |infile|
          File.open(Lich.hosts_file, 'w') { |outfile|
            outfile.write(infile.read)
          }
        }
        File.unlink "#{Lich.hosts_file}.bak"
      end
    rescue
      $stdout.puts "--- error: restore_hosts: #{$!}"
      Lich.log "error: restore_hosts: #{$!}\n\t#{$!.backtrace.join("\n\t")}"
      exit(1)
    end
  end
end

.seek(fe) ⇒ Object



198
199
200
201
202
203
204
205
# File 'documented/lich.rb', line 198

def Lich.seek(fe)
  if fe =~ /wizard/
    return $wiz_fe_loc
  elsif fe =~ /stormfront/
    return $sf_fe_loc
  end
  pp "Landed in get_simu_launcher method"
end

.set_inventory_boxes(player_id, enabled) ⇒ Object

Sets the inventory boxes state for the specified player.

Examples:

Lich.set_inventory_boxes(12345, true)

Parameters:

  • player_id (Integer)

    The ID of the player to set.

  • enabled (Boolean)

    Whether to enable or disable inventory boxes.

Raises:

  • (SQLite3::BusyException)

    If the database is busy.



748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
# File 'documented/lich.rb', line 748

def Lich.set_inventory_boxes(player_id, enabled)
  if enabled
    begin
      Lich.db.execute('INSERT OR REPLACE INTO enable_inventory_boxes values(?);', [player_id.to_i])
    rescue SQLite3::BusyException
      sleep 0.1
      retry
    end
  else
    begin
      Lich.db.execute('DELETE FROM enable_inventory_boxes where player_id=?;', [player_id.to_i])
    rescue SQLite3::BusyException
      sleep 0.1
      retry
    end
  end
  nil
end

.show_deprecated_logObject

Displays the log of deprecated messages.

Examples:

Lich.show_deprecated_log


262
263
264
265
266
# File 'documented/lich.rb', line 262

def Lich.show_deprecated_log
  @@deprecated_log.each do |msg|
    respond(msg)
  end
end

.track_autosort_stateBoolean

Retrieves the track autosort state setting from the database.

Examples:

track_enabled = Lich.track_autosort_state

Returns:

  • (Boolean)

    True if track autosort state is enabled, false otherwise.



1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
# File 'documented/lich.rb', line 1072

def Lich.track_autosort_state
  if @@track_autosort_state.nil?
    begin
      val = Lich.db.get_first_value("SELECT value FROM lich_settings WHERE name='track_autosort_state';")
    rescue SQLite3::BusyException
      sleep 0.1
      retry
    end
    @@track_autosort_state = (val.to_s =~ /on|true|yes/ ? true : false)
  end
  return @@track_autosort_state
end

.track_autosort_state=(val) ⇒ Object

Sets the track autosort state setting in the database.

Examples:

Lich.track_autosort_state = true

Parameters:

  • val (Boolean)

    The value to set for track autosort state.

Raises:

  • (SQLite3::BusyException)

    If the database is busy.



1090
1091
1092
1093
1094
1095
1096
1097
1098
# File 'documented/lich.rb', line 1090

def Lich.track_autosort_state=(val)
  @@track_autosort_state = (val.to_s =~ /on|true|yes/ ? true : false)
  begin
    Lich.db.execute("INSERT OR REPLACE INTO lich_settings(name,value) values('track_autosort_state',?);", [@@track_autosort_state.to_s.encode('UTF-8')])
  rescue SQLite3::BusyException
    sleep 0.1
    retry
  end
end

.track_dark_modeBoolean

Retrieves the track dark mode setting from the database.

Examples:

dark_mode_enabled = Lich.track_dark_mode

Returns:

  • (Boolean)

    True if track dark mode is enabled, false otherwise.



1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
# File 'documented/lich.rb', line 1104

def Lich.track_dark_mode
  if @@track_dark_mode.nil?
    begin
      val = Lich.db.get_first_value("SELECT value FROM lich_settings WHERE name='track_dark_mode';")
    rescue SQLite3::BusyException
      sleep 0.1
      retry
    end
    @@track_dark_mode = (val.to_s =~ /on|true|yes/ ? true : false)
  end
  return @@track_dark_mode
end

.track_dark_mode=(val) ⇒ Object

Sets the track dark mode setting in the database.

Examples:

Lich.track_dark_mode = true

Parameters:

  • val (Boolean)

    The value to set for track dark mode.

Raises:

  • (SQLite3::BusyException)

    If the database is busy.



1122
1123
1124
1125
1126
1127
1128
1129
1130
# File 'documented/lich.rb', line 1122

def Lich.track_dark_mode=(val)
  @@track_dark_mode = (val.to_s =~ /on|true|yes/ ? true : false)
  begin
    Lich.db.execute("INSERT OR REPLACE INTO lich_settings(name,value) values('track_dark_mode',?);", [@@track_dark_mode.to_s.encode('UTF-8')])
  rescue SQLite3::BusyException
    sleep 0.1
    retry
  end
end

.track_layout_stateBoolean

Retrieves the track layout state setting from the database.

Examples:

layout_enabled = Lich.track_layout_state

Returns:

  • (Boolean)

    True if track layout state is enabled, false otherwise.



1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
# File 'documented/lich.rb', line 1136

def Lich.track_layout_state
  if @@track_layout_state.nil?
    begin
      val = Lich.db.get_first_value("SELECT value FROM lich_settings WHERE name='track_layout_state';")
    rescue SQLite3::BusyException
      sleep 0.1
      retry
    end
    @@track_layout_state = (val.to_s =~ /on|true|yes/ ? true : false)
  end
  return @@track_layout_state
end

.track_layout_state=(val) ⇒ Object

Sets the track layout state setting in the database.

Examples:

Lich.track_layout_state = true

Parameters:

  • val (Boolean)

    The value to set for track layout state.

Raises:

  • (SQLite3::BusyException)

    If the database is busy.



1154
1155
1156
1157
1158
1159
1160
1161
1162
# File 'documented/lich.rb', line 1154

def Lich.track_layout_state=(val)
  @@track_layout_state = (val.to_s =~ /on|true|yes/ ? true : false)
  begin
    Lich.db.execute("INSERT OR REPLACE INTO lich_settings(name,value) values('track_layout_state',?);", [@@track_layout_state.to_s.encode('UTF-8')])
  rescue SQLite3::BusyException
    sleep 0.1
    retry
  end
end

Unlinks the Lich application from the Simutronics Auto Launcher (SAL).

Examples:

unlinked = Lich.unlink_from_sal

Returns:

  • (Boolean)

    True if unlinked successfully, false otherwise.



576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
# File 'documented/lich.rb', line 576

def Lich.unlink_from_sal
  if defined?(Win32)
    if Win32.admin?
      begin
        launcher_key = Win32.RegOpenKeyEx(:hKey => Win32::HKEY_LOCAL_MACHINE, :lpSubKey => 'Software\\Classes\\Simutronics.Autolaunch\\Shell\\Open\\command', :samDesired => (Win32::KEY_ALL_ACCESS | Win32::KEY_WOW64_32KEY))[:phkResult]
        real_directory = Win32.RegQueryValueEx(:hKey => launcher_key, :lpValueName => 'RealCommand')[:lpData]
        if real_directory.nil? or real_directory.empty?
          # not linked
          return true
        end

        r = Win32.RegSetValueEx(:hKey => launcher_key, :dwType => Win32::REG_SZ, :lpData => real_directory)
        return false unless (r == 0)

        r = Win32.RegDeleteValue(:hKey => launcher_key, :lpValueName => 'RealCommand')
        return (r == 0)
      ensure
        Win32.RegCloseKey(:hKey => launcher_key) rescue nil
      end
    else
      begin
        r = Win32.GetModuleFileName
        file = ((r[:return] > 0) ? r[:lpFilename] : 'rubyw.exe')
        params = "#{$PROGRAM_NAME.split(/\/|\\/).last} --unlink-from-sal"
        r = Win32.ShellExecuteEx(:lpVerb => 'runas', :lpFile => file, :lpDirectory => LICH_DIR.tr("/", "\\"), :lpParameters => params, :fMask => Win32::SEE_MASK_NOCLOSEPROCESS)
        if r[:return] > 0
          process_id = r[:hProcess]
          sleep 0.2 while Win32.GetExitCodeProcess(:hProcess => process_id)[:lpExitCode] == Win32::STILL_ACTIVE
          sleep 3
        else
          Win32.ShellExecute(:lpOperation => 'runas', :lpFile => file, :lpDirectory => LICH_DIR.tr("/", "\\"), :lpParameters => params)
          sleep 6
        end
      rescue
        Lich.msgbox(:message => $!)
      end
    end
  elsif defined?(Wine)
    real_launch_cmd = Wine.registry_gets('HKEY_LOCAL_MACHINE\\Software\\Classes\\Simutronics.Autolaunch\\Shell\\Open\\command\\RealCommand')
    result = true
    if real_launch_cmd and not real_launch_cmd.empty?
      result = result && Wine.registry_puts('HKEY_LOCAL_MACHINE\\Software\\Classes\\Simutronics.Autolaunch\\Shell\\Open\\command\\', real_launch_cmd)
      result = result && Wine.registry_puts('HKEY_LOCAL_MACHINE\\Software\\Classes\\Simutronics.Autolaunch\\Shell\\Open\\command\\RealCommand', '')
    end
    return result
  else
    return false
  end
end

Unlinks the Lich application from the Simutronics Game Engine (SGE).

Examples:

unlinked = Lich.unlink_from_sge

Returns:

  • (Boolean)

    True if unlinked successfully, false otherwise.



449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
# File 'documented/lich.rb', line 449

def Lich.unlink_from_sge
  if defined?(Win32)
    if Win32.admin?
      begin
        launcher_key = Win32.RegOpenKeyEx(:hKey => Win32::HKEY_LOCAL_MACHINE, :lpSubKey => 'Software\\Simutronics\\Launcher', :samDesired => (Win32::KEY_ALL_ACCESS | Win32::KEY_WOW64_32KEY))[:phkResult]
        real_directory = Win32.RegQueryValueEx(:hKey => launcher_key, :lpValueName => 'RealDirectory')[:lpData]
        if real_directory.nil? or real_directory.empty?
          # not linked
          return true
        end

        r = Win32.RegSetValueEx(:hKey => launcher_key, :lpValueName => 'Directory', :dwType => Win32::REG_SZ, :lpData => real_directory)
        return false unless (r == 0)

        r = Win32.RegDeleteValue(:hKey => launcher_key, :lpValueName => 'RealDirectory')
        return (r == 0)
      ensure
        Win32.RegCloseKey(:hKey => launcher_key) rescue nil
      end
    else
      begin
        r = Win32.GetModuleFileName
        file = ((r[:return] > 0) ? r[:lpFilename] : 'rubyw.exe')
        params = "#{$PROGRAM_NAME.split(/\/|\\/).last} --unlink-from-sge"
        r = Win32.ShellExecuteEx(:lpVerb => 'runas', :lpFile => file, :lpDirectory => LICH_DIR.tr("/", "\\"), :lpParameters => params, :fMask => Win32::SEE_MASK_NOCLOSEPROCESS)
        if r[:return] > 0
          process_id = r[:hProcess]
          sleep 0.2 while Win32.GetExitCodeProcess(:hProcess => process_id)[:lpExitCode] == Win32::STILL_ACTIVE
          sleep 3
        else
          Win32.ShellExecute(:lpOperation => 'runas', :lpFile => file, :lpDirectory => LICH_DIR.tr("/", "\\"), :lpParameters => params)
          sleep 6
        end
      rescue
        Lich.msgbox(:message => $!)
      end
    end
  elsif defined?(Wine)
    real_launch_dir = Wine.registry_gets('HKEY_LOCAL_MACHINE\\Software\\Simutronics\\Launcher\\RealDirectory')
    result = true
    if real_launch_dir and not real_launch_dir.empty?
      result = result && Wine.registry_puts('HKEY_LOCAL_MACHINE\\Software\\Simutronics\\Launcher\\Directory', real_launch_dir)
      result = result && Wine.registry_puts('HKEY_LOCAL_MACHINE\\Software\\Simutronics\\Launcher\\RealDirectory', '')
    end
    return result
  else
    return false
  end
end

.win32_launch_methodString

Retrieves the Windows launch method setting from the database.

Examples:

method = Lich.win32_launch_method

Returns:

  • (String)

    The launch method or nil if not found.



771
772
773
774
775
776
777
778
779
# File 'documented/lich.rb', line 771

def Lich.win32_launch_method
  begin
    val = Lich.db.get_first_value("SELECT value FROM lich_settings WHERE name='win32_launch_method';")
  rescue SQLite3::BusyException
    sleep 0.1
    retry
  end
  val
end

.win32_launch_method=(val) ⇒ Object

Sets the Windows launch method in the database.

Examples:

Lich.win32_launch_method = "method_name"

Parameters:

  • val (String)

    The launch method to set.

Raises:

  • (SQLite3::BusyException)

    If the database is busy.



786
787
788
789
790
791
792
793
# File 'documented/lich.rb', line 786

def Lich.win32_launch_method=(val)
  begin
    Lich.db.execute("INSERT OR REPLACE INTO lich_settings(name,value) values('win32_launch_method',?);", [val.to_s.encode('UTF-8')])
  rescue SQLite3::BusyException
    sleep 0.1
    retry
  end
end