tweaks to js handling

This commit is contained in:
GiantLuigi4 2023-11-27 15:18:30 -05:00
parent 2e30446281
commit 7e7133e08c
13 changed files with 178 additions and 106 deletions

View File

@ -17,6 +17,7 @@ import net.minecraft.network.chat.Component;
import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.api.distmarker.OnlyIn;
import net.montoyo.wd.WebDisplays; import net.montoyo.wd.WebDisplays;
import net.montoyo.wd.client.ClientProxy; import net.montoyo.wd.client.ClientProxy;
import net.montoyo.wd.utilities.browser.WDBrowser;
import net.montoyo.wd.utilities.browser.handlers.js.Scripts; import net.montoyo.wd.utilities.browser.handlers.js.Scripts;
import net.montoyo.wd.utilities.browser.handlers.WDRouter; import net.montoyo.wd.utilities.browser.handlers.WDRouter;
import net.montoyo.wd.utilities.data.BlockSide; import net.montoyo.wd.utilities.data.BlockSide;
@ -342,55 +343,10 @@ public class GuiMinePad extends WDScreen {
} }
} }
private static WDRouter.Task<JsonObject> activeTask;
private static long futureStart = 0;
protected void pollElement() { protected void pollElement() {
if (activeTask != null) { if (pad.view instanceof WDBrowser browser) {
if (System.currentTimeMillis() - 1000 > futureStart) { JsonObject object = browser.pointerLockElement().getObj();
activeTask.cancel(); if (object != null) updateCrd(object);
activeTask = null;
} else return;
} }
//@formatter:off
activeTask = WDRouter.INSTANCE.requestJson(pad.view, "PointerElement", """
try {
let focusedElement = document.pointerLockElement;
if (focusedElement == null || focusedElement == document.body) {
window.cefQuery({
request: 'WebDisplays_PointerElement{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_PointerElement{exists: true,'+
'x: ' + (elemRect.left) + ',' +
'y: ' + (elemRect.top) + ',' +
'w: ' + ((elemRect.right - elemRect.left)) + ',' +
'h: ' + ((elemRect.bottom - elemRect.top)) + ',' +
'unadjust: ' + document.webdisplays__unadjustPointerMotion +
'}',
onSuccess: function(response) {},
onFailure: function(error_code, error_message) {}
});
}
} catch (err) {
console.error(err);
window.cefQuery({
request: 'WebDisplays_PointerElement{exists: false}',
onSuccess: function(response) {},
onFailure: function(error_code, error_message) {}
});
}""".replace("\n", "")
).thenAccept((o1) -> {
updateCrd(o1);
activeTask = null;
});
futureStart = System.currentTimeMillis();
//@formatter:on
} }
} }

View File

