package me.exz.omniocular.handler;
import me.exz.omniocular.util.NBTHelper;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.StatCollector;
import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.fluids.FluidRegistry;
import net.minecraftforge.fluids.FluidStack;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static me.exz.omniocular.util.NBTHelper.NBTCache;
@SuppressWarnings({"CanBeFinal", "UnusedDeclaration"})
public class JSHandler {
static ScriptEngine engine;
static HashSet<String> scriptSet = new HashSet<>();
private static List<String> lastTips = new ArrayList<>();
private static int lastHash;
private static Map<String, String> fluidList = new HashMap<>();
private static Map<String, String> displayNameList = new HashMap<>();
private static EntityPlayer entityPlayer;
static List<String> getBody(Map<Pattern, Node> patternMap, NBTTagCompound n, String id, EntityPlayer player) {
entityPlayer = player;
if (n.hashCode() != lastHash || player.worldObj.getTotalWorldTime() % 10 == 0) {
lastHash = n.hashCode();
lastTips.clear();
//LogHelper.info(NBTHelper.NBT2json(n));
try {
String bareJson = NBTHelper.NBT2json(n);
String json = "var nbt=" + bareJson + ";";
JSHandler.engine.eval(json);
WebSocketHandler.broadcast(bareJson);
} catch (ScriptException e) {
e.printStackTrace();
}
for (Map.Entry<Pattern, Node> entry : patternMap.entrySet()) {
Matcher matcher = entry.getKey().matcher(id);
if (matcher.matches()) {
Element item = (Element) entry.getValue();
// if (item.getElementsByTagName("head").getLength() > 0) {
// Node head = item.getElementsByTagName("head").item(0);
// }
if (item.getElementsByTagName("line").getLength() > 0) {
String tip;
NodeList lines = item.getElementsByTagName("line");
for (int i = 0; i < lines.getLength(); i++) {
Node line = lines.item(i);
String displayname = "";
if (line.getAttributes().getNamedItem("displayname") != null && !line.getAttributes().getNamedItem("displayname").getTextContent().trim().isEmpty()) {
displayname = StatCollector.translateToLocal(line.getAttributes().getNamedItem("displayname").getTextContent());
}
String functionContent = line.getTextContent();
String hash = "S" + NBTHelper.MD5(functionContent);
if (!JSHandler.scriptSet.contains(hash)) {
JSHandler.scriptSet.add(hash);
if (!functionContent.contains("return")) {
functionContent = "return " + functionContent.trim();
}
String script = "function " + hash + "()" + "{" + functionContent + "}";
try {
JSHandler.engine.eval(script);
} catch (Exception e) {
e.printStackTrace();
}
}
Invocable invoke = (Invocable) JSHandler.engine;
try {
String result = String.valueOf(invoke.invokeFunction(hash, ""));
if (result.equals("__ERROR__") || result.equals("null") || result.equals("undefined")
|| result.equals("NaN")) {
continue;
}
if (patternMap == ConfigHandler.tooltipPattern) {
tip = "\u00A77" + displayname + ": \u00A7f";
} else {
tip = ConfigHandler.settingList.get("displaynameTileentity")
.replace("DISPLAYNAME", displayname)
.replace("RETURN", result);
}
} catch (Exception e) {
continue;
//e.printStackTrace();
}
if (tip.equals("__ERROR__")) {
continue;
}
lastTips.addAll(Arrays.asList(tip.split("\n")));
}
}
}
}
}
return lastTips;
}
//todo provide an function to detect player keyboard action. (hold shift, etc.)
static void initEngine() {
ScriptEngineManager manager = new ScriptEngineManager(null);
engine = manager.getEngineByName("javascript");
setSpecialChar();
/* java 8 work around */
try {
engine.eval("load(\"nashorn:mozilla_compat.js\");");
} catch (ScriptException e) {
//e.printStackTrace();
}
try {
engine.eval("importClass(Packages.me.exz.omniocular.handler.JSHandler);");
engine.eval("function translate(t){return Packages.me.exz.omniocular.handler.JSHandler.translate(t)}");
engine.eval("function translateFormatted(t,obj){return Packages.me.exz.omniocular.handler.JSHanlder.translateFormatted(t,obj)}");
engine.eval("function name(n){return Packages.me.exz.omniocular.handler.JSHandler.getDisplayName(n.hashCode)}");
engine.eval("function fluidName(n){return Packages.me.exz.omniocular.handler.JSHandler.getFluidName(n)}");
engine.eval("function holding(){return Packages.me.exz.omniocular.handler.JSHandler.playerHolding()}");
engine.eval("function armor(i){return Packages.me.exz.omniocular.handler.JSHandler.playerArmor(i)}");
engine.eval("function isInHotbar(n){return Packages.me.exz.omniocular.handler.JSHandler.haveItemInHotbar(n)}");
engine.eval("function isInInv(n){return Packages.me.exz.omniocular.handler.JSHandler.haveItemInInventory(n)}");
} catch (ScriptException e) {
e.printStackTrace();
}
}
private static void setSpecialChar() {
String MCStyle = "\u00A7";
engine.put("BLACK", MCStyle + "0");
engine.put("DBLUE", MCStyle + "1");
engine.put("DGREEN", MCStyle + "2");
engine.put("DAQUA", MCStyle + "3");
engine.put("DRED", MCStyle + "4");
engine.put("DPURPLE", MCStyle + "5");
engine.put("GOLD", MCStyle + "6");
engine.put("GRAY", MCStyle + "7");
engine.put("DGRAY", MCStyle + "8");
engine.put("BLUE", MCStyle + "9");
engine.put("GREEN", MCStyle + "a");
engine.put("AQUA", MCStyle + "b");
engine.put("RED", MCStyle + "c");
engine.put("LPURPLE", MCStyle + "d");
engine.put("YELLOW", MCStyle + "e");
engine.put("WHITE", MCStyle + "f");
engine.put("OBF", MCStyle + "k");
engine.put("BOLD", MCStyle + "l");
engine.put("STRIKE", MCStyle + "m");
engine.put("UNDER", MCStyle + "n");
engine.put("ITALIC", MCStyle + "o");
engine.put("RESET", MCStyle + "r");
String WailaStyle = "\u00A4";
String WailaIcon = "\u00A5";
engine.put("TAB", WailaStyle + WailaStyle + "a");
engine.put("ALIGNRIGHT", WailaStyle + WailaStyle + "b");
engine.put("ALIGNCENTER", WailaStyle + WailaStyle + "c");
engine.put("HEART", WailaStyle + WailaIcon + "a");
engine.put("HHEART", WailaStyle + WailaIcon + "b");
engine.put("EHEART", WailaStyle + WailaIcon + "c");
// LogHelper.info("Special Char loaded");
}
public static String translate(String t) {
return StatCollector.translateToLocal(t);
}
public static String translateFormatted(String t, Object[] format) {
return StatCollector.translateToLocalFormatted(t, format);
}
public static String playerHolding() {
ItemStack is = entityPlayer.getHeldItem();
if (is == null) {
return "";
}
return Item.itemRegistry.getNameForObject(is.getItem());
}
public static String playerArmor(int i) {
if (i < 0 || i > 3) {
return null;
}
ItemStack is = entityPlayer.inventory.armorInventory[i];
if (is == null) {
return "";
}
return Item.itemRegistry.getNameForObject(is.getItem());
}
public static Boolean haveItemInHotbar(String n) {
int s = entityPlayer.inventory.func_146029_c((Item) Item.itemRegistry.getObject(n));
return s > -1 && s < 9;
}
public static Boolean haveItemInInventory(String n) {
return entityPlayer.inventory.func_146029_c((Item) Item.itemRegistry.getObject(n)) != -1;
}
public static String getDisplayName(String hashCode) {
try {
NBTTagCompound nc = NBTCache.get(Integer.valueOf(hashCode));
ItemStack is = ItemStack.loadItemStackFromNBT(nc);
return is.getDisplayName();
} catch (Exception e) {
return "__ERROR__";
}
}
public static String getFluidName(String uName) {
if (fluidList.containsKey(uName)) {
return fluidList.get(uName);
} else {
try {
Fluid f = FluidRegistry.getFluid(uName.toLowerCase());
FluidStack fs = new FluidStack(f, 1);
String lName = fs.getLocalizedName();
fluidList.put(uName, lName);
return lName;
} catch (Exception e) {
return "__ERROR__";
}
}
}
}