local fileFilters = { ["model/vehicle"] = { }, ["model/person"] = { }, ["model/car"] = { }, ["model/rock"] = { }, ["model/tree"] = { }, ["model/signal"] = { }, ["model/other"] = { }, multipleUnit = { }, street = { }, track = { }, bridge = { }, tunnel = { }, railroadCrossing = { }, trafficLight = { }, environment = { }, construction = { }, ["module"] = {}, autoGroundTex = { }, groundTex = { }, terrainGenerator = { }, terrainMaterial = { }, cargoType = { }, grass = { }, gameScript = { }, climate = { }, } function addFileFilter(cat, fn) local ff = fileFilters[cat] ff[#ff + 1] = fn end function clearFileFilter(cat) fileFilters[cat] = {} end function applyFileFilters(cat, fileName, data) local function filter(filters, fileName, data) for i, fn in ipairs(filters) do if not fn(fileName, data) then return nil end end return data end if string.ends(cat, "/") then for k, v in pairs(fileFilters) do if string.starts(k, cat) then local result = filter(v, fileName, data) if result then return result end end end return nil end return filter(fileFilters[cat], fileName, data) end local modifiers = { loadModel = { }, loadModule = { }, loadMultipleUnit = { }, loadStreet = { }, loadTrack = { }, loadBridge = { }, loadTunnel = { }, loadRailroadCrossing = { }, loadTrafficLight = { }, loadEnvironment = { }, loadConstruction = { }, loadConstructionCategory = { }, loadConstructionMenu = { }, loadSoundSet = { }, loadScript = { }, loadTerrainMaterial = { }, loadGrass = { }, loadGameScript = { }, loadGroundTex = { }, loadTerrainGenerator = { }, loadClimate = { }, loadCargoType = { }, } function addModifier(key, fun) table.insert(modifiers[key], fun) end function applyModifiers(key, name, data) for i, v in ipairs(modifiers[key]) do data = v(name, data) end return data end local i18n = { } function setStrings(mod, strings) i18n[mod] = { strings = strings } end function translateModStr(modId, locale, id) --print("translate: ", id, " to ", locale, "\n") if not i18n[modId] then return id end local strings = i18n[modId].strings if strings[locale] then local result = strings[locale][id] if result then return result end end if locale:len() > 2 then local shortLocale = string.sub(locale, 1, 2) --print(" shortLocale: ", shortLocale, "\n") if strings[shortLocale] then local result = strings[shortLocale][id] if result then return result end end end if locale ~= "en" then if strings["en"] then local result = strings["en"][id] if result then return result end end end return id end function _(id) if id == nil or _locale:len() == 0 then return id end if _currentModIdTr ~= nil then local txt = translateModStr(_currentModIdTr, _locale, id) if txt ~= id then return txt end end if _getTextNow then return getTextRes(id) end return id end -- relozu_find_modifiers_and_filefilters_script local rReduceErrorMessagesToMinimum = true local rErrMessages = { } local rModifierFns = table.copy(modifiers) local rFileFilterFns = table.copy(fileFilters) local rLuaTypes = { typeString = type(""), typeNil = type(nil), typeTable = type({ }), typeBoolean = type(true), } local rFnType = { modifier = 0, fileFilter = 1, } local rErrType = { errDefault = 0, errReturn = 1, } local rUnknownMod = "unknown mod" local rUnknownFile = "unknown file" local rUnknownError = "unknown error" local rPrefix = "[relozu_find_modifiers_and_filefilters] " local rDirSeparator = "/" local rQuotationMark = "\"" local rErrorFileFilterDefault = "Error in a fileFilter function: Mod: " local rErrorModifierDefault = "Error in a modifier function: Mod: " local rErrorFileFilterReturn = "Get back wrong value type from a fileFilter function: Mod: " local rErrorModifierReturn = "Get back wrong value type from a modifier function: Mod: " local rGetType = ", Get value type: " local rExpectedTypeText = ", Expected value type: " local rHandledFile = ", Handled file: " local rErrorMsg = ", Error message: " local rModifierType = ", Modifier type: " local rFileFilterType = ", FileFilter type: " -- relozu_find_modifiers_and_filefilters function local function getErrorStrings(t, name, fn) local modCurrent = nil for i = 1, #t, 1 do if t[i].fn == fn then modCurrent = t[i].mod break end end if type(t) ~= rLuaTypes.typeTable then t = { } end if type(modCurrent) ~= rLuaTypes.typeString then modCurrent = rUnknownMod end if type(name) ~= rLuaTypes.typeString then name = rUnknownFile end return modCurrent, name end -- relozu_find_modifiers_and_filefilters function local function printErrorMessage(fn, fnType, key, fileName, val, errType) local modCurrent, errorTypeText, expectedType, fnTypeText, errMessageKey, printMiddlePart if fnType == rFnType.fileFilter then modCurrent, fileName = getErrorStrings(rFileFilterFns[key], fileName, fn) expectedType = rLuaTypes.typeBoolean fnTypeText = rFileFilterType if errType == rErrType.errReturn then errorTypeText = rErrorFileFilterReturn else errorTypeText = rErrorFileFilterDefault end else modCurrent, fileName = getErrorStrings(rModifierFns[key], fileName, fn) expectedType = rLuaTypes.typeTable fnTypeText = rModifierType if errType == rErrType.errReturn then errorTypeText = rErrorModifierReturn else errorTypeText = rErrorModifierDefault end end if errType == rErrType.errReturn then errMessageKey = errorTypeText .. modCurrent .. key .. val .. expectedType else if type(val) ~= rLuaTypes.typeString then val = rUnknownError end if rReduceErrorMessagesToMinimum then errMessageKey = errorTypeText .. modCurrent .. key else errMessageKey = errorTypeText .. modCurrent .. key .. val end end if type(rErrMessages[errMessageKey]) == rLuaTypes.typeNil then rErrMessages[errMessageKey] = 1 if errType == rErrType.errReturn then printMiddlePart = rGetType .. rQuotationMark .. val .. rQuotationMark .. rExpectedTypeText .. rQuotationMark .. expectedType .. rQuotationMark else printMiddlePart = rErrorMsg .. rQuotationMark .. val .. rQuotationMark end print(rPrefix .. errorTypeText .. rQuotationMark .. modCurrent .. rQuotationMark .. fnTypeText .. rQuotationMark .. key .. rQuotationMark .. printMiddlePart .. rHandledFile .. rQuotationMark .. fileName .. rQuotationMark) end end -- relozu_find_modifiers_and_filefilters function addFileFilter = function(cat, fn) table.insert(fileFilters[cat], fn) table.insert(rFileFilterFns[cat], { mod = getCurrentModId(), fn = fn }) end -- relozu_find_modifiers_and_filefilters function clearFileFilter = function(cat) fileFilters[cat] = { } rFileFilterFns[cat] = { } end -- relozu_find_modifiers_and_filefilters function applyFileFilters = function(cat, fileName, data) local function filter(filters, fileName, data) local worked, modCurrent, val for i, fn in ipairs(filters) do worked, val = pcall(fn, fileName, data) if not worked then printErrorMessage(fn, rFnType.fileFilter, cat, fileName, val, rErrType.errDefault) else if type(val) == rLuaTypes.typeBoolean then if not val then return nil end else printErrorMessage(fn, rFnType.fileFilter, cat, fileName, type(val), rErrType.errReturn) end end end return data end if string.ends(cat, rDirSeparator) then for k, v in pairs(fileFilters) do if string.starts(k, cat) then local result = filter(v, fileName, data) if result then return result end end end return nil end return filter(fileFilters[cat], fileName, data) end -- relozu_find_modifiers_and_filefilters function addModifier = function(key, fun) table.insert(modifiers[key], fun) table.insert(rModifierFns[key], { mod = getCurrentModId(), fn = fun }) end -- relozu_find_modifiers_and_filefilters function applyModifiers = function(key, name, data) local worked, modCurrent, val for k, fn in ipairs(modifiers[key]) do worked, val = pcall(fn, name, data) if not worked then printErrorMessage(fn, rFnType.modifier, key, name, val, rErrType.errDefault) else if type(val) == rLuaTypes.typeTable then data = val else printErrorMessage(fn, rFnType.modifier, key, name, type(val), rErrType.errReturn) end end end return data end