Module: Lich::GameBase::XMLCleaner

Defined in:
documented/games.rb

Overview

XML string cleaner module

Class Method Summary collapse

Class Method Details

.clean_nested_quotes(server_string) ⇒ String

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.

Escapes nested single and double quotes within XML attribute values.

Converts matching quote pairs to XML entities (', ") to repair malformed tags where a quote inside an attribute value prematurely closes it.

Examples:

XMLCleaner.clean_nested_quotes("<a x='Tsetem's Items'>") #=> "<a x='Tsetem&apos;s Items'>"

Parameters:

  • server_string (String)

    the server string, modified in place

Returns:

  • (String)

    the server string with nested quotes escaped



302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
# File 'documented/games.rb', line 302

def clean_nested_quotes(server_string)
  # Fix nested single quotes
  unless (matches = server_string.scan(/'([^=>]*'[^=>]*)'/)).empty?
    Lich.log "Invalid nested single quotes XML tags detected: #{server_string.inspect}"
    matches.flatten.each do |match|
      server_string.gsub!(match, match.gsub(/'/, '&apos;'))
    end
    Lich.log "Invalid nested single quotes XML tags fixed to: #{server_string.inspect}"
  end

  # Fix nested double quotes
  unless (matches = server_string.scan(/"([^=>]*"[^=>]*)"/)).empty?
    Lich.log "Invalid nested double quotes XML tags detected: #{server_string.inspect}"
    matches.flatten.each do |match|
      server_string.gsub!(match, match.gsub(/"/, '&quot;'))
    end
    Lich.log "Invalid nested double quotes XML tags fixed to: #{server_string.inspect}"
  end

  server_string
end

.fix_invalid_characters(server_string) ⇒ String

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.

Removes or escapes invalid characters that cause XML parsing failures.

Strips bell characters (\a) that are not valid in XML.

Parameters:

  • server_string (String)

    the server string, modified in place

Returns:

  • (String)

    the server string with invalid characters removed



331
332
333
334
335
336
337
338
339
340
341
342
343
344
# File 'documented/games.rb', line 331

def fix_invalid_characters(server_string)
  # Note: a bare '&' is intentionally not escaped here. REXML raised on it
  # (hence the old escaping); Ox tolerates it (convert_special: false emits
  # it verbatim with no error), so escaping is no longer needed for parsing.

  # Fix bell character
  if server_string.include?("\a")
    Lich.log "Invalid \\a detected: #{server_string.inspect}"
    server_string.gsub!("\a", '')
    Lich.log "Invalid \\a stripped out: #{server_string.inspect}"
  end

  server_string
end

.fix_xml_tags(server_string) ⇒ String

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.

Repairs malformed XML tags in the server string.

Fixes open-ended dynaStream/component tags, removes extraneous closing tags, and removes unclosed wound tags from empath appraisals.

Parameters:

  • server_string (String)

    the server string, modified in place

Returns:

  • (String)

    the server string with XML tags repaired



354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
# File 'documented/games.rb', line 354

def fix_xml_tags(server_string)
  # Fix open-ended XML tags
  if /^<(?<xmltag>dynaStream|component) id='.*'>[^<]*(?!<\/\k<xmltag>>)\r\n$/ =~ server_string
    Lich.log "Open-ended #{xmltag} tag: #{server_string.inspect}"
    server_string.gsub!("\r\n", "</#{xmltag}>")
    Lich.log "Open-ended #{xmltag} tag fixed to: #{server_string.inspect}"
  end

  # Remove dangling closing tags
  if server_string =~ /^(?:(\"|<compass><\/compass>))?<\/(dynaStream|component)>\r\n/
    Lich.log "Extraneous closing tag detected and deleted: #{server_string.inspect}"
    server_string = ""
  end

  # Remove unclosed tag in long strings from empath appraisals
  if server_string =~ / and <d cmd=\"transfer .+? nerves\">a/
    Lich.log "Unclosed wound (nerves) tag detected and deleted: #{server_string.inspect}"
    server_string.sub!(/ and <d cmd=\"transfer .+? nerves\">a.+?$/, " and more.")
  end

  server_string
end