Commit Graph
69 Commits
Author SHA1 Message Date
Hornwitser a0807b22a4 Fix inventory wipe on SE remote view (#530)
Exit the Space Exploration remote view if its active to prevent the
empty remote view "character" being serialized as the inventory instead
of the real character for the player.

Original-patch-by: @Reavershark
Fixes: #513
2023-11-30 01:32:13 +01:00
Hornwitser f1edbd78cb Move dist/web_build inside dest/web
By default webpack-dev-middleware will refuse to delete files outside of
its working directory. This becomes dist/web in the configuration
currently set up, which means that a rebuild triggered on the watched
files will fail when declaration files are output to to dist/web_build.

Fix by moving dist/web_build to dist/web/build.
2023-11-29 18:02:27 +01:00
Hornwitser 0a4368d1c0 Rename index.css to style.css
Make the tab completion on web/in<Tab> give the TypeScript code instead
of annoyingly stopping at the extension.
2023-11-28 15:52:54 +01:00
Hornwitser 6a404d9fb3 Refactor and port plugin web code to TypeScript
Clean up the configuration for compiling TypeScript for the Web
interface to us its own tsconfig.web.json config files and reference the
TypeScript source files directly in the configuration and imports
instead of files compiled to dist.

To properly support recompliation with TypeScript's projects feature
each package's tsconfig.web.json file is set to output the build to
dist/web_build which is then ignored in .npmignore.  Webpack is still
used to create the proper build in dist/web, so this is mainly to make
TypeScipt's compiler happy but it also allows the root tsconfig.json
file to include the web interface code, meaning running the build script
now also checks the typing of the web interface.

Final part of #491.
2023-11-28 15:52:54 +01:00
Hornwitser 70d2b319b3 Fix types related to plugins and the web interface 2023-11-28 15:35:40 +01:00
Hornwitser 808eda0513 Move base plugins to their respective packages
Move BaseControllerPlugin to controller/src/BaseControllerPlugin.ts
Move BaseInstancePlugin to host/src/BaseInstancePlugin.ts
Move BaseControlPlugin to ctl/src/BaseCtlPlugin.ts
Move BaseWebPlugin to web_ui/src/BaseWebPlugin.ts

This solves the circular package dependency problem of the base plugins
needing types that are available only in the dependencies to lib.
2023-11-25 18:41:43 +01:00
Hornwitser 87e52b804e Convert JSON file indents to tabs
Be consistent with the usage of tabs as indents in all JSON files in the
project.  This makes it easier to configure editors to emit the right
indents when manually editing these files.
2023-11-25 18:19:15 +01:00
Hornwitser 7314dc99c8 Fix code style errors
Remove extra whitespace, use more consistent spacing, add missing
semicolons, using dangling commas, break up long lines, consistent
multiline operator placement, add missing JSDoc strings and so on.
2023-11-19 04:48:38 +01:00
Luciole 838170a9ff Port packages/web_ui to TypeScript (#508)
* .jsx to .tsx

* controller: tsc --build before webpack-cli

* Type Annotation

* disabled move into the <Input/> and <Checkbox/>

* cleanup debug left over

* documentation

* default ModPack

* modPackUpdateHandlers no undefined

* PluginInfo changes proposition

* PluginInfo changes proposition miss

* ModRecord & ModInfo feedback loop at const mods = [ ?

* ["connect", "drop", "resume", "close"] as const

* .tsx to .ts when possible
2023-09-02 14:51:35 +02:00
Hornwitser 425daac6b6 Set up references in TSConfig
Link the projects together properly so that builds don't use out of date
files and editor "go to definition" function give the right file.
2023-08-26 17:11:47 +02:00
Hornwitser c3d78a8cb8 Organise TSConfig files using inheritance
Removed duplicated TSConfig options by using a shared base config which
all plugins inherit shared settings from.
2023-08-26 17:11:46 +02:00
Hornwitser 36ced0d3ba Merge pull request #503 from Luciole0x/inventory_sync-fix
fix inventory_sync plugin
2023-08-26 14:52:25 +02:00
Luciole 318a4301c0 Define responses types, DownloadResponse.player_data > playerData 2023-08-26 00:16:31 +02:00
Hornwitser b1a6628bfa Remove left over load entries from 7b8127f
Remove save_crafts.lua and restore_crafts.lua entries in the module.json
for inventory_sync which was left over from the removal in 7b8127f.
2023-08-25 15:26:44 +02:00
Luciole 0b3550b472 Port remaining plugins to Typescript (#499)
* .js to .ts

* Allow access to _items entries; getItemCount return number

* add permission field to PluginPage interface

* port plugins to typescript

* update Request classes

* fix IpcFlowType
2023-08-22 16:17:16 +02:00
Luciole 50f12c719b Port global_chat plugin to typescript (#497)
* .js to .ts

* translate

* update paths to dist/plugin

* add "tsc --build" to prepare

* use field main in package.json de find info

* tsc --build need to append before webpack

* update test and use for plugins package.main
2023-08-18 00:06:49 +02:00
Hornwitser bfe119eaa3 Flatten lib namespace
Move all functions and classes currently available through lib/name and
libName to be under a single flat namespace in lib.  This make
reorganising the lib namespace much simpler as the location of symbols
can move without breaking the consumers of lib.

The multi-entrypoint design was already problematic for the web plugin
system which couldn't effectively use it due to how webpack's shared
module system is awkward to set up with multiple entrypoints per package.
2023-07-28 16:03:29 +02:00
Hornwitser fd709fd98c Update web dependencies
- react: Update to new root rendering method
- react-router: Replace useHistory with useNavigate
- react-router: Replace <Switch> with <Routes>
- reimplement sticky notice from scratch in ModPackViewPage
- remove isomorphic-ws as it's latest version doesn't work and only
  saves one line of code.
- remove import of antd.dark.css
- fix misc css breakages.
2023-07-27 17:50:14 +02:00
Hornwitser 2de029b96e Fix strict mode warnings from Ajv
Add type object to schemas specifying properties and minItems to schemas
specifying tuples. Disable strictTuples because it's desirable to be
able to add additional items to the tuples in the future.
2023-07-27 00:35:26 +02:00
Hornwitser 1a9cbd26b3 Update non-web dependencies
Update non-web related dependencies to their latest version were
possible. It appears yargs has changed its parsing of command line
options to no longer remove a layer of quotes.
2023-07-27 00:35:26 +02:00
Hornwitser a96a8a6d25 Bump minimum supported Node.js version to v18
The LTS releases for v12 and v14 are already end of life and the v16 is
end of life in under two months from now on.  Bump supported version up
to v18 as it does not make sense to continue to support EOL releases.
Even if we wanted to keep supporting them, our dependencies will not.

Note that Node.js v18 is currently not avaliable via the NodeSource PPA
on Ubuntu 19.10 and below or Debian 9 and below.
2023-07-27 00:35:26 +02:00
Hornwitser 295cc7543a Reverse argument order for sendTo
It makes more sense to put the address first then have the large
structure to send as the second argument to sendTo.  The opposite order
was originally chosen to be similar to that of sendto in BSD sockets.
2023-07-27 00:24:24 +02:00
Hornwitser 7f8a700716 Refactor message registration and validation
Split up the action of registring an event or request data class to be
decoded by the Link class and the action of registring a handler for
those requests and events.  This moves the validation work from Link
instantiation time to startup initialisation which makes logic errors
fail on startup instead of failing instantiation of the link when a
connection attempt is made.

Additionally implement a partial validation logic for messages received
using the newly refactored message registration.  This unfortunately
ended up merged with the registration refactor.
2023-06-03 16:47:47 +02:00
Hornwitser bcd94709d2 Refactor link system to JSON serialisable class pattern
Reverse the direction of the API for sending messages from

    messageDefinition.send(link, { content });

to

    link.send(new MessageClass(content));

and convert all message definitions to use the JSON serialisable class
pattern and explicit registration of message handlers, along with a
end-to-end based routing of messages instead of link to link.

The experience I gained from the existing way messages were defined and
sent over links was that it was difficult to understand for people
unfamiliar with the system.  The automatic registration of message
handlers ment that code was being called as if by magic from nowhere
with no easy way to discover it.  The manual forwarding and rules for
what can be sent where and how obscured its working.

The use of pure JSON as both input and output from message handlers made
it tedious to work with.  Data had to be manually converted between the
program representation and the over the wire format, which made handler
code unplesant to write.  Particularly because the over the wire format
used snake_case while the program code uses camelCase for variables.
The idea behind the decision to do it this way was to make it more clear
which data came from the wire and which from the program, and while this
worked it didn't make message handlers any nicer to write.

The direction of the API and magic registration of message handlers also
meant that a future migration to TypeScript would be troublesome.  While
it may be possible to implement, the degree of TypeScript magic required
would go starkly against the principle of keep it simple stupid.

By refactoring to using the JSON serialisable class pattern most of
these issues go away.  There is no longer a need to distinguish the on
wire format of messages with the program representation because the only
place that deals with the wire format of messages are the toJSON and
fromJSON methods on the classes themselves.  Message handlers will work
with proper instances of classes instead of raw data, something that
makes them easier to write, and trivial to type with TypeScript.

End-to-end routing also simplifies sending messages that need to do
mulitple hops to reach the destination.  And removes the need for having
all messages be specified in plugin's info module, as they can be routed
without having to be parsed completely.

The explicit registration of message handlers is something that I
thought would be tedious boilerplate code that could be automated away.
But experience now shows it to be the opposite.  Allthough dull
repetition, the purpose it serves is to link together the code in a way
that humans can easily find.  With explicit registration searching the
name of the message handler in the editor will show the registration that
ties it together with the type of message it handles and the kind of
registration.  With implicit registration searching the name of the
message handler turns up only the handler with no clue as to what calls
it.
2023-04-23 13:19:46 +02:00
Hornwitser 05e9230e9e Add .id shorthand to InstanceInfo
Turn instance.config.get("instance.id") into instance.id.
2023-02-24 02:00:12 +01:00
Hornwitser 6fc3abafd5 Rename Slave to Host
The role of a slave as a host for Factorio servers is not well reflected
in its name and has caused confusion among users.  Rename slave to host
to better reflect its role as a host of Factorio servers.
2023-02-22 15:30:51 +01:00
Hornwitser 70ad295a89 Rename Master to Controller
The role of the master server as the party controlling every part of the
cluster is not well reflected in its name and has caused confusion among
users on several occasions.  Rename master to controller to better
reflects its role.
2023-02-22 15:30:51 +01:00
Hornwitser bcb2365c9a 2.0.0-alpha.13 2022-07-20 13:30:35 +02:00
Hornwitser 7b8127fef8 Refactor inventory_sync serialisation (#470)
Fix broken support for retrying uploads and background downloads by
making crafting queue serialisation non-destructive and only performing
the serialisation and deserialisation while the player is online.

This removes the /save-crafts and /restore-crafts commands because the
existing implementation would voids the non-saved crafting queue items
if /save-crafts is performed and then new items are added to the
crafting queue before switching server.

Fixes #419.
2022-07-19 21:24:12 +02:00
Hornwitser 105f99ced3 Preserve entered vehicle on inventory sync
Save vehicle the player is driving before downloading the inventory and
restore the player position to this vehicle if possible.
2022-06-19 19:51:22 +02:00
Hornwitser 430a64722e Use empty slots as end for logistics requests
Count up to 100 empty slots past the last seen slot with data in it
before stopping to look for personal logistics slots in inventory_sync.
Allows unlimeted amount of logistics request slots to be used for
heavily modded games.
2022-06-19 17:03:08 +02:00
Hornwitser e32637503d Move all web assets to shared cached space
Put all web assets including plugin assets under a shared static/ route
in the web interface that's declared as immutable and cacheable for 1
year.  This allows all JavaScript bundles to be loaded from disk instead
of having to check with the web server each time and significantly
speeds up the web interface load time.  It also fixes the public path
issue when using the --dev-plugin option behind a proxy.

To prevent collisions and stale data all assets now include a hash in
the filename.  This means the entrypoint is now dynamic and specified in
a manifest.json file created from the web build.  For plugins this means
the filename attribute needs to be removed from webpack.config.js.
2022-06-08 21:01:36 +02:00
Hornwitser 4d5597a1da Use prepare instead of build as script
The prepare script runs before publishing a package, after installation
of a package from source, and when running npm install without
arguments in the repository.  These are the times where a build of the
web interface files are required to make the web interface work and
removes a manual step from using the package(s). The "build" script on
the other hand is never automatically invoked by npm.
2022-06-05 16:13:53 +02:00
Hornwitser 1e4292876c v2.0.0-alpha.12 2022-04-22 12:36:00 +02:00
Hornwitser 61cd5bd76c Fix issues detected by lgtm.com 2022-01-03 19:45:46 +01:00
Hornwitser 1ff1e3e5f8 v2.0.0-alpha.11 2021-12-19 15:57:08 +01:00
Hornwitser e23d07e965 Use safe file writing pattern (#421)
Write new file contents to a temporary file and then rename over the
target file to avoid data loss in the unlikely event there's an error
writing the new file contents or the process is interrupted.

Resolves #416.
2021-11-03 16:14:18 +01:00
Hornwitser ef3d5209eb v2.0.0-alpha.10 2021-10-01 17:59:16 +02:00
Hornwitser bad86a5ff2 Fix inventory_sync uploading editor mode
The serialization and deserialization of editor mode is not supported by
the current code, and while the download correctly checked for the
player being in editor mode, the upload did not check for the player
being in editor mode causing players in editor mode to break. Fix by
adding check in upload_inventory.
2021-10-01 01:52:18 +02:00
Hornwitser 0c74aef68e Hide unauthorized web interface controls
Hide or disable controls in the web interface that the user for the
control connection it's connected as don't have the requisite
permissions to use.
2021-09-20 00:54:43 +02:00
Hornwitser 1035389c9e Hotfix new player sync logic
Fix has_data not being checked by sync_player, dialog being stuck open if
no data is received by the master and master server refusing to server
empty data.
2021-09-12 00:27:46 +02:00
Hornwitser 8c62213a52 v2.0.0-alpha.9 2021-09-11 23:37:28 +02:00
Hornwitser 90dacd98b2 Rework inventory_sync (#411)
Complete rework of the inventory synchronization to reduce the number of
times the inventory has to be downloaded and the possibilities for item
loss/duplication.

The basic concept is to acquire exclusive access to the player data
before downloading the data.  This prevents the player from logging in
to two servers at the same time and getting the synced inventory twice.
The acquisition will in most cases execute faster than the player can
provide input to the game on login, and if the player data on the master
isn't what was previously uploaded then the player inventory is deleted
and the player is turned into a spectator while the updated inventory is
being transferred into the game.  This model allows for the downloading
of the synced inventory to be skipped in the case the player joins the
same server they left from.

The synced data is expanded to include more than just the character and
inventory to properly handle sync of dead players.  If the player leaves
dead on one server this state will be saved and when the player joins
another server they continue off as dead.  The ghost, god, and spectator
controllers are supported, while the cutscene and editor controllers are
not.  For players in a cutscene when joining the acquisition will be
attempted immediately, but the scenario waits until the player is out of
the cutscene before acting upon the response to the acquisition.  For
players in the editor mode the scenario toggles them out of the mode
before syncing data.

Since uploads to the master can fail handling of this is also added.
The scenario will retry uploading the player data at exponentially
increasing intervals until it gets the message back that the upload
succeeded.  Since it's possible for servers to go down and stay down for
a long time the exclusive access held by these servers are released after
a timeout.  This means that a player could be playing and or have
uploaded newer data by the time the instance comes back online and tries
to upload the inventory, in this case the master will report the upload
succeeded but discard the data.  Instances may also upload old data if
they load back to an earlier save, which will also be discarded by the
master.

Other small improvements made by this rework:
- Add a retry button to the failed download dialog
- Update the existing progress dialog instead of destroying and
  recreating it every time.
- Automatically stuff the items from the temporary inventory into the
  synced inventory if they fit.
- Move player back to the position they started the download from if
  they were turned into a spectator for the download.
- Ensure the player has a character if the stored data is wiped.
- Add error checking of the RCON commands sent by the instance.
2021-09-07 15:49:53 +02:00
Hornwitser f4635a79f9 Remove ajv from plugin webpack config
The ajv module was made shared to reduce package size, but it turned out
the package size was large because of a missunderstanding in how imports
to sub-paths works with module federation.  Since that was fixed the ajv
module was no longer shared, but plugins incorrectly still specified it.
2021-08-17 01:42:45 +02:00
Hornwitser 8a0c1e8a4b Use single entrypoint for lib in web interface
In order to import a path inside packages/lib/ in the webpack shared
module environment it has to be declared as shared in both the web_ui
webpack config and the plugin's webpack config.  This is rather error
prone and easy to miss.  Move the burden of specifying which entrypoints
are valid in lib to lib itself by changing all imports in the web
interface code to import from @clusterio/lib instead sub paths.

For web code this means imports is done like this from now on:

import { libConfig, libLink } from "@clusterio/lib";

For info.js which has to be loadable by both Node.js and web code the
imports are done as follows:

const { libConfig, libLink } = require("@clusterio/lib");

While the Node.js only code can either continue to import sub paths
directly or use the info.js style.
2021-08-17 01:42:45 +02:00
Hornwitser cbfc0adf3d Remove extra whitespace in inventory_sync plugin 2021-08-13 06:22:45 +02:00
Hornwitser 4a29c13acb Fix bad reference in inventory_sync stat request 2021-08-13 06:21:32 +02:00
Hornwitser 60e434e4ac Fix inventory_sync player created/removed
Create entries for players that are present in the save on server
startup to preserving their inventory and fix attempting to reference the
player object after it had been removed in on_player_removed.
2021-08-13 06:17:59 +02:00
Hornwitser d126e7f25a Validate GUI element in on_gui_click
Make sure the GUI element in the on_gui_click event is valid before
attempting to access this, as another module may have destroyed it
during its event handler.
2021-08-10 18:19:18 +02:00
Hornwitser ecbce16c99 Be more defensive with global table initialization
When upgrading or downgrading the inventory_sync plugin it's possible
an different structure of the global.inventory_sync table is left behind
which could cause the code to crash when certain sub tables are not
present.

Be more defensive in the initialization of the table to make sure all
sub-tables are present on startup.
2021-08-10 17:41:40 +02:00