diff --git a/src/main/c/CMakeLists.txt b/src/main/c/CMakeLists.txt index 87d04be..9e1ddcb 100644 --- a/src/main/c/CMakeLists.txt +++ b/src/main/c/CMakeLists.txt @@ -29,7 +29,7 @@ add_library( quickjs/cutils.c quickjs/libbf.c console.c - com_thebrokenrail_scriptcraft_quickjs_QuickJS.c + com_thebrokenrail_scriptcraft_core_quickjs_QuickJSNative.c ) file(STRINGS "quickjs/VERSION" QUICKJS_VERSION) diff --git a/src/main/c/com_thebrokenrail_scriptcraft_quickjs_QuickJS.c b/src/main/c/com_thebrokenrail_scriptcraft_core_quickjs_QuickJSNative.c similarity index 87% rename from src/main/c/com_thebrokenrail_scriptcraft_quickjs_QuickJS.c rename to src/main/c/com_thebrokenrail_scriptcraft_core_quickjs_QuickJSNative.c index 13f9dea..06b6720 100644 --- a/src/main/c/com_thebrokenrail_scriptcraft_quickjs_QuickJS.c +++ b/src/main/c/com_thebrokenrail_scriptcraft_core_quickjs_QuickJSNative.c @@ -6,19 +6,19 @@ #include #include -#include "com_thebrokenrail_scriptcraft_quickjs_QuickJS.h" +#include "com_thebrokenrail_scriptcraft_core_quickjs_QuickJSNative.h" #include "console.h" static JavaVM *jvm; static void *get_pointer(JNIEnv *env, jobject obj, const char *name) { - jclass clazz = (*env)->FindClass(env, "com/thebrokenrail/scriptcraft/quickjs/QuickJS"); + jclass clazz = (*env)->FindClass(env, "com/thebrokenrail/scriptcraft/core/quickjs/QuickJSNative"); jfieldID field = (*env)->GetFieldID(env, clazz, name, "J"); return (void *) (long) (*env)->GetLongField(env, obj, field); } static void set_pointer(JNIEnv *env, jobject obj, const char *name, void *value) { - jclass clazz = (*env)->FindClass(env, "com/thebrokenrail/scriptcraft/quickjs/QuickJS"); + jclass clazz = (*env)->FindClass(env, "com/thebrokenrail/scriptcraft/core/quickjs/QuickJSNative"); jfieldID field = (*env)->GetFieldID(env, clazz, name, "J"); (*env)->SetLongField(env, obj, field, (jlong) (long) value); } @@ -27,7 +27,7 @@ static char *js_module_normalize_name(JSContext *ctx, const char *base_name, con JNIEnv *env; (*jvm)->AttachCurrentThread(jvm, (void **) &env, NULL); - jclass clazz = (*env)->FindClass(env, "com/thebrokenrail/scriptcraft/quickjs/QuickJS"); + jclass clazz = (*env)->FindClass(env, "com/thebrokenrail/scriptcraft/core/quickjs/QuickJSModules"); jmethodID methodID = (*env)->GetStaticMethodID(env, clazz, "normalizeModule", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;"); jstring java_name = (*env)->NewStringUTF(env, name); @@ -99,7 +99,7 @@ static char *js_load_file(JSContext *ctx, const char *filename) { JNIEnv *env; (*jvm)->AttachCurrentThread(jvm, (void **) &env, NULL); - jclass clazz = (*env)->FindClass(env, "com/thebrokenrail/scriptcraft/quickjs/QuickJS"); + jclass clazz = (*env)->FindClass(env, "com/thebrokenrail/scriptcraft/core/quickjs/QuickJSModules"); jmethodID methodID = (*env)->GetStaticMethodID(env, clazz, "loadModule", "(Ljava/lang/String;)Ljava/lang/String;"); jstring java_filename = (*env)->NewStringUTF(env, filename); @@ -164,7 +164,7 @@ static JSModuleDef *js_module_loader(JSContext *ctx, const char *module_name, vo } static void throw_exception(JNIEnv *env, const char *message) { - jclass exception_clazz = (*env)->FindClass(env, "com/thebrokenrail/scriptcraft/quickjs/JSException"); + jclass exception_clazz = (*env)->FindClass(env, "com/thebrokenrail/scriptcraft/core/quickjs/JSException"); (*env)->ThrowNew(env, exception_clazz, message); } @@ -193,13 +193,15 @@ static JSClassDef JS_CLASS_JAVA_OBJECT = { }; static JSValue java_object_to_js_object(JNIEnv *env, JSContext *ctx, jobject obj) { - JSValue out = JS_NULL; + JSValue out; jclass boolean_clazz = (*env)->FindClass(env, "java/lang/Boolean"); jclass double_clazz = (*env)->FindClass(env, "java/lang/Double"); jclass string_clazz = (*env)->FindClass(env, "java/lang/String"); jclass array_clazz = (*env)->FindClass(env, "[Ljava/lang/Object;"); - if ((*env)->IsInstanceOf(env, obj, string_clazz)) { + if (!obj) { + out = JS_NULL; + } else if ((*env)->IsInstanceOf(env, obj, string_clazz)) { const char *native_string = (*env)->GetStringUTFChars(env, (jstring) obj, 0); out = JS_NewString(ctx, native_string); (*env)->ReleaseStringUTFChars(env, (jstring) obj, native_string); @@ -275,7 +277,21 @@ static jobject js_object_to_java_object(JNIEnv *env, JSContext *ctx, JSValue inp return obj; } -static JSValue js_bridge(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { +static JSValue js_add_bridge(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { + JSValue global_obj = JS_GetGlobalObject(ctx); + JSValue scriptcraft_obj = JS_GetPropertyStr(ctx, global_obj, "__scriptcraft_bridges__"); + + const char *name = JS_ToCString(ctx, argv[0]); + JS_SetPropertyStr(ctx, scriptcraft_obj, name, JS_DupValue(ctx, argv[1])); + JS_FreeCString(ctx, name); + + JS_FreeValue(ctx, scriptcraft_obj); + JS_FreeValue(ctx, global_obj); + + return JS_UNDEFINED; +} + +static JSValue js_use_bridge(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { JNIEnv *env; (*jvm)->AttachCurrentThread(jvm, (void **) &env, NULL); @@ -288,7 +304,7 @@ static JSValue js_bridge(JSContext *ctx, JSValueConst this_val, int argc, JSValu (*env)->DeleteLocalRef(env, obj); } - jclass clazz = (*env)->FindClass(env, "com/thebrokenrail/scriptcraft/bridge/Bridges"); + jclass clazz = (*env)->FindClass(env, "com/thebrokenrail/scriptcraft/core/ScriptCraftCore"); jmethodID methodID = (*env)->GetStaticMethodID(env, clazz, "useBridge", "(Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/Object;"); const char *js_bridge_name = JS_ToCString(ctx, argv[0]); @@ -325,7 +341,7 @@ static JSValue js_bridge(JSContext *ctx, JSValueConst this_val, int argc, JSValu return js_out; } -JNIEXPORT jobject JNICALL Java_com_thebrokenrail_scriptcraft_quickjs_QuickJS_bridge(JNIEnv *env, jobject this_val, jstring bridge_name, jobjectArray arr) { +JNIEXPORT jobject JNICALL Java_com_thebrokenrail_scriptcraft_core_quickjs_QuickJSNative_bridge(JNIEnv *env, jobject this_val, jstring bridge_name, jobjectArray arr) { JSContext *ctx = (JSContext *) get_pointer(env, this_val, "ctx"); int length = (*env)->GetArrayLength(env, arr); @@ -336,11 +352,10 @@ JNIEXPORT jobject JNICALL Java_com_thebrokenrail_scriptcraft_quickjs_QuickJS_bri } JSValue global_obj = JS_GetGlobalObject(ctx); - JSValue scriptcraft_obj = JS_GetPropertyStr(ctx, global_obj, "__scriptcraft__"); - JSValue bridges = JS_GetPropertyStr(ctx, scriptcraft_obj, "bridges"); + JSValue scriptcraft_obj = JS_GetPropertyStr(ctx, global_obj, "__scriptcraft_bridges__"); const char *native_string = (*env)->GetStringUTFChars(env, bridge_name, 0); - JSValue bridge = JS_GetPropertyStr(ctx, bridges, native_string); + JSValue bridge = JS_GetPropertyStr(ctx, scriptcraft_obj, native_string); (*env)->ReleaseStringUTFChars(env, bridge_name, native_string); JSValue out; @@ -360,7 +375,6 @@ JNIEXPORT jobject JNICALL Java_com_thebrokenrail_scriptcraft_quickjs_QuickJS_bri } JS_FreeValue(ctx, bridge); - JS_FreeValue(ctx, bridges); JS_FreeValue(ctx, scriptcraft_obj); JS_FreeValue(ctx, global_obj); @@ -370,7 +384,13 @@ JNIEXPORT jobject JNICALL Java_com_thebrokenrail_scriptcraft_quickjs_QuickJS_bri return java_out; } -JNIEXPORT void JNICALL Java_com_thebrokenrail_scriptcraft_quickjs_QuickJS_init(JNIEnv *env, jobject this_val) { +static int scriptcraft_core_init(JSContext *ctx, JSModuleDef *m) { + JS_SetModuleExport(ctx, m, "useBridge", JS_NewCFunction(ctx, js_use_bridge, "useBridge", 1)); + JS_SetModuleExport(ctx, m, "addBridge", JS_NewCFunction(ctx, js_add_bridge, "addBridge", 2)); + return 0; +} + +JNIEXPORT void JNICALL Java_com_thebrokenrail_scriptcraft_core_quickjs_QuickJSNative_init(JNIEnv *env, jobject this_val) { jint rc = (*env)->GetJavaVM(env, &jvm); if (rc != JNI_OK) { throw_exception(env, "qjs: unable to cache JavaVM"); @@ -392,24 +412,28 @@ JNIEXPORT void JNICALL Java_com_thebrokenrail_scriptcraft_quickjs_QuickJS_init(J js_console_init(ctx); - JSValue global_obj = JS_GetGlobalObject(ctx); - - JSValue scriptcraft_obj = JS_NewObject(ctx); - JS_SetPropertyStr(ctx, scriptcraft_obj, "bridges", JS_NewObject(ctx)); - JS_SetPropertyStr(ctx, scriptcraft_obj, "useBridge", JS_NewCFunction(ctx, js_bridge, "useBridge", 1)); - JS_SetPropertyStr(ctx, global_obj, "__scriptcraft__", scriptcraft_obj); - - JS_FreeValue(ctx, global_obj); - JS_NewClassID(&JS_CLASS_JAVA_OBJECT_ID); JS_NewClass(JS_GetRuntime(ctx), JS_CLASS_JAVA_OBJECT_ID, &JS_CLASS_JAVA_OBJECT); JS_SetClassProto(ctx, JS_CLASS_JAVA_OBJECT_ID, JS_NewObject(ctx)); + JSModuleDef *m = JS_NewCModule(ctx, "scriptcraft-core", scriptcraft_core_init); + if (!m) { + throw_exception(env, "qjs: unable to allocate C module"); + return; + } + + JS_AddModuleExport(ctx, m, "useBridge"); + JS_AddModuleExport(ctx, m, "addBridge"); + + JSValue global_obj = JS_GetGlobalObject(ctx); + JS_SetPropertyStr(ctx, global_obj, "__scriptcraft_bridges__", JS_NewObject(ctx)); + JS_FreeValue(ctx, global_obj); + set_pointer(env, this_val, "rt", rt); set_pointer(env, this_val, "ctx", ctx); } -JNIEXPORT void JNICALL Java_com_thebrokenrail_scriptcraft_quickjs_QuickJS_free(JNIEnv *env, jobject this_val) { +JNIEXPORT void JNICALL Java_com_thebrokenrail_scriptcraft_core_quickjs_QuickJSNative_free(JNIEnv *env, jobject this_val) { JSContext *ctx = (JSContext *) get_pointer(env, this_val, "ctx"); JSRuntime *rt = (JSRuntime *) get_pointer(env, this_val, "rt"); @@ -442,7 +466,7 @@ static int eval_buf(JNIEnv *env, JSContext *ctx, const void *buf, int buf_len, c return ret; } -JNIEXPORT void JNICALL Java_com_thebrokenrail_scriptcraft_quickjs_QuickJS_run(JNIEnv *env, jobject this_val, jstring data) { +JNIEXPORT void JNICALL Java_com_thebrokenrail_scriptcraft_core_quickjs_QuickJSNative_run(JNIEnv *env, jobject this_val, jstring data) { JSContext *ctx = (JSContext *) get_pointer(env, this_val, "ctx"); const char *native_string = (*env)->GetStringUTFChars(env, data, 0); @@ -454,7 +478,7 @@ void print_data(char *data, int err) { JNIEnv *env; (*jvm)->AttachCurrentThread(jvm, (void **) &env, NULL); - jclass clazz = (*env)->FindClass(env, "com/thebrokenrail/scriptcraft/quickjs/QuickJS"); + jclass clazz = (*env)->FindClass(env, "com/thebrokenrail/scriptcraft/core/quickjs/QuickJSNative"); jmethodID print_methodID = (*env)->GetStaticMethodID(env, clazz, "print", "(Ljava/lang/String;Z)V"); jstring str = (*env)->NewStringUTF(env, data); (*env)->CallStaticVoidMethod(env, clazz, print_methodID, str, err); diff --git a/src/main/c/com_thebrokenrail_scriptcraft_core_quickjs_QuickJSNative.h b/src/main/c/com_thebrokenrail_scriptcraft_core_quickjs_QuickJSNative.h new file mode 100644 index 0000000..42362a0 --- /dev/null +++ b/src/main/c/com_thebrokenrail_scriptcraft_core_quickjs_QuickJSNative.h @@ -0,0 +1,47 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class com_thebrokenrail_scriptcraft_core_quickjs_QuickJSNative */ + +#ifndef _Included_com_thebrokenrail_scriptcraft_core_quickjs_QuickJSNative +#define _Included_com_thebrokenrail_scriptcraft_core_quickjs_QuickJSNative +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: com_thebrokenrail_scriptcraft_core_quickjs_QuickJSNative + * Method: init + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_com_thebrokenrail_scriptcraft_core_quickjs_QuickJSNative_init + (JNIEnv *, jobject); + +/* + * Class: com_thebrokenrail_scriptcraft_core_quickjs_QuickJSNative + * Method: free + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_com_thebrokenrail_scriptcraft_core_quickjs_QuickJSNative_free + (JNIEnv *, jobject); + +/* + * Class: com_thebrokenrail_scriptcraft_core_quickjs_QuickJSNative + * Method: bridge + * Signature: (Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/Object; + */ +JNIEXPORT jobject JNICALL Java_com_thebrokenrail_scriptcraft_core_quickjs_QuickJSNative_bridge + (JNIEnv *, jobject, jstring, jobjectArray); + +/* + * Class: com_thebrokenrail_scriptcraft_core_quickjs_QuickJSNative + * Method: run + * Signature: (Ljava/lang/String;Ljava/lang/String;)V + */ +JNIEXPORT void JNICALL Java_com_thebrokenrail_scriptcraft_core_quickjs_QuickJSNative_run + (JNIEnv *, jobject, jstring); + +void print_data(char *data, int err); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/src/main/c/com_thebrokenrail_scriptcraft_quickjs_QuickJS.h b/src/main/c/com_thebrokenrail_scriptcraft_quickjs_QuickJS.h deleted file mode 100644 index e049fc4..0000000 --- a/src/main/c/com_thebrokenrail_scriptcraft_quickjs_QuickJS.h +++ /dev/null @@ -1,47 +0,0 @@ -/* DO NOT EDIT THIS FILE - it is machine generated */ -#include -/* Header for class com_thebrokenrail_scriptcraft_quickjs_QuickJS */ - -#ifndef _Included_com_thebrokenrail_scriptcraft_quickjs_QuickJS -#define _Included_com_thebrokenrail_scriptcraft_quickjs_QuickJS -#ifdef __cplusplus -extern "C" { -#endif -/* - * Class: com_thebrokenrail_scriptcraft_quickjs_QuickJS - * Method: init - * Signature: ()V - */ -JNIEXPORT void JNICALL Java_com_thebrokenrail_scriptcraft_quickjs_QuickJS_init - (JNIEnv *, jobject); - -/* - * Class: com_thebrokenrail_scriptcraft_quickjs_QuickJS - * Method: free - * Signature: ()V - */ -JNIEXPORT void JNICALL Java_com_thebrokenrail_scriptcraft_quickjs_QuickJS_free - (JNIEnv *, jobject); - -/* - * Class: com_thebrokenrail_scriptcraft_quickjs_QuickJS - * Method: bridge - * Signature: (Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/Object; - */ -JNIEXPORT jobject JNICALL Java_com_thebrokenrail_scriptcraft_quickjs_QuickJS_bridge - (JNIEnv *, jobject, jstring, jobjectArray); - -/* - * Class: com_thebrokenrail_scriptcraft_quickjs_QuickJS - * Method: run - * Signature: (Ljava/lang/String;Ljava/lang/String;)V - */ -JNIEXPORT void JNICALL Java_com_thebrokenrail_scriptcraft_quickjs_QuickJS_run - (JNIEnv *, jobject, jstring); - -void print_data(char *data, int err); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/src/main/c/console.c b/src/main/c/console.c index c032257..d6b87f3 100644 --- a/src/main/c/console.c +++ b/src/main/c/console.c @@ -4,7 +4,7 @@ #include #include -#include "com_thebrokenrail_scriptcraft_quickjs_QuickJS.h" +#include "com_thebrokenrail_scriptcraft_core_quickjs_QuickJSNative.h" static JSValue js_print_internal(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int err, int prepend_throw) { int i; diff --git a/src/main/java/com/thebrokenrail/scriptcraft/Demo.java b/src/main/java/com/thebrokenrail/scriptcraft/Demo.java index 192853e..342231e 100644 --- a/src/main/java/com/thebrokenrail/scriptcraft/Demo.java +++ b/src/main/java/com/thebrokenrail/scriptcraft/Demo.java @@ -1,6 +1,6 @@ package com.thebrokenrail.scriptcraft; -import com.thebrokenrail.scriptcraft.util.ScriptCraftEntrypoint; +import com.thebrokenrail.scriptcraft.core.ScriptCraftEntrypoint; public class Demo implements ScriptCraftEntrypoint { @Override diff --git a/src/main/java/com/thebrokenrail/scriptcraft/ScriptCraft.java b/src/main/java/com/thebrokenrail/scriptcraft/ScriptCraft.java index 808fde0..191328e 100644 --- a/src/main/java/com/thebrokenrail/scriptcraft/ScriptCraft.java +++ b/src/main/java/com/thebrokenrail/scriptcraft/ScriptCraft.java @@ -1,35 +1,13 @@ package com.thebrokenrail.scriptcraft; -import com.thebrokenrail.scriptcraft.quickjs.QuickJS; -import com.thebrokenrail.scriptcraft.quickjs.QuickJSManager; -import com.thebrokenrail.scriptcraft.util.ScriptCraftEntrypoint; +import com.thebrokenrail.scriptcraft.api.ScriptCraftAPI; +import com.thebrokenrail.scriptcraft.core.ScriptCraftCore; import net.fabricmc.api.ModInitializer; -import net.fabricmc.loader.api.FabricLoader; - -import java.util.List; -import java.util.regex.Pattern; public class ScriptCraft implements ModInitializer { - public static final String NAMESPACE = "scriptcraft"; - public static final Pattern MOD_ID_PATTERN = Pattern.compile("[a-z][a-z0-9-_]{1,63}"); - @Override public void onInitialize() { - QuickJSManager.init(new QuickJSManager.Task() { - @Override - protected Object run(QuickJS quickjs) { - List mods = FabricLoader.getInstance().getEntrypoints(NAMESPACE, ScriptCraftEntrypoint.class); - for (ScriptCraftEntrypoint mod : mods) { - if (MOD_ID_PATTERN.matcher(mod.getModID()).matches()) { - if (mod.shouldAutoLoad()) { - quickjs.run("import '" + mod.getModID() + "';"); - } - } else { - throw new RuntimeException("Invalid Mod ID: " + mod.getModID()); - } - } - return null; - } - }); + ScriptCraftAPI.init(); + ScriptCraftCore.init(); } } diff --git a/src/main/java/com/thebrokenrail/scriptcraft/api/ScriptCraftAPI.java b/src/main/java/com/thebrokenrail/scriptcraft/api/ScriptCraftAPI.java new file mode 100644 index 0000000..2ec5871 --- /dev/null +++ b/src/main/java/com/thebrokenrail/scriptcraft/api/ScriptCraftAPI.java @@ -0,0 +1,26 @@ +package com.thebrokenrail.scriptcraft.api; + +import com.thebrokenrail.scriptcraft.api.bridge.Bridges; +import com.thebrokenrail.scriptcraft.core.ScriptCraftEntrypoint; + +@SuppressWarnings("unused") +public class ScriptCraftAPI implements ScriptCraftEntrypoint { + @Override + public String getModID() { + return "minecraft"; + } + + @Override + public String getModIndex() { + return "index"; + } + + @Override + public boolean shouldAutoLoad() { + return false; + } + + public static void init() { + Bridges.init(); + } +} \ No newline at end of file diff --git a/src/main/java/com/thebrokenrail/scriptcraft/api/CustomBlock.java b/src/main/java/com/thebrokenrail/scriptcraft/api/block/CustomBlock.java similarity index 62% rename from src/main/java/com/thebrokenrail/scriptcraft/api/CustomBlock.java rename to src/main/java/com/thebrokenrail/scriptcraft/api/block/CustomBlock.java index 4feb014..fbbdb53 100644 --- a/src/main/java/com/thebrokenrail/scriptcraft/api/CustomBlock.java +++ b/src/main/java/com/thebrokenrail/scriptcraft/api/block/CustomBlock.java @@ -1,7 +1,7 @@ -package com.thebrokenrail.scriptcraft.api; +package com.thebrokenrail.scriptcraft.api.block; -import com.thebrokenrail.scriptcraft.util.Util; -import com.thebrokenrail.scriptcraft.quickjs.QuickJSManager; +import com.thebrokenrail.scriptcraft.core.ValueUtil; +import com.thebrokenrail.scriptcraft.core.quickjs.QuickJSManager; import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.entity.player.PlayerEntity; @@ -23,6 +23,6 @@ public class CustomBlock extends Block { @Override public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) { - return Util.getEnumValue(ActionResult.class, (String) QuickJSManager.bridge("CustomBlock.onUse", id.toString(), world, state, (double) pos.getX(), (double) pos.getY(), (double) pos.getZ(), hit.getSide().name(), player, hand.name()), ActionResult.PASS); + return ValueUtil.getEnumValue(ActionResult.class, (String) QuickJSManager.bridge("CustomBlock.onUse", id.toString(), world, state, (double) pos.getX(), (double) pos.getY(), (double) pos.getZ(), hit.getSide().name(), player, hand.name()), ActionResult.PASS); } } diff --git a/src/main/java/com/thebrokenrail/scriptcraft/api/CustomBlockEntity.java b/src/main/java/com/thebrokenrail/scriptcraft/api/block/CustomBlockEntity.java similarity index 64% rename from src/main/java/com/thebrokenrail/scriptcraft/api/CustomBlockEntity.java rename to src/main/java/com/thebrokenrail/scriptcraft/api/block/CustomBlockEntity.java index f347d92..f1c998b 100644 --- a/src/main/java/com/thebrokenrail/scriptcraft/api/CustomBlockEntity.java +++ b/src/main/java/com/thebrokenrail/scriptcraft/api/block/CustomBlockEntity.java @@ -1,6 +1,6 @@ -package com.thebrokenrail.scriptcraft.api; +package com.thebrokenrail.scriptcraft.api.block; -import com.thebrokenrail.scriptcraft.quickjs.QuickJSManager; +import com.thebrokenrail.scriptcraft.core.quickjs.QuickJSManager; import net.fabricmc.fabric.api.block.entity.BlockEntityClientSerializable; import net.minecraft.block.entity.BlockEntity; import net.minecraft.block.entity.BlockEntityType; @@ -11,22 +11,15 @@ import net.minecraft.util.Tickable; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; -import java.util.HashMap; -import java.util.Map; - public class CustomBlockEntity extends BlockEntity implements BlockEntityClientSerializable, Tickable { - private static final Map newObjID = new HashMap<>(); + private static long newObjID = 0; - private final Identifier id; - private final int objID; + private final long objID; public CustomBlockEntity(BlockEntityType type, Identifier id) { super(type); - this.id = id; - newObjID.putIfAbsent(id, 0); - objID = newObjID.get(id); - newObjID.put(id, newObjID.get(id) + 1); + objID = newObjID++; QuickJSManager.bridge("CustomBlockEntity.create", id.toString(), (double) objID); } @@ -34,7 +27,7 @@ public class CustomBlockEntity extends BlockEntity implements BlockEntityClientS @Override public void fromTag(CompoundTag tag) { super.fromTag(tag); - QuickJSManager.bridge("CustomBlockEntity.fromTag", id.toString(), (double) objID, tag); + QuickJSManager.bridge("CustomBlockEntity.fromTag", (double) objID, tag); } @Override @@ -44,7 +37,7 @@ public class CustomBlockEntity extends BlockEntity implements BlockEntityClientS @Override public CompoundTag toTag(CompoundTag tag) { - return (CompoundTag) QuickJSManager.bridge("CustomBlockEntity.toTag", id.toString(), (double) objID, super.toTag(tag)); + return (CompoundTag) QuickJSManager.bridge("CustomBlockEntity.toTag", (double) objID, super.toTag(tag)); } @Override @@ -54,20 +47,20 @@ public class CustomBlockEntity extends BlockEntity implements BlockEntityClientS @Override public void tick() { - QuickJSManager.bridge("CustomBlockEntity.tick", id.toString(), (double) objID); + QuickJSManager.bridge("CustomBlockEntity.tick", (double) objID); } @Override public void setLocation(World world, BlockPos pos) { super.setLocation(world, pos); - QuickJSManager.bridge("CustomBlockEntity.setLocation", id.toString(), (double) objID, world, (double) pos.getX(), (double) pos.getY(), (double) pos.getZ()); + QuickJSManager.bridge("CustomBlockEntity.setLocation", (double) objID, world, (double) pos.getX(), (double) pos.getY(), (double) pos.getZ()); } @SuppressWarnings("deprecation") @Override protected void finalize() throws Throwable { try { - QuickJSManager.bridge("CustomBlockEntity.free", id.toString(), (double) objID); + QuickJSManager.bridge("CustomBlockEntity.free", (double) objID); } finally { super.finalize(); } @@ -80,4 +73,8 @@ public class CustomBlockEntity extends BlockEntity implements BlockEntityClientS sync(); } } + + public long getObjID() { + return objID; + } } diff --git a/src/main/java/com/thebrokenrail/scriptcraft/api/CustomBlockWithEntity.java b/src/main/java/com/thebrokenrail/scriptcraft/api/block/CustomBlockWithEntity.java similarity index 76% rename from src/main/java/com/thebrokenrail/scriptcraft/api/CustomBlockWithEntity.java rename to src/main/java/com/thebrokenrail/scriptcraft/api/block/CustomBlockWithEntity.java index 378b47c..457add7 100644 --- a/src/main/java/com/thebrokenrail/scriptcraft/api/CustomBlockWithEntity.java +++ b/src/main/java/com/thebrokenrail/scriptcraft/api/block/CustomBlockWithEntity.java @@ -1,5 +1,7 @@ -package com.thebrokenrail.scriptcraft.api; +package com.thebrokenrail.scriptcraft.api.block; +import com.thebrokenrail.scriptcraft.api.block.CustomBlock; +import com.thebrokenrail.scriptcraft.api.block.CustomBlockEntity; import net.minecraft.block.BlockEntityProvider; import net.minecraft.block.entity.BlockEntity; import net.minecraft.util.Identifier; diff --git a/src/main/java/com/thebrokenrail/scriptcraft/bridge/BlockSettingsBridges.java b/src/main/java/com/thebrokenrail/scriptcraft/api/bridge/BlockSettingsBridges.java similarity index 87% rename from src/main/java/com/thebrokenrail/scriptcraft/bridge/BlockSettingsBridges.java rename to src/main/java/com/thebrokenrail/scriptcraft/api/bridge/BlockSettingsBridges.java index 286a879..7e08dc9 100644 --- a/src/main/java/com/thebrokenrail/scriptcraft/bridge/BlockSettingsBridges.java +++ b/src/main/java/com/thebrokenrail/scriptcraft/api/bridge/BlockSettingsBridges.java @@ -1,5 +1,6 @@ -package com.thebrokenrail.scriptcraft.bridge; +package com.thebrokenrail.scriptcraft.api.bridge; +import com.thebrokenrail.scriptcraft.core.ScriptCraftCore; import net.fabricmc.fabric.api.block.FabricBlockSettings; import net.minecraft.block.Material; import net.minecraft.block.MaterialColor; @@ -8,7 +9,7 @@ import java.util.Locale; class BlockSettingsBridges { static void register() { - Bridges.addBridge("BlockSettings.create", args -> { + ScriptCraftCore.addBridge("BlockSettings.create", args -> { try { String materialID = ((String) args[0]).toUpperCase(Locale.ROOT); Material material = (Material) Material.class.getField(materialID).get(null); diff --git a/src/main/java/com/thebrokenrail/scriptcraft/api/bridge/BlockStateBridges.java b/src/main/java/com/thebrokenrail/scriptcraft/api/bridge/BlockStateBridges.java new file mode 100644 index 0000000..8147c93 --- /dev/null +++ b/src/main/java/com/thebrokenrail/scriptcraft/api/bridge/BlockStateBridges.java @@ -0,0 +1,13 @@ +package com.thebrokenrail.scriptcraft.api.bridge; + +import com.thebrokenrail.scriptcraft.core.ScriptCraftCore; +import net.minecraft.block.BlockState; +import net.minecraft.util.Identifier; +import net.minecraft.util.registry.Registry; + +class BlockStateBridges { + static void register() { + ScriptCraftCore.addBridge("BlockState.getDefaultState", args -> Registry.BLOCK.get(new Identifier((String) args[0])).getDefaultState()); + ScriptCraftCore.addBridge("BlockState.getBlock", args -> Registry.BLOCK.getId(((BlockState) args[0]).getBlock()).toString()); + } +} diff --git a/src/main/java/com/thebrokenrail/scriptcraft/api/bridge/Bridges.java b/src/main/java/com/thebrokenrail/scriptcraft/api/bridge/Bridges.java new file mode 100644 index 0000000..79514fd --- /dev/null +++ b/src/main/java/com/thebrokenrail/scriptcraft/api/bridge/Bridges.java @@ -0,0 +1,16 @@ +package com.thebrokenrail.scriptcraft.api.bridge; + +public class Bridges { + public static void init() { + BlockSettingsBridges.register(); + RegistryBridge.register(); + ItemStackBridges.register(); + LivingEntityBridges.register(); + BlockStateBridges.register(); + WorldBridges.register(); + ItemSettingsBridges.register(); + EntityBridges.register(); + DamageSourceBridges.register(); + TagBridges.register(); + } +} diff --git a/src/main/java/com/thebrokenrail/scriptcraft/bridge/DamageSourceBridges.java b/src/main/java/com/thebrokenrail/scriptcraft/api/bridge/DamageSourceBridges.java similarity index 56% rename from src/main/java/com/thebrokenrail/scriptcraft/bridge/DamageSourceBridges.java rename to src/main/java/com/thebrokenrail/scriptcraft/api/bridge/DamageSourceBridges.java index 65e9f17..f067768 100644 --- a/src/main/java/com/thebrokenrail/scriptcraft/bridge/DamageSourceBridges.java +++ b/src/main/java/com/thebrokenrail/scriptcraft/api/bridge/DamageSourceBridges.java @@ -1,5 +1,6 @@ -package com.thebrokenrail.scriptcraft.bridge; +package com.thebrokenrail.scriptcraft.api.bridge; +import com.thebrokenrail.scriptcraft.core.ScriptCraftCore; import net.minecraft.entity.LivingEntity; import net.minecraft.entity.damage.DamageSource; import net.minecraft.entity.player.PlayerEntity; @@ -8,7 +9,7 @@ import java.util.Locale; class DamageSourceBridges { static void register() { - Bridges.addBridge("DamageSource.create", args -> { + ScriptCraftCore.addBridge("DamageSource.create", args -> { try { String id = ((String) args[0]).toUpperCase(Locale.ROOT); return DamageSource.class.getField(id).get(null); @@ -17,7 +18,7 @@ class DamageSourceBridges { } }); - Bridges.addBridge("DamageSource.createFromPlayer", args -> DamageSource.player((PlayerEntity) args[1])); - Bridges.addBridge("DamageSource.createFromMob", args -> DamageSource.mob((LivingEntity) args[1])); + ScriptCraftCore.addBridge("DamageSource.createFromPlayer", args -> DamageSource.player((PlayerEntity) args[1])); + ScriptCraftCore.addBridge("DamageSource.createFromMob", args -> DamageSource.mob((LivingEntity) args[1])); } } diff --git a/src/main/java/com/thebrokenrail/scriptcraft/api/bridge/EntityBridges.java b/src/main/java/com/thebrokenrail/scriptcraft/api/bridge/EntityBridges.java new file mode 100644 index 0000000..695a2cc --- /dev/null +++ b/src/main/java/com/thebrokenrail/scriptcraft/api/bridge/EntityBridges.java @@ -0,0 +1,57 @@ +package com.thebrokenrail.scriptcraft.api.bridge; + +import com.thebrokenrail.scriptcraft.core.ScriptCraftCore; +import com.thebrokenrail.scriptcraft.core.ValueUtil; +import net.minecraft.entity.Entity; +import net.minecraft.entity.damage.DamageSource; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.util.math.Vec3d; +import net.minecraft.util.registry.Registry; + +import java.util.Objects; + +class EntityBridges { + static void register() { + ScriptCraftCore.addBridge("Entity.getEntityWorld", args -> ((Entity) args[0]).getEntityWorld()); + ScriptCraftCore.addBridge("Entity.getID", args -> Registry.ENTITY_TYPE.getId(((Entity) args[0]).getType()).toString()); + + ScriptCraftCore.addBridge("Entity.getName", args -> ((Entity) args[0]).getName().asString()); + ScriptCraftCore.addBridge("Entity.getDisplayName", args -> ((Entity) args[0]).getDisplayName().asString()); + ScriptCraftCore.addBridge("Entity.getCustomName", args -> ((Entity) args[0]).hasCustomName() ? Objects.requireNonNull(((Entity) args[0]).getCustomName()).asString() : null); + + ScriptCraftCore.addBridge("Entity.kill", args -> { + ((Entity) args[0]).kill(); + return null; + }); + ScriptCraftCore.addBridge("Entity.remove", args -> { + ((Entity) args[0]).remove(); + return null; + }); + ScriptCraftCore.addBridge("Entity.damage", args -> ((Entity) args[0]).damage((DamageSource) args[1], (float) args[2])); + + ScriptCraftCore.addBridge("Entity.setFireTicks", args -> { + ((Entity) args[0]).setFireTicks((int) args[1]); + return null; + }); + ScriptCraftCore.addBridge("Entity.getFireTicks", args -> ((Entity) args[0]).getFireTicks()); + + ScriptCraftCore.addBridge("Entity.getPosition", args -> { + Vec3d pos = ((Entity) args[0]).getPos(); + Double[] out = new Double[3]; + out[0] = pos.getX(); + out[1] = pos.getY(); + out[2] = pos.getZ(); + return out; + }); + ScriptCraftCore.addBridge("Entity.setPosition", args -> { + ((Entity) args[0]).updatePosition(ValueUtil.toDouble(args[1], 0), ValueUtil.toDouble(args[2], 0), ValueUtil.toDouble(args[3], 0)); + return null; + }); + + ScriptCraftCore.addBridge("Entity.toTag", args -> ((Entity) args[0]).toTag(new CompoundTag())); + ScriptCraftCore.addBridge("Entity.fromTag", args -> { + ((Entity) args[0]).fromTag((CompoundTag) args[1]); + return null; + }); + } +} diff --git a/src/main/java/com/thebrokenrail/scriptcraft/bridge/ItemSettingsBridges.java b/src/main/java/com/thebrokenrail/scriptcraft/api/bridge/ItemSettingsBridges.java similarity index 80% rename from src/main/java/com/thebrokenrail/scriptcraft/bridge/ItemSettingsBridges.java rename to src/main/java/com/thebrokenrail/scriptcraft/api/bridge/ItemSettingsBridges.java index ca2e141..f46da29 100644 --- a/src/main/java/com/thebrokenrail/scriptcraft/bridge/ItemSettingsBridges.java +++ b/src/main/java/com/thebrokenrail/scriptcraft/api/bridge/ItemSettingsBridges.java @@ -1,12 +1,13 @@ -package com.thebrokenrail.scriptcraft.bridge; +package com.thebrokenrail.scriptcraft.api.bridge; +import com.thebrokenrail.scriptcraft.core.ScriptCraftCore; import net.minecraft.item.Item; import net.minecraft.item.ItemGroup; import net.minecraft.util.Rarity; class ItemSettingsBridges { static void register() { - Bridges.addBridge("ItemSettings.create", args -> { + ScriptCraftCore.addBridge("ItemSettings.create", args -> { Item.Settings settings = new Item.Settings(); settings.maxCount(((Double) args[0]).intValue()); diff --git a/src/main/java/com/thebrokenrail/scriptcraft/api/bridge/ItemStackBridges.java b/src/main/java/com/thebrokenrail/scriptcraft/api/bridge/ItemStackBridges.java new file mode 100644 index 0000000..7860a3e --- /dev/null +++ b/src/main/java/com/thebrokenrail/scriptcraft/api/bridge/ItemStackBridges.java @@ -0,0 +1,38 @@ +package com.thebrokenrail.scriptcraft.api.bridge; + +import com.thebrokenrail.scriptcraft.core.ScriptCraftCore; +import com.thebrokenrail.scriptcraft.core.ValueUtil; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.util.Identifier; +import net.minecraft.util.registry.Registry; + +class ItemStackBridges { + static void register() { + ScriptCraftCore.addBridge("ItemStack.create", args -> new ItemStack(Registry.ITEM.get(new Identifier((String) args[0])), ((Double) args[1]).intValue())); + + ScriptCraftCore.addBridge("ItemStack.getItem", args -> Registry.ITEM.getId(((ItemStack) args[0]).getItem()).toString()); + + ScriptCraftCore.addBridge("ItemStack.setCount", args -> { + ((ItemStack) args[0]).setCount((int) ValueUtil.toDouble(args[1], 0)); + return null; + }); + ScriptCraftCore.addBridge("ItemStack.getCount", args -> (double) ((ItemStack) args[0]).getCount()); + + ScriptCraftCore.addBridge("ItemStack.setDamage", args -> { + ((ItemStack) args[0]).setDamage((int) ValueUtil.toDouble(args[1], 0)); + return null; + }); + ScriptCraftCore.addBridge("ItemStack.getDamage", args -> (double) ((ItemStack) args[0]).getDamage()); + ScriptCraftCore.addBridge("ItemStack.isDamageable", args -> ((ItemStack) args[0]).isDamageable()); + + ScriptCraftCore.addBridge("ItemStack.getTag", args -> ((ItemStack) args[0]).getTag()); + ScriptCraftCore.addBridge("ItemStack.setTag", args -> { + ((ItemStack) args[0]).setTag((CompoundTag) args[1]); + return null; + }); + + ScriptCraftCore.addBridge("ItemStack.toTag", args -> ((ItemStack) args[0]).toTag(new CompoundTag())); + ScriptCraftCore.addBridge("ItemStack.fromTag", args -> ItemStack.fromTag((CompoundTag) args[1])); + } +} diff --git a/src/main/java/com/thebrokenrail/scriptcraft/api/bridge/LivingEntityBridges.java b/src/main/java/com/thebrokenrail/scriptcraft/api/bridge/LivingEntityBridges.java new file mode 100644 index 0000000..2313c5c --- /dev/null +++ b/src/main/java/com/thebrokenrail/scriptcraft/api/bridge/LivingEntityBridges.java @@ -0,0 +1,12 @@ +package com.thebrokenrail.scriptcraft.api.bridge; + +import com.thebrokenrail.scriptcraft.core.ScriptCraftCore; +import net.minecraft.entity.LivingEntity; +import net.minecraft.util.Hand; + +class LivingEntityBridges { + static void register() { + ScriptCraftCore.addBridge("LivingEntity.getStackInHand", args -> ((LivingEntity) args[0]).getStackInHand((Hand) args[1])); + ScriptCraftCore.addBridge("LivingEntity.getHealth", args -> ((LivingEntity) args[0]).getHealth()); + } +} diff --git a/src/main/java/com/thebrokenrail/scriptcraft/bridge/RegistryBridge.java b/src/main/java/com/thebrokenrail/scriptcraft/api/bridge/RegistryBridge.java similarity index 68% rename from src/main/java/com/thebrokenrail/scriptcraft/bridge/RegistryBridge.java rename to src/main/java/com/thebrokenrail/scriptcraft/api/bridge/RegistryBridge.java index 74e7554..f7f2fe9 100644 --- a/src/main/java/com/thebrokenrail/scriptcraft/bridge/RegistryBridge.java +++ b/src/main/java/com/thebrokenrail/scriptcraft/api/bridge/RegistryBridge.java @@ -1,9 +1,10 @@ -package com.thebrokenrail.scriptcraft.bridge; +package com.thebrokenrail.scriptcraft.api.bridge; -import com.thebrokenrail.scriptcraft.api.CustomBlock; -import com.thebrokenrail.scriptcraft.api.CustomBlockEntity; -import com.thebrokenrail.scriptcraft.api.CustomBlockWithEntity; -import com.thebrokenrail.scriptcraft.api.CustomItem; +import com.thebrokenrail.scriptcraft.api.block.CustomBlock; +import com.thebrokenrail.scriptcraft.api.block.CustomBlockEntity; +import com.thebrokenrail.scriptcraft.api.block.CustomBlockWithEntity; +import com.thebrokenrail.scriptcraft.api.item.CustomItem; +import com.thebrokenrail.scriptcraft.core.ScriptCraftCore; import net.minecraft.block.Block; import net.minecraft.block.entity.BlockEntityType; import net.minecraft.item.BlockItem; @@ -13,20 +14,20 @@ import net.minecraft.util.registry.Registry; class RegistryBridge { static void register() { - Bridges.addBridge("Registry.registerBlock", args -> { + ScriptCraftCore.addBridge("Registry.registerBlock", args -> { Registry.register(Registry.BLOCK, new Identifier((String) args[0]), new CustomBlock((Block.Settings) args[1], new Identifier((String) args[0]))); return null; }); - Bridges.addBridge("Registry.registerBlockWithEntity", args -> { + ScriptCraftCore.addBridge("Registry.registerBlockWithEntity", args -> { Registry.register(Registry.BLOCK, new Identifier((String) args[0]), new CustomBlockWithEntity((Block.Settings) args[1], new Identifier((String) args[0]))); Registry.register(Registry.BLOCK_ENTITY_TYPE, new Identifier((String) args[0]), BlockEntityType.Builder.create(() -> new CustomBlockEntity(Registry.BLOCK_ENTITY_TYPE.get(new Identifier((String) args[0])), new Identifier((String) args[0])), Registry.BLOCK.get(new Identifier((String) args[0]))).build(null)); return null; }); - Bridges.addBridge("Registry.registerItem", args -> { + ScriptCraftCore.addBridge("Registry.registerItem", args -> { Registry.register(Registry.ITEM, new Identifier((String) args[0]), new CustomItem((Item.Settings) args[1], new Identifier((String) args[0]))); return null; }); - Bridges.addBridge("Registry.registerBlockItem", args -> { + ScriptCraftCore.addBridge("Registry.registerBlockItem", args -> { Registry.register(Registry.ITEM, new Identifier((String) args[0]), new BlockItem(Registry.BLOCK.get(new Identifier((String) args[2])), (Item.Settings) args[1])); return null; }); diff --git a/src/main/java/com/thebrokenrail/scriptcraft/bridge/TagBridges.java b/src/main/java/com/thebrokenrail/scriptcraft/api/bridge/TagBridges.java similarity index 79% rename from src/main/java/com/thebrokenrail/scriptcraft/bridge/TagBridges.java rename to src/main/java/com/thebrokenrail/scriptcraft/api/bridge/TagBridges.java index e4689c7..24fc600 100644 --- a/src/main/java/com/thebrokenrail/scriptcraft/bridge/TagBridges.java +++ b/src/main/java/com/thebrokenrail/scriptcraft/api/bridge/TagBridges.java @@ -1,6 +1,7 @@ -package com.thebrokenrail.scriptcraft.bridge; +package com.thebrokenrail.scriptcraft.api.bridge; -import com.thebrokenrail.scriptcraft.util.Util; +import com.thebrokenrail.scriptcraft.core.ScriptCraftCore; +import com.thebrokenrail.scriptcraft.core.ValueUtil; import net.minecraft.nbt.AbstractListTag; import net.minecraft.nbt.AbstractNumberTag; import net.minecraft.nbt.ByteTag; @@ -74,37 +75,37 @@ class TagBridges { } static void register() { - Bridges.addBridge("CompoundTag.get", args -> { + ScriptCraftCore.addBridge("CompoundTag.get", args -> { CompoundTag tag = (CompoundTag) args[0]; Tag obj = tag.get((String) args[1]); return toOut(obj); }); - Bridges.addBridge("CompoundTag.set", args -> { + ScriptCraftCore.addBridge("CompoundTag.set", args -> { CompoundTag tag = (CompoundTag) args[0]; tag.put((String) args[1], toTag(args[2], (String) args[3])); return null; }); - Bridges.addBridge("CompoundTag.keys", args -> { + ScriptCraftCore.addBridge("CompoundTag.keys", args -> { CompoundTag tag = (CompoundTag) args[0]; return tag.getKeys().toArray(new String[0]); }); - Bridges.addBridge("ListTag.get", args -> { + ScriptCraftCore.addBridge("ListTag.get", args -> { AbstractListTag tag = (AbstractListTag) args[0]; - Tag obj = tag.get((int) Util.toDouble(args[1], 0)); + Tag obj = tag.get((int) ValueUtil.toDouble(args[1], 0)); return toOut(obj); }); - Bridges.addBridge("ListTag.set", args -> { + ScriptCraftCore.addBridge("ListTag.set", args -> { AbstractListTag tag = (AbstractListTag) args[0]; - tag.set((int) Util.toDouble(args[1], 0), toTag(args[2], (String) args[3])); + tag.set((int) ValueUtil.toDouble(args[1], 0), toTag(args[2], (String) args[3])); return null; }); - Bridges.addBridge("ListTag.size", args -> { + ScriptCraftCore.addBridge("ListTag.size", args -> { AbstractListTag tag = (AbstractListTag) args[0]; return tag.size(); }); - Bridges.addBridge("CompoundTag.create", args -> new CompoundTag()); - Bridges.addBridge("ListTag.create", args -> new ListTag()); + ScriptCraftCore.addBridge("CompoundTag.create", args -> new CompoundTag()); + ScriptCraftCore.addBridge("ListTag.create", args -> new ListTag()); } } diff --git a/src/main/java/com/thebrokenrail/scriptcraft/api/bridge/WorldBridges.java b/src/main/java/com/thebrokenrail/scriptcraft/api/bridge/WorldBridges.java new file mode 100644 index 0000000..0f2428a --- /dev/null +++ b/src/main/java/com/thebrokenrail/scriptcraft/api/bridge/WorldBridges.java @@ -0,0 +1,64 @@ +package com.thebrokenrail.scriptcraft.api.bridge; + +import com.thebrokenrail.scriptcraft.api.block.CustomBlockEntity; +import com.thebrokenrail.scriptcraft.core.ScriptCraftCore; +import com.thebrokenrail.scriptcraft.core.ValueUtil; +import net.minecraft.block.BlockState; +import net.minecraft.block.entity.BlockEntity; +import net.minecraft.entity.Entity; +import net.minecraft.util.Identifier; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.registry.Registry; +import net.minecraft.world.World; + +import java.util.Objects; + +class WorldBridges { + static void register() { + ScriptCraftCore.addBridge("World.getBlockState", args -> ((World) args[0]).getBlockState(new BlockPos((double) args[1], (double) args[2], (double) args[3]))); + ScriptCraftCore.addBridge("World.setBlockState", args -> ((World) args[0]).setBlockState(new BlockPos((double) args[1], (double) args[2], (double) args[3]), (BlockState) args[4])); + + ScriptCraftCore.addBridge("World.spawnEntity", args -> { + Entity entity = Registry.ENTITY_TYPE.get(new Identifier((String) args[4])).create((World) args[0]); + if (entity != null) { + entity.updatePosition(ValueUtil.toDouble(args[1], 0), ValueUtil.toDouble(args[2], 0), ValueUtil.toDouble(args[3], 0)); + ((World) args[0]).spawnEntity(entity); + return entity; + } else { + return null; + } + }); + + ScriptCraftCore.addBridge("World.markBlockEntityDirty", args -> { + World world = (World) args[0]; + BlockPos pos = new BlockPos(ValueUtil.toDouble(args[1], 0), ValueUtil.toDouble(args[2], 0), ValueUtil.toDouble(args[3], 0)); + BlockEntity entity = world.getBlockEntity(pos); + if (entity != null) { + entity.markDirty(); + } + return null; + }); + + ScriptCraftCore.addBridge("World.getBlockEntity", args -> { + World world = (World) args[0]; + BlockPos pos = new BlockPos(ValueUtil.toDouble(args[1], 0), ValueUtil.toDouble(args[2], 0), ValueUtil.toDouble(args[3], 0)); + BlockEntity entity = world.getBlockEntity(pos); + if (entity != null) { + return Objects.requireNonNull(Registry.BLOCK_ENTITY_TYPE.getId(entity.getType())).toString(); + } else { + return null; + } + }); + + ScriptCraftCore.addBridge("World.getCustomBlockEntity", args -> { + World world = (World) args[0]; + BlockPos pos = new BlockPos(ValueUtil.toDouble(args[1], 0), ValueUtil.toDouble(args[2], 0), ValueUtil.toDouble(args[3], 0)); + BlockEntity entity = world.getBlockEntity(pos); + if (entity instanceof CustomBlockEntity) { + return ((CustomBlockEntity) entity).getObjID(); + } else { + return null; + } + }); + } +} diff --git a/src/main/java/com/thebrokenrail/scriptcraft/api/CustomItem.java b/src/main/java/com/thebrokenrail/scriptcraft/api/item/CustomItem.java similarity index 54% rename from src/main/java/com/thebrokenrail/scriptcraft/api/CustomItem.java rename to src/main/java/com/thebrokenrail/scriptcraft/api/item/CustomItem.java index 0fd5004..52459c8 100644 --- a/src/main/java/com/thebrokenrail/scriptcraft/api/CustomItem.java +++ b/src/main/java/com/thebrokenrail/scriptcraft/api/item/CustomItem.java @@ -1,7 +1,7 @@ -package com.thebrokenrail.scriptcraft.api; +package com.thebrokenrail.scriptcraft.api.item; -import com.thebrokenrail.scriptcraft.util.Util; -import com.thebrokenrail.scriptcraft.quickjs.QuickJSManager; +import com.thebrokenrail.scriptcraft.core.ValueUtil; +import com.thebrokenrail.scriptcraft.core.quickjs.QuickJSManager; import net.minecraft.entity.LivingEntity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.Item; @@ -24,17 +24,17 @@ public class CustomItem extends Item { @Override public TypedActionResult use(World world, PlayerEntity user, Hand hand) { ItemStack stack = user.getStackInHand(hand); - ActionResult result = Util.getEnumValue(ActionResult.class, (String) QuickJSManager.bridge("CustomItem.onUse", id.toString(), world, user, hand.name()), ActionResult.PASS); + ActionResult result = ValueUtil.getEnumValue(ActionResult.class, (String) QuickJSManager.bridge("CustomItem.onUse", id.toString(), world, user, hand.name()), ActionResult.PASS); return new TypedActionResult<>(result, stack); } @Override public ActionResult useOnBlock(ItemUsageContext context) { - return Util.getEnumValue(ActionResult.class, (String) QuickJSManager.bridge("CustomItem.onUseOnBlock", id.toString(), context.getWorld(), (double) context.getBlockPos().getX(), (double) context.getBlockPos().getY(), (double) context.getBlockPos().getZ(), context.getSide().name(), context.getPlayer(), context.getHand().name()), ActionResult.PASS); + return ValueUtil.getEnumValue(ActionResult.class, (String) QuickJSManager.bridge("CustomItem.onUseOnBlock", id.toString(), context.getWorld(), (double) context.getBlockPos().getX(), (double) context.getBlockPos().getY(), (double) context.getBlockPos().getZ(), context.getSide().name(), context.getPlayer(), context.getHand().name()), ActionResult.PASS); } @Override public boolean useOnEntity(ItemStack stack, PlayerEntity user, LivingEntity entity, Hand hand) { - return Util.toBoolean(QuickJSManager.bridge("CustomItem.onUseOnEntity", id.toString(), user, entity, hand.name()), false); + return ValueUtil.toBoolean(QuickJSManager.bridge("CustomItem.onUseOnEntity", id.toString(), user, entity, hand.name()), false); } } diff --git a/src/main/java/com/thebrokenrail/scriptcraft/bridge/BlockStateBridges.java b/src/main/java/com/thebrokenrail/scriptcraft/bridge/BlockStateBridges.java deleted file mode 100644 index 24c2b36..0000000 --- a/src/main/java/com/thebrokenrail/scriptcraft/bridge/BlockStateBridges.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.thebrokenrail.scriptcraft.bridge; - -import net.minecraft.block.BlockState; -import net.minecraft.util.Identifier; -import net.minecraft.util.registry.Registry; - -class BlockStateBridges { - static void register() { - Bridges.addBridge("BlockState.getDefaultState", args -> Registry.BLOCK.get(new Identifier((String) args[0])).getDefaultState()); - Bridges.addBridge("BlockState.getBlock", args -> Registry.BLOCK.getId(((BlockState) args[0]).getBlock()).toString()); - } -} diff --git a/src/main/java/com/thebrokenrail/scriptcraft/bridge/Bridges.java b/src/main/java/com/thebrokenrail/scriptcraft/bridge/Bridges.java deleted file mode 100644 index ff4c894..0000000 --- a/src/main/java/com/thebrokenrail/scriptcraft/bridge/Bridges.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.thebrokenrail.scriptcraft.bridge; - -import com.thebrokenrail.scriptcraft.quickjs.QuickJS; -import com.thebrokenrail.scriptcraft.quickjs.QuickJSManager; - -import java.util.HashMap; - -@SuppressWarnings("unused") -public class Bridges { - private static final HashMap bridges = new HashMap<>(); - - public static void addBridge(String name, Bridge bridge) { - bridges.put(name, bridge); - } - - public static Object useBridge(String name, Object... args) { - QuickJSManager.Task task = new QuickJSManager.Task() { - @Override - protected Object run(QuickJS quickjs) { - if (bridges.containsKey(name)) { - return bridges.get(name).use(args); - } else { - throw new RuntimeException("Invalid Bridge: '" + name + '\''); - } - } - }; - return QuickJSManager.sendTaskFromQuickJS(task); - } - - static { - BlockSettingsBridges.register(); - RegistryBridge.register(); - ItemStackBridges.register(); - LivingEntityBridges.register(); - BlockStateBridges.register(); - WorldBridges.register(); - ItemSettingsBridges.register(); - EntityBridges.register(); - DamageSourceBridges.register(); - TagBridges.register(); - } -} diff --git a/src/main/java/com/thebrokenrail/scriptcraft/bridge/EntityBridges.java b/src/main/java/com/thebrokenrail/scriptcraft/bridge/EntityBridges.java deleted file mode 100644 index f8a958f..0000000 --- a/src/main/java/com/thebrokenrail/scriptcraft/bridge/EntityBridges.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.thebrokenrail.scriptcraft.bridge; - -import com.thebrokenrail.scriptcraft.util.Util; -import net.minecraft.entity.Entity; -import net.minecraft.entity.damage.DamageSource; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.util.math.Vec3d; -import net.minecraft.util.registry.Registry; - -import java.util.Objects; - -class EntityBridges { - static void register() { - Bridges.addBridge("Entity.getEntityWorld", args -> ((Entity) args[0]).getEntityWorld()); - Bridges.addBridge("Entity.getID", args -> Registry.ENTITY_TYPE.getId(((Entity) args[0]).getType()).toString()); - - Bridges.addBridge("Entity.getName", args -> ((Entity) args[0]).getName().asString()); - Bridges.addBridge("Entity.getDisplayName", args -> ((Entity) args[0]).getDisplayName().asString()); - Bridges.addBridge("Entity.getCustomName", args -> ((Entity) args[0]).hasCustomName() ? Objects.requireNonNull(((Entity) args[0]).getCustomName()).asString() : null); - - Bridges.addBridge("Entity.kill", args -> { - ((Entity) args[0]).kill(); - return null; - }); - Bridges.addBridge("Entity.remove", args -> { - ((Entity) args[0]).remove(); - return null; - }); - Bridges.addBridge("Entity.damage", args -> ((Entity) args[0]).damage((DamageSource) args[1], (float) args[2])); - - Bridges.addBridge("Entity.setFireTicks", args -> { - ((Entity) args[0]).setFireTicks((int) args[1]); - return null; - }); - Bridges.addBridge("Entity.getFireTicks", args -> ((Entity) args[0]).getFireTicks()); - - Bridges.addBridge("Entity.getPosition", args -> { - Vec3d pos = ((Entity) args[0]).getPos(); - Double[] out = new Double[3]; - out[0] = pos.getX(); - out[1] = pos.getY(); - out[2] = pos.getZ(); - return out; - }); - Bridges.addBridge("Entity.setPosition", args -> { - ((Entity) args[0]).updatePosition(Util.toDouble(args[1], 0), Util.toDouble(args[2], 0), Util.toDouble(args[3], 0)); - return null; - }); - - Bridges.addBridge("Entity.toTag", args -> ((Entity) args[0]).toTag(new CompoundTag())); - Bridges.addBridge("Entity.fromTag", args -> { - ((Entity) args[0]).fromTag((CompoundTag) args[1]); - return null; - }); - } -} diff --git a/src/main/java/com/thebrokenrail/scriptcraft/bridge/ItemStackBridges.java b/src/main/java/com/thebrokenrail/scriptcraft/bridge/ItemStackBridges.java deleted file mode 100644 index 6a922a4..0000000 --- a/src/main/java/com/thebrokenrail/scriptcraft/bridge/ItemStackBridges.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.thebrokenrail.scriptcraft.bridge; - -import com.thebrokenrail.scriptcraft.util.Util; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.util.Identifier; -import net.minecraft.util.registry.Registry; - -class ItemStackBridges { - static void register() { - Bridges.addBridge("ItemStack.create", args -> new ItemStack(Registry.ITEM.get(new Identifier((String) args[0])), ((Double) args[1]).intValue())); - - Bridges.addBridge("ItemStack.getItem", args -> Registry.ITEM.getId(((ItemStack) args[0]).getItem()).toString()); - - Bridges.addBridge("ItemStack.setCount", args -> { - ((ItemStack) args[0]).setCount((int) Util.toDouble(args[1], 0)); - return null; - }); - Bridges.addBridge("ItemStack.getCount", args -> (double) ((ItemStack) args[0]).getCount()); - - Bridges.addBridge("ItemStack.setDamage", args -> { - ((ItemStack) args[0]).setDamage((int) Util.toDouble(args[1], 0)); - return null; - }); - Bridges.addBridge("ItemStack.getDamage", args -> (double) ((ItemStack) args[0]).getDamage()); - Bridges.addBridge("ItemStack.isDamageable", args -> ((ItemStack) args[0]).isDamageable()); - - Bridges.addBridge("ItemStack.getTag", args -> ((ItemStack) args[0]).getTag()); - Bridges.addBridge("ItemStack.setTag", args -> { - ((ItemStack) args[0]).setTag((CompoundTag) args[1]); - return null; - }); - - Bridges.addBridge("ItemStack.toTag", args -> ((ItemStack) args[0]).toTag(new CompoundTag())); - Bridges.addBridge("ItemStack.fromTag", args -> ItemStack.fromTag((CompoundTag) args[1])); - } -} diff --git a/src/main/java/com/thebrokenrail/scriptcraft/bridge/LivingEntityBridges.java b/src/main/java/com/thebrokenrail/scriptcraft/bridge/LivingEntityBridges.java deleted file mode 100644 index 816c0a6..0000000 --- a/src/main/java/com/thebrokenrail/scriptcraft/bridge/LivingEntityBridges.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.thebrokenrail.scriptcraft.bridge; - -import net.minecraft.entity.LivingEntity; -import net.minecraft.util.Hand; - -class LivingEntityBridges { - static void register() { - Bridges.addBridge("LivingEntity.getStackInHand", args -> ((LivingEntity) args[0]).getStackInHand((Hand) args[1])); - Bridges.addBridge("LivingEntity.getHealth", args -> ((LivingEntity) args[0]).getHealth()); - } -} diff --git a/src/main/java/com/thebrokenrail/scriptcraft/bridge/WorldBridges.java b/src/main/java/com/thebrokenrail/scriptcraft/bridge/WorldBridges.java deleted file mode 100644 index 964abc9..0000000 --- a/src/main/java/com/thebrokenrail/scriptcraft/bridge/WorldBridges.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.thebrokenrail.scriptcraft.bridge; - -import com.thebrokenrail.scriptcraft.util.Util; -import net.minecraft.block.BlockState; -import net.minecraft.block.entity.BlockEntity; -import net.minecraft.entity.Entity; -import net.minecraft.util.Identifier; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.registry.Registry; -import net.minecraft.world.World; - -import java.util.Objects; - -class WorldBridges { - static void register() { - Bridges.addBridge("World.getBlockState", args -> ((World) args[0]).getBlockState(new BlockPos((double) args[1], (double) args[2], (double) args[3]))); - Bridges.addBridge("World.setBlockState", args -> ((World) args[0]).setBlockState(new BlockPos((double) args[1], (double) args[2], (double) args[3]), (BlockState) args[4])); - - Bridges.addBridge("World.spawnEntity", args -> { - Entity entity = Registry.ENTITY_TYPE.get(new Identifier((String) args[4])).create((World) args[0]); - if (entity != null) { - entity.updatePosition(Util.toDouble(args[1], 0), Util.toDouble(args[2], 0), Util.toDouble(args[3], 0)); - ((World) args[0]).spawnEntity(entity); - return entity; - } else { - return null; - } - }); - - Bridges.addBridge("World.markBlockEntityDirty", args -> { - World world = (World) args[0]; - BlockPos pos = new BlockPos(Util.toDouble(args[1], 0), Util.toDouble(args[2], 0), Util.toDouble(args[3], 0)); - BlockEntity entity = world.getBlockEntity(pos); - if (entity != null) { - entity.markDirty(); - } - return null; - }); - - Bridges.addBridge("World.getBlockEntity", args -> { - World world = (World) args[0]; - BlockPos pos = new BlockPos(Util.toDouble(args[1], 0), Util.toDouble(args[2], 0), Util.toDouble(args[3], 0)); - BlockEntity entity = world.getBlockEntity(pos); - if (entity != null) { - return Objects.requireNonNull(Registry.BLOCK_ENTITY_TYPE.getId(entity.getType())).toString(); - } else { - return null; - } - }); - } -} diff --git a/src/main/java/com/thebrokenrail/scriptcraft/bridge/Bridge.java b/src/main/java/com/thebrokenrail/scriptcraft/core/Bridge.java similarity index 57% rename from src/main/java/com/thebrokenrail/scriptcraft/bridge/Bridge.java rename to src/main/java/com/thebrokenrail/scriptcraft/core/Bridge.java index 230b321..ea6bcea 100644 --- a/src/main/java/com/thebrokenrail/scriptcraft/bridge/Bridge.java +++ b/src/main/java/com/thebrokenrail/scriptcraft/core/Bridge.java @@ -1,4 +1,4 @@ -package com.thebrokenrail.scriptcraft.bridge; +package com.thebrokenrail.scriptcraft.core; public interface Bridge { Object use(Object... args); diff --git a/src/main/java/com/thebrokenrail/scriptcraft/util/OSUtil.java b/src/main/java/com/thebrokenrail/scriptcraft/core/OSUtil.java similarity index 97% rename from src/main/java/com/thebrokenrail/scriptcraft/util/OSUtil.java rename to src/main/java/com/thebrokenrail/scriptcraft/core/OSUtil.java index e3d625d..e4ffc66 100644 --- a/src/main/java/com/thebrokenrail/scriptcraft/util/OSUtil.java +++ b/src/main/java/com/thebrokenrail/scriptcraft/core/OSUtil.java @@ -1,4 +1,4 @@ -package com.thebrokenrail.scriptcraft.util; +package com.thebrokenrail.scriptcraft.core; import java.util.Locale; diff --git a/src/main/java/com/thebrokenrail/scriptcraft/core/ScriptCraftCore.java b/src/main/java/com/thebrokenrail/scriptcraft/core/ScriptCraftCore.java new file mode 100644 index 0000000..d09a5f3 --- /dev/null +++ b/src/main/java/com/thebrokenrail/scriptcraft/core/ScriptCraftCore.java @@ -0,0 +1,54 @@ +package com.thebrokenrail.scriptcraft.core; + +import com.thebrokenrail.scriptcraft.core.quickjs.QuickJSNative; +import com.thebrokenrail.scriptcraft.core.quickjs.QuickJSManager; +import net.fabricmc.loader.api.FabricLoader; + +import java.util.HashMap; +import java.util.List; +import java.util.regex.Pattern; + +@SuppressWarnings("unused") +public class ScriptCraftCore { + private static final HashMap bridges = new HashMap<>(); + + public static void addBridge(String name, Bridge bridge) { + bridges.put(name, bridge); + } + + public static Object useBridge(String name, Object... args) { + QuickJSManager.Task task = new QuickJSManager.Task() { + @Override + protected Object run(QuickJSNative quickjs) { + if (bridges.containsKey(name)) { + return bridges.get(name).use(args); + } else { + throw new RuntimeException("Invalid Bridge: '" + name + '\''); + } + } + }; + return QuickJSManager.sendTaskFromQuickJS(task); + } + + public static final String NAMESPACE = "scriptcraft"; + public static final Pattern MOD_ID_PATTERN = Pattern.compile("[a-z][a-z0-9-_]{1,63}"); + + public static void init() { + QuickJSManager.init(new QuickJSManager.Task() { + @Override + protected Object run(QuickJSNative quickjs) { + List mods = FabricLoader.getInstance().getEntrypoints(NAMESPACE, ScriptCraftEntrypoint.class); + for (ScriptCraftEntrypoint mod : mods) { + if (MOD_ID_PATTERN.matcher(mod.getModID()).matches()) { + if (mod.shouldAutoLoad()) { + quickjs.run("import '" + mod.getModID() + "';"); + } + } else { + throw new RuntimeException("Invalid Mod ID: " + mod.getModID()); + } + } + return null; + } + }); + } +} diff --git a/src/main/java/com/thebrokenrail/scriptcraft/util/ScriptCraftEntrypoint.java b/src/main/java/com/thebrokenrail/scriptcraft/core/ScriptCraftEntrypoint.java similarity index 78% rename from src/main/java/com/thebrokenrail/scriptcraft/util/ScriptCraftEntrypoint.java rename to src/main/java/com/thebrokenrail/scriptcraft/core/ScriptCraftEntrypoint.java index 5ede493..44524d8 100644 --- a/src/main/java/com/thebrokenrail/scriptcraft/util/ScriptCraftEntrypoint.java +++ b/src/main/java/com/thebrokenrail/scriptcraft/core/ScriptCraftEntrypoint.java @@ -1,4 +1,4 @@ -package com.thebrokenrail.scriptcraft.util; +package com.thebrokenrail.scriptcraft.core; public interface ScriptCraftEntrypoint { String getModID(); diff --git a/src/main/java/com/thebrokenrail/scriptcraft/util/Util.java b/src/main/java/com/thebrokenrail/scriptcraft/core/ValueUtil.java similarity index 92% rename from src/main/java/com/thebrokenrail/scriptcraft/util/Util.java rename to src/main/java/com/thebrokenrail/scriptcraft/core/ValueUtil.java index 2c08da4..ca93270 100644 --- a/src/main/java/com/thebrokenrail/scriptcraft/util/Util.java +++ b/src/main/java/com/thebrokenrail/scriptcraft/core/ValueUtil.java @@ -1,9 +1,9 @@ -package com.thebrokenrail.scriptcraft.util; +package com.thebrokenrail.scriptcraft.core; import java.util.Locale; @SuppressWarnings("UnnecessaryUnboxing") -public class Util { +public class ValueUtil { public static > T getEnumValue(Class clazz, String value, T defaultValue) { try { return Enum.valueOf(clazz, value.toUpperCase(Locale.ROOT)); diff --git a/src/main/java/com/thebrokenrail/scriptcraft/quickjs/JSException.java b/src/main/java/com/thebrokenrail/scriptcraft/core/quickjs/JSException.java similarity index 69% rename from src/main/java/com/thebrokenrail/scriptcraft/quickjs/JSException.java rename to src/main/java/com/thebrokenrail/scriptcraft/core/quickjs/JSException.java index aaf1597..71bab7b 100644 --- a/src/main/java/com/thebrokenrail/scriptcraft/quickjs/JSException.java +++ b/src/main/java/com/thebrokenrail/scriptcraft/core/quickjs/JSException.java @@ -1,4 +1,4 @@ -package com.thebrokenrail.scriptcraft.quickjs; +package com.thebrokenrail.scriptcraft.core.quickjs; public class JSException extends Exception { public JSException(String message) { diff --git a/src/main/java/com/thebrokenrail/scriptcraft/quickjs/QuickJSManager.java b/src/main/java/com/thebrokenrail/scriptcraft/core/quickjs/QuickJSManager.java similarity index 93% rename from src/main/java/com/thebrokenrail/scriptcraft/quickjs/QuickJSManager.java rename to src/main/java/com/thebrokenrail/scriptcraft/core/quickjs/QuickJSManager.java index 8288da6..a3ee5cb 100644 --- a/src/main/java/com/thebrokenrail/scriptcraft/quickjs/QuickJSManager.java +++ b/src/main/java/com/thebrokenrail/scriptcraft/core/quickjs/QuickJSManager.java @@ -1,10 +1,10 @@ -package com.thebrokenrail.scriptcraft.quickjs; +package com.thebrokenrail.scriptcraft.core.quickjs; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; public class QuickJSManager { - private static QuickJS quickjs; + private static QuickJSNative quickjs; public static abstract class Task { private boolean lastTask = false; @@ -12,7 +12,7 @@ public class QuickJSManager { private boolean err; private Object obj; - protected abstract Object run(QuickJS quickjs) throws JSException; + protected abstract Object run(QuickJSNative quickjs) throws JSException; } private static Thread thread; @@ -83,7 +83,7 @@ public class QuickJSManager { private void init() { try { - quickjs = new QuickJS(); + quickjs = new QuickJSNative(); synchronized (startedLock) { startedLock.notifyAll(); } @@ -124,7 +124,7 @@ public class QuickJSManager { started.set(false); Task task = new Task() { @Override - protected Object run(QuickJS quickjs) { + protected Object run(QuickJSNative quickjs) { System.out.println("Freeing QuickJS"); quickjs.free(); return null; @@ -181,7 +181,7 @@ public class QuickJSManager { public static Object bridge(String method, Object... args) { Task task = new Task() { @Override - protected Object run(QuickJS quickjs) throws JSException { + protected Object run(QuickJSNative quickjs) throws JSException { return quickjs.bridge(method, args); } }; diff --git a/src/main/java/com/thebrokenrail/scriptcraft/quickjs/QuickJS.java b/src/main/java/com/thebrokenrail/scriptcraft/core/quickjs/QuickJSModules.java similarity index 60% rename from src/main/java/com/thebrokenrail/scriptcraft/quickjs/QuickJS.java rename to src/main/java/com/thebrokenrail/scriptcraft/core/quickjs/QuickJSModules.java index 2490a5e..9c77cd4 100644 --- a/src/main/java/com/thebrokenrail/scriptcraft/quickjs/QuickJS.java +++ b/src/main/java/com/thebrokenrail/scriptcraft/core/quickjs/QuickJSModules.java @@ -1,8 +1,7 @@ -package com.thebrokenrail.scriptcraft.quickjs; +package com.thebrokenrail.scriptcraft.core.quickjs; -import com.thebrokenrail.scriptcraft.ScriptCraft; -import com.thebrokenrail.scriptcraft.util.OSUtil; -import com.thebrokenrail.scriptcraft.util.ScriptCraftEntrypoint; +import com.thebrokenrail.scriptcraft.core.ScriptCraftCore; +import com.thebrokenrail.scriptcraft.core.ScriptCraftEntrypoint; import net.fabricmc.loader.api.FabricLoader; import java.io.BufferedReader; @@ -11,50 +10,17 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; -import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.nio.file.StandardCopyOption; +import java.util.Arrays; import java.util.List; @SuppressWarnings("unused") -public class QuickJS { - public QuickJS() throws JSException { - init(); - } - - private long ctx; - private long rt; - - public native void init() throws JSException; - - public native void free(); - - public native Object bridge(String method, Object... args) throws JSException; - - public native void run(String data); - - static { - try { - File file = File.createTempFile("lib" + ScriptCraft.NAMESPACE, OSUtil.getLibExtension()); - file.deleteOnExit(); - System.out.println("Extracting ScriptCraft Native To: " + file.getAbsoluteFile().toPath()); - InputStream so = (QuickJS.class.getResourceAsStream(File.separator + "natives" + File.separator + OSUtil.getOS() + File.separator + "lib" + ScriptCraft.NAMESPACE + OSUtil.getLibExtension())); - if (so == null) { - throw new RuntimeException("ScriptCraft does not support your OS: " + OSUtil.getOS()); - } else { - Files.copy(so, file.getAbsoluteFile().toPath(), StandardCopyOption.REPLACE_EXISTING); - System.load(file.getAbsolutePath()); - } - } catch (IOException e) { - throw new RuntimeException(e); - } - } - +public class QuickJSModules { public static String loadModule(String name) { String[] arr = name.split(File.separator, 2); - if (ScriptCraft.MOD_ID_PATTERN.matcher(arr[0]).matches()) { - List mods = FabricLoader.getInstance().getEntrypoints(ScriptCraft.NAMESPACE, ScriptCraftEntrypoint.class); + if (ScriptCraftCore.MOD_ID_PATTERN.matcher(arr[0]).matches()) { + List mods = FabricLoader.getInstance().getEntrypoints(ScriptCraftCore.NAMESPACE, ScriptCraftEntrypoint.class); if (arr.length == 1) { return null; } else { @@ -62,7 +28,7 @@ public class QuickJS { if (mod.getModID().equals(arr[0])) { //noinspection CatchMayIgnoreException try { - InputStream stream = mod.getClass().getResourceAsStream(File.separator + ScriptCraft.NAMESPACE + File.separator + arr[0] + File.separator + arr[1]); + InputStream stream = mod.getClass().getResourceAsStream(File.separator + ScriptCraftCore.NAMESPACE + File.separator + arr[0] + File.separator + arr[1]); if (stream != null) { StringBuilder textBuilder = new StringBuilder(); @@ -86,8 +52,13 @@ public class QuickJS { } private static final String[] SUPPORTED_EXTENSION = new String[]{"", ".js", ".json", ".mjs"}; + private static final String[] BUILTIN_MODULES = new String[]{"scriptcraft-core"}; public static String normalizeModule(String baseName, String name) { + if (Arrays.asList(BUILTIN_MODULES).contains(name)) { + return name; + } + String normalizedPath; if (name.startsWith(".")) { @@ -107,8 +78,8 @@ public class QuickJS { boolean success = false; String[] arr = normalizedPath.split(File.separator, 2); - if (ScriptCraft.MOD_ID_PATTERN.matcher(arr[0]).matches()) { - List mods = FabricLoader.getInstance().getEntrypoints(ScriptCraft.NAMESPACE, ScriptCraftEntrypoint.class); + if (ScriptCraftCore.MOD_ID_PATTERN.matcher(arr[0]).matches()) { + List mods = FabricLoader.getInstance().getEntrypoints(ScriptCraftCore.NAMESPACE, ScriptCraftEntrypoint.class); if (arr.length == 1) { for (ScriptCraftEntrypoint mod : mods) { if (mod.getModID().equals(arr[0])) { @@ -133,15 +104,4 @@ public class QuickJS { return null; } - - public static void print(String data, boolean err) { - String[] lines = data.split("\n"); - for (String line : lines) { - if (err) { - System.err.println(line); - } else { - System.out.println(line); - } - } - } } diff --git a/src/main/java/com/thebrokenrail/scriptcraft/core/quickjs/QuickJSNative.java b/src/main/java/com/thebrokenrail/scriptcraft/core/quickjs/QuickJSNative.java new file mode 100644 index 0000000..c48c7d9 --- /dev/null +++ b/src/main/java/com/thebrokenrail/scriptcraft/core/quickjs/QuickJSNative.java @@ -0,0 +1,56 @@ +package com.thebrokenrail.scriptcraft.core.quickjs; + +import com.thebrokenrail.scriptcraft.core.OSUtil; +import com.thebrokenrail.scriptcraft.core.ScriptCraftCore; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.StandardCopyOption; + +@SuppressWarnings("unused") +public class QuickJSNative { + public QuickJSNative() throws JSException { + init(); + } + + private long ctx; + private long rt; + + public native void init() throws JSException; + + public native void free(); + + public native Object bridge(String method, Object... args) throws JSException; + + public native void run(String data); + + static { + try { + File file = File.createTempFile("lib" + ScriptCraftCore.NAMESPACE, OSUtil.getLibExtension()); + file.deleteOnExit(); + System.out.println("Extracting ScriptCraft Native To: " + file.getAbsoluteFile().toPath()); + InputStream so = (QuickJSNative.class.getResourceAsStream(File.separator + "natives" + File.separator + OSUtil.getOS() + File.separator + "lib" + ScriptCraftCore.NAMESPACE + OSUtil.getLibExtension())); + if (so == null) { + throw new RuntimeException("ScriptCraft does not support your OS: " + OSUtil.getOS()); + } else { + Files.copy(so, file.getAbsoluteFile().toPath(), StandardCopyOption.REPLACE_EXISTING); + System.load(file.getAbsolutePath()); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + public static void print(String data, boolean err) { + String[] lines = data.split("\n"); + for (String line : lines) { + if (err) { + System.err.println(line); + } else { + System.out.println(line); + } + } + } +} diff --git a/src/main/java/com/thebrokenrail/scriptcraft/util/MinecraftAPIEntrypoint.java b/src/main/java/com/thebrokenrail/scriptcraft/util/MinecraftAPIEntrypoint.java deleted file mode 100644 index c8880be..0000000 --- a/src/main/java/com/thebrokenrail/scriptcraft/util/MinecraftAPIEntrypoint.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.thebrokenrail.scriptcraft.util; - -public class MinecraftAPIEntrypoint implements ScriptCraftEntrypoint { - @Override - public String getModID() { - return "minecraft"; - } - - @Override - public String getModIndex() { - return "index"; - } - - @Override - public boolean shouldAutoLoad() { - return false; - } -} diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 1ca9663..ec33ec1 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -20,7 +20,7 @@ "com.thebrokenrail.scriptcraft.ScriptCraft" ], "scriptcraft": [ - "com.thebrokenrail.scriptcraft.util.MinecraftAPIEntrypoint", + "com.thebrokenrail.scriptcraft.api.ScriptCraftAPI", "com.thebrokenrail.scriptcraft.Demo" ] }, diff --git a/src/main/resources/scriptcraft/.prettierrc b/src/main/resources/scriptcraft/.prettierrc index 0e98f6a..8624f77 100644 --- a/src/main/resources/scriptcraft/.prettierrc +++ b/src/main/resources/scriptcraft/.prettierrc @@ -4,5 +4,5 @@ "semi": true, "singleQuote": true, "arrowParens": "avoid", - "printWidth": 2400 + "printWidth": 24000 } \ No newline at end of file diff --git a/src/main/resources/scriptcraft/minecraft/block.ts b/src/main/resources/scriptcraft/minecraft/block.ts index f30cd8e..f60965e 100644 --- a/src/main/resources/scriptcraft/minecraft/block.ts +++ b/src/main/resources/scriptcraft/minecraft/block.ts @@ -1,7 +1,8 @@ import { World } from './world'; import { PlayerEntity } from './entity'; -import { useBridge, addBridge, Identifier, Hand, Pos, ActionResult, Direction, SimpleRegistry } from './core'; +import { Identifier, Hand, Pos, ActionResult, Direction, SimpleRegistry } from './core'; import { CompoundTag } from './tag'; +import { useBridge, addBridge } from 'scriptcraft-core'; /** * Settings for {@link CustomBlock} @@ -233,11 +234,11 @@ export class BlockRegistry implements SimpleRegistry { #blocks: Map; - #blockEntities: Map; + #blockEntities: CustomBlockEntity[]; private constructor() { this.#blocks = new Map(); - this.#blockEntities = new Map(); + this.#blockEntities = []; } register(id: Identifier, obj: CustomBlock) { @@ -262,29 +263,21 @@ export class BlockRegistry implements SimpleRegistry { return null; } - getCustomBlockEntity(id: Identifier, i: number): CustomBlockEntity { - return this.#blockEntities.get(id.toString())[i]; + getCustomBlockEntity(i: number): CustomBlockEntity { + return this.#blockEntities[i]; } getCustomBlockEntities(): CustomBlockEntity[] { - let out: CustomBlockEntity[] = []; - for (const key of this.#blockEntities.keys()) { - const list = this.#blockEntities.get(key); - out = out.concat(list); - } - return out; + return this.#blockEntities; } createCustomBlockEntity(id: Identifier, i: number) { const block = this.get(id) as CustomBlockWithEntity; - if (!this.#blockEntities.get(id.toString())) { - this.#blockEntities.set(id.toString(), []); - } - this.#blockEntities.get(id.toString()).push(block.createBlockEntity()); + this.#blockEntities[this.#blockEntities.length] = (block.createBlockEntity()); } - freeCustomBlockEntity(id: Identifier, i: number) { - delete this.#blockEntities.get(id.toString())[i]; + freeCustomBlockEntity(i: number) { + delete this.#blockEntities[i]; } } @@ -292,27 +285,25 @@ addBridge('CustomBlockEntity.create', (id: string, i: number) => { BlockRegistry.INSTANCE.createCustomBlockEntity(new Identifier(id), i); }); -addBridge('CustomBlockEntity.fromTag', (id: string, i: number, tag: JavaObject) => { - BlockRegistry.INSTANCE.getCustomBlockEntity(new Identifier(id), i).fromTag(new CompoundTag(tag)); +addBridge('CustomBlockEntity.fromTag', (i: number, tag: JavaObject) => { + BlockRegistry.INSTANCE.getCustomBlockEntity(i).fromTag(new CompoundTag(tag)); }); -addBridge( - 'CustomBlockEntity.toTag', - (id: string, i: number, tag: JavaObject): JavaObject => { - return BlockRegistry.INSTANCE.getCustomBlockEntity(new Identifier(id), i).toTag(new CompoundTag(tag)).javaObject; +addBridge('CustomBlockEntity.toTag', ( i: number, tag: JavaObject): JavaObject => { + return BlockRegistry.INSTANCE.getCustomBlockEntity(i).toTag(new CompoundTag(tag)).javaObject; } ); -addBridge('CustomBlockEntity.tick', (id: string, i: number) => { - BlockRegistry.INSTANCE.getCustomBlockEntity(new Identifier(id), i).tick(); +addBridge('CustomBlockEntity.tick', (i: number) => { + BlockRegistry.INSTANCE.getCustomBlockEntity(i).tick(); }); -addBridge('CustomBlockEntity.setLocation', (id: string, i: number, world: JavaObject, x: number, y: number, z: number) => { - BlockRegistry.INSTANCE.getCustomBlockEntity(new Identifier(id), i).setLocation(new World(world), new Pos(x, y, z)); +addBridge('CustomBlockEntity.setLocation', (i: number, world: JavaObject, x: number, y: number, z: number) => { + BlockRegistry.INSTANCE.getCustomBlockEntity(i).setLocation(new World(world), new Pos(x, y, z)); }); -addBridge('CustomBlockEntity.free', (id: string, i: number) => { - BlockRegistry.INSTANCE.freeCustomBlockEntity(new Identifier(id), i); +addBridge('CustomBlockEntity.free', (i: number) => { + BlockRegistry.INSTANCE.freeCustomBlockEntity(i); }); addBridge('CustomBlock.onUse', (id: string, world: JavaObject, state: JavaObject, x: number, y: number, z: number, side: keyof typeof Direction, player: JavaObject, hand: keyof typeof Hand): string => { diff --git a/src/main/resources/scriptcraft/minecraft/core.ts b/src/main/resources/scriptcraft/minecraft/core.ts index 7c76e01..6d3facd 100644 --- a/src/main/resources/scriptcraft/minecraft/core.ts +++ b/src/main/resources/scriptcraft/minecraft/core.ts @@ -1,17 +1,3 @@ -/** - * @internal - */ -export function addBridge(name: string, bridge: BridgeType) { - __scriptcraft__.bridges[name] = bridge; -} - -/** - * @internal - */ -export function useBridge(name: string, ...args: BridgeValueType[]): BridgeValueType { - return __scriptcraft__.useBridge(name, ...args); -} - /** * Action Result */ diff --git a/src/main/resources/scriptcraft/minecraft/entity.ts b/src/main/resources/scriptcraft/minecraft/entity.ts index 86e5fbd..fba13e2 100644 --- a/src/main/resources/scriptcraft/minecraft/entity.ts +++ b/src/main/resources/scriptcraft/minecraft/entity.ts @@ -1,7 +1,8 @@ import { ItemStack } from './item'; -import { useBridge, Hand, Identifier, Pos } from './core'; +import { Hand, Identifier, Pos } from './core'; import { World } from './world'; import { CompoundTag } from './tag'; +import { useBridge } from 'scriptcraft-core'; /** * Damage Source diff --git a/src/main/resources/scriptcraft/minecraft/item.ts b/src/main/resources/scriptcraft/minecraft/item.ts index 0e222d7..e074fb1 100644 --- a/src/main/resources/scriptcraft/minecraft/item.ts +++ b/src/main/resources/scriptcraft/minecraft/item.ts @@ -1,7 +1,8 @@ -import { useBridge, Identifier, Hand, ActionResult, addBridge, Pos, Direction, SimpleRegistry } from './core'; +import { Identifier, Hand, ActionResult, Pos, Direction, SimpleRegistry } from './core'; import { World } from './world'; import { PlayerEntity, LivingEntity } from './entity'; import { CompoundTag } from './tag'; +import { useBridge, addBridge } from 'scriptcraft-core'; /** * Item Stack diff --git a/src/main/resources/scriptcraft/minecraft/registry.ts b/src/main/resources/scriptcraft/minecraft/registry.ts index 9f3ceda..7c26136 100644 --- a/src/main/resources/scriptcraft/minecraft/registry.ts +++ b/src/main/resources/scriptcraft/minecraft/registry.ts @@ -1,6 +1,6 @@ import { Identifier, SimpleRegistry } from './core'; -import { BlockRegistry } from './block'; -import { ItemRegistry } from './item'; +import { BlockRegistry, CustomBlock } from './block'; +import { ItemRegistry, CustomItem, BlockItem } from './item'; /** * Registry @@ -9,11 +9,11 @@ export abstract class Registry { /** * Block Registry */ - static BLOCK = BlockRegistry.INSTANCE; + static BLOCK: SimpleRegistry = BlockRegistry.INSTANCE; /** * Item Registry */ - static ITEM = ItemRegistry.INSTANCE; + static ITEM: SimpleRegistry = ItemRegistry.INSTANCE; /** * Register Object diff --git a/src/main/resources/scriptcraft/minecraft/tag.ts b/src/main/resources/scriptcraft/minecraft/tag.ts index f96d2fe..d160586 100644 --- a/src/main/resources/scriptcraft/minecraft/tag.ts +++ b/src/main/resources/scriptcraft/minecraft/tag.ts @@ -1,4 +1,4 @@ -import { useBridge } from './core'; +import { useBridge } from 'scriptcraft-core'; type TagType = number | boolean | string | CompoundTag | ListTag; diff --git a/src/main/resources/scriptcraft/minecraft/world.ts b/src/main/resources/scriptcraft/minecraft/world.ts index 5f875a4..5544483 100644 --- a/src/main/resources/scriptcraft/minecraft/world.ts +++ b/src/main/resources/scriptcraft/minecraft/world.ts @@ -1,6 +1,7 @@ import { BlockState, CustomBlockEntity, BlockRegistry } from './block'; import { Entity } from './entity'; -import { useBridge, Pos, Identifier } from './core'; +import { Pos, Identifier } from './core'; +import { useBridge } from 'scriptcraft-core'; /** * World @@ -56,26 +57,18 @@ export class World { } } - /** - * @internal - */ - private getCustomBlockEntities(): CustomBlockEntity[] { - return BlockRegistry.INSTANCE.getCustomBlockEntities(); - } - /** * Get Custom Block Entity At Position * @param pos Position * @returns Custom Block Entity At Position */ getCustomBlockEntity(pos: Pos): CustomBlockEntity { - const list = this.getCustomBlockEntities(); - for (const entity of list) { - if (pos.equals(entity.getPos())) { - return entity; - } + const obj = useBridge('World.getBlockEntity', this.javaObject, pos.getX(), pos.getY(), pos.getZ()) as number; + if (obj) { + return BlockRegistry.INSTANCE.getCustomBlockEntity(obj); + } else { + return null; } - return null; } /** diff --git a/src/main/resources/scriptcraft/test/index.ts b/src/main/resources/scriptcraft/test/index.ts index 3bf6cb8..f085d9c 100644 --- a/src/main/resources/scriptcraft/test/index.ts +++ b/src/main/resources/scriptcraft/test/index.ts @@ -3,7 +3,7 @@ import { BlockSettings, Identifier, Registry, BlockState, ActionResult, World, P console.log('hello'); class MyBlockEntity extends CustomBlockEntity { - ticks: number; + ticks = 0; toTag(tag: CompoundTag): CompoundTag { tag.set('MyTicks', this.ticks, NumberType.INT); diff --git a/src/main/resources/scriptcraft/tsconfig.json b/src/main/resources/scriptcraft/tsconfig.json index 55f600f..9bc5cc0 100644 --- a/src/main/resources/scriptcraft/tsconfig.json +++ b/src/main/resources/scriptcraft/tsconfig.json @@ -15,6 +15,6 @@ } }, "include": [ - "**/*.ts" + "**/*" ] } \ No newline at end of file diff --git a/src/main/resources/scriptcraft/typedoc.json b/src/main/resources/scriptcraft/typedoc.json index 5fb920f..af09caa 100644 --- a/src/main/resources/scriptcraft/typedoc.json +++ b/src/main/resources/scriptcraft/typedoc.json @@ -2,8 +2,8 @@ "name": "ScriptCraft API", "mode": "modules", "readme": "none", + "excludeExternals": true, "excludeNotExported": true, "excludePrivate": true, - "excludeExternals": true, "stripInternal": true } \ No newline at end of file diff --git a/src/main/resources/scriptcraft/types/scriptcraft/index.d.ts b/src/main/resources/scriptcraft/types/scriptcraft/index.d.ts index f53efe7..d1d9a0a 100644 --- a/src/main/resources/scriptcraft/types/scriptcraft/index.d.ts +++ b/src/main/resources/scriptcraft/types/scriptcraft/index.d.ts @@ -26,3 +26,9 @@ interface Console { } declare const console: Console; + +declare module 'scriptcraft-core' { + function addBridge(name: string, bridge: BridgeType): void; + + function useBridge(name: string, ...args: BridgeValueType[]): BridgeValueType; +} \ No newline at end of file