Module: Lich::Gemstone::Infomon::XMLParser
- Defined in:
- documented/gemstone/infomon/xmlparser.rb
Overview
this module handles all of the logic for parsing game lines that infomon depends on
Defined Under Namespace
Modules: Pattern
Class Method Summary collapse
-
.parse(line) ⇒ Symbol
private
Parses a single line of XML game output and updates game state accordingly.
Class Method Details
.parse(line) ⇒ Symbol
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Rescues StandardError and logs to Lich.log with full backtrace; always
returns a symbol even on error (does not re-raise)
Parses a single line of XML game output and updates game state accordingly.
Detects NPC deaths, group arrivals, stow container configurations, ready item assignments, and status prompt markers. Uses a fast-path optimization: for single-line output, scans anchored patterns only at line start; for multiline buffered strings (containing interior newlines), falls back to full union to catch anchored patterns like death messages on inner lines.
552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 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 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 625 626 627 628 629 630 631 632 633 634 |
# File 'documented/gemstone/infomon/xmlparser.rb', line 552 def self.parse(line) # Fast path: attempt the anchored union only at line start and scan just # the mid-line patterns. A non-terminal newline means a combined # multi-line string (e.g. buffered combat); fall back to the full union # so inner-line ^ anchors (e.g. death messages) still match. nl = line.index("\n") matched = if nl && nl < line.length - 1 Pattern::All.match?(line) else Pattern::AllStart.match?(line) || Pattern::AllMidline.match?(line) end return :noop unless matched begin case line # this detects for death messages in XML that are not matched with appropriate combat attributes above when Pattern::NpcDeathMessage match = Regexp.last_match if (npc = GameObj.npcs.find { |obj| obj.id == match[:npc_id] && obj.status !~ /\b(?:dead|gone)\b/ }) npc.status = 'dead' end :ok when Pattern::Group_Short return :noop unless (match_data = Group::Observer.wants?(line)) Group::Observer.consume(line.strip, match_data) :ok when Pattern::Overwatch_Short return :noop unless (match_data = Overwatch::Observer.wants?(line)) Overwatch::Observer.consume(line, match_data) :ok when Pattern::Also_Here_Arrival return :noop unless Lich::Claim::Lock.locked? line.scan(%r{<a exist=(?:'|")(?<id>.*?)(?:'|") noun=(?:'|")(?<noun>.*?)(?:'|")>(?<name>.*?)</a>}).each { |player_found| next unless player_found[0].to_s.start_with?('-') next if XMLData.arrival_pcs.include?(player_found[1]) XMLData.arrival_pcs.push(player_found[1]) } :ok when Pattern::StowListOutputStart StowList.reset :ok when Pattern::StowListContainer, Pattern::StowSetContainer1, Pattern::StowSetContainer2 match = Regexp.last_match StowList.__send__("#{match[:type].downcase}=", GameObj.index_or_create(match[:id], match[:noun], match[:name], (match[:before].nil? ? nil : match[:before].strip), (match[:after].nil? ? nil : match[:after].strip))) StowList.checked = true if line =~ Pattern::StowListContainer :ok when Pattern::ReadyListOutputStart ReadyList.reset :ok when Pattern::ReadyListNormal, Pattern::ReadyListAmmo2, Pattern::ReadyListSheathsSet, Pattern::ReadyItemSet match = Regexp.last_match unless match[:id].nil? ReadyList.__send__("#{Lich::Util.normalize_name(match[:type].downcase)}=", GameObj.index_or_create(match[:id], match[:noun], match[:name], (match[:before].nil? ? nil : match[:before].strip), (match[:after].nil? ? nil : match[:after].strip))) end if match.named_captures.include?("store") ReadyList.__send__("store_#{Lich::Util.normalize_name(match[:type].downcase)}=", match[:store]) end :ok when Pattern::ReadyListFinished ReadyList.checked = true :ok when Pattern::ReadyItemClear match = Regexp.last_match ReadyList.__send__("#{Lich::Util.normalize_name(match[:type].downcase)}=", nil) :ok when Pattern::ReadyStoreSet match = Regexp.last_match ReadyList.__send__("store_#{Lich::Util.normalize_name(match[:type].downcase)}=", match[:store]) :ok when Pattern::StatusPrompt Infomon::Parser::State.set(Infomon::Parser::State::Ready) unless Infomon::Parser::State.get.eql?(Infomon::Parser::State::Ready) :ok else :noop end rescue StandardError respond "--- Lich: error: Infomon::XMLParser.parse: #{$!}" respond "--- Lich: error: line: #{line}" Lich.log "error: Infomon::XMLParser.parse: #{$!}\n\t#{$!.backtrace.join("\n\t")}" Lich.log "error: line: #{line}\n\t" end end |