From 3ac7283409c9d23648563c0aa565d013bc7c6d55 Mon Sep 17 00:00:00 2001 From: hinyb <40139991+hinyb@users.noreply.github.com> Date: Fri, 13 Mar 2026 02:24:04 +0800 Subject: [PATCH 1/2] feat(lwjgl3ify): add drop_file event --- build.gradle | 8 +++ dependencies.gradle | 2 +- .../li/cil/oc/api/internal/TextBuffer.java | 11 +++++ .../loot/openos/boot/95_drop_file.lua | 27 ++++++++++ .../li/cil/oc/client/PacketHandler.scala | 4 ++ .../scala/li/cil/oc/client/PacketSender.scala | 18 +++++++ .../oc/client/gui/traits/InputBuffer.scala | 49 +++++++++++++++++-- .../scala/li/cil/oc/common/PacketType.scala | 1 + .../oc/common/component/GpuTextBuffer.scala | 1 + .../cil/oc/common/component/TextBuffer.scala | 14 ++++++ .../scala/li/cil/oc/integration/Mods.scala | 3 ++ .../lwjgl3ify/FileUploadSupport.scala | 33 +++++++++++++ .../integration/lwjgl3ify/ModLwjgl3ify.scala | 12 +++++ .../li/cil/oc/server/PacketHandler.scala | 11 +++++ 14 files changed, 190 insertions(+), 4 deletions(-) create mode 100644 src/main/resources/assets/opencomputers/loot/openos/boot/95_drop_file.lua create mode 100644 src/main/scala/li/cil/oc/integration/lwjgl3ify/FileUploadSupport.scala create mode 100644 src/main/scala/li/cil/oc/integration/lwjgl3ify/ModLwjgl3ify.scala diff --git a/build.gradle b/build.gradle index e57a16f9f1..f7b1280ffb 100644 --- a/build.gradle +++ b/build.gradle @@ -3,3 +3,11 @@ plugins { id 'com.gtnewhorizons.gtnhconvention' } + +// https://github.com/GTNewHorizons/NewHorizonsCoreMod/blob/master/build.gradle.kts +def lwjgl3Version = project.minecraft.lwjgl3Version.get() +dependencies { + compileOnly("org.lwjgl:lwjgl-sdl:${lwjgl3Version}") { transitive = false } + compileOnly("org.lwjgl:lwjgl:${lwjgl3Version}") { transitive = false } + compileOnly("com.github.GTNewHorizons:lwjgl3ify:3.0.3:dev") { transitive = false } +} \ No newline at end of file diff --git a/dependencies.gradle b/dependencies.gradle index 996b710cf6..70fac78cda 100644 --- a/dependencies.gradle +++ b/dependencies.gradle @@ -7,7 +7,7 @@ dependencies { api("com.github.GTNewHorizons:AE2FluidCraft-Rework:1.5.39-gtnh:dev") compileOnly("com.github.GTNewHorizons:Angelica:1.0.0-beta68a:api") {transitive = false} - api("com.github.GTNewHorizons:Applied-Energistics-2-Unofficial:rv3-betea-777-GTNH:dev") + api("com.github.GTNewHorizons:Applied-Energistics-2-Unofficial:rv3-beta-777-GTNH:dev") compileOnly("com.github.GTNewHorizons:Avaritiaddons:1.9.3-GTNH:dev") {transitive = false} compileOnly("com.github.GTNewHorizons:BloodMagic:1.8.8:dev") {transitive = false} compileOnly("com.github.GTNewHorizons:BuildCraft:7.1.48:dev") {transitive = false} diff --git a/src/main/java/li/cil/oc/api/internal/TextBuffer.java b/src/main/java/li/cil/oc/api/internal/TextBuffer.java index 4221196407..b30aebcc3a 100644 --- a/src/main/java/li/cil/oc/api/internal/TextBuffer.java +++ b/src/main/java/li/cil/oc/api/internal/TextBuffer.java @@ -581,6 +581,17 @@ public interface TextBuffer extends ManagedEnvironment, Persistable { */ void clipboard(String value, EntityPlayer player); + /** + * Signals a file drop event for the buffer. + *
+ * This method is intended to be called on the client side only. + * + * @param fileName the name of file that was dropped. + * @param fileContent the context of the file being transferred. + * @param player the player that dropped the file. Pass null on the client side. + */ + void dropFile(String fileName, String fileContent, EntityPlayer player); + /** * Signals a mouse button down event for the buffer. *
diff --git a/src/main/resources/assets/opencomputers/loot/openos/boot/95_drop_file.lua b/src/main/resources/assets/opencomputers/loot/openos/boot/95_drop_file.lua new file mode 100644 index 0000000000..6ffba4f52f --- /dev/null +++ b/src/main/resources/assets/opencomputers/loot/openos/boot/95_drop_file.lua @@ -0,0 +1,27 @@ +local event = require("event") +local fs = require("filesystem") +local shell = require("shell") + +local function onDropFile(ev, _, filename, context) + local path = shell.resolve(filename) + local file_parentpath = fs.path(path) + fs.makeDirectory(file_parentpath) + + if fs.exists(path) then + if not os.remove(path) then + io.stderr:write("file already exists") + return + end + end + + local f, reason = io.open(filename, "w") + if not f then + io.stderr:write("Failed opening file for writing: " .. reason) + return + end + + f:write(context) + f:close() +end + +event.listen("drop_file", onDropFile) diff --git a/src/main/scala/li/cil/oc/client/PacketHandler.scala b/src/main/scala/li/cil/oc/client/PacketHandler.scala index ccf46a956c..1ffd855d7d 100644 --- a/src/main/scala/li/cil/oc/client/PacketHandler.scala +++ b/src/main/scala/li/cil/oc/client/PacketHandler.scala @@ -48,6 +48,7 @@ object PacketHandler extends CommonPacketHandler { case PacketType.ChargerState => onChargerState(p) case PacketType.ClientLog => onClientLog(p) case PacketType.Clipboard => onClipboard(p) + case PacketType.DropFile => onDropFile(p) case PacketType.ColorChange => onColorChange(p) case PacketType.ComputerState => onComputerState(p) case PacketType.ComputerUserList => onComputerUserList(p) @@ -140,6 +141,9 @@ object PacketHandler extends CommonPacketHandler { GuiScreen.setClipboardString(p.readUTF()) } + def onDropFile(p: PacketParser): Unit = { + } + def onColorChange(p: PacketParser) = p.readTileEntity[Colored]() match { case Some(t) => diff --git a/src/main/scala/li/cil/oc/client/PacketSender.scala b/src/main/scala/li/cil/oc/client/PacketSender.scala index 1b4b7f0eb8..2fd7b58477 100644 --- a/src/main/scala/li/cil/oc/client/PacketSender.scala +++ b/src/main/scala/li/cil/oc/client/PacketSender.scala @@ -91,6 +91,24 @@ object PacketSender { } } + def sendDropFile(address: String, name: String, context: String): Unit = { + val length = name.length + context.length + if (length > 64 * 1024) { + val player = Minecraft.getMinecraft.thePlayer + val handler = Minecraft.getMinecraft.getSoundHandler + handler.playSound(new PositionedSoundRecord(new ResourceLocation("note.harp"), 1, 1, player.posX.toFloat, player.posY.toFloat, player.posZ.toFloat)) + } + else { + val pb = new CompressedPacketBuilder(PacketType.DropFile) + + pb.writeUTF(address) + pb.writeUTF(name) + pb.writeUTF(context) + + pb.sendToServer() + } + } + def sendMouseClick(address: String, x: Double, y: Double, drag: Boolean, button: Int) { val pb = new SimplePacketBuilder(PacketType.MouseClickOrDrag) diff --git a/src/main/scala/li/cil/oc/client/gui/traits/InputBuffer.scala b/src/main/scala/li/cil/oc/client/gui/traits/InputBuffer.scala index 75f142aad1..aff35a5329 100644 --- a/src/main/scala/li/cil/oc/client/gui/traits/InputBuffer.scala +++ b/src/main/scala/li/cil/oc/client/gui/traits/InputBuffer.scala @@ -1,8 +1,8 @@ package li.cil.oc.client.gui.traits -import li.cil.oc.api -import li.cil.oc.client.KeyBindings -import li.cil.oc.client.Textures +import li.cil.oc.{OpenComputers, api} +import li.cil.oc.client.{KeyBindings, Textures} +import li.cil.oc.common.EventHandler import li.cil.oc.integration.util.NEI import li.cil.oc.util.RenderState import net.minecraft.client.Minecraft @@ -12,7 +12,13 @@ import net.minecraft.client.renderer.Tessellator import org.lwjgl.input.Keyboard import org.lwjgl.opengl.GL11 +import java.io.File +import java.nio.charset.StandardCharsets +import java.nio.file.Files +import java.util.concurrent.Executors +import scala.collection.JavaConverters.asScalaIteratorConverter import scala.collection.mutable +import scala.concurrent.{ExecutionContext, Future} trait InputBuffer extends DisplayBuffer { protected def buffer: api.internal.TextBuffer @@ -117,4 +123,41 @@ trait InputBuffer extends DisplayBuffer { code == Keyboard.KEY_LMETA || code == Keyboard.KEY_RMETA } + + private val fileIoContext: ExecutionContext = ExecutionContext.fromExecutor(Executors.newFixedThreadPool(2)) + private case class FileResult(relativePath: String, file: File) + + private def getFiles(path: String): List[FileResult] = { + val rootFile = new File(path) + if (rootFile.isDirectory) { + val basePath = rootFile.getAbsoluteFile.getParentFile.toPath + val stream = Files.walk(rootFile.toPath) + try { + stream.iterator().asScala.filter(Files.isRegularFile(_)).map { path => + val relative = basePath.relativize(path.toAbsolutePath).toString + FileResult(relative, path.toFile) + }.toList + } finally { + stream.close() + } + } else { + List(FileResult(rootFile.getName, rootFile)) + } + } + + def handleDropFile(filePath: String): Unit = { + Future { + getFiles(filePath).foreach { + case FileResult(path, file) => + if (file.length() < 64 * 1024){ + val content = new String(Files.readAllBytes(file.toPath), StandardCharsets.UTF_8) + EventHandler.scheduleClient(() => { + buffer.dropFile(path, content, null) + }) + } + } + }(fileIoContext).failed.foreach{ e => + OpenComputers.log.warn("Failed to handle drop file.", e) + }(fileIoContext) + } } diff --git a/src/main/scala/li/cil/oc/common/PacketType.scala b/src/main/scala/li/cil/oc/common/PacketType.scala index 8e05f946dd..02c5cceb58 100644 --- a/src/main/scala/li/cil/oc/common/PacketType.scala +++ b/src/main/scala/li/cil/oc/common/PacketType.scala @@ -83,6 +83,7 @@ object PacketType extends Enumeration { KeyDown, KeyUp, Clipboard, + DropFile, MouseClickOrDrag, MouseScroll, MouseUp, diff --git a/src/main/scala/li/cil/oc/common/component/GpuTextBuffer.scala b/src/main/scala/li/cil/oc/common/component/GpuTextBuffer.scala index 59c542f8e0..4e0d0887bd 100644 --- a/src/main/scala/li/cil/oc/common/component/GpuTextBuffer.scala +++ b/src/main/scala/li/cil/oc/common/component/GpuTextBuffer.scala @@ -60,6 +60,7 @@ class GpuTextBuffer(val owner: String, val id: Int, val data: li.cil.oc.util.Tex override def keyDown(character: Char, code: Int, player: EntityPlayer): Unit = {} override def keyUp(character: Char, code: Int, player: EntityPlayer): Unit = {} override def clipboard(value: String, player: EntityPlayer): Unit = {} + override def dropFile(fileName: String, fileContent: String, player: EntityPlayer): Unit = {} override def mouseDown(x: Double, y: Double, button: Int, player: EntityPlayer): Unit = {} override def mouseDrag(x: Double, y: Double, button: Int, player: EntityPlayer): Unit = {} override def mouseUp(x: Double, y: Double, button: Int, player: EntityPlayer): Unit = {} diff --git a/src/main/scala/li/cil/oc/common/component/TextBuffer.scala b/src/main/scala/li/cil/oc/common/component/TextBuffer.scala index a45531435f..caf43f8fb2 100644 --- a/src/main/scala/li/cil/oc/common/component/TextBuffer.scala +++ b/src/main/scala/li/cil/oc/common/component/TextBuffer.scala @@ -381,6 +381,9 @@ class TextBuffer(val host: EnvironmentHost) extends prefab.ManagedEnvironment wi override def clipboard(value: String, player: EntityPlayer): Unit = proxy.clipboard(value, player) + override def dropFile(fileName: String, fileContent: String, player: EntityPlayer): Unit = + proxy.dropFile(fileName, fileContent, player) + override def mouseDown(x: Double, y: Double, button: Int, player: EntityPlayer): Unit = proxy.mouseDown(x, y, button, player) @@ -589,6 +592,8 @@ object TextBuffer { def clipboard(value: String, player: EntityPlayer): Unit + def dropFile(fileName: String, fileContent: String, player: EntityPlayer): Unit + def mouseDown(x: Double, y: Double, button: Int, player: EntityPlayer): Unit def mouseDrag(x: Double, y: Double, button: Int, player: EntityPlayer): Unit @@ -682,6 +687,11 @@ object TextBuffer { ClientPacketSender.sendClipboard(nodeAddress, value) } + override def dropFile(fileName: String, fileContent: String, player: EntityPlayer) { + debug(s"{type = dropFile}") + ClientPacketSender.sendDropFile(nodeAddress, fileName, fileContent) + } + override def mouseDown(x: Double, y: Double, button: Int, player: EntityPlayer) { debug(s"{type = mouseDown, x = $x, y = $y, button = $button}") ClientPacketSender.sendMouseClick(nodeAddress, x, y, drag = false, button) @@ -819,6 +829,10 @@ object TextBuffer { sendToKeyboards("keyboard.clipboard", player, value) } + override def dropFile(fileName: String, fileContent: String, player: EntityPlayer): Unit = { + owner.node.sendToReachable("computer.checked_signal", player, "drop_file", fileName, fileContent) + } + override def mouseDown(x: Double, y: Double, button: Int, player: EntityPlayer) { sendMouseEvent(player, "touch", x, y, button) } diff --git a/src/main/scala/li/cil/oc/integration/Mods.scala b/src/main/scala/li/cil/oc/integration/Mods.scala index 886a80787e..ac540e4aa7 100644 --- a/src/main/scala/li/cil/oc/integration/Mods.scala +++ b/src/main/scala/li/cil/oc/integration/Mods.scala @@ -51,6 +51,7 @@ object Mods { val IndustrialCraft2 = new SimpleMod(IDs.IndustrialCraft2) val IndustrialCraft2Classic = new SimpleMod(IDs.IndustrialCraft2Classic) val IngameWiki = new SimpleMod(IDs.IngameWiki, version = "@[1.1.3,)") + val lwjgl3ify = new SimpleMod(IDs.lwjgl3ify, version = "@[3.0.0,)") val Mekanism = new SimpleMod(IDs.Mekanism) val MekanismGas = new SimpleMod(IDs.MekanismGas) val Minecraft = new SimpleMod(IDs.Minecraft) @@ -114,6 +115,7 @@ object Mods { integration.gc.ModGalacticraft, integration.gregtech.ModGregtech, integration.ic2.ModIndustrialCraft2, + integration.lwjgl3ify.ModLwjgl3ify, integration.mekanism.ModMekanism, integration.mekanism.gas.ModMekanismGas, integration.mfr.ModMineFactoryReloaded, @@ -204,6 +206,7 @@ object Mods { final val IndustrialCraft2Classic = "IC2-Classic" final val IndustrialCraft2Spmod = "IC2-Classic-Spmod" final val IngameWiki = "IGWMod" + final val lwjgl3ify = "lwjgl3ify" final val Mekanism = "Mekanism" final val MekanismGas = "MekanismAPI|gas" final val Minecraft = "Minecraft" diff --git a/src/main/scala/li/cil/oc/integration/lwjgl3ify/FileUploadSupport.scala b/src/main/scala/li/cil/oc/integration/lwjgl3ify/FileUploadSupport.scala new file mode 100644 index 0000000000..5156e31318 --- /dev/null +++ b/src/main/scala/li/cil/oc/integration/lwjgl3ify/FileUploadSupport.scala @@ -0,0 +1,33 @@ +package li.cil.oc.integration.lwjgl3ify + +import li.cil.oc.client.gui.traits.InputBuffer +import me.eigenraven.lwjgl3ify.api.Lwjgl3Aware +import net.minecraft.client.Minecraft +import org.lwjgl.sdl.SDLEvents.SDL_EVENT_DROP_FILE +import org.lwjgl.sdl.{SDLEvents, SDL_Event, SDL_EventFilter} +import org.lwjgl.system.MemoryUtil + + +@Lwjgl3Aware class DropFileFilter extends SDL_EventFilter { + override def invoke(userdata: Long, eventPtr: Long): Boolean = { + val event = SDL_Event.create(eventPtr) + if (event.`type` == SDL_EVENT_DROP_FILE) { + val screen = Minecraft.getMinecraft.currentScreen + screen match { + case handler: InputBuffer => + val file = MemoryUtil.memUTF8(event.drop().data()) + handler.handleDropFile(file) + case _ => + } + } + true + } +} + +@Lwjgl3Aware object FileUploadSupport { + val filter = new DropFileFilter + + def init(): Unit = { + SDLEvents.SDL_AddEventWatch(filter, MemoryUtil.NULL) + } +} \ No newline at end of file diff --git a/src/main/scala/li/cil/oc/integration/lwjgl3ify/ModLwjgl3ify.scala b/src/main/scala/li/cil/oc/integration/lwjgl3ify/ModLwjgl3ify.scala new file mode 100644 index 0000000000..35b28e1d10 --- /dev/null +++ b/src/main/scala/li/cil/oc/integration/lwjgl3ify/ModLwjgl3ify.scala @@ -0,0 +1,12 @@ +package li.cil.oc.integration.lwjgl3ify + +import li.cil.oc.integration.ModProxy +import li.cil.oc.integration.Mods + +object ModLwjgl3ify extends ModProxy { + override def getMod: Mods.SimpleMod = Mods.lwjgl3ify + + override def initialize(): Unit = { + FileUploadSupport.init() + } +} diff --git a/src/main/scala/li/cil/oc/server/PacketHandler.scala b/src/main/scala/li/cil/oc/server/PacketHandler.scala index 16a45d2485..9ff88c4c26 100644 --- a/src/main/scala/li/cil/oc/server/PacketHandler.scala +++ b/src/main/scala/li/cil/oc/server/PacketHandler.scala @@ -50,6 +50,7 @@ object PacketHandler extends CommonPacketHandler { case PacketType.KeyDown => onKeyDown(p) case PacketType.KeyUp => onKeyUp(p) case PacketType.Clipboard => onClipboard(p) + case PacketType.DropFile => onDropFile(p) case PacketType.MouseClickOrDrag => onMouseClick(p) case PacketType.MouseScroll => onMouseScroll(p) case PacketType.DatabaseSetSlot => onDatabaseSetSlot(p) @@ -201,6 +202,16 @@ object PacketHandler extends CommonPacketHandler { } } + def onDropFile(p: PacketParser): Unit = { + val address = p.readUTF() + val fileName = p.readUTF() + val fileContent = p.readUTF() + ComponentTracker.get(p.player.worldObj, address) match { + case Some(buffer: api.internal.TextBuffer) => buffer.dropFile(fileName, fileContent, p.player.asInstanceOf[EntityPlayer]) + case _ => // Invalid Packet + } + } + def onMouseClick(p: PacketParser) { val address = p.readUTF() val x = p.readFloat() From b40121effcea728574f9ea1fe8e59922d53de38b Mon Sep 17 00:00:00 2001 From: hinyb <40139991+hinyb@users.noreply.github.com> Date: Fri, 13 Mar 2026 20:31:08 +0800 Subject: [PATCH 2/2] build: fix build conflicts by isolating lwjgl3 sourceSet --- addon.gradle | 7 ++++ build.gradle | 10 +++-- .../lwjgl3ify/FileUploadSupport.java | 38 +++++++++++++++++++ .../lwjgl3ify/FileUploadSupport.scala | 33 ---------------- .../oc/integration/lwjgl3ify/IFileUpload.java | 5 +++ .../integration/lwjgl3ify/ModLwjgl3ify.scala | 12 ++++-- 6 files changed, 66 insertions(+), 39 deletions(-) create mode 100644 src/lwjgl3/java/li/cil/oc/integration/lwjgl3ify/FileUploadSupport.java delete mode 100644 src/main/scala/li/cil/oc/integration/lwjgl3ify/FileUploadSupport.scala create mode 100644 src/main/scala/li/cil/oc/integration/lwjgl3ify/IFileUpload.java diff --git a/addon.gradle b/addon.gradle index 76b1bdee62..67e58c78ff 100644 --- a/addon.gradle +++ b/addon.gradle @@ -11,3 +11,10 @@ tasks.named("processResources", ProcessResources).configure { filter(ReplaceTokens, tokens: [version: pVersion]) } } + +sourceSets { + lwjgl3 { + compileClasspath += sourceSets.main.compileClasspath + compileClasspath += sourceSets.main.output + } +} \ No newline at end of file diff --git a/build.gradle b/build.gradle index f7b1280ffb..9597fbeaa8 100644 --- a/build.gradle +++ b/build.gradle @@ -7,7 +7,11 @@ plugins { // https://github.com/GTNewHorizons/NewHorizonsCoreMod/blob/master/build.gradle.kts def lwjgl3Version = project.minecraft.lwjgl3Version.get() dependencies { - compileOnly("org.lwjgl:lwjgl-sdl:${lwjgl3Version}") { transitive = false } - compileOnly("org.lwjgl:lwjgl:${lwjgl3Version}") { transitive = false } - compileOnly("com.github.GTNewHorizons:lwjgl3ify:3.0.3:dev") { transitive = false } + lwjgl3CompileOnly("org.lwjgl:lwjgl-sdl:${lwjgl3Version}") { transitive = false } + lwjgl3CompileOnly("org.lwjgl:lwjgl:${lwjgl3Version}") { transitive = false } + lwjgl3CompileOnly("com.github.GTNewHorizons:lwjgl3ify:3.0.3:dev") { transitive = false } +} + +jar { + from sourceSets.lwjgl3.output } \ No newline at end of file diff --git a/src/lwjgl3/java/li/cil/oc/integration/lwjgl3ify/FileUploadSupport.java b/src/lwjgl3/java/li/cil/oc/integration/lwjgl3ify/FileUploadSupport.java new file mode 100644 index 0000000000..a0ded9f9a5 --- /dev/null +++ b/src/lwjgl3/java/li/cil/oc/integration/lwjgl3ify/FileUploadSupport.java @@ -0,0 +1,38 @@ +package li.cil.oc.integration.lwjgl3ify; + +import li.cil.oc.client.gui.traits.InputBuffer; +import li.cil.oc.integration.lwjgl3ify.IFileUpload; +import me.eigenraven.lwjgl3ify.api.Lwjgl3Aware; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiScreen; +import org.lwjgl.sdl.SDLEvents; +import org.lwjgl.sdl.SDL_Event; +import org.lwjgl.sdl.SDL_EventFilter; +import org.lwjgl.system.MemoryUtil; + +import static org.lwjgl.sdl.SDLEvents.SDL_EVENT_DROP_FILE; + +@Lwjgl3Aware +class FileUploadSupport implements IFileUpload { + @Lwjgl3Aware + class DropFileFilter extends SDL_EventFilter { + @Override + public boolean invoke(long userdata, long eventPtr) { + SDL_Event event = SDL_Event.create(eventPtr); + if (event.type() == SDL_EVENT_DROP_FILE) { + GuiScreen screen = Minecraft.getMinecraft().currentScreen; + if (screen instanceof InputBuffer) { + String file = MemoryUtil.memUTF8Safe(event.drop().data()); + if (file != null) ((InputBuffer) screen).handleDropFile(file); + } + } + return true; + } + } + + DropFileFilter filter = new DropFileFilter(); + @Override + public void init() { + SDLEvents.SDL_AddEventWatch(filter, MemoryUtil.NULL); + } +} \ No newline at end of file diff --git a/src/main/scala/li/cil/oc/integration/lwjgl3ify/FileUploadSupport.scala b/src/main/scala/li/cil/oc/integration/lwjgl3ify/FileUploadSupport.scala deleted file mode 100644 index 5156e31318..0000000000 --- a/src/main/scala/li/cil/oc/integration/lwjgl3ify/FileUploadSupport.scala +++ /dev/null @@ -1,33 +0,0 @@ -package li.cil.oc.integration.lwjgl3ify - -import li.cil.oc.client.gui.traits.InputBuffer -import me.eigenraven.lwjgl3ify.api.Lwjgl3Aware -import net.minecraft.client.Minecraft -import org.lwjgl.sdl.SDLEvents.SDL_EVENT_DROP_FILE -import org.lwjgl.sdl.{SDLEvents, SDL_Event, SDL_EventFilter} -import org.lwjgl.system.MemoryUtil - - -@Lwjgl3Aware class DropFileFilter extends SDL_EventFilter { - override def invoke(userdata: Long, eventPtr: Long): Boolean = { - val event = SDL_Event.create(eventPtr) - if (event.`type` == SDL_EVENT_DROP_FILE) { - val screen = Minecraft.getMinecraft.currentScreen - screen match { - case handler: InputBuffer => - val file = MemoryUtil.memUTF8(event.drop().data()) - handler.handleDropFile(file) - case _ => - } - } - true - } -} - -@Lwjgl3Aware object FileUploadSupport { - val filter = new DropFileFilter - - def init(): Unit = { - SDLEvents.SDL_AddEventWatch(filter, MemoryUtil.NULL) - } -} \ No newline at end of file diff --git a/src/main/scala/li/cil/oc/integration/lwjgl3ify/IFileUpload.java b/src/main/scala/li/cil/oc/integration/lwjgl3ify/IFileUpload.java new file mode 100644 index 0000000000..4ecb89ac54 --- /dev/null +++ b/src/main/scala/li/cil/oc/integration/lwjgl3ify/IFileUpload.java @@ -0,0 +1,5 @@ +package li.cil.oc.integration.lwjgl3ify; + +public interface IFileUpload { + void init(); +} diff --git a/src/main/scala/li/cil/oc/integration/lwjgl3ify/ModLwjgl3ify.scala b/src/main/scala/li/cil/oc/integration/lwjgl3ify/ModLwjgl3ify.scala index 35b28e1d10..90d7011c00 100644 --- a/src/main/scala/li/cil/oc/integration/lwjgl3ify/ModLwjgl3ify.scala +++ b/src/main/scala/li/cil/oc/integration/lwjgl3ify/ModLwjgl3ify.scala @@ -1,12 +1,18 @@ package li.cil.oc.integration.lwjgl3ify -import li.cil.oc.integration.ModProxy -import li.cil.oc.integration.Mods +import li.cil.oc.integration.{ModProxy, Mods} object ModLwjgl3ify extends ModProxy { override def getMod: Mods.SimpleMod = Mods.lwjgl3ify override def initialize(): Unit = { - FileUploadSupport.init() + try { + val clazz = Class.forName("li.cil.oc.integration.lwjgl3ify.FileUploadSupport") + val support = clazz.getDeclaredConstructor().newInstance().asInstanceOf[IFileUpload] + + support.init() + } catch { + case _: Throwable => + } } }