{File, Directory} = require 'atom' fs = require 'fs' module.exports = class QspDecoder constructor: (@data, @file) -> @decodeFile() decodeFile: -> prepare = @prepare() if !prepare return version = @readLine(prepare) console.log @toString(version.line) password = @readLine(version.next) console.log @toString @decode password.line locations = @readLine password.next locationsNumber = (@toString @decode locations.line).valueOf() next = locations.next builder = new ProjectBuilder(@config) for i in [0...locationsNumber] location = @readLocation next next = location.next builder.createLocation location prepare: -> @config = {} @config.ucs2le = @data[1] == 0 @config.crlf = @data[7 * if @config.ucs2le then 2 else 1] == 13 @config.encodedPath = @file.getPath() check = @readLine(0, 9) if @toString(check.line) == 'QSPGAME' return check.next else return 0 readLocation: (position) -> name = @readLine position description = @readLine name.next code = @readLine description.next actions = @readLine code.next actionsNumber = (@toString @decode actions.line).valueOf() next = actions.next actions = [] for i in [0...actionsNumber] action = @readAction next next = action.next actions.push(action) name: @toString @decode name.line description: @toString @decode description.line code: @toString @decode code.line actions: actions next: next readAction: (position) -> picture = @readLine position name = @readLine picture.next code = @readLine name.next picture: @toString @decode picture.line name: @toString @decode name.line code: @toString @decode code.line next: code.next readLine: (start, max) -> counter = start line = [] that = @ check = -> if that.config.crlf return line[line.length - 1] == 10 and line[line.length - 2] == 13 else return line[line.length - 1] == 10 while !check() and counter < @data.length line.push(@readSymbol(counter)) counter += if @config.ucs2le then 2 else 1 if max and line.length > max break line: if line.length > 0 then line[0...if @config.crlf then -2 else -1] else [] next: counter readSymbol: (position) -> code = @data[position] code += @data[position + 1] * 256 if @config.ucs2le return code decode: (line) -> for i in [0...line.length] line[i] += 5 return line toString: (line) -> result = "" step = 65535 for i in [0...line.length] by step result += String.fromCharCode.apply(@, line[i...i + step]) return result class ProjectBuilder constructor: (@config) -> @directoryStack = [] @root = new Directory(@config.encodedPath[0...@config.encodedPath.lastIndexOf('.')]) try fs.mkdirSync(@root.getPath(), 0o755) catch error createLocation: (location) -> fs.writeFileSync("#{@root.getPath()}/#{location.name}.qsrc", location.code, {mode: 0o644}) createDirectoryRecursive: (directory, callback) -> if directory.getParent().exists() that = @ directory.create(0o755).then(() -> if that.directoryStack.length > 0 that.createDirectoryRecursive(that.directoryStack.pop(), callback) else callback() ) else @directoryStack.push(directory) createDirectoryRecursive(directory.getParent(), callback) write: (path, data) ->