kitgit

tirbofish/dropbear · commit

d45784d3a9abe8cc557478b45e3b8c6b13a69610

got the JDB and debugging working pretty nicely, as well as some additional fixes+tweaks.

Unverified

tk <4tkbytes@pm.me> · 2025-10-16 11:47

view full diff

diff --git a/build.gradle.kts b/build.gradle.kts
index d40bd31..53dfe23 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -1,3 +1,5 @@
+import org.jetbrains.kotlin.gradle.targets.jvm.KotlinJvmTarget
+
 plugins {
     alias(libs.plugins.kotlinMultiplatform)
     alias(libs.plugins.kotlinxSerialization)
@@ -13,7 +15,9 @@ repositories {
 }
 
 kotlin {
-    jvm()
+    jvm {
+        withJava()
+    }
 
     val hostOs = System.getProperty("os.name")
     val isArm64 = System.getProperty("os.arch") == "aarch64"
@@ -102,7 +106,7 @@ kotlin {
         }
 
         jvmMain {
-            kotlin.srcDirs("src/jvmMain/kotlin", "src/jvmMain/java", "build/magna-carta")
+            kotlin.srcDirs("src/jvmMain/kotlin", "build/magna-carta")
             dependencies {
 
             }
diff --git a/eucalyptus-core/Cargo.toml b/eucalyptus-core/Cargo.toml
index d7fbc51..532c2af 100644
--- a/eucalyptus-core/Cargo.toml
+++ b/eucalyptus-core/Cargo.toml
@@ -30,8 +30,8 @@ rayon.workspace = true
 jni.workspace = true
 crossbeam-channel = "0.5.15"
 libloading = "0.8.9"
-tokio-util = "0.7"
 app_dirs2.workspace = true
+sha2 = "0.10"
 
 [features]
 # editor only stuff
diff --git a/eucalyptus-core/src/scripting.rs b/eucalyptus-core/src/scripting.rs
index 2708b83..8a3b69f 100644
--- a/eucalyptus-core/src/scripting.rs
+++ b/eucalyptus-core/src/scripting.rs
@@ -112,9 +112,9 @@ impl ScriptManager {
         _input_state: &InputState,
     ) -> anyhow::Result<()> {
         match &self.script_target {
-            ScriptTarget::JVM { library_path } => {
+            ScriptTarget::JVM { library_path: _ } => {
                 if let Some(jvm) = &mut self.jvm {
-                    jvm.init(library_path, world)?;
+                    jvm.init(world)?;
                     for tag in self.entity_tag_database.keys() {
                         log::trace!("Loading systems for tag: {}", tag);
                         jvm.load_systems_for_tag(tag)?;
diff --git a/eucalyptus-core/src/scripting/jni.rs b/eucalyptus-core/src/scripting/jni.rs
index fb0f0bd..e321b1b 100644
--- a/eucalyptus-core/src/scripting/jni.rs
+++ b/eucalyptus-core/src/scripting/jni.rs
@@ -3,14 +3,16 @@
 
 pub mod exception;
 
+use std::fs;
 use dropbear_engine::entity::AdoptedEntity;
 use hecs::World;
-use jni::objects::{GlobalRef, JClass, JObject, JString, JThrowable, JValue, JValueGen};
+use jni::objects::{GlobalRef, JClass, JString, JValue};
 use jni::sys::jlong;
 use jni::sys::jobject;
 use jni::{InitArgsBuilder, JNIEnv, JNIVersion, JavaVM};
-use std::path::{Path, PathBuf};
-use crate::{info, APP_INFO};
+use std::path::{PathBuf};
+use crate::{success, APP_INFO};
+use sha2::{Digest, Sha256};
 use crate::logging::{LOG_LEVEL};
 use crate::ptr::WorldPtr;
 use crate::scripting::jni::exception::get_exception_info;
@@ -30,17 +32,46 @@ impl JavaContext {
     pub fn new() -> anyhow::Result<Self> {
         let root = app_dirs2::app_root(app_dirs2::AppDataType::UserData, &APP_INFO)?;
         let deps = root.join("dependencies");
-        let host_jar_filename = "dropbear-1.0-SNAPSHOT-all.jar";
+        let host_jar_filename = "dropbear-jvm-fat-1.0-SNAPSHOT.jar";
         let host_jar_path = deps.join(host_jar_filename);
-
-        std::fs::create_dir_all(&deps)?;
-
-        if !host_jar_path.exists() {
-            log::info!("Host library JAR not found at {:?}, writing embedded JAR.", host_jar_path);
-            std::fs::write(&host_jar_path, LIBRARY_PATH)?;
-            log::info!("Host library JAR written to {:?}", host_jar_path);
+        let hash_filename = format!("{}.sha256", host_jar_filename);
+        let hash_file_path = deps.join(hash_filename);
+
+        fs::create_dir_all(&deps)?;
+
+        let embedded_jar_hash = {
+            let mut hasher = Sha256::new();
+            hasher.update(LIBRARY_PATH);
+            format!("{:x}", hasher.finalize())
+        };
+
+        let stored_hash = fs::read_to_string(&hash_file_path).ok();
+
+        let should_update = match stored_hash {
+            Some(stored) => {
+                if stored.trim() == embedded_jar_hash {
+                    log::debug!("Host library JAR hash matches stored hash. No update needed.");
+                    false
+                } else {
+                    log::info!("Host library JAR hash differs from stored hash. Update required.");
+                    true
+                }
+            }
+            None => {
+                log::info!("Host library JAR hash file not found. Update required.");
+                true
+            }
+        };
+
+        if should_update {
+            log::info!("Writing (or updating) Host library JAR to {:?}.", host_jar_path);
+            fs::write(&host_jar_path, LIBRARY_PATH)?;
+            log::info!("Host library JAR written to {:?}.", host_jar_path);
+
+            fs::write(&hash_file_path, &embedded_jar_hash)?;
+            log::debug!("Host library JAR hash written to {:?}.", hash_file_path);
         } else {
-            log::debug!("Host library JAR found at {:?}", host_jar_path);
+            log::debug!("Host library JAR at {:?} is up-to-date.", host_jar_path);
         }
 
         let jvm_args = InitArgsBuilder::new()
@@ -59,7 +90,8 @@ impl JavaContext {
         let jvm_args = jvm_args.build()?;
         let jvm = JavaVM::new(jvm_args)?;
 
-        info!("JDB debugger enabled on localhost:6741");
+        #[cfg(feature = "editor")]
+        success!("JDB debugger enabled on localhost:6741");
 
         log::info!("Created JVM instance");
 
@@ -71,8 +103,7 @@ impl JavaContext {
         })
     }
 
-    pub fn init(&mut self, jar_path: impl AsRef<Path>, world: WorldPtr) -> anyhow::Result<()> {
-        self.jar_path = jar_path.as_ref().to_owned();
+    pub fn init(&mut self, world: WorldPtr) -> anyhow::Result<()> {
         let mut env = self.jvm.attach_current_thread()?;
 
         if let Some(old_ref) = self.dropbear_engine_class.take() {
@@ -353,44 +384,45 @@ impl Drop for JavaContext {
     }
 }
 
-
-
+#[unsafe(no_mangle)]
+// JNIEXPORT jlong JNICALL Java_com_dropbear_ffi_JNINative_getEntity
+// (JNIEnv *, jobject, jlong, jstring);
 pub fn Java_com_dropbear_ffi_JNINative_getEntity(
     mut env: JNIEnv,
     _obj: jobject,
     world_handle: jlong,
     label: JString,
 ) -> jlong {
-    eprintln!("JNI call started");
-    eprintln!("world_handle: {}", world_handle);
-    eprintln!("label ptr: {:p}", label.as_raw());
-
-    if world_handle == 0 {
-        eprintln!("ERROR: world_handle is null!");
-        return -1;
-    }
-
-    let label_result = env.get_string(&label);
-    if label_result.is_err() {
-        eprintln!("ERROR: Failed to get string: {:?}", label_result.err());
-        return -1;
-    }
-    let label = label_result.unwrap();
+    let label_jni_result = env.get_string(&label);
+    let label_str = match label_jni_result {
+        Ok(java_string) => {
+            match java_string.to_str() {
+                Ok(rust_str) => rust_str.to_string(),
+                Err(e) => {
+                    println!("[Java_com_dropbear_ffi_JNINative_getEntity] [ERROR] Failed to convert Java string to Rust string: {}", e);
+                    return -1;
+                }
+            }
+        },
+        Err(e) => {
+            println!("[Java_com_dropbear_ffi_JNINative_getEntity] [ERROR] Failed to get string from JNI: {}", e);
+            return -1;
+        }
+    };
 
     let world = world_handle as *mut World;
 
     if world.is_null() {
-        eprintln!("ERROR: world pointer is null!");
+        println!("[Java_com_dropbear_ffi_JNINative_getEntity] [ERROR] World pointer is null in Java_com_dropbear_ffi_JNINative_getEntity");
         return -1;
     }
 
     let world = unsafe { &mut *world };
-    let rust_label = label.to_str().unwrap().to_string();
 
     for (id, entity) in world.query::<&AdoptedEntity>().iter() {
-        if entity.model.label == rust_label {
-            return jlong::from(id.id());
+        if entity.model.label == label_str {
+            return id.id() as jlong;
         }
     }
-    jlong::from(-1)
-}
+    -1
+}
\ No newline at end of file
diff --git a/eucalyptus-core/src/scripting/jni/exception.rs b/eucalyptus-core/src/scripting/jni/exception.rs
index b7efccc..22a8f57 100644
--- a/eucalyptus-core/src/scripting/jni/exception.rs
+++ b/eucalyptus-core/src/scripting/jni/exception.rs
@@ -1,4 +1,3 @@
-use std::error::Error;
 use jni::JNIEnv;
 use jni::objects::JThrowable;
 
diff --git a/eucalyptus-editor/src/editor/component.rs b/eucalyptus-editor/src/editor/component.rs
index 5e021d2..0236fc6 100644
--- a/eucalyptus-editor/src/editor/component.rs
+++ b/eucalyptus-editor/src/editor/component.rs
@@ -659,7 +659,9 @@ impl InspectableComponent for AdoptedEntity {
                     }
                     cfg.label_last_edit = None;
                 }
-            })
+            });
+
+            ui.label(format!("Entity ID: {}", entity.id()));
         });
     }
 }
diff --git a/eucalyptus-editor/src/editor/input.rs b/eucalyptus-editor/src/editor/input.rs
index 68ad671..b594342 100644
--- a/eucalyptus-editor/src/editor/input.rs
+++ b/eucalyptus-editor/src/editor/input.rs
@@ -238,9 +238,7 @@ impl Mouse for Editor {
     #[cfg(target_os = "linux")]
     // this impl doesn't have the mouse being recentered back to the center (to be fixed), this works as a usable alternative for now
     fn mouse_move(&mut self, position: PhysicalPosition<f64>) {
-        if (self.is_viewport_focused && matches!(self.viewport_mode, ViewportMode::CameraMove))
-            || (matches!(self.editor_state, EditorState::Playing)
-                && !self.input_state.is_cursor_locked)
+        if self.is_viewport_focused && matches!(self.viewport_mode, ViewportMode::CameraMove)
         {
             if let Some(last_pos) = self.input_state.last_mouse_pos {
                 let dx = position.x - last_pos.0;
@@ -266,37 +264,34 @@ impl Mouse for Editor {
     #[cfg(not(target_os = "linux"))]
     // for some reason, this doesn't work on linux but works on windows (not tested on anywhere else)
     fn mouse_move(&mut self, position: PhysicalPosition<f64>) {
-        // if ((self.is_viewport_focused && matches!(self.viewport_mode, ViewportMode::CameraMove))
-        //     || (matches!(self.editor_state, EditorState::Playing)
-        //         && !self.input_state.is_cursor_locked))
-        //     && let Some(window) = &self.window
-        // {
-        //     let size = window.inner_size();
-        //     let center = PhysicalPosition::new(size.width as f64 / 2.0, size.height as f64 / 2.0);
-        //
-        //     let distance_from_center =
-        //         ((position.x - center.x).powi(2) + (position.y - center.y).powi(2)).sqrt();
-        //
-        //     if distance_from_center > 5.0 {
-        //         let dx = position.x - center.x;
-        //         let dy = position.y - center.y;
-        //
-        //         if let Some(active_camera) = *self.active_camera.lock()
-        //             && let Ok(mut q) = self.world.query_one::<(
-        //                 &mut Camera,
-        //                 &CameraComponent,
-        //                 // Option<&CameraFollowTarget>,
-        //             )>(active_camera)
-        //             && let Some((camera, _)) = q.get()
-        //         {
-        //             camera.track_mouse_delta(dx, dy);
-        //         }
-        //
-        //         let _ = window.set_cursor_position(center);
-        //     }
-        //
-        //     window.set_cursor_visible(false);
-        // }
+        if (self.is_viewport_focused && matches!(self.viewport_mode, ViewportMode::CameraMove))
+            && let Some(window) = &self.window
+        {
+            let size = window.inner_size();
+            let center = PhysicalPosition::new(size.width as f64 / 2.0, size.height as f64 / 2.0);
+
+            let distance_from_center =
+                ((position.x - center.x).powi(2) + (position.y - center.y).powi(2)).sqrt();
+
+            if distance_from_center > 5.0 {
+                let dx = position.x - center.x;
+                let dy = position.y - center.y;
+
+                if let Some(active_camera) = *self.active_camera.lock()
+                    && let Ok(mut q) = self.world.query_one::<(
+                        &mut Camera,
+                        &CameraComponent,
+                    )>(active_camera)
+                    && let Some((camera, _)) = q.get()
+                {
+                    camera.track_mouse_delta(dx, dy);
+                }
+
+                let _ = window.set_cursor_position(center);
+            }
+
+            window.set_cursor_visible(false);
+        }
 
         self.input_state.mouse_pos = (position.x, position.y);
     }
diff --git a/magna-carta-plugin/build.gradle.kts b/magna-carta-plugin/build.gradle.kts
index 9f7d176..a1d77c1 100644
--- a/magna-carta-plugin/build.gradle.kts
+++ b/magna-carta-plugin/build.gradle.kts
@@ -3,6 +3,7 @@ import org.gradle.kotlin.dsl.compileOnly
 plugins {
     `kotlin-dsl`
     `maven-publish`
+    id("com.gradle.plugin-publish") version "2.0.0"
 }
 
 group = "com.dropbear"
@@ -18,11 +19,17 @@ dependencies {
 }
 
 gradlePlugin {
+    website.set("https://github.com/4tkbytes/dropbear")
+    vcsUrl.set("https://github.com/4tkbytes/dropbear")
     plugins {
-        create("dropbearPlugin") {
+
+        create("magnaCartaPlugin") {
             id = "magna-carta"
             implementationClass = "com.dropbear.magna_carta.MagnaCartaPlugin"
-            version = "1.0-SNAPSHOT"
+            displayName = "magna-carta plugin"
+            description = "Gradle plugin for generating manifests from annotation data during compile time" +
+                    " for use with KMP and the dropbear engine"
+            version = version as String
         }
     }
 }
\ No newline at end of file