@ -51,7 +51,7 @@ public class ScreenRenderer implements BlockEntityRenderer<ScreenBlockEntity> {
if (scr.browser == null) { if (scr.browser == null) {
double dist = WebDisplays.PROXY.distanceTo(te, Minecraft.getInstance().getEntityRenderDispatcher().camera.getPosition()); double dist = WebDisplays.PROXY.distanceTo(te, Minecraft.getInstance().getEntityRenderDispatcher().camera.getPosition());
if (dist <= WebDisplays.INSTANCE.loadDistance2 * 16) if (dist <= WebDisplays.INSTANCE.loadDistance2 * 16)
scr.createBrowser(true); scr.createBrowser(te, true);
else continue; else continue;
} }

View File

@ -135,7 +135,7 @@ public class ScreenBlockEntity extends BlockEntity {
public void handleUpdateTag(CompoundTag tag) { public void handleUpdateTag(CompoundTag tag) {
load(tag); load(tag);
for (ScreenData screen : screens) { for (ScreenData screen : screens) {
if (screen.browser == null) screen.createBrowser(false); if (screen.browser == null) screen.createBrowser(this, false);
if (screen.browser != null) screen.browser.loadURL(screen.url); if (screen.browser != null) screen.browser.loadURL(screen.url);
} }
updateAABB(); updateAABB();
@ -1085,7 +1085,7 @@ public class ScreenBlockEntity extends BlockEntity {
public void activate() { public void activate() {
for (ScreenData screen : screens) { for (ScreenData screen : screens) {
if (screen.browser == null) if (screen.browser == null)
screen.createBrowser(false); screen.createBrowser(this, false);
} }
} }

View File

@ -10,11 +10,13 @@ import net.minecraft.nbt.ListTag;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.montoyo.wd.WebDisplays; import net.montoyo.wd.WebDisplays;
import net.montoyo.wd.client.ClientProxy; import net.montoyo.wd.client.ClientProxy;
import net.montoyo.wd.config.CommonConfig; import net.montoyo.wd.config.CommonConfig;
import net.montoyo.wd.core.ScreenRights; import net.montoyo.wd.core.ScreenRights;
import net.montoyo.wd.utilities.*; import net.montoyo.wd.utilities.*;
import net.montoyo.wd.utilities.browser.InWorldQueries;
import net.montoyo.wd.utilities.browser.WDBrowser; import net.montoyo.wd.utilities.browser.WDBrowser;
import net.montoyo.wd.utilities.data.BlockSide; import net.montoyo.wd.utilities.data.BlockSide;
import net.montoyo.wd.utilities.data.Rotation; import net.montoyo.wd.utilities.data.Rotation;
@ -183,21 +185,23 @@ public class ScreenData {
} }
} }
public void createBrowser(boolean doAnim) { public void createBrowser(ScreenBlockEntity be, boolean doAnim) {
if (WebDisplays.PROXY instanceof ClientProxy clientProxy) { if (WebDisplays.PROXY instanceof ClientProxy) {
browser = WDBrowser.createBrowser(WebDisplays.applyBlacklist(url != null ? url : "https://www.google.com"), false); browser = WDBrowser.createBrowser(WebDisplays.applyBlacklist(url != null ? url : "https://www.google.com"), false);
// set screen
if (browser instanceof MCEFBrowser mcefBrowser) { if (browser instanceof MCEFBrowser mcefBrowser) {
if (rotation.isVertical) if (rotation.isVertical)
mcefBrowser.resize(resolution.y, resolution.x); mcefBrowser.resize(resolution.y, resolution.x);
else else
mcefBrowser.resize(resolution.x, resolution.y); mcefBrowser.resize(resolution.x, resolution.y);
// uh yes this is intentional mcefBrowser.setCursorChangeListener((type) -> mouseType = type);
// basically: on my laptop, this line caused an error inexplicably }
// reason: the compiler didn't update this file, so it stayed as a Consumer<Integer> in the bytecode
//noinspection RedundantCast // setup screen as in world
mcefBrowser.setCursorChangeListener((MCEFCursorChangeListener) (type) -> mouseType = type); if (browser instanceof WDBrowser wdBrowser) {
InWorldQueries.attach(be, side, wdBrowser);
} }
doTurnOnAnim = doAnim; doTurnOnAnim = doAnim;

View File

@ -0,0 +1,14 @@
package net.montoyo.wd.utilities.browser;
import net.montoyo.wd.entity.ScreenBlockEntity;
import net.montoyo.wd.utilities.browser.handlers.js.queries.GetSizeQuery;
import net.montoyo.wd.utilities.data.BlockSide;
public class InWorldQueries {
private static final GetSizeQuery getSize = new GetSizeQuery();
public static void attach(ScreenBlockEntity blockEntity, BlockSide side, WDBrowser browser) {
browser.setBe(blockEntity, side);
browser.queryHandlers().put(getSize.getName(), getSize);
}
}

View File

@ -1,8 +1,10 @@
package net.montoyo.wd.utilities.browser; package net.montoyo.wd.utilities.browser;
import com.cinemamod.mcef.MCEF; import com.cinemamod.mcef.MCEF;
import net.montoyo.wd.entity.ScreenBlockEntity;
import net.montoyo.wd.utilities.browser.handlers.js.queries.ElementCenterQuery; import net.montoyo.wd.utilities.browser.handlers.js.queries.ElementCenterQuery;
import net.montoyo.wd.utilities.browser.handlers.js.JSQueryHandler; import net.montoyo.wd.utilities.browser.handlers.js.JSQueryHandler;
import net.montoyo.wd.utilities.data.BlockSide;
import org.cef.browser.CefBrowser; import org.cef.browser.CefBrowser;
import java.util.HashMap; import java.util.HashMap;
@ -20,10 +22,19 @@ public interface WDBrowser {
static void registerQueries(WDBrowser browser) { static void registerQueries(WDBrowser browser) {
Map<String, JSQueryHandler> handlerMap = browser.queryHandlers(); Map<String, JSQueryHandler> handlerMap = browser.queryHandlers();
JSQueryHandler handler = browser.focusedElement(); JSQueryHandler handler;
handler = browser.focusedElement();
handlerMap.put(handler.getName(), handler);
handler = browser.pointerLockElement();
handlerMap.put(handler.getName(), handler); handlerMap.put(handler.getName(), handler);
} }
HashMap<String, JSQueryHandler> queryHandlers(); HashMap<String, JSQueryHandler> queryHandlers();
ElementCenterQuery focusedElement(); ElementCenterQuery focusedElement();
ElementCenterQuery pointerLockElement();
void setBe(ScreenBlockEntity blockEntity, BlockSide side);
ScreenBlockEntity getBe();
BlockSide getSide();
} }

View File

@ -2,15 +2,24 @@ package net.montoyo.wd.utilities.browser;
import com.cinemamod.mcef.MCEFBrowser; import com.cinemamod.mcef.MCEFBrowser;
import com.cinemamod.mcef.MCEFClient; import com.cinemamod.mcef.MCEFClient;
import net.montoyo.wd.entity.ScreenBlockEntity;
import net.montoyo.wd.utilities.browser.handlers.js.queries.ElementCenterQuery; import net.montoyo.wd.utilities.browser.handlers.js.queries.ElementCenterQuery;
import net.montoyo.wd.utilities.browser.handlers.js.JSQueryHandler; import net.montoyo.wd.utilities.browser.handlers.js.JSQueryHandler;
import net.montoyo.wd.utilities.data.BlockSide;
import java.util.HashMap; import java.util.HashMap;
public class WDClientBrowser extends MCEFBrowser implements WDBrowser { public class WDClientBrowser extends MCEFBrowser implements WDBrowser {
ElementCenterQuery focusedEl = new ElementCenterQuery("ActiveElement", "document.activeElement"); ElementCenterQuery focusedEl = new ElementCenterQuery("ActiveElement", "document.activeElement");
ElementCenterQuery pointerLockEl =
new ElementCenterQuery("PointerElement", "document.pointerLockElement")
.addAdditional("unadjust", "document.webdisplays__unadjustPointerMotion")
;
HashMap<String, JSQueryHandler> handlerHashMap = new HashMap<>(); HashMap<String, JSQueryHandler> handlerHashMap = new HashMap<>();
ScreenBlockEntity be;
BlockSide side;
public WDClientBrowser(MCEFClient client, String url, boolean transparent) { public WDClientBrowser(MCEFClient client, String url, boolean transparent) {
super(client, url, transparent); super(client, url, transparent);
} }
@ -24,4 +33,25 @@ public class WDClientBrowser extends MCEFBrowser implements WDBrowser {
public ElementCenterQuery focusedElement() { public ElementCenterQuery focusedElement() {
return focusedEl; return focusedEl;
} }
@Override
public ElementCenterQuery pointerLockElement() {
return pointerLockEl;
}
@Override
public void setBe(ScreenBlockEntity blockEntity, BlockSide side) {
this.be = blockEntity;
this.side = side;
}
@Override
public ScreenBlockEntity getBe() {
return be;
}
@Override
public BlockSide getSide() {
return side;
}
} }

View File

@ -66,26 +66,28 @@ public class WDRouter extends CefMessageRouterHandlerAdapter {
int i0 = request.indexOf('('); // legacy, TODO: support int i0 = request.indexOf('('); // legacy, TODO: support
int i1 = request.indexOf('{'); int i1 = request.indexOf('{');
if (i0 == -1) i0 = i1; if (i0 == -1) i0 = i1;
if (i1 == -1) i1 = i0;
if (i1 == -1) { if (i1 == -1) {
if (handlerMap.containsKey(request)) { if (handlerMap.containsKey(request)) {
if (!handlerMap.get(request).handle(browser, frame, null, persistent, callback)) { 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."); callback.failure(-1, "Query " + queryId + " with data " + request + " completed, but wasn't marked as successful.");
} }
} }
} } else {
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);
int min = Math.min(i0, i1); if (!handlerMap.get(text).handle(browser, frame, obj, persistent, callback)) {
String text = request.substring(0, min); callback.failure(-1, "Query " + queryId + " with data " + request + " completed, but wasn't marked as successful.");
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.");
} }
callback.failure(-1, "Query " + queryId + " with data " + request + " completed, but there was no active request waiting for the result.");
} }
} }

View File

@ -10,15 +10,24 @@ import org.cef.callback.CefQueryCallback;
public class ElementCenterQuery extends JSQueryHandler { public class ElementCenterQuery extends JSQueryHandler {
boolean exists = false; boolean exists = false;
double x, y; double x, y;
JsonObject obj;
long start = -1; long start = -1;
String extra;
String elementName; String elementName;
String script = null;
public ElementCenterQuery(String queryName, String name) { public ElementCenterQuery(String queryName, String name) {
super(queryName); super(queryName);
elementName = name; elementName = name;
} }
public ElementCenterQuery addAdditional(String key, String value) {
extra += "'" + key + "':" + value + " + ";
script = null;
return this;
}
@Override @Override
public boolean handle(CefBrowser browser, CefFrame frame, JsonObject data, boolean persistent, CefQueryCallback callback) { public boolean handle(CefBrowser browser, CefFrame frame, JsonObject data, boolean persistent, CefQueryCallback callback) {
exists = data.getAsJsonPrimitive("exists").getAsBoolean(); exists = data.getAsJsonPrimitive("exists").getAsBoolean();
@ -26,18 +35,25 @@ public class ElementCenterQuery extends JSQueryHandler {
x = data.getAsJsonPrimitive("x").getAsDouble() + data.getAsJsonPrimitive("w").getAsDouble() / 2; x = data.getAsJsonPrimitive("x").getAsDouble() + data.getAsJsonPrimitive("w").getAsDouble() / 2;
y = data.getAsJsonPrimitive("y").getAsDouble() + data.getAsJsonPrimitive("h").getAsDouble() / 2; y = data.getAsJsonPrimitive("y").getAsDouble() + data.getAsJsonPrimitive("h").getAsDouble() / 2;
} }
obj = data;
start = -1; start = -1;
callback.success(""); callback.success("Success");
return true; return true;
} }
public void dispatch(CefBrowser browser) { public void dispatch(CefBrowser browser) {
if (script == null) {
script = Scripts.QUERY_ELEMENT
.replace("%type%", elementName)
.replace("%Type%", name)
.replace("%extra%", extra)
;
}
if (start == -1) { if (start == -1) {
browser.executeJavaScript( browser.executeJavaScript(
Scripts.QUERY_ELEMENT script,
.replace("%type%", elementName)
.replace("%Type%", name),
"CenterQuery", "CenterQuery",
0 0
); );
@ -46,10 +62,8 @@ public class ElementCenterQuery extends JSQueryHandler {
long ms = System.currentTimeMillis(); long ms = System.currentTimeMillis();
if (start + 1000 < ms) { if (start + 1000 < ms) {
browser.executeJavaScript( browser.executeJavaScript(
Scripts.QUERY_ELEMENT script,
.replace("%type%", elementName) "CenterQuery",
.replace("%Type%", name),
"KeyboardCamera",
0 0
); );
start = System.currentTimeMillis(); start = System.currentTimeMillis();
@ -68,4 +82,8 @@ public class ElementCenterQuery extends JSQueryHandler {
public double getY() { public double getY() {
return y; return y;
} }
public JsonObject getObj() {
return obj;
}
} }

View File

@ -0,0 +1,32 @@
package net.montoyo.wd.utilities.browser.handlers.js.queries;
import com.google.gson.JsonObject;
import net.montoyo.wd.utilities.browser.WDBrowser;
import net.montoyo.wd.utilities.browser.handlers.js.JSQueryHandler;
import net.montoyo.wd.utilities.math.Vector2i;
import org.cef.browser.CefBrowser;
import org.cef.browser.CefFrame;
import org.cef.callback.CefQueryCallback;
public class GetSizeQuery extends JSQueryHandler {
public GetSizeQuery() {
super("GetSize");
}
@Override
public boolean handle(CefBrowser browser, CefFrame frame, JsonObject data, boolean persistent, CefQueryCallback callback) {
if (browser instanceof WDBrowser wdBrowser) {
if (wdBrowser.getSide() != null) {
Vector2i sz = wdBrowser.getBe().getScreen(
wdBrowser.getSide()
).size;
callback.success(
"{\"x\":" + sz.x + ",\"y\":" + sz.y + "}"
);
return true;
}
}
callback.failure(404, "Screen has been removed.");
return true;
}
}

View File

@ -5,7 +5,7 @@
*/ */
function wdExecRequest(name, func) { function wdExecRequest(name, func) {
window.mcefQuery({ request: "WebDisplays_" + name, window.cefQuery({ request: "WebDisplays_" + name,
persistent: true, persistent: true,
onSuccess: function(response) { onSuccess: function(response) {
try { try {

View File

@ -11,21 +11,26 @@
elemRef['element'] = this; elemRef['element'] = this;
elemRef['unadjusted'] = unadjustedMovement; elemRef['unadjusted'] = unadjustedMovement;
document.pointerLockElement = elemRef['element']; document.pointerLockElement = elemRef['element'];
document.dispatchEvent(new Event("pointerlockchange"));
let bodyRect = document.body.getBoundingClientRect(); let bodyRect = document.body.getBoundingClientRect();
let elemRect = this.getBoundingClientRect(); let elemRect = this.getBoundingClientRect();
let doc = document;
window.cefQuery({ window.cefQuery({
request: 'WebDisplays_ActiveElement{exists: true,'+ request:
'x: ' + (elemRect.left) + ',' + 'WebDisplays_PointerElement{' +
'y: ' + (elemRect.top) + ',' + 'exists:true,' +
'w: ' + ((elemRect.right - elemRect.left)) + ',' + 'x:' + (elemRect.left) + ',' +
'h: ' + ((elemRect.bottom - elemRect.top)) + 'y:' + (elemRect.top) + ',' +
'}', 'w:' + ((elemRect.right - elemRect.left)) + ',' +
onSuccess: function(response) {}, 'h:' + ((elemRect.bottom - elemRect.top)) + ',' +
onFailure: function(error_code, error_message) {} 'unadjust:' + document.webdisplays__unadjustPointerMotion +
'}', onSuccess: function(response) {
doc.dispatchEvent(new Event("pointerlockchange"));
},
onFailure: function(error_code, error_message) {
doc.dispatchEvent(new Event("pointerlockerror"));
}
}); });
} }
Document.prototype.exitPointerLock = () => { Document.prototype.exitPointerLock = () => {
@ -34,9 +39,9 @@
document.pointerLockElement = elemRef['element']; document.pointerLockElement = elemRef['element'];
window.cefQuery({ window.cefQuery({
request: 'WebDisplays_ActiveElement{exists: false}', request: 'WebDisplays_PointerElement{exists: false}',
onSuccess: function(response) {}, onSuccess: function(response) {},
onFailure: function(error_code, error_message) {} onFailure: function(error_code, error_message) {}
}); });
} }
} }

View File

@ -2,30 +2,30 @@ try {
let focusedElement = %type%; let focusedElement = %type%;
if (focusedElement == null || focusedElement == document.body) { if (focusedElement == null || focusedElement == document.body) {
window.cefQuery({ window.cefQuery({
request: 'WebDisplays_%Type%{exists: false}', request: 'WebDisplays_%Type%{exists: false}',
onSuccess: function(response) {}, onSuccess: function(response) {},
onFailure: function(error_code, error_message) {} onFailure: function(error_code, error_message) {}
}); });
} else { } else {
let bodyRect = document.body.getBoundingClientRect(); let bodyRect = document.body.getBoundingClientRect();
let elemRect = focusedElement.getBoundingClientRect(); let elemRect = focusedElement.getBoundingClientRect();
window.cefQuery({ window.cefQuery({
request: 'WebDisplays_%Type%{exists: true,'+ request: 'WebDisplays_%Type%{' +
'x: ' + (elemRect.left) + ',' + 'exists:true,' +
'y: ' + (elemRect.top) + ',' + 'x:' + (elemRect.left) + ',' +
'w: ' + ((elemRect.right - elemRect.left)) + ',' + 'y:' + (elemRect.top) + ',' +
'h: ' + ((elemRect.bottom - elemRect.top)) + 'w:' + ((elemRect.right - elemRect.left)) + ',' +
'}', 'h:' + ((elemRect.bottom - elemRect.top)) + %extra%
onSuccess: function(response) {}, '}', onSuccess: function(response) {},
onFailure: function(error_code, error_message) {} onFailure: function(error_code, error_message) {}
}); });
} }
} catch (err) { } catch (err) {
console.error(err); console.error(err);
window.cefQuery({ window.cefQuery({
request: 'WebDisplays_%Type%{exists: false}', request: 'WebDisplays_%Type%{exists: false}',
onSuccess: function(response) {}, onSuccess: function(response) {},
onFailure: function(error_code, error_message) {} onFailure: function(error_code, error_message) {}
}); });
} }