project re-organisation, and rename

This commit is contained in:
Adam 2021-12-01 16:57:46 +01:00
parent 53862ef1b5
commit 633e898f3c
52 changed files with 525 additions and 387 deletions

View file

@ -0,0 +1,235 @@
import com.github.gradle.node.npm.task.NpmTask
import dev.adamko.factoriowebmap.configurations.asConsumer
import dev.adamko.factoriowebmap.configurations.asProvider
import dev.adamko.factoriowebmap.configurations.factorioModAttributes
import dev.adamko.factoriowebmap.configurations.typescriptAttributes
import groovy.json.JsonOutput
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonObject
import kotlinx.serialization.json.JsonPrimitive
import kotlinx.serialization.json.jsonObject
import kotlinx.serialization.json.jsonPrimitive
import org.apache.tools.ant.filters.ReplaceTokens
import org.gradle.kotlin.dsl.support.useToRun
import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs
import org.jetbrains.kotlin.util.suffixIfNot
plugins {
idea
id("dev.adamko.factoriowebmap.archetype.node")
}
val tokens: Map<String, String> by project.extra
val licenseFile: RegularFile by project.extra
val tsSrcDir: Directory = layout.projectDirectory.dir("src/main/typescript")
node {
nodeProjectDir.set(tsSrcDir)
}
val dataModelTs by configurations.registering {
asConsumer()
typescriptAttributes(objects)
defaultDependencies {
project.dependencies.create(projects.modules.eventsSchema)
}
}
val typescriptToLua by tasks.registering(NpmTask::class) {
description = "Convert Typescript To Lua"
group = project.name
dependsOn(tasks.npmInstall)
execOverrides { standardOutput = System.out }
npmCommand.set(listOf("run", "build"))
inputs.dir(project.node.nodeProjectDir)
.skipWhenEmpty()
.withPropertyName("sourceFiles")
.withPathSensitivity(PathSensitivity.RELATIVE)
val intermediateOutputDir = temporaryDir
args.set(parseSpaceSeparatedArgs("-- --outDir $intermediateOutputDir"))
val outputDir = layout.buildDirectory.dir("typescriptToLua")
outputs.dir(outputDir)
.withPropertyName("outputDir")
ignoreExitValue.set(false)
doFirst("clean") {
delete(intermediateOutputDir)
}
doLast("syncTstlOutput") {
sync {
from(intermediateOutputDir)
into(outputDir)
}
}
}
val updatePackageJsonVersion by tasks.registering {
group = project.name
description = """
Read the package.json file and set the version to be the project's version.
""".trimIndent()
val projectVersion = "${project.version}"
inputs.properties(
"projectVersion" to projectVersion,
)
val packageJsonFile = layout.projectDirectory.file("src/main/typescript/package.json")
outputs.file(packageJsonFile)
val jsonFormatter = Json {
prettyPrint = true
prettyPrintIndent = " "
}
onlyIf {
// check to see if the version is already up-to-date
val packageJsonContent = packageJsonFile.asFile.readText()
val packageJson = jsonFormatter.parseToJsonElement(packageJsonContent).jsonObject
packageJson["version"]?.jsonPrimitive?.content != projectVersion
}
doLast {
val packageJsonContent = packageJsonFile.asFile.readText()
val packageJson = jsonFormatter.parseToJsonElement(packageJsonContent).jsonObject
val packageJsonUpdate = JsonObject(
packageJson + ("version" to JsonPrimitive(projectVersion))
)
val packageJsonContentUpdated =
jsonFormatter
.encodeToString(packageJsonUpdate)
.suffixIfNot("\n")
packageJsonFile.asFile.writer().useToRun {
write(packageJsonContentUpdated)
}
}
}
val updateDataModel by tasks.registering(Sync::class) {
group = project.name
description = "Fetch the latest shared data-model"
dependsOn(dataModelTs)
from(
dataModelTs.map { c ->
c.incoming
.artifactView { lenient(true) }
.artifacts
.artifactFiles
.filter { file -> file.exists() }
}
)
into(layout.projectDirectory.dir("src/main/typescript/model"))
}
val packageMod by tasks.registering(Zip::class) {
description = "Package mod files into ZIP"
group = project.name
dependsOn(typescriptToLua)
inputs.properties(tokens)
from(layout.projectDirectory.dir("src/main/resources/mod-data")) {
include("**/**")
filter<ReplaceTokens>("tokens" to tokens)
}
dependsOn(typescriptToLua)
from(licenseFile)
into(rootProject.name)
// Factorio required format is:
// - filename: `mod-name_version.zip`
// - zip contains one directory, `mod-name`
archiveFileName.set("${rootProject.name}_${project.version}.zip")
destinationDirectory.set(layout.buildDirectory.dir("dist"))
doLast {
val outDir = destinationDirectory.asFile.get().toRelativeString(layout.projectDirectory.asFile)
val outZip = "${archiveFileName.orNull}"
logger.lifecycle("Packaged mod into $outDir/$outZip")
}
}
val downloadFactorioApiDocs by tasks.registering {
group = project.name
val target = uri("https://lua-api.factorio.com/latest/runtime-api.json")
val apiFilename = File(target.path).name
val downloadedFile = file("$temporaryDir/$apiFilename")
val apiFile = layout.buildDirectory.file(apiFilename)
outputs.file(apiFile)
doLast {
ant.invokeMethod(
"get", mapOf(
"src" to target,
"dest" to downloadedFile,
"verbose" to true,
)
)
val json = downloadedFile.readText()
val prettyJson = JsonOutput.prettyPrint(json)
apiFile.get().asFile.writeText(prettyJson)
logger.lifecycle("Downloaded Factorio API json: $apiFile")
}
}
val factorioModProvider by configurations.registering {
asProvider()
factorioModAttributes(objects)
outgoing.artifact(packageMod)
}
tasks.assemble { dependsOn(updateDataModel, updatePackageJsonVersion) }
tasks.build { dependsOn(packageMod) }
//
//idea {
// // this doesn't work - no source sets?
// module {
// sourceDirs.add(mkdir(layout.projectDirectory.dir("src/main/typescript").asFile))
// excludeDirs.add(mkdir(layout.projectDirectory.dir("src/main/typescript/node_modules").asFile))
// resourceDirs.add(mkdir(layout.projectDirectory.dir("src/main/resources").asFile))
// resourceDirs.add(mkdir(layout.projectDirectory.dir("infra").asFile))
// excludeDirs.add(mkdir(layout.projectDirectory.dir("infra/factorio-server").asFile))
// }
//}
//
//val typescriptSrcSet =
// project.objects.sourceDirectorySet("typescript", "typescript").apply {
// srcDir(layout.projectDirectory.dir("src/main/typescript"))
//
// destinationDirectory.set(modBuildDir.dir("typescriptToLua").asFile)
// compiledBy(tstlTask) {
//
// project.objects.directoryProperty().apply {
// set(modBuildDir.dir("typescriptToLua"))
// }
// }
// }

