From 5dfd956ba2d0aa570f666b8e6f006c9c2de84a8e Mon Sep 17 00:00:00 2001 From: altrisi Date: Sun, 29 Nov 2020 21:45:53 +0100 Subject: [PATCH] Only allow globals in clients, fix potential issue and mention in docs --- docs/scarpet/api/Overview.md | 5 ++-- docs/scarpet/api/ScriptCommand.md | 12 ++++---- docs/scarpet/language/Overview.md | 7 +++-- .../carpet/script/CarpetScriptServer.java | 29 ++++++++++--------- 4 files changed, 30 insertions(+), 23 deletions(-) diff --git a/docs/scarpet/api/Overview.md b/docs/scarpet/api/Overview.md index 9e9fc5bd..1beac900 100644 --- a/docs/scarpet/api/Overview.md +++ b/docs/scarpet/api/Overview.md @@ -6,7 +6,8 @@ Here is the gist of the Minecraft related functions. Otherwise the CarpetScript ## App structure The main delivery method for scarpet programs into the game is in the form of apps in `*.sc` files located in the world `scripts` -folder. When loaded (via `/script load` command, etc.), the game will run the content of the app once, regardless of its scope +folder. In singleplayer, you can also save apps in `.minecraft/config/carpet/scripts` for them to be available in any world. +When loaded (via `/script load` command, etc.), the game will run the content of the app once, regardless of its scope (more about the app scopes below), without executing of any functions, unless called directly, and with the exception of the `__config()` function, if present, which will be executed once. Loading the app will also bind specific events to the event system (check Events section for details). @@ -40,7 +41,7 @@ running anything in the global scope for a `'player'` scoped app is not recommen stay loaded after startup. Otherwise, after reading the app the first time, and fetching the config, server will drop them down. This is to allow to store multiple apps on the server/world and selectively decide which one should be running at startup. WARNING: all apps will run once at startup anyways, so be aware that their actions that are called -statically, will be performed once anyways. +statically, will be performed once anyways. Only apps present in the world's `scripts` folder will be autoloaded. * `'legacy_command_type_support'` - if `true`, and the app defines the legacy command system via `__command()` function, all parameters of command functions will be interpreted and used using brigadier / vanilla style argument parser and their type will be inferred from their names, otherwise diff --git a/docs/scarpet/api/ScriptCommand.md b/docs/scarpet/api/ScriptCommand.md index b10b5dc6..f2f2aa6a 100644 --- a/docs/scarpet/api/ScriptCommand.md +++ b/docs/scarpet/api/ScriptCommand.md @@ -8,13 +8,15 @@ to simulate running commands in a different scope. # `/script load / unload (global?)`, `/script in ` commands -`load / unload` commands allow for very conventient way of writing your code, providing it to the game and -distribute with your worlds without the need of use of commandblocks. Just place your scarpet code in the -/scripts folder of your world files and make sure it ends with `.sc` extension. The good thing about editing that -code is that you can no only use normal editing without the need of marking of newlines, +`load / unload` commands allow for very convenient way of writing your code, providing it to the game and +distribute with your worlds without the need of use of commandblocks. Just place your Scarpet code in the +`/scripts` folder of your world files and make sure it ends with `.sc` extension. In singleplayer, you can +also save your scripts in `.minecraft/config/carpet/scripts` to make them available in any world. + +The good thing about editing that code is that you can not only use normal editing without the need of marking of newlines, but you can also use comments in your code. -a comment is anything that starts with a double slash, and continues to the end of the line: +A comment is anything that starts with a double slash, and continues to the end of the line:
 foo = 1;
diff --git a/docs/scarpet/language/Overview.md b/docs/scarpet/language/Overview.md
index 64c3d81d..0030ad73 100644
--- a/docs/scarpet/language/Overview.md
+++ b/docs/scarpet/language/Overview.md
@@ -151,9 +151,10 @@ have memory and act like objects so to speak. Check `outer(var)` for details.
 ## Code delivery, line indicators
 
 Note that this should only apply to pasting your code to execute with commandblock. Scarpet recommends placing 
