* Switched to latest MCEF version

* Switched to latest recommended forge version
+ Added auto-punycode in SetURL GUIs
+ Added welcome notice on first run
+ Added computer-craft support
This commit is contained in:
Nicolas BARBOTIN 2019-07-24 13:38:06 +02:00
parent 4e194e4856
commit 82aa167ae7
29 changed files with 1024 additions and 364 deletions

View File

@ -11,7 +11,7 @@ apply plugin: 'net.minecraftforge.gradle.forge'
//Only edit below this line, the above code adds and enables the necessary things for Forge to be setup.
version = "1.12.2-1.0"
version = "1.12.2-1.1"
group = "net.montoyo.wd" // http://maven.apache.org/guides/mini/guide-naming-conventions.html
archivesBaseName = "webdisplays"
@ -21,7 +21,7 @@ compileJava {
}
minecraft {
version = "1.12.2-14.23.2.2611"
version = "1.12.2-14.23.5.2768"
runDir = "run"
// the mappings can be changed at any time, and must be in the following format.

Binary file not shown.

Binary file not shown.

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2018 BARBOTIN Nicolas
* Copyright (C) 2019 BARBOTIN Nicolas
*/
package net.montoyo.wd;
@ -11,7 +11,7 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.common.DimensionManager;
import net.minecraftforge.fml.server.FMLServerHandler;
import net.montoyo.mcef.utilities.Log;
import net.montoyo.wd.utilities.Log;
import net.montoyo.wd.core.HasAdvancement;
import net.montoyo.wd.core.JSServerRequest;
import net.montoyo.wd.data.GuiData;

View File

@ -1,12 +1,14 @@
/*
* Copyright (C) 2018 BARBOTIN Nicolas
* Copyright (C) 2019 BARBOTIN Nicolas
*/
package net.montoyo.wd;
import com.google.gson.Gson;
import net.minecraft.advancements.Advancement;
import net.minecraft.advancements.CriteriaTriggers;
import net.minecraft.block.Block;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.init.SoundEvents;
@ -17,10 +19,13 @@ import net.minecraft.server.MinecraftServer;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.SoundCategory;
import net.minecraft.util.SoundEvent;
import net.minecraft.util.text.TextFormatting;
import net.minecraftforge.client.event.ClientChatEvent;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.common.capabilities.CapabilityManager;
import net.minecraftforge.common.config.Configuration;
import net.minecraftforge.common.config.Property;
import net.minecraftforge.event.AttachCapabilitiesEvent;
import net.minecraftforge.event.RegistryEvent;
import net.minecraftforge.event.ServerChatEvent;
import net.minecraftforge.event.entity.item.ItemTossEvent;
@ -52,10 +57,10 @@ import java.net.URL;
import java.util.Arrays;
import java.util.UUID;
@Mod(modid = "webdisplays", version = WebDisplays.MOD_VERSION, dependencies = "required-after:mcef;after:opencomputers;")
@Mod(modid = "webdisplays", version = WebDisplays.MOD_VERSION, dependencies = "required-after:mcef@[1.0,2.0);after:opencomputers;after:computercraft;")
public class WebDisplays {
public static final String MOD_VERSION = "1.0";
public static final String MOD_VERSION = "1.1";
@Mod.Instance(owner = "webdisplays")
public static WebDisplays INSTANCE;
@ -67,6 +72,8 @@ public class WebDisplays {
public static WDCreativeTab CREATIVE_TAB;
public static final ResourceLocation ADV_PAD_BREAK = new ResourceLocation("webdisplays", "webdisplays/pad_break");
public static final String BLACKLIST_URL = "mod://webdisplays/blacklisted.html";
public static final Gson GSON = new Gson();
public static final ResourceLocation CAPABILITY = new ResourceLocation("webdisplays", "customdatacap");
//Blocks
public BlockScreen blockScreen;
@ -105,6 +112,7 @@ public class WebDisplays {
private int lastPadId = 0;
public boolean doHardRecipe;
private boolean hasOC;
private boolean hasCC;
private String[] blacklist;
public boolean disableOwnershipThief;
public double unloadDistance2;
@ -241,13 +249,14 @@ public class WebDisplays {
@Mod.EventHandler
public void onInit(FMLInitializationEvent ev) {
//Register tile entities
GameRegistry.registerTileEntity(TileEntityScreen.class, "webdisplays:screen");
GameRegistry.registerTileEntity(TileEntityScreen.class, new ResourceLocation("webdisplays", "screen"));
for(DefaultPeripheral dp: DefaultPeripheral.values()) {
if(dp.getTEClass() != null)
GameRegistry.registerTileEntity(dp.getTEClass(), "webdisplays:" + dp.getName());
GameRegistry.registerTileEntity(dp.getTEClass(), new ResourceLocation("webdisplays", dp.getName()));
}
//Other things
CapabilityManager.INSTANCE.register(IWDDCapability.class, new WDDCapability.Storage(), new WDDCapability.Factory());
PROXY.init();
NET_HANDLER = NetworkRegistry.INSTANCE.newSimpleChannel("webdisplays");
Messages.registerAll(NET_HANDLER);
@ -257,6 +266,17 @@ public class WebDisplays {
public void onPostInit(FMLPostInitializationEvent ev) {
PROXY.postInit();
hasOC = Loader.isModLoaded("opencomputers");
hasCC = Loader.isModLoaded("computercraft");
if(hasCC) {
try {
//We have to do this because the "register" method might be stripped out if CC isn't loaded
CCPeripheralProvider.class.getMethod("register").invoke(null);
} catch(Throwable t) {
Log.error("ComputerCraft was found, but WebDisplays wasn't able to register its CC Interface Peripheral");
t.printStackTrace();
}
}
}
@SubscribeEvent
@ -371,8 +391,20 @@ public class WebDisplays {
@SubscribeEvent
public void onLogIn(PlayerEvent.PlayerLoggedInEvent ev) {
if(!ev.player.world.isRemote && ev.player instanceof EntityPlayerMP)
if(!ev.player.world.isRemote && ev.player instanceof EntityPlayerMP) {
WebDisplays.NET_HANDLER.sendTo(new CMessageServerInfo(miniservPort), (EntityPlayerMP) ev.player);
IWDDCapability cap = ev.player.getCapability(WDDCapability.INSTANCE, null);
if(cap == null)
Log.warning("Player %s (%s) has null IWDDCapability!", ev.player.getName(), ev.player.getGameProfile().getId().toString());
else if(cap.isFirstRun()) {
Util.toast(ev.player, TextFormatting.LIGHT_PURPLE, "welcome1");
Util.toast(ev.player, TextFormatting.LIGHT_PURPLE, "welcome2");
Util.toast(ev.player, TextFormatting.LIGHT_PURPLE, "welcome3");
cap.clearFirstRun();
}
}
}
@SubscribeEvent
@ -381,6 +413,30 @@ public class WebDisplays {
Server.getInstance().getClientManager().revokeClientKey(ev.player.getGameProfile().getId());
}
@SubscribeEvent
public void attachEntityCaps(AttachCapabilitiesEvent<Entity> ev) {
if(ev.getObject() instanceof EntityPlayer)
ev.addCapability(CAPABILITY, new WDDCapability.Provider());
}
@SubscribeEvent
public void onPlayerClone(net.minecraftforge.event.entity.player.PlayerEvent.Clone ev) {
IWDDCapability src = ev.getOriginal().getCapability(WDDCapability.INSTANCE, null);
IWDDCapability dst = ev.getEntityPlayer().getCapability(WDDCapability.INSTANCE, null);
if(src == null) {
Log.error("src is null");
return;
}
if(dst == null) {
Log.error("dst is null");
return;
}
src.cloneTo(dst);
}
@SubscribeEvent
public void onServerChat(ServerChatEvent ev) {
String msg = ev.getMessage().trim().replaceAll("\\s+", " ").toLowerCase();
@ -435,6 +491,10 @@ public class WebDisplays {
return INSTANCE.hasOC;
}
public static boolean isComputerCraftAvailable() {
return INSTANCE.hasCC;
}
public static boolean isSiteBlacklisted(String url) {
try {
URL url2 = new URL(Util.addProtocol(url));

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2018 BARBOTIN Nicolas
* Copyright (C) 2019 BARBOTIN Nicolas
*/
package net.montoyo.wd.block;
@ -33,10 +33,7 @@ import net.minecraft.world.World;
import net.minecraftforge.fml.common.network.NetworkRegistry;
import net.montoyo.wd.WebDisplays;
import net.montoyo.wd.core.DefaultPeripheral;
import net.montoyo.wd.entity.TileEntityKeyboard;
import net.montoyo.wd.entity.TileEntityOCInterface;
import net.montoyo.wd.entity.TileEntityPeripheralBase;
import net.montoyo.wd.entity.TileEntityServer;
import net.montoyo.wd.entity.*;
import net.montoyo.wd.item.ItemLinker;
import net.montoyo.wd.item.ItemPeripheral;
import net.montoyo.wd.net.client.CMessageCloseGui;
@ -209,8 +206,8 @@ public class BlockPeripheral extends WDBlockContainer {
if(te instanceof TileEntityServer)
((TileEntityServer) te).setOwner((EntityPlayer) placer);
else if(te instanceof TileEntityOCInterface)
((TileEntityOCInterface) te).setOwner((EntityPlayer) placer);
else if(te instanceof TileEntityInterfaceBase)
((TileEntityInterfaceBase) te).setOwner((EntityPlayer) placer);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2018 BARBOTIN Nicolas
* Copyright (C) 2019 BARBOTIN Nicolas
*/
package net.montoyo.wd.client;
@ -15,7 +15,6 @@ import net.minecraft.client.multiplayer.ClientAdvancementManager;
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
import net.minecraft.client.renderer.texture.TextureMap;
import net.minecraft.client.resources.IResourceManager;
import net.minecraft.client.resources.IResourceManagerReloadListener;
import net.minecraft.client.resources.SimpleReloadableResourceManager;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.Slot;
@ -31,9 +30,10 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import net.minecraftforge.client.GuiIngameForge;
import net.minecraftforge.client.event.*;
import net.minecraftforge.client.model.ModelLoader;
import net.minecraftforge.client.resource.IResourceType;
import net.minecraftforge.client.resource.ISelectiveResourceReloadListener;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.world.WorldEvent;
import net.minecraftforge.fml.client.registry.ClientRegistry;
@ -65,8 +65,9 @@ import java.lang.reflect.Field;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.util.*;
import java.util.function.Predicate;
public class ClientProxy extends SharedProxy implements IResourceManagerReloadListener, IDisplayHandler, IJSQueryHandler {
public class ClientProxy extends SharedProxy implements ISelectiveResourceReloadListener, IDisplayHandler, IJSQueryHandler {
public class PadData {
@ -126,7 +127,7 @@ public class ClientProxy extends SharedProxy implements IResourceManagerReloadLi
mcef = MCEFApi.getAPI();
if(mcef != null)
mcef.registerScheme("wd", WDScheme.class, true, false, false);
mcef.registerScheme("wd", WDScheme.class, true, false, false, true, true, false, false);
}
@Override
@ -374,7 +375,7 @@ public class ClientProxy extends SharedProxy implements IResourceManagerReloadLi
/**************************************** RESOURCE MANAGER METHODS ****************************************/
@Override
public void onResourceManagerReload(@Nonnull IResourceManager rm) {
public void onResourceManagerReload(IResourceManager resourceManager, Predicate<IResourceType> resourcePredicate) {
Log.info("Resource manager reload: clearing GUI cache...");
GuiLoader.clearCache();
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2018 BARBOTIN Nicolas
* Copyright (C) 2019 BARBOTIN Nicolas
*/
package net.montoyo.wd.client.gui;
@ -17,10 +17,12 @@ import net.montoyo.wd.entity.TileEntityScreen;
import net.montoyo.wd.net.server.SMessageScreenCtrl;
import net.montoyo.wd.utilities.BlockSide;
import net.montoyo.wd.utilities.Log;
import net.montoyo.wd.utilities.TypeData;
import net.montoyo.wd.utilities.Util;
import org.lwjgl.input.Keyboard;
import java.io.*;
import java.util.ArrayList;
import java.util.Map;
@SideOnly(Side.CLIENT)
@ -30,8 +32,7 @@ public class GuiKeyboard extends WDScreen {
private TileEntityScreen tes;
private BlockSide side;
private String eventStack = "";
private boolean lastIsType = false;
private final ArrayList<TypeData> evStack = new ArrayList<>();
private BlockPos kbPos;
private boolean showWarning = true;
@ -119,45 +120,28 @@ public class GuiKeyboard extends WDScreen {
else {
char chr = Keyboard.getEventCharacter();
if(chr == '\n' || chr == '\r' || chr == '\b') {
if(Keyboard.getEventKeyState()) {
if(lastIsType)
lastIsType = false;
if(Keyboard.getEventKeyState()) {
int kc = Keyboard.getEventKey();
if(!eventStack.isEmpty())
eventStack += (char) 1;
eventStack += 'p';
eventStack += chr;
eventStack += (char) 1;
eventStack += 'r';
eventStack += chr;
}
} else if(chr != 0) {
if(!lastIsType) {
if(!eventStack.isEmpty())
eventStack += (char) 1;
eventStack += 't';
lastIsType = true;
}
eventStack += chr;
evStack.add(new TypeData(TypeData.Action.PRESS, kc, chr));
evStack.add(new TypeData(TypeData.Action.RELEASE, kc, chr));
}
if(chr != 0)
evStack.add(new TypeData(TypeData.Action.TYPE, 0, chr));
}
}
if(!eventStack.isEmpty() && !syncRequested())
if(!evStack.isEmpty() && !syncRequested())
requestSync();
}
}
@Override
protected void sync() {
if(!eventStack.isEmpty()) {
WebDisplays.NET_HANDLER.sendToServer(SMessageScreenCtrl.type(tes, side, eventStack, kbPos));
eventStack = "";
lastIsType = false;
if(!evStack.isEmpty()) {
WebDisplays.NET_HANDLER.sendToServer(SMessageScreenCtrl.type(tes, side, WebDisplays.GSON.toJson(evStack), kbPos));
evStack.clear();
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2018 BARBOTIN Nicolas
* Copyright (C) 2019 BARBOTIN Nicolas
*/
package net.montoyo.wd.client.gui;
@ -82,6 +82,7 @@ public class GuiMinePad extends WDScreen {
public void handleInput() {
while(Keyboard.next()) {
char key = Keyboard.getEventCharacter();
int keycode = Keyboard.getEventKey();
boolean pressed = Keyboard.getEventKeyState();
if(Keyboard.getEventKey() == Keyboard.KEY_ESCAPE) {
@ -90,14 +91,12 @@ public class GuiMinePad extends WDScreen {
}
if(pad.view != null) {
if(key != '.' && key != ';' && key != ',') {
if(pressed)
pad.view.injectKeyPressed(key, 0);
else
pad.view.injectKeyReleased(key, 0);
}
if(pressed)
pad.view.injectKeyPressedByKeyCode(keycode, key, 0);
else
pad.view.injectKeyReleasedByKeyCode(keycode, key, 0);
if(key != Keyboard.CHAR_NONE)
if(key != 0)
pad.view.injectKeyTyped(key, 0);
}
}

View File

@ -1,11 +1,13 @@
/*
* Copyright (C) 2018 BARBOTIN Nicolas
* Copyright (C) 2019 BARBOTIN Nicolas
*/
package net.montoyo.wd.client.gui;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
import net.montoyo.mcef.api.API;
import net.montoyo.wd.client.ClientProxy;
import net.montoyo.wd.WebDisplays;
import net.montoyo.wd.client.gui.controls.Button;
import net.montoyo.wd.client.gui.controls.TextField;
@ -54,8 +56,10 @@ public class GuiRedstoneCtrl extends WDScreen {
@GuiSubscribe
public void onClick(Button.ClickEvent ev) {
if(ev.getSource() == btnOk) {
String rising = Util.addProtocol(tfRisingEdge.getText());
String falling = Util.addProtocol(tfFallingEdge.getText());
API mcef = ((ClientProxy) WebDisplays.PROXY).getMCEF();
String rising = mcef.punycode(Util.addProtocol(tfRisingEdge.getText()));
String falling = mcef.punycode(Util.addProtocol(tfFallingEdge.getText()));
WebDisplays.NET_HANDLER.sendToServer(new SMessageRedstoneCtrl(dimension, pos, rising, falling));
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2018 BARBOTIN Nicolas
* Copyright (C) 2019 BARBOTIN Nicolas
*/
package net.montoyo.wd.client.gui;
@ -94,6 +94,7 @@ public class GuiSetURL2 extends WDScreen {
private void validate(String url) {
if(!url.isEmpty()) {
url = Util.addProtocol(url);
url = ((ClientProxy) WebDisplays.PROXY).getMCEF().punycode(url);
if(isPad) {
WebDisplays.NET_HANDLER.sendToServer(new SMessagePadCtrl(url));

View File

@ -0,0 +1,90 @@
/*
* Copyright (C) 2019 BARBOTIN Nicolas
*/
package net.montoyo.wd.core;
import java.util.List;
import java.util.Map;
public class CCArguments implements IComputerArgs {
private final Object[] args;
public CCArguments(Object[] args) {
this.args = args;
}
@Override
public String checkString(int i) {
checkIndex(i, "string");
Object obj = args[i];
if(!(obj instanceof String))
throw typeError(i, "string", obj);
return (String) obj;
}
@Override
public int checkInteger(int i) {
checkIndex(i, "number");
Object obj = args[i];
int ret;
if(obj instanceof Integer)
ret = (int) obj;
else if(obj instanceof Double)
ret = ((Double) obj).intValue();
else if(obj instanceof Float)
ret = ((Float) obj).intValue();
else
throw typeError(i, "number", obj);
return ret;
}
@Override
public Map checkTable(int i) {
checkIndex(i, "table");
Object obj = args[i];
if(!(obj instanceof Map))
throw typeError(i, "table", args[i]);
return (Map) obj;
}
private void checkIndex(int idx, String want) {
if(idx < 0 || idx >= args.length)
typeError(idx, want, null);
}
private static IllegalArgumentException typeError(int idx, String want, Object got) {
return new IllegalArgumentException("bad argument #" + (idx + 1) + " (" + want + " expected, got " + luaTypeName(got) + ")");
}
private static String luaTypeName(Object obj) {
if(obj == null)
return "nil";
Class<?> cls = obj.getClass();
if(cls == Boolean.class || cls == Boolean.TYPE)
return "boolean";
else if(cls == Integer.class || cls == Integer.TYPE || cls == Double.class || cls == Double.TYPE || cls == Float.class || cls == Float.TYPE)
return "number";
else if(cls == String.class)
return "string";
else if(Map.class.isAssignableFrom(cls))
return "table";
else
return cls.getSimpleName();
}
@Override
public int count() {
return args.length;
}
}

View File

@ -0,0 +1,39 @@
/*
* Copyright (C) 2019 BARBOTIN Nicolas
*/
package net.montoyo.wd.core;
import dan200.computercraft.api.ComputerCraftAPI;
import dan200.computercraft.api.peripheral.IPeripheral;
import dan200.computercraft.api.peripheral.IPeripheralProvider;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.fml.common.Optional;
import net.montoyo.wd.entity.TileEntityCCInterface;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
@Optional.Interface(iface = "dan200.computercraft.api.peripheral.IPeripheralProvider", modid = "computercraft")
public class CCPeripheralProvider implements IPeripheralProvider {
private CCPeripheralProvider() {
}
@Optional.Method(modid = "computercraft")
@Nullable
@Override
public IPeripheral getPeripheral(@Nonnull World world, @Nonnull BlockPos pos, @Nonnull EnumFacing f) {
TileEntity te = world.getTileEntity(pos);
return (te instanceof TileEntityCCInterface) ? ((TileEntityCCInterface) te) : null;
}
@Optional.Method(modid = "computercraft")
public static void register() {
ComputerCraftAPI.registerPeripheralProvider(new CCPeripheralProvider());
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2018 BARBOTIN Nicolas
* Copyright (C) 2019 BARBOTIN Nicolas
*/
package net.montoyo.wd.core;
@ -13,7 +13,7 @@ import javax.annotation.Nonnull;
public enum DefaultPeripheral implements IStringSerializable {
KEYBOARD("keyboard", "Keyboard", TileEntityKeyboard.class), //WITH FACING (< 3)
CC_INTERFACE("ccinterface", "ComputerCraft_Interface", null),
CC_INTERFACE("ccinterface", "ComputerCraft_Interface", TileEntityCCInterface.class),
OC_INTERFACE("cointerface", "OpenComputers_Interface", TileEntityOCInterface.class),
REMOTE_CONTROLLER("remotectrl", "Remote_Controller", TileEntityRCtrl.class), //WITHOUT FACING (>= 3)
REDSTONE_CONTROLLER("redstonectrl", "Redstone_Controller", TileEntityRedCtrl.class),

View File

@ -0,0 +1,16 @@
/*
* Copyright (C) 2019 BARBOTIN Nicolas
*/
package net.montoyo.wd.core;
import java.util.Map;
public interface IComputerArgs {
String checkString(int i);
int checkInteger(int i);
Map checkTable(int i);
int count();
}

View File

@ -0,0 +1,13 @@
/*
* Copyright (C) 2019 BARBOTIN Nicolas
*/
package net.montoyo.wd.core;
public interface IWDDCapability {
boolean isFirstRun();
void clearFirstRun();
void cloneTo(IWDDCapability dst);
}

View File

@ -0,0 +1,46 @@
/*
* Copyright (C) 2019 BARBOTIN Nicolas
*/
package net.montoyo.wd.core;
import li.cil.oc.api.machine.Arguments;
import net.minecraftforge.fml.common.Optional;
import java.util.Map;
@Optional.Interface(iface = "net.montoyo.wd.core.IComputerArgs", modid = "opencomputers")
public class OCArguments implements IComputerArgs {
//Keep this as an "Object" so that it doesn't crash if OC is absent
private final Object args;
public OCArguments(Object a) {
args = a;
}
@Optional.Method(modid = "opencomputers")
@Override
public String checkString(int i) {
return ((Arguments) args).checkString(i);
}
@Optional.Method(modid = "opencomputers")
@Override
public int checkInteger(int i) {
return ((Arguments) args).checkInteger(i);
}
@Optional.Method(modid = "opencomputers")
@Override
public Map checkTable(int i) {
return ((Arguments) args).checkTable(i);
}
@Optional.Method(modid = "opencomputers")
@Override
public int count() {
return ((Arguments) args).count();
}
}

View File

@ -0,0 +1,104 @@
/*
* Copyright (C) 2019 BARBOTIN Nicolas
*/
package net.montoyo.wd.core;
import net.minecraft.nbt.NBTBase;
import net.minecraft.nbt.NBTTagByte;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.EnumFacing;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.capabilities.CapabilityInject;
import net.minecraftforge.common.capabilities.ICapabilitySerializable;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.concurrent.Callable;
public class WDDCapability implements IWDDCapability {
@CapabilityInject(IWDDCapability.class)
public static final Capability<IWDDCapability> INSTANCE = null;
public static class Storage implements Capability.IStorage<IWDDCapability> {
@Nullable
@Override
public NBTBase writeNBT(Capability<IWDDCapability> cap, IWDDCapability inst, EnumFacing side) {
NBTTagCompound tag = new NBTTagCompound();
tag.setBoolean("FirstRun", inst.isFirstRun());
return tag;
}
@Override
public void readNBT(Capability<IWDDCapability> cap, IWDDCapability inst, EnumFacing side, NBTBase nbt) {
if(nbt instanceof NBTTagCompound) {
NBTTagCompound tag = (NBTTagCompound) nbt;
if(tag.hasKey("FirstRun") && tag.getTag("FirstRun") instanceof NBTTagByte && !tag.getBoolean("FirstRun"))
inst.clearFirstRun();
}
}
}
public static class Factory implements Callable<IWDDCapability> {
@Override
public IWDDCapability call() throws Exception {
return new WDDCapability();
}
}
public static class Provider implements ICapabilitySerializable<NBTBase> {
private IWDDCapability cap = INSTANCE.getDefaultInstance();
@Override
public boolean hasCapability(@Nonnull Capability<?> cap, @Nullable EnumFacing f) {
return cap == INSTANCE;
}
@Nullable
@Override
public <T> T getCapability(@Nonnull Capability<T> cap, @Nullable EnumFacing f) {
return cap == INSTANCE ? INSTANCE.cast(this.cap) : null;
}
@Override
public NBTBase serializeNBT() {
return INSTANCE.getStorage().writeNBT(INSTANCE, cap, null);
}
@Override
public void deserializeNBT(NBTBase nbt) {
INSTANCE.getStorage().readNBT(INSTANCE, cap, null, nbt);
}
}
private boolean firstRun = true;
private WDDCapability() {
}
@Override
public boolean isFirstRun() {
return firstRun;
}
@Override
public void clearFirstRun() {
firstRun = false;
}
@Override
public void cloneTo(IWDDCapability dst) {
if(!isFirstRun())
dst.clearFirstRun();
}
}

View File

@ -0,0 +1,83 @@
/*
* Copyright (C) 2019 BARBOTIN Nicolas
*/
package net.montoyo.wd.entity;
import dan200.computercraft.api.lua.ILuaContext;
import dan200.computercraft.api.lua.LuaException;
import dan200.computercraft.api.peripheral.IComputerAccess;
import dan200.computercraft.api.peripheral.IPeripheral;
import net.minecraftforge.fml.common.Optional;
import net.montoyo.wd.core.CCArguments;
import net.montoyo.wd.core.IComputerArgs;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
@Optional.Interface(iface = "dan200.computercraft.api.peripheral.IPeripheral", modid = "computercraft")
public class TileEntityCCInterface extends TileEntityInterfaceBase implements IPeripheral {
private static final String[] METHOD_NAMES;
private static final Method[] METHODS;
static {
ArrayList<String> names = new ArrayList<>();
ArrayList<Method> methods = new ArrayList<>();
Method[] src = TileEntityInterfaceBase.class.getMethods();
for(Method m: src) {
if(m.getAnnotation(TileEntityInterfaceBase.ComputerFunc.class) != null) {
if(m.getParameterCount() != 1 || m.getParameterTypes()[0] != IComputerArgs.class)
throw new RuntimeException("Found @ComputerFunc method with invalid arguments");
if(m.getReturnType() != Object[].class)
throw new RuntimeException("Found @ComputerFunc method with invalid return type");
names.add(m.getName());
methods.add(m);
}
}
METHOD_NAMES = names.toArray(new String[0]);
METHODS = methods.toArray(new Method[0]);
}
@Nonnull
@Override
public String getType() {
return "webdisplays";
}
@Nonnull
@Override
public String[] getMethodNames() {
return METHOD_NAMES;
}
@Optional.Method(modid = "computercraft")
@Nullable
@Override
public Object[] callMethod(@Nonnull IComputerAccess ca, @Nonnull ILuaContext ctx, int mid, @Nonnull Object[] args) throws LuaException, InterruptedException {
try {
return (Object[]) METHODS[mid].invoke(this, new CCArguments(args));
} catch(IllegalAccessException e) {
throw new RuntimeException(e);
} catch(InvocationTargetException e) {
if(e.getCause() instanceof IllegalArgumentException)
throw new LuaException(e.getCause().getMessage());
else
throw new RuntimeException(e.getCause());
}
}
@Optional.Method(modid = "computercraft")
@Override
public boolean equals(@Nullable IPeripheral periph) {
return periph == this;
}
}

View File

@ -0,0 +1,401 @@
/*
* Copyright (C) 2019 BARBOTIN Nicolas
*/
package net.montoyo.wd.entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.nbt.NBTTagCompound;
import net.montoyo.wd.WebDisplays;
import net.montoyo.wd.core.IComputerArgs;
import net.montoyo.wd.core.IUpgrade;
import net.montoyo.wd.core.ScreenRights;
import net.montoyo.wd.net.client.CMessageScreenUpdate;
import net.montoyo.wd.utilities.*;
import javax.annotation.Nonnull;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.ArrayList;
import java.util.Map;
public abstract class TileEntityInterfaceBase extends TileEntityPeripheralBase {
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ComputerFunc {}
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();
}
@ComputerFunc
public Object[] isLinked(IComputerArgs args) {
return new Object[] { isLinked() };
}
@ComputerFunc
public Object[] isScreenChunkLoaded(IComputerArgs args) {
return new Object[] { isScreenChunkLoaded() };
}
@ComputerFunc
public Object[] getScreenPos(IComputerArgs args) {
return isLinked() ? new Object[] { screenPos.x, screenPos.y, screenPos.z } : null;
}
@ComputerFunc
public Object[] getScreenSide(IComputerArgs args) {
return isLinked() ? new Object[] { screenSide.toString().toLowerCase() } : null;
}
@ComputerFunc
public Object[] getOwner(IComputerArgs args) {
if(owner == null)
return null;
else
return new Object[] { owner.name, owner.uuid.toString() };
}
@ComputerFunc
public Object[] can(IComputerArgs args) {
String what = args.checkString(0).toLowerCase();
int right;
switch(what) {
case "click":
case "type":
right = ScreenRights.CLICK;
break;
case "seturl":
case "js":
case "javascript":
case "runjs":
right = ScreenRights.CHANGE_URL;
break;
case "setresolution":
case "setrotation":
right = ScreenRights.CHANGE_RESOLUTION;
break;
default:
throw new IllegalArgumentException("invalid right name");
}
TileEntityScreen tes = getConnectedScreenEx();
if(owner == null || tes == null)
return null;
else
return ((tes.getScreen(screenSide).rightsFor(owner.uuid) & right) == 0) ? FALSE : TRUE;
}
@ComputerFunc
public Object[] hasUpgrade(IComputerArgs args) {
String name = args.checkString(0);
TileEntityScreen tes = getConnectedScreenEx();
if(owner == null || tes == null)
return null;
else
return tes.getScreen(screenSide).upgrades.stream().anyMatch(is -> ((IUpgrade) is.getItem()).getJSName(is).equalsIgnoreCase(name)) ? TRUE : FALSE;
}
@ComputerFunc
public Object[] getSize(IComputerArgs args) {
TileEntityScreen tes = getConnectedScreenEx();
if(owner == null || tes == null)
return null;
else {
Vector2i sz = tes.getScreen(screenSide).size;
return new Object[] { sz.x, sz.y };
}
}
@ComputerFunc
public Object[] getResolution(IComputerArgs args) {
TileEntityScreen tes = getConnectedScreenEx();
if(owner == null || tes == null)
return null;
else {
Vector2i res = tes.getScreen(screenSide).resolution;
return new Object[] { res.x, res.y };
}
}
@ComputerFunc
public Object[] getRotation(IComputerArgs args) {
TileEntityScreen tes = getConnectedScreenEx();
if(owner == null || tes == null)
return null;
else
return new Object[] { tes.getScreen(screenSide).rotation.getAngleAsInt() };
}
@ComputerFunc
public Object[] getURL(IComputerArgs args) {
TileEntityScreen tes = getConnectedScreenEx();
if(owner == null || tes == null)
return null;
else
return new Object[] { tes.getScreen(screenSide).url };
}
private static Object[] err(String str) {
return new Object[] { false, str };
}
@ComputerFunc
public Object[] click(IComputerArgs 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");
}
TileEntityScreen scr = getConnectedScreenEx();
if(owner == null || scr == null)
return err("notlinked");
else {
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) {
TileEntityScreen scr = getConnectedScreenEx();
if(owner == null || scr == null)
return err("notlinked");
else if((scr.getScreen(screenSide).rightsFor(owner.uuid) & ScreenRights.CLICK) == 0)
return err("restrictions");
else {
scr.type(screenSide, what, null);
return TRUE;
}
}
@ComputerFunc
public Object[] type(IComputerArgs 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);
}
@ComputerFunc
public Object[] typeAdvanced(IComputerArgs args) {
ArrayList<TypeData> data = new ArrayList<>();
Map map = args.checkTable(0);
int maxEvents = 0;
for(Object o: map.values()) {
if(!(o instanceof Map))
return err("badinput");
if(++maxEvents >= 16)
return err("toomany");
Map event = (Map) o;
Object action = event.get("action");
Object chr = event.get("char");
int code = 0;
if(!(action instanceof String))
return err("badaction");
if(!(chr instanceof String))
return err("badchar");
String strAction = (String) action;
String strChr = (String) chr;
TypeData.Action dataAction;
if(strAction.equalsIgnoreCase("press"))
dataAction = TypeData.Action.PRESS;
else if(strAction.equalsIgnoreCase("release"))
dataAction = TypeData.Action.RELEASE;
else if(strAction.equalsIgnoreCase("type"))
dataAction = TypeData.Action.TYPE;
else
return err("unknownaction");
if(strChr.isEmpty())
return err("emptychar");
if(dataAction != TypeData.Action.TYPE) {
Object oCode = event.get("code");
if(!(oCode instanceof Double))
return err("badcode");
code = ((Double) oCode).intValue();
}
data.add(new TypeData(dataAction, code, strChr.charAt(0)));
}
return realType(WebDisplays.GSON.toJson(data));
}
@ComputerFunc
public Object[] setURL(IComputerArgs args) {
String url = args.checkString(0);
TileEntityScreen scr = getConnectedScreenEx();
if(owner == null || scr == null)
return err("notlinked");
else if((scr.getScreen(screenSide).rightsFor(owner.uuid) & ScreenRights.CHANGE_URL) == 0)
return err("restrictions");
else {
scr.setScreenURL(screenSide, url);
return TRUE;
}
}
@ComputerFunc
public Object[] setResolution(IComputerArgs args) {
int rx = args.checkInteger(0);
int ry = args.checkInteger(1);
TileEntityScreen scr = getConnectedScreenEx();
if(owner == null || scr == null)
return err("notlinked");
else if((scr.getScreen(screenSide).rightsFor(owner.uuid) & ScreenRights.CHANGE_RESOLUTION) == 0)
return err("restrictions");
else {
scr.setResolution(screenSide, new Vector2i(rx, ry));
return TRUE;
}
}
@ComputerFunc
public Object[] setRotation(IComputerArgs args) {
int rot = args.checkInteger(0);
if(rot < 0) {
int toAdd = (rot / -360) + 1;
rot += toAdd * 360;
}
rot /= 90;
rot &= 3;
TileEntityScreen scr = getConnectedScreenEx();
if(owner == null || scr == null)
return err("notlinked");
else if((scr.getScreen(screenSide).rightsFor(owner.uuid) & ScreenRights.CHANGE_RESOLUTION) == 0)
return err("restrictions");
else {
scr.setRotation(screenSide, Rotation.values()[rot]);
return TRUE;
}
}
@ComputerFunc
public Object[] runJS(IComputerArgs args) {
String code = args.checkString(0);
TileEntityScreen scr = getConnectedScreenEx();
if(owner == null || scr == null)
return err("notlinked");
else if((scr.getScreen(screenSide).rightsFor(owner.uuid) & ScreenRights.CHANGE_URL) == 0)
return err("restrictions");
else {
scr.evalJS(screenSide, code);
return TRUE;
}
}
@ComputerFunc
public Object[] unlink(IComputerArgs args) {
if(isLinked()) {
screenPos = null;
screenSide = null;
markDirty();
}
return null;
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2018 BARBOTIN Nicolas
* Copyright (C) 2019 BARBOTIN Nicolas
*/
package net.montoyo.wd.entity;
@ -8,43 +8,11 @@ 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;
import net.montoyo.wd.core.OCArguments;
@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();
}
public class TileEntityOCInterface extends TileEntityInterfaceBase implements SimpleComponent {
@Override
public String getComponentName() {
@ -54,335 +22,115 @@ public class TileEntityOCInterface extends TileEntityPeripheralBase implements S
@Callback
@Optional.Method(modid = "opencomputers")
public Object[] isLinked(Context ctx, Arguments args) {
return new Object[] { isLinked() };
return isLinked(new OCArguments(args));
}
@Callback
@Optional.Method(modid = "opencomputers")
public Object[] isScreenChunkLoaded(Context ctx, Arguments args) {
return new Object[] { isScreenChunkLoaded() };
return isScreenChunkLoaded(new OCArguments(args));
}
@Callback
@Optional.Method(modid = "opencomputers")
public Object[] getScreenPos(Context ctx, Arguments args) {
return isLinked() ? new Object[] { screenPos.x, screenPos.y, screenPos.z } : null;
return getScreenPos(new OCArguments(args));
}
@Callback
@Optional.Method(modid = "opencomputers")
public Object[] getScreenSide(Context ctx, Arguments args) {
return isLinked() ? new Object[] { screenSide.toString().toLowerCase() } : null;
return getScreenSide(new OCArguments(args));
}
@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() };
return getOwner(new OCArguments(args));
}
@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":
right = ScreenRights.CLICK;
break;
case "seturl":
case "js":
case "javascript":
case "runjs":
right = ScreenRights.CHANGE_URL;
break;
case "setresolution":
case "setrotation":
right = ScreenRights.CHANGE_RESOLUTION;
break;
default:
throw new IllegalArgumentException("invalid right name");
}
TileEntityScreen tes = getConnectedScreenEx();
if(owner == null || tes == null)
return null;
else
return ((tes.getScreen(screenSide).rightsFor(owner.uuid) & right) == 0) ? FALSE : TRUE;
return can(new OCArguments(args));
}
@Callback
@Optional.Method(modid = "opencomputers")
public Object[] hasUpgrade(Context ctx, Arguments args) {
String name = args.checkString(0);
TileEntityScreen tes = getConnectedScreenEx();
if(owner == null || tes == null)
return null;
else
return tes.getScreen(screenSide).upgrades.stream().anyMatch(is -> ((IUpgrade) is.getItem()).getJSName(is).equalsIgnoreCase(name)) ? TRUE : FALSE;
return hasUpgrade(new OCArguments(args));
}
@Callback
@Optional.Method(modid = "opencomputers")
public Object[] getSize(Context ctx, Arguments args) {
TileEntityScreen tes = getConnectedScreenEx();
if(owner == null || tes == null)
return null;
else {
Vector2i sz = tes.getScreen(screenSide).size;
return new Object[] { sz.x, sz.y };
}
return getSize(new OCArguments(args));
}
@Callback
@Optional.Method(modid = "opencomputers")
public Object[] getResolution(Context ctx, Arguments args) {
TileEntityScreen tes = getConnectedScreenEx();
if(owner == null || tes == null)
return null;
else {
Vector2i res = tes.getScreen(screenSide).resolution;
return new Object[] { res.x, res.y };
}
return getResolution(new OCArguments(args));
}
@Callback
@Optional.Method(modid = "opencomputers")
public Object[] getRotation(Context ctx, Arguments args) {
TileEntityScreen tes = getConnectedScreenEx();
if(owner == null || tes == null)
return null;
else
return new Object[] { tes.getScreen(screenSide).rotation.getAngleAsInt() };
return getRotation(new OCArguments(args));
}
@Callback
@Optional.Method(modid = "opencomputers")
public Object[] getURL(Context ctx, Arguments args) {
TileEntityScreen tes = getConnectedScreenEx();
if(owner == null || tes == null)
return null;
else
return new Object[] { tes.getScreen(screenSide).url };
}
private static Object[] err(String str) {
return new Object[] { false, str };
return getURL(new OCArguments(args));
}
@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");
}
TileEntityScreen scr = getConnectedScreenEx();
if(owner == null || scr == null)
return err("notlinked");
else {
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) {
TileEntityScreen scr = getConnectedScreenEx();
if(owner == null || scr == null)
return err("notlinked");
else if((scr.getScreen(screenSide).rightsFor(owner.uuid) & ScreenRights.CLICK) == 0)
return err("restrictions");
else {
scr.type(screenSide, what, null);
return TRUE;
}
return click(new OCArguments(args));
}
@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);
return type(new OCArguments(args));
}
@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);
return typeAdvanced(new OCArguments(args));
}
@Callback(limit = 1)
@Optional.Method(modid = "opencomputers")
public Object[] setURL(Context ctx, Arguments args) {
String url = args.checkString(0);
TileEntityScreen scr = getConnectedScreenEx();
if(owner == null || scr == null)
return err("notlinked");
else if((scr.getScreen(screenSide).rightsFor(owner.uuid) & ScreenRights.CHANGE_URL) == 0)
return err("restrictions");
else {
scr.setScreenURL(screenSide, url);
return TRUE;
}
return setURL(new OCArguments(args));
}
@Callback(limit = 1)
@Optional.Method(modid = "opencomputers")
public Object[] setResolution(Context ctx, Arguments args) {
int rx = args.checkInteger(0);
int ry = args.checkInteger(1);
TileEntityScreen scr = getConnectedScreenEx();
if(owner == null || scr == null)
return err("notlinked");
else if((scr.getScreen(screenSide).rightsFor(owner.uuid) & ScreenRights.CHANGE_RESOLUTION) == 0)
return err("restrictions");
else {
scr.setResolution(screenSide, new Vector2i(rx, ry));
return TRUE;
}
return setResolution(new OCArguments(args));
}
@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;
TileEntityScreen scr = getConnectedScreenEx();
if(owner == null || scr == null)
return err("notlinked");
else if((scr.getScreen(screenSide).rightsFor(owner.uuid) & ScreenRights.CHANGE_RESOLUTION) == 0)
return err("restrictions");
else {
scr.setRotation(screenSide, Rotation.values()[rot]);
return TRUE;
}
return setRotation(new OCArguments(args));
}
@Callback(limit = 4)
@Optional.Method(modid = "opencomputers")
public Object[] runJS(Context ctx, Arguments args) {
String code = args.checkString(0);
TileEntityScreen scr = getConnectedScreenEx();
if(owner == null || scr == null)
return err("notlinked");
else if((scr.getScreen(screenSide).rightsFor(owner.uuid) & ScreenRights.CHANGE_URL) == 0)
return err("restrictions");
else {
scr.evalJS(screenSide, code);
return TRUE;
}
return runJS(new OCArguments(args));
}
@Callback
@Optional.Method(modid = "opencomputers")
public Object[] unlink(Context ctx, Arguments args) {
if(isLinked()) {
screenPos = null;
screenSide = null;
markDirty();
}
return null;
return unlink(new OCArguments(args));
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2018 BARBOTIN Nicolas
* Copyright (C) 2019 BARBOTIN Nicolas
*/
package net.montoyo.wd.entity;
@ -759,20 +759,35 @@ public class TileEntityScreen extends TileEntity {
if(world.isRemote) {
if(scr.browser != null) {
try {
String[] events = text.split("" + ((char) 1));
if(text.startsWith("t")) {
for(int i = 1; i < text.length(); i++) {
char chr = text.charAt(i);
if(chr == 1)
break;
for(String ev: events) {
char action = ev.charAt(0);
scr.browser.injectKeyTyped(chr, 0);
}
} else {
TypeData[] data = WebDisplays.GSON.fromJson(text, TypeData[].class);
if(action == 'p')
scr.browser.injectKeyPressed(ev.charAt(1), 0);
else if(action == 'r')
scr.browser.injectKeyReleased(ev.charAt(1), 0);
else if(action == 't') {
for(int i = 1; i < ev.length(); i++)
scr.browser.injectKeyTyped(ev.charAt(i), 0);
} else
throw new RuntimeException("Invalid control key '" + action + '\'');
for(TypeData ev : data) {
switch(ev.getAction()) {
case PRESS:
scr.browser.injectKeyPressedByKeyCode(ev.getKeyCode(), ev.getKeyChar(), 0);
break;
case RELEASE:
scr.browser.injectKeyReleasedByKeyCode(ev.getKeyCode(), ev.getKeyChar(), 0);
break;
case TYPE:
scr.browser.injectKeyTyped(ev.getKeyChar(), 0);
break;
default:
throw new RuntimeException("Invalid type action '" + ev.getAction() + '\'');
}
}
}
} catch(Throwable t) {
Log.warningEx("Suspicious keyboard type packet received...", t);

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2018 BARBOTIN Nicolas
* Copyright (C) 2019 BARBOTIN Nicolas
*/
package net.montoyo.wd.item;
@ -56,8 +56,8 @@ public class ItemPeripheral extends ItemMultiTexture implements WDItem {
super.addInformation(is, world, tt, ttFlags);
if(is != null && tt != null) {
if(is.getMetadata() == 1) //CC Interface
tt.add("" + ChatFormatting.RED + I18n.format("webdisplays.message.missingCC")); //CC is not available for 1.12.2
if(is.getMetadata() == 1 && !WebDisplays.isComputerCraftAvailable()) //CC Interface
tt.add("" + ChatFormatting.RED + I18n.format("webdisplays.message.missingCC"));
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

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2018 BARBOTIN Nicolas
* Copyright (C) 2019 BARBOTIN Nicolas
*/
package net.montoyo.wd.net.client;
@ -8,7 +8,7 @@ import io.netty.buffer.ByteBuf;
import net.minecraftforge.fml.common.network.ByteBufUtils;
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
import net.minecraftforge.fml.relauncher.Side;
import net.montoyo.mcef.utilities.Log;
import net.montoyo.wd.utilities.Log;
import net.montoyo.wd.WebDisplays;
import net.montoyo.wd.data.GuiData;
import net.montoyo.wd.net.Message;

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2018 BARBOTIN Nicolas
* Copyright (C) 2019 BARBOTIN Nicolas
*/
package net.montoyo.wd.net.server;
@ -13,7 +13,7 @@ import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler;
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
import net.minecraftforge.fml.relauncher.Side;
import net.montoyo.mcef.utilities.Log;
import net.montoyo.wd.utilities.Log;
import net.montoyo.wd.entity.TileEntityScreen;
import net.montoyo.wd.net.Message;
import net.montoyo.wd.utilities.Vector3i;

View File

@ -0,0 +1,53 @@
/*
* Copyright (C) 2019 BARBOTIN Nicolas
*/
package net.montoyo.wd.utilities;
import com.google.gson.annotations.SerializedName;
public class TypeData {
public enum Action {
@SerializedName("i")
INVALID,
@SerializedName("p")
PRESS,
@SerializedName("r")
RELEASE,
@SerializedName("t")
TYPE
}
private Action a;
private int k;
private int c;
public TypeData() {
a = Action.INVALID;
k = 0;
c = 0;
}
public TypeData(Action action, int code, char chr) {
a = action;
k = code;
c = (int) chr;
}
public Action getAction() {
return a;
}
public char getKeyChar() {
return (char) c;
}
public int getKeyCode() {
return k;
}
}

View File

@ -54,6 +54,9 @@ webdisplays.message.upgradeOk=Upgrade installed!
webdisplays.message.linkAbort=Linker reset
webdisplays.message.noMiniserv=Server block is disabled on this server
webdisplays.message.otDisabled=Ownership thief is disabled on this server
webdisplays.message.welcome1=Thank you for installing WebDisplays! If you
webdisplays.message.welcome2=need help, hover any WD item with your mouse
webdisplays.message.welcome3=and hit F1. Have fun with the mod, - montoyo
webdisplays.gui.screencfg.owner=Screen owner:
webdisplays.gui.screencfg.friends=Friends:
webdisplays.gui.screencfg.permissions=Permissions:

View File

@ -10,7 +10,7 @@ tile.webdisplays.peripheral.server.name=Serveur
item.webdisplays.screencfg.name=Gestionnaire d'écran
item.webdisplays.ownerthief.name=Voleur d'écran [ADMIN]
item.webdisplays.linker.name=Outil d'appairage
item.webdisplays.craftcomp.name=Composant de recette
item.webdisplays.craftcomp.name=Ingrédient de recette
item.webdisplays.craftcomp.stonekey.name=Touche en pierre
item.webdisplays.craftcomp.upgrade.name=Amélioration vide
item.webdisplays.craftcomp.peripheral.name=Base de périphérique
@ -54,6 +54,9 @@ webdisplays.message.upgradeOk=Amélioration installée !
webdisplays.message.linkAbort=Outil d'appairage remis à zéro.
webdisplays.message.noMiniserv=Le bloc serveur est désactivé
webdisplays.message.otDisabled=Le voleur d'écran est désactivé sur ce serveur
webdisplays.message.welcome1=Merci d'avoir installé WebDisplays ! Pour obtenir
webdisplays.message.welcome2=de l'aide sur un item, passez la souris dessus
webdisplays.message.welcome3=et appuyez sur F1. Amusez-vous bien, - montoyo
webdisplays.gui.screencfg.owner=Propriétaire :
webdisplays.gui.screencfg.friends=Amis :
webdisplays.gui.screencfg.permissions=Permissions :

View File

@ -8,7 +8,7 @@
"url": "https://montoyo.net/wd2.php",
"updateUrl": "",
"authorList": [ "montoyo" ],
"credits": "Thanks to sadreminderwindows for the Chinese translation",
"credits": "Thanks to sadreminderwindows for the Chinese translation. Thanks to binary1230 for the ComputerCraft support.",
"logoFile": "",
"screenshots": [],
"dependencies": []