1
0
mirror of https://github.com/tobspr/shapez.io.git synced 2026-03-02 03:39:21 +00:00

Mod Support - 1.5.0 Update (#1361)

* initial modloader draft

* modloader features

* Refactor mods to use signals

* Add support for modifying and registering new transltions

* Minor adjustments

* Support for string building ids for mods

* Initial support for adding new buildings

* Refactor how mods are loaded to resolve circular dependencies and prepare for future mod loading

* Lazy Load mods to make sure all dependencies are loaded

* Expose all exported members automatically to mods

* Fix duplicate exports

* Allow loading mods from standalone

* update changelog

* Fix mods folder incorrect path

* Fix modloading in standalone

* Fix sprites not getting replaced, update demo mod

* Load dev mod via raw loader

* Improve mod developing so mods are directly ready to be deployed, load mods from local file server

* Proper mods ui

* Allow mods to register game systems and draw stuff

* Change mods path

* Fix sprites not loading

* Minor adjustments, closes #1333

* Add support for loading atlases via mods

* Add support for loading mods from external sources in DEV

* Add confirmation when loading mods

* Fix circular dependency

* Minor Keybindings refactor, add support for keybindings to mods, add support for dialogs to mods

* Add some mod signals

* refactor game loading states

* Make shapez exports global

* Start to make mods safer

* Refactor file system electron event handling

* Properly isolate electron renderer process

* Update to latest electron

* Show errors when loading mods

* Update confirm dialgo

* Minor restructure, start to add mod examples

* Allow adding custom themesw

* Add more examples and allow defining custom item processor operations

* Add interface to register new buildings

* Fixed typescript type errors (#1335)

* Refactor building registry, make it easier for mods to add new buildings

* Allow overriding existing methods

* Add more examples and more features

* More mod examples

* Make mod loading simpler

* Add example how to add custom drawings

* Remove unused code

* Minor modloader adjustments

* Support for rotation variants in mods (was broken previously)

* Allow mods to replace builtin sub shapes

* Add helper methods to extend classes

* Fix menu bar on mac os

* Remember window state

* Add support for paste signals

* Add example how to add custom components and systems

* Support for mod settings

* Add example for adding a new item type

* Update class extensions

* Minor adjustments

* Fix typo

* Add notification blocks mod example

* Add small tutorial

* Update readme

* Add better instructions

* Update JSDoc for Replacing Methods (#1336)

* upgraded types for overriding methods

* updated comments

Co-authored-by: Edward Badel <you@example.com>

* Direction lock now indicates when there is a building inbetween

* Fix mod examples

* Fix linter error

* Game state register (#1341)

* Added a gamestate register helper

Added a gamestate register helper

* Update mod_interface.js

* export build options

* Fix runBeforeMethod and runAfterMethod

* Minor game system code cleanup

* Belt path drawing optimization

* Fix belt path optimization

* Belt drawing improvements, again

* Do not render belts in statics disabled view

* Allow external URL to load more than one mod (#1337)

* Allow external URL to load more than one mod

Instead of loading the text returned from the remote server, load a JSON object with a `mods` field, containing strings of all the mods. This lets us work on more than one mod at a time or without separate repos. This will break tooling such as `create-shapezio-mod` though.

* Update modloader.js

* Prettier fixes

* Added link to create-shapezio-mod npm page (#1339)

Added link to create-shapezio-mod npm page: https://www.npmjs.com/package/create-shapezio-mod

* allow command line switch to load more than one mod (#1342)

* Fixed class handle type (#1345)

* Fixed class handle type

* Fixed import game state

* Minor adjustments

* Refactor item acceptor to allow only single direction slots

* Allow specifying minimumGameVersion

* Add sandbox example

* Replaced concatenated strings with template literals (#1347)

* Mod improvements

* Make wired pins component optional on the storage

* Fix mod examples

* Bind `this` for method overriding JSDoc (#1352)

* fix entity debugger reaching HTML elements (#1353)

* Store mods in savegame and show warning when it differs

* Closes #1357

* Fix All Shapez Exports Being Const (#1358)

* Allowed setting of variables inside webpack modules

* remove console log

* Fix stringification of things inside of eval

Co-authored-by: Edward Badel <you@example.com>

* Fix building placer intersection warning

* Add example for storing data in the savegame

* Fix double painter bug (#1349)

* Add example on how to extend builtin buildings

* update readme

* Disable steam achievements when playing with mods

* Update translations

Co-authored-by: Thomas (DJ1TJOO) <44841260+DJ1TJOO@users.noreply.github.com>
Co-authored-by: Bagel03 <70449196+Bagel03@users.noreply.github.com>
Co-authored-by: Edward Badel <you@example.com>
Co-authored-by: Emerald Block <69981203+EmeraldBlock@users.noreply.github.com>
Co-authored-by: saile515 <63782477+saile515@users.noreply.github.com>
Co-authored-by: Sense101 <67970865+Sense101@users.noreply.github.com>
This commit is contained in:
tobspr
2022-02-01 16:35:49 +01:00
committed by GitHub
parent a7a2aad2b6
commit c41aaa1fc5
170 changed files with 5935 additions and 1551 deletions

View File

@@ -14,6 +14,8 @@ import { SavegameInterface_V1006 } from "./schemas/1006";
import { SavegameInterface_V1007 } from "./schemas/1007";
import { SavegameInterface_V1008 } from "./schemas/1008";
import { SavegameInterface_V1009 } from "./schemas/1009";
import { MODS } from "../mods/modloader";
import { SavegameInterface_V1010 } from "./schemas/1010";
const logger = createLogger("savegame");
@@ -54,7 +56,7 @@ export class Savegame extends ReadWriteProxy {
* @returns {number}
*/
static getCurrentVersion() {
return 1009;
return 1010;
}
/**
@@ -103,6 +105,7 @@ export class Savegame extends ReadWriteProxy {
usedInverseRotater: false,
},
lastUpdate: Date.now(),
mods: MODS.getModsListForSavegame(),
};
}
@@ -160,6 +163,11 @@ export class Savegame extends ReadWriteProxy {
data.version = 1009;
}
if (data.version === 1009) {
SavegameInterface_V1010.migrate1009to1010(data);
data.version = 1010;
}
return ExplainedResult.good();
}
@@ -269,6 +277,7 @@ export class Savegame extends ReadWriteProxy {
shadowData.dump = dump;
shadowData.lastUpdate = new Date().getTime();
shadowData.version = this.getCurrentVersion();
shadowData.mods = MODS.getModsListForSavegame();
const reader = this.getDumpReaderForExternalData(shadowData);

View File

@@ -10,6 +10,7 @@ import { SavegameInterface_V1006 } from "./schemas/1006";
import { SavegameInterface_V1007 } from "./schemas/1007";
import { SavegameInterface_V1008 } from "./schemas/1008";
import { SavegameInterface_V1009 } from "./schemas/1009";
import { SavegameInterface_V1010 } from "./schemas/1010";
/** @type {Object.<number, typeof BaseSavegameInterface>} */
export const savegameInterfaces = {
@@ -23,6 +24,7 @@ export const savegameInterfaces = {
1007: SavegameInterface_V1007,
1008: SavegameInterface_V1008,
1009: SavegameInterface_V1009,
1010: SavegameInterface_V1010,
};
const logger = createLogger("savegame_interface_registry");

View File

@@ -1,9 +1,8 @@
import { ExplainedResult } from "../core/explained_result";
import { createLogger } from "../core/logging";
import { gComponentRegistry } from "../core/global_registries";
import { createLogger } from "../core/logging";
import { MOD_SIGNALS } from "../mods/mod_signals";
import { SerializerInternal } from "./serializer_internal";
import { HUDPinnedShapes } from "../game/hud/parts/pinned_shapes";
import { HUDWaypoints } from "../game/hud/parts/waypoints";
/**
* @typedef {import("../game/component").Component} Component
@@ -42,8 +41,12 @@ export class SavegameSerializer {
beltPaths: root.systemMgr.systems.belt.serializePaths(),
pinnedShapes: root.hud.parts.pinnedShapes ? root.hud.parts.pinnedShapes.serialize() : null,
waypoints: root.hud.parts.waypoints ? root.hud.parts.waypoints.serialize() : null,
modExtraData: {},
};
MOD_SIGNALS.gameSerialized.dispatch(root, data);
if (G_IS_DEV) {
if (sanityChecks) {
// Sanity check
@@ -151,6 +154,9 @@ export class SavegameSerializer {
return ExplainedResult.bad(errorReason);
}
// Mods
MOD_SIGNALS.gameDeserialized.dispatch(root, savegame);
return ExplainedResult.good();
}
}

View File

@@ -2,6 +2,14 @@
* @typedef {import("../game/entity").Entity} Entity
*
* @typedef {{
* id: string;
* version: string;
* website: string;
* name: string;
* author: string;
* }[]} SavegameStoredMods
*
* @typedef {{
* failedMam: boolean,
* trashedCount: number,
* usedInverseRotater: boolean
@@ -17,7 +25,8 @@
* pinnedShapes: any,
* waypoints: any,
* entities: Array<Entity>,
* beltPaths: Array<any>
* beltPaths: Array<any>,
* modExtraData: Object
* }} SerializedGame
*
* @typedef {{
@@ -25,6 +34,7 @@
* dump: SerializedGame,
* stats: SavegameStats,
* lastUpdate: number,
* mods: SavegameStoredMods
* }} SavegameData
*
* @typedef {{

View File

@@ -0,0 +1,28 @@
import { createLogger } from "../../core/logging.js";
import { SavegameInterface_V1009 } from "./1009.js";
const schema = require("./1010.json");
const logger = createLogger("savegame_interface/1010");
export class SavegameInterface_V1010 extends SavegameInterface_V1009 {
getVersion() {
return 1010;
}
getSchemaUncached() {
return schema;
}
/**
* @param {import("../savegame_typedefs.js").SavegameData} data
*/
static migrate1009to1010(data) {
logger.log("Migrating 1009 to 1010");
data.mods = [];
if (data.dump) {
data.dump.modExtraData = {};
}
}
}

View File

@@ -0,0 +1,5 @@
{
"type": "object",
"required": [],
"additionalProperties": true
}

View File

@@ -22,6 +22,7 @@ import {
TypeString,
TypeStructuredObject,
TypeVector,
TypePositiveIntegerOrString,
} from "./serialization_data_types";
const logger = createLogger("serialization");
@@ -38,6 +39,7 @@ export const types = {
vector: new TypeVector(),
tileVector: new TypeVector(),
bool: new TypeBoolean(),
uintOrString: new TypePositiveIntegerOrString(),
/**
* @param {BaseDataType} wrapped
@@ -136,7 +138,7 @@ export const types = {
/**
* A full schema declaration
* @typedef {Object.<string, BaseDataType>} Schema
* @typedef {Object.<string, BaseDataType> | object} Schema
*/
const globalSchemaCache = {};

View File

@@ -213,6 +213,53 @@ export class TypePositiveInteger extends BaseDataType {
}
}
export class TypePositiveIntegerOrString extends BaseDataType {
serialize(value) {
if (Number.isInteger(value)) {
assert(value >= 0, "type integer got negative value: " + value);
} else if (typeof value === "string") {
// all good
} else {
assertAlways(false, "Type integer|string got non integer or string for serialize: " + value);
}
return value;
}
/**
* @see BaseDataType.deserialize
* @param {any} value
* @param {GameRoot} root
* @param {object} targetObject
* @param {string|number} targetKey
* @returns {string|void} String error code or null on success
*/
deserialize(value, targetObject, targetKey, root) {
targetObject[targetKey] = value;
}
getAsJsonSchemaUncached() {
return {
oneOf: [{ type: "integer", minimum: 0 }, { type: "string" }],
};
}
verifySerializedValue(value) {
if (Number.isInteger(value)) {
if (value < 0) {
return "Negative value for positive integer";
}
} else if (typeof value === "string") {
// all good
} else {
return "Not a valid number or string: " + value;
}
}
getCacheKey() {
return "uint_str";
}
}
export class TypeBoolean extends BaseDataType {
serialize(value) {
assert(value === true || value === false, "Type bool got non bool for serialize: " + value);