-your code in apps (files with `.sc` extension that can be placed inside "/scripts" folder in the world files and 
-loaded as a scarpet app with command `/script load [app_name]`. Scarpet apps loaded from disk should only 
-contain code, no need to start with "/script run" prefix
+your code in apps (files with `.sc` extension that can be placed inside `/scripts` folder in the world files 
+or as a globally available app in singleplayer in the `.minecraft/config/carpet/scripts` folder and loaded 
+as a Scarpet app with the command `/script load [app_name]`. Scarpet apps loaded from disk should only 
+contain code, no need to start with `/script run` prefix.
 
 The following is the code that could be provided in a `foo.sc` app file located in world `/scripts` folder
 
diff --git a/src/main/java/carpet/script/CarpetScriptServer.java b/src/main/java/carpet/script/CarpetScriptServer.java
index 4bab3309..e450460b 100644
--- a/src/main/java/carpet/script/CarpetScriptServer.java
+++ b/src/main/java/carpet/script/CarpetScriptServer.java
@@ -17,6 +17,7 @@ import com.mojang.brigadier.builder.LiteralArgumentBuilder;
 import com.mojang.brigadier.exceptions.CommandSyntaxException;
 import com.mojang.brigadier.tree.CommandNode;
 
+import net.fabricmc.api.EnvType;
 import net.fabricmc.loader.api.FabricLoader;
 import net.minecraft.server.MinecraftServer;
 import net.minecraft.server.command.ServerCommandSource;
@@ -143,16 +144,18 @@ public class CarpetScriptServer
                 ).findFirst();
             if (scriptPath.isPresent())
                 return new FileModule(scriptPath.get());
-            
-            Path globalFolder = FabricLoader.getInstance().getConfigDir().resolve("carpet/scripts");
-            Files.createDirectories(globalFolder);
-            scriptPath = Files.walk(globalFolder)
-                .filter(script -> 
-                    script.getFileName().toString().equalsIgnoreCase(name+".sc") || 
-                    (allowLibraries && script.getFileName().toString().equalsIgnoreCase(name+".scl"))
-                ).findFirst();
-            if (scriptPath.isPresent())
-                return new FileModule(scriptPath.get());
+
+            if (FabricLoader.getInstance().getEnvironmentType() == EnvType.CLIENT)
+            {
+                Path globalFolder = FabricLoader.getInstance().getConfigDir().resolve("carpet/scripts");
+                Files.createDirectories(globalFolder);
+                scriptPath = Files.walk(globalFolder)
+                        .filter(script -> script.getFileName().toString().equalsIgnoreCase(name + ".sc") ||
+                                (allowLibraries && script.getFileName().toString().equalsIgnoreCase(name + ".scl")))
+                        .findFirst();
+                if (scriptPath.isPresent())
+                    return new FileModule(scriptPath.get());
+            }
         } catch (IOException e) {
             CarpetSettings.LOG.error("Exception while loading the app: ", e);
         }
@@ -193,15 +196,15 @@ public class CarpetScriptServer
             Files.createDirectories(worldScripts);
             Files.walk(worldScripts)
                 .filter(f -> f.toString().endsWith(".sc"))
-                .forEach(f -> moduleNames.add(f.getFileName().toString().replaceFirst("\\.sc","").toLowerCase(Locale.ROOT)));
+                .forEach(f -> moduleNames.add(f.getFileName().toString().replaceFirst("\\.sc$","").toLowerCase(Locale.ROOT)));
 
-            if (includeBuiltIns)
+            if (includeBuiltIns && (FabricLoader.getInstance().getEnvironmentType() == EnvType.CLIENT))
             {
                 Path globalScripts = FabricLoader.getInstance().getConfigDir().resolve("carpet/scripts");
                 Files.createDirectories(globalScripts);
                 Files.walk(globalScripts)
                     .filter(f -> f.toString().endsWith(".sc"))
-                    .forEach(f -> moduleNames.add(f.getFileName().toString().replaceFirst("\\.sc","").toLowerCase(Locale.ROOT)));
+                    .forEach(f -> moduleNames.add(f.getFileName().toString().replaceFirst("\\.sc$","").toLowerCase(Locale.ROOT)));
             }
         } catch (IOException e) {
             CarpetSettings.LOG.error("Exception while searching for apps: ", e);