From bc16cf9769bcdee75daa852b04f798c506ef3501 Mon Sep 17 00:00:00 2001 From: GiantLuigi4 <49770992+GiantLuigi4@users.noreply.github.com> Date: Tue, 14 Mar 2023 13:00:34 -0400 Subject: [PATCH] large reworks of network code, various fixes --- build.gradle | 2 +- src/main/java/net/montoyo/wd/WebDisplays.java | 5 + .../net/montoyo/wd/block/BlockScreen.java | 124 +++--- .../net/montoyo/wd/client/ClientProxy.java | 12 +- .../wd/client/gui/GuiScreenConfig.java | 12 +- .../wd/client/renderers/ScreenRenderer.java | 261 ++++++----- .../montoyo/wd/controls/ScreenControl.java | 38 ++ .../wd/controls/ScreenControlRegistry.java | 73 ++++ .../wd/controls/ScreenControlType.java | 15 + .../controls/builtin/AutoVolumeControl.java | 49 +++ .../wd/controls/builtin/JSRequestControl.java | 63 +++ .../wd/controls/builtin/KeyTypedControl.java | 52 +++ .../wd/controls/builtin/LaserControl.java | 64 +++ .../ManageRightsAndUpdgradesControl.java | 97 +++++ .../builtin/ModifyFriendListControl.java | 56 +++ .../controls/builtin/ScreenModifyControl.java | 71 +++ .../wd/controls/builtin/SetURLControl.java | 63 +++ .../net/montoyo/wd/core/ScreenRights.java | 7 +- .../net/montoyo/wd/data/ScreenConfigData.java | 2 +- .../wd/entity/TileEntityInterfaceBase.java | 12 +- .../montoyo/wd/entity/TileEntityKeyboard.java | 6 +- .../montoyo/wd/entity/TileEntityScreen.java | 5 +- .../java/net/montoyo/wd/net/BufferUtils.java | 5 +- .../net/client_bound/S2CMessageACResult.java | 13 +- .../net/client_bound/S2CMessageAddScreen.java | 74 ++-- .../net/client_bound/S2CMessageCloseGui.java | 18 +- .../client_bound/S2CMessageJSResponse.java | 24 +- .../client_bound/S2CMessageMiniservKey.java | 2 +- .../net/client_bound/S2CMessageOpenGui.java | 8 +- .../client_bound/S2CMessageScreenUpdate.java | 40 +- .../client_bound/S2CMessageServerInfo.java | 4 +- .../net/server_bound/C2SMessageACQuery.java | 26 +- .../C2SMessageMiniservConnect.java | 6 +- .../server_bound/C2SMessageRedstoneCtrl.java | 128 +++--- .../server_bound/C2SMessageScreenCtrl.java | 409 +++++------------- .../net/montoyo/wd/utilities/VideoType.java | 1 + .../assets/webdisplays/lang/en_us.json | 20 +- 37 files changed, 1190 insertions(+), 677 deletions(-) create mode 100644 src/main/java/net/montoyo/wd/controls/ScreenControl.java create mode 100644 src/main/java/net/montoyo/wd/controls/ScreenControlRegistry.java create mode 100644 src/main/java/net/montoyo/wd/controls/ScreenControlType.java create mode 100644 src/main/java/net/montoyo/wd/controls/builtin/AutoVolumeControl.java create mode 100644 src/main/java/net/montoyo/wd/controls/builtin/JSRequestControl.java create mode 100644 src/main/java/net/montoyo/wd/controls/builtin/KeyTypedControl.java create mode 100644 src/main/java/net/montoyo/wd/controls/builtin/LaserControl.java create mode 100644 src/main/java/net/montoyo/wd/controls/builtin/ManageRightsAndUpdgradesControl.java create mode 100644 src/main/java/net/montoyo/wd/controls/builtin/ModifyFriendListControl.java create mode 100644 src/main/java/net/montoyo/wd/controls/builtin/ScreenModifyControl.java create mode 100644 src/main/java/net/montoyo/wd/controls/builtin/SetURLControl.java diff --git a/build.gradle b/build.gradle index 1186ece..0317ddc 100644 --- a/build.gradle +++ b/build.gradle @@ -80,7 +80,7 @@ dependencies { implementation fg.deobf("curse.maven:SU-370704:4410614") implementation fg.deobf("curse.maven:spark-361579:4381167") - implementation fg.deobf("curse.maven:vivecraft-667903:4409427") + compileOnly fg.deobf("curse.maven:vivecraft-667903:4409427") } sourceSets { diff --git a/src/main/java/net/montoyo/wd/WebDisplays.java b/src/main/java/net/montoyo/wd/WebDisplays.java index d5ab58e..900e7f8 100644 --- a/src/main/java/net/montoyo/wd/WebDisplays.java +++ b/src/main/java/net/montoyo/wd/WebDisplays.java @@ -41,6 +41,7 @@ import net.minecraftforge.network.PacketDistributor; import net.minecraftforge.registries.DeferredRegister; import net.minecraftforge.registries.ForgeRegistries; import net.montoyo.wd.config.ModConfig; +import net.montoyo.wd.controls.ScreenControlRegistry; import net.montoyo.wd.core.*; import net.montoyo.wd.init.BlockInit; import net.montoyo.wd.init.ItemInit; @@ -185,6 +186,10 @@ public class WebDisplays { t.printStackTrace(); } } */ + + if (!FMLEnvironment.production) { + ScreenControlRegistry.init(); + } } @SubscribeEvent diff --git a/src/main/java/net/montoyo/wd/block/BlockScreen.java b/src/main/java/net/montoyo/wd/block/BlockScreen.java index 4b22ddb..a8ac918 100644 --- a/src/main/java/net/montoyo/wd/block/BlockScreen.java +++ b/src/main/java/net/montoyo/wd/block/BlockScreen.java @@ -194,13 +194,18 @@ public class BlockScreen extends BaseEntityBlock { return InteractionResult.SUCCESS; } } else { - if ((scr.rightsFor(player) & ScreenRights.CLICK) == 0) { + if ((scr.rightsFor(player) & ScreenRights.INTERACT) == 0) { Util.toast(player, "restrictions"); return InteractionResult.SUCCESS; } Vector2i tmp = new Vector2i(); - if (hit2pixels(side, hit.getBlockPos(), pos, scr, (float) hit.getLocation().x, (float) hit.getLocation().y, (float) hit.getLocation().z, tmp)) + + float hitX = ((float) hit.getLocation().x) - (float) te.getBlockPos().getX(); + float hitY = ((float) hit.getLocation().y) - (float) te.getBlockPos().getY(); + float hitZ = ((float) hit.getLocation().z) - (float) te.getBlockPos().getZ(); + + if (hit2pixels(side, hit.getBlockPos(), new Vector3i(hit.getBlockPos()), scr, hitX, hitY, hitZ, tmp)) te.click(side, tmp); return InteractionResult.SUCCESS; } @@ -258,67 +263,64 @@ public class BlockScreen extends BaseEntityBlock { } } } - - public static boolean hit2pixels (BlockSide side, BlockPos bpos, Vector3i pos, TileEntityScreen.Screen scr, - float hitX, float hitY, float hitZ, Vector2i dst){ - if (side.right.x < 0) - hitX -= 1.f; - - if (side.right.z < 0 || side == BlockSide.TOP || side == BlockSide.BOTTOM) - hitZ -= 1.f; - - Vector3f rel = new Vector3f(hitX, hitY, hitZ); - rel.sub(pos.toBlock().getX(), pos.toBlock().getY(), pos.toBlock().getZ()); - - float cx = Math.abs(rel.dot(side.right.toFloat()) - 2.f / 16.f); - float cy = Math.abs(rel.dot(side.up.toFloat()) - 2.f / 16.f); - float sw = ((float) scr.size.x) - 4.f / 16.f; - float sh = ((float) scr.size.y) - 4.f / 16.f; - - cx /= sw; - cy /= sh; - - cx = cx - 0.05f; - cy = cy - 0.05f; - - if (cx >= 0 && cx <= 1 && cy >= 0 && cy <= 1) { - if (side != BlockSide.BOTTOM) - cy = 1.f - cy; - - switch (scr.rotation) { - case ROT_90: - cy = 1.0f - cy; - break; - - case ROT_180: - cx = 1.0f - cx; - cy = 1.0f - cy; - break; - - case ROT_270: - cx = 1.0f - cx; - break; - - default: - break; - } - - cx *= (float) scr.resolution.x; - cy *= (float) scr.resolution.y; - - if (scr.rotation.isVertical) { - dst.x = (int) cy; - dst.y = (int) cx; - } else { - dst.x = (int) cx; - dst.y = (int) cy; - } - - return true; + + public static boolean hit2pixels(BlockSide side, BlockPos bpos, Vector3i pos, TileEntityScreen.Screen scr, float hitX, float hitY, float hitZ, Vector2i dst) { + if(side.right.x < 0) + hitX -= 1.f; + + if(side.right.z < 0 || side == BlockSide.TOP || side == BlockSide.BOTTOM) + hitZ -= 1.f; + + Vector3f rel = new Vector3f(bpos.getX(), bpos.getY(), bpos.getZ()); + rel.sub((float) pos.x, (float) pos.y, (float) pos.z); + rel.add(hitX, hitY, hitZ); + + float cx = rel.dot(side.right.toFloat()) - 2.f / 16.f; + float cy = rel.dot(side.up.toFloat()) - 2.f / 16.f; + float sw = ((float) scr.size.x) - 4.f / 16.f; + float sh = ((float) scr.size.y) - 4.f / 16.f; + + cx /= sw; + cy /= sh; + + if(cx >= 0.f && cx <= 1.0 && cy >= 0.f && cy <= 1.f) { + if(side != BlockSide.BOTTOM) + cy = 1.f - cy; + + switch(scr.rotation) { + case ROT_90: + cy = 1.0f - cy; + break; + + case ROT_180: + cx = 1.0f - cx; + cy = 1.0f - cy; + break; + + case ROT_270: + cx = 1.0f - cx; + break; + + default: + break; } - - return false; + + cx *= (float) scr.resolution.x; + cy *= (float) scr.resolution.y; + + if(scr.rotation.isVertical) { + dst.x = (int) cy; + dst.y = (int) cx; + } else { + dst.x = (int) cx; + dst.y = (int) cy; + } + + return true; } + + return false; + } @org.jetbrains.annotations.Nullable @Override diff --git a/src/main/java/net/montoyo/wd/client/ClientProxy.java b/src/main/java/net/montoyo/wd/client/ClientProxy.java index d9e3339..be3d80b 100644 --- a/src/main/java/net/montoyo/wd/client/ClientProxy.java +++ b/src/main/java/net/montoyo/wd/client/ClientProxy.java @@ -630,8 +630,8 @@ public class ClientProxy extends SharedProxy implements IDisplayHandler, IJSQuer float hitY = ((float) result.getLocation().y) - (float) bpos.getY(); float hitZ = ((float) result.getLocation().z) - (float) bpos.getZ(); Vector2i tmp = new Vector2i(); - - if(BlockScreen.hit2pixels(side, bpos, pos, scr, hitX, hitY, hitZ, tmp)) { + + if(BlockScreen.hit2pixels(side, bpos, new Vector3i(result.getBlockPos()), scr, hitX, hitY, hitZ, tmp)) { laserClick(te, side, scr, tmp); } } @@ -694,13 +694,13 @@ public class ClientProxy extends SharedProxy implements IDisplayHandler, IJSQuer if(t - lastPointPacket >= 100) { lastPointPacket = t; - WDNetworkRegistry.INSTANCE.sendToServer(C2SMessageScreenCtrl.vec2(tes, side, C2SMessageScreenCtrl.CTRL_LASER_MOVE, hit)); + WDNetworkRegistry.INSTANCE.sendToServer(C2SMessageScreenCtrl.laserMove(tes, side, hit)); } } else { deselectScreen(); pointedScreen = tes; pointedScreenSide = side; - WDNetworkRegistry.INSTANCE.sendToServer(C2SMessageScreenCtrl.vec2(tes, side, C2SMessageScreenCtrl.CTRL_LASER_DOWN, hit)); + WDNetworkRegistry.INSTANCE.sendToServer(C2SMessageScreenCtrl.laserDown(tes, side, hit)); } } @@ -802,6 +802,8 @@ public class ClientProxy extends SharedProxy implements IDisplayHandler, IJSQuer @Override public BlockGetter getWorld(NetworkEvent.Context context) { - return Minecraft.getInstance().level; + BlockGetter senderLevel = super.getWorld(context); + if (senderLevel == null) return Minecraft.getInstance().level; + return senderLevel; } } diff --git a/src/main/java/net/montoyo/wd/client/gui/GuiScreenConfig.java b/src/main/java/net/montoyo/wd/client/gui/GuiScreenConfig.java index 98dec71..ee69954 100644 --- a/src/main/java/net/montoyo/wd/client/gui/GuiScreenConfig.java +++ b/src/main/java/net/montoyo/wd/client/gui/GuiScreenConfig.java @@ -133,17 +133,17 @@ public class GuiScreenConfig extends WDScreen { loadFrom(new ResourceLocation("webdisplays", "gui/screencfg.json")); friendBoxes = new CheckBox[] { boxFResolution, boxFUpgrades, boxFOthers, boxFFriends, boxFClick, boxFSetUrl }; - boxFResolution.setUserdata(ScreenRights.CHANGE_RESOLUTION); + boxFResolution.setUserdata(ScreenRights.MODIFY_SCREEN); boxFUpgrades.setUserdata(ScreenRights.MANAGE_UPGRADES); boxFOthers.setUserdata(ScreenRights.MANAGE_OTHER_RIGHTS); boxFFriends.setUserdata(ScreenRights.MANAGE_FRIEND_LIST); - boxFClick.setUserdata(ScreenRights.CLICK); + boxFClick.setUserdata(ScreenRights.INTERACT); boxFSetUrl.setUserdata(ScreenRights.CHANGE_URL); otherBoxes = new CheckBox[] { boxOResolution, boxOUpgrades, boxOClick, boxOSetUrl }; - boxOResolution.setUserdata(ScreenRights.CHANGE_RESOLUTION); + boxOResolution.setUserdata(ScreenRights.MODIFY_SCREEN); boxOUpgrades.setUserdata(ScreenRights.MANAGE_UPGRADES); - boxOClick.setUserdata(ScreenRights.CLICK); + boxOClick.setUserdata(ScreenRights.INTERACT); boxOSetUrl.setUserdata(ScreenRights.CHANGE_URL); TileEntityScreen.Screen scr = tes.getScreen(side); @@ -201,7 +201,7 @@ public class GuiScreenConfig extends WDScreen { throw new NumberFormatException(); //I'm lazy if(x != scr.resolution.x || y != scr.resolution.y) - WDNetworkRegistry.INSTANCE.sendToServer(C2SMessageScreenCtrl.vec2(tes, side, C2SMessageScreenCtrl.CTRL_SET_RESOLUTION, new Vector2i(x, y))); + WDNetworkRegistry.INSTANCE.sendToServer(C2SMessageScreenCtrl.resolution(tes, side, new Vector2i(x, y))); } catch(NumberFormatException ex) { //Roll back tfResX.setText("" + scr.resolution.x); @@ -455,7 +455,7 @@ public class GuiScreenConfig extends WDScreen { flag = (myRights & ScreenRights.MANAGE_OTHER_RIGHTS) == 0; grpOthers.setDisabled(flag); - flag = (myRights & ScreenRights.CHANGE_RESOLUTION) == 0; + flag = (myRights & ScreenRights.MODIFY_SCREEN) == 0; tfResX.setDisabled(flag); tfResY.setDisabled(flag); btnChangeRot.setDisabled(flag); diff --git a/src/main/java/net/montoyo/wd/client/renderers/ScreenRenderer.java b/src/main/java/net/montoyo/wd/client/renderers/ScreenRenderer.java index d635e78..3ac5367 100644 --- a/src/main/java/net/montoyo/wd/client/renderers/ScreenRenderer.java +++ b/src/main/java/net/montoyo/wd/client/renderers/ScreenRenderer.java @@ -18,116 +18,153 @@ import org.jetbrains.annotations.NotNull; import static com.mojang.math.Vector3f.*; public class ScreenRenderer implements BlockEntityRenderer { - public ScreenRenderer() {} - - public static class ScreenRendererProvider implements BlockEntityRendererProvider { - @Override - public @NotNull BlockEntityRenderer create(@NotNull Context arg) { - return new ScreenRenderer(); - } - } - - private final Vector3f mid = new Vector3f(); - private final Vector3i tmpi = new Vector3i(); - private final Vector3f tmpf = new Vector3f(); - - @Override - public void render(TileEntityScreen te, float partialTick, @NotNull PoseStack poseStack, @NotNull MultiBufferSource bufferSource, int packedLight, int packedOverlay) { - if(!te.isLoaded()) - return; - - //Disable lighting - RenderSystem.enableTexture(); + public ScreenRenderer() { + } + + public static class ScreenRendererProvider implements BlockEntityRendererProvider { + @Override + public @NotNull BlockEntityRenderer create(@NotNull Context arg) { + return new ScreenRenderer(); + } + } + + private final Vector3f mid = new Vector3f(); + private final Vector3i tmpi = new Vector3i(); + private final Vector3f tmpf = new Vector3f(); + + @Override + public void render(TileEntityScreen te, float partialTick, @NotNull PoseStack poseStack, @NotNull MultiBufferSource bufferSource, int packedLight, int packedOverlay) { + if (!te.isLoaded()) + return; + + //Disable lighting + RenderSystem.enableTexture(); // RenderSystem.disableCull(); - RenderSystem.disableBlend(); - - for(int i = 0; i < te.screenCount(); i++) { - TileEntityScreen.Screen scr = te.getScreen(i); - if(scr.browser == null) { - scr.createBrowser(true); - } - - // TODO: manually backface cull the screens - - tmpi.set(scr.side.right); - tmpi.mul(scr.size.x); - tmpi.addMul(scr.side.up, scr.size.y); - tmpf.set(tmpi); - mid.set(0.5, 0.5, 0.5); - mid.addMul(tmpf, 0.5f); - tmpf.set(scr.side.left); - mid.addMul(tmpf, 0.5f); - tmpf.set(scr.side.down); - mid.addMul(tmpf, 0.5f); - - poseStack.pushPose(); - poseStack.translate(mid.x, mid.y, mid.z); - - switch(scr.side) { - case BOTTOM: - poseStack.mulPose(XP.rotation(90.f + 49.8f)); - break; - - case TOP: - poseStack.mulPose(XN.rotation(90.f + 49.8f)); - break; - - case NORTH: - poseStack.mulPose(YN.rotationDegrees(180.f)); - break; - - case SOUTH: - break; - - case WEST: - poseStack.mulPose(YN.rotationDegrees(90.f)); - break; - - case EAST: - poseStack.mulPose(YP.rotationDegrees(90.f)); - break; - } - - if(scr.doTurnOnAnim) { - long lt = System.currentTimeMillis() - scr.turnOnTime; - float ft = ((float) lt) / 100.0f; - - if(ft >= 1.0f) { - ft = 1.0f; - scr.doTurnOnAnim = false; - } - - poseStack.scale(ft, ft, 1.0f); - } - - if(!scr.rotation.isNull) - poseStack.mulPose(ZP.rotationDegrees(scr.rotation.angle)); - - float sw = ((float) scr.size.x) * 0.5f - 2.f / 16.f; - float sh = ((float) scr.size.y) * 0.5f - 2.f / 16.f; - - if(scr.rotation.isVertical) { - float tmp = sw; - sw = sh; - sh = tmp; - } - - Tesselator tesselator = Tesselator.getInstance(); - BufferBuilder builder = tesselator.getBuilder(); - //TODO: don't use tesselator - RenderSystem.enableDepthTest(); - RenderSystem.setShader(GameRenderer::getPositionTexColorShader); - RenderSystem._setShaderTexture(0, scr.browser.getTextureID()); - RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f); - builder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_TEX_COLOR); - builder.vertex(poseStack.last().pose(),-sw, -sh, 0.505f).uv(0.f, 1.f).color(1.f, 1.f, 1.f, 1.f).endVertex(); - builder.vertex(poseStack.last().pose(), sw, -sh, 0.505f).uv(1.f, 1.f).color(1.f, 1.f, 1.f, 1.f).endVertex(); - builder.vertex(poseStack.last().pose(), sw, sh, 0.505f).uv(1.f, 0.f).color(1.f, 1.f, 1.f, 1.f).endVertex(); - builder.vertex(poseStack.last().pose(),-sw, sh, 0.505f).uv(0.f, 0.f).color(1.f, 1.f, 1.f, 1.f).endVertex(); - tesselator.end();//Minecraft does shit with mah texture otherwise... - RenderSystem.disableDepthTest(); - poseStack.popPose(); - } + RenderSystem.disableBlend(); + + for (int i = 0; i < te.screenCount(); i++) { + TileEntityScreen.Screen scr = te.getScreen(i); + if (scr.browser == null) { + scr.createBrowser(true); + } + + // TODO: manually backface cull the screens + + tmpi.set(scr.side.right); + tmpi.mul(scr.size.x); + tmpi.addMul(scr.side.up, scr.size.y); + tmpf.set(tmpi); + mid.set(0.5, 0.5, 0.5); + mid.addMul(tmpf, 0.5f); + tmpf.set(scr.side.left); + mid.addMul(tmpf, 0.5f); + tmpf.set(scr.side.down); + mid.addMul(tmpf, 0.5f); + + poseStack.pushPose(); + poseStack.translate(mid.x, mid.y, mid.z); + + switch (scr.side) { + case BOTTOM: + poseStack.mulPose(XP.rotation(90.f + 49.8f)); + break; + + case TOP: + poseStack.mulPose(XN.rotation(90.f + 49.8f)); + break; + + case NORTH: + poseStack.mulPose(YN.rotationDegrees(180.f)); + break; + + case SOUTH: + break; + + case WEST: + poseStack.mulPose(YN.rotationDegrees(90.f)); + break; + + case EAST: + poseStack.mulPose(YP.rotationDegrees(90.f)); + break; + } + + if (scr.doTurnOnAnim) { + long lt = System.currentTimeMillis() - scr.turnOnTime; + float ft = ((float) lt) / 100.0f; + + if (ft >= 1.0f) { + ft = 1.0f; + scr.doTurnOnAnim = false; + } + + poseStack.scale(ft, ft, 1.0f); + } + + if (!scr.rotation.isNull) + poseStack.mulPose(ZP.rotationDegrees(scr.rotation.angle)); + + float sw = ((float) scr.size.x) * 0.5f - 2.f / 16.f; + float sh = ((float) scr.size.y) * 0.5f - 2.f / 16.f; + + if (scr.rotation.isVertical) { + float tmp = sw; + sw = sh; + sh = tmp; + } + + Tesselator tesselator = Tesselator.getInstance(); + BufferBuilder builder = tesselator.getBuilder(); + //TODO: don't use tesselator + RenderSystem.enableDepthTest(); + RenderSystem.setShader(GameRenderer::getPositionTexColorShader); + RenderSystem._setShaderTexture(0, scr.browser.getTextureID()); + RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f); + builder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_TEX_COLOR); + builder.vertex(poseStack.last().pose(), -sw, -sh, 0.505f).uv(0.f, 1.f).color(1.f, 1.f, 1.f, 1.f).endVertex(); + builder.vertex(poseStack.last().pose(), sw, -sh, 0.505f).uv(1.f, 1.f).color(1.f, 1.f, 1.f, 1.f).endVertex(); + builder.vertex(poseStack.last().pose(), sw, sh, 0.505f).uv(1.f, 0.f).color(1.f, 1.f, 1.f, 1.f).endVertex(); + builder.vertex(poseStack.last().pose(), -sw, sh, 0.505f).uv(0.f, 0.f).color(1.f, 1.f, 1.f, 1.f).endVertex(); + tesselator.end();//Minecraft does shit with mah texture otherwise... + RenderSystem.disableDepthTest(); + + // TODO: it'd be neat to draw a mouse cursor on the screen +// // debug hit2pixels +// HitResult result = Minecraft.getInstance().hitResult; +// VertexConsumer consumer = bufferSource.getBuffer(RenderType.lines()); +// poseStack.translate(-sw, -sh, 0); +// if (result instanceof BlockHitResult hit) { +// BlockPos bpos = hit.getBlockPos(); +// +// Vector3i pos = new Vector3i(hit.getBlockPos()); +// float hitX = ((float) result.getLocation().x) - (float) te.getBlockPos().getX(); +// float hitY = ((float) result.getLocation().y) - (float) te.getBlockPos().getY(); +// float hitZ = ((float) result.getLocation().z) - (float) te.getBlockPos().getZ(); +// Vector2i tmp = new Vector2i(); +// +// if (BlockScreen.hit2pixels(scr.side, bpos, pos, scr, hitX, hitY, hitZ, tmp)) { +// float x = tmp.x / (float) scr.resolution.x * scr.size.x; +// float y = tmp.y / (float) scr.resolution.y * scr.size.y; +// y = scr.size.y - y; +// +// x /= scr.size.x; +// y /= scr.size.y; +// x *= sw * 2; +// y *= sh * 2; +// +// LevelRenderer.renderLineBox( +// poseStack, +// consumer, new AABB( +// x - 0.01, y - 0.01, 0.5 - 0.01, +// x + 0.01, y + 0.01, 0.5 + 0.01 +// ), +// 1f, 0, 0, 1f +// ); +// } +// } + + poseStack.popPose(); + } // //Bounding box debugging @@ -138,8 +175,8 @@ public class ScreenRenderer implements BlockEntityRenderer { // te.getRenderBoundingBox(), 1, 1, 1, 1f // ); // poseStack.popPose(); - - //Re-enable lighting + + //Re-enable lighting // RenderSystem.enableCull(); - } + } } diff --git a/src/main/java/net/montoyo/wd/controls/ScreenControl.java b/src/main/java/net/montoyo/wd/controls/ScreenControl.java new file mode 100644 index 0000000..a1c2410 --- /dev/null +++ b/src/main/java/net/montoyo/wd/controls/ScreenControl.java @@ -0,0 +1,38 @@ +package net.montoyo.wd.controls; + +import net.minecraft.core.BlockPos; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.level.ServerPlayer; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; +import net.minecraftforge.network.NetworkEvent; +import net.montoyo.wd.core.MissingPermissionException; +import net.montoyo.wd.entity.TileEntityScreen; +import net.montoyo.wd.utilities.BlockSide; + +import java.util.Objects; +import java.util.function.Function; + +public abstract class ScreenControl { + private final ResourceLocation id; + + public ScreenControl(ResourceLocation id) { + this.id = id; + } + + public abstract void write(FriendlyByteBuf buf); + public abstract void handleServer(BlockPos pos, BlockSide side, TileEntityScreen tes, NetworkEvent.Context ctx, Function permissionChecker) throws MissingPermissionException; + @OnlyIn(Dist.CLIENT) + public abstract void handleClient(BlockPos pos, BlockSide side, TileEntityScreen tes, NetworkEvent.Context ctx); + + public void checkPerms(int perms, Function checker, ServerPlayer player) throws MissingPermissionException { + if (!checker.apply(perms)) { + throw new MissingPermissionException(perms, Objects.requireNonNull(player)); + } + } + + public final ResourceLocation getId() { + return id; + } +} diff --git a/src/main/java/net/montoyo/wd/controls/ScreenControlRegistry.java b/src/main/java/net/montoyo/wd/controls/ScreenControlRegistry.java new file mode 100644 index 0000000..d5e5d0a --- /dev/null +++ b/src/main/java/net/montoyo/wd/controls/ScreenControlRegistry.java @@ -0,0 +1,73 @@ +package net.montoyo.wd.controls; + +import net.minecraft.core.BlockPos; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.resources.ResourceLocation; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; +import net.minecraftforge.fml.loading.FMLEnvironment; +import net.minecraftforge.network.NetworkEvent; +import net.montoyo.wd.controls.builtin.*; +import net.montoyo.wd.entity.TileEntityScreen; +import net.montoyo.wd.utilities.BlockSide; +import net.montoyo.wd.utilities.Log; + +import java.lang.reflect.Method; +import java.util.HashMap; + +// TODO: enable deferred registry of these +public class ScreenControlRegistry { + private static final HashMap> CONTROL_TYPES = new HashMap<>(); + + public static void register(ResourceLocation name, ScreenControlType type) { + if (CONTROL_TYPES.containsKey(name)) { + Log.warning("ScreenControlRegistry#CONTROL_TYPES already contains an entry with name " + name); + throw new IllegalArgumentException("Cannot have two entries with the same name."); + } + CONTROL_TYPES.put(name, type); + + // lil thing for sanity + // avoids the pain the dist cleaner causes, hopefully + if (!FMLEnvironment.production) { + if (FMLEnvironment.dist.isClient()) { + boolean shouldThrow = false; + try { + Method m = type.clazz.getMethod("handleClient", BlockPos.class, BlockSide.class, TileEntityScreen.class, NetworkEvent.Context.class); + OnlyIn onlyIn = m.getAnnotation(OnlyIn.class); + if (onlyIn == null) shouldThrow = true; + Dist d = onlyIn.value(); // idc if this throws, lol + if (d != Dist.CLIENT) shouldThrow = true; + } catch (Throwable ignored) { + } + if (shouldThrow) { + Log.warning("handleClient on ScreenControl classes MUST be marked with `@OnlyIn(Dist.CLIENT)`, but it is not on " + type.clazz); + throw new IllegalStateException( + "handleClient on ScreenControl classes MUST be marked with `@OnlyIn(Dist.CLIENT)`, but it is not on " + type.clazz + ); + } + } + } + } + + // if needed, the old code + // https://github.com/Mysticpasta1/webdisplays/blob/ff55cbf1b27773c15f44f17ad3364da3a16b6ed9/src/main/java/net/montoyo/wd/net/server/SMessageScreenCtrl.java + static { + register(SetURLControl.id, new ScreenControlType<>(SetURLControl.class, SetURLControl::new)); + register(KeyTypedControl.id, new ScreenControlType<>(KeyTypedControl.class, KeyTypedControl::new)); + register(AutoVolumeControl.id, new ScreenControlType<>(AutoVolumeControl.class, AutoVolumeControl::new)); + register(JSRequestControl.id, new ScreenControlType<>(JSRequestControl.class, JSRequestControl::new)); + register(LaserControl.id, new ScreenControlType<>(LaserControl.class, LaserControl::new)); + register(ScreenModifyControl.id, new ScreenControlType<>(ScreenModifyControl.class, ScreenModifyControl::new)); + register(ModifyFriendListControl.id, new ScreenControlType<>(ModifyFriendListControl.class, ModifyFriendListControl::new)); + register(ManageRightsAndUpdgradesControl.id, new ScreenControlType<>(ManageRightsAndUpdgradesControl.class, ManageRightsAndUpdgradesControl::new)); + } + + public static ScreenControl parse(FriendlyByteBuf buf) { + return CONTROL_TYPES.get(new ResourceLocation(buf.readUtf())) + .deserializer.apply(buf); + } + + public static void init() { + /* NO-OP: allows static init to run during mod init in dev env */ + } +} diff --git a/src/main/java/net/montoyo/wd/controls/ScreenControlType.java b/src/main/java/net/montoyo/wd/controls/ScreenControlType.java new file mode 100644 index 0000000..2c3c1b5 --- /dev/null +++ b/src/main/java/net/montoyo/wd/controls/ScreenControlType.java @@ -0,0 +1,15 @@ +package net.montoyo.wd.controls; + +import net.minecraft.network.FriendlyByteBuf; + +import java.util.function.Function; + +public class ScreenControlType { + Class clazz; + Function deserializer; + + public ScreenControlType(Class clazz, Function deserializer) { + this.clazz = clazz; + this.deserializer = deserializer; + } +} \ No newline at end of file diff --git a/src/main/java/net/montoyo/wd/controls/builtin/AutoVolumeControl.java b/src/main/java/net/montoyo/wd/controls/builtin/AutoVolumeControl.java new file mode 100644 index 0000000..7b3aac1 --- /dev/null +++ b/src/main/java/net/montoyo/wd/controls/builtin/AutoVolumeControl.java @@ -0,0 +1,49 @@ +package net.montoyo.wd.controls.builtin; + +import net.minecraft.core.BlockPos; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.resources.ResourceLocation; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; +import net.minecraftforge.network.NetworkEvent; +import net.montoyo.wd.controls.ScreenControl; +import net.montoyo.wd.core.MissingPermissionException; +import net.montoyo.wd.core.ScreenRights; +import net.montoyo.wd.entity.TileEntityScreen; +import net.montoyo.wd.utilities.BlockSide; + +import java.util.function.Function; + +public class AutoVolumeControl extends ScreenControl { + public static final ResourceLocation id = new ResourceLocation("webdisplays:auto_volume"); + + boolean autoVol; + + public AutoVolumeControl(boolean autoVol) { + super(id); + this.autoVol = autoVol; + } + + public AutoVolumeControl(FriendlyByteBuf buf) { + super(id); + autoVol = buf.readBoolean(); + } + + @Override + public void write(FriendlyByteBuf buf) { + buf.writeBoolean(autoVol); + } + + @Override + public void handleServer(BlockPos pos, BlockSide side, TileEntityScreen tes, NetworkEvent.Context ctx, Function permissionChecker) throws MissingPermissionException { + // I feel like there's probably a better permission category + checkPerms(ScreenRights.MANAGE_UPGRADES, permissionChecker, ctx.getSender()); + tes.setAutoVolume(side, autoVol); + } + + @Override + @OnlyIn(Dist.CLIENT) + public void handleClient(BlockPos pos, BlockSide side, TileEntityScreen tes, NetworkEvent.Context ctx) { + tes.setAutoVolume(side, autoVol); + } +} diff --git a/src/main/java/net/montoyo/wd/controls/builtin/JSRequestControl.java b/src/main/java/net/montoyo/wd/controls/builtin/JSRequestControl.java new file mode 100644 index 0000000..5b3f5fb --- /dev/null +++ b/src/main/java/net/montoyo/wd/controls/builtin/JSRequestControl.java @@ -0,0 +1,63 @@ +package net.montoyo.wd.controls.builtin; + +import net.minecraft.core.BlockPos; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.level.ServerPlayer; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; +import net.minecraftforge.network.NetworkEvent; +import net.montoyo.wd.controls.ScreenControl; +import net.montoyo.wd.core.JSServerRequest; +import net.montoyo.wd.core.MissingPermissionException; +import net.montoyo.wd.entity.TileEntityScreen; +import net.montoyo.wd.utilities.BlockSide; +import net.montoyo.wd.utilities.Log; + +import java.util.function.Function; + +public class JSRequestControl extends ScreenControl { + public static final ResourceLocation id = new ResourceLocation("webdisplays:js_req"); + + int reqId; + JSServerRequest reqType; + Object[] data; + + public JSRequestControl(int reqId, JSServerRequest reqType, Object[] data) { + super(id); + this.reqId = reqId; + this.reqType = reqType; + this.data = data; + } + + public JSRequestControl(FriendlyByteBuf buf) { + super(id); + reqId = buf.readInt(); + reqType = JSServerRequest.fromID(buf.readByte()); + + if (reqType != null) + data = reqType.deserialize(buf); + } + + @Override + public void write(FriendlyByteBuf buf) { + buf.writeInt(reqId); + buf.writeByte(reqType.ordinal()); + + if (!reqType.serialize(buf, data)) + throw new RuntimeException("Could not serialize CTRL_JS_REQUEST " + reqType); + } + + @Override + public void handleServer(BlockPos pos, BlockSide side, TileEntityScreen tes, NetworkEvent.Context ctx, Function permissionChecker) throws MissingPermissionException { + ServerPlayer player = ctx.getSender(); + if (reqType == null || data == null) Log.warning("Caught invalid JS request from player %s (UUID %s)", player.getName(), player.getGameProfile().getId().toString()); + else tes.handleJSRequest(player, side, reqId, reqType, data); + } + + @Override + @OnlyIn(Dist.CLIENT) + public void handleClient(BlockPos pos, BlockSide side, TileEntityScreen tes, NetworkEvent.Context ctx) { + throw new RuntimeException("TODO"); + } +} diff --git a/src/main/java/net/montoyo/wd/controls/builtin/KeyTypedControl.java b/src/main/java/net/montoyo/wd/controls/builtin/KeyTypedControl.java new file mode 100644 index 0000000..fedc669 --- /dev/null +++ b/src/main/java/net/montoyo/wd/controls/builtin/KeyTypedControl.java @@ -0,0 +1,52 @@ +package net.montoyo.wd.controls.builtin; + +import net.minecraft.core.BlockPos; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.resources.ResourceLocation; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; +import net.minecraftforge.network.NetworkEvent; +import net.montoyo.wd.controls.ScreenControl; +import net.montoyo.wd.core.MissingPermissionException; +import net.montoyo.wd.core.ScreenRights; +import net.montoyo.wd.entity.TileEntityScreen; +import net.montoyo.wd.utilities.BlockSide; + +import java.util.function.Function; + +public class KeyTypedControl extends ScreenControl { + public static final ResourceLocation id = new ResourceLocation("webdisplays:type"); + + String text; + BlockPos soundPos; + + public KeyTypedControl(String text, BlockPos soundPos) { + super(id); + this.text = text; + this.soundPos = soundPos; + } + + public KeyTypedControl(FriendlyByteBuf buf) { + super(id); + text = buf.readUtf(); + soundPos = buf.readBlockPos(); + } + + @Override + public void write(FriendlyByteBuf buf) { + buf.writeUtf(text); + buf.writeBlockPos(soundPos); + } + + @Override + public void handleServer(BlockPos pos, BlockSide side, TileEntityScreen tes, NetworkEvent.Context ctx, Function permissionChecker) throws MissingPermissionException { + checkPerms(ScreenRights.INTERACT, permissionChecker, ctx.getSender()); + tes.type(side, text, soundPos); + } + + @Override + @OnlyIn(Dist.CLIENT) + public void handleClient(BlockPos pos, BlockSide side, TileEntityScreen tes, NetworkEvent.Context ctx) { + tes.type(side, text, soundPos); + } +} diff --git a/src/main/java/net/montoyo/wd/controls/builtin/LaserControl.java b/src/main/java/net/montoyo/wd/controls/builtin/LaserControl.java new file mode 100644 index 0000000..be3a93e --- /dev/null +++ b/src/main/java/net/montoyo/wd/controls/builtin/LaserControl.java @@ -0,0 +1,64 @@ +package net.montoyo.wd.controls.builtin; + +import net.minecraft.core.BlockPos; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.level.ServerPlayer; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; +import net.minecraftforge.network.NetworkEvent; +import net.montoyo.wd.controls.ScreenControl; +import net.montoyo.wd.core.MissingPermissionException; +import net.montoyo.wd.entity.TileEntityScreen; +import net.montoyo.wd.utilities.BlockSide; +import net.montoyo.wd.utilities.Vector2i; + +import java.util.function.Function; + +public class LaserControl extends ScreenControl { + public static final ResourceLocation id = new ResourceLocation("webdisplays:laser"); + + public static enum ControlType { + MOVE, DOWN, UP + } + + ControlType type; + Vector2i coord; + + public LaserControl(ControlType type, Vector2i coord) { + super(id); + this.type = type; + this.coord = coord; + } + + public LaserControl(FriendlyByteBuf buf) { + super(id); + type = ControlType.values()[buf.readByte()]; + if (!type.equals(ControlType.UP)) + coord = new Vector2i(buf); + } + + @Override + public void write(FriendlyByteBuf buf) { + buf.writeByte(type.ordinal()); + if (coord != null) coord.writeTo(buf); + } + + @Override + public void handleServer(BlockPos pos, BlockSide side, TileEntityScreen tes, NetworkEvent.Context ctx, Function permissionChecker) throws MissingPermissionException { + // feel like this makes sense, but I wanna get opinions first +// checkPerms(ScreenRights.INTERACT, permissionChecker, ctx.getSender()); + ServerPlayer sender = ctx.getSender(); + switch (type) { + case UP -> tes.laserUp(side, sender); + case DOWN -> tes.laserDownMove(side, sender, coord, true); + case MOVE -> tes.laserDownMove(side, sender, coord, false); + } + } + + @Override + @OnlyIn(Dist.CLIENT) + public void handleClient(BlockPos pos, BlockSide side, TileEntityScreen tes, NetworkEvent.Context ctx) { + throw new RuntimeException("TODO"); + } +} diff --git a/src/main/java/net/montoyo/wd/controls/builtin/ManageRightsAndUpdgradesControl.java b/src/main/java/net/montoyo/wd/controls/builtin/ManageRightsAndUpdgradesControl.java new file mode 100644 index 0000000..786ea48 --- /dev/null +++ b/src/main/java/net/montoyo/wd/controls/builtin/ManageRightsAndUpdgradesControl.java @@ -0,0 +1,97 @@ +package net.montoyo.wd.controls.builtin; + +import net.minecraft.core.BlockPos; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.item.ItemStack; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; +import net.minecraftforge.network.NetworkEvent; +import net.montoyo.wd.controls.ScreenControl; +import net.montoyo.wd.core.MissingPermissionException; +import net.montoyo.wd.core.ScreenRights; +import net.montoyo.wd.entity.TileEntityScreen; +import net.montoyo.wd.utilities.BlockSide; + +import java.util.function.Function; + +/** + * TODO: I'm considering merging this with {@link ModifyFriendListControl} to make ManageScreenControl + */ +@Deprecated +public class ManageRightsAndUpdgradesControl extends ScreenControl { + public static final ResourceLocation id = new ResourceLocation("webdisplays:mod_rights_upgrades"); + + public static enum ControlType { + RIGHTS, UPGRADES + } + + ControlType type; + ItemStack toRemove; + + private int friendRights; + private int otherRights; + + public ManageRightsAndUpdgradesControl(ItemStack toRemove) { + super(id); + type = ControlType.UPGRADES; + this.toRemove = toRemove; + } + + public ManageRightsAndUpdgradesControl(int friendRights, int otherRights) { + super(id); + this.friendRights = friendRights; + this.otherRights = otherRights; + } + + public ManageRightsAndUpdgradesControl(FriendlyByteBuf buf) { + super(id); + type = ControlType.values()[buf.readByte()]; + switch (type) { + case UPGRADES -> toRemove = buf.readItem(); + case RIGHTS -> { + friendRights = buf.readInt(); + otherRights = buf.readInt(); + } + } + } + + @Override + public void write(FriendlyByteBuf buf) { + buf.writeByte(type.ordinal()); + switch (type) { + case UPGRADES -> buf.writeItem(toRemove); + case RIGHTS -> { + buf.writeInt(friendRights); + buf.writeInt(otherRights); + } + } + } + + @Override + public void handleServer(BlockPos pos, BlockSide side, TileEntityScreen tes, NetworkEvent.Context ctx, Function permissionChecker) throws MissingPermissionException { + ServerPlayer player = ctx.getSender(); + switch (type) { + case UPGRADES -> { + checkPerms(ScreenRights.MANAGE_UPGRADES, permissionChecker, ctx.getSender()); + tes.removeUpgrade(side, toRemove, player); + } + case RIGHTS -> { + TileEntityScreen.Screen scr = tes.getScreen(side); + + int fr = scr.owner.uuid.equals(player.getGameProfile().getId()) ? friendRights : scr.friendRights; + int or = (scr.rightsFor(player) & ScreenRights.MANAGE_OTHER_RIGHTS) == 0 ? scr.otherRights : otherRights; + + if(scr.friendRights != fr || scr.otherRights != or) + tes.setRights(player, side, fr, or); + } + } + } + + @Override + @OnlyIn(Dist.CLIENT) + public void handleClient(BlockPos pos, BlockSide side, TileEntityScreen tes, NetworkEvent.Context ctx) { + throw new RuntimeException("TODO"); + } +} diff --git a/src/main/java/net/montoyo/wd/controls/builtin/ModifyFriendListControl.java b/src/main/java/net/montoyo/wd/controls/builtin/ModifyFriendListControl.java new file mode 100644 index 0000000..56a5364 --- /dev/null +++ b/src/main/java/net/montoyo/wd/controls/builtin/ModifyFriendListControl.java @@ -0,0 +1,56 @@ +package net.montoyo.wd.controls.builtin; + +import net.minecraft.core.BlockPos; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.level.ServerPlayer; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; +import net.minecraftforge.network.NetworkEvent; +import net.montoyo.wd.controls.ScreenControl; +import net.montoyo.wd.core.MissingPermissionException; +import net.montoyo.wd.core.ScreenRights; +import net.montoyo.wd.entity.TileEntityScreen; +import net.montoyo.wd.utilities.BlockSide; +import net.montoyo.wd.utilities.NameUUIDPair; + +import java.util.function.Function; + +public class ModifyFriendListControl extends ScreenControl { + public static final ResourceLocation id = new ResourceLocation("webdisplays:mod_friend_list"); + + boolean adding; + NameUUIDPair friend; + + public ModifyFriendListControl(NameUUIDPair pair, boolean adding) { + super(id); + this.adding = adding; + this.friend = pair; + } + + public ModifyFriendListControl(FriendlyByteBuf buf) { + super(id); + adding = buf.readBoolean(); + friend = new NameUUIDPair(buf); + } + + @Override + public void write(FriendlyByteBuf buf) { + buf.writeBoolean(adding); + friend.writeTo(buf); + } + + @Override + public void handleServer(BlockPos pos, BlockSide side, TileEntityScreen tes, NetworkEvent.Context ctx, Function permissionChecker) throws MissingPermissionException { + ServerPlayer player = ctx.getSender(); + checkPerms(ScreenRights.MANAGE_FRIEND_LIST, permissionChecker, ctx.getSender()); + if (adding) tes.addFriend(player, side, friend); + else tes.removeFriend(player, side, friend); + } + + @Override + @OnlyIn(Dist.CLIENT) + public void handleClient(BlockPos pos, BlockSide side, TileEntityScreen tes, NetworkEvent.Context ctx) { + throw new RuntimeException("TODO"); + } +} diff --git a/src/main/java/net/montoyo/wd/controls/builtin/ScreenModifyControl.java b/src/main/java/net/montoyo/wd/controls/builtin/ScreenModifyControl.java new file mode 100644 index 0000000..b63a673 --- /dev/null +++ b/src/main/java/net/montoyo/wd/controls/builtin/ScreenModifyControl.java @@ -0,0 +1,71 @@ +package net.montoyo.wd.controls.builtin; + +import net.minecraft.core.BlockPos; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.resources.ResourceLocation; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; +import net.minecraftforge.network.NetworkEvent; +import net.montoyo.wd.controls.ScreenControl; +import net.montoyo.wd.core.MissingPermissionException; +import net.montoyo.wd.core.ScreenRights; +import net.montoyo.wd.entity.TileEntityScreen; +import net.montoyo.wd.utilities.BlockSide; +import net.montoyo.wd.utilities.Rotation; +import net.montoyo.wd.utilities.Vector2i; + +import java.util.function.Function; + +public class ScreenModifyControl extends ScreenControl { + public static final ResourceLocation id = new ResourceLocation("webdisplays:mod_screen"); + + public static enum ControlType { + RESOLUTION, ROTATION + } + + ControlType type; + Vector2i res; + Rotation rotation; + + public ScreenModifyControl(Vector2i res) { + super(id); + this.type = ControlType.RESOLUTION; + this.res = res; + } + + public ScreenModifyControl(Rotation rotation) { + super(id); + this.type = ControlType.ROTATION; + this.rotation = rotation; + } + + public ScreenModifyControl(FriendlyByteBuf buf) { + super(id); + type = ControlType.values()[buf.readByte()]; + if (type.equals(ControlType.RESOLUTION)) + res = new Vector2i(buf); + else rotation = Rotation.values()[buf.readByte()]; + } + + @Override + public void write(FriendlyByteBuf buf) { + buf.writeByte(type.ordinal()); + if (res != null) res.writeTo(buf); + else if (rotation != null) buf.writeByte(rotation.ordinal()); + } + + @Override + public void handleServer(BlockPos pos, BlockSide side, TileEntityScreen tes, NetworkEvent.Context ctx, Function permissionChecker) throws MissingPermissionException { + checkPerms(ScreenRights.MODIFY_SCREEN, permissionChecker, ctx.getSender()); + switch (type) { + case RESOLUTION -> tes.setResolution(side, res); + case ROTATION -> tes.setRotation(side, rotation); + } + } + + @Override + @OnlyIn(Dist.CLIENT) + public void handleClient(BlockPos pos, BlockSide side, TileEntityScreen tes, NetworkEvent.Context ctx) { + throw new RuntimeException("TODO"); + } +} diff --git a/src/main/java/net/montoyo/wd/controls/builtin/SetURLControl.java b/src/main/java/net/montoyo/wd/controls/builtin/SetURLControl.java new file mode 100644 index 0000000..44b1187 --- /dev/null +++ b/src/main/java/net/montoyo/wd/controls/builtin/SetURLControl.java @@ -0,0 +1,63 @@ +package net.montoyo.wd.controls.builtin; + +import net.minecraft.core.BlockPos; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.resources.ResourceLocation; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; +import net.minecraftforge.network.NetworkEvent; +import net.montoyo.wd.controls.ScreenControl; +import net.montoyo.wd.core.MissingPermissionException; +import net.montoyo.wd.core.ScreenRights; +import net.montoyo.wd.entity.TileEntityScreen; +import net.montoyo.wd.utilities.BlockSide; +import net.montoyo.wd.utilities.Vector3i; + +import java.util.function.Function; + +public class SetURLControl extends ScreenControl { + public static final ResourceLocation id = new ResourceLocation("webdisplays:set_url"); + + String url; + Vector3i remoteLocation; + + public SetURLControl(String url, Vector3i remoteLocation) { + super(id); + this.url = url; + this.remoteLocation = remoteLocation; + } + + public SetURLControl(FriendlyByteBuf buf) { + super(id); + url = buf.readUtf(); + if (buf.readBoolean()) remoteLocation = new Vector3i(buf); + } + + @Override + public void write(FriendlyByteBuf buf) { + buf.writeUtf(url); + buf.writeBoolean(remoteLocation != null); + if (remoteLocation != null) remoteLocation.writeTo(buf); + } + + @Override + public void handleServer(BlockPos pos, BlockSide side, TileEntityScreen tes, NetworkEvent.Context ctx, Function permissionChecker) throws MissingPermissionException { + // TODO: deal with remote + checkPerms(ScreenRights.CHANGE_URL, permissionChecker, ctx.getSender()); + try { + tes.setScreenURL(side, url); + } catch (Throwable err) { + err.printStackTrace(); + } + } + + @Override + @OnlyIn(Dist.CLIENT) + public void handleClient(BlockPos pos, BlockSide side, TileEntityScreen tes, NetworkEvent.Context ctx) { + try { + tes.setScreenURL(side, url); + } catch (Throwable err) { + err.printStackTrace(); + } + } +} diff --git a/src/main/java/net/montoyo/wd/core/ScreenRights.java b/src/main/java/net/montoyo/wd/core/ScreenRights.java index 7d52623..41f7759 100644 --- a/src/main/java/net/montoyo/wd/core/ScreenRights.java +++ b/src/main/java/net/montoyo/wd/core/ScreenRights.java @@ -7,14 +7,19 @@ package net.montoyo.wd.core; public abstract class ScreenRights { public static final int CHANGE_URL = 1; //Change URL AND run JavaScript + /** use {@link ScreenRights#INTERACT instead} */ + @Deprecated(forRemoval = true) public static final int CLICK = 2; //Click AND type + public static final int INTERACT = 2; //Click AND type public static final int MANAGE_FRIEND_LIST = 4; public static final int MANAGE_OTHER_RIGHTS = 8; public static final int MANAGE_UPGRADES = 16; //Manage upgrades AND peripherals AND autoVolume + @Deprecated(forRemoval = true) public static final int CHANGE_RESOLUTION = 32; //Change resolution AND rotation + public static final int MODIFY_SCREEN = 32; //Change resolution AND rotation public static final int NONE = 0; public static final int ALL = 0xFF; - public static final int DEFAULTS = CHANGE_URL | CLICK | MANAGE_UPGRADES | CHANGE_RESOLUTION; + public static final int DEFAULTS = CHANGE_URL | INTERACT | MANAGE_UPGRADES | MODIFY_SCREEN; } diff --git a/src/main/java/net/montoyo/wd/data/ScreenConfigData.java b/src/main/java/net/montoyo/wd/data/ScreenConfigData.java index c016e6c..9c25b1a 100644 --- a/src/main/java/net/montoyo/wd/data/ScreenConfigData.java +++ b/src/main/java/net/montoyo/wd/data/ScreenConfigData.java @@ -100,7 +100,7 @@ public class ScreenConfigData extends GuiData { onlyUpdate = buf.readBoolean(); pos = BufferUtils.readVec3i(buf); side = (BlockSide) BufferUtils.readEnum(buf, (v) -> BlockSide.values()[v], (byte) 1); - friends = BufferUtils.readArray(buf, () -> new NameUUIDPair(buf)); + friends = BufferUtils.readArray(buf, new NameUUIDPair[0], () -> new NameUUIDPair(buf)); friendRights = buf.readInt(); otherRights = buf.readInt(); } diff --git a/src/main/java/net/montoyo/wd/entity/TileEntityInterfaceBase.java b/src/main/java/net/montoyo/wd/entity/TileEntityInterfaceBase.java index ee841ed..98ed360 100644 --- a/src/main/java/net/montoyo/wd/entity/TileEntityInterfaceBase.java +++ b/src/main/java/net/montoyo/wd/entity/TileEntityInterfaceBase.java @@ -89,7 +89,7 @@ public abstract class TileEntityInterfaceBase extends TileEntityPeripheralBase { switch(what) { case "click": case "type": - right = ScreenRights.CLICK; + right = ScreenRights.INTERACT; break; case "seturl": @@ -101,7 +101,7 @@ public abstract class TileEntityInterfaceBase extends TileEntityPeripheralBase { case "setresolution": case "setrotation": - right = ScreenRights.CHANGE_RESOLUTION; + right = ScreenRights.MODIFY_SCREEN; break; default: @@ -213,7 +213,7 @@ public abstract class TileEntityInterfaceBase extends TileEntityPeripheralBase { else { TileEntityScreen.Screen scrscr = scr.getScreen(screenSide); - if((scrscr.rightsFor(owner.uuid) & ScreenRights.CLICK) == 0) + if((scrscr.rightsFor(owner.uuid) & ScreenRights.INTERACT) == 0) return err("restrictions"); else { switch(scrscr.rotation) { @@ -249,7 +249,7 @@ public abstract class TileEntityInterfaceBase extends TileEntityPeripheralBase { if(owner == null || scr == null) return err("notlinked"); - else if((scr.getScreen(screenSide).rightsFor(owner.uuid) & ScreenRights.CLICK) == 0) + else if((scr.getScreen(screenSide).rightsFor(owner.uuid) & ScreenRights.INTERACT) == 0) return err("restrictions"); else { scr.type(screenSide, what, null); @@ -350,7 +350,7 @@ public abstract class TileEntityInterfaceBase extends TileEntityPeripheralBase { if(owner == null || scr == null) return err("notlinked"); - else if((scr.getScreen(screenSide).rightsFor(owner.uuid) & ScreenRights.CHANGE_RESOLUTION) == 0) + else if((scr.getScreen(screenSide).rightsFor(owner.uuid) & ScreenRights.MODIFY_SCREEN) == 0) return err("restrictions"); else { scr.setResolution(screenSide, new Vector2i(rx, ry)); @@ -373,7 +373,7 @@ public abstract class TileEntityInterfaceBase extends TileEntityPeripheralBase { if(owner == null || scr == null) return err("notlinked"); - else if((scr.getScreen(screenSide).rightsFor(owner.uuid) & ScreenRights.CHANGE_RESOLUTION) == 0) + else if((scr.getScreen(screenSide).rightsFor(owner.uuid) & ScreenRights.MODIFY_SCREEN) == 0) return err("restrictions"); else { scr.setRotation(screenSide, Rotation.values()[rot]); diff --git a/src/main/java/net/montoyo/wd/entity/TileEntityKeyboard.java b/src/main/java/net/montoyo/wd/entity/TileEntityKeyboard.java index 58254a0..915a9f0 100644 --- a/src/main/java/net/montoyo/wd/entity/TileEntityKeyboard.java +++ b/src/main/java/net/montoyo/wd/entity/TileEntityKeyboard.java @@ -53,7 +53,7 @@ public class TileEntityKeyboard extends TileEntityPeripheralBase { } TileEntityScreen.Screen scr = tes.getScreen(screenSide); - if((scr.rightsFor(player) & ScreenRights.CLICK) == 0) { + if((scr.rightsFor(player) & ScreenRights.INTERACT) == 0) { Util.toast(player, "restrictions"); return InteractionResult.SUCCESS; } @@ -71,9 +71,9 @@ public class TileEntityKeyboard extends TileEntityPeripheralBase { boolean ok; if(ent instanceof Player) - ok = (scr.rightsFor((Player) ent) & ScreenRights.CLICK) != 0; + ok = (scr.rightsFor((Player) ent) & ScreenRights.INTERACT) != 0; else - ok = (scr.otherRights & ScreenRights.CLICK) != 0; + ok = (scr.otherRights & ScreenRights.INTERACT) != 0; if(ok) { char rnd = RANDOM_CHARS.charAt((int) (Math.random() * ((double) RANDOM_CHARS.length()))); diff --git a/src/main/java/net/montoyo/wd/entity/TileEntityScreen.java b/src/main/java/net/montoyo/wd/entity/TileEntityScreen.java index e417c8e..d40fe38 100644 --- a/src/main/java/net/montoyo/wd/entity/TileEntityScreen.java +++ b/src/main/java/net/montoyo/wd/entity/TileEntityScreen.java @@ -491,7 +491,7 @@ public class TileEntityScreen extends BlockEntity { } private static void checkLaserUserRights(Screen scr) { - if (scr.laserUser != null && (scr.rightsFor(scr.laserUser) & ScreenRights.CLICK) == 0) + if (scr.laserUser != null && (scr.rightsFor(scr.laserUser) & ScreenRights.INTERACT) == 0) scr.laserUser = null; } @@ -586,7 +586,6 @@ public class TileEntityScreen extends BlockEntity { } public void handleJSRequest(ServerPlayer src, BlockSide side, int reqId, JSServerRequest req, Object[] data) { - // TODO: if (level.isClientSide) { Log.error("Called handleJSRequest client-side"); return; @@ -1058,7 +1057,7 @@ public class TileEntityScreen extends BlockEntity { return null; } - if ((scr.rightsFor(ply) & ScreenRights.CLICK) == 0) + if ((scr.rightsFor(ply) & ScreenRights.INTERACT) == 0) return null; //Don't output an error, it can 'legally' happen if (scr.upgrades.stream().noneMatch(DefaultUpgrade.LASERMOUSE::matchesLaserMouse)) { diff --git a/src/main/java/net/montoyo/wd/net/BufferUtils.java b/src/main/java/net/montoyo/wd/net/BufferUtils.java index fa29cad..f310fa4 100644 --- a/src/main/java/net/montoyo/wd/net/BufferUtils.java +++ b/src/main/java/net/montoyo/wd/net/BufferUtils.java @@ -3,6 +3,7 @@ package net.montoyo.wd.net; import net.minecraft.network.FriendlyByteBuf; import net.montoyo.wd.utilities.Vector3i; +import java.util.Arrays; import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Supplier; @@ -54,9 +55,9 @@ public class BufferUtils { for (T element : elements) writer.accept(element); } - public static T[] readArray(FriendlyByteBuf buf, Supplier reader) { + public static T[] readArray(FriendlyByteBuf buf, T[] array, Supplier reader) { //noinspection unchecked - T[] ts = (T[]) new Object[readUShort(buf)]; + T[] ts = (T[]) Arrays.copyOf(array, readUShort(buf), array.getClass()); for (int i = 0; i < ts.length; i++) ts[i] = reader.get(); return ts; } diff --git a/src/main/java/net/montoyo/wd/net/client_bound/S2CMessageACResult.java b/src/main/java/net/montoyo/wd/net/client_bound/S2CMessageACResult.java index 69b46a9..e54f152 100644 --- a/src/main/java/net/montoyo/wd/net/client_bound/S2CMessageACResult.java +++ b/src/main/java/net/montoyo/wd/net/client_bound/S2CMessageACResult.java @@ -36,10 +36,11 @@ public class S2CMessageACResult extends Packet { } public void handle(NetworkEvent.Context ctx) { - ctx.enqueueWork(() -> { - WebDisplays.PROXY.onAutocompleteResult(result); - }); - ctx.setPacketHandled(true); + if (checkClient(ctx)) { + ctx.enqueueWork(() -> { + WebDisplays.PROXY.onAutocompleteResult(result); + }); + ctx.setPacketHandled(true); + } } - -} \ No newline at end of file +} diff --git a/src/main/java/net/montoyo/wd/net/client_bound/S2CMessageAddScreen.java b/src/main/java/net/montoyo/wd/net/client_bound/S2CMessageAddScreen.java index 1761e08..80d65ab 100644 --- a/src/main/java/net/montoyo/wd/net/client_bound/S2CMessageAddScreen.java +++ b/src/main/java/net/montoyo/wd/net/client_bound/S2CMessageAddScreen.java @@ -91,45 +91,47 @@ public class S2CMessageAddScreen extends Packet { } public void handle(NetworkEvent.Context ctx) { - ctx.enqueueWork(() -> { - Level lvl = (Level) WebDisplays.PROXY.getWorld(ctx); - BlockEntity te = lvl.getBlockEntity(pos.toBlock()); - if (!(te instanceof TileEntityScreen)) { - lvl.setBlockAndUpdate(pos.toBlock(), lvl.getBlockState(pos.toBlock()).setValue(hasTE, true)); - te = lvl.getBlockEntity(pos.toBlock()); - + if (checkClient(ctx)) { + ctx.enqueueWork(() -> { + Level lvl = (Level) WebDisplays.PROXY.getWorld(ctx); + BlockEntity te = lvl.getBlockEntity(pos.toBlock()); if (!(te instanceof TileEntityScreen)) { - if (clear) - Log.error("CMessageAddScreen: Can't add screen to invalid tile entity at %s", pos.toString()); + lvl.setBlockAndUpdate(pos.toBlock(), lvl.getBlockState(pos.toBlock()).setValue(hasTE, true)); + te = lvl.getBlockEntity(pos.toBlock()); - return; - } - } - - TileEntityScreen tes = (TileEntityScreen) te; - if (clear) - tes.clear(); - - for (TileEntityScreen.Screen entry : screens) { - TileEntityScreen.Screen scr = tes.addScreen(entry.side, entry.size, entry.resolution, null, false); - scr.rotation = entry.rotation; - String webUrl; - - try { - webUrl = TileEntityScreen.url(entry.url); - } catch (IOException e) { - throw new RuntimeException(e); + if (!(te instanceof TileEntityScreen)) { + if (clear) + Log.error("CMessageAddScreen: Can't add screen to invalid tile entity at %s", pos.toString()); + + return; + } } - scr.url = webUrl; - scr.owner = entry.owner; - scr.upgrades = entry.upgrades; + TileEntityScreen tes = (TileEntityScreen) te; + if (clear) + tes.clear(); - if (scr.browser != null) - scr.browser.loadURL(webUrl); - } - }); - - ctx.setPacketHandled(true); + for (TileEntityScreen.Screen entry : screens) { + TileEntityScreen.Screen scr = tes.addScreen(entry.side, entry.size, entry.resolution, null, false); + scr.rotation = entry.rotation; + String webUrl; + + try { + webUrl = TileEntityScreen.url(entry.url); + } catch (IOException e) { + throw new RuntimeException(e); + } + + scr.url = webUrl; + scr.owner = entry.owner; + scr.upgrades = entry.upgrades; + + if (scr.browser != null) + scr.browser.loadURL(webUrl); + } + }); + + ctx.setPacketHandled(true); + } } -} \ No newline at end of file +} diff --git a/src/main/java/net/montoyo/wd/net/client_bound/S2CMessageCloseGui.java b/src/main/java/net/montoyo/wd/net/client_bound/S2CMessageCloseGui.java index 5b8789b..761b541 100644 --- a/src/main/java/net/montoyo/wd/net/client_bound/S2CMessageCloseGui.java +++ b/src/main/java/net/montoyo/wd/net/client_bound/S2CMessageCloseGui.java @@ -46,12 +46,14 @@ public class S2CMessageCloseGui extends Packet { } public void handle(NetworkEvent.Context ctx) { - ctx.enqueueWork(() -> { - if (blockSide == null) - Arrays.stream(BlockSide.values()).forEach(s -> WebDisplays.PROXY.closeGui(blockPos, s)); - else - WebDisplays.PROXY.closeGui(blockPos, blockSide); - }); - ctx.setPacketHandled(true); + if (checkClient(ctx)) { + ctx.enqueueWork(() -> { + if (blockSide == null) + Arrays.stream(BlockSide.values()).forEach(s -> WebDisplays.PROXY.closeGui(blockPos, s)); + else + WebDisplays.PROXY.closeGui(blockPos, blockSide); + }); + ctx.setPacketHandled(true); + } } -} \ No newline at end of file +} diff --git a/src/main/java/net/montoyo/wd/net/client_bound/S2CMessageJSResponse.java b/src/main/java/net/montoyo/wd/net/client_bound/S2CMessageJSResponse.java index 9de71c6..6894c5e 100644 --- a/src/main/java/net/montoyo/wd/net/client_bound/S2CMessageJSResponse.java +++ b/src/main/java/net/montoyo/wd/net/client_bound/S2CMessageJSResponse.java @@ -80,16 +80,18 @@ public class S2CMessageJSResponse extends Packet { } public void handle(NetworkEvent.Context ctx) { - ctx.enqueueWork(() -> { - try { - if (success) - WebDisplays.PROXY.handleJSResponseSuccess(id, type, data); - else - WebDisplays.PROXY.handleJSResponseError(id, type, errCode, errString); - } catch (Throwable t) { - Log.warningEx("Could not handle JS response", t); - } - }); - ctx.setPacketHandled(true); + if (checkClient(ctx)) { + ctx.enqueueWork(() -> { + try { + if (success) + WebDisplays.PROXY.handleJSResponseSuccess(id, type, data); + else + WebDisplays.PROXY.handleJSResponseError(id, type, errCode, errString); + } catch (Throwable t) { + Log.warningEx("Could not handle JS response", t); + } + }); + ctx.setPacketHandled(true); + } } } diff --git a/src/main/java/net/montoyo/wd/net/client_bound/S2CMessageMiniservKey.java b/src/main/java/net/montoyo/wd/net/client_bound/S2CMessageMiniservKey.java index f2608ef..b98061e 100644 --- a/src/main/java/net/montoyo/wd/net/client_bound/S2CMessageMiniservKey.java +++ b/src/main/java/net/montoyo/wd/net/client_bound/S2CMessageMiniservKey.java @@ -43,4 +43,4 @@ public class S2CMessageMiniservKey extends Packet { ctx.setPacketHandled(true); } } -} \ No newline at end of file +} diff --git a/src/main/java/net/montoyo/wd/net/client_bound/S2CMessageOpenGui.java b/src/main/java/net/montoyo/wd/net/client_bound/S2CMessageOpenGui.java index de1fb9b..4f46f86 100644 --- a/src/main/java/net/montoyo/wd/net/client_bound/S2CMessageOpenGui.java +++ b/src/main/java/net/montoyo/wd/net/client_bound/S2CMessageOpenGui.java @@ -37,7 +37,9 @@ public class S2CMessageOpenGui extends Packet { } public void handle(NetworkEvent.Context context) { - context.enqueueWork(() -> WebDisplays.PROXY.displayGui(data)); - context.setPacketHandled(true); + if (checkClient(context)) { + context.enqueueWork(() -> WebDisplays.PROXY.displayGui(data)); + context.setPacketHandled(true); + } } -} \ No newline at end of file +} diff --git a/src/main/java/net/montoyo/wd/net/client_bound/S2CMessageScreenUpdate.java b/src/main/java/net/montoyo/wd/net/client_bound/S2CMessageScreenUpdate.java index f5b55a6..8950d1e 100644 --- a/src/main/java/net/montoyo/wd/net/client_bound/S2CMessageScreenUpdate.java +++ b/src/main/java/net/montoyo/wd/net/client_bound/S2CMessageScreenUpdate.java @@ -234,22 +234,23 @@ public class S2CMessageScreenUpdate extends Packet { } public void handle(NetworkEvent.Context ctx) { - ctx.enqueueWork(() -> { - BlockGetter level = WebDisplays.PROXY.getWorld(ctx); - if (level instanceof Level level1) - // ensure that the TE exists - level1.setBlock( - pos.toBlock(), - level.getBlockState(pos.toBlock()).setValue(BlockScreen.hasTE, true),11 - ); - BlockEntity te = level.getBlockEntity(pos.toBlock()); - if(!(te instanceof TileEntityScreen)) { - Log.error("CMessageScreenUpdate: TileEntity at %s is not a screen!", pos.toString()); - return; - } - - TileEntityScreen tes = (TileEntityScreen) te; - + if (checkClient(ctx)) { + ctx.enqueueWork(() -> { + BlockGetter level = WebDisplays.PROXY.getWorld(ctx); + if (level instanceof Level level1) + // ensure that the TE exists + level1.setBlock( + pos.toBlock(), + level.getBlockState(pos.toBlock()).setValue(BlockScreen.hasTE, true),11 + ); + BlockEntity te = level.getBlockEntity(pos.toBlock()); + if(!(te instanceof TileEntityScreen)) { + Log.error("CMessageScreenUpdate: TileEntity at %s is not a screen!", pos.toString()); + return; + } + + TileEntityScreen tes = (TileEntityScreen) te; + switch (action) { case UPDATE_URL -> { try { @@ -274,8 +275,9 @@ public class S2CMessageScreenUpdate extends Packet { case UPDATE_AUTO_VOL -> tes.setAutoVolume(side, autoVolume); default -> Log.warning("Caught invalid CMessageScreenUpdate with action ID %d", action); } - }); - - ctx.setPacketHandled(true); + }); + + ctx.setPacketHandled(true); + } } } diff --git a/src/main/java/net/montoyo/wd/net/client_bound/S2CMessageServerInfo.java b/src/main/java/net/montoyo/wd/net/client_bound/S2CMessageServerInfo.java index c31ebe3..13a9469 100644 --- a/src/main/java/net/montoyo/wd/net/client_bound/S2CMessageServerInfo.java +++ b/src/main/java/net/montoyo/wd/net/client_bound/S2CMessageServerInfo.java @@ -35,7 +35,7 @@ public class S2CMessageServerInfo extends Packet { try { WebDisplays.PROXY.setMiniservClientPort(miniservPort); C2SMessageMiniservConnect message = Client.getInstance().beginConnection(); - respondLater(ctx, message); + respond(ctx, message); ctx.setPacketHandled(true); } catch (Throwable err) { err.printStackTrace(); @@ -43,4 +43,4 @@ public class S2CMessageServerInfo extends Packet { } } } -} \ No newline at end of file +} diff --git a/src/main/java/net/montoyo/wd/net/server_bound/C2SMessageACQuery.java b/src/main/java/net/montoyo/wd/net/server_bound/C2SMessageACQuery.java index 197b6f3..082ec6e 100644 --- a/src/main/java/net/montoyo/wd/net/server_bound/C2SMessageACQuery.java +++ b/src/main/java/net/montoyo/wd/net/server_bound/C2SMessageACQuery.java @@ -18,7 +18,6 @@ import net.montoyo.wd.utilities.NameUUIDPair; import java.util.Arrays; public class C2SMessageACQuery extends Packet implements Runnable { - private ServerPlayer player; private String beginning; private boolean matchExact; @@ -27,13 +26,13 @@ public class C2SMessageACQuery extends Packet implements Runnable { beginning = beg; matchExact = exact; } - - public C2SMessageACQuery(FriendlyByteBuf buf) { - super(buf); - beginning = buf.readUtf(); - matchExact = buf.readBoolean(); - } - + + public C2SMessageACQuery(FriendlyByteBuf buf) { + super(buf); + beginning = buf.readUtf(); + matchExact = buf.readBoolean(); + } + @Override public void write(FriendlyByteBuf buf) { buf.writeUtf(beginning); @@ -56,9 +55,10 @@ public class C2SMessageACQuery extends Packet implements Runnable { } public void handle(NetworkEvent.Context ctx) { - player = ctx.getSender(); - ctx.enqueueWork(this); - ctx.setPacketHandled(true); + if (checkServer(ctx)) { + player = ctx.getSender(); + ctx.enqueueWork(this); + ctx.setPacketHandled(true); + } } - -} \ No newline at end of file +} diff --git a/src/main/java/net/montoyo/wd/net/server_bound/C2SMessageMiniservConnect.java b/src/main/java/net/montoyo/wd/net/server_bound/C2SMessageMiniservConnect.java index 0ff4d3a..ab02227 100644 --- a/src/main/java/net/montoyo/wd/net/server_bound/C2SMessageMiniservConnect.java +++ b/src/main/java/net/montoyo/wd/net/server_bound/C2SMessageMiniservConnect.java @@ -42,11 +42,11 @@ public class C2SMessageMiniservConnect extends Packet { try { ClientManager cliMgr = Server.getInstance().getClientManager(); byte[] encKey = cliMgr.encryptClientKey(Objects.requireNonNull(ctx.getSender()).getGameProfile().getId(), modulus, exponent); - + if (encKey != null) { respond(ctx, new S2CMessageMiniservKey(encKey)); } - + ctx.setPacketHandled(true); } catch (Throwable err) { err.printStackTrace(); @@ -54,4 +54,4 @@ public class C2SMessageMiniservConnect extends Packet { } } } -} \ No newline at end of file +} diff --git a/src/main/java/net/montoyo/wd/net/server_bound/C2SMessageRedstoneCtrl.java b/src/main/java/net/montoyo/wd/net/server_bound/C2SMessageRedstoneCtrl.java index 40f19e1..5d7261c 100644 --- a/src/main/java/net/montoyo/wd/net/server_bound/C2SMessageRedstoneCtrl.java +++ b/src/main/java/net/montoyo/wd/net/server_bound/C2SMessageRedstoneCtrl.java @@ -19,66 +19,68 @@ import net.montoyo.wd.utilities.Util; import net.montoyo.wd.utilities.Vector3i; public class C2SMessageRedstoneCtrl extends Packet implements Runnable { - private Player player; - private Vector3i pos; - private String risingEdgeURL; - private String fallingEdgeURL; - - public C2SMessageRedstoneCtrl() { - } - - public C2SMessageRedstoneCtrl(Vector3i p, String r, String f) { - pos = p; - risingEdgeURL = r; - fallingEdgeURL = f; - } - - public C2SMessageRedstoneCtrl(FriendlyByteBuf buf) { - super(buf); - pos = new Vector3i(buf); - risingEdgeURL = buf.readUtf(); - fallingEdgeURL = buf.readUtf(); - } - - @Override - public void run() { - Level world = player.level; - BlockPos blockPos = pos.toBlock(); - final double maxRange = player.getAttribute(ForgeMod.REACH_DISTANCE.get()).getValue(); - - if(player.distanceToSqr(blockPos.getX(), blockPos.getY(), blockPos.getZ()) > maxRange * maxRange) - return; - - BlockEntity te = world.getBlockEntity(blockPos); - if(te == null || !(te instanceof TileEntityRedCtrl)) - return; - - TileEntityRedCtrl redCtrl = (TileEntityRedCtrl) te; - if(!redCtrl.isScreenChunkLoaded()) { - Util.toast(player, "chunkUnloaded"); - return; - } - - TileEntityScreen tes = redCtrl.getConnectedScreen(); - if(tes == null) - return; - - if((tes.getScreen(redCtrl.getScreenSide()).rightsFor(player) & ScreenRights.CHANGE_URL) == 0) - return; - - redCtrl.setURLs(risingEdgeURL, fallingEdgeURL); - } - - @Override - public void write(FriendlyByteBuf buf) { - pos.writeTo(buf); - buf.writeUtf(risingEdgeURL); - buf.writeUtf(fallingEdgeURL); - } - - public void handle(NetworkEvent.Context ctx) { - player = ctx.getSender(); - ctx.enqueueWork(this); - ctx.setPacketHandled(true); - } -} \ No newline at end of file + private Player player; + private Vector3i pos; + private String risingEdgeURL; + private String fallingEdgeURL; + + public C2SMessageRedstoneCtrl() { + } + + public C2SMessageRedstoneCtrl(Vector3i p, String r, String f) { + pos = p; + risingEdgeURL = r; + fallingEdgeURL = f; + } + + public C2SMessageRedstoneCtrl(FriendlyByteBuf buf) { + super(buf); + pos = new Vector3i(buf); + risingEdgeURL = buf.readUtf(); + fallingEdgeURL = buf.readUtf(); + } + + @Override + public void run() { + Level world = player.level; + BlockPos blockPos = pos.toBlock(); + final double maxRange = player.getAttribute(ForgeMod.REACH_DISTANCE.get()).getValue(); + + if (player.distanceToSqr(blockPos.getX(), blockPos.getY(), blockPos.getZ()) > maxRange * maxRange) + return; + + BlockEntity te = world.getBlockEntity(blockPos); + if (te == null || !(te instanceof TileEntityRedCtrl)) + return; + + TileEntityRedCtrl redCtrl = (TileEntityRedCtrl) te; + if (!redCtrl.isScreenChunkLoaded()) { + Util.toast(player, "chunkUnloaded"); + return; + } + + TileEntityScreen tes = redCtrl.getConnectedScreen(); + if (tes == null) + return; + + if ((tes.getScreen(redCtrl.getScreenSide()).rightsFor(player) & ScreenRights.CHANGE_URL) == 0) + return; + + redCtrl.setURLs(risingEdgeURL, fallingEdgeURL); + } + + @Override + public void write(FriendlyByteBuf buf) { + pos.writeTo(buf); + buf.writeUtf(risingEdgeURL); + buf.writeUtf(fallingEdgeURL); + } + + public void handle(NetworkEvent.Context ctx) { + if (checkServer(ctx)) { + player = ctx.getSender(); + ctx.enqueueWork(this); + ctx.setPacketHandled(true); + } + } +} diff --git a/src/main/java/net/montoyo/wd/net/server_bound/C2SMessageScreenCtrl.java b/src/main/java/net/montoyo/wd/net/server_bound/C2SMessageScreenCtrl.java index 6cc578b..1ea5274 100644 --- a/src/main/java/net/montoyo/wd/net/server_bound/C2SMessageScreenCtrl.java +++ b/src/main/java/net/montoyo/wd/net/server_bound/C2SMessageScreenCtrl.java @@ -6,369 +6,176 @@ package net.montoyo.wd.net.server_bound; import net.minecraft.core.BlockPos; import net.minecraft.network.FriendlyByteBuf; -import net.minecraft.resources.ResourceLocation; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraftforge.common.ForgeMod; import net.minecraftforge.network.NetworkEvent; -import net.montoyo.wd.block.BlockPeripheral; -import net.montoyo.wd.core.DefaultPeripheral; +import net.montoyo.wd.WebDisplays; +import net.montoyo.wd.controls.ScreenControl; +import net.montoyo.wd.controls.ScreenControlRegistry; +import net.montoyo.wd.controls.builtin.*; import net.montoyo.wd.core.JSServerRequest; import net.montoyo.wd.core.MissingPermissionException; -import net.montoyo.wd.core.ScreenRights; import net.montoyo.wd.entity.TileEntityScreen; -import net.montoyo.wd.init.BlockInit; +import net.montoyo.wd.net.BufferUtils; import net.montoyo.wd.net.Packet; import net.montoyo.wd.utilities.*; -import java.io.IOException; - // TODO: this is a mess; a registry based approach would likely be more readable -public class C2SMessageScreenCtrl extends Packet implements Runnable { - public static final int CTRL_SET_URL = 0; - public static final int CTRL_SHUT_DOWN = 1; - public static final int CTRL_ADD_FRIEND = 2; - public static final int CTRL_REMOVE_FRIEND = 3; - public static final int CTRL_SET_RIGHTS = 4; - public static final int CTRL_SET_RESOLUTION = 5; - public static final int CTRL_TYPE = 6; - public static final int CTRL_REMOVE_UPGRADE = 7; - public static final int CTRL_LASER_DOWN = 8; - public static final int CTRL_LASER_MOVE = 9; - public static final int CTRL_LASER_UP = 10; - public static final int CTRL_JS_REQUEST = 11; - public static final int CTRL_SET_ROTATION = 12; - public static final int CTRL_SET_URL_REMOTE = 13; - public static final int CTRL_SET_AUTO_VOL = 14; +public class C2SMessageScreenCtrl extends Packet { + @Deprecated(forRemoval = true) + public static final int CTRL_LASER_MOVE = 0; + @Deprecated(forRemoval = true) + public static final int CTRL_LASER_UP = 0; + @Deprecated(forRemoval = true) + public static final int CTRL_LASER_DOWN = 0; + @Deprecated(forRemoval = true) + public static final int CTRL_SET_RESOLUTION = 0; - private int ctrl; - private ResourceLocation dim; - private Vector3i pos; - private BlockSide side; - private String url; - private NameUUIDPair friend; - private ServerPlayer player; - private int friendRights; - private int otherRights; - private Vector2i vec2i; - private String text; - private BlockPos soundPos; - private ItemStack toRemove; - private int jsReqID; - private JSServerRequest jsReqType; - private Object[] jsReqData; - private Rotation rotation; - private Vector3i remoteLoc; - private boolean autoVol; + ScreenControl control; + BlockPos pos; + BlockSide side; public C2SMessageScreenCtrl() { } + public C2SMessageScreenCtrl(TileEntityScreen screen, BlockSide side, ScreenControl control) { + this.pos = screen.getBlockPos(); + this.side = side; + this.control = control; + } + + protected static C2SMessageScreenCtrl base(TileEntityScreen screen, BlockSide side) { + C2SMessageScreenCtrl packet = new C2SMessageScreenCtrl(); + packet.pos = screen.getBlockPos(); + packet.side = side; + return packet; + } + + @Deprecated(forRemoval = true) public static C2SMessageScreenCtrl setURL(TileEntityScreen tes, BlockSide side, String url, Vector3i remoteLocation) { - C2SMessageScreenCtrl ret = new C2SMessageScreenCtrl(); - ret.ctrl = (remoteLocation == null) ? CTRL_SET_URL : CTRL_SET_URL_REMOTE; - ret.dim = tes.getLevel().dimension().location(); - ret.pos = new Vector3i(tes.getBlockPos()); - ret.side = side; - ret.url = url; - - if (remoteLocation != null) - ret.remoteLoc = remoteLocation; - + C2SMessageScreenCtrl ret = base(tes, side); + ret.control = new SetURLControl(url, remoteLocation); return ret; } + @Deprecated(forRemoval = true) public C2SMessageScreenCtrl(TileEntityScreen tes, BlockSide side, NameUUIDPair friend, boolean del) { - ctrl = del ? CTRL_REMOVE_FRIEND : CTRL_ADD_FRIEND; - dim = tes.getLevel().dimension().location(); - pos = new Vector3i(tes.getBlockPos()); - this.side = side; - this.friend = friend; + this(tes, side, new ModifyFriendListControl(friend, !del)); } + @Deprecated(forRemoval = true) public C2SMessageScreenCtrl(TileEntityScreen tes, BlockSide side, int fr, int or) { - ctrl = CTRL_SET_RIGHTS; - dim = tes.getLevel().dimension().location(); - pos = new Vector3i(tes.getBlockPos()); - this.side = side; - friendRights = fr; - otherRights = or; + this(tes, side, new ManageRightsAndUpdgradesControl(fr, or)); } + @Deprecated(forRemoval = true) public C2SMessageScreenCtrl(TileEntityScreen tes, BlockSide side, ItemStack toRem) { - ctrl = CTRL_REMOVE_UPGRADE; - dim = tes.getLevel().dimension().location(); - pos = new Vector3i(tes.getBlockPos()); - this.side = side; - toRemove = toRem; + this(tes, side, new ManageRightsAndUpdgradesControl(toRem)); } + @Deprecated(forRemoval = true) public C2SMessageScreenCtrl(TileEntityScreen tes, BlockSide side, Rotation rot) { - ctrl = CTRL_SET_ROTATION; - dim = tes.getLevel().dimension().location(); - pos = new Vector3i(tes.getBlockPos()); - this.side = side; - rotation = rot; - } - - public static C2SMessageScreenCtrl type(TileEntityScreen tes, BlockSide side, String text, BlockPos soundPos) { - C2SMessageScreenCtrl ret = new C2SMessageScreenCtrl(); - ret.ctrl = CTRL_TYPE; - ret.pos = new Vector3i(tes.getBlockPos()); - ret.dim = tes.getLevel().dimension().location(); - ret.side = side; - ret.text = text; - ret.soundPos = soundPos; - - return ret; + this(tes, side, new ScreenModifyControl(rot)); } + @Deprecated(forRemoval = true) public static C2SMessageScreenCtrl vec2(TileEntityScreen tes, BlockSide side, int ctrl, Vector2i vec) { - if (!isVec2Ctrl(ctrl)) - throw new RuntimeException("Called SMessageScreenCtrl.vec2() with non-vec2 control message " + ctrl); - - C2SMessageScreenCtrl ret = new C2SMessageScreenCtrl(); - ret.ctrl = ctrl; - ret.pos = new Vector3i(tes.getBlockPos()); - ret.dim = tes.getLevel().dimension().location(); - ret.side = side; - ret.vec2i = vec; - + throw new RuntimeException("Moved: look into ScreenControlRegistry"); + } + + @Deprecated(forRemoval = true) + public static C2SMessageScreenCtrl resolution(TileEntityScreen tes, BlockSide side, Vector2i vec) { + C2SMessageScreenCtrl ret = base(tes, side); + ret.control = new ScreenModifyControl(vec); return ret; } + @Deprecated(forRemoval = true) + public static C2SMessageScreenCtrl type(TileEntityScreen tes, BlockSide side, String text, BlockPos soundPos) { + C2SMessageScreenCtrl ret = base(tes, side); + ret.control = new KeyTypedControl(text, soundPos); + return ret; + } + + public static C2SMessageScreenCtrl laserMove(TileEntityScreen tes, BlockSide side, Vector2i vec) { + C2SMessageScreenCtrl ret = base(tes, side); + ret.control = new LaserControl(LaserControl.ControlType.MOVE, vec); + return ret; + } + + public static C2SMessageScreenCtrl laserDown(TileEntityScreen tes, BlockSide side, Vector2i vec) { + C2SMessageScreenCtrl ret = base(tes, side); + ret.control = new LaserControl(LaserControl.ControlType.MOVE, vec); + return ret; + } + + @Deprecated(forRemoval = true) public static C2SMessageScreenCtrl laserUp(TileEntityScreen tes, BlockSide side) { - C2SMessageScreenCtrl ret = new C2SMessageScreenCtrl(); - ret.ctrl = CTRL_LASER_UP; - ret.pos = new Vector3i(tes.getBlockPos()); - ret.dim = tes.getLevel().dimension().location(); - ret.side = side; - + C2SMessageScreenCtrl ret = base(tes, side); + ret.control = new LaserControl(LaserControl.ControlType.UP, null); return ret; } + @Deprecated(forRemoval = true) public static C2SMessageScreenCtrl jsRequest(TileEntityScreen tes, BlockSide side, int reqId, JSServerRequest reqType, Object... data) { - C2SMessageScreenCtrl ret = new C2SMessageScreenCtrl(); - ret.ctrl = CTRL_JS_REQUEST; - ret.pos = new Vector3i(tes.getBlockPos()); - ret.dim = tes.getLevel().dimension().location(); - ret.side = side; - ret.jsReqID = reqId; - ret.jsReqType = reqType; - ret.jsReqData = data; - + C2SMessageScreenCtrl ret = base(tes, side); + ret.control = new JSRequestControl(reqId, reqType, data); return ret; } + @Deprecated(forRemoval = true) public static C2SMessageScreenCtrl autoVol(TileEntityScreen tes, BlockSide side, boolean av) { - C2SMessageScreenCtrl ret = new C2SMessageScreenCtrl(); - ret.ctrl = CTRL_SET_AUTO_VOL; - ret.pos = new Vector3i(tes.getBlockPos()); - ret.dim = tes.getLevel().dimension().location(); - ret.side = side; - ret.autoVol = av; - + C2SMessageScreenCtrl ret = base(tes, side); + ret.control = new AutoVolumeControl(av); return ret; } - private static boolean isVec2Ctrl(int msg) { - return msg == CTRL_SET_RESOLUTION || msg == CTRL_LASER_DOWN || msg == CTRL_LASER_MOVE; - } - public C2SMessageScreenCtrl(FriendlyByteBuf buf) { super(buf); - decode(buf); - } - - public void decode(FriendlyByteBuf buf) { - C2SMessageScreenCtrl message = this; - message.ctrl = buf.readByte(); - message.dim = buf.readResourceLocation(); - message.pos = new Vector3i(buf); - message.side = BlockSide.fromInt(buf.readByte()); - if (message.ctrl == CTRL_SET_URL) - message.url = buf.readUtf(); - else if (message.ctrl == CTRL_ADD_FRIEND || message.ctrl == CTRL_REMOVE_FRIEND) - message.friend = new NameUUIDPair(buf); - else if (message.ctrl == CTRL_SET_RIGHTS) { - message.friendRights = buf.readByte(); - message.otherRights = buf.readByte(); - } else if (isVec2Ctrl(message.ctrl)) - message.vec2i = new Vector2i(buf); - else if (message.ctrl == CTRL_TYPE) { - message.text = buf.readUtf(); - - int sx = buf.readInt(); - int sy = buf.readInt(); - int sz = buf.readInt(); - message.soundPos = new BlockPos(sx, sy, sz); - } else if (message.ctrl == CTRL_REMOVE_UPGRADE) - message.toRemove = buf.readItem(); - else if (message.ctrl == CTRL_JS_REQUEST) { - message.jsReqID = buf.readInt(); - message.jsReqType = JSServerRequest.fromID(buf.readByte()); - - if (message.jsReqType != null) - message.jsReqData = message.jsReqType.deserialize(buf); - } else if (message.ctrl == CTRL_SET_ROTATION) - message.rotation = Rotation.values()[buf.readByte() & 3]; - else if (message.ctrl == CTRL_SET_URL_REMOTE) { - message.url = buf.readUtf(); - message.remoteLoc = new Vector3i(buf); - } else if (message.ctrl == CTRL_SET_AUTO_VOL) - message.autoVol = buf.readBoolean(); + pos = buf.readBlockPos(); + side = (BlockSide) BufferUtils.readEnum(buf, (i) -> BlockSide.values()[i], (byte) 1); + + this.control = ScreenControlRegistry.parse(buf); } @Override public void write(FriendlyByteBuf buf) { - buf.writeByte(ctrl); - buf.writeResourceLocation(dim); - pos.writeTo(buf); - buf.writeByte(side.ordinal()); + buf.writeBlockPos(pos); + BufferUtils.writeEnum(buf, side, (byte) 1); - if (ctrl == CTRL_SET_URL) - buf.writeUtf(url); - else if (ctrl == CTRL_ADD_FRIEND || ctrl == CTRL_REMOVE_FRIEND) - friend.writeTo(buf); - else if (ctrl == CTRL_SET_RIGHTS) { - buf.writeByte(friendRights); - buf.writeByte(otherRights); - } else if (isVec2Ctrl(ctrl)) - vec2i.writeTo(buf); - else if (ctrl == CTRL_TYPE) { - buf.writeUtf(text); - buf.writeInt(soundPos.getX()); - buf.writeInt(soundPos.getY()); - buf.writeInt(soundPos.getZ()); - } else if (ctrl == CTRL_REMOVE_UPGRADE) - buf.writeItem(toRemove); - else if (ctrl == CTRL_JS_REQUEST) { - buf.writeInt(jsReqID); - buf.writeByte(jsReqType.ordinal()); - - if (!jsReqType.serialize(buf, jsReqData)) - throw new RuntimeException("Could not serialize CTRL_JS_REQUEST " + jsReqType); - } else if (ctrl == CTRL_SET_ROTATION) - buf.writeByte(rotation.ordinal()); - else if (ctrl == CTRL_SET_URL_REMOTE) { - buf.writeUtf(url); - remoteLoc.writeTo(buf); - } else if (ctrl == CTRL_SET_AUTO_VOL) - buf.writeBoolean(autoVol); + buf.writeUtf(control.getId().toString()); + control.write(buf); } - @Override - public void run() { - if (side == null) { - Log.warning("Caught invalid packet from %s (UUID %s) referencing an invalid block side", player.getName(), player.getGameProfile().getId().toString()); - return; - } - - try { - runUnsafe(); - } catch (MissingPermissionException e) { - Log.errorEx("I have reasons to believe %s (UUID %s) is a hacker, but don't take my word for it...", e, e.getPlayer().getName(), e.getPlayer().getGameProfile().getId().toString()); - } - } - - private void checkPermission(TileEntityScreen scr, int right) throws MissingPermissionException { - int prights = scr.getScreen(side).rightsFor(player); + public void checkPermission(ServerPlayer sender, TileEntityScreen scr, int right) throws MissingPermissionException { + int prights = scr.getScreen(side).rightsFor(sender); if ((prights & right) == 0) - throw new MissingPermissionException(right, player); - } - - private void runUnsafe() throws MissingPermissionException { - Level world = player.level; - BlockPos bp = pos.toBlock(); - - if (!world.dimension().location().equals(dim)) - return; //Out of range (dimension mismatch) - - if (ctrl == CTRL_SET_URL_REMOTE) { - double reachDist = player.getAttributeValue(ForgeMod.REACH_DISTANCE.get()); - BlockPos blockPos = remoteLoc.toBlock(); - - if (player.distanceToSqr(blockPos.getX(), blockPos.getY(), blockPos.getZ()) > reachDist * reachDist) - return; //Out of range (player reach distance) - - BlockState bs = world.getBlockState(blockPos); - if (bs.getBlock() != BlockInit.blockServer.get() && bs.getBlock() != BlockInit.blockRControl.get() && - bs.getBlock() != BlockInit.blockKeyBoard.get() && bs.getBlock() != BlockInit.blockRedControl.get() - && bs.getValue(BlockPeripheral.type) != DefaultPeripheral.REMOTE_CONTROLLER) - return; //I call it hax... - } else if (player.distanceToSqr(bp.getX(), bp.getY(), bp.getZ()) > (128 * 128)) - return; //Out of range (range problem) - - BlockEntity te = world.getBlockEntity(bp); - if (te == null || !(te instanceof TileEntityScreen)) { - Log.error("TileEntity at %s is not a screen; can't control it!", pos.toString()); - return; - } - - TileEntityScreen tes = (TileEntityScreen) te; - - if (ctrl == CTRL_SET_URL || ctrl == CTRL_SET_URL_REMOTE) { - checkPermission(tes, ScreenRights.CHANGE_URL); - try { - tes.setScreenURL(side, url); - } catch (IOException e) { - throw new RuntimeException(e); - } - } else if (ctrl == CTRL_SHUT_DOWN) { - //TODO - //checkPermission(tes, ScreenRights.CHANGE_URL); - //tes.removeScreen(side); - } else if (ctrl == CTRL_ADD_FRIEND) { - checkPermission(tes, ScreenRights.MANAGE_FRIEND_LIST); - tes.addFriend(player, side, friend); - } else if (ctrl == CTRL_REMOVE_FRIEND) { - checkPermission(tes, ScreenRights.MANAGE_FRIEND_LIST); - tes.removeFriend(player, side, friend); - } else if (ctrl == CTRL_SET_RIGHTS) { - TileEntityScreen.Screen scr = tes.getScreen(side); - - if (scr != null) { - int fr = scr.owner.uuid.equals(player.getGameProfile().getId()) ? friendRights : scr.friendRights; - int or = (scr.rightsFor(player) & ScreenRights.MANAGE_OTHER_RIGHTS) == 0 ? scr.otherRights : otherRights; - - if (scr.friendRights != fr || scr.otherRights != or) - tes.setRights(player, side, fr, or); - } - } else if (ctrl == CTRL_SET_RESOLUTION) { - checkPermission(tes, ScreenRights.CHANGE_RESOLUTION); - tes.setResolution(side, vec2i); - } else if (ctrl == CTRL_TYPE) { - checkPermission(tes, ScreenRights.CLICK); - tes.type(side, text, soundPos); - } else if (ctrl == CTRL_REMOVE_UPGRADE) { - checkPermission(tes, ScreenRights.MANAGE_UPGRADES); - tes.removeUpgrade(side, toRemove, player); - } else if (ctrl == CTRL_LASER_DOWN || ctrl == CTRL_LASER_MOVE) - tes.laserDownMove(side, player, vec2i, ctrl == CTRL_LASER_DOWN); - else if (ctrl == CTRL_LASER_UP) - tes.laserUp(side, player); - else if (ctrl == CTRL_JS_REQUEST) { - if (jsReqType == null || jsReqData == null) - Log.warning("Caught invalid JS request from player %s (UUID %s)", player.getName(), player.getGameProfile().getId().toString()); - else - tes.handleJSRequest(player, side, jsReqID, jsReqType, jsReqData); - } else if (ctrl == CTRL_SET_ROTATION) { - checkPermission(tes, ScreenRights.CHANGE_RESOLUTION); - tes.setRotation(side, rotation); - } else if (ctrl == CTRL_SET_AUTO_VOL) { - checkPermission(tes, ScreenRights.MANAGE_UPGRADES); //because why not - tes.setAutoVolume(side, autoVol); - } else - Log.warning("Caught SMessageScreenCtrl with invalid control ID %d from player %s (UUID %s)", ctrl, player.getName(), player.getGameProfile().getId().toString()); + throw new MissingPermissionException(right, sender); } public void handle(NetworkEvent.Context ctx) { - player = ctx.getSender(); - ctx.enqueueWork(this); - ctx.setPacketHandled(true); + if (checkServer(ctx)) { + ctx.enqueueWork(() -> { + try { + Level level = (Level) WebDisplays.PROXY.getWorld(ctx); + BlockEntity be = level.getBlockEntity(pos); + if (be instanceof TileEntityScreen tes) { + control.handleServer(pos, side, tes, ctx, (perm) -> { + try { + checkPermission(ctx.getSender(), tes, perm); + return true; + } catch (Throwable ignored) { + return false; + } + }); + } + } catch (MissingPermissionException e) { + } + }); + ctx.setPacketHandled(true); + } } } diff --git a/src/main/java/net/montoyo/wd/utilities/VideoType.java b/src/main/java/net/montoyo/wd/utilities/VideoType.java index 28176c5..eae8212 100644 --- a/src/main/java/net/montoyo/wd/utilities/VideoType.java +++ b/src/main/java/net/montoyo/wd/utilities/VideoType.java @@ -81,6 +81,7 @@ public enum VideoType { return String.format(format, vid); } + // TODO: timestamp stuff @Nonnull public String getVolumeJSQuery(int volInt, int volFrac) { return (new StringBuilder(volumeCap)).append(volumePrefix).append(volInt).append('.').append(volFrac).append(volumeSuffix).toString(); diff --git a/src/main/resources/assets/webdisplays/lang/en_us.json b/src/main/resources/assets/webdisplays/lang/en_us.json index 2ac67e4..c96ad5c 100644 --- a/src/main/resources/assets/webdisplays/lang/en_us.json +++ b/src/main/resources/assets/webdisplays/lang/en_us.json @@ -2,12 +2,12 @@ "itemGroup.webdisplays": "ยง5Web Displays", "block.webdisplays.screen": "Web Screen", "block.webdisplays.peripheral": "Peripheral", - "block.webdisplays.peripheral.keyboard": "Keyboard", - "block.webdisplays.peripheral.remotectrl": "Remote Controller", - "block.webdisplays.peripheral.ccinterface": "ComputerCraft Interface", - "block.webdisplays.peripheral.cointerface": "OpenComputers Interface", - "block.webdisplays.peripheral.redstonectrl": "Redstone Controller", - "block.webdisplays.peripheral.server": "Server", + "block.webdisplays.kb_left": "Keyboard", + "block.webdisplays.rctrl": "Remote Controller", + "block.webdisplays.ccinterface": "ComputerCraft Interface", + "block.webdisplays.cointerface": "OpenComputers Interface", + "block.webdisplays.redctrl": "Redstone Controller", + "block.webdisplays.server": "Server", "item.webdisplays.screencfg": "Screen Configurator", "item.webdisplays.ownerthief": "Ownership Thief [ADMIN]", "item.webdisplays.linker": "Linking Tool", @@ -24,10 +24,10 @@ "item.webdisplays.minepad": "minePad", "item.webdisplays.minepad2": "minePad 2", "item.webdisplays.upgrade": "Screen Upgrade", - "item.webdisplays.upgrade.lasermouse": "Laser Sensor", - "item.webdisplays.upgrade.redinput": "Redstone Input Port", - "item.webdisplays.upgrade.redoutput": "Redstone Output Port", - "item.webdisplays.upgrade.gps": "GPS Module", + "item.webdisplays.upgrade_lasermouse": "Laser Sensor", + "item.webdisplays.upgrade_redinput": "Redstone Input Port", + "item.webdisplays.upgrade_redoutput": "Redstone Output Port", + "item.webdisplays.upgrade_gps": "GPS Module", "item.webdisplays.laserpointer": "Laser Pointer", "item.webdisplays.advicon": "Advancement Icon", "item.webdisplays.advicon.wd": "WebDisplays",