View file

@ -0,0 +1,4 @@
---------------------------------------------------------------------------------------------------
Version: 0.0.1
Features:
- Factorio Web Map

View file

@ -0,0 +1,8 @@
{
"name": "factorio-web-map",
"version": "@project.version@",
"title": "Factorio Web Map",
"author": "fredthedeadhead",
"factorio_version": "1.1",
"dependencies": []
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 702 B

View file

@ -0,0 +1 @@
require("events")

View file

@ -0,0 +1,120 @@
// import {Data, Mods} from "typed-factorio/settings/types"
// import { events } from "typed-factorio/generated"
// declare const factorioData: Data
// declare const factorioMods: Mods
import {Serdes} from "./serdes/serdes"
// import {FactorioEvent, JsonTable} from "./model/model";
const MOD_VERSION = script.active_mods["factorio-web-map"]
const mapEventIdToName = new LuaTable<defines.Events, keyof typeof defines.events>()
for (const [k, v] of pairs(defines.events)) {
mapEventIdToName.set(v, k)
}
function handlePlayerUpdate(tick: uint, playerIndex: uint, eventType: string) {
let player: LuaPlayer = game.players[playerIndex]
let table = Serdes.Player.playerToTable(player)
emitEvent(table, tick, eventType)
handleCharactersEvent(tick, playerIndex, eventType)
}
function handleCharactersEvent(tick: uint, playerIndex: uint, eventType: string) {
let player: LuaPlayer = game.players[playerIndex]
if (player.character != undefined) {
handleEntityUpdate(tick, player.character, eventType)
}
for (const character of player.get_associated_characters()) {
if (character != undefined) {
handleEntityUpdate(tick, character, eventType)
}
}
}
function handleEntityUpdate(tick: uint, entity: LuaEntity, eventType: string) {
let table = Serdes.Entity.entityToTable(entity)
emitEvent(table, tick, eventType)
}
function surfaceEvent(tick: uint, surface: LuaSurface, eventType: string) {
let table = Serdes.Surface.surfaceToTable(surface)
emitEvent(table, tick, eventType)
}
// const SERVER_ID: uint = 0
// const EVENT_FILE_DIR: string = "events"
/** Emit a serialised event */
function emitEvent<T extends FactorioObjectData>(eventData: T, tick: uint, eventType: string) {
let event: FactorioEvent<T> = {
data: eventData,
event_type: eventType,
mod_version: MOD_VERSION,
tick: tick
}
let data = game.table_to_json(event)
localised_print(`FactorioEvent: ${data}`)
}
// script.on_event(
// [defines.events.on_pre_build, defines.events.on_player_dropped_item],
// (e: OnPreBuildEvent | OnPlayerDroppedItemEvent) => {
// game.print("player " + e.player_index + " dropped item, tick:" + e.tick)
// }
// );
script.on_event(
defines.events.on_player_mined_entity,
(e: OnPlayerMinedEntityEvent) => {
handlePlayerUpdate(e.tick, e.player_index, "on_player_mined_entity")
handleEntityUpdate(e.tick, e.entity, "on_player_mined_entity")
}
)
script.on_event(
defines.events.on_player_joined_game,
(e: OnPlayerJoinedGameEvent) => {
handlePlayerUpdate(e.tick, e.player_index, "on_player_joined_game")
}
)
script.on_event(
defines.events.on_player_changed_position,
// this is actually a character update, not a player update?
(e: OnPlayerChangedPositionEvent) => {
handlePlayerUpdate(e.tick, e.player_index, "on_player_changed_position")
}
)
script.on_event(
defines.events.on_tick,
(e: OnTickEvent) => {
if (e.tick % 60 == 0) {
for (const [index,] of pairs(game.surfaces)) {
let surface = game.surfaces[index]
surfaceEvent(e.tick, surface, mapEventIdToName.get(e.name))
// surfaceEvent(e.tick, surface, "on_tick")
}
// let filename: string = table.concat([entity.unit_number, eventType, tick], "_")
// let msg = "test mod tick: " + e.tick + "\n"
// game.write_file("tick.log", msg, true, SERVER_ID)
// let filename: string = `OnTickEvent/${e.tick}`
// outputEvent(filename, e)
}
}
);
// script.on_load(() => {
// game.print("loaded Factorio Web Map!")
// });

View file

@ -0,0 +1,46 @@
// Generated code - do edit this file manually
interface FactorioObjectData {
object_name: string;
}
interface FactorioEvent<T extends FactorioObjectData> {
data: T;
event_type: string;
mod_version: string;
tick: uint;
}
interface PositionData {
x: double;
y: double;
}
interface PlayerData extends FactorioObjectData {
associated_characters_unit_numbers: uint[];
character_unit_number: uint | null;
name: string;
object_name: string;
position: PositionData;
}
interface EntityData extends FactorioObjectData {
active: boolean;
health: double | null;
health_ratio: double;
name: string;
object_name: string;
player_index: uint | null;
position: PositionData;
surface_index: int;
type: string;
unit_number: uint | null;
}
interface SurfaceData extends FactorioObjectData {
daytime: double;
index: uint;
name: string;
object_name: string;
}

View file

@ -0,0 +1,101 @@
{
"name": "factorio-web-map-mod",
"version": "0.0.7",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"@types/node": {
"version": "12.20.33",
"resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.33.tgz",
"integrity": "sha512-5XmYX2GECSa+CxMYaFsr2mrql71Q4EvHjKS+ox/SiwSdaASMoBIWE6UmZqFO+VX1jIcsYLStI4FFoB6V7FeIYw=="
},
"enhanced-resolve": {
"version": "5.8.3",
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.8.3.tgz",
"integrity": "sha512-EGAbGvH7j7Xt2nc0E7D99La1OiEs8LnyimkRgwExpUMScN6O+3x9tIWs7PLQZVNx4YD+00skHXPXi1yQHpAmZA==",
"requires": {
"graceful-fs": "^4.2.4",
"tapable": "^2.2.0"
}
},
"function-bind": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
},
"graceful-fs": {
"version": "4.2.8",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz",
"integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg=="
},
"has": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
"integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
"requires": {
"function-bind": "^1.1.1"
}
},
"is-core-module": {
"version": "2.8.0",
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.0.tgz",
"integrity": "sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw==",
"requires": {
"has": "^1.0.3"
}
},
"lua-types": {
"version": "2.11.0",
"resolved": "https://registry.npmjs.org/lua-types/-/lua-types-2.11.0.tgz",
"integrity": "sha512-J/8qHrOjkZuPBDhnuAg0DWoaJEImqXNzgEnUigCTVrSVCcchM5Y5zpcI3aWAZPhuZlb0QKC/f3nc7VGmZmBg7w=="
},
"path-parse": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="
},
"resolve": {
"version": "1.20.0",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz",
"integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==",
"requires": {
"is-core-module": "^2.2.0",
"path-parse": "^1.0.6"
}
},
"source-map": {
"version": "0.7.3",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz",
"integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ=="
},
"tapable": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz",
"integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ=="
},
"typed-factorio": {
"version": "0.12.0",
"resolved": "https://registry.npmjs.org/typed-factorio/-/typed-factorio-0.12.0.tgz",
"integrity": "sha512-7SeZX7TvWjtO+V5buWEgHUbhi7tSNZsHGveh5uPQ6Vvr7BDEhHre9DP3OrdD+L7cpAtvJ2w9OwaMnDm2P5dvng==",
"requires": {
"lua-types": "^2.10.1",
"typescript-to-lua": "^1.0.0"
}
},
"typescript": {
"version": "4.4.4",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.4.tgz",
"integrity": "sha512-DqGhF5IKoBl8WNf8C1gu8q0xZSInh9j1kJJMqT3a94w1JzVaBU4EXOSMrz9yDqMT0xt3selp83fuFMQ0uzv6qA=="
},
"typescript-to-lua": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/typescript-to-lua/-/typescript-to-lua-1.1.1.tgz",
"integrity": "sha512-13vk/FSQyqbBkXNvg73LpT0tsPKdepJHPYR6TNtbc9l1ClSxAEUvkB3k49MAwSQ6LoN8Ui4Bgyu9dKFoDB315Q==",
"requires": {
"enhanced-resolve": "^5.8.2",
"resolve": "^1.15.1",
"source-map": "^0.7.3"
}
}
}
}

