Last active
August 29, 2015 14:07
-
-
Save tlux/67af92690dd715d1a24b to your computer and use it in GitHub Desktop.
Freelancer Savegame Encoder/Decoder
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # This script is based on the C++ implementation by Sherlog <sherlog@t-online.de> and Jor <flcodec@jors.net> | |
| require 'active_support/all' | |
| require 'singleton' | |
| class FLCodec | |
| include Singleton | |
| class << self | |
| delegate :encode, :decode, :load_file, :decode_file, :encode_file, to: :instance | |
| end | |
| class InvalidData < StandardError | |
| def initialize | |
| super "Stream contains invalid data" | |
| end | |
| end | |
| HEADER = 'FLS1'.freeze | |
| GENE = 'Gene'.freeze | |
| def load_file(filename) | |
| result = StringIO.new | |
| File.open(filename, 'r') do |file| | |
| self.decode(file, result) | |
| end | |
| result.string | |
| end | |
| def decode_file(src_path, dst_path = nil) | |
| convert_file(:decode, src_path, dst_path, '.ini') | |
| end | |
| def decode(src_io, dst_io) | |
| header = src_io.read(HEADER.length) | |
| raise InvalidData unless header == HEADER | |
| convert(src_io, dst_io) | |
| end | |
| def encode_file(src_path, dst_path = nil) | |
| convert_file(:encode, src_path, dst_path, '.fl') | |
| end | |
| def encode(src_io, dst_io) | |
| dst_io.write(HEADER) | |
| convert(src_io, dst_io) | |
| end | |
| private | |
| def convert(src_io, dst_io) | |
| buffer = src_io.read | |
| buffer.each_byte.with_index do |byte, index| | |
| key = (GENE[index % GENE.length].ord + index) % 256 | |
| new_byte = byte ^ (key | 0x80) | |
| dst_io.write(new_byte.chr) | |
| end | |
| true | |
| end | |
| def convert_file(type, src_path, dst_path, default_ext) | |
| dst_path = src_path.chomp(File.extname(src_path)) + default_ext if dst_path.nil? | |
| File.open(src_path, 'r') do |src_file| | |
| File.open(dst_path, 'w') do |dst_file| | |
| self.public_send(type, src_file, dst_file) | |
| end | |
| end | |
| dst_path | |
| end | |
| end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment