webdisplays/src/main/java/net/montoyo/wd/entity/TileEntityInterfaceBase.java
GiantLuigi4 a9d9dcfecf format.
2023-11-10 23:50:06 -05:00

409 lines
12 KiB
Java

/*
* Copyright (C) 2019 BARBOTIN Nicolas
*/
package net.montoyo.wd.entity;
import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
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.utilities.*;
import java.io.IOException;
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 {
public TileEntityInterfaceBase(BlockEntityType<?> arg, BlockPos arg2, BlockState arg3) {
super(arg, arg2, arg3);
}
@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 load(CompoundTag tag) {
super.load(tag);
owner = Util.readOwnerFromNBT(tag);
}
@Override
protected void saveAdditional(CompoundTag tag) {
super.saveAdditional(tag);
Util.writeOwnerToNBT(tag, owner);
}
public void setOwner(Player ep) {
owner = new NameUUIDPair(ep.getGameProfile());
setChanged();
}
@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.INTERACT;
break;
case "seturl":
case "js":
case "javascript":
case "runjs":
right = ScreenRights.CHANGE_URL;
break;
case "setresolution":
case "setrotation":
right = ScreenRights.MODIFY_SCREEN;
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.INTERACT) == 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.INTERACT) == 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, 0, 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 {
try {
scr.setScreenURL(screenSide, url);
} catch (IOException e) {
throw new RuntimeException(e);
}
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.MODIFY_SCREEN) == 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.MODIFY_SCREEN) == 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;
setChanged();
}
return null;
}
}