Module: TT2::SaveParser

Defined in:
lib/tt2/save_parser.rb

Overview

Initial Ruby save-file parser from www.reddit.com/r/TapTitans2/comments/5zzhx1/clan_mgmt_101_import_save_twice_a_day_kick/df37xnv/ modified to clean up a bit.

Constant Summary collapse

ENCRYPTION_KEY =
['4bc07927192f4e9a'].pack('H*')

Class Method Summary collapse

Class Method Details

.decrypt(encrypted) ⇒ Object



23
24
25
26
27
28
29
30
31
32
33
# File 'lib/tt2/save_parser.rb', line 23

def decrypt(encrypted)
  iv = encrypted.shift(8).pack('c*')
  encrypted = encrypted.pack('c*')

  des = OpenSSL::Cipher.new('DES-CBC')
  des.decrypt
  des.key = ENCRYPTION_KEY
  des.iv = iv

  des.update(encrypted) + des.final
end

.parse_json(json) ⇒ Object



35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/tt2/save_parser.rb', line 35

def parse_json(json)
  # For stripping the JSON of the .NET-special fields `$content` and `$type`
  clean_up = proc do |o|
    next unless o.is_a? Hash
    o.each_pair do |k, v|
      next unless v.is_a? Hash
      v.delete('$type')
      o[k] = v['$content'] if v.key?('$content')
    end
  end

  JSON.load(JSON.load(json), clean_up) # rubocop:disable Security/JSONLoad
end

.read(filename = 'ISavableGlobal.adat') ⇒ Object



12
13
14
15
16
17
18
19
20
21
# File 'lib/tt2/save_parser.rb', line 12

def read(filename = 'ISavableGlobal.adat')
  encrypted = File.read(filename).bytes

  plain = decrypt(encrypted)

  json = plain.slice(plain.index('saveString') + 12...
                     plain.index('playerData') - 2)

  parse_json(json)
end