Module: Deckstrings
- Defined in:
- lib/deckstrings/enum.rb,
lib/deckstrings/varint.rb,
lib/deckstrings/deckstrings.rb
Defined Under Namespace
Modules: Enum Classes: Card, Deck, Format, FormatError, Hero, HeroClass
Class Method Summary collapse
-
.decode(deckstring) ⇒ { format: Integer, heroes: Array<Integer>, cards: Hash{Integer => Integer} }
Decodes a Hearthstone deckstring into format, hero, and card counts.
-
.encode(format:, heroes:, cards:) ⇒ String
Encodes a Hearthstone deck as a compact deckstring.
Class Method Details
.decode(deckstring) ⇒ { format: Integer, heroes: Array<Integer>, cards: Hash{Integer => Integer} }
Decodes a Hearthstone deckstring into format, hero, and card counts.
This method validates the well-formedness of the deckstring and the embedded version, but does not validate the format, individual hero/card IDs, or card counts. For stricter validation and additional deck info, see Deckstrings::Deck.decode.
All IDs refer to unique Hearthstone DBF IDs which can be used in conjunction with HearthstoneJSON metadata.
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 571 572 573 574 575 |
# File 'lib/deckstrings/deckstrings.rb', line 526 def self.decode(deckstring) if deckstring.nil? || deckstring.empty? raise FormatError, 'Invalid deckstring.' end stream = begin StringIO.new(Base64::strict_decode64(deckstring)) rescue ArgumentError raise FormatError, 'Invalid base64-encoded string.' end begin reserved = stream.read_varint if reserved != 0 raise FormatError, "Unexpected reserved byte: #{reserved}." end version = stream.read_varint if version != 1 raise FormatError, "Unexpected version: #{version}." end format = stream.read_varint # Heroes heroes = [] length = stream.read_varint length.times do heroes << stream.read_varint end # Cards cards = {} 1.upto(3) do |i| length = stream.read_varint length.times do card = stream.read_varint cards[card] = i < 3 ? i : stream.read_varint end end rescue EOFError raise FormatError, 'Unexpected end of data.' end return { format: format, heroes: heroes, cards: cards } end |
.encode(format:, heroes:, cards:) ⇒ String
Encodes a Hearthstone deck as a compact deckstring.
This method validates card counts, but does not validate the format or individual hero/card IDs. For stricter validation, see Deckstrings::Deck.encode.
All IDs refer to unique Hearthstone DBF IDs which can be seen in HearthstoneJSON metadata.
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 498 499 500 501 502 503 504 505 506 |
# File 'lib/deckstrings/deckstrings.rb', line 471 def self.encode(format:, heroes:, cards:) stream = StringIO.new('') format = format.is_a?(Deckstrings::Format) ? format.value : format heroes = heroes.map { |hero| hero.is_a?(Deckstrings::Hero) ? hero.id : hero } # Reserved slot, version, and format. stream.write_varint(0) stream.write_varint(1) stream.write_varint(format) # Heroes. stream.write_varint(heroes.length) heroes.sort.each do |hero| stream.write_varint(hero) end # Cards. by_count = cards.group_by { |id, n| n > 2 ? 3 : n } invalid = by_count.keys.select { |count| count < 1 } unless invalid.empty? raise FormatError, "Invalid card count: #{invalid.join(', ')}." end 1.upto(3) do |count| group = by_count[count] || [] stream.write_varint(group.length) group.sort_by { |id, n| id }.each do |id, n| stream.write_varint(id) stream.write_varint(n) if n > 2 end end Base64::strict_encode64(stream.string).strip end |