diff --git a/src/main/java/net/montoyo/wd/SharedProxy.java b/src/main/java/net/montoyo/wd/SharedProxy.java index 408a4c7..0535750 100644 --- a/src/main/java/net/montoyo/wd/SharedProxy.java +++ b/src/main/java/net/montoyo/wd/SharedProxy.java @@ -41,7 +41,7 @@ public class SharedProxy { public void postInit() { } - public void onCefInit(/*CefInitEvent event*/) { + public void onCefInit() { } @Deprecated(forRemoval = true) diff --git a/src/main/java/net/montoyo/wd/client/ClientProxy.java b/src/main/java/net/montoyo/wd/client/ClientProxy.java index 9da60e9..4063afa 100644 --- a/src/main/java/net/montoyo/wd/client/ClientProxy.java +++ b/src/main/java/net/montoyo/wd/client/ClientProxy.java @@ -61,8 +61,8 @@ import net.montoyo.wd.WebDisplays; import net.montoyo.wd.block.ScreenBlock; import net.montoyo.wd.client.gui.*; import net.montoyo.wd.client.gui.loading.GuiLoader; -import net.montoyo.wd.client.handlers.DisplayHandler; -import net.montoyo.wd.client.handlers.js.WDRouter; +import net.montoyo.wd.utilities.browser.handlers.DisplayHandler; +import net.montoyo.wd.utilities.browser.handlers.WDRouter; import net.montoyo.wd.client.renderers.*; import net.montoyo.wd.core.HasAdvancement; import net.montoyo.wd.data.GuiData; @@ -75,19 +75,14 @@ import net.montoyo.wd.item.ItemLaserPointer; import net.montoyo.wd.item.ItemMinePad2; import net.montoyo.wd.item.WDItem; import net.montoyo.wd.miniserv.client.Client; -import net.montoyo.wd.net.WDNetworkRegistry; -import net.montoyo.wd.net.server_bound.C2SMessageMinepadUrl; import net.montoyo.wd.utilities.*; import net.montoyo.wd.utilities.math.Vector2i; import net.montoyo.wd.utilities.math.Vector3i; import net.montoyo.wd.utilities.data.BlockSide; import net.montoyo.wd.utilities.data.Rotation; import net.montoyo.wd.utilities.serialization.NameUUIDPair; -import org.cef.CefSettings; import org.cef.browser.CefBrowser; -import org.cef.browser.CefFrame; import org.cef.browser.CefMessageRouter; -import org.cef.handler.CefDisplayHandler; import org.cef.misc.CefCursorType; import org.joml.Vector3d; import org.lwjgl.glfw.GLFW; @@ -285,7 +280,7 @@ public class ClientProxy extends SharedProxy implements ResourceManagerReloadLis } @Override - public void onCefInit(/*CefInitEvent event*/) { + public void onCefInit() { minePadRenderer = new MinePadRenderer(); laserPointerRenderer = new LaserPointerRenderer(); @@ -299,10 +294,7 @@ public class ClientProxy extends SharedProxy implements ResourceManagerReloadLis } ); -// jsDispatcher = new JSQueryDispatcher(this); MCEF.getClient().addDisplayHandler(DisplayHandler.INSTANCE); -// mcef.registerJSQueryHandler(this); - MCEF.getClient().getHandle().addMessageRouter(CefMessageRouter.create(WDRouter.INSTANCE)); findAdvancementToProgressField(); @@ -579,38 +571,9 @@ public class ClientProxy extends SharedProxy implements ResourceManagerReloadLis // @Override // public void cancelQuery(IBrowser browser, long queryId) { // } - + /**************************************** EVENT METHODS ****************************************/ - -// @SubscribeEvent -// public void onBakeModel(ModelBakeEvent ev) { -// for(ResourceModelPair pair : modelBakers) -// ev.getModelRegistry().put(pair.getResourceLocation(), pair.getModel()); -// } - /* @SubscribeEvent - public void onRegisterModels(ModelRegistryEvent ev) { - final WebDisplays wd = WebDisplays.INSTANCE; - - //I hope I'm doing this right because it doesn't seem like it... - registerItemModel(wd.blockScreen.getItem(), 0, "inventory"); - ModelLoaderRegistry.setCustomModelResourceLocation(wd.blockPeripheral.getItem(), 0, new ModelResourceLocation("webdisplays:kb_inv", "normal")); - registerItemModel(wd.blockPeripheral.getItem(), 1, "facing=2,type=ccinterface"); - registerItemModel(wd.blockPeripheral.getItem(), 2, "facing=2,type=cointerface"); - registerItemModel(wd.blockPeripheral.getItem(), 3, "facing=0,type=remotectrl"); - registerItemModel(wd.blockPeripheral.getItem(), 7, "facing=0,type=redstonectrl"); - registerItemModel(wd.blockPeripheral.getItem(), 11, "facing=0,type=server"); - registerItemModel(wd.itemScreenCfg, 0, "normal"); - registerItemModel(wd.itemOwnerThief, 0, "normal"); - registerItemModel(wd.itemLinker, 0, "normal"); - registerItemModel(wd.itemMinePad, 0, "normal"); - registerItemModel(wd.itemMinePad, 1, "normal"); - registerItemModel(wd.itemLaserPointer, 0, "normal"); - registerItemMultiModels(wd.itemUpgrade); - registerItemMultiModels(wd.itemCraftComp); - registerItemMultiModels(wd.itemAdvIcon); - } */ - @SubscribeEvent public void onLevelTick(TickEvent.LevelTickEvent ev) { if (!ev.side.equals(LogicalSide.CLIENT)) return; @@ -735,9 +698,6 @@ public class ClientProxy extends SharedProxy implements ResourceManagerReloadLis } else { ItemLaserPointer.deselect(mc); } - -// //Handle JS queries -// jsDispatcher.handleQueries(); //Miniserv if (msClientStarted && mc.player == null) { diff --git a/src/main/java/net/montoyo/wd/client/gui/GuiMinePad.java b/src/main/java/net/montoyo/wd/client/gui/GuiMinePad.java index 7394323..f8585bc 100644 --- a/src/main/java/net/montoyo/wd/client/gui/GuiMinePad.java +++ b/src/main/java/net/montoyo/wd/client/gui/GuiMinePad.java @@ -4,31 +4,25 @@ package net.montoyo.wd.client.gui; -import com.cinemamod.mcef.MCEF; import com.cinemamod.mcef.MCEFBrowser; import com.google.gson.JsonObject; import com.mojang.blaze3d.platform.InputConstants; import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.*; import net.minecraft.client.Minecraft; -import net.minecraft.client.MouseHandler; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.renderer.GameRenderer; import net.minecraft.core.BlockPos; import net.minecraft.network.chat.Component; -import net.minecraft.util.Mth; import net.minecraftforge.api.distmarker.OnlyIn; import net.montoyo.wd.WebDisplays; import net.montoyo.wd.client.ClientProxy; -import net.montoyo.wd.client.handlers.js.Scripts; -import net.montoyo.wd.client.handlers.js.WDRouter; -import net.montoyo.wd.entity.ScreenBlockEntity; -import net.montoyo.wd.entity.ScreenData; +import net.montoyo.wd.utilities.browser.handlers.js.Scripts; +import net.montoyo.wd.utilities.browser.handlers.WDRouter; import net.montoyo.wd.utilities.data.BlockSide; import org.cef.misc.CefCursorType; import org.lwjgl.glfw.GLFW; -import java.awt.*; import java.util.Optional; import static net.minecraftforge.api.distmarker.Dist.CLIENT; diff --git a/src/main/java/net/montoyo/wd/client/gui/camera/KeyboardCamera.java b/src/main/java/net/montoyo/wd/client/gui/camera/KeyboardCamera.java index 9621fdc..2b72e32 100644 --- a/src/main/java/net/montoyo/wd/client/gui/camera/KeyboardCamera.java +++ b/src/main/java/net/montoyo/wd/client/gui/camera/KeyboardCamera.java @@ -9,9 +9,11 @@ import net.minecraft.world.phys.Vec2; import net.minecraft.world.phys.Vec3; import net.minecraftforge.client.event.ViewportEvent; import net.minecraftforge.event.TickEvent; -import net.montoyo.wd.client.handlers.js.WDRouter; +import net.montoyo.wd.utilities.browser.handlers.js.queries.ElementCenterQuery; +import net.montoyo.wd.utilities.browser.handlers.WDRouter; import net.montoyo.wd.entity.ScreenBlockEntity; import net.montoyo.wd.entity.ScreenData; +import net.montoyo.wd.utilities.browser.WDBrowser; import net.montoyo.wd.utilities.data.BlockSide; public class KeyboardCamera { @@ -74,19 +76,19 @@ public class KeyboardCamera { return new Vec2(cx + (2 / 16f), cy + (2 / 16f)); } - protected static void updateCrd(JsonObject obj) { - if (obj.getAsJsonPrimitive("exists").getAsBoolean()) { + protected static void updateCrd(ElementCenterQuery lock) { + if (lock.hasFocused()) { ScreenData scr = tes.getScreen(side); if (scr != null) { - nextX = obj.getAsJsonPrimitive("x").getAsDouble() + obj.getAsJsonPrimitive("w").getAsDouble() / 2; - nextY = obj.getAsJsonPrimitive("y").getAsDouble() + obj.getAsJsonPrimitive("h").getAsDouble() / 2; + nextX = lock.getX(); + nextY = lock.getY(); Vec2 c = pxToHit(scr, new Vec2((float) nextX, (float) nextY)); nextX = c.x; nextY = c.y; - float scl = Math.max(scr.size.x, scr.size.y) / 1.0f; + float scl = Math.max(scr.size.x, scr.size.y); double mx = Minecraft.getInstance().mouseHandler.xpos(); mx /= Minecraft.getInstance().getWindow().getWidth(); @@ -95,17 +97,9 @@ public class KeyboardCamera { my /= Minecraft.getInstance().getWindow().getHeight(); Vec2 v2 = new Vec2((float) mx, (float) my).add(-0.5f); -// v2 = v2.normalized().scale(Mth.sqrt(v2.length())); nextX += v2.x * scl; nextY -= v2.y * scl; - -// if (side.right.x > 0) -// nextX += 1.f; -// if (side.right.z > 0) -// nextX += 1.f; -// if (side == BlockSide.BOTTOM) -// nextY -= 1.f; } } else { nextX = -1; @@ -113,12 +107,7 @@ public class KeyboardCamera { } } - private static WDRouter.Task activeTask; - private static long futureStart = 0; - protected static void pollElement() { - if (activeTask != null) return; - ScreenBlockEntity teTmp = tes; BlockSide sdTmp = side; @@ -127,66 +116,14 @@ public class KeyboardCamera { ScreenData scr = teTmp.getScreen(sdTmp); if (scr != null) { -//@formatter:off -activeTask = WDRouter.INSTANCE.requestJson(scr.browser, "ActiveElement", """ -try { - let focusedElement = document.activeElement; - if (focusedElement == null || focusedElement == document.body) { - window.cefQuery({ - request: 'WebDisplays_ActiveElement{exists: false}', - onSuccess: function(response) {}, - onFailure: function(error_code, error_message) {} - }); - } else { - let bodyRect = document.body.getBoundingClientRect(); - let elemRect = focusedElement.getBoundingClientRect(); - - window.cefQuery({ - request: 'WebDisplays_ActiveElement{exists: true,'+ - 'x: ' + (elemRect.left) + ',' + - 'y: ' + (elemRect.top) + ',' + - 'w: ' + ((elemRect.right - elemRect.left)) + ',' + - 'h: ' + ((elemRect.bottom - elemRect.top)) + - '}', - onSuccess: function(response) {}, - onFailure: function(error_code, error_message) {} - }); - } -} catch (err) { - console.error(err); - window.cefQuery({ - request: 'WebDisplays_ActiveElement{exists: false}', - onSuccess: function(response) {}, - onFailure: function(error_code, error_message) {} - }); -}""".replace("\n", "") -).thenAccept((o1) -> { - updateCrd(o1); - activeTask = null; -}); -futureStart = System.currentTimeMillis(); -//@formatter:on + if (scr.browser instanceof WDBrowser wdBrowser) { + wdBrowser.pointerLock().dispatch(scr.browser); + updateCrd(((WDBrowser) scr.browser).pointerLock()); + } } } - protected static double signedSqrt(double v) { - double sv = Math.signum(v); - v *= sv; - return Math.sqrt(v) * sv; - } - public static void updateCamera(ViewportEvent.ComputeCameraAngles event) { - if (futureStart != 0) { - if (futureStart < System.currentTimeMillis() - 5000 || tes == null) { - WDRouter.Task active = activeTask; - if (active != null) { - active.cancel(); - activeTask = null; - futureStart = 0; - } - } - } - if (tes == null) { xCrd = -1; yCrd = -1; @@ -218,23 +155,10 @@ futureStart = System.currentTimeMillis(); new Vec3(focalX, focalY, focalZ) ); - float scl = 20; - - double mx = Minecraft.getInstance().mouseHandler.xpos(); - mx /= Minecraft.getInstance().getWindow().getWidth(); - - double my = Minecraft.getInstance().mouseHandler.ypos(); - my /= Minecraft.getInstance().getWindow().getHeight(); - - Vec2 v2 = new Vec2((float) mx, (float) my); - v2 = v2.normalized().scale(Mth.sqrt(v2.length())); - -// angle[1] += (v2.x - 0.5f) * scl; -// angle[0] += (v2.y - 0.5f) * scl; - - float xRot = event.getYaw(); // left right - float yRot = event.getPitch(); // up down +// float xRot = event.getYaw(); // left right +// float yRot = event.getPitch(); // up down + // TODO: smooth in/out event.setYaw(angle[1]); event.setPitch(angle[0]); } @@ -259,9 +183,6 @@ futureStart = System.currentTimeMillis(); public static void gameTick(TickEvent.ClientTickEvent event) { if (event.phase.equals(TickEvent.Phase.END)) { - if (activeTask != null) - return; - if (side == null) { delay = 1; oxCrd = -1; @@ -273,6 +194,8 @@ futureStart = System.currentTimeMillis(); return; } + pollElement(); + double anxx = nextX; double anxy = nextY; @@ -290,14 +213,11 @@ futureStart = System.currentTimeMillis(); anxy = data.size.y / 2.0; if (nxCrd == -1) { - oxCrd = xCrd = nxCrd = anxx; - oyCrd = yCrd = nyCrd = anxy; + oxCrd = xCrd = anxx; + oyCrd = yCrd = anxy; } } - if (activeTask == null) - pollElement(); - nxCrd = anxx; nyCrd = anxy; diff --git a/src/main/java/net/montoyo/wd/entity/ScreenData.java b/src/main/java/net/montoyo/wd/entity/ScreenData.java index f3b696a..2a551b4 100644 --- a/src/main/java/net/montoyo/wd/entity/ScreenData.java +++ b/src/main/java/net/montoyo/wd/entity/ScreenData.java @@ -15,6 +15,7 @@ import net.montoyo.wd.client.ClientProxy; import net.montoyo.wd.config.CommonConfig; import net.montoyo.wd.core.ScreenRights; import net.montoyo.wd.utilities.*; +import net.montoyo.wd.utilities.browser.WDBrowser; import net.montoyo.wd.utilities.data.BlockSide; import net.montoyo.wd.utilities.data.Rotation; import net.montoyo.wd.utilities.math.Vector2i; @@ -25,7 +26,6 @@ import java.util.ArrayList; import java.util.UUID; public class ScreenData { - public BlockSide side; public Vector2i size; public Vector2i resolution; @@ -185,7 +185,7 @@ public class ScreenData { public void createBrowser(boolean doAnim) { if (WebDisplays.PROXY instanceof ClientProxy clientProxy) { - browser = MCEF.createBrowser(WebDisplays.applyBlacklist(url != null ? url : "https://www.google.com"), false); + browser = WDBrowser.createBrowser(WebDisplays.applyBlacklist(url != null ? url : "https://www.google.com"), false); if (browser instanceof MCEFBrowser mcefBrowser) { if (rotation.isVertical) diff --git a/src/main/java/net/montoyo/wd/utilities/browser/WDBrowser.java b/src/main/java/net/montoyo/wd/utilities/browser/WDBrowser.java new file mode 100644 index 0000000..aa7aedf --- /dev/null +++ b/src/main/java/net/montoyo/wd/utilities/browser/WDBrowser.java @@ -0,0 +1,29 @@ +package net.montoyo.wd.utilities.browser; + +import com.cinemamod.mcef.MCEF; +import net.montoyo.wd.utilities.browser.handlers.js.queries.ElementCenterQuery; +import net.montoyo.wd.utilities.browser.handlers.js.JSQueryHandler; +import org.cef.browser.CefBrowser; + +import java.util.HashMap; +import java.util.Map; + +public interface WDBrowser { + static CefBrowser createBrowser(String url, boolean transparent) { + WDClientBrowser browser = new WDClientBrowser(MCEF.getClient(), url, transparent); + browser.setCloseAllowed(); + browser.createImmediately(); + registerQueries(browser); + return browser; + } + + static void registerQueries(WDBrowser browser) { + Map handlerMap = browser.queryHandlers(); + + JSQueryHandler handler = browser.pointerLock(); + handlerMap.put(handler.getName(), handler); + } + + HashMap queryHandlers(); + ElementCenterQuery pointerLock(); +} diff --git a/src/main/java/net/montoyo/wd/utilities/browser/WDClientBrowser.java b/src/main/java/net/montoyo/wd/utilities/browser/WDClientBrowser.java new file mode 100644 index 0000000..738a445 --- /dev/null +++ b/src/main/java/net/montoyo/wd/utilities/browser/WDClientBrowser.java @@ -0,0 +1,27 @@ +package net.montoyo.wd.utilities.browser; + +import com.cinemamod.mcef.MCEFBrowser; +import com.cinemamod.mcef.MCEFClient; +import net.montoyo.wd.utilities.browser.handlers.js.queries.ElementCenterQuery; +import net.montoyo.wd.utilities.browser.handlers.js.JSQueryHandler; + +import java.util.HashMap; + +public class WDClientBrowser extends MCEFBrowser implements WDBrowser { + ElementCenterQuery lock = new ElementCenterQuery("ActiveElement","document.activeElement"); + HashMap handlerHashMap = new HashMap<>(); + + public WDClientBrowser(MCEFClient client, String url, boolean transparent) { + super(client, url, transparent); + } + + @Override + public HashMap queryHandlers() { + return handlerHashMap; + } + + @Override + public ElementCenterQuery pointerLock() { + return lock; + } +} diff --git a/src/main/java/net/montoyo/wd/client/handlers/DisplayHandler.java b/src/main/java/net/montoyo/wd/utilities/browser/handlers/DisplayHandler.java similarity index 94% rename from src/main/java/net/montoyo/wd/client/handlers/DisplayHandler.java rename to src/main/java/net/montoyo/wd/utilities/browser/handlers/DisplayHandler.java index e09c75e..a43a543 100644 --- a/src/main/java/net/montoyo/wd/client/handlers/DisplayHandler.java +++ b/src/main/java/net/montoyo/wd/utilities/browser/handlers/DisplayHandler.java @@ -1,8 +1,8 @@ -package net.montoyo.wd.client.handlers; +package net.montoyo.wd.utilities.browser.handlers; import net.montoyo.wd.WebDisplays; import net.montoyo.wd.client.ClientProxy; -import net.montoyo.wd.client.handlers.js.Scripts; +import net.montoyo.wd.utilities.browser.handlers.js.Scripts; import net.montoyo.wd.entity.ScreenBlockEntity; import net.montoyo.wd.net.WDNetworkRegistry; import net.montoyo.wd.net.server_bound.C2SMessageMinepadUrl; @@ -11,8 +11,6 @@ import org.cef.browser.CefBrowser; import org.cef.browser.CefFrame; import org.cef.handler.CefDisplayHandler; -import java.io.InputStream; - public class DisplayHandler implements CefDisplayHandler { diff --git a/src/main/java/net/montoyo/wd/client/handlers/js/WDRouter.java b/src/main/java/net/montoyo/wd/utilities/browser/handlers/WDRouter.java similarity index 65% rename from src/main/java/net/montoyo/wd/client/handlers/js/WDRouter.java rename to src/main/java/net/montoyo/wd/utilities/browser/handlers/WDRouter.java index 16cb612..7626615 100644 --- a/src/main/java/net/montoyo/wd/client/handlers/js/WDRouter.java +++ b/src/main/java/net/montoyo/wd/utilities/browser/handlers/WDRouter.java @@ -1,13 +1,16 @@ -package net.montoyo.wd.client.handlers.js; +package net.montoyo.wd.utilities.browser.handlers; import com.google.gson.Gson; import com.google.gson.JsonObject; +import net.montoyo.wd.utilities.browser.WDBrowser; +import net.montoyo.wd.utilities.browser.handlers.js.JSQueryHandler; import org.cef.browser.CefBrowser; import org.cef.browser.CefFrame; import org.cef.callback.CefQueryCallback; import org.cef.handler.CefMessageRouterHandlerAdapter; import java.util.ArrayList; +import java.util.Map; import java.util.concurrent.CompletableFuture; import java.util.function.BiConsumer; import java.util.function.Consumer; @@ -57,7 +60,33 @@ public class WDRouter extends CefMessageRouterHandlerAdapter { awaitingQueries.remove(target); callback.success(""); } else { - callback.failure(-1, "Query " + queryId + " with data " + request + " completed, but there was no active request waiting for the result."); + if (browser instanceof WDBrowser wdBrowser) { + Map handlerMap = wdBrowser.queryHandlers(); + + int i0 = request.indexOf('('); // legacy, TODO: support + int i1 = request.indexOf('{'); + if (i0 == -1) i0 = i1; + if (i1 == -1) { + if (handlerMap.containsKey(request)) { + if (!handlerMap.get(request).handle(browser, frame, null, persistent, callback)) { + callback.failure(-1, "Query " + queryId + " with data " + request + " completed, but wasn't marked as successful."); + } + } + } + + int min = Math.min(i0, i1); + String text = request.substring(0, min); + if (handlerMap.containsKey(text)) { + JsonObject obj = null; + if (request.charAt(min) == '{') + obj = gson.fromJson(request.substring(min), JsonObject.class); + + if (!handlerMap.get(text).handle(browser, frame, obj, persistent, callback)) { + callback.failure(-1, "Query " + queryId + " with data " + request + " completed, but wasn't marked as successful."); + } + } + callback.failure(-1, "Query " + queryId + " with data " + request + " completed, but there was no active request waiting for the result."); + } } return true; diff --git a/src/main/java/net/montoyo/wd/client/handlers/js/FileName.java b/src/main/java/net/montoyo/wd/utilities/browser/handlers/js/FileName.java similarity index 76% rename from src/main/java/net/montoyo/wd/client/handlers/js/FileName.java rename to src/main/java/net/montoyo/wd/utilities/browser/handlers/js/FileName.java index 93ae3df..7ff15b3 100644 --- a/src/main/java/net/montoyo/wd/client/handlers/js/FileName.java +++ b/src/main/java/net/montoyo/wd/utilities/browser/handlers/js/FileName.java @@ -1,4 +1,4 @@ -package net.montoyo.wd.client.handlers.js; +package net.montoyo.wd.utilities.browser.handlers.js; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; diff --git a/src/main/java/net/montoyo/wd/utilities/browser/handlers/js/JSQueryHandler.java b/src/main/java/net/montoyo/wd/utilities/browser/handlers/js/JSQueryHandler.java new file mode 100644 index 0000000..a33d8e2 --- /dev/null +++ b/src/main/java/net/montoyo/wd/utilities/browser/handlers/js/JSQueryHandler.java @@ -0,0 +1,20 @@ +package net.montoyo.wd.utilities.browser.handlers.js; + +import com.google.gson.JsonObject; +import org.cef.browser.CefBrowser; +import org.cef.browser.CefFrame; +import org.cef.callback.CefQueryCallback; + +public abstract class JSQueryHandler { + protected final String name; + + public JSQueryHandler(String name) { + this.name = name; + } + + public abstract boolean handle(CefBrowser browser, CefFrame frame, JsonObject data, boolean persistent, CefQueryCallback callback); + + public final String getName() { + return name; + } +} diff --git a/src/main/java/net/montoyo/wd/client/handlers/js/Scripts.java b/src/main/java/net/montoyo/wd/utilities/browser/handlers/js/Scripts.java similarity index 78% rename from src/main/java/net/montoyo/wd/client/handlers/js/Scripts.java rename to src/main/java/net/montoyo/wd/utilities/browser/handlers/js/Scripts.java index ba5db10..23d0dd3 100644 --- a/src/main/java/net/montoyo/wd/client/handlers/js/Scripts.java +++ b/src/main/java/net/montoyo/wd/utilities/browser/handlers/js/Scripts.java @@ -1,6 +1,6 @@ -package net.montoyo.wd.client.handlers.js; +package net.montoyo.wd.utilities.browser.handlers.js; -import net.montoyo.wd.client.handlers.DisplayHandler; +import net.montoyo.wd.utilities.browser.handlers.DisplayHandler; import java.io.InputStream; import java.lang.reflect.Field; @@ -12,6 +12,8 @@ public class Scripts { public static final String POINTER_LOCK = get(); @FileName("assets/webdisplays/js/mouse_event.js") public static final String MOUSE_EVENT = get(); + @FileName("assets/webdisplays/js/query_element.js") + public static final String QUERY_ELEMENT = get(); private static String get() { Field field = Scripts.class.getDeclaredFields()[index++]; diff --git a/src/main/java/net/montoyo/wd/utilities/browser/handlers/js/queries/ElementCenterQuery.java b/src/main/java/net/montoyo/wd/utilities/browser/handlers/js/queries/ElementCenterQuery.java new file mode 100644 index 0000000..cf2ca37 --- /dev/null +++ b/src/main/java/net/montoyo/wd/utilities/browser/handlers/js/queries/ElementCenterQuery.java @@ -0,0 +1,71 @@ +package net.montoyo.wd.utilities.browser.handlers.js.queries; + +import com.google.gson.JsonObject; +import net.montoyo.wd.utilities.browser.handlers.js.JSQueryHandler; +import net.montoyo.wd.utilities.browser.handlers.js.Scripts; +import org.cef.browser.CefBrowser; +import org.cef.browser.CefFrame; +import org.cef.callback.CefQueryCallback; + +public class ElementCenterQuery extends JSQueryHandler { + boolean exists = false; + double x, y; + long start = -1; + + String elementName; + + public ElementCenterQuery(String queryName, String name) { + super(queryName); + elementName = name; + } + + @Override + public boolean handle(CefBrowser browser, CefFrame frame, JsonObject data, boolean persistent, CefQueryCallback callback) { + exists = data.getAsJsonPrimitive("exists").getAsBoolean(); + if (exists) { + x = data.getAsJsonPrimitive("x").getAsDouble() + data.getAsJsonPrimitive("w").getAsDouble() / 2; + y = data.getAsJsonPrimitive("y").getAsDouble() + data.getAsJsonPrimitive("h").getAsDouble() / 2; + } + + start = -1; + callback.success(""); + return true; + } + + public void dispatch(CefBrowser browser) { + if (start == -1) { + browser.executeJavaScript( + Scripts.QUERY_ELEMENT + .replace("%type%", elementName) + .replace("%Type%", name), + "CenterQuery", + 0 + ); + start = System.currentTimeMillis(); + } else { + long ms = System.currentTimeMillis(); + if (start + 1000 < ms) { + browser.executeJavaScript( + Scripts.QUERY_ELEMENT + .replace("%type%", elementName) + .replace("%Type%", name), + "KeyboardCamera", + 0 + ); + start = System.currentTimeMillis(); + } + } + } + + public boolean hasFocused() { + return exists; + } + + public double getX() { + return x; + } + + public double getY() { + return y; + } +} diff --git a/src/main/resources/assets/webdisplays/js/pointer_lock.js b/src/main/resources/assets/webdisplays/js/pointer_lock.js index 96b07b3..d407f91 100644 --- a/src/main/resources/assets/webdisplays/js/pointer_lock.js +++ b/src/main/resources/assets/webdisplays/js/pointer_lock.js @@ -12,10 +12,31 @@ elemRef['unadjusted'] = unadjustedMovement; document.pointerLockElement = elemRef['element']; document.dispatchEvent(new Event("pointerlockchange")); + + + let bodyRect = document.body.getBoundingClientRect(); + let elemRect = this.getBoundingClientRect(); + + window.cefQuery({ + request: 'WebDisplays_ActiveElement{exists: true,'+ + 'x: ' + (elemRect.left) + ',' + + 'y: ' + (elemRect.top) + ',' + + 'w: ' + ((elemRect.right - elemRect.left)) + ',' + + 'h: ' + ((elemRect.bottom - elemRect.top)) + + '}', + onSuccess: function(response) {}, + onFailure: function(error_code, error_message) {} + }); } Document.prototype.exitPointerLock = () => { elemRef['element'] = undefined; elemRef['unadjusted'] = false; document.pointerLockElement = elemRef['element']; + + window.cefQuery({ + request: 'WebDisplays_ActiveElement{exists: false}', + onSuccess: function(response) {}, + onFailure: function(error_code, error_message) {} + }); } } diff --git a/src/main/resources/assets/webdisplays/js/query_element.js b/src/main/resources/assets/webdisplays/js/query_element.js new file mode 100644 index 0000000..ef09f45 --- /dev/null +++ b/src/main/resources/assets/webdisplays/js/query_element.js @@ -0,0 +1,31 @@ +try { + let focusedElement = %type%; + if (focusedElement == null || focusedElement == document.body) { + window.cefQuery({ + request: 'WebDisplays_%Type%{exists: false}', + onSuccess: function(response) {}, + onFailure: function(error_code, error_message) {} + }); + } else { + let bodyRect = document.body.getBoundingClientRect(); + let elemRect = focusedElement.getBoundingClientRect(); + + window.cefQuery({ + request: 'WebDisplays_%Type%{exists: true,'+ + 'x: ' + (elemRect.left) + ',' + + 'y: ' + (elemRect.top) + ',' + + 'w: ' + ((elemRect.right - elemRect.left)) + ',' + + 'h: ' + ((elemRect.bottom - elemRect.top)) + + '}', + onSuccess: function(response) {}, + onFailure: function(error_code, error_message) {} + }); + } +} catch (err) { + console.error(err); + window.cefQuery({ + request: 'WebDisplays_%Type%{exists: false}', + onSuccess: function(response) {}, + onFailure: function(error_code, error_message) {} + }); +} \ No newline at end of file