hack together some sort of queue to help stop the chunk updates overloading the server. It doesn't work too well I think...
This commit is contained in:
parent
f2ccbbd456
commit
678cf5504e
11 changed files with 228 additions and 30 deletions
|
|
@ -1,6 +1,13 @@
|
||||||
import {handleConfigurationUpdate} from "./main/config-update/handleConfigurationUpdate";
|
import {handleConfigurationUpdate} from "./main/config-update/handleConfigurationUpdate";
|
||||||
|
import {emitPrototypes} from "./main/config-update/prototypes";
|
||||||
|
import {Queue} from "./main/queue/queue";
|
||||||
|
|
||||||
require("./main/events/registerHandlers")
|
require("./main/events/registerHandlers")
|
||||||
require("./main/commands/kafkatorioCommands")
|
require("./main/commands/kafkatorioCommands")
|
||||||
|
|
||||||
script.on_configuration_changed(handleConfigurationUpdate)
|
script.on_configuration_changed(handleConfigurationUpdate)
|
||||||
|
|
||||||
|
script.on_init(() => {
|
||||||
|
Queue.reset()
|
||||||
|
emitPrototypes()
|
||||||
|
})
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
import {emitPrototypes} from "../config-update/prototypes";
|
import {emitPrototypes} from "../config-update/prototypes";
|
||||||
import {handleChunkUpdate} from "../events/handlers";
|
import {handleChunkUpdate} from "../events/handlers";
|
||||||
|
import {Queue} from "../queue/queue";
|
||||||
import floor = math.floor;
|
import floor = math.floor;
|
||||||
|
|
||||||
|
|
||||||
commands.add_command(
|
commands.add_command(
|
||||||
"kafkatorio",
|
"kafkatorio",
|
||||||
"kafkatorio innit bruv",
|
"kafkatorio innit bruv",
|
||||||
|
|
@ -36,7 +38,7 @@ commands.add_command(
|
||||||
|
|
||||||
handleChunkUpdate(
|
handleChunkUpdate(
|
||||||
e.tick,
|
e.tick,
|
||||||
"player-command",
|
"player-command-" + e.parameter,
|
||||||
player.surface.index,
|
player.surface.index,
|
||||||
chunkPosition,
|
chunkPosition,
|
||||||
chunkArea,
|
chunkArea,
|
||||||
|
|
@ -44,23 +46,50 @@ commands.add_command(
|
||||||
}
|
}
|
||||||
} else if ("CHUNKS" == e.parameter.toUpperCase()) {
|
} else if ("CHUNKS" == e.parameter.toUpperCase()) {
|
||||||
|
|
||||||
for (let [, surface] of game.surfaces) {
|
if (e.player_index != undefined) {
|
||||||
for (let chunk of surface.get_chunks()) {
|
let player = game.players[e.player_index]
|
||||||
if (
|
|
||||||
(chunk.x >= -16 || chunk.x <= 16)
|
let chunkPosition: ChunkPosition = {
|
||||||
&&
|
x: floor(player.position.x / 32),
|
||||||
(chunk.y >= -16 || chunk.y <= 16)
|
y: floor(player.position.y / 32),
|
||||||
) {
|
}
|
||||||
handleChunkUpdate(
|
|
||||||
e.tick,
|
let delta = 1
|
||||||
"player-command",
|
|
||||||
surface.index,
|
let chunkXMin = chunkPosition.x - delta
|
||||||
chunk,
|
let chunkXMax = chunkPosition.x + delta
|
||||||
chunk.area,
|
let chunkYMin = chunkPosition.y - delta
|
||||||
)
|
let chunkYMax = chunkPosition.y + delta
|
||||||
|
|
||||||
|
for (let [, surface] of game.surfaces) {
|
||||||
|
for (let chunk of surface.get_chunks()) {
|
||||||
|
if (
|
||||||
|
(chunk.x >= chunkXMin || chunk.x <= chunkXMax)
|
||||||
|
&&
|
||||||
|
(chunk.y >= chunkYMin || chunk.y <= chunkYMax)
|
||||||
|
) {
|
||||||
|
|
||||||
|
let data: OnChunkGeneratedEvent = {
|
||||||
|
name: defines.events.on_chunk_generated,
|
||||||
|
position: {x: chunk.x, y: chunk.y},
|
||||||
|
area: chunk.area,
|
||||||
|
surface: surface,
|
||||||
|
tick: e.tick
|
||||||
|
}
|
||||||
|
|
||||||
|
Queue.enqueue(
|
||||||
|
`${surface.index}${chunk.x}${chunk.y}`,
|
||||||
|
data,
|
||||||
|
50
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if ("QUEUE_RESET" == e.parameter.toUpperCase()) {
|
||||||
|
Queue.reset()
|
||||||
|
} else if ("QUEUE_INIT" == e.parameter.toUpperCase()) {
|
||||||
|
Queue.init()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import {emitPacket} from "../emitKafkatorioPacket";
|
import {emitPacket} from "../emitKafkatorioPacket";
|
||||||
import {updateGlobal} from "./updateGlobal";
|
import {updateGlobal} from "./updateGlobal";
|
||||||
import {emitPrototypes} from "./prototypes";
|
import {emitPrototypes} from "./prototypes";
|
||||||
|
import {Queue} from "../queue/queue";
|
||||||
|
|
||||||
export function handleConfigurationUpdate(changeData: ConfigurationChangedData) {
|
export function handleConfigurationUpdate(changeData: ConfigurationChangedData) {
|
||||||
updateGlobal()
|
updateGlobal()
|
||||||
|
|
@ -12,6 +13,7 @@ export function handleConfigurationUpdate(changeData: ConfigurationChangedData)
|
||||||
factorioData: factorioData(changeData)
|
factorioData: factorioData(changeData)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
Queue.reset()
|
||||||
emitPrototypes()
|
emitPrototypes()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
/** Emit a serialised KafkatorioPacket */
|
/** Emit a serialised KafkatorioPacket */
|
||||||
export function emitPacket<T extends KafkatorioPacket>(packet: T) {
|
export function emitPacket<T extends KafkatorioPacket>(packet: T) {
|
||||||
let data = game.table_to_json(packet)
|
let data = game.table_to_json(packet)
|
||||||
|
// localised_print(`KafkatorioPacket: ${packet.packetType}`)
|
||||||
localised_print(`KafkatorioPacket: ${data}`)
|
localised_print(`KafkatorioPacket: ${data}`)
|
||||||
// rcon.print(`KafkatorioPacket: ${data}`)
|
// rcon.print(`KafkatorioPacket: ${data}`)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,3 @@
|
||||||
// const SERVER_ID: uint = 0
|
|
||||||
// const EVENT_FILE_DIR: string = "events"
|
|
||||||
|
|
||||||
import {emitPacket} from "../emitKafkatorioPacket";
|
import {emitPacket} from "../emitKafkatorioPacket";
|
||||||
|
|
||||||
/** Emit a serialised event */
|
/** Emit a serialised event */
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,10 @@
|
||||||
import {Converters} from "./converters"
|
import {Converters} from "./converters"
|
||||||
import {emitEvent} from "./emitEvent";
|
import {emitEvent} from "./emitEvent";
|
||||||
|
|
||||||
|
|
||||||
export function handlePlayerUpdate(tick: uint, eventType: string, playerIndex: uint) {
|
export function handlePlayerUpdate(tick: uint, eventType: string, playerIndex: uint) {
|
||||||
let player: LuaPlayer = game.players[playerIndex]
|
let player: LuaPlayer = game.players[playerIndex]
|
||||||
let table = Converters.playerToTable(player)
|
let table = Converters.playerToTable(player)
|
||||||
|
|
||||||
|
|
||||||
emitEvent(table, tick, eventType)
|
emitEvent(table, tick, eventType)
|
||||||
|
|
||||||
handleCharactersEvent(tick, eventType, playerIndex)
|
handleCharactersEvent(tick, eventType, playerIndex)
|
||||||
|
|
@ -50,8 +48,6 @@ export function handleConsoleChat(
|
||||||
emitEvent(table, tick, eventType)
|
emitEvent(table, tick, eventType)
|
||||||
}
|
}
|
||||||
|
|
||||||
// const CHUNK_SIZE = 32
|
|
||||||
|
|
||||||
export function handleChunkUpdate(
|
export function handleChunkUpdate(
|
||||||
tick: uint,
|
tick: uint,
|
||||||
eventType: string,
|
eventType: string,
|
||||||
|
|
@ -64,8 +60,6 @@ export function handleChunkUpdate(
|
||||||
|
|
||||||
let tiles: LuaTile[] = surface?.find_tiles_filtered({
|
let tiles: LuaTile[] = surface?.find_tiles_filtered({
|
||||||
area: area,
|
area: area,
|
||||||
// position: {x: x, y: y},
|
|
||||||
// radius: CHUNK_SIZE,
|
|
||||||
collision_mask: ["ground-tile", "water-tile"]
|
collision_mask: ["ground-tile", "water-tile"]
|
||||||
}
|
}
|
||||||
) ?? []
|
) ?? []
|
||||||
|
|
|
||||||
|
|
@ -6,13 +6,20 @@ import {
|
||||||
handleSurfaceUpdate,
|
handleSurfaceUpdate,
|
||||||
handleTilesUpdate
|
handleTilesUpdate
|
||||||
} from "./handlers";
|
} from "./handlers";
|
||||||
|
import {Queue} from "../queue/queue";
|
||||||
import on_player_built_tile = defines.events.on_player_built_tile;
|
import on_player_built_tile = defines.events.on_player_built_tile;
|
||||||
import on_robot_built_tile = defines.events.on_robot_built_tile;
|
import on_robot_built_tile = defines.events.on_robot_built_tile;
|
||||||
|
|
||||||
|
|
||||||
const mapEventIdToName = new LuaTable<defines.Events, keyof typeof defines.events>()
|
const mapEventIdToName = new LuaTable<defines.Events, keyof typeof defines.events>()
|
||||||
for (const [k, v] of pairs(defines.events)) {
|
for (const [eventName, eventId] of pairs(defines.events)) {
|
||||||
mapEventIdToName.set(v, k)
|
mapEventIdToName.set(eventId, eventName)
|
||||||
|
}
|
||||||
|
|
||||||
|
const mapEventIdToDefinedType = new LuaTable<EventId<EventData>, EventId<EventData>>()
|
||||||
|
for (const [eventName, eventId] of pairs(defines.events)) {
|
||||||
|
let definedType = defines.events[eventName]
|
||||||
|
mapEventIdToDefinedType.set(eventId, definedType)
|
||||||
}
|
}
|
||||||
|
|
||||||
// script.on_event(
|
// script.on_event(
|
||||||
|
|
@ -34,6 +41,9 @@ script.on_event(
|
||||||
script.on_event(
|
script.on_event(
|
||||||
defines.events.on_player_joined_game,
|
defines.events.on_player_joined_game,
|
||||||
(e: OnPlayerJoinedGameEvent) => {
|
(e: OnPlayerJoinedGameEvent) => {
|
||||||
|
|
||||||
|
Queue.init() // TODO make Queue initialisation more stable, not dependent on events
|
||||||
|
|
||||||
handlePlayerUpdate(e.tick, mapEventIdToName.get(e.name), e.player_index)
|
handlePlayerUpdate(e.tick, mapEventIdToName.get(e.name), e.player_index)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
@ -52,6 +62,29 @@ script.on_event(
|
||||||
for (const [, surface] of pairs(game.surfaces)) {
|
for (const [, surface] of pairs(game.surfaces)) {
|
||||||
handleSurfaceUpdate(e.tick, mapEventIdToName.get(e.name), surface)
|
handleSurfaceUpdate(e.tick, mapEventIdToName.get(e.name), surface)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// let packets = new KafkatorioPacketQueue().dequeueValues(1)
|
||||||
|
// for (const packet of packets) {
|
||||||
|
// emitPacket(packet)
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.tick % 30 == 0) {
|
||||||
|
let events: EventData[] = Queue.dequeueValues(1)
|
||||||
|
|
||||||
|
if (events.length > 0) {
|
||||||
|
log(`[${e.tick}] dequed ${events.length} events, current size: ${Queue.size()}`)
|
||||||
|
|
||||||
|
for (const event of events) {
|
||||||
|
|
||||||
|
if (isEventType<OnChunkGeneratedEvent>(event)) {
|
||||||
|
let eName = mapEventIdToName.get(event.name)
|
||||||
|
|
||||||
|
log(`[${e.tick}] dequed event ${eName}`)
|
||||||
|
handleChunkUpdate(e.tick, eName, event.surface.index, event.position, event.area)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
@ -82,3 +115,14 @@ script.on_event(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
function isEventType<E extends EventData>(e: EventData): e is E {
|
||||||
|
let id: EventId<EventData> | string = e.name
|
||||||
|
if (typeof id === "string") {
|
||||||
|
return false
|
||||||
|
} else {
|
||||||
|
let name = mapEventIdToDefinedType.get(id)
|
||||||
|
return e.name == name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
124
modules/events-mod/src/main/typescript/main/queue/queue.ts
Normal file
124
modules/events-mod/src/main/typescript/main/queue/queue.ts
Normal file
|
|
@ -0,0 +1,124 @@
|
||||||
|
export namespace Queue {
|
||||||
|
|
||||||
|
declare const global: {
|
||||||
|
store: EventQueueStore
|
||||||
|
|
||||||
|
head: Node | null
|
||||||
|
tail: Node | null
|
||||||
|
|
||||||
|
size: uint
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function init() {
|
||||||
|
if (global.store == undefined) {
|
||||||
|
log("initialising EventQueue")
|
||||||
|
reset()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function reset() {
|
||||||
|
log("Resetting EventQueue")
|
||||||
|
global.store = {}
|
||||||
|
global.head = null
|
||||||
|
global.tail = null
|
||||||
|
global.size = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function size(): uint {
|
||||||
|
return global.size
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function enqueue(key: string, event: EventData, weight: int = 1) {
|
||||||
|
if (key ! in global.store) {
|
||||||
|
let node = new Node(key, weight)
|
||||||
|
if (global.head == null) {
|
||||||
|
global.head = node
|
||||||
|
}
|
||||||
|
if (global.tail != null) {
|
||||||
|
global.tail.next = node
|
||||||
|
}
|
||||||
|
global.tail = node
|
||||||
|
}
|
||||||
|
|
||||||
|
global.store[key] = event
|
||||||
|
global.size++
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function dequeue(): WeightedPacket | null {
|
||||||
|
if (global.head == null) {
|
||||||
|
return null
|
||||||
|
} else {
|
||||||
|
let weight = global.head.weight
|
||||||
|
let storeKey = global.head.storeKey
|
||||||
|
global.head = global.head.next
|
||||||
|
|
||||||
|
let storedPacket = global.store[storeKey]
|
||||||
|
global.store[storeKey] = null
|
||||||
|
|
||||||
|
if (storedPacket == null) {
|
||||||
|
return null
|
||||||
|
} else {
|
||||||
|
global.size--
|
||||||
|
return {
|
||||||
|
value: storedPacket,
|
||||||
|
weight: weight,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function dequeueValues(targetWeight: uint = 50): EventData[] {
|
||||||
|
let values: EventData[] = []
|
||||||
|
let weight: uint = 0
|
||||||
|
|
||||||
|
do {
|
||||||
|
let packet = dequeue()
|
||||||
|
|
||||||
|
if (packet == null) {
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
weight += packet.weight
|
||||||
|
values[values.length] = packet.value
|
||||||
|
}
|
||||||
|
} while (weight <= targetWeight)
|
||||||
|
|
||||||
|
return values
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class Node {
|
||||||
|
storeKey: string;
|
||||||
|
next: Node | null = null;
|
||||||
|
weight: uint
|
||||||
|
|
||||||
|
constructor(storeKey: string, weight: uint) {
|
||||||
|
this.storeKey = storeKey;
|
||||||
|
this.weight = weight
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
interface EventQueueStore {
|
||||||
|
[key: string]: EventData | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// interface PacketQueue<T> {
|
||||||
|
// enqueue(key: string, packet: T, weight: int): void
|
||||||
|
//
|
||||||
|
// dequeue(): WeightedPacket<T> | null
|
||||||
|
//
|
||||||
|
// dequeueValues(targetWeight: int): T[]
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
interface WeightedPacket {
|
||||||
|
value: EventData,
|
||||||
|
weight: int,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "kafkatorio-events-mod",
|
"name": "kafkatorio-events-mod",
|
||||||
"version": "0.2.6",
|
"version": "0.2.7",
|
||||||
"lockfileVersion": 1,
|
"lockfileVersion": 1,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "kafkatorio-events-mod",
|
"name": "kafkatorio-events-mod",
|
||||||
"version": "0.2.6",
|
"version": "0.2.7",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "tstl",
|
"build": "tstl",
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
{
|
{
|
||||||
"$schema": "https://raw.githubusercontent.com/TypeScriptToLua/vscode-typescript-to-lua/master/tsconfig-schema.json",
|
"$schema": "https://raw.githubusercontent.com/TypeScriptToLua/vscode-typescript-to-lua/master/tsconfig-schema.json",
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"target": "es2019",
|
"target": "esnext",
|
||||||
"lib": [
|
"lib": [
|
||||||
"es2019"
|
"esnext"
|
||||||
],
|
],
|
||||||
"module": "commonjs",
|
"module": "commonjs",
|
||||||
"moduleResolution": "node",
|
"moduleResolution": "node",
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue