diff --git a/modules/events-mod/build.gradle.kts b/modules/events-mod/build.gradle.kts index 1f9084d..bbfb92e 100644 --- a/modules/events-mod/build.gradle.kts +++ b/modules/events-mod/build.gradle.kts @@ -71,7 +71,8 @@ val typescriptToLua by tasks.registering(TypescriptToLuaTask::class) { dependsOn(tasks.npmInstall, installEventsTsSchema, tasks.updatePackageJson) sourceFiles.set(tsSrcDir) - outputDirectory.set(layout.buildDirectory.dir("typescriptToLua")) +// outputDirectory.set(layout.buildDirectory.dir("typescriptToLua")) + outputDirectory.set(layout.projectDirectory.dir("src/main/lua")) } @@ -80,7 +81,6 @@ val installEventsTsSchema by tasks.registering(Sync::class) { group = project.name dependsOn(typescriptEventsSchema) -// dependsOn(fixLink) val outputDir = layout.projectDirectory.dir("src/main/typescript/generated/") outputs.dir(outputDir) @@ -140,6 +140,8 @@ distributions { from(licenseFile) from(typescriptToLua.map { it.outputDirectory }) filesNotMatching("**/*.png") { + // maybe make a bug report for projectTokensX1 causing null$null$null error? + // val tokens333: MutableMap = projectTokensX1.get() filter("tokens" to tokens333) } includeEmptyDirs = false @@ -160,7 +162,6 @@ tasks.withType().configureEach { } - val factorioModProvider by configurations.registering { asProvider() factorioModAttributes(objects) @@ -185,14 +186,34 @@ tasks.assemble { dependsOn(installEventsTsSchema, tasks.updatePackageJson) } idea { module { - sourceDirs = sourceDirs + file("src/main/typescript") + sourceDirs.plusAssign( + listOf( + file("src/main/typescript"), + file("src/main/lua"), + ) + ) +// sourceDirs = sourceDirs + file("src/main/lua") resourceDirs = resourceDirs + file("src/main/resources") testSourceDirs = testSourceDirs + file("src/test/typescript") + + generatedSourceDirs = generatedSourceDirs + listOf( + file("src/main/lua") + ) iml { whenMerged { require(this is org.gradle.plugins.ide.idea.model.Module) - sourceDirs = sourceDirs + file("src/main/typescript") + sourceDirs.plusAssign( + listOf( + file("src/main/typescript"), + file("src/main/lua"), + ) + ) + + generatedSourceFolders.plusAssign( + org.gradle.plugins.ide.idea.model.Path(file("src/main/lua").toURI().toString()) + ) +// sourceDirs = sourceDirs + file("src/main/typescript") resourceDirs = resourceDirs + file("src/main/resources") testSourceDirs = testSourceDirs + file("src/test/typescript") } diff --git a/modules/events-mod/src/main/lua/control.lua b/modules/events-mod/src/main/lua/control.lua new file mode 100644 index 0000000..0bd8e16 --- /dev/null +++ b/modules/events-mod/src/main/lua/control.lua @@ -0,0 +1,15 @@ +local ____exports = {} +local ____global_2Dinit = require("main.global-init") +local initGlobal = ____global_2Dinit.initGlobal +local ____prototypeUpdates = require("main.events.prototypeUpdates") +local emitPrototypes = ____prototypeUpdates.emitPrototypes +require("main.events.registerHandlers") +require("main.events.mapChunkUpdates") +require("main.events.playerUpdates") +require("main.events.entityUpdates") +require("main.commands.kafkatorioCommands") +script.on_init(function() + initGlobal(true) + emitPrototypes() +end) +return ____exports diff --git a/modules/events-mod/src/main/lua/generated/kafkatorio-schema.lua b/modules/events-mod/src/main/lua/generated/kafkatorio-schema.lua new file mode 100644 index 0000000..65df7de --- /dev/null +++ b/modules/events-mod/src/main/lua/generated/kafkatorio-schema.lua @@ -0,0 +1,26 @@ +local ____exports = {} +____exports.KafkatorioPacketData = {} +local KafkatorioPacketData = ____exports.KafkatorioPacketData +do + KafkatorioPacketData.Type = Type or ({}) + KafkatorioPacketData.Type.ConfigurationUpdate = "kafkatorio.packet.instant.ConfigurationUpdate" + KafkatorioPacketData.Type.ConsoleChatUpdate = "kafkatorio.packet.instant.ConsoleChatUpdate" + KafkatorioPacketData.Type.ConsoleCommandUpdate = "kafkatorio.packet.instant.ConsoleCommandUpdate" + KafkatorioPacketData.Type.PrototypesUpdate = "kafkatorio.packet.instant.PrototypesUpdate" + KafkatorioPacketData.Type.SurfaceUpdate = "kafkatorio.packet.instant.SurfaceUpdate" + KafkatorioPacketData.Type.EntityUpdate = "kafkatorio.packet.keyed.EntityUpdate" + KafkatorioPacketData.Type.MapChunkUpdate = "kafkatorio.packet.keyed.MapChunkUpdate" + KafkatorioPacketData.Type.PlayerUpdate = "kafkatorio.packet.keyed.PlayerUpdate" + KafkatorioPacketData.Type.Error = "kafkatorio.packet.KafkatorioPacketData.Error" +end +____exports.FactorioPrototype = {} +local FactorioPrototype = ____exports.FactorioPrototype +do + FactorioPrototype.Type = Type or ({}) + FactorioPrototype.Type.Entity = "kafkatorio.prototype.Entity" + FactorioPrototype.Type.MapTile = "kafkatorio.prototype.MapTile" +end +____exports.MinedProductType = MinedProductType or ({}) +____exports.MinedProductType.item = "item" +____exports.MinedProductType.fluid = "fluid" +return ____exports diff --git a/modules/events-mod/src/main/lua/lualib_bundle.lua b/modules/events-mod/src/main/lua/lualib_bundle.lua new file mode 100644 index 0000000..e76c793 --- /dev/null +++ b/modules/events-mod/src/main/lua/lualib_bundle.lua @@ -0,0 +1,2475 @@ +local function __TS__ArrayIsArray(value) + return type(value) == "table" and (value[1] ~= nil or next(value) == nil) +end + +local function __TS__ArrayConcat(self, ...) + local items = {...} + local result = {} + local len = 0 + for i = 1, #self do + len = len + 1 + result[len] = self[i] + end + for i = 1, #items do + local item = items[i] + if __TS__ArrayIsArray(item) then + for j = 1, #item do + len = len + 1 + result[len] = item[j] + end + else + len = len + 1 + result[len] = item + end + end + return result +end + +local __TS__Symbol, Symbol +do + local symbolMetatable = {__tostring = function(self) + return ("Symbol(" .. (self.description or "")) .. ")" + end} + function __TS__Symbol(description) + return setmetatable({description = description}, symbolMetatable) + end + Symbol = { + iterator = __TS__Symbol("Symbol.iterator"), + hasInstance = __TS__Symbol("Symbol.hasInstance"), + species = __TS__Symbol("Symbol.species"), + toStringTag = __TS__Symbol("Symbol.toStringTag") + } +end + +local function __TS__ArrayEntries(array) + local key = 0 + return { + [Symbol.iterator] = function(self) + return self + end, + next = function(self) + local result = {done = array[key + 1] == nil, value = {key, array[key + 1]}} + key = key + 1 + return result + end + } +end + +local function __TS__ArrayEvery(self, callbackfn, thisArg) + for i = 1, #self do + if not callbackfn(thisArg, self[i], i - 1, self) then + return false + end + end + return true +end + +local function __TS__ArrayFilter(self, callbackfn, thisArg) + local result = {} + local len = 0 + for i = 1, #self do + if callbackfn(thisArg, self[i], i - 1, self) then + len = len + 1 + result[len] = self[i] + end + end + return result +end + +local function __TS__ArrayForEach(self, callbackFn, thisArg) + for i = 1, #self do + callbackFn(thisArg, self[i], i - 1, self) + end +end + +local function __TS__ArrayFind(self, predicate, thisArg) + for i = 1, #self do + local elem = self[i] + if predicate(thisArg, elem, i - 1, self) then + return elem + end + end + return nil +end + +local function __TS__ArrayFindIndex(self, callbackFn, thisArg) + for i = 1, #self do + if callbackFn(thisArg, self[i], i - 1, self) then + return i - 1 + end + end + return -1 +end + +local __TS__Iterator +do + local function iteratorGeneratorStep(self) + local co = self.____coroutine + local status, value = coroutine.resume(co) + if not status then + error(value, 0) + end + if coroutine.status(co) == "dead" then + return + end + return true, value + end + local function iteratorIteratorStep(self) + local result = self:next() + if result.done then + return + end + return true, result.value + end + local function iteratorStringStep(self, index) + index = index + 1 + if index > #self then + return + end + return index, string.sub(self, index, index) + end + function __TS__Iterator(iterable) + if type(iterable) == "string" then + return iteratorStringStep, iterable, 0 + elseif iterable.____coroutine ~= nil then + return iteratorGeneratorStep, iterable + elseif iterable[Symbol.iterator] then + local iterator = iterable[Symbol.iterator](iterable) + return iteratorIteratorStep, iterator + else + return ipairs(iterable) + end + end +end + +local __TS__ArrayFrom +do + local function arrayLikeStep(self, index) + index = index + 1 + if index > self.length then + return + end + return index, self[index] + end + local function arrayLikeIterator(arr) + if type(arr.length) == "number" then + return arrayLikeStep, arr, 0 + end + return __TS__Iterator(arr) + end + function __TS__ArrayFrom(arrayLike, mapFn, thisArg) + local result = {} + if mapFn == nil then + for ____, v in arrayLikeIterator(arrayLike) do + result[#result + 1] = v + end + else + for i, v in arrayLikeIterator(arrayLike) do + result[#result + 1] = mapFn(thisArg, v, i - 1) + end + end + return result + end +end + +local function __TS__ArrayIncludes(self, searchElement, fromIndex) + if fromIndex == nil then + fromIndex = 0 + end + local len = #self + local k = fromIndex + if fromIndex < 0 then + k = len + fromIndex + end + if k < 0 then + k = 0 + end + for i = k + 1, len do + if self[i] == searchElement then + return true + end + end + return false +end + +local function __TS__ArrayIndexOf(self, searchElement, fromIndex) + if fromIndex == nil then + fromIndex = 0 + end + local len = #self + if len == 0 then + return -1 + end + if fromIndex >= len then + return -1 + end + if fromIndex < 0 then + fromIndex = len + fromIndex + if fromIndex < 0 then + fromIndex = 0 + end + end + for i = fromIndex + 1, len do + if self[i] == searchElement then + return i - 1 + end + end + return -1 +end + +local function __TS__ArrayJoin(self, separator) + if separator == nil then + separator = "," + end + local parts = {} + for i = 1, #self do + parts[i] = tostring(self[i]) + end + return table.concat(parts, separator) +end + +local function __TS__ArrayMap(self, callbackfn, thisArg) + local result = {} + for i = 1, #self do + result[i] = callbackfn(thisArg, self[i], i - 1, self) + end + return result +end + +local function __TS__ArrayPush(self, ...) + local items = {...} + local len = #self + for i = 1, #items do + len = len + 1 + self[len] = items[i] + end + return len +end + +local function __TS__ArrayPushArray(self, items) + local len = #self + for i = 1, #items do + len = len + 1 + self[len] = items[i] + end + return len +end + +local function __TS__ArrayReduce(self, callbackFn, ...) + local len = #self + local k = 0 + local accumulator = nil + if select("#", ...) ~= 0 then + accumulator = ... + elseif len > 0 then + accumulator = self[1] + k = 1 + else + error("Reduce of empty array with no initial value", 0) + end + for i = k + 1, len do + accumulator = callbackFn( + nil, + accumulator, + self[i], + i - 1, + self + ) + end + return accumulator +end + +local function __TS__ArrayReduceRight(self, callbackFn, ...) + local len = #self + local k = len - 1 + local accumulator = nil + if select("#", ...) ~= 0 then + accumulator = ... + elseif len > 0 then + accumulator = self[k + 1] + k = k - 1 + else + error("Reduce of empty array with no initial value", 0) + end + for i = k + 1, 1, -1 do + accumulator = callbackFn( + nil, + accumulator, + self[i], + i - 1, + self + ) + end + return accumulator +end + +local function __TS__ArrayReverse(self) + local i = 1 + local j = #self + while i < j do + local temp = self[j] + self[j] = self[i] + self[i] = temp + i = i + 1 + j = j - 1 + end + return self +end + +local function __TS__ArrayUnshift(self, ...) + local items = {...} + local numItemsToInsert = #items + if numItemsToInsert == 0 then + return #self + end + for i = #self, 1, -1 do + self[i + numItemsToInsert] = self[i] + end + for i = 1, numItemsToInsert do + self[i] = items[i] + end + return #self +end + +local function __TS__ArraySort(self, compareFn) + if compareFn ~= nil then + table.sort( + self, + function(a, b) return compareFn(nil, a, b) < 0 end + ) + else + table.sort(self) + end + return self +end + +local function __TS__ArraySlice(self, first, last) + local len = #self + first = first or 0 + if first < 0 then + first = len + first + if first < 0 then + first = 0 + end + else + if first > len then + first = len + end + end + last = last or len + if last < 0 then + last = len + last + if last < 0 then + last = 0 + end + else + if last > len then + last = len + end + end + local out = {} + first = first + 1 + last = last + 1 + local n = 1 + while first < last do + out[n] = self[first] + first = first + 1 + n = n + 1 + end + return out +end + +local function __TS__ArraySome(self, callbackfn, thisArg) + for i = 1, #self do + if callbackfn(thisArg, self[i], i - 1, self) then + return true + end + end + return false +end + +local function __TS__ArraySplice(self, ...) + local args = {...} + local len = #self + local actualArgumentCount = select("#", ...) + local start = args[1] + local deleteCount = args[2] + if start < 0 then + start = len + start + if start < 0 then + start = 0 + end + elseif start > len then + start = len + end + local itemCount = actualArgumentCount - 2 + if itemCount < 0 then + itemCount = 0 + end + local actualDeleteCount + if actualArgumentCount == 0 then + actualDeleteCount = 0 + elseif actualArgumentCount == 1 then + actualDeleteCount = len - start + else + actualDeleteCount = deleteCount or 0 + if actualDeleteCount < 0 then + actualDeleteCount = 0 + end + if actualDeleteCount > len - start then + actualDeleteCount = len - start + end + end + local out = {} + for k = 1, actualDeleteCount do + local from = start + k + if self[from] ~= nil then + out[k] = self[from] + end + end + if itemCount < actualDeleteCount then + for k = start + 1, len - actualDeleteCount do + local from = k + actualDeleteCount + local to = k + itemCount + if self[from] then + self[to] = self[from] + else + self[to] = nil + end + end + for k = len - actualDeleteCount + itemCount + 1, len do + self[k] = nil + end + elseif itemCount > actualDeleteCount then + for k = len - actualDeleteCount, start + 1, -1 do + local from = k + actualDeleteCount + local to = k + itemCount + if self[from] then + self[to] = self[from] + else + self[to] = nil + end + end + end + local j = start + 1 + for i = 3, actualArgumentCount do + self[j] = args[i] + j = j + 1 + end + for k = #self, len - actualDeleteCount + itemCount + 1, -1 do + self[k] = nil + end + return out +end + +local function __TS__ArrayToObject(self) + local object = {} + for i = 1, #self do + object[i - 1] = self[i] + end + return object +end + +local function __TS__ArrayFlat(self, depth) + if depth == nil then + depth = 1 + end + local result = {} + local len = 0 + for i = 1, #self do + local value = self[i] + if depth > 0 and __TS__ArrayIsArray(value) then + local toAdd + if depth == 1 then + toAdd = value + else + toAdd = __TS__ArrayFlat(value, depth - 1) + end + for j = 1, #toAdd do + local val = toAdd[j] + len = len + 1 + result[len] = val + end + else + len = len + 1 + result[len] = value + end + end + return result +end + +local function __TS__ArrayFlatMap(self, callback, thisArg) + local result = {} + local len = 0 + for i = 1, #self do + local value = callback(thisArg, self[i], i - 1, self) + if __TS__ArrayIsArray(value) then + for j = 1, #value do + len = len + 1 + result[len] = value[j] + end + else + len = len + 1 + result[len] = value + end + end + return result +end + +local function __TS__ArraySetLength(self, length) + if length < 0 or length ~= length or length == math.huge or math.floor(length) ~= length then + error( + "invalid array length: " .. tostring(length), + 0 + ) + end + for i = length + 1, #self do + self[i] = nil + end + return length +end + +local function __TS__InstanceOf(obj, classTbl) + if type(classTbl) ~= "table" then + error("Right-hand side of 'instanceof' is not an object", 0) + end + if classTbl[Symbol.hasInstance] ~= nil then + return not not classTbl[Symbol.hasInstance](classTbl, obj) + end + if type(obj) == "table" then + local luaClass = obj.constructor + while luaClass ~= nil do + if luaClass == classTbl then + return true + end + luaClass = luaClass.____super + end + end + return false +end + +local function __TS__New(target, ...) + local instance = setmetatable({}, target.prototype) + instance:____constructor(...) + return instance +end + +local function __TS__Class(self) + local c = {prototype = {}} + c.prototype.__index = c.prototype + c.prototype.constructor = c + return c +end + +local __TS__Unpack = table.unpack or unpack + +local function __TS__FunctionBind(fn, ...) + local boundArgs = {...} + return function(____, ...) + local args = {...} + __TS__ArrayUnshift( + args, + __TS__Unpack(boundArgs) + ) + return fn(__TS__Unpack(args)) + end +end + +local __TS__Promise +do + local function promiseDeferred(self) + local resolve + local reject + local promise = __TS__New( + __TS__Promise, + function(____, res, rej) + resolve = res + reject = rej + end + ) + return {promise = promise, resolve = resolve, reject = reject} + end + local function isPromiseLike(self, thing) + return __TS__InstanceOf(thing, __TS__Promise) + end + __TS__Promise = __TS__Class() + __TS__Promise.name = "__TS__Promise" + function __TS__Promise.prototype.____constructor(self, executor) + self.state = 0 + self.fulfilledCallbacks = {} + self.rejectedCallbacks = {} + self.finallyCallbacks = {} + do + local function ____catch(e) + self:reject(e) + end + local ____try, ____hasReturned = pcall(function() + executor( + nil, + __TS__FunctionBind(self.resolve, self), + __TS__FunctionBind(self.reject, self) + ) + end) + if not ____try then + ____catch(____hasReturned) + end + end + end + function __TS__Promise.resolve(data) + local promise = __TS__New( + __TS__Promise, + function() + end + ) + promise.state = 1 + promise.value = data + return promise + end + function __TS__Promise.reject(reason) + local promise = __TS__New( + __TS__Promise, + function() + end + ) + promise.state = 2 + promise.rejectionReason = reason + return promise + end + __TS__Promise.prototype["then"] = function(self, onFulfilled, onRejected) + local ____promiseDeferred_result_0 = promiseDeferred(nil) + local promise = ____promiseDeferred_result_0.promise + local resolve = ____promiseDeferred_result_0.resolve + local reject = ____promiseDeferred_result_0.reject + local isFulfilled = self.state == 1 + local isRejected = self.state == 2 + if onFulfilled then + local internalCallback = self:createPromiseResolvingCallback(onFulfilled, resolve, reject) + local ____self_fulfilledCallbacks_1 = self.fulfilledCallbacks + ____self_fulfilledCallbacks_1[#____self_fulfilledCallbacks_1 + 1] = internalCallback + if isFulfilled then + internalCallback(nil, self.value) + end + else + local ____self_fulfilledCallbacks_2 = self.fulfilledCallbacks + ____self_fulfilledCallbacks_2[#____self_fulfilledCallbacks_2 + 1] = function() return resolve(nil, nil) end + end + if onRejected then + local internalCallback = self:createPromiseResolvingCallback(onRejected, resolve, reject) + local ____self_rejectedCallbacks_3 = self.rejectedCallbacks + ____self_rejectedCallbacks_3[#____self_rejectedCallbacks_3 + 1] = internalCallback + if isRejected then + internalCallback(nil, self.rejectionReason) + end + end + if isFulfilled then + resolve(nil, self.value) + end + if isRejected then + reject(nil, self.rejectionReason) + end + return promise + end + function __TS__Promise.prototype.catch(self, onRejected) + return self["then"](self, nil, onRejected) + end + function __TS__Promise.prototype.finally(self, onFinally) + if onFinally then + local ____self_finallyCallbacks_4 = self.finallyCallbacks + ____self_finallyCallbacks_4[#____self_finallyCallbacks_4 + 1] = onFinally + if self.state ~= 0 then + onFinally(nil) + end + end + return self + end + function __TS__Promise.prototype.resolve(self, data) + if __TS__InstanceOf(data, __TS__Promise) then + data["then"]( + data, + function(____, v) return self:resolve(v) end, + function(____, err) return self:reject(err) end + ) + return + end + if self.state == 0 then + self.state = 1 + self.value = data + for ____, callback in ipairs(self.fulfilledCallbacks) do + callback(nil, data) + end + for ____, callback in ipairs(self.finallyCallbacks) do + callback(nil) + end + end + end + function __TS__Promise.prototype.reject(self, reason) + if self.state == 0 then + self.state = 2 + self.rejectionReason = reason + for ____, callback in ipairs(self.rejectedCallbacks) do + callback(nil, reason) + end + for ____, callback in ipairs(self.finallyCallbacks) do + callback(nil) + end + end + end + function __TS__Promise.prototype.createPromiseResolvingCallback(self, f, resolve, reject) + return function(____, value) + do + local function ____catch(e) + reject(nil, e) + end + local ____try, ____hasReturned = pcall(function() + self:handleCallbackData( + f(nil, value), + resolve, + reject + ) + end) + if not ____try then + ____catch(____hasReturned) + end + end + end + end + function __TS__Promise.prototype.handleCallbackData(self, data, resolve, reject) + if isPromiseLike(nil, data) then + local nextpromise = data + if nextpromise.state == 1 then + resolve(nil, nextpromise.value) + elseif nextpromise.state == 2 then + reject(nil, nextpromise.rejectionReason) + else + data["then"](data, resolve, reject) + end + else + resolve(nil, data) + end + end +end + +local function __TS__AsyncAwaiter(generator) + return __TS__New( + __TS__Promise, + function(____, resolve, reject) + local adopt, fulfilled, step, resolved, asyncCoroutine + function adopt(self, value) + local ____temp_0 + if __TS__InstanceOf(value, __TS__Promise) then + ____temp_0 = value + else + ____temp_0 = __TS__Promise.resolve(value) + end + return ____temp_0 + end + function fulfilled(self, value) + local success, resultOrError = coroutine.resume(asyncCoroutine, value) + if success then + step(nil, resultOrError) + else + reject(nil, resultOrError) + end + end + function step(self, result) + if resolved then + return + end + if coroutine.status(asyncCoroutine) == "dead" then + resolve(nil, result) + else + local ____self_1 = adopt(nil, result) + ____self_1["then"](____self_1, fulfilled, reject) + end + end + resolved = false + asyncCoroutine = coroutine.create(generator) + local success, resultOrError = coroutine.resume( + asyncCoroutine, + function(____, v) + resolved = true + local ____self_2 = adopt(nil, v) + ____self_2["then"](____self_2, resolve, reject) + end + ) + if success then + step(nil, resultOrError) + else + reject(nil, resultOrError) + end + end + ) +end +local function __TS__Await(thing) + return coroutine.yield(thing) +end + +local function __TS__ClassExtends(target, base) + target.____super = base + local staticMetatable = setmetatable({__index = base}, base) + setmetatable(target, staticMetatable) + local baseMetatable = getmetatable(base) + if baseMetatable then + if type(baseMetatable.__index) == "function" then + staticMetatable.__index = baseMetatable.__index + end + if type(baseMetatable.__newindex) == "function" then + staticMetatable.__newindex = baseMetatable.__newindex + end + end + setmetatable(target.prototype, base.prototype) + if type(base.prototype.__index) == "function" then + target.prototype.__index = base.prototype.__index + end + if type(base.prototype.__newindex) == "function" then + target.prototype.__newindex = base.prototype.__newindex + end + if type(base.prototype.__tostring) == "function" then + target.prototype.__tostring = base.prototype.__tostring + end +end + +local function __TS__CloneDescriptor(____bindingPattern0) + local value + local writable + local set + local get + local configurable + local enumerable + enumerable = ____bindingPattern0.enumerable + configurable = ____bindingPattern0.configurable + get = ____bindingPattern0.get + set = ____bindingPattern0.set + writable = ____bindingPattern0.writable + value = ____bindingPattern0.value + local descriptor = {enumerable = enumerable == true, configurable = configurable == true} + local hasGetterOrSetter = get ~= nil or set ~= nil + local hasValueOrWritableAttribute = writable ~= nil or value ~= nil + if hasGetterOrSetter and hasValueOrWritableAttribute then + error("Invalid property descriptor. Cannot both specify accessors and a value or writable attribute.", 0) + end + if get or set then + descriptor.get = get + descriptor.set = set + else + descriptor.value = value + descriptor.writable = writable == true + end + return descriptor +end + +local function __TS__ObjectAssign(target, ...) + local sources = {...} + for i = 1, #sources do + local source = sources[i] + for key in pairs(source) do + target[key] = source[key] + end + end + return target +end + +local function __TS__ObjectGetOwnPropertyDescriptor(object, key) + local metatable = getmetatable(object) + if not metatable then + return + end + if not rawget(metatable, "_descriptors") then + return + end + return rawget(metatable, "_descriptors")[key] +end + +local __TS__SetDescriptor +do + local function descriptorIndex(self, key) + local value = rawget(self, key) + if value ~= nil then + return value + end + local metatable = getmetatable(self) + while metatable do + local rawResult = rawget(metatable, key) + if rawResult ~= nil then + return rawResult + end + local descriptors = rawget(metatable, "_descriptors") + if descriptors then + local descriptor = descriptors[key] + if descriptor then + if descriptor.get then + return descriptor.get(self) + end + return descriptor.value + end + end + metatable = getmetatable(metatable) + end + end + local function descriptorNewIndex(self, key, value) + local metatable = getmetatable(self) + while metatable do + local descriptors = rawget(metatable, "_descriptors") + if descriptors then + local descriptor = descriptors[key] + if descriptor then + if descriptor.set then + descriptor.set(self, value) + else + if descriptor.writable == false then + error( + ((("Cannot assign to read only property '" .. key) .. "' of object '") .. tostring(self)) .. "'", + 0 + ) + end + descriptor.value = value + end + return + end + end + metatable = getmetatable(metatable) + end + rawset(self, key, value) + end + function __TS__SetDescriptor(target, key, desc, isPrototype) + if isPrototype == nil then + isPrototype = false + end + local ____isPrototype_0 + if isPrototype then + ____isPrototype_0 = target + else + ____isPrototype_0 = getmetatable(target) + end + local metatable = ____isPrototype_0 + if not metatable then + metatable = {} + setmetatable(target, metatable) + end + local value = rawget(target, key) + if value ~= nil then + rawset(target, key, nil) + end + if not rawget(metatable, "_descriptors") then + metatable._descriptors = {} + end + local descriptor = __TS__CloneDescriptor(desc) + metatable._descriptors[key] = descriptor + metatable.__index = descriptorIndex + metatable.__newindex = descriptorNewIndex + end +end + +local function __TS__Decorate(decorators, target, key, desc) + local result = target + do + local i = #decorators + while i >= 0 do + local decorator = decorators[i + 1] + if decorator then + local oldResult = result + if key == nil then + result = decorator(nil, result) + elseif desc == true then + local value = rawget(target, key) + local descriptor = __TS__ObjectGetOwnPropertyDescriptor(target, key) or ({configurable = true, writable = true, value = value}) + local desc = decorator(nil, target, key, descriptor) or descriptor + local isSimpleValue = desc.configurable == true and desc.writable == true and not desc.get and not desc.set + if isSimpleValue then + rawset(target, key, desc.value) + else + __TS__SetDescriptor( + target, + key, + __TS__ObjectAssign({}, descriptor, desc) + ) + end + elseif desc == false then + result = decorator(nil, target, key, desc) + else + result = decorator(nil, target, key) + end + result = result or oldResult + end + i = i - 1 + end + end + return result +end + +local function __TS__DecorateParam(paramIndex, decorator) + return function(____, target, key) return decorator(nil, target, key, paramIndex) end +end + +local Error, RangeError, ReferenceError, SyntaxError, TypeError, URIError +do + local function getErrorStack(self, constructor) + local level = 1 + while true do + local info = debug.getinfo(level, "f") + level = level + 1 + if not info then + level = 1 + break + elseif info.func == constructor then + break + end + end + return debug.traceback(nil, level) + end + local function wrapErrorToString(self, getDescription) + return function(self) + local description = getDescription(self) + local caller = debug.getinfo(3, "f") + if _VERSION == "Lua 5.1" or caller and caller.func ~= error then + return description + else + return (tostring(description) .. "\n") .. self.stack + end + end + end + local function initErrorClass(self, Type, name) + Type.name = name + return setmetatable( + Type, + {__call = function(____, _self, message) return __TS__New(Type, message) end} + ) + end + local ____initErrorClass_2 = initErrorClass + local ____class_0 = __TS__Class() + ____class_0.name = "" + function ____class_0.prototype.____constructor(self, message) + if message == nil then + message = "" + end + self.message = message + self.name = "Error" + self.stack = getErrorStack(nil, self.constructor.new) + local metatable = getmetatable(self) + if not metatable.__errorToStringPatched then + metatable.__errorToStringPatched = true + metatable.__tostring = wrapErrorToString(nil, metatable.__tostring) + end + end + function ____class_0.prototype.__tostring(self) + local ____temp_1 + if self.message ~= "" then + ____temp_1 = (self.name .. ": ") .. self.message + else + ____temp_1 = self.name + end + return ____temp_1 + end + Error = ____initErrorClass_2(nil, ____class_0, "Error") + local function createErrorClass(self, name) + local ____initErrorClass_4 = initErrorClass + local ____class_3 = __TS__Class() + ____class_3.name = ____class_3.name + __TS__ClassExtends(____class_3, Error) + function ____class_3.prototype.____constructor(self, ...) + ____class_3.____super.prototype.____constructor(self, ...) + self.name = name + end + return ____initErrorClass_4(nil, ____class_3, name) + end + RangeError = createErrorClass(nil, "RangeError") + ReferenceError = createErrorClass(nil, "ReferenceError") + SyntaxError = createErrorClass(nil, "SyntaxError") + TypeError = createErrorClass(nil, "TypeError") + URIError = createErrorClass(nil, "URIError") +end + +local function __TS__ObjectGetOwnPropertyDescriptors(object) + local metatable = getmetatable(object) + if not metatable then + return {} + end + return rawget(metatable, "_descriptors") or ({}) +end + +local function __TS__Delete(target, key) + local descriptors = __TS__ObjectGetOwnPropertyDescriptors(target) + local descriptor = descriptors[key] + if descriptor then + if not descriptor.configurable then + error( + __TS__New( + TypeError, + ((("Cannot delete property " .. tostring(key)) .. " of ") .. tostring(target)) .. "." + ), + 0 + ) + end + descriptors[key] = nil + return true + end + target[key] = nil + return true +end + +local function __TS__StringAccess(self, index) + if index >= 0 and index < #self then + return string.sub(self, index + 1, index + 1) + end +end + +local function __TS__DelegatedYield(iterable) + if type(iterable) == "string" then + for index = 0, #iterable - 1 do + coroutine.yield(__TS__StringAccess(iterable, index)) + end + elseif iterable.____coroutine ~= nil then + local co = iterable.____coroutine + while true do + local status, value = coroutine.resume(co) + if not status then + error(value, 0) + end + if coroutine.status(co) == "dead" then + return value + else + coroutine.yield(value) + end + end + elseif iterable[Symbol.iterator] then + local iterator = iterable[Symbol.iterator](iterable) + while true do + local result = iterator:next() + if result.done then + return result.value + else + coroutine.yield(result.value) + end + end + else + for ____, value in ipairs(iterable) do + coroutine.yield(value) + end + end +end + +local __TS__Generator +do + local function generatorIterator(self) + return self + end + local function generatorNext(self, ...) + local co = self.____coroutine + if coroutine.status(co) == "dead" then + return {done = true} + end + local status, value = coroutine.resume(co, ...) + if not status then + error(value, 0) + end + return { + value = value, + done = coroutine.status(co) == "dead" + } + end + function __TS__Generator(fn) + return function(...) + local args = {...} + local argsLength = select("#", ...) + return { + ____coroutine = coroutine.create(function() return fn((unpack or table.unpack)(args, 1, argsLength)) end), + [Symbol.iterator] = generatorIterator, + next = generatorNext + } + end + end +end + +local function __TS__InstanceOfObject(value) + local valueType = type(value) + return valueType == "table" or valueType == "function" +end + +local Map +do + Map = __TS__Class() + Map.name = "Map" + function Map.prototype.____constructor(self, entries) + self[Symbol.toStringTag] = "Map" + self.items = {} + self.size = 0 + self.nextKey = {} + self.previousKey = {} + if entries == nil then + return + end + local iterable = entries + if iterable[Symbol.iterator] then + local iterator = iterable[Symbol.iterator](iterable) + while true do + local result = iterator:next() + if result.done then + break + end + local value = result.value + self:set(value[1], value[2]) + end + else + local array = entries + for ____, kvp in ipairs(array) do + self:set(kvp[1], kvp[2]) + end + end + end + function Map.prototype.clear(self) + self.items = {} + self.nextKey = {} + self.previousKey = {} + self.firstKey = nil + self.lastKey = nil + self.size = 0 + end + function Map.prototype.delete(self, key) + local contains = self:has(key) + if contains then + self.size = self.size - 1 + local next = self.nextKey[key] + local previous = self.previousKey[key] + if next and previous then + self.nextKey[previous] = next + self.previousKey[next] = previous + elseif next then + self.firstKey = next + self.previousKey[next] = nil + elseif previous then + self.lastKey = previous + self.nextKey[previous] = nil + else + self.firstKey = nil + self.lastKey = nil + end + self.nextKey[key] = nil + self.previousKey[key] = nil + end + self.items[key] = nil + return contains + end + function Map.prototype.forEach(self, callback) + for ____, key in __TS__Iterator(self:keys()) do + callback(nil, self.items[key], key, self) + end + end + function Map.prototype.get(self, key) + return self.items[key] + end + function Map.prototype.has(self, key) + return self.nextKey[key] ~= nil or self.lastKey == key + end + function Map.prototype.set(self, key, value) + local isNewValue = not self:has(key) + if isNewValue then + self.size = self.size + 1 + end + self.items[key] = value + if self.firstKey == nil then + self.firstKey = key + self.lastKey = key + elseif isNewValue then + self.nextKey[self.lastKey] = key + self.previousKey[key] = self.lastKey + self.lastKey = key + end + return self + end + Map.prototype[Symbol.iterator] = function(self) + return self:entries() + end + function Map.prototype.entries(self) + local ____temp_0 = self + local items = ____temp_0.items + local nextKey = ____temp_0.nextKey + local key = self.firstKey + return { + [Symbol.iterator] = function(self) + return self + end, + next = function(self) + local result = {done = not key, value = {key, items[key]}} + key = nextKey[key] + return result + end + } + end + function Map.prototype.keys(self) + local nextKey = self.nextKey + local key = self.firstKey + return { + [Symbol.iterator] = function(self) + return self + end, + next = function(self) + local result = {done = not key, value = key} + key = nextKey[key] + return result + end + } + end + function Map.prototype.values(self) + local ____temp_1 = self + local items = ____temp_1.items + local nextKey = ____temp_1.nextKey + local key = self.firstKey + return { + [Symbol.iterator] = function(self) + return self + end, + next = function(self) + local result = {done = not key, value = items[key]} + key = nextKey[key] + return result + end + } + end + Map[Symbol.species] = Map +end + +local __TS__MathAtan2 = math.atan2 or math.atan + +local function __TS__MathSign(val) + if val > 0 then + return 1 + elseif val < 0 then + return -1 + end + return 0 +end + +local function __TS__Number(value) + local valueType = type(value) + if valueType == "number" then + return value + elseif valueType == "string" then + local numberValue = tonumber(value) + if numberValue then + return numberValue + end + if value == "Infinity" then + return math.huge + end + if value == "-Infinity" then + return -math.huge + end + local stringWithoutSpaces = string.gsub(value, "%s", "") + if stringWithoutSpaces == "" then + return 0 + end + return 0 / 0 + elseif valueType == "boolean" then + return value and 1 or 0 + else + return 0 / 0 + end +end + +local function __TS__NumberIsFinite(value) + return type(value) == "number" and value == value and value ~= math.huge and value ~= -math.huge +end + +local function __TS__NumberIsNaN(value) + return value ~= value +end + +local __TS__NumberToString +do + local radixChars = "0123456789abcdefghijklmnopqrstuvwxyz" + function __TS__NumberToString(self, radix) + if radix == nil or radix == 10 or self == math.huge or self == -math.huge or self ~= self then + return tostring(self) + end + radix = math.floor(radix) + if radix < 2 or radix > 36 then + error("toString() radix argument must be between 2 and 36", 0) + end + local integer, fraction = math.modf(math.abs(self)) + local result = "" + if radix == 8 then + result = string.format("%o", integer) + elseif radix == 16 then + result = string.format("%x", integer) + else + repeat + do + result = __TS__StringAccess(radixChars, integer % radix) .. result + integer = math.floor(integer / radix) + end + until not (integer ~= 0) + end + if fraction ~= 0 then + result = result .. "." + local delta = 1e-16 + repeat + do + fraction = fraction * radix + delta = delta * radix + local digit = math.floor(fraction) + result = result .. __TS__StringAccess(radixChars, digit) + fraction = fraction - digit + end + until not (fraction >= delta) + end + if self < 0 then + result = "-" .. result + end + return result + end +end + +local function __TS__ObjectDefineProperty(target, key, desc) + local ____temp_0 + if type(key) == "number" then + ____temp_0 = key + 1 + else + ____temp_0 = key + end + local luaKey = ____temp_0 + local value = rawget(target, luaKey) + local hasGetterOrSetter = desc.get ~= nil or desc.set ~= nil + local descriptor + if hasGetterOrSetter then + if value ~= nil then + error( + "Cannot redefine property: " .. tostring(key), + 0 + ) + end + descriptor = desc + else + local valueExists = value ~= nil + local ____desc_set_5 = desc.set + local ____desc_get_6 = desc.get + local ____temp_1 + if desc.configurable ~= nil then + ____temp_1 = desc.configurable + else + ____temp_1 = valueExists + end + local ____temp_2 + if desc.enumerable ~= nil then + ____temp_2 = desc.enumerable + else + ____temp_2 = valueExists + end + local ____temp_3 + if desc.writable ~= nil then + ____temp_3 = desc.writable + else + ____temp_3 = valueExists + end + local ____temp_4 + if desc.value ~= nil then + ____temp_4 = desc.value + else + ____temp_4 = value + end + descriptor = { + set = ____desc_set_5, + get = ____desc_get_6, + configurable = ____temp_1, + enumerable = ____temp_2, + writable = ____temp_3, + value = ____temp_4 + } + end + __TS__SetDescriptor(target, luaKey, descriptor) + return target +end + +local function __TS__ObjectEntries(obj) + local result = {} + local len = 0 + for key in pairs(obj) do + len = len + 1 + result[len] = {key, obj[key]} + end + return result +end + +local function __TS__ObjectFromEntries(entries) + local obj = {} + local iterable = entries + if iterable[Symbol.iterator] then + local iterator = iterable[Symbol.iterator](iterable) + while true do + local result = iterator:next() + if result.done then + break + end + local value = result.value + obj[value[1]] = value[2] + end + else + for ____, entry in ipairs(entries) do + obj[entry[1]] = entry[2] + end + end + return obj +end + +local function __TS__ObjectKeys(obj) + local result = {} + local len = 0 + for key in pairs(obj) do + len = len + 1 + result[len] = key + end + return result +end + +local function __TS__ObjectRest(target, usedProperties) + local result = {} + for property in pairs(target) do + if not usedProperties[property] then + result[property] = target[property] + end + end + return result +end + +local function __TS__ObjectValues(obj) + local result = {} + local len = 0 + for key in pairs(obj) do + len = len + 1 + result[len] = obj[key] + end + return result +end + +local function __TS__ParseFloat(numberString) + local infinityMatch = string.match(numberString, "^%s*(-?Infinity)") + if infinityMatch then + local ____temp_0 + if __TS__StringAccess(infinityMatch, 0) == "-" then + ____temp_0 = -math.huge + else + ____temp_0 = math.huge + end + return ____temp_0 + end + local number = tonumber(string.match(numberString, "^%s*(-?%d+%.?%d*)")) + return number or 0 / 0 +end + +local function __TS__StringSubstr(self, from, length) + if from ~= from then + from = 0 + end + if length ~= nil then + if length ~= length or length <= 0 then + return "" + end + length = length + from + end + if from >= 0 then + from = from + 1 + end + return string.sub(self, from, length) +end + +local function __TS__StringSubstring(self, start, ____end) + if ____end ~= ____end then + ____end = 0 + end + if ____end ~= nil and start > ____end then + start, ____end = ____end, start + end + if start >= 0 then + start = start + 1 + else + start = 1 + end + if ____end ~= nil and ____end < 0 then + ____end = 0 + end + return string.sub(self, start, ____end) +end + +local __TS__ParseInt +do + local parseIntBasePattern = "0123456789aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTvVwWxXyYzZ" + function __TS__ParseInt(numberString, base) + if base == nil then + base = 10 + local hexMatch = string.match(numberString, "^%s*-?0[xX]") + if hexMatch then + base = 16 + local ____string_match_result__0_0 + if string.match(hexMatch, "-") then + ____string_match_result__0_0 = "-" .. __TS__StringSubstr(numberString, #hexMatch) + else + ____string_match_result__0_0 = __TS__StringSubstr(numberString, #hexMatch) + end + numberString = ____string_match_result__0_0 + end + end + if base < 2 or base > 36 then + return 0 / 0 + end + local ____temp_1 + if base <= 10 then + ____temp_1 = __TS__StringSubstring(parseIntBasePattern, 0, base) + else + ____temp_1 = __TS__StringSubstr(parseIntBasePattern, 0, 10 + 2 * (base - 10)) + end + local allowedDigits = ____temp_1 + local pattern = ("^%s*(-?[" .. allowedDigits) .. "]*)" + local number = tonumber( + string.match(numberString, pattern), + base + ) + if number == nil then + return 0 / 0 + end + if number >= 0 then + return math.floor(number) + else + return math.ceil(number) + end + end +end + +local function __TS__PromiseAll(iterable) + local results = {} + local toResolve = {} + local numToResolve = 0 + local i = 0 + for ____, item in __TS__Iterator(iterable) do + if __TS__InstanceOf(item, __TS__Promise) then + if item.state == 1 then + results[i + 1] = item.value + elseif item.state == 2 then + return __TS__Promise.reject(item.rejectionReason) + else + numToResolve = numToResolve + 1 + toResolve[i] = item + end + else + results[i + 1] = item + end + i = i + 1 + end + if numToResolve == 0 then + return __TS__Promise.resolve(results) + end + return __TS__New( + __TS__Promise, + function(____, resolve, reject) + for index, promise in pairs(toResolve) do + promise["then"]( + promise, + function(____, data) + results[index + 1] = data + numToResolve = numToResolve - 1 + if numToResolve == 0 then + resolve(nil, results) + end + end, + function(____, reason) + reject(nil, reason) + end + ) + end + end + ) +end + +local function __TS__PromiseAllSettled(iterable) + local results = {} + local toResolve = {} + local numToResolve = 0 + local i = 0 + for ____, item in __TS__Iterator(iterable) do + if __TS__InstanceOf(item, __TS__Promise) then + if item.state == 1 then + results[i + 1] = {status = "fulfilled", value = item.value} + elseif item.state == 2 then + results[i + 1] = {status = "rejected", reason = item.rejectionReason} + else + numToResolve = numToResolve + 1 + toResolve[i] = item + end + else + results[i + 1] = {status = "fulfilled", value = item} + end + i = i + 1 + end + if numToResolve == 0 then + return __TS__Promise.resolve(results) + end + return __TS__New( + __TS__Promise, + function(____, resolve) + for index, promise in pairs(toResolve) do + promise["then"]( + promise, + function(____, data) + results[index + 1] = {status = "fulfilled", value = data} + numToResolve = numToResolve - 1 + if numToResolve == 0 then + resolve(nil, results) + end + end, + function(____, reason) + results[index + 1] = {status = "rejected", reason = reason} + numToResolve = numToResolve - 1 + if numToResolve == 0 then + resolve(nil, results) + end + end + ) + end + end + ) +end + +local function __TS__PromiseAny(iterable) + local rejections = {} + local pending = {} + for ____, item in __TS__Iterator(iterable) do + if __TS__InstanceOf(item, __TS__Promise) then + if item.state == 1 then + return __TS__Promise.resolve(item.value) + elseif item.state == 2 then + rejections[#rejections + 1] = item.rejectionReason + else + pending[#pending + 1] = item + end + else + return __TS__Promise.resolve(item) + end + end + if #pending == 0 then + return __TS__Promise.reject("No promises to resolve with .any()") + end + local numResolved = 0 + return __TS__New( + __TS__Promise, + function(____, resolve, reject) + for ____, promise in ipairs(pending) do + promise["then"]( + promise, + function(____, data) + resolve(nil, data) + end, + function(____, reason) + rejections[#rejections + 1] = reason + numResolved = numResolved + 1 + if numResolved == #pending then + reject(nil, {name = "AggregateError", message = "All Promises rejected", errors = rejections}) + end + end + ) + end + end + ) +end + +local function __TS__PromiseRace(iterable) + local pending = {} + for ____, item in __TS__Iterator(iterable) do + if __TS__InstanceOf(item, __TS__Promise) then + if item.state == 1 then + return __TS__Promise.resolve(item.value) + elseif item.state == 2 then + return __TS__Promise.reject(item.rejectionReason) + else + pending[#pending + 1] = item + end + else + return __TS__Promise.resolve(item) + end + end + return __TS__New( + __TS__Promise, + function(____, resolve, reject) + for ____, promise in ipairs(pending) do + promise["then"]( + promise, + function(____, value) return resolve(nil, value) end, + function(____, reason) return reject(nil, reason) end + ) + end + end + ) +end + +local Set +do + Set = __TS__Class() + Set.name = "Set" + function Set.prototype.____constructor(self, values) + self[Symbol.toStringTag] = "Set" + self.size = 0 + self.nextKey = {} + self.previousKey = {} + if values == nil then + return + end + local iterable = values + if iterable[Symbol.iterator] then + local iterator = iterable[Symbol.iterator](iterable) + while true do + local result = iterator:next() + if result.done then + break + end + self:add(result.value) + end + else + local array = values + for ____, value in ipairs(array) do + self:add(value) + end + end + end + function Set.prototype.add(self, value) + local isNewValue = not self:has(value) + if isNewValue then + self.size = self.size + 1 + end + if self.firstKey == nil then + self.firstKey = value + self.lastKey = value + elseif isNewValue then + self.nextKey[self.lastKey] = value + self.previousKey[value] = self.lastKey + self.lastKey = value + end + return self + end + function Set.prototype.clear(self) + self.nextKey = {} + self.previousKey = {} + self.firstKey = nil + self.lastKey = nil + self.size = 0 + end + function Set.prototype.delete(self, value) + local contains = self:has(value) + if contains then + self.size = self.size - 1 + local next = self.nextKey[value] + local previous = self.previousKey[value] + if next and previous then + self.nextKey[previous] = next + self.previousKey[next] = previous + elseif next then + self.firstKey = next + self.previousKey[next] = nil + elseif previous then + self.lastKey = previous + self.nextKey[previous] = nil + else + self.firstKey = nil + self.lastKey = nil + end + self.nextKey[value] = nil + self.previousKey[value] = nil + end + return contains + end + function Set.prototype.forEach(self, callback) + for ____, key in __TS__Iterator(self:keys()) do + callback(nil, key, key, self) + end + end + function Set.prototype.has(self, value) + return self.nextKey[value] ~= nil or self.lastKey == value + end + Set.prototype[Symbol.iterator] = function(self) + return self:values() + end + function Set.prototype.entries(self) + local nextKey = self.nextKey + local key = self.firstKey + return { + [Symbol.iterator] = function(self) + return self + end, + next = function(self) + local result = {done = not key, value = {key, key}} + key = nextKey[key] + return result + end + } + end + function Set.prototype.keys(self) + local nextKey = self.nextKey + local key = self.firstKey + return { + [Symbol.iterator] = function(self) + return self + end, + next = function(self) + local result = {done = not key, value = key} + key = nextKey[key] + return result + end + } + end + function Set.prototype.values(self) + local nextKey = self.nextKey + local key = self.firstKey + return { + [Symbol.iterator] = function(self) + return self + end, + next = function(self) + local result = {done = not key, value = key} + key = nextKey[key] + return result + end + } + end + Set[Symbol.species] = Set +end + +local function __TS__SparseArrayNew(...) + local sparseArray = {...} + sparseArray.sparseLength = select("#", ...) + return sparseArray +end + +local function __TS__SparseArrayPush(sparseArray, ...) + local args = {...} + local argsLen = select("#", ...) + local listLen = sparseArray.sparseLength + for i = 1, argsLen do + sparseArray[listLen + i] = args[i] + end + sparseArray.sparseLength = listLen + argsLen +end + +local function __TS__SparseArraySpread(sparseArray) + local _unpack = unpack or table.unpack + return _unpack(sparseArray, 1, sparseArray.sparseLength) +end + +local WeakMap +do + WeakMap = __TS__Class() + WeakMap.name = "WeakMap" + function WeakMap.prototype.____constructor(self, entries) + self[Symbol.toStringTag] = "WeakMap" + self.items = {} + setmetatable(self.items, {__mode = "k"}) + if entries == nil then + return + end + local iterable = entries + if iterable[Symbol.iterator] then + local iterator = iterable[Symbol.iterator](iterable) + while true do + local result = iterator:next() + if result.done then + break + end + local value = result.value + self.items[value[1]] = value[2] + end + else + for ____, kvp in ipairs(entries) do + self.items[kvp[1]] = kvp[2] + end + end + end + function WeakMap.prototype.delete(self, key) + local contains = self:has(key) + self.items[key] = nil + return contains + end + function WeakMap.prototype.get(self, key) + return self.items[key] + end + function WeakMap.prototype.has(self, key) + return self.items[key] ~= nil + end + function WeakMap.prototype.set(self, key, value) + self.items[key] = value + return self + end + WeakMap[Symbol.species] = WeakMap +end + +local WeakSet +do + WeakSet = __TS__Class() + WeakSet.name = "WeakSet" + function WeakSet.prototype.____constructor(self, values) + self[Symbol.toStringTag] = "WeakSet" + self.items = {} + setmetatable(self.items, {__mode = "k"}) + if values == nil then + return + end + local iterable = values + if iterable[Symbol.iterator] then + local iterator = iterable[Symbol.iterator](iterable) + while true do + local result = iterator:next() + if result.done then + break + end + self.items[result.value] = true + end + else + for ____, value in ipairs(values) do + self.items[value] = true + end + end + end + function WeakSet.prototype.add(self, value) + self.items[value] = true + return self + end + function WeakSet.prototype.delete(self, value) + local contains = self:has(value) + self.items[value] = nil + return contains + end + function WeakSet.prototype.has(self, value) + return self.items[value] == true + end + WeakSet[Symbol.species] = WeakSet +end + +local function __TS__SourceMapTraceBack(fileName, sourceMap) + _G.__TS__sourcemap = _G.__TS__sourcemap or ({}) + _G.__TS__sourcemap[fileName] = sourceMap + if _G.__TS__originalTraceback == nil then + local originalTraceback = debug.traceback + _G.__TS__originalTraceback = originalTraceback + debug.traceback = function(thread, message, level) + local trace + if thread == nil and message == nil and level == nil then + trace = originalTraceback() + else + trace = originalTraceback(thread, message, level) + end + if type(trace) ~= "string" then + return trace + end + local function replacer(____, file, srcFile, line) + local fileSourceMap = _G.__TS__sourcemap[file] + if fileSourceMap and fileSourceMap[line] then + local data = fileSourceMap[line] + if type(data) == "number" then + return (srcFile .. ":") .. tostring(data) + end + return (tostring(data.file) .. ":") .. tostring(data.line) + end + return (file .. ":") .. line + end + local result = string.gsub( + trace, + "(%S+)%.lua:(%d+)", + function(file, line) return replacer(nil, file .. ".lua", file .. ".ts", line) end + ) + local function stringReplacer(____, file, line) + local fileSourceMap = _G.__TS__sourcemap[file] + if fileSourceMap and fileSourceMap[line] then + local chunkName = string.match(file, "%[string \"([^\"]+)\"%]") + local sourceName = string.gsub(chunkName, ".lua$", ".ts") + local data = fileSourceMap[line] + if type(data) == "number" then + return (sourceName .. ":") .. tostring(data) + end + return (tostring(data.file) .. ":") .. tostring(data.line) + end + return (file .. ":") .. line + end + result = string.gsub( + result, + "(%[string \"[^\"]+\"%]):(%d+)", + function(file, line) return stringReplacer(nil, file, line) end + ) + return result + end + end +end + +local function __TS__Spread(iterable) + local arr = {} + if type(iterable) == "string" then + for i = 0, #iterable - 1 do + arr[i + 1] = __TS__StringAccess(iterable, i) + end + else + local len = 0 + for ____, item in __TS__Iterator(iterable) do + len = len + 1 + arr[len] = item + end + end + return __TS__Unpack(arr) +end + +local function __TS__StringCharAt(self, pos) + if pos ~= pos then + pos = 0 + end + if pos < 0 then + return "" + end + return string.sub(self, pos + 1, pos + 1) +end + +local function __TS__StringCharCodeAt(self, index) + if index ~= index then + index = 0 + end + if index < 0 then + return 0 / 0 + end + return string.byte(self, index + 1) or 0 / 0 +end + +local function __TS__StringEndsWith(self, searchString, endPosition) + if endPosition == nil or endPosition > #self then + endPosition = #self + end + return string.sub(self, endPosition - #searchString + 1, endPosition) == searchString +end + +local function __TS__StringIncludes(self, searchString, position) + if not position then + position = 1 + else + position = position + 1 + end + local index = string.find(self, searchString, position, true) + return index ~= nil +end + +local function __TS__StringPadEnd(self, maxLength, fillString) + if fillString == nil then + fillString = " " + end + if maxLength ~= maxLength then + maxLength = 0 + end + if maxLength == -math.huge or maxLength == math.huge then + error("Invalid string length", 0) + end + if #self >= maxLength or #fillString == 0 then + return self + end + maxLength = maxLength - #self + if maxLength > #fillString then + fillString = fillString .. string.rep( + fillString, + math.floor(maxLength / #fillString) + ) + end + return self .. string.sub( + fillString, + 1, + math.floor(maxLength) + ) +end + +local function __TS__StringPadStart(self, maxLength, fillString) + if fillString == nil then + fillString = " " + end + if maxLength ~= maxLength then + maxLength = 0 + end + if maxLength == -math.huge or maxLength == math.huge then + error("Invalid string length", 0) + end + if #self >= maxLength or #fillString == 0 then + return self + end + maxLength = maxLength - #self + if maxLength > #fillString then + fillString = fillString .. string.rep( + fillString, + math.floor(maxLength / #fillString) + ) + end + return string.sub( + fillString, + 1, + math.floor(maxLength) + ) .. self +end + +local __TS__StringReplace +do + local sub = string.sub + function __TS__StringReplace(source, searchValue, replaceValue) + local startPos, endPos = string.find(source, searchValue, nil, true) + if not startPos then + return source + end + local before = sub(source, 1, startPos - 1) + local ____temp_0 + if type(replaceValue) == "string" then + ____temp_0 = replaceValue + else + ____temp_0 = replaceValue(nil, searchValue, startPos - 1, source) + end + local replacement = ____temp_0 + local after = sub(source, endPos + 1) + return (before .. replacement) .. after + end +end + +local __TS__StringSplit +do + local sub = string.sub + local find = string.find + function __TS__StringSplit(source, separator, limit) + if limit == nil then + limit = 4294967295 + end + if limit == 0 then + return {} + end + local result = {} + local resultIndex = 1 + if separator == nil or separator == "" then + for i = 1, #source do + result[resultIndex] = sub(source, i, i) + resultIndex = resultIndex + 1 + end + else + local currentPos = 1 + while resultIndex <= limit do + local startPos, endPos = find(source, separator, currentPos, true) + if not startPos then + break + end + result[resultIndex] = sub(source, currentPos, startPos - 1) + resultIndex = resultIndex + 1 + currentPos = endPos + 1 + end + if resultIndex <= limit then + result[resultIndex] = sub(source, currentPos) + end + end + return result + end +end + +local __TS__StringReplaceAll +do + local sub = string.sub + local find = string.find + function __TS__StringReplaceAll(source, searchValue, replaceValue) + if type(replaceValue) == "string" then + local concat = table.concat( + __TS__StringSplit(source, searchValue), + replaceValue + ) + if #searchValue == 0 then + return (replaceValue .. concat) .. replaceValue + end + return concat + end + local parts = {} + local partsIndex = 1 + if #searchValue == 0 then + parts[1] = replaceValue(nil, "", 0, source) + partsIndex = 2 + for i = 1, #source do + parts[partsIndex] = sub(source, i, i) + parts[partsIndex + 1] = replaceValue(nil, "", i, source) + partsIndex = partsIndex + 2 + end + else + local currentPos = 1 + while true do + local startPos, endPos = find(source, searchValue, currentPos, true) + if not startPos then + break + end + parts[partsIndex] = sub(source, currentPos, startPos - 1) + parts[partsIndex + 1] = replaceValue(nil, searchValue, startPos - 1, source) + partsIndex = partsIndex + 2 + currentPos = endPos + 1 + end + parts[partsIndex] = sub(source, currentPos) + end + return table.concat(parts) + end +end + +local function __TS__StringSlice(self, start, ____end) + if start == nil or start ~= start then + start = 0 + end + if ____end ~= ____end then + ____end = 0 + end + if start >= 0 then + start = start + 1 + end + if ____end ~= nil and ____end < 0 then + ____end = ____end - 1 + end + return string.sub(self, start, ____end) +end + +local function __TS__StringStartsWith(self, searchString, position) + if position == nil or position < 0 then + position = 0 + end + return string.sub(self, position + 1, #searchString + position) == searchString +end + +local function __TS__StringTrim(self) + local result = string.gsub(self, "^[%s ]*(.-)[%s ]*$", "%1") + return result +end + +local function __TS__StringTrimEnd(self) + local result = string.gsub(self, "[%s ]*$", "") + return result +end + +local function __TS__StringTrimStart(self) + local result = string.gsub(self, "^[%s ]*", "") + return result +end + +local __TS__SymbolRegistryFor, __TS__SymbolRegistryKeyFor +do + local symbolRegistry = {} + function __TS__SymbolRegistryFor(key) + if not symbolRegistry[key] then + symbolRegistry[key] = __TS__Symbol(key) + end + return symbolRegistry[key] + end + function __TS__SymbolRegistryKeyFor(sym) + for key in pairs(symbolRegistry) do + if symbolRegistry[key] == sym then + return key + end + end + end +end + +local function __TS__TypeOf(value) + local luaType = type(value) + if luaType == "table" then + return "object" + elseif luaType == "nil" then + return "undefined" + else + return luaType + end +end + +return { + __TS__ArrayConcat = __TS__ArrayConcat, + __TS__ArrayEntries = __TS__ArrayEntries, + __TS__ArrayEvery = __TS__ArrayEvery, + __TS__ArrayFilter = __TS__ArrayFilter, + __TS__ArrayForEach = __TS__ArrayForEach, + __TS__ArrayFind = __TS__ArrayFind, + __TS__ArrayFindIndex = __TS__ArrayFindIndex, + __TS__ArrayFrom = __TS__ArrayFrom, + __TS__ArrayIncludes = __TS__ArrayIncludes, + __TS__ArrayIndexOf = __TS__ArrayIndexOf, + __TS__ArrayIsArray = __TS__ArrayIsArray, + __TS__ArrayJoin = __TS__ArrayJoin, + __TS__ArrayMap = __TS__ArrayMap, + __TS__ArrayPush = __TS__ArrayPush, + __TS__ArrayPushArray = __TS__ArrayPushArray, + __TS__ArrayReduce = __TS__ArrayReduce, + __TS__ArrayReduceRight = __TS__ArrayReduceRight, + __TS__ArrayReverse = __TS__ArrayReverse, + __TS__ArrayUnshift = __TS__ArrayUnshift, + __TS__ArraySort = __TS__ArraySort, + __TS__ArraySlice = __TS__ArraySlice, + __TS__ArraySome = __TS__ArraySome, + __TS__ArraySplice = __TS__ArraySplice, + __TS__ArrayToObject = __TS__ArrayToObject, + __TS__ArrayFlat = __TS__ArrayFlat, + __TS__ArrayFlatMap = __TS__ArrayFlatMap, + __TS__ArraySetLength = __TS__ArraySetLength, + __TS__AsyncAwaiter = __TS__AsyncAwaiter, + __TS__Await = __TS__Await, + __TS__Class = __TS__Class, + __TS__ClassExtends = __TS__ClassExtends, + __TS__CloneDescriptor = __TS__CloneDescriptor, + __TS__Decorate = __TS__Decorate, + __TS__DecorateParam = __TS__DecorateParam, + __TS__Delete = __TS__Delete, + __TS__DelegatedYield = __TS__DelegatedYield, + Error = Error, + RangeError = RangeError, + ReferenceError = ReferenceError, + SyntaxError = SyntaxError, + TypeError = TypeError, + URIError = URIError, + __TS__FunctionBind = __TS__FunctionBind, + __TS__Generator = __TS__Generator, + __TS__InstanceOf = __TS__InstanceOf, + __TS__InstanceOfObject = __TS__InstanceOfObject, + __TS__Iterator = __TS__Iterator, + Map = Map, + __TS__MathAtan2 = __TS__MathAtan2, + __TS__MathSign = __TS__MathSign, + __TS__New = __TS__New, + __TS__Number = __TS__Number, + __TS__NumberIsFinite = __TS__NumberIsFinite, + __TS__NumberIsNaN = __TS__NumberIsNaN, + __TS__NumberToString = __TS__NumberToString, + __TS__ObjectAssign = __TS__ObjectAssign, + __TS__ObjectDefineProperty = __TS__ObjectDefineProperty, + __TS__ObjectEntries = __TS__ObjectEntries, + __TS__ObjectFromEntries = __TS__ObjectFromEntries, + __TS__ObjectGetOwnPropertyDescriptor = __TS__ObjectGetOwnPropertyDescriptor, + __TS__ObjectGetOwnPropertyDescriptors = __TS__ObjectGetOwnPropertyDescriptors, + __TS__ObjectKeys = __TS__ObjectKeys, + __TS__ObjectRest = __TS__ObjectRest, + __TS__ObjectValues = __TS__ObjectValues, + __TS__ParseFloat = __TS__ParseFloat, + __TS__ParseInt = __TS__ParseInt, + __TS__Promise = __TS__Promise, + __TS__PromiseAll = __TS__PromiseAll, + __TS__PromiseAllSettled = __TS__PromiseAllSettled, + __TS__PromiseAny = __TS__PromiseAny, + __TS__PromiseRace = __TS__PromiseRace, + Set = Set, + __TS__SetDescriptor = __TS__SetDescriptor, + __TS__SparseArrayNew = __TS__SparseArrayNew, + __TS__SparseArrayPush = __TS__SparseArrayPush, + __TS__SparseArraySpread = __TS__SparseArraySpread, + WeakMap = WeakMap, + WeakSet = WeakSet, + __TS__SourceMapTraceBack = __TS__SourceMapTraceBack, + __TS__Spread = __TS__Spread, + __TS__StringAccess = __TS__StringAccess, + __TS__StringCharAt = __TS__StringCharAt, + __TS__StringCharCodeAt = __TS__StringCharCodeAt, + __TS__StringEndsWith = __TS__StringEndsWith, + __TS__StringIncludes = __TS__StringIncludes, + __TS__StringPadEnd = __TS__StringPadEnd, + __TS__StringPadStart = __TS__StringPadStart, + __TS__StringReplace = __TS__StringReplace, + __TS__StringReplaceAll = __TS__StringReplaceAll, + __TS__StringSlice = __TS__StringSlice, + __TS__StringSplit = __TS__StringSplit, + __TS__StringStartsWith = __TS__StringStartsWith, + __TS__StringSubstr = __TS__StringSubstr, + __TS__StringSubstring = __TS__StringSubstring, + __TS__StringTrim = __TS__StringTrim, + __TS__StringTrimEnd = __TS__StringTrimEnd, + __TS__StringTrimStart = __TS__StringTrimStart, + __TS__Symbol = __TS__Symbol, + Symbol = Symbol, + __TS__SymbolRegistryFor = __TS__SymbolRegistryFor, + __TS__SymbolRegistryKeyFor = __TS__SymbolRegistryKeyFor, + __TS__TypeOf = __TS__TypeOf, + __TS__Unpack = __TS__Unpack +} diff --git a/modules/events-mod/src/main/lua/main/PacketEmitter.lua b/modules/events-mod/src/main/lua/main/PacketEmitter.lua new file mode 100644 index 0000000..1ff529d --- /dev/null +++ b/modules/events-mod/src/main/lua/main/PacketEmitter.lua @@ -0,0 +1,22 @@ +local ____lualib = require("lualib_bundle") +local __TS__Class = ____lualib.__TS__Class +local __TS__New = ____lualib.__TS__New +local ____exports = {} +____exports.KafkatorioPacketEmitter = __TS__Class() +local KafkatorioPacketEmitter = ____exports.KafkatorioPacketEmitter +KafkatorioPacketEmitter.name = "KafkatorioPacketEmitter" +function KafkatorioPacketEmitter.prototype.____constructor(self) +end +function KafkatorioPacketEmitter.prototype.emitInstantPacket(self, data) + ____exports.KafkatorioPacketEmitter:emitPacket({data = data, modVersion = global.MOD_VERSION, tick = game.tick}) +end +function KafkatorioPacketEmitter.prototype.emitKeyedPacket(self, data) + ____exports.KafkatorioPacketEmitter:emitPacket({data = data, modVersion = global.MOD_VERSION, tick = game.tick}) +end +function KafkatorioPacketEmitter.emitPacket(self, packet) + local data = game.table_to_json(packet) + localised_print("KafkatorioPacket: " .. data) +end +local PacketEmitter = __TS__New(____exports.KafkatorioPacketEmitter) +____exports.default = PacketEmitter +return ____exports diff --git a/modules/events-mod/src/main/lua/main/cache/EventDataCache.lua b/modules/events-mod/src/main/lua/main/cache/EventDataCache.lua new file mode 100644 index 0000000..71b961b --- /dev/null +++ b/modules/events-mod/src/main/lua/main/cache/EventDataCache.lua @@ -0,0 +1,145 @@ +local ____lualib = require("lualib_bundle") +local __TS__Class = ____lualib.__TS__Class +local __TS__New = ____lualib.__TS__New +local ____exports = {} +local ____KafkatorioSettings = require("main.settings.KafkatorioSettings") +local KafkatorioSettings = ____KafkatorioSettings.default +local ____PacketEmitter = require("main.PacketEmitter") +local packetEmitter = ____PacketEmitter.default +____exports.EventUpdates = {} +local EventUpdates = ____exports.EventUpdates +do + local CacheEntry + EventUpdates.Manager = __TS__Class() + local Manager = EventUpdates.Manager + Manager.name = "Manager" + function Manager.prototype.____constructor(self) + end + function Manager.prototype.init(self, force) + local isAnythingUndefined = global.cache == nil + log(((("Initialising EventDataCache (force=" .. tostring(force)) .. ", isAnythingUndefined=") .. tostring(isAnythingUndefined)) .. ")...") + if force == true or isAnythingUndefined then + log("Initialising global.cache") + global.cache = {} + end + log("Finished initialising EventDataCache") + end + function Manager.prototype.throttle(self, key, ____type, mutate, expirationDurationTicks) + self:update( + key, + ____type, + mutate, + false, + expirationDurationTicks + ) + end + function Manager.prototype.debounce(self, key, ____type, mutate, expirationDurationTicks) + self:update( + key, + ____type, + mutate, + true, + expirationDurationTicks + ) + end + function Manager.prototype.update(self, key, ____type, mutate, resetLastUpdated, expirationDurationTicks) + local entry = self:getCacheEntry(key, ____type) or EventUpdates.Manager:createCacheEntry(key, ____type) + mutate(entry.packet) + if resetLastUpdated then + entry.lastUpdatedTick = game.tick + end + if expirationDurationTicks ~= nil then + entry.expirationDurationTicks = expirationDurationTicks + end + if entry.expirationDurationTicks ~= nil and entry.expirationDurationTicks <= 0 then + self:extractAndEmitExpiredPackets() + end + end + function Manager.prototype.setExpiration(self, key, ____type, expirationDurationTicks) + local entry = self:getCacheEntry(key, ____type) + if entry ~= nil then + entry.expirationDurationTicks = expirationDurationTicks + end + end + function Manager.prototype.extractExpired(self) + local countExpired = 0 + local countTotal = 0 + local expiredData = {} + for key, entry in pairs(global.cache) do + countTotal = countTotal + 1 + if self:isExpired(entry) then + countExpired = countExpired + 1 + expiredData[#expiredData + 1] = entry.packet + global.cache[key] = nil + end + end + local hasExpiredItems = countExpired > 0 + local hasAnyItem = countTotal > 0 + if hasExpiredItems or game.tick % 30 == 0 and hasAnyItem then + log((("[extractExpired] expired items: " .. tostring(countExpired)) .. ", total: ") .. tostring(countTotal)) + end + return expiredData + end + function Manager.prototype.extractAndEmitExpiredPackets(self) + local cachedEvents = self:extractExpired() + if #cachedEvents > 0 then + log((("[EventDataCache] emitting " .. tostring(#cachedEvents)) .. " events on tick ") .. tostring(game.tick)) + for ____, event in ipairs(cachedEvents) do + packetEmitter:emitKeyedPacket(event) + end + end + return #cachedEvents + end + function Manager.prototype.getCacheEntry(self, key, ____type) + local hash = EventUpdates.Manager:hashKey(key) + if not (global.cache[hash] ~= nil) then + return nil + end + local value = global.cache[hash] + if self:isEntryInstanceOf(value, ____type) then + return value + else + return nil + end + end + function Manager.createCacheEntry(self, key, ____type) + local data = {type = ____type, key = key} + local entry = __TS__New(CacheEntry, data) + local hash = EventUpdates.Manager:hashKey(key) + global.cache[hash] = entry + return entry + end + function Manager.prototype.isExpired(self, entry) + local expiryDuration = entry.expirationDurationTicks or KafkatorioSettings:getEventCacheExpirationTicks(entry.packet) + if expiryDuration == nil then + return true + else + return game.tick - entry.lastUpdatedTick > expiryDuration + end + end + function Manager.prototype.isEntryInstanceOf(self, entry, ____type) + local ____self_2 = self + local ____self_isDataInstanceOf_3 = self.isDataInstanceOf + local ____entry_packet_0 = entry + if ____entry_packet_0 ~= nil then + ____entry_packet_0 = ____entry_packet_0.packet + end + return ____self_isDataInstanceOf_3(____self_2, ____entry_packet_0, ____type) + end + function Manager.prototype.isDataInstanceOf(self, packet, ____type) + return packet ~= nil and packet.type == ____type + end + function Manager.hashKey(self, key) + return game.encode_string(game.table_to_json(key)) + end + CacheEntry = __TS__Class() + CacheEntry.name = "CacheEntry" + function CacheEntry.prototype.____constructor(self, packet, expirationDurationTicks) + self.lastUpdatedTick = game.tick + self.packet = packet + self.expirationDurationTicks = expirationDurationTicks + end +end +local EventUpdatesManager = __TS__New(____exports.EventUpdates.Manager) +____exports.default = EventUpdatesManager +return ____exports diff --git a/modules/events-mod/src/main/lua/main/commands/kafkatorioCommands.lua b/modules/events-mod/src/main/lua/main/commands/kafkatorioCommands.lua new file mode 100644 index 0000000..e9939d2 --- /dev/null +++ b/modules/events-mod/src/main/lua/main/commands/kafkatorioCommands.lua @@ -0,0 +1,76 @@ +local ____lualib = require("lualib_bundle") +local __TS__StringStartsWith = ____lualib.__TS__StringStartsWith +local __TS__StringSplit = ____lualib.__TS__StringSplit +local __TS__ParseInt = ____lualib.__TS__ParseInt +local ____exports = {} +local ____global_2Dinit = require("main.global-init") +local initGlobal = ____global_2Dinit.initGlobal +local ____queue = require("main.queue.queue") +local Queue = ____queue.Queue +local ____prototypeUpdates = require("main.events.prototypeUpdates") +local emitPrototypes = ____prototypeUpdates.emitPrototypes +commands.add_command( + "kafkatorio", + "kafkatorio innit bruv", + function(e) + local ____temp_0 + if e.player_index ~= nil then + ____temp_0 = game.get_player(e.player_index) + else + ____temp_0 = nil + end + local player = ____temp_0 + if e.parameter == nil then + if player ~= nil then + player.print("no parameter") + end + else + local paramUppercase = string.upper(e.parameter) + if "PROTOTYPES" == paramUppercase then + emitPrototypes() + elseif __TS__StringStartsWith(paramUppercase, "CHUNKS") then + local ____paramUppercase_split_result__1_1 = __TS__StringSplit(paramUppercase, " ") + if ____paramUppercase_split_result__1_1 ~= nil then + ____paramUppercase_split_result__1_1 = ____paramUppercase_split_result__1_1[2] + end + local size = ____paramUppercase_split_result__1_1 or nil + local radius = size ~= nil and __TS__ParseInt(size) or 1 + if e.player_index ~= nil then + local player = game.players[e.player_index] + local chunkPosition = { + x = math.floor(player.position.x / 32), + y = math.floor(player.position.y / 32) + } + local chunkXMin = chunkPosition.x - radius + local chunkXMax = chunkPosition.x + radius + local chunkYMin = chunkPosition.y - radius + local chunkYMax = chunkPosition.y + radius + local chunkCount = 0 + for ____, surface in pairs(game.surfaces) do + for chunk in surface.get_chunks() do + if chunk.x >= chunkXMin and chunk.x <= chunkXMax and (chunk.y >= chunkYMin and chunk.y <= chunkYMax) then + local data = { + name = defines.events.on_chunk_generated, + position = {x = chunk.x, y = chunk.y}, + area = chunk.area, + surface = surface, + tick = e.tick + } + Queue.enqueue( + (tostring(surface.index) .. tostring(chunk.x)) .. tostring(chunk.y), + data, + 50 + ) + chunkCount = chunkCount + 1 + end + end + end + player.print(((((((((("enqueued " .. tostring(chunkCount)) .. " chunks from [x:") .. tostring(chunkXMin)) .. ", y:") .. tostring(chunkYMin)) .. "] to [x:") .. tostring(chunkXMax)) .. ", y:") .. tostring(chunkYMax)) .. "]") + end + elseif __TS__StringStartsWith(paramUppercase, "INIT_GLOBAL") then + initGlobal(__TS__StringStartsWith(paramUppercase, "INIT_GLOBAL FORCE")) + end + end + end +) +return ____exports diff --git a/modules/events-mod/src/main/lua/main/events/configurationUpdate.lua b/modules/events-mod/src/main/lua/main/events/configurationUpdate.lua new file mode 100644 index 0000000..e548e73 --- /dev/null +++ b/modules/events-mod/src/main/lua/main/events/configurationUpdate.lua @@ -0,0 +1,65 @@ +local ____lualib = require("lualib_bundle") +local __TS__ObjectKeys = ____lualib.__TS__ObjectKeys +local __TS__ArrayConcat = ____lualib.__TS__ArrayConcat +local Set = ____lualib.Set +local __TS__New = ____lualib.__TS__New +local __TS__Spread = ____lualib.__TS__Spread +local __TS__ArrayMap = ____lualib.__TS__ArrayMap +local ____exports = {} +local emitConfigurationUpdate, factorioData, allMods, Type +local ____PacketEmitter = require("main.PacketEmitter") +local PacketEmitter = ____PacketEmitter.default +local ____kafkatorio_2Dschema = require("generated.kafkatorio-schema") +local KafkatorioPacketData = ____kafkatorio_2Dschema.KafkatorioPacketData +local ____global_2Dinit = require("main.global-init") +local initGlobal = ____global_2Dinit.initGlobal +local ____prototypeUpdates = require("main.events.prototypeUpdates") +local emitPrototypes = ____prototypeUpdates.emitPrototypes +function emitConfigurationUpdate(changeData) + local configUpdateData = { + type = Type.ConfigurationUpdate, + migrationApplied = changeData.migration_applied, + modStartupSettingsChange = changeData.mod_startup_settings_changed, + allMods = allMods(changeData), + factorioData = factorioData(changeData) + } + PacketEmitter:emitInstantPacket(configUpdateData) +end +function factorioData(changeData) + return {oldVersion = changeData.old_version or nil, newVersion = changeData.new_version or nil} +end +function allMods(e) + local namesOfChangedMods = __TS__ObjectKeys(e.mod_changes) + local namesOfCurrentMods = __TS__ObjectKeys(script.active_mods) + local modNames = {__TS__Spread(__TS__New( + Set, + __TS__ArrayConcat(namesOfChangedMods, namesOfCurrentMods) + ))} + return __TS__ArrayMap( + modNames, + function(modName) + local ____script_active_mods_modName_2 = script.active_mods[modName] + if ____script_active_mods_modName_2 == nil then + local ____e_mod_changes_modName_new_version_0 = e.mod_changes[modName] + if ____e_mod_changes_modName_new_version_0 ~= nil then + ____e_mod_changes_modName_new_version_0 = ____e_mod_changes_modName_new_version_0.new_version + end + ____script_active_mods_modName_2 = ____e_mod_changes_modName_new_version_0 + end + local currentVer = ____script_active_mods_modName_2 or nil + local ____e_mod_changes_modName_old_version_3 = e.mod_changes[modName] + if ____e_mod_changes_modName_old_version_3 ~= nil then + ____e_mod_changes_modName_old_version_3 = ____e_mod_changes_modName_old_version_3.old_version + end + local previousVer = ____e_mod_changes_modName_old_version_3 or nil + return {modName = modName, currentVersion = currentVer, previousVersion = previousVer} + end + ) +end +Type = KafkatorioPacketData.Type +script.on_configuration_changed(function(data) + initGlobal(true) + emitConfigurationUpdate(data) + emitPrototypes() +end) +return ____exports diff --git a/modules/events-mod/src/main/lua/main/events/consoleUpdates.lua b/modules/events-mod/src/main/lua/main/events/consoleUpdates.lua new file mode 100644 index 0000000..daf3956 --- /dev/null +++ b/modules/events-mod/src/main/lua/main/events/consoleUpdates.lua @@ -0,0 +1,21 @@ +local ____exports = {} +local ____PacketEmitter = require("main.PacketEmitter") +local PacketEmitter = ____PacketEmitter.default +local ____kafkatorio_2Dschema = require("generated.kafkatorio-schema") +local KafkatorioPacketData = ____kafkatorio_2Dschema.KafkatorioPacketData +local Type = KafkatorioPacketData.Type +script.on_event( + defines.events.on_console_chat, + function(event) + local update = {type = Type.ConsoleChatUpdate, authorPlayerIndex = event.player_index or nil, content = event.message} + PacketEmitter:emitInstantPacket(update) + end +) +script.on_event( + defines.events.on_console_command, + function(event) + local update = {type = Type.ConsoleCommandUpdate, authorPlayerIndex = event.player_index or nil, command = event.command, parameters = event.parameters} + PacketEmitter:emitInstantPacket(update) + end +) +return ____exports diff --git a/modules/events-mod/src/main/lua/main/events/converters.lua b/modules/events-mod/src/main/lua/main/events/converters.lua new file mode 100644 index 0000000..4dcc755 --- /dev/null +++ b/modules/events-mod/src/main/lua/main/events/converters.lua @@ -0,0 +1,40 @@ +local ____exports = {} +____exports.Converters = {} +local Converters = ____exports.Converters +do + local mapEventIdToName = {} + for eventName, eventId in pairs(defines.events) do + mapEventIdToName[eventId] = eventName + end + function Converters.eventNameString(event) + return mapEventIdToName[event] + end + function Converters.mapColour(color) + return {color.r or 0, color.g or 0, color.b or 0, color.a or 0} + end + function Converters.convertPlacedTiles(placedTile, oldTiles) + local converted = {} + for ____, tile in ipairs(oldTiles) do + converted[#converted + 1] = {position = {x = tile.position.x, y = tile.position.y}, name = placedTile.name} + end + return converted + end + function Converters.convertRemovedTiles(surface, oldTiles) + local converted = {} + for ____, tile in ipairs(oldTiles) do + converted[#converted + 1] = surface.get_tile(tile.position.x, tile.position.y) + end + return converted + end + function Converters.convertMapTablePosition(position) + return {position.x, position.y} + end + function Converters.convertCollisionMaskToNames(cm) + local masks = {} + for name in pairs(cm) do + masks[#masks + 1] = name + end + return masks + end +end +return ____exports diff --git a/modules/events-mod/src/main/lua/main/events/entityUpdates.lua b/modules/events-mod/src/main/lua/main/events/entityUpdates.lua new file mode 100644 index 0000000..c5fd3ee --- /dev/null +++ b/modules/events-mod/src/main/lua/main/events/entityUpdates.lua @@ -0,0 +1,105 @@ +local ____exports = {} +local handleBuiltEntityEvent, handleMinedEntityEvent +local ____converters = require("main.events.converters") +local Converters = ____converters.Converters +local ____EventDataCache = require("main.cache.EventDataCache") +local EventDataCache = ____EventDataCache.default +local ____kafkatorio_2Dschema = require("generated.kafkatorio-schema") +local KafkatorioPacketData = ____kafkatorio_2Dschema.KafkatorioPacketData +function handleBuiltEntityEvent(event) + local eventName = Converters.eventNameString(event.name) + if event.created_entity.unit_number == nil then + return + end + local key = {name = event.created_entity.name, protoType = event.created_entity.prototype.name, unitNumber = event.created_entity.unit_number} + EventDataCache:debounce( + key, + KafkatorioPacketData.Type.EntityUpdate, + function(data) + if data.events == nil then + data.events = {} + end + local ____data_events_0, ____eventName_1 = data.events, eventName + if ____data_events_0[____eventName_1] == nil then + ____data_events_0[____eventName_1] = {} + end + local ____data_events_eventName_2 = data.events[eventName] + ____data_events_eventName_2[#____data_events_eventName_2 + 1] = event.tick + data.chunkPosition = Converters.convertMapTablePosition(event.created_entity.position) + data.graphicsVariation = event.created_entity.graphics_variation + data.health = event.created_entity.health + data.isActive = event.created_entity.active + data.isRotatable = event.created_entity.rotatable + local ____data_5 = data + local ____event_created_entity_last_user_index_3 = event.created_entity.last_user + if ____event_created_entity_last_user_index_3 ~= nil then + ____event_created_entity_last_user_index_3 = ____event_created_entity_last_user_index_3.index + end + ____data_5.lastUser = ____event_created_entity_last_user_index_3 + data.prototype = event.created_entity.prototype.name + end + ) +end +function handleMinedEntityEvent(event) + local eventName = Converters.eventNameString(event.name) + if event.entity.unit_number == nil then + return + end + local key = {name = event.entity.name, protoType = event.entity.prototype.name, unitNumber = event.entity.unit_number} + EventDataCache:debounce( + key, + KafkatorioPacketData.Type.EntityUpdate, + function(data) + if data.events == nil then + data.events = {} + end + local ____data_events_6, ____eventName_7 = data.events, eventName + if ____data_events_6[____eventName_7] == nil then + ____data_events_6[____eventName_7] = {} + end + local ____data_events_eventName_8 = data.events[eventName] + ____data_events_eventName_8[#____data_events_eventName_8 + 1] = event.tick + data.chunkPosition = Converters.convertMapTablePosition(event.entity.position) + data.graphicsVariation = event.entity.graphics_variation + data.health = event.entity.health + data.isActive = event.entity.active + data.isRotatable = event.entity.rotatable + local ____data_11 = data + local ____event_entity_last_user_index_9 = event.entity.last_user + if ____event_entity_last_user_index_9 ~= nil then + ____event_entity_last_user_index_9 = ____event_entity_last_user_index_9.index + end + ____data_11.lastUser = ____event_entity_last_user_index_9 + data.prototype = event.entity.prototype.name + end + ) +end +script.on_event( + defines.events.on_built_entity, + function(e) + log("on_built_entity " .. tostring(e.tick)) + handleBuiltEntityEvent(e) + end +) +script.on_event( + defines.events.on_robot_built_entity, + function(e) + log("on_robot_built_entity " .. tostring(e.tick)) + handleBuiltEntityEvent(e) + end +) +script.on_event( + defines.events.on_player_mined_entity, + function(e) + log("on_player_mined_entity " .. tostring(e.tick)) + handleMinedEntityEvent(e) + end +) +script.on_event( + defines.events.on_robot_mined_entity, + function(e) + log("on_robot_mined_entity " .. tostring(e.tick)) + handleMinedEntityEvent(e) + end +) +return ____exports diff --git a/modules/events-mod/src/main/lua/main/events/eventTypeCheck.lua b/modules/events-mod/src/main/lua/main/events/eventTypeCheck.lua new file mode 100644 index 0000000..d9cb883 --- /dev/null +++ b/modules/events-mod/src/main/lua/main/events/eventTypeCheck.lua @@ -0,0 +1,6 @@ +local ____exports = {} +function ____exports.isEventType(eventData, ____type) + local id = eventData.name + return id == ____type +end +return ____exports diff --git a/modules/events-mod/src/main/lua/main/events/mapChunkUpdates.lua b/modules/events-mod/src/main/lua/main/events/mapChunkUpdates.lua new file mode 100644 index 0000000..7c24f25 --- /dev/null +++ b/modules/events-mod/src/main/lua/main/events/mapChunkUpdates.lua @@ -0,0 +1,248 @@ +local ____lualib = require("lualib_bundle") +local Map = ____lualib.Map +local __TS__Iterator = ____lualib.__TS__Iterator +local __TS__New = ____lualib.__TS__New +local ____exports = {} +local mapTilesUpdateDebounce, getTiles, getSurface, groupTiles, handleBuiltTileEvent, handleMinedTileEvent, Type +local ____eventTypeCheck = require("main.events.eventTypeCheck") +local isEventType = ____eventTypeCheck.isEventType +local ____converters = require("main.events.converters") +local Converters = ____converters.Converters +local ____EventDataCache = require("main.cache.EventDataCache") +local EventUpdatesManager = ____EventDataCache.default +local ____kafkatorio_2Dschema = require("generated.kafkatorio-schema") +local KafkatorioPacketData = ____kafkatorio_2Dschema.KafkatorioPacketData +function mapTilesUpdateDebounce(surface, chunkPosition, tiles, event, updater, expirationDurationTicks) + if surface == nil then + return + end + local eventName = Converters.eventNameString(event.name) + local key = {surfaceIndex = surface.index, chunkPosition = chunkPosition} + EventUpdatesManager:debounce( + key, + Type.MapChunkUpdate, + function(data) + if data.tileDictionary == nil then + data.tileDictionary = {tilesXY = {}, protos = {}} + end + local protosCount = table_size(data.tileDictionary.protos) + for ____, tile in ipairs(tiles) do + local ____data_tileDictionary_protos_1, ____tile_name_2 = data.tileDictionary.protos, tile.name + if ____data_tileDictionary_protos_1[____tile_name_2] == nil then + local ____protosCount_0 = protosCount + protosCount = ____protosCount_0 + 1 + ____data_tileDictionary_protos_1[____tile_name_2] = ____protosCount_0 + end + local protoKey = data.tileDictionary.protos[tile.name] + local xString = tostring(tile.position.x) + local yString = tostring(tile.position.y) + local ____data_tileDictionary_tilesXY_3, ____xString_4 = data.tileDictionary.tilesXY, xString + if ____data_tileDictionary_tilesXY_3[____xString_4] == nil then + ____data_tileDictionary_tilesXY_3[____xString_4] = {} + end + data.tileDictionary.tilesXY[xString][yString] = protoKey + end + if data.events == nil then + data.events = {} + end + local ____data_events_5, ____eventName_6 = data.events, eventName + if ____data_events_5[____eventName_6] == nil then + ____data_events_5[____eventName_6] = {} + end + local ____data_events_eventName_7 = data.events[eventName] + ____data_events_eventName_7[#____data_events_eventName_7 + 1] = event.tick + if updater ~= nil then + updater(data) + end + end, + expirationDurationTicks + ) +end +function getTiles(surface, area) + local ____surface_find_tiles_filtered_result_8 = surface + if ____surface_find_tiles_filtered_result_8 ~= nil then + ____surface_find_tiles_filtered_result_8 = ____surface_find_tiles_filtered_result_8.find_tiles_filtered({area = area}) + end + return ____surface_find_tiles_filtered_result_8 or ({}) +end +function getSurface(surfaceIndex) + return game.surfaces[surfaceIndex] +end +function ____exports.handleChunkGeneratedEvent(event, expirationDurationTicks) + local tiles = getTiles(event.surface, event.area) + mapTilesUpdateDebounce( + event.surface, + Converters.convertMapTablePosition(event.position), + tiles, + event, + nil, + expirationDurationTicks + ) +end +function groupTiles(tiles) + local mapChunkPositionToTiles = __TS__New(Map) + for ____, tile in ipairs(tiles) do + local chunkPosition = { + math.floor(tile.position.x / 32), + math.floor(tile.position.y / 32) + } + if not mapChunkPositionToTiles:has(chunkPosition) then + mapChunkPositionToTiles:set(chunkPosition, {}) + end + local ____mapChunkPositionToTiles_get_result_push_result_10 = mapChunkPositionToTiles:get(chunkPosition) + if ____mapChunkPositionToTiles_get_result_push_result_10 ~= nil then + local ____temp_11 = mapChunkPositionToTiles:get(chunkPosition) + ____temp_11[#____temp_11 + 1] = tile + ____mapChunkPositionToTiles_get_result_push_result_10 = nil + end + end + return mapChunkPositionToTiles +end +function handleBuiltTileEvent(event) + local surface = getSurface(event.surface_index) + if surface == nil then + local eventName = Converters.eventNameString(event.name) + log("[handleBuiltTileEvent] undefined surface " .. eventName) + return + end + local tiles = Converters.convertPlacedTiles(event.tile, event.tiles) + local groupedTiles = groupTiles(tiles) + for ____, ____value in __TS__Iterator(groupedTiles) do + local chunkPos = ____value[1] + local tiles = ____value[2] + mapTilesUpdateDebounce( + surface, + chunkPos, + tiles, + event, + function(data) + if isEventType(event, defines.events.on_player_built_tile) then + data.player = event.player_index + return + end + if isEventType(event, defines.events.on_robot_built_tile) then + local ____data_15 = data + local ____event_robot_unit_number_13 = event.robot + if ____event_robot_unit_number_13 ~= nil then + ____event_robot_unit_number_13 = ____event_robot_unit_number_13.unit_number + end + ____data_15.robot = {unitNumber = ____event_robot_unit_number_13 or nil, name = event.robot.name, protoType = event.robot.type} + return + end + local exhaustiveCheck = event + end + ) + end +end +function handleMinedTileEvent(event) + local surface = getSurface(event.surface_index) + if surface == nil then + local eventName = Converters.eventNameString(event.name) + log("[handleMinedTileEvent] undefined surface " .. eventName) + return + end + local tiles = Converters.convertRemovedTiles(surface, event.tiles) + local groupedTiles = groupTiles(tiles) + for ____, ____value in __TS__Iterator(groupedTiles) do + local chunkPos = ____value[1] + local tiles = ____value[2] + mapTilesUpdateDebounce( + surface, + chunkPos, + tiles, + event, + function(data) + if isEventType(event, defines.events.on_player_mined_tile) then + data.player = event.player_index + return + end + if isEventType(event, defines.events.on_robot_mined_tile) then + local ____data_18 = data + local ____event_robot_unit_number_16 = event.robot + if ____event_robot_unit_number_16 ~= nil then + ____event_robot_unit_number_16 = ____event_robot_unit_number_16.unit_number + end + ____data_18.robot = {unitNumber = ____event_robot_unit_number_16 or nil, name = event.robot.name, protoType = event.robot.type} + return + end + local exhaustiveCheck = event + end + ) + end +end +Type = KafkatorioPacketData.Type +script.on_event( + defines.events.on_chunk_generated, + function(e) + log("on_chunk_generated " .. tostring(e.tick)) + ____exports.handleChunkGeneratedEvent(e) + end +) +script.on_event( + defines.events.script_raised_set_tiles, + function(event) + log("script_raised_set_tiles " .. tostring(event.tick)) + local surface = getSurface(event.surface_index) + if surface == nil then + return + end + local groupedTiles = groupTiles(event.tiles) + for ____, ____value in __TS__Iterator(groupedTiles) do + local chunkPos = ____value[1] + local tiles = ____value[2] + mapTilesUpdateDebounce(surface, chunkPos, tiles, event) + end + end +) +script.on_event( + defines.events.on_player_built_tile, + function(e) + log("on_player_built_tile " .. tostring(e.tick)) + handleBuiltTileEvent(e) + end +) +script.on_event( + defines.events.on_robot_built_tile, + function(e) + log("on_robot_built_tile " .. tostring(e.tick)) + handleBuiltTileEvent(e) + end +) +script.on_event( + defines.events.on_player_mined_tile, + function(e) + log("on_player_mined_tile " .. tostring(e.tick)) + handleMinedTileEvent(e) + end +) +script.on_event( + defines.events.on_robot_mined_tile, + function(e) + log("on_robot_mined_tile " .. tostring(e.tick)) + handleMinedTileEvent(e) + end +) +script.on_event( + defines.events.on_pre_chunk_deleted, + function(e) + log("on_pre_chunk_deleted " .. tostring(e.tick)) + local surface = getSurface(e.surface_index) + if surface == nil then + return + end + for ____, position in ipairs(e.positions) do + local key = {surfaceIndex = surface.index, chunkPosition = {position.x, position.y}} + EventUpdatesManager:debounce( + key, + Type.MapChunkUpdate, + function(data) + local ____temp_19 = true + data.isDeleted = ____temp_19 + return ____temp_19 + end, + 0 + ) + end + end +) +return ____exports diff --git a/modules/events-mod/src/main/lua/main/events/playerUpdates.lua b/modules/events-mod/src/main/lua/main/events/playerUpdates.lua new file mode 100644 index 0000000..3cfa307 --- /dev/null +++ b/modules/events-mod/src/main/lua/main/events/playerUpdates.lua @@ -0,0 +1,165 @@ +local ____exports = {} +local playerUpdateThrottle, playerOnlineInfo, handleBannedEvent, Type +local ____converters = require("main.events.converters") +local Converters = ____converters.Converters +local ____EventDataCache = require("main.cache.EventDataCache") +local EventUpdatesManager = ____EventDataCache.default +local ____kafkatorio_2Dschema = require("generated.kafkatorio-schema") +local KafkatorioPacketData = ____kafkatorio_2Dschema.KafkatorioPacketData +local ____PacketEmitter = require("main.PacketEmitter") +local packetEmitter = ____PacketEmitter.default +function playerUpdateThrottle(event, mutate, expirationDurationTicks) + if expirationDurationTicks == nil then + expirationDurationTicks = nil + end + local playerIndex = event.player_index + if playerIndex == nil then + return + end + local eventName = Converters.eventNameString(event.name) + EventUpdatesManager:throttle( + {index = playerIndex}, + Type.PlayerUpdate, + function(data) + local player = game.players[playerIndex] + if player ~= nil then + mutate(player, data) + end + if data.events == nil then + data.events = {} + end + local ____data_events_0, ____eventName_1 = data.events, eventName + if ____data_events_0[____eventName_1] == nil then + ____data_events_0[____eventName_1] = {} + end + local ____data_events_eventName_2 = data.events[eventName] + ____data_events_eventName_2[#____data_events_eventName_2 + 1] = event.tick + end, + expirationDurationTicks + ) +end +function playerOnlineInfo(player, data) + data.lastOnline = player.last_online + data.onlineTime = player.online_time + data.afkTime = player.afk_time + data.isConnected = player.connected +end +function handleBannedEvent(event) + playerUpdateThrottle( + event, + function(player, data) + data.bannedReason = event.reason or nil + playerOnlineInfo(player, data) + end + ) +end +Type = KafkatorioPacketData.Type +local function playerUpdateImmediate(event, mutate) + playerUpdateThrottle(event, mutate, 0) +end +script.on_event( + defines.events.on_player_joined_game, + function(e) + playerUpdateThrottle( + e, + function(player, data) + data.isAdmin = player.admin + local ____data_5 = data + local ____player_character_unit_number_3 = player.character + if ____player_character_unit_number_3 ~= nil then + ____player_character_unit_number_3 = ____player_character_unit_number_3.unit_number + end + ____data_5.characterUnitNumber = ____player_character_unit_number_3 or nil + data.chatColour = Converters.mapColour(player.chat_color) + data.colour = Converters.mapColour(player.color) + data.forceIndex = player.force.index + data.name = player.name + data.isShowOnMap = player.show_on_map + data.isSpectator = player.spectator + data.surfaceIndex = player.surface.index + data.tag = player.tag + playerOnlineInfo(player, data) + end + ) + end +) +script.on_event( + defines.events.on_player_changed_position, + function(e) + playerUpdateThrottle( + e, + function(player, data) + data.position = {player.position.x, player.position.y} + end + ) + end +) +script.on_event( + defines.events.on_player_changed_surface, + function(e) + playerUpdateThrottle( + e, + function(player, data) + data.position = {player.position.x, player.position.y} + data.surfaceIndex = player.surface.index + end + ) + end +) +script.on_event( + defines.events.on_player_died, + function(e) + playerUpdateThrottle( + e, + function(player, data) + data.ticksToRespawn = player.ticks_to_respawn or nil + playerOnlineInfo(player, data) + if e.cause ~= nil then + data.diedCause = {unitNumber = e.cause.unit_number or nil, name = e.cause.name, protoType = e.cause.type} + end + end + ) + end +) +script.on_event(defines.events.on_player_banned, handleBannedEvent) +script.on_event(defines.events.on_player_unbanned, handleBannedEvent) +script.on_event( + defines.events.on_player_kicked, + function(event) + log((("on_player_kicked " .. tostring(event.tick)) .. " ") .. tostring(event.name)) + playerUpdateImmediate( + event, + function(player, data) + data.kickedReason = event.reason or nil + playerOnlineInfo(player, data) + end + ) + end +) +local disconnectReasons = {} +for name, disconnectId in pairs(defines.disconnect_reason) do + disconnectReasons[disconnectId] = name +end +script.on_event( + defines.events.on_pre_player_left_game, + function(event) + log((("on_pre_player_left_game " .. tostring(event.tick)) .. " ") .. tostring(event.name)) + local playerUpdateKey = {index = event.player_index} + local playerUpdate = {type = KafkatorioPacketData.Type.PlayerUpdate, key = playerUpdateKey, disconnectReason = disconnectReasons[event.reason]} + packetEmitter:emitKeyedPacket(playerUpdate) + end +) +script.on_event( + defines.events.on_player_removed, + function(event) + log((("on_player_removed " .. tostring(event.tick)) .. " ") .. tostring(event.name)) + playerUpdateImmediate( + event, + function(player, data) + data.isRemoved = true + playerOnlineInfo(player, data) + end + ) + end +) +return ____exports diff --git a/modules/events-mod/src/main/lua/main/events/prototypeUpdates.lua b/modules/events-mod/src/main/lua/main/events/prototypeUpdates.lua new file mode 100644 index 0000000..1daa787 --- /dev/null +++ b/modules/events-mod/src/main/lua/main/events/prototypeUpdates.lua @@ -0,0 +1,42 @@ +local ____lualib = require("lualib_bundle") +local __TS__ArrayPushArray = ____lualib.__TS__ArrayPushArray +local ____exports = {} +local prototypeUpdates, getMapTilePrototypes +local ____PacketEmitter = require("main.PacketEmitter") +local PacketEmitter = ____PacketEmitter.default +local ____kafkatorio_2Dschema = require("generated.kafkatorio-schema") +local FactorioPrototype = ____kafkatorio_2Dschema.FactorioPrototype +local KafkatorioPacketData = ____kafkatorio_2Dschema.KafkatorioPacketData +local ____converters = require("main.events.converters") +local Converters = ____converters.Converters +function prototypeUpdates() + local prototypes = {} + __TS__ArrayPushArray( + prototypes, + getMapTilePrototypes() + ) + return prototypes +end +function getMapTilePrototypes() + local tiles = {} + for ____, tile in pairs(game.tile_prototypes) do + tiles[#tiles + 1] = { + type = FactorioPrototype.Type.MapTile, + name = tile.name, + order = tile.order, + layer = tile.layer, + collisionMasks = Converters.convertCollisionMaskToNames(tile.collision_mask), + mapColour = Converters.mapColour(tile.map_color), + canBeMined = tile.mineable_properties.minable + } + end + return tiles +end +function ____exports.emitPrototypes() + local data = { + prototypes = prototypeUpdates(), + type = KafkatorioPacketData.Type.PrototypesUpdate + } + PacketEmitter:emitInstantPacket(data) +end +return ____exports diff --git a/modules/events-mod/src/main/lua/main/events/registerHandlers.lua b/modules/events-mod/src/main/lua/main/events/registerHandlers.lua new file mode 100644 index 0000000..65aacb2 --- /dev/null +++ b/modules/events-mod/src/main/lua/main/events/registerHandlers.lua @@ -0,0 +1,49 @@ +local ____exports = {} +local ____queue = require("main.queue.queue") +local Queue = ____queue.Queue +local ____eventTypeCheck = require("main.events.eventTypeCheck") +local isEventType = ____eventTypeCheck.isEventType +local ____converters = require("main.events.converters") +local Converters = ____converters.Converters +local ____mapChunkUpdates = require("main.events.mapChunkUpdates") +local handleChunkGeneratedEvent = ____mapChunkUpdates.handleChunkGeneratedEvent +local ____surfaceUpdates = require("main.events.surfaceUpdates") +local handleSurfaceUpdate = ____surfaceUpdates.handleSurfaceUpdate +local ____EventDataCache = require("main.cache.EventDataCache") +local EventCacheService = ____EventDataCache.default +script.on_event( + defines.events.on_tick, + function(event) + if event.tick % 1000 == 0 then + for ____, surface in pairs(game.surfaces) do + handleSurfaceUpdate( + event, + Converters.eventNameString(event.name), + surface + ) + end + end + if event.tick % 6 == 0 then + local emittedCount = EventCacheService:extractAndEmitExpiredPackets() + if emittedCount > 0 then + log(((("[on_tick:" .. tostring(event.tick)) .. "] emitted ") .. tostring(emittedCount)) .. " events") + end + end + if event.tick % 7 == 0 then + local events = Queue.dequeueValues(1) + if #events > 0 then + log((((("[on_tick:" .. tostring(event.tick)) .. "] dequeued ") .. tostring(#events)) .. " events, current size: ") .. tostring(Queue.size())) + local i = 1 + for ____, event in ipairs(events) do + if isEventType(event, defines.events.on_chunk_generated) then + local eName = Converters.eventNameString(event.name) + log((((("[on_tick:" .. tostring(event.tick)) .. "] dequed event ") .. eName) .. ", delay ") .. tostring(i)) + handleChunkGeneratedEvent(event, i) + i = i + 1 + end + end + end + end + end +) +return ____exports diff --git a/modules/events-mod/src/main/lua/main/events/settingsUpdate.lua b/modules/events-mod/src/main/lua/main/events/settingsUpdate.lua new file mode 100644 index 0000000..e320cd0 --- /dev/null +++ b/modules/events-mod/src/main/lua/main/events/settingsUpdate.lua @@ -0,0 +1,6 @@ +script.on_event( + defines.events.on_runtime_mod_setting_changed, + function(e) + print((((((("Settings changed " .. e.setting_type) .. ", ") .. tostring(e.player_index)) .. ", ") .. e.setting) .. ", ") .. tostring(e.mod_name)) + end +) diff --git a/modules/events-mod/src/main/lua/main/events/surfaceUpdates.lua b/modules/events-mod/src/main/lua/main/events/surfaceUpdates.lua new file mode 100644 index 0000000..3e2f804 --- /dev/null +++ b/modules/events-mod/src/main/lua/main/events/surfaceUpdates.lua @@ -0,0 +1,11 @@ +local ____exports = {} +local ____PacketEmitter = require("main.PacketEmitter") +local PacketEmitter = ____PacketEmitter.default +local ____kafkatorio_2Dschema = require("generated.kafkatorio-schema") +local KafkatorioPacketData = ____kafkatorio_2Dschema.KafkatorioPacketData +local Type = KafkatorioPacketData.Type +function ____exports.handleSurfaceUpdate(event, eventType, surface) + local update = {type = Type.SurfaceUpdate, name = surface.name, index = surface.index, daytime = surface.daytime} + PacketEmitter:emitInstantPacket(update) +end +return ____exports diff --git a/modules/events-mod/src/main/lua/main/global-init.lua b/modules/events-mod/src/main/lua/main/global-init.lua new file mode 100644 index 0000000..5f21c61 --- /dev/null +++ b/modules/events-mod/src/main/lua/main/global-init.lua @@ -0,0 +1,17 @@ +local ____exports = {} +local ____queue = require("main.queue.queue") +local Queue = ____queue.Queue +local ____EventDataCache = require("main.cache.EventDataCache") +local EventUpdatesManager = ____EventDataCache.default +function ____exports.initGlobal(force) + if force == nil then + force = false + end + log(("Initialising Kafkatorio Global variables (force=" .. tostring(force)) .. ")...") + global.MOD_VERSION = script.active_mods[script.mod_name] + global.FACTORIO_VERSION = script.active_mods.base + Queue.init(true) + EventUpdatesManager:init(true) + log("Finished initialising Kafkatorio Global variables") +end +return ____exports diff --git a/modules/events-mod/src/main/lua/main/queue/queue.lua b/modules/events-mod/src/main/lua/main/queue/queue.lua new file mode 100644 index 0000000..2dcf0ca --- /dev/null +++ b/modules/events-mod/src/main/lua/main/queue/queue.lua @@ -0,0 +1,84 @@ +local ____lualib = require("lualib_bundle") +local __TS__New = ____lualib.__TS__New +local __TS__Class = ____lualib.__TS__Class +local ____exports = {} +____exports.Queue = {} +local Queue = ____exports.Queue +do + local Node + function Queue.init(force) + local isAnythingUndefined = global.store == nil or global.size == nil or global.head == nil or global.tail == nil + log(((("Initialising EventQueue globals (force=" .. tostring(force)) .. ", isAnythingUndefined=") .. tostring(isAnythingUndefined)) .. ")") + if force == true or isAnythingUndefined then + global.store = {} + global.head = nil + global.tail = nil + global.size = 0 + end + log("Finished initialising EventQueue") + end + function Queue.size() + return global.size + end + function Queue.enqueue(key, event, weight) + if weight == nil then + weight = 1 + end + if global.store[key] ~= nil then + local node = __TS__New(Node, key, weight) + if global.head == nil then + global.head = node + end + if global.tail ~= nil then + global.tail.next = node + end + global.tail = node + global.size = global.size + 1 + end + global.store[key] = event + end + function Queue.dequeue() + if global.head == nil then + return nil + else + local weight = global.head.weight + local storeKey = global.head.storeKey + global.head = global.head.next + global.size = global.size - 1 + local storedPacket = global.store[storeKey] + global.store[storeKey] = nil + if storedPacket == nil then + return nil + else + return {value = storedPacket, weight = weight} + end + end + end + function Queue.dequeueValues(targetWeight) + if targetWeight == nil then + targetWeight = 50 + end + local values = {} + local weight = 0 + repeat + do + local packet = Queue.dequeue() + if packet == nil then + break + else + weight = weight + packet.weight + values[#values + 1] = packet.value + end + end + until not (weight <= targetWeight) + return values + end + Node = __TS__Class() + Node.name = "Node" + function Node.prototype.____constructor(self, storeKey, weight) + self.next = nil + self.storeKey = storeKey + self.weight = weight + end +end +return ____exports diff --git a/modules/events-mod/src/main/lua/main/settings/KafkatorioSettings.lua b/modules/events-mod/src/main/lua/main/settings/KafkatorioSettings.lua new file mode 100644 index 0000000..aa8a574 --- /dev/null +++ b/modules/events-mod/src/main/lua/main/settings/KafkatorioSettings.lua @@ -0,0 +1,40 @@ +local ____lualib = require("lualib_bundle") +local __TS__Class = ____lualib.__TS__Class +local __TS__StringReplaceAll = ____lualib.__TS__StringReplaceAll +local __TS__New = ____lualib.__TS__New +local ____exports = {} +____exports.KafkatorioSettingsConfig = __TS__Class() +local KafkatorioSettingsConfig = ____exports.KafkatorioSettingsConfig +KafkatorioSettingsConfig.name = "KafkatorioSettingsConfig" +function KafkatorioSettingsConfig.prototype.____constructor(self) +end +function KafkatorioSettingsConfig.prototype.getEventCacheExpirationTicks(self, packet) + local settingName = ____exports.KafkatorioSettingsConfig:cacheDurationSettingName(packet.type) + local seconds = settings.global[settingName].value + return seconds * 60 +end +function KafkatorioSettingsConfig.prototype.initialiseSettings(self, data) + for ____type in pairs(____exports.KafkatorioSettingsConfig.eventCacheExpirationDefaultSeconds) do + data:extend({____exports.KafkatorioSettingsConfig:createDefaultCacheDuration(____type)}) + end +end +function KafkatorioSettingsConfig.createDefaultCacheDuration(self, ____type, defaultExpirationSeconds) + if defaultExpirationSeconds == nil then + defaultExpirationSeconds = ____exports.KafkatorioSettingsConfig.eventCacheExpirationDefaultSeconds[____type] + end + return { + type = "double-setting", + name = ____exports.KafkatorioSettingsConfig:cacheDurationSettingName(____type), + setting_type = "runtime-global", + default_value = defaultExpirationSeconds, + minimum_value = 0.25, + maximum_value = 120 + } +end +function KafkatorioSettingsConfig.cacheDurationSettingName(self, ____type) + return "kafkatorio:cache-expiration-seconds_" .. __TS__StringReplaceAll(____type, ".", "-") +end +KafkatorioSettingsConfig.eventCacheExpirationDefaultSeconds = {["kafkatorio.packet.keyed.PlayerUpdate"] = 0.5, ["kafkatorio.packet.keyed.MapChunkUpdate"] = 30, ["kafkatorio.packet.keyed.EntityUpdate"] = 5} +local KafkatorioSettings = __TS__New(____exports.KafkatorioSettingsConfig) +____exports.default = KafkatorioSettings +return ____exports diff --git a/modules/events-mod/src/main/lua/settings.lua b/modules/events-mod/src/main/lua/settings.lua new file mode 100644 index 0000000..f01f592 --- /dev/null +++ b/modules/events-mod/src/main/lua/settings.lua @@ -0,0 +1,5 @@ +local ____exports = {} +local ____KafkatorioSettings = require("main.settings.KafkatorioSettings") +local KafkatorioSettings = ____KafkatorioSettings.default +KafkatorioSettings:initialiseSettings(data) +return ____exports