diff --git a/docs/scarpet/Full.md b/docs/scarpet/Full.md index 69b7f366..9bd20fcd 100644 --- a/docs/scarpet/Full.md +++ b/docs/scarpet/Full.md @@ -1919,11 +1919,12 @@ These options affect directly how scarpet functions and can be triggered via `/c when loaded with the world (i.e. present in the world/scripts folder) - `scriptsAutoload`: when set to `false` will prevent apps loaded with the world to load automatically. You can still load them on demand via `/script load` command - - `commandScriptACE`: command permission level that is used to trigger commands from scarpet scripts (regardless who triggeres + - `commandScriptACE`: command permission level that is used to trigger commands from scarpet scripts (regardless who triggers the code that calls the command). Defaults to `ops`, could be customized to any level via a numerical value (0, 1, 2, 3 or 4) - `scriptsOptimization`: when disabled, disables default app compile time optimizations. If your app behaves differently with - and without optimizations, please file a bug report on the bug tracker and disable code optimizations + and without optimizations, please file a bug report on the bug tracker and disable code optimizations. - `scriptsDebugging`: Puts detailed information about apps loading, performance and runtime in system log. + - `scriptsAppStore`: location of the app store for downloadable scarpet apps - can be configured to point to other scarpet app store. ## App structure @@ -2013,6 +2014,36 @@ predicate that is volatile and might change, the command might falsely do or do however player will always be able to type it in and either succeed, or fail, based on their current permissions. Custom permission applies to legacy commands with `'legacy_command_type_support'` as well as for the custom commands defined with `'commands'`, see below. +* `'resources'` - list of all downloadable resources when installing the app from an app store. List of resources needs to be +in a list and contain of map-like resources descriptors, looking like + ``` + 'resources' -> [ + { + 'source' -> 'https://raw.githubusercontent.com/gnembon/fabric-carpet/master/src/main/resources/assets/carpet/icon.png', + 'type' -> 'url', + 'target' -> 'foo/photos.zip/foo/cm.png', + }, + { + 'source' -> 'survival/README.md', + 'type' -> 'store', + 'target' -> 'survival_readme.md', + 'shared' -> true, + }, + { + 'source' -> 'carpets.sc', + 'type' -> 'app', + 'target' -> 'apps/flying_carpets.sc', + 'shared' -> true, + }, + ] + ``` + `source` and `type` indicate resource location: either an arbitrary url (type `'url'`), + absolute location of a file in the app store (type `'store'`), +or a relative location in the same folder as the app in question (type `'app'`). +`'target'` points to the path in app data, or shared app data folder +if `'shared'` is specified and `true`. When re-downloading the app, all resources will be re-downloaded as well. +Currently, app resources +are only downloaded when using `/carpet download` command. * `'arguments'` - defines custom argument types for legacy commands with `'legacy_command_type_support'` as well as for the custom commands defined with `'commands'`, see below. * `'commands'` - defines custom commands for the app to be executed with `/` command, see below. @@ -5629,3 +5660,18 @@ This would slow down the computation of fib(40) from a minute to two, but allows and be responsive to commands, using about half of each tick to advance the computation. Obviously depending on the problem, and available hardware, certain things can take more or less time to execute, so portioning of work with calling `gametick` should be balanced in each case separately + +# `/script download` command + +`/script download ` command allows downloading and running apps directly from an online app store (it's all free), +by default the [scarpet app store](https://www.github.com/gnembon/scarpet). +Downloaded apps will be placed in the world's scripts folder automatically. Location of the app store is controlled +with a global carpet setting of `/carpet scriptsAppStore`. Apps, if required, will also download all the resources they need +to run it. Consecutive downloads of the same app will re-download its content and its resources, but will not remove anything +that has been removed or renamed. + +# `/script remove` command + +command allow to stop and remove apps installed in the worlds scripts folder. The app is unloaded and app 'sc' file is moved +to the `/scripts/trash`. Removed apps can only be restored by manually moving it back from the trash folder, +or by redownloading from the appstore. diff --git a/src/main/java/carpet/CarpetServer.java b/src/main/java/carpet/CarpetServer.java index a2887fa8..00b7ca93 100644 --- a/src/main/java/carpet/CarpetServer.java +++ b/src/main/java/carpet/CarpetServer.java @@ -114,7 +114,7 @@ public class CarpetServer implements ClientModInitializer,DedicatedServerModInit { TickSpeed.tick(); HUDController.update_hud(server, null); - scriptServer.tick(); + if (scriptServer != null) scriptServer.tick(); //in case something happens CarpetSettings.impendingFillSkipUpdates.set(false); @@ -168,6 +168,12 @@ public class CarpetServer implements ClientModInitializer,DedicatedServerModInit extensions.forEach(e -> e.onPlayerLoggedOut(player)); } + public static void clientPreClosing() + { + if (scriptServer != null) scriptServer.onClose(); + scriptServer = null; + } + public static void onServerClosed(MinecraftServer server) { // this for whatever reason gets called multiple times even when joining on SP @@ -175,6 +181,7 @@ public class CarpetServer implements ClientModInitializer,DedicatedServerModInit if (minecraft_server != null) { if (scriptServer != null) scriptServer.onClose(); + scriptServer = null; ServerNetworkHandler.close(); currentCommandDispatcher = null; diff --git a/src/main/java/carpet/network/CarpetClient.java b/src/main/java/carpet/network/CarpetClient.java index 36a885c3..ac59bc26 100644 --- a/src/main/java/carpet/network/CarpetClient.java +++ b/src/main/java/carpet/network/CarpetClient.java @@ -37,13 +37,17 @@ public class CarpetClient public static void disconnect() { - if (isServerCarpet) + if (isServerCarpet) // multiplayer connection { isServerCarpet = false; clientPlayer = null; CarpetServer.onServerClosed(null); CarpetServer.onServerDoneClosing(null); } + else // singleplayer disconnect + { + CarpetServer.clientPreClosing(); + } } public static void setCarpet()