Module: Lich::DragonRealms::DRExpMonitor
- Defined in:
- documented/dragonrealms/drinfomon/drexpmonitor.rb
Constant Summary collapse
- MAX_SQLITE_RETRIES =
Maximum SQLite retry attempts before giving up (prevents infinite loops)
10- BOOLEAN_TRUE_PATTERN =
Stricter boolean matching pattern - anchored to avoid partial matches
/\A(on|true|yes)\z/i.freeze
- @@reporter_thread =
nil- @@running =
false- @@report_interval =
Hard-coded 1 second for real-time reporting
1- @@inline_display =
Lazy-loaded from DB, defaults to true
nil- @@mutex =
Thread safety for start/stop operations
Mutex.new
Class Method Summary collapse
-
.active? ⇒ Boolean
Checks if the experience gain reporter is currently running.
-
.format_briefexp_off(line, skill, rate_word) ⇒ String
Formats the BRIEFEXP OFF line with gained experience.
-
.format_briefexp_on(line, skill) ⇒ String
Formats the BRIEFEXP ON line with gained experience.
-
.format_gains(gains_array) ⇒ Array<String>
Formats an array of skill gains into a readable string.
-
.inline_display=(value) ⇒ void
Enables or disables inline experience display.
-
.inline_display? ⇒ Boolean
Checks if inline experience display is enabled.
-
.report_skill_gains ⇒ void
Reports the skill gains to the messaging system.
-
.reset! ⇒ void
Resets the state of the experience monitor.
-
.start ⇒ void
Starts the background experience gain reporter.
-
.stop ⇒ void
Stops the background experience gain reporter.
Class Method Details
.active? ⇒ Boolean
Checks if the experience gain reporter is currently running.
103 104 105 |
# File 'documented/dragonrealms/drinfomon/drexpmonitor.rb', line 103 def self.active? @@running end |
.format_briefexp_off(line, skill, rate_word) ⇒ String
Formats the BRIEFEXP OFF line with gained experience.
177 178 179 180 181 182 183 |
# File 'documented/dragonrealms/drinfomon/drexpmonitor.rb', line 177 def self.format_briefexp_off(line, skill, rate_word) return line unless @@inline_display gained = DRSkill.gained_exp(skill) || 0.00 padded_rate = rate_word.ljust(DR_LONGEST_LEARNING_RATE_LENGTH) line.sub(/(%\s+)(#{Regexp.escape(rate_word)})/, "\\1#{padded_rate} #{format('%0.2f', gained)}") end |
.format_briefexp_on(line, skill) ⇒ String
Formats the BRIEFEXP ON line with gained experience.
165 166 167 168 169 170 |
# File 'documented/dragonrealms/drinfomon/drexpmonitor.rb', line 165 def self.format_briefexp_on(line, skill) return line unless @@inline_display gained = DRSkill.gained_exp(skill) || 0.00 line.sub(%r{(/34\])}, "\\1 #{format('%0.2f', gained)}") end |
.format_gains(gains_array) ⇒ Array<String>
Formats an array of skill gains into a readable string.
188 189 190 191 192 193 194 195 196 197 |
# File 'documented/dragonrealms/drinfomon/drexpmonitor.rb', line 188 def self.format_gains(gains_array) # Aggregate multiple pulses of same skill aggregated = gains_array.reduce(Hash.new(0)) do |result, gain| result[gain[:skill]] += gain[:change] result end # Format as "Skill(+N)" strings aggregated.keys.sort.map { |skill| "#{skill}(+#{aggregated[skill]})" } end |
.inline_display=(value) ⇒ void
This method returns an undefined value.
Enables or disables inline experience display.
145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 |
# File 'documented/dragonrealms/drinfomon/drexpmonitor.rb', line 145 def self.inline_display=(value) @@inline_display = BOOLEAN_TRUE_PATTERN.match?(value.to_s) retries = 0 begin Lich.db.execute("INSERT OR REPLACE INTO lich_settings(name,value) values('display_inline_exp',?);", [@@inline_display.to_s.encode('UTF-8')]) rescue SQLite3::BusyException retries += 1 if retries >= MAX_SQLITE_RETRIES Lich::Messaging.msg('error', "DRExpMonitor: SQLite busy after #{MAX_SQLITE_RETRIES} retries, inline_display setting may not be persisted") return end sleep 0.1 retry end end |
.inline_display? ⇒ Boolean
Checks if inline experience display is enabled.
119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
# File 'documented/dragonrealms/drinfomon/drexpmonitor.rb', line 119 def self.inline_display? if @@inline_display.nil? retries = 0 begin val = Lich.db.get_first_value("SELECT value FROM lich_settings WHERE name='display_inline_exp';") rescue SQLite3::BusyException retries += 1 if retries >= MAX_SQLITE_RETRIES Lich::Messaging.msg('error', "DRExpMonitor: SQLite busy after #{MAX_SQLITE_RETRIES} retries, defaulting inline_display to false") @@inline_display = false return @@inline_display end sleep 0.1 retry end # Default to false - inline display must be explicitly enabled # Once enabled, the persisted value takes precedence # BUG FIX: Use anchored pattern to avoid matching partial strings like "money" or "trust" @@inline_display = val.nil? ? false : BOOLEAN_TRUE_PATTERN.match?(val.to_s) end @@inline_display end |
.report_skill_gains ⇒ void
This method returns an undefined value.
Reports the skill gains to the messaging system.
201 202 203 204 205 206 207 208 209 |
# File 'documented/dragonrealms/drinfomon/drexpmonitor.rb', line 201 def self.report_skill_gains # Drain the gained_skills array new_skills = DRSkill.gained_skills.shift(DRSkill.gained_skills.size) return if new_skills.empty? # Format and display formatted_gains = format_gains(new_skills) Lich::Messaging.msg('info', "DRExpMonitor: #{formatted_gains.join(', ')}") end |
.reset! ⇒ void
This method returns an undefined value.
Resets the state of the experience monitor.
109 110 111 112 113 114 115 |
# File 'documented/dragonrealms/drinfomon/drexpmonitor.rb', line 109 def self.reset! @@mutex.synchronize do @@inline_display = nil @@running = false @@reporter_thread = nil end end |
.start ⇒ void
This method will not start if the exp-monitor.lic script is running.
This method returns an undefined value.
Starts the background experience gain reporter.
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'documented/dragonrealms/drinfomon/drexpmonitor.rb', line 48 def self.start @@mutex.synchronize do if @@running Lich::Messaging.msg('info', 'DRExpMonitor: Experience gain reporting is already active') return end # Check for exp-monitor.lic conflict if Script.running?('exp-monitor') Lich::Messaging.msg('error', 'DRExpMonitor: Cannot start: exp-monitor.lic script is running') Lich::Messaging.msg('error', "DRExpMonitor: Stop it first with: #{$clean_lich_char}kill exp-monitor") return end @@running = true @@reporter_thread = Thread.new do begin loop do break unless @@running begin report_skill_gains sleep @@report_interval rescue StandardError => e Lich::Messaging.msg('error', "DRExpMonitor: Error: #{e.}") if $DREXPMONITOR_DEBUG Lich.log "DRExpMonitor error: #{e.}\n\t#{e.backtrace.join("\n\t")}" sleep @@report_interval end end ensure @@running = false end end end end |
.stop ⇒ void
This method will do nothing if the reporter is already inactive.
This method returns an undefined value.
Stops the background experience gain reporter.
88 89 90 91 92 93 94 95 96 97 98 99 |
# File 'documented/dragonrealms/drinfomon/drexpmonitor.rb', line 88 def self.stop @@mutex.synchronize do unless @@running Lich::Messaging.msg('info', 'DRExpMonitor: Experience gain reporting is already inactive') return end @@running = false @@reporter_thread&.kill @@reporter_thread = nil end end |