From 8324aa671035077f99127b0dc4deb31f27c33144 Mon Sep 17 00:00:00 2001 From: Nicolas BARBOTIN Date: Fri, 9 Feb 2018 22:30:01 +0100 Subject: [PATCH] + Added OC Interface * Fixed backspace bug with keyboard * Fixed bug with minePad URLs * Fixed bug with minePad right-click --- README.md | 4 +- src/main/java/net/montoyo/wd/WebDisplays.java | 9 +- .../java/net/montoyo/wd/client/WDScheme.java | 8 + .../montoyo/wd/client/gui/GuiKeyboard.java | 17 +- .../net/montoyo/wd/client/gui/GuiSetURL2.java | 16 +- .../montoyo/wd/core/DefaultPeripheral.java | 2 +- .../net/montoyo/wd/core/ScreenRights.java | 4 +- .../wd/entity/TileEntityOCInterface.java | 390 ++++++++++++++++++ .../montoyo/wd/entity/TileEntityScreen.java | 28 +- .../montoyo/wd/entity/TileEntityServer.java | 16 +- .../net/montoyo/wd/item/ItemMinePad2.java | 19 +- .../net/montoyo/wd/item/ItemPeripheral.java | 2 + .../miniserv/client/ClientTaskCheckFile.java | 9 +- .../wd/net/client/CMessageScreenUpdate.java | 36 +- .../java/net/montoyo/wd/utilities/Util.java | 69 +--- 15 files changed, 527 insertions(+), 102 deletions(-) create mode 100644 src/main/java/net/montoyo/wd/entity/TileEntityOCInterface.java diff --git a/README.md b/README.md index 2c83404..069c4a0 100644 --- a/README.md +++ b/README.md @@ -2,12 +2,10 @@ This is the unfinished port of the WebDisplays mod for Minecraft 1.12.2. The text below is my "TODO" list. ### Missing features -* Peripheral: OpenComputers interface * Read config (see "Config elements" below) ### TODO * French translations -* minePad management: check GuiContainer.draggedStack for minePad * Change mod name to WD2 * Put a limit on screen resolution * Auto-find rotation for BOTTOM & TOP screens @@ -27,4 +25,6 @@ This is the unfinished port of the WebDisplays mod for Minecraft 1.12.2. The tex * The Shop * CC Interface, if CC gets updated... * Center camera to screen when using keyboard +* minePad management: check GuiContainer.draggedStack for minePad + diff --git a/src/main/java/net/montoyo/wd/WebDisplays.java b/src/main/java/net/montoyo/wd/WebDisplays.java index 2e218fc..557ba73 100644 --- a/src/main/java/net/montoyo/wd/WebDisplays.java +++ b/src/main/java/net/montoyo/wd/WebDisplays.java @@ -20,6 +20,7 @@ import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.event.RegistryEvent; import net.minecraftforge.event.entity.item.ItemTossEvent; import net.minecraftforge.event.world.WorldEvent; +import net.minecraftforge.fml.common.Loader; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.SidedProxy; import net.minecraftforge.fml.common.event.*; @@ -47,7 +48,7 @@ import java.util.Arrays; import java.util.Optional; import java.util.UUID; -@Mod(modid = "webdisplays", version = WebDisplays.MOD_VERSION, dependencies = "required-after:mcef;") +@Mod(modid = "webdisplays", version = WebDisplays.MOD_VERSION, dependencies = "required-after:mcef;after:opencomputers;") public class WebDisplays { public static final String MOD_VERSION = "1.0"; @@ -97,6 +98,7 @@ public class WebDisplays { public double padResY; private int lastPadId = 0; public boolean doHardRecipe = true; + private boolean hasOC; @Mod.EventHandler public void onPreInit(FMLPreInitializationEvent ev) { @@ -158,6 +160,7 @@ public class WebDisplays { @Mod.EventHandler public void onPostInit(FMLPostInitializationEvent ev) { PROXY.postInit(); + hasOC = Loader.isModLoaded("opencomputers"); } @SubscribeEvent @@ -317,5 +320,9 @@ public class WebDisplays { } } + public static boolean isOpenComputersAvailable() { + return INSTANCE.hasOC; + } + } diff --git a/src/main/java/net/montoyo/wd/client/WDScheme.java b/src/main/java/net/montoyo/wd/client/WDScheme.java index 22c12ec..f3e547b 100644 --- a/src/main/java/net/montoyo/wd/client/WDScheme.java +++ b/src/main/java/net/montoyo/wd/client/WDScheme.java @@ -16,6 +16,8 @@ import net.montoyo.wd.utilities.Log; import net.montoyo.wd.utilities.Util; import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import java.net.URLEncoder; import java.util.UUID; public class WDScheme implements IScheme { @@ -35,6 +37,12 @@ public class WDScheme implements IScheme { String uuidStr = url.substring(0, pos); String fileStr = url.substring(pos + 1); + try { + fileStr = URLDecoder.decode(fileStr, "UTF-8"); + } catch(UnsupportedEncodingException ex) { + Log.warningEx("UTF-8 isn't supported... yeah... and I'm a billionaire...", ex); + } + if(uuidStr.isEmpty() || Util.isFileNameInvalid(fileStr)) return SchemePreResponse.NOT_HANDLED; diff --git a/src/main/java/net/montoyo/wd/client/gui/GuiKeyboard.java b/src/main/java/net/montoyo/wd/client/gui/GuiKeyboard.java index 87e4970..6430666 100644 --- a/src/main/java/net/montoyo/wd/client/gui/GuiKeyboard.java +++ b/src/main/java/net/montoyo/wd/client/gui/GuiKeyboard.java @@ -120,18 +120,19 @@ public class GuiKeyboard extends WDScreen { char chr = Keyboard.getEventCharacter(); if(chr == '\n' || chr == '\r' || chr == '\b') { - if(lastIsType) - lastIsType = false; + if(Keyboard.getEventKeyState()) { + if(lastIsType) + lastIsType = false; - if(!eventStack.isEmpty()) - eventStack += (char) 1; + if(!eventStack.isEmpty()) + eventStack += (char) 1; - if(Keyboard.getEventKeyState()) eventStack += 'p'; - else + eventStack += chr; + eventStack += (char) 1; eventStack += 'r'; - - eventStack += chr; + eventStack += chr; + } } else if(chr != 0) { if(!lastIsType) { if(!eventStack.isEmpty()) diff --git a/src/main/java/net/montoyo/wd/client/gui/GuiSetURL2.java b/src/main/java/net/montoyo/wd/client/gui/GuiSetURL2.java index 9711c29..0830aeb 100644 --- a/src/main/java/net/montoyo/wd/client/gui/GuiSetURL2.java +++ b/src/main/java/net/montoyo/wd/client/gui/GuiSetURL2.java @@ -4,8 +4,12 @@ package net.montoyo.wd.client.gui; +import net.minecraft.item.ItemStack; +import net.minecraft.util.EnumHand; import net.minecraft.util.ResourceLocation; +import net.montoyo.mcef.api.IBrowser; import net.montoyo.wd.WebDisplays; +import net.montoyo.wd.client.ClientProxy; import net.montoyo.wd.client.gui.controls.Button; import net.montoyo.wd.client.gui.controls.TextField; import net.montoyo.wd.client.gui.loading.FillControl; @@ -91,9 +95,17 @@ public class GuiSetURL2 extends WDScreen { if(!url.isEmpty()) { url = Util.addProtocol(url); - if(isPad) + if(isPad) { WebDisplays.NET_HANDLER.sendToServer(new SMessagePadCtrl(url)); - else + ItemStack held = mc.player.getHeldItem(EnumHand.MAIN_HAND); + + if(held.getItem() == WebDisplays.INSTANCE.itemMinePad && held.getTagCompound() != null && held.getTagCompound().hasKey("PadID")) { + ClientProxy.PadData pd = ((ClientProxy) WebDisplays.PROXY).getPadByID(held.getTagCompound().getInteger("PadID")); + + if(pd != null && pd.view != null) + pd.view.loadURL(url); + } + } else WebDisplays.NET_HANDLER.sendToServer(SMessageScreenCtrl.setURL(tileEntity, screenSide, url, remoteLocation)); } diff --git a/src/main/java/net/montoyo/wd/core/DefaultPeripheral.java b/src/main/java/net/montoyo/wd/core/DefaultPeripheral.java index 7d078ad..7c86a01 100644 --- a/src/main/java/net/montoyo/wd/core/DefaultPeripheral.java +++ b/src/main/java/net/montoyo/wd/core/DefaultPeripheral.java @@ -14,7 +14,7 @@ public enum DefaultPeripheral implements IStringSerializable { KEYBOARD("keyboard", TileEntityKeyboard.class), //WITH FACING (< 3) CC_INTERFACE("ccinterface", null), - OC_INTERFACE("cointerface", null), + OC_INTERFACE("cointerface", TileEntityOCInterface.class), REMOTE_CONTROLLER("remotectrl", TileEntityRCtrl.class), //WITHOUT FACING (>= 3) REDSTONE_CONTROLLER("redstonectrl", TileEntityRedCtrl.class), SERVER("server", TileEntityServer.class); diff --git a/src/main/java/net/montoyo/wd/core/ScreenRights.java b/src/main/java/net/montoyo/wd/core/ScreenRights.java index 9b6ae36..ef9dc27 100644 --- a/src/main/java/net/montoyo/wd/core/ScreenRights.java +++ b/src/main/java/net/montoyo/wd/core/ScreenRights.java @@ -6,11 +6,11 @@ package net.montoyo.wd.core; public abstract class ScreenRights { - public static final int CHANGE_URL = 1; + public static final int CHANGE_URL = 1; //Change URL AND run JavaScript public static final int CLICK = 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; + public static final int MANAGE_UPGRADES = 16; //Manage upgrades AND peripherals public static final int CHANGE_RESOLUTION = 32; //Change resolution AND rotation public static final int NONE = 0; diff --git a/src/main/java/net/montoyo/wd/entity/TileEntityOCInterface.java b/src/main/java/net/montoyo/wd/entity/TileEntityOCInterface.java new file mode 100644 index 0000000..c2f532b --- /dev/null +++ b/src/main/java/net/montoyo/wd/entity/TileEntityOCInterface.java @@ -0,0 +1,390 @@ +/* + * Copyright (C) 2018 BARBOTIN Nicolas + */ + +package net.montoyo.wd.entity; + +import li.cil.oc.api.machine.Arguments; +import li.cil.oc.api.machine.Callback; +import li.cil.oc.api.machine.Context; +import li.cil.oc.api.network.SimpleComponent; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraftforge.fml.common.Optional; +import net.montoyo.wd.core.IUpgrade; +import net.montoyo.wd.core.ScreenRights; +import net.montoyo.wd.net.client.CMessageScreenUpdate; +import net.montoyo.wd.utilities.NameUUIDPair; +import net.montoyo.wd.utilities.Rotation; +import net.montoyo.wd.utilities.Util; +import net.montoyo.wd.utilities.Vector2i; + +import javax.annotation.Nonnull; + +@Optional.Interface(iface = "li.cil.oc.api.network.SimpleComponent", modid = "opencomputers") +public class TileEntityOCInterface extends TileEntityPeripheralBase implements SimpleComponent { + + private NameUUIDPair owner; + private static final Object[] TRUE = new Object[] { true }; + private static final Object[] FALSE = new Object[] { false }; + + @Override + public void readFromNBT(NBTTagCompound tag) { + super.readFromNBT(tag); + owner = Util.readOwnerFromNBT(tag); + } + + @Override + @Nonnull + public NBTTagCompound writeToNBT(NBTTagCompound tag) { + super.writeToNBT(tag); + return Util.writeOwnerToNBT(tag, owner); + } + + public void setOwner(EntityPlayer ep) { + owner = new NameUUIDPair(ep.getGameProfile()); + markDirty(); + } + + @Override + public String getComponentName() { + return "webdisplays"; + } + + @Callback + @Optional.Method(modid = "opencomputers") + public Object[] isLinked(Context ctx, Arguments args) { + return new Object[] { isLinked() }; + } + + @Callback + @Optional.Method(modid = "opencomputers") + public Object[] isScreenChunkLoaded(Context ctx, Arguments args) { + return new Object[] { isScreenChunkLoaded() }; + } + + @Callback + @Optional.Method(modid = "opencomputers") + public Object[] getScreenPos(Context ctx, Arguments args) { + return isLinked() ? new Object[] { screenPos.x, screenPos.y, screenPos.z } : null; + } + + @Callback + @Optional.Method(modid = "opencomputers") + public Object[] getScreenSide(Context ctx, Arguments args) { + return isLinked() ? new Object[] { screenSide.toString().toLowerCase() } : null; + } + + @Callback + @Optional.Method(modid = "opencomputers") + public Object[] getOwner(Context ctx, Arguments args) { + if(owner == null) + return null; + else + return new Object[] { owner.name, owner.uuid.toString() }; + } + + @Callback + @Optional.Method(modid = "opencomputers") + public Object[] can(Context ctx, Arguments args) { + String what = args.checkString(0).toLowerCase(); + int right; + switch(what) { + case "click": + case "type": + case "js": + case "javascript": + case "runjs": + right = ScreenRights.CLICK; + break; + + case "seturl": + right = ScreenRights.CHANGE_URL; + break; + + case "setresolution": + case "setrotation": + right = ScreenRights.CHANGE_RESOLUTION; + break; + + default: + throw new IllegalArgumentException("invalid right name"); + } + + if(owner == null || !isLinked() || !isScreenChunkLoaded()) + return null; + else + return ((getConnectedScreen().getScreen(screenSide).rightsFor(owner.uuid) & right) == 0) ? FALSE : TRUE; + } + + @Callback + @Optional.Method(modid = "opencomputers") + public Object[] hasUpgrade(Context ctx, Arguments args) { + String name = args.checkString(0); + + if(owner == null || !isLinked() || !isScreenChunkLoaded()) + return null; + else + return getConnectedScreen().getScreen(screenSide).upgrades.stream().anyMatch(is -> ((IUpgrade) is.getItem()).getJSName(is).equalsIgnoreCase(name)) ? TRUE : FALSE; + } + + @Callback + @Optional.Method(modid = "opencomputers") + public Object[] getSize(Context ctx, Arguments args) { + if(owner == null || !isLinked() || !isScreenChunkLoaded()) + return null; + else { + Vector2i sz = getConnectedScreen().getScreen(screenSide).size; + return new Object[] { sz.x, sz.y }; + } + } + + @Callback + @Optional.Method(modid = "opencomputers") + public Object[] getResolution(Context ctx, Arguments args) { + if(owner == null || !isLinked() || !isScreenChunkLoaded()) + return null; + else { + Vector2i res = getConnectedScreen().getScreen(screenSide).resolution; + return new Object[] { res.x, res.y }; + } + } + + @Callback + @Optional.Method(modid = "opencomputers") + public Object[] getRotation(Context ctx, Arguments args) { + if(owner == null || !isLinked() || !isScreenChunkLoaded()) + return null; + else + return new Object[] { getConnectedScreen().getScreen(screenSide).rotation.angle }; + } + + @Callback + @Optional.Method(modid = "opencomputers") + public Object[] getURL(Context ctx, Arguments args) { + if(owner == null || !isLinked() || !isScreenChunkLoaded()) + return null; + else + return new Object[] { getConnectedScreen().getScreen(screenSide).url }; + } + + private static Object[] err(String str) { + return new Object[] { false, str }; + } + + @Callback(limit = 4) + @Optional.Method(modid = "opencomputers") + public Object[] click(Context ctx, Arguments args) { + int x = args.checkInteger(0); + int y = args.checkInteger(1); + String action = "click"; + if(args.count() > 2) + action = args.checkString(2).toLowerCase(); + + int actionId; + switch(action) { + case "click": + actionId = CMessageScreenUpdate.MOUSE_CLICK; + break; + + case "up": + case "release": + actionId = CMessageScreenUpdate.MOUSE_UP; + break; + + case "down": + case "press": + actionId = CMessageScreenUpdate.MOUSE_DOWN; + break; + + case "move": + actionId = CMessageScreenUpdate.MOUSE_MOVE; + break; + + default: + throw new IllegalArgumentException("bad action name"); + } + + if(owner == null || !isLinked() || !isScreenChunkLoaded()) + return err("notlinked"); + else { + TileEntityScreen scr = getConnectedScreen(); + TileEntityScreen.Screen scrscr = scr.getScreen(screenSide); + + if((scrscr.rightsFor(owner.uuid) & ScreenRights.CLICK) == 0) + return err("restrictions"); + else { + switch(scrscr.rotation) { + case ROT_90: + y = scrscr.resolution.y - y; + break; + + case ROT_180: + x = scrscr.resolution.x - x; + y = scrscr.resolution.y - y; + break; + + case ROT_270: + x = scrscr.resolution.x - x; + break; + + default: + break; + } + + if(scrscr.rotation.isVertical) + scr.clickUnsafe(screenSide, actionId, y, x); + else + scr.clickUnsafe(screenSide, actionId, x, y); + + return TRUE; + } + } + } + + private Object[] realType(String what) { + if(owner == null || !isLinked() || !isScreenChunkLoaded()) + return err("notlinked"); + else { + TileEntityScreen scr = getConnectedScreen(); + + if((scr.getScreen(screenSide).rightsFor(owner.uuid) & ScreenRights.CLICK) == 0) + return err("restrictions"); + else { + scr.type(screenSide, what, null); + return TRUE; + } + } + } + + @Callback(limit = 4) + @Optional.Method(modid = "opencomputers") + public Object[] type(Context ctx, Arguments args) { + String text = args.checkString(0); + if(text.length() > 64) + return err("toolong"); + + if(text.indexOf((char) 1) >= 0) + return err("badchar"); + + return realType("t" + text); + } + + @Callback(limit = 4) + @Optional.Method(modid = "opencomputers") + public Object[] typeAdvanced(Context ctx, Arguments args) { + String text = args.checkString(0); + if(text.length() > 64) + return err("toolong"); + + String[] ctrl = text.split("" + ((char) 1)); + for(String c: ctrl) { + if(c.length() < 2) + return err("badformat"); + + if(c.charAt(0) != 't' && c.charAt(0) != 'p' && c.charAt(0) != 'r') + return err("badformat"); + } + + return realType(text); + } + + @Callback(limit = 1) + @Optional.Method(modid = "opencomputers") + public Object[] setURL(Context ctx, Arguments args) { + String url = args.checkString(0); + + if(owner == null || !isLinked() || !isScreenChunkLoaded()) + return err("notlinked"); + else { + TileEntityScreen scr = getConnectedScreen(); + + if((scr.getScreen(screenSide).rightsFor(owner.uuid) & ScreenRights.CHANGE_URL) == 0) + return err("restrictions"); + else { + scr.setScreenURL(screenSide, url); + return TRUE; + } + } + } + + @Callback(limit = 1) + @Optional.Method(modid = "opencomputers") + public Object[] setResolution(Context ctx, Arguments args) { + int rx = args.checkInteger(0); + int ry = args.checkInteger(1); + + if(owner == null || !isLinked() || !isScreenChunkLoaded()) + return err("notlinked"); + else { + TileEntityScreen scr = getConnectedScreen(); + + if((scr.getScreen(screenSide).rightsFor(owner.uuid) & ScreenRights.CHANGE_RESOLUTION) == 0) + return err("restrictions"); + else { + scr.setResolution(screenSide, new Vector2i(rx, ry)); + return TRUE; + } + } + } + + @Callback(limit = 1) + @Optional.Method(modid = "opencomputers") + public Object[] setRotation(Context ctx, Arguments args) { + int rot = args.checkInteger(0); + if(rot < 0) { + int toAdd = (rot / -360) + 1; + rot += toAdd * 360; + } + + rot /= 90; + rot &= 3; + + if(owner == null || !isLinked() || !isScreenChunkLoaded()) + return err("notlinked"); + else { + TileEntityScreen scr = getConnectedScreen(); + + if((scr.getScreen(screenSide).rightsFor(owner.uuid) & ScreenRights.CHANGE_RESOLUTION) == 0) + return err("restrictions"); + else { + scr.setRotation(screenSide, Rotation.values()[rot]); + return TRUE; + } + } + } + + @Callback(limit = 4) + @Optional.Method(modid = "opencomputers") + public Object[] runJS(Context ctx, Arguments args) { + String code = args.checkString(0); + + if(owner == null || !isLinked() || !isScreenChunkLoaded()) + return err("notlinked"); + else { + TileEntityScreen scr = getConnectedScreen(); + + if((scr.getScreen(screenSide).rightsFor(owner.uuid) & ScreenRights.CHANGE_URL) == 0) + return err("restrictions"); + else { + scr.evalJS(screenSide, code); + return TRUE; + } + } + } + + @Callback + @Optional.Method(modid = "opencomputers") + public Object[] unlink(Context ctx, Arguments args) { + if(isLinked()) { + screenPos = null; + screenSide = null; + markDirty(); + } + + return null; + } + + + +} diff --git a/src/main/java/net/montoyo/wd/entity/TileEntityScreen.java b/src/main/java/net/montoyo/wd/entity/TileEntityScreen.java index 8ddd04e..5c4d0d8 100644 --- a/src/main/java/net/montoyo/wd/entity/TileEntityScreen.java +++ b/src/main/java/net/montoyo/wd/entity/TileEntityScreen.java @@ -145,11 +145,14 @@ public class TileEntityScreen extends TileEntity { } public int rightsFor(EntityPlayer ply) { - final UUID uuid = ply.getGameProfile().getId(); + return rightsFor(ply.getGameProfile().getId()); + } + + public int rightsFor(UUID uuid) { if(owner.uuid.equals(uuid)) return ScreenRights.ALL; - return friends.stream().anyMatch((f) -> f.uuid.equals(uuid)) ? friendRights : otherRights; + return friends.stream().anyMatch(f -> f.uuid.equals(uuid)) ? friendRights : otherRights; } public void setupRedstoneStatus(World world, BlockPos start) { @@ -424,6 +427,13 @@ public class TileEntityScreen extends TileEntity { WebDisplays.NET_HANDLER.sendToAllAround(CMessageScreenUpdate.click(this, side, CMessageScreenUpdate.MOUSE_CLICK, vec), point()); } + void clickUnsafe(BlockSide side, int action, int x, int y) { + if(world.isRemote) { + Vector2i vec = (action == CMessageScreenUpdate.MOUSE_UP) ? null : new Vector2i(x, y); + WebDisplays.NET_HANDLER.sendToAllAround(CMessageScreenUpdate.click(this, side, action, vec), point()); + } + } + public void handleMouseEvent(BlockSide side, int event, @Nullable Vector2i vec) { Screen scr = getScreen(side); if(scr == null) { @@ -990,4 +1000,18 @@ public class TileEntityScreen extends TileEntity { } } + public void evalJS(BlockSide side, String code) { + Screen scr = getScreen(side); + if(scr == null) { + Log.error("Trying to run JS code on invalid screen on side %s", side.toString()); + return; + } + + if(world.isRemote) { + if(scr.browser != null) + scr.browser.runJS(code, ""); + } else + WebDisplays.NET_HANDLER.sendToAllAround(CMessageScreenUpdate.js(this, side, code), point()); + } + } diff --git a/src/main/java/net/montoyo/wd/entity/TileEntityServer.java b/src/main/java/net/montoyo/wd/entity/TileEntityServer.java index f3ae578..b72194a 100644 --- a/src/main/java/net/montoyo/wd/entity/TileEntityServer.java +++ b/src/main/java/net/montoyo/wd/entity/TileEntityServer.java @@ -13,7 +13,6 @@ import net.montoyo.wd.utilities.NameUUIDPair; import net.montoyo.wd.utilities.Util; import javax.annotation.Nonnull; -import java.util.UUID; public class TileEntityServer extends TileEntity { @@ -22,25 +21,14 @@ public class TileEntityServer extends TileEntity { @Override public void readFromNBT(NBTTagCompound tag) { super.readFromNBT(tag); - - long msb = tag.getLong("OwnerMSB"); - long lsb = tag.getLong("OwnerLSB"); - String str = tag.getString("OwnerName"); - owner = new NameUUIDPair(str, new UUID(msb, lsb)); + owner = Util.readOwnerFromNBT(tag); } @Override @Nonnull public NBTTagCompound writeToNBT(NBTTagCompound tag) { super.writeToNBT(tag); - - if(owner != null) { - tag.setLong("OwnerMSB", owner.uuid.getMostSignificantBits()); - tag.setLong("OwnerLSB", owner.uuid.getLeastSignificantBits()); - tag.setString("OwnerName", owner.name); - } - - return tag; + return Util.writeOwnerToNBT(tag, owner); } public void setOwner(EntityPlayer ep) { diff --git a/src/main/java/net/montoyo/wd/item/ItemMinePad2.java b/src/main/java/net/montoyo/wd/item/ItemMinePad2.java index 2aa3b55..e8c708f 100644 --- a/src/main/java/net/montoyo/wd/item/ItemMinePad2.java +++ b/src/main/java/net/montoyo/wd/item/ItemMinePad2.java @@ -49,15 +49,22 @@ public class ItemMinePad2 extends Item { @Nonnull public ActionResult onItemRightClick(World world, EntityPlayer ply, @Nonnull EnumHand hand) { ItemStack is = ply.getHeldItem(hand); + boolean ok; - if(world.isRemote) { - if(ply.isSneaking()) + if(ply.isSneaking()) { + if(world.isRemote) WebDisplays.PROXY.displaySetPadURLGui(getURL(is)); - else if(is.getTagCompound() != null && is.getTagCompound().hasKey("PadID")) - WebDisplays.PROXY.openMinePadGui(is.getTagCompound().getInteger("PadID")); - } - return ActionResult.newResult(EnumActionResult.SUCCESS, is); + ok = true; + } else if(is.getTagCompound() != null && is.getTagCompound().hasKey("PadID")) { + if(world.isRemote) + WebDisplays.PROXY.openMinePadGui(is.getTagCompound().getInteger("PadID")); + + ok = true; + } else + ok = false; + + return ActionResult.newResult(ok ? EnumActionResult.SUCCESS : EnumActionResult.PASS, is); } @Override diff --git a/src/main/java/net/montoyo/wd/item/ItemPeripheral.java b/src/main/java/net/montoyo/wd/item/ItemPeripheral.java index ac87227..a1b4b3f 100644 --- a/src/main/java/net/montoyo/wd/item/ItemPeripheral.java +++ b/src/main/java/net/montoyo/wd/item/ItemPeripheral.java @@ -54,6 +54,8 @@ public class ItemPeripheral extends ItemMultiTexture { public void addInformation(ItemStack is, @Nullable World world, List tt, ITooltipFlag ttFlags) { if(is.getMetadata() == 1) //CC Interface tt.add("" + ChatFormatting.RED + I18n.format("webdisplays.message.missingCC")); //CC is not available for 1.12.2 + else if(is.getMetadata() == 2 && !WebDisplays.isOpenComputersAvailable()) //OC Interface + tt.add("" + ChatFormatting.RED + I18n.format("webdisplays.message.missingOC")); else if(is.getMetadata() == 11 && WebDisplays.PROXY.isMiniservDisabled()) //Server tt.add("" + ChatFormatting.RED + I18n.format("webdisplays.message.noMiniserv")); } diff --git a/src/main/java/net/montoyo/wd/miniserv/client/ClientTaskCheckFile.java b/src/main/java/net/montoyo/wd/miniserv/client/ClientTaskCheckFile.java index b84a490..6b81825 100644 --- a/src/main/java/net/montoyo/wd/miniserv/client/ClientTaskCheckFile.java +++ b/src/main/java/net/montoyo/wd/miniserv/client/ClientTaskCheckFile.java @@ -8,6 +8,8 @@ import net.montoyo.wd.miniserv.Constants; import net.montoyo.wd.miniserv.OutgoingPacket; import net.montoyo.wd.miniserv.PacketID; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; import java.util.UUID; public class ClientTaskCheckFile extends ClientTask { @@ -48,7 +50,12 @@ public class ClientTaskCheckFile extends ClientTask { } public String getURL() { - return ((new StringBuilder("wd://"))).append(uuid.toString()).append('/').append(fname).toString(); + try { + return ((new StringBuilder("wd://"))).append(uuid.toString()).append('/').append(URLEncoder.encode(fname, "UTF-8")).toString(); + } catch(UnsupportedEncodingException ex) { + ex.printStackTrace(); + return "hi"; + } } } diff --git a/src/main/java/net/montoyo/wd/net/client/CMessageScreenUpdate.java b/src/main/java/net/montoyo/wd/net/client/CMessageScreenUpdate.java index 36bb387..3cbb99e 100644 --- a/src/main/java/net/montoyo/wd/net/client/CMessageScreenUpdate.java +++ b/src/main/java/net/montoyo/wd/net/client/CMessageScreenUpdate.java @@ -31,6 +31,7 @@ public class CMessageScreenUpdate implements IMessage, Runnable { public static final int UPDATE_JS_REDSTONE = 6; public static final int UPDATE_OWNER = 7; public static final int UPDATE_ROTATION = 8; + public static final int UPDATE_RUN_JS = 9; public static final int MOUSE_CLICK = 0; public static final int MOUSE_UP = 1; @@ -40,10 +41,9 @@ public class CMessageScreenUpdate implements IMessage, Runnable { private Vector3i pos; private BlockSide side; private int action; - private String url; + private String string; private Vector2i vec2i; private int mouseEvent; - private String text; private ItemStack[] upgrades; private int redstoneLevel; private NameUUIDPair owner; @@ -57,7 +57,7 @@ public class CMessageScreenUpdate implements IMessage, Runnable { ret.pos = new Vector3i(tes.getPos()); ret.side = side; ret.action = UPDATE_URL; - ret.url = url; + ret.string = url; return ret; } @@ -93,12 +93,22 @@ public class CMessageScreenUpdate implements IMessage, Runnable { CMessageScreenUpdate ret = new CMessageScreenUpdate(); ret.pos = new Vector3i(tes.getPos()); ret.side = side; - ret.text = text; + ret.string = text; ret.action = UPDATE_TYPE; return ret; } + public static CMessageScreenUpdate js(TileEntityScreen tes, BlockSide side, String code) { + CMessageScreenUpdate ret = new CMessageScreenUpdate(); + ret.pos = new Vector3i(tes.getPos()); + ret.side = side; + ret.string = code; + ret.action = UPDATE_RUN_JS; + + return ret; + } + public static CMessageScreenUpdate upgrade(TileEntityScreen tes, BlockSide side) { CMessageScreenUpdate ret = new CMessageScreenUpdate(); ret.pos = new Vector3i(tes.getPos()); @@ -151,8 +161,8 @@ public class CMessageScreenUpdate implements IMessage, Runnable { side = BlockSide.values()[buf.readByte()]; action = buf.readByte(); - if(action == UPDATE_URL) - url = ByteBufUtils.readUTF8String(buf); + if(action == UPDATE_URL || action == UPDATE_TYPE || action == UPDATE_RUN_JS) + string = ByteBufUtils.readUTF8String(buf); else if(action == UPDATE_MOUSE) { mouseEvent = buf.readByte(); @@ -160,8 +170,6 @@ public class CMessageScreenUpdate implements IMessage, Runnable { vec2i = new Vector2i(buf); } else if(action == UPDATE_RESOLUTION) vec2i = new Vector2i(buf); - else if(action == UPDATE_TYPE) - text = ByteBufUtils.readUTF8String(buf); else if(action == UPDATE_UPGRADES) { upgrades = new ItemStack[buf.readByte()]; @@ -182,8 +190,8 @@ public class CMessageScreenUpdate implements IMessage, Runnable { buf.writeByte(side.ordinal()); buf.writeByte(action); - if(action == UPDATE_URL) - ByteBufUtils.writeUTF8String(buf, url); + if(action == UPDATE_URL || action == UPDATE_TYPE || action == UPDATE_RUN_JS) + ByteBufUtils.writeUTF8String(buf, string); else if(action == UPDATE_MOUSE) { buf.writeByte(mouseEvent); @@ -191,8 +199,6 @@ public class CMessageScreenUpdate implements IMessage, Runnable { vec2i.writeTo(buf); } else if(action == UPDATE_RESOLUTION) vec2i.writeTo(buf); - else if(action == UPDATE_TYPE) - ByteBufUtils.writeUTF8String(buf, text); else if(action == UPDATE_UPGRADES) { buf.writeByte(upgrades.length); @@ -223,7 +229,7 @@ public class CMessageScreenUpdate implements IMessage, Runnable { }*/ if(action == UPDATE_URL) - tes.setScreenURL(side, url); + tes.setScreenURL(side, string); else if(action == UPDATE_MOUSE) tes.handleMouseEvent(side, mouseEvent, vec2i); else if(action == UPDATE_DELETE) @@ -231,7 +237,9 @@ public class CMessageScreenUpdate implements IMessage, Runnable { else if(action == UPDATE_RESOLUTION) tes.setResolution(side, vec2i); else if(action == UPDATE_TYPE) - tes.type(side, text, null); + tes.type(side, string, null); + else if(action == UPDATE_RUN_JS) + tes.evalJS(side, string); else if(action == UPDATE_UPGRADES) tes.updateUpgrades(side, upgrades); else if(action == UPDATE_JS_REDSTONE) diff --git a/src/main/java/net/montoyo/wd/utilities/Util.java b/src/main/java/net/montoyo/wd/utilities/Util.java index 876c677..d64deeb 100644 --- a/src/main/java/net/montoyo/wd/utilities/Util.java +++ b/src/main/java/net/montoyo/wd/utilities/Util.java @@ -6,7 +6,7 @@ package net.montoyo.wd.utilities; import io.netty.buffer.ByteBuf; import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.nbt.*; +import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.text.*; import net.minecraftforge.fml.common.network.ByteBufUtils; @@ -15,6 +15,7 @@ import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.Arrays; import java.util.StringJoiner; +import java.util.UUID; public abstract class Util { @@ -107,54 +108,6 @@ public abstract class Util { throw new RuntimeException(String.format("Cannot unserialize class %s!", cls.getName())); } - public static NBTBase serialize(Object f) { - Class cls = f.getClass(); - - if(cls == Integer.class) - return new NBTTagInt((Integer) f); - else if(cls == Float.class) - return new NBTTagFloat((Float) f); - else if(cls == Double.class) - return new NBTTagDouble((Double) f); - else if(cls == String.class) - return new NBTTagString((String) f); - else if(cls.isEnum()) - return new NBTTagInt(((Enum) f).ordinal()); - else if(cls.isArray()) { - Object[] ray = (Object[]) f; - NBTTagList ret = new NBTTagList(); - - for(Object o : ray) - ret.appendTag(serialize(o)); - - return ret; - } else - throw new RuntimeException(String.format("Cannot save class %s as NBT!", cls.getName())); - } - - public static Object unserialize(NBTBase nbt, Class cls) { - if(cls == Integer.class || cls == Integer.TYPE) - return ((NBTTagInt) nbt).getInt(); - else if(cls == Float.class || cls == Float.TYPE) - return ((NBTTagFloat) nbt).getFloat(); - else if(cls == Double.class || cls == Double.TYPE) - return ((NBTTagDouble) nbt).getDouble(); - else if(cls == String.class) - return ((NBTTagString) nbt).getString(); - else if(cls.isEnum()) - return cls.getEnumConstants()[((NBTTagInt) nbt).getInt()]; - else if(cls.isArray()) { - NBTTagList lst = (NBTTagList) nbt; - Object[] ray = new Object[lst.tagCount()]; - - for(int i = 0; lst.tagCount() > 0; i++) - ray[i] = unserialize(lst.removeTag(0), cls.getComponentType()); - - return Arrays.copyOf(ray, ray.length, cls); - } else - throw new RuntimeException(String.format("Cannot load class %s from NBT!", cls.getName())); - } - public static String[] commaSplit(String str) { ArrayList lst = new ArrayList<>(); String out = ""; @@ -250,4 +203,22 @@ public abstract class Util { return j.toString(); } + public static NBTTagCompound writeOwnerToNBT(NBTTagCompound tag, NameUUIDPair owner) { + if(owner != null) { + tag.setLong("OwnerMSB", owner.uuid.getMostSignificantBits()); + tag.setLong("OwnerLSB", owner.uuid.getLeastSignificantBits()); + tag.setString("OwnerName", owner.name); + } + + return tag; + } + + public static NameUUIDPair readOwnerFromNBT(NBTTagCompound tag) { + long msb = tag.getLong("OwnerMSB"); + long lsb = tag.getLong("OwnerLSB"); + String str = tag.getString("OwnerName"); + + return new NameUUIDPair(str, new UUID(msb, lsb)); + } + }