local C = Class:extend() -- local ITEM_DATA = require 'database.items' local OPTIONAL_REPLACES = { 'Max health increased by ', 'Max life increased by ', '= 1 end function C:placeItemAtLocation(item, location) local wasChanged self._text, wasChanged = self:_stringReplace(self._text, " pEnd then -- This is totally normal and can be ignored. logNotice(('Found "%s", but was outside of label.'):format(needle, replacement)) return text, false end local len = needle:len() local j = i + len - 1 assert((i % 1 == 0) and (i > 0) and (i <= j), tostring(i)) assert((j % 1 == 0), tostring(j)) local a = text:sub(1, i - 1) local b = text:sub(j + 1) return a .. replacement .. b, true end function C:_getLabelPositionRange(label) local labelStart, labelEnd -- Recursive shit for when label is a table... if type(label) == 'table' then labelStart, labelEnd = math.huge, 0 for _, _label in ipairs(label) do local _start, _end = self:_getLabelPositionRange(_label) labelStart = math.min(labelStart, _start) labelEnd = math.max(labelEnd, _end) end return labelStart, labelEnd end assert(type(label) == 'string') assert(#label == 4) assert(tonumber(label) >= 1) assert(tonumber(label) <= 9999) local i = 1 local labelPattern = "#%d%d%d%d\r\n" while true do local j = self._text:find(labelPattern, i) if j == nil then break end i = j + 1 if labelStart then labelEnd = j - 1 break end local _label = self._text:sub(j + 1, j + 4) if label == _label then labelStart = j end end if labelStart == nil then logError(("%s: Could not find label: %s"):format(self.mapName, label)) labelStart = 1 end if labelEnd == nil then labelEnd = #self._text end return labelStart, labelEnd end function C:writePlaintextTo(path) logInfo('writing Plaintext TSC to: ' .. path) U.writeFile(path, self._text) end function C:writeTo(path) logInfo('writing TSC to: ' .. path) local encoded = self:_codec(self._text, 'encode') U.writeFile(path, encoded) end function C:_codec(text, mode) -- Create array of chars. local chars = {} text:gsub(".", function(c) table.insert(chars, c) end) -- Determine encoding char value local encodingCharPosition = math.floor(#chars / 2) + 1 local encodingChar = chars[encodingCharPosition]:byte() if mode == 'decode' then encodingChar = encodingChar * -1 elseif mode == 'encode' then -- OK! else error('Unknown codec mode: ' .. tostring(mode)) end logDebug(" filesize", #chars) logDebug(" encoding char:", encodingChar) logDebug(" encoding char position:", encodingCharPosition) -- Encode or decode. for pos, char in ipairs(chars) do if pos ~= encodingCharPosition then local byte = (char:byte() + encodingChar) % 256 chars[pos] = string.char(byte) end end local decoded = table.concat(chars) return decoded end return C