View file

@ -0,0 +1,26 @@
{
"name": "factorio-web-map-mod",
"version": "0.0.7",
"private": true,
"scripts": {
"build": "tstl",
"dev": "tstl --watch"
},
"engines": {
"node": ">=10.13.0"
},
"devDependencies": {},
"dependencies": {
"lua-types": "^2.11.0",
"@types/node": "^12.0.8",
"typescript-to-lua": "1.1.1",
"typed-factorio": "0.12.0",
"typescript": "4.4.4"
},
"//": {
"typed-factorio": "0.10.0"
},
"peerDependencies": {},
"optionalDependencies": {},
"bundledDependencies": []
}

View file

@ -0,0 +1,79 @@
export namespace Serdes {
export namespace Player {
export function playerToTable(player: LuaPlayer): PlayerData {
let charIds = Entity.entitiesToUnitNumbers(player.get_associated_characters())
return {
object_name: player.object_name,
name: player.name,
character_unit_number: player.character?.unit_number ?? null,
associated_characters_unit_numbers: charIds,
position: DataClasses.positionTableToTable(player.position),
}
}
}
export namespace Entity {
export function entityToTable(entity: LuaEntity): EntityData {
let player: LuaPlayer | null = entity.is_player() ? entity.player!! : null
return {
object_name: entity.object_name,
// entity data
name: entity.name,
type: entity.type,
active: entity.active,
health: entity.health ?? null,
health_ratio: entity.get_health_ratio(),
surface_index: entity.surface.index,
unit_number: entity.unit_number ?? null,
position: DataClasses.positionTableToTable(entity.position),
// player data
player_index: player?.index ?? null
}
}
export function entitiesToUnitNumbers(entities: LuaEntity[]): uint[] {
let result: (uint) [] = []
for (let entity of entities) {
if (entity.unit_number != null) {
result[result.length] = entity.unit_number
}
}
return result
}
}
export namespace Surface {
export function surfaceToTable(surface: LuaSurface): SurfaceData {
return {
object_name: surface.object_name,
name: surface.name,
index: surface.index,
daytime: surface.daytime,
}
}
}
export namespace DataClasses {
export function positionTableToTable(positionTable: PositionTable): PositionData {
return {
x: positionTable.x,
y: positionTable.y,
}
}
}
}

View file

@ -0,0 +1,35 @@
{
"$schema": "https://raw.githubusercontent.com/TypeScriptToLua/vscode-typescript-to-lua/master/tsconfig-schema.json",
"compilerOptions": {
"target": "es2019",
"lib": [
"es2019"
],
"module": "commonjs",
"moduleResolution": "node",
"types": [
"typescript-to-lua/language-extensions",
"lua-types/5.2",
"typed-factorio/runtime"
],
"explainFiles": true,
"forceConsistentCasingInFileNames": true,
"listEmittedFiles": true,
"listFiles": true,
"noImplicitAny": true,
"noImplicitThis": true,
"sourceMap": false,
"strict": true,
"strictFunctionTypes": true,
"strictNullChecks": true,
"traceResolution": true,
"esModuleInterop": true
},
"tstl": {
"luaTarget": "5.2",
"tstlVerbose": true,
"noHeader": true,
"noImplicitSelf": true,
"luaLibImport": "inline"
}
}