This commit is contained in:
parent
afeea22abe
commit
aa8e3f5e2b
@ -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)
|
||||
|
@ -6,19 +6,19 @@
|
||||
#include <cutils.h>
|
||||
#include <quickjs.h>
|
||||
|
||||
#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);
|
@ -0,0 +1,47 @@
|
||||
/* DO NOT EDIT THIS FILE - it is machine generated */
|
||||
#include <jni.h>
|
||||
/* 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
|
@ -1,47 +0,0 @@
|
||||
/* DO NOT EDIT THIS FILE - it is machine generated */
|
||||
#include <jni.h>
|
||||
/* 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
|
@ -4,7 +4,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <quickjs.h>
|
||||
|
||||
#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;
|
||||
|
@ -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
|
||||
|
@ -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<ScriptCraftEntrypoint> 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();
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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<Identifier, Integer> 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;
|
||||
}
|
||||
}
|
@ -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;
|
@ -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);
|
@ -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());
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
@ -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]));
|
||||
}
|
||||
}
|
@ -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;
|
||||
});
|
||||
}
|
||||
}
|
@ -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());
|
@ -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]));
|
||||
}
|
||||
}
|
@ -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());
|
||||
}
|
||||
}
|
@ -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;
|
||||
});
|
@ -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());
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@ -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<ItemStack> 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);
|
||||
}
|
||||
}
|
@ -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());
|
||||
}
|
||||
}
|
@ -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<String, Bridge> 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();
|
||||
}
|
||||
}
|
@ -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;
|
||||
});
|
||||
}
|
||||
}
|
@ -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]));
|
||||
}
|
||||
}
|
@ -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());
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package com.thebrokenrail.scriptcraft.bridge;
|
||||
package com.thebrokenrail.scriptcraft.core;
|
||||
|
||||
public interface Bridge {
|
||||
Object use(Object... args);
|
@ -1,4 +1,4 @@
|
||||
package com.thebrokenrail.scriptcraft.util;
|
||||
package com.thebrokenrail.scriptcraft.core;
|
||||
|
||||
import java.util.Locale;
|
||||
|
@ -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<String, Bridge> 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<ScriptCraftEntrypoint> 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;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package com.thebrokenrail.scriptcraft.util;
|
||||
package com.thebrokenrail.scriptcraft.core;
|
||||
|
||||
public interface ScriptCraftEntrypoint {
|
||||
String getModID();
|
@ -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 extends Enum<T>> T getEnumValue(Class<T> clazz, String value, T defaultValue) {
|
||||
try {
|
||||
return Enum.valueOf(clazz, value.toUpperCase(Locale.ROOT));
|
@ -1,4 +1,4 @@
|
||||
package com.thebrokenrail.scriptcraft.quickjs;
|
||||
package com.thebrokenrail.scriptcraft.core.quickjs;
|
||||
|
||||
public class JSException extends Exception {
|
||||
public JSException(String message) {
|
@ -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);
|
||||
}
|
||||
};
|
@ -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<ScriptCraftEntrypoint> mods = FabricLoader.getInstance().getEntrypoints(ScriptCraft.NAMESPACE, ScriptCraftEntrypoint.class);
|
||||
if (ScriptCraftCore.MOD_ID_PATTERN.matcher(arr[0]).matches()) {
|
||||
List<ScriptCraftEntrypoint> 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<ScriptCraftEntrypoint> mods = FabricLoader.getInstance().getEntrypoints(ScriptCraft.NAMESPACE, ScriptCraftEntrypoint.class);
|
||||
if (ScriptCraftCore.MOD_ID_PATTERN.matcher(arr[0]).matches()) {
|
||||
List<ScriptCraftEntrypoint> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -20,7 +20,7 @@
|
||||
"com.thebrokenrail.scriptcraft.ScriptCraft"
|
||||
],
|
||||
"scriptcraft": [
|
||||
"com.thebrokenrail.scriptcraft.util.MinecraftAPIEntrypoint",
|
||||
"com.thebrokenrail.scriptcraft.api.ScriptCraftAPI",
|
||||
"com.thebrokenrail.scriptcraft.Demo"
|
||||
]
|
||||
},
|
||||
|
@ -4,5 +4,5 @@
|
||||
"semi": true,
|
||||
"singleQuote": true,
|
||||
"arrowParens": "avoid",
|
||||
"printWidth": 2400
|
||||
"printWidth": 24000
|
||||
}
|
@ -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<CustomBlock> {
|
||||
|
||||
#blocks: Map<string, CustomBlock>;
|
||||
|
||||
#blockEntities: Map<string, CustomBlockEntity[]>;
|
||||
#blockEntities: CustomBlockEntity[];
|
||||
|
||||
private constructor() {
|
||||
this.#blocks = new Map<string, CustomBlock>();
|
||||
this.#blockEntities = new Map<string, CustomBlockEntity[]>();
|
||||
this.#blockEntities = [];
|
||||
}
|
||||
|
||||
register(id: Identifier, obj: CustomBlock) {
|
||||
@ -262,29 +263,21 @@ export class BlockRegistry implements SimpleRegistry<CustomBlock> {
|
||||
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 => {
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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<CustomBlock> = BlockRegistry.INSTANCE;
|
||||
/**
|
||||
* Item Registry
|
||||
*/
|
||||
static ITEM = ItemRegistry.INSTANCE;
|
||||
static ITEM: SimpleRegistry<CustomItem | BlockItem> = ItemRegistry.INSTANCE;
|
||||
|
||||
/**
|
||||
* Register Object
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { useBridge } from './core';
|
||||
import { useBridge } from 'scriptcraft-core';
|
||||
|
||||
type TagType = number | boolean | string | CompoundTag | ListTag;
|
||||
|
||||
|
@ -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,27 +57,19 @@ 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;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Block Entity ID At Position
|
||||
|
@ -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);
|
||||
|
@ -15,6 +15,6 @@
|
||||
}
|
||||
},
|
||||
"include": [
|
||||
"**/*.ts"
|
||||
"**/*"
|
||||
]
|
||||
}
|
@ -2,8 +2,8 @@
|
||||
"name": "ScriptCraft API",
|
||||
"mode": "modules",
|
||||
"readme": "none",
|
||||
"excludeExternals": true,
|
||||
"excludeNotExported": true,
|
||||
"excludePrivate": true,
|
||||
"excludeExternals": true,
|
||||
"stripInternal": true
|
||||
}
|
@ -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;
|
||||
}
|
Reference in New Issue
Block a user