///* // * Copyright (C) 2018 BARBOTIN Nicolas // */ // //package net.montoyo.wd.client; // //import net.minecraft.client.Minecraft; //import net.minecraft.core.BlockPos; //import net.minecraft.core.Direction; //import net.minecraft.world.item.ItemStack; //import net.minecraftforge.api.distmarker.Dist; //import net.minecraftforge.api.distmarker.OnlyIn; //import net.montoyo.wd.block.BlockScreen; //import net.montoyo.wd.core.DefaultUpgrade; //import net.montoyo.wd.core.IScreenQueryHandler; //import net.montoyo.wd.core.IUpgrade; //import net.montoyo.wd.core.JSServerRequest; //import net.montoyo.wd.entity.TileEntityScreen; //import net.montoyo.wd.net.WDNetworkRegistry; //import net.montoyo.wd.net.server_bound.C2SMessageScreenCtrl; //import net.montoyo.wd.utilities.*; // //import java.util.*; // //@OnlyIn(Dist.CLIENT) //public final class JSQueryDispatcher { // // private static final class QueryData { // // private final IBrowser browser; // private final String query; // private final String args; // private final IJSQueryCallback callback; // // private QueryData(IBrowser b, String q, String a, IJSQueryCallback cb) { // browser = b; // query = q; // args = a; // callback = cb; // } // // } // // public static final class ServerQuery { // // private static int lastId = 0; // // private final TileEntityScreen tes; // private final BlockSide side; // private final IJSQueryCallback callback; // private final int id; // // private ServerQuery(TileEntityScreen t, BlockSide s, IJSQueryCallback cb) { // tes = t; // side = s; // callback = cb; // id = lastId++; // } // // public TileEntityScreen getTileEntity() { // return tes; // } // // public BlockSide getSide() { // return side; // } // // public TileEntityScreen.Screen getScreen() { // return tes.getScreen(side); // } // // public void success(String resp) { // callback.success(resp); // } // // public void error(int errId, String errStr) { // callback.failure(errId, errStr); // } // // } // // private final ClientProxy proxy; // private final ArrayDeque queue = new ArrayDeque<>(); // private final ClientProxy.ScreenSidePair lookupResult = new ClientProxy.ScreenSidePair(); // private final HashMap handlers = new HashMap<>(); // private final ArrayList serverQueries = new ArrayList<>(); // private final Minecraft mc = Minecraft.getInstance(); // // public JSQueryDispatcher(ClientProxy proxy) { // this.proxy = proxy; // registerDefaults(); // } // // public void enqueueQuery(IBrowser b, String q, String a, IJSQueryCallback cb) { // synchronized(queue) { // queue.offer(new QueryData(b, q, a, cb)); // } // } // // public void handleQueries() { // while(true) { // QueryData next; // synchronized(queue) { // next = queue.poll(); // } // // if(next == null) // break; // // if(proxy.findScreenFromBrowser(next.browser, lookupResult)) { // Object[] args = (next.args == null) ? new Object[0] : parseArgs(next.args); // // if(args == null) // next.callback.failure(400, "Malformed request parameters"); // else { // try { // handlers.get(next.query).handleQuery(next.callback, lookupResult.tes, lookupResult.side, args); // } catch(Throwable t) { // Log.warningEx("Could not execute JS query %s(%s)", t, next.query, (next.args == null) ? "" : next.args); // next.callback.failure(500, "Internal error"); // } // } // } else // next.callback.failure(403, "A screen is required"); // } // } // // public boolean canHandleQuery(String q) { // return handlers.containsKey(q); // } // // private static Object[] parseArgs(String args) { // ArrayList array = new ArrayList<>(); // int lastIdx = 0; // boolean inString = false; // boolean escape = false; // boolean hadString = false; // // for(int i = 0; i < args.length(); i++) { // char chr = args.charAt(i); // // if(inString) { // if(escape) // escape = false; // else { // if(chr == '\"') // inString = false; // else if(chr == '\\') // escape = true; // } // } else if(chr == '\"') { // if(hadString) // return null; // // inString = true; // hadString = true; // } else if(chr == ',') { // array.add(args.substring(lastIdx, i).trim()); // lastIdx = i + 1; // hadString = false; // } // } // // if(inString) // return null; //Non terminated string // // array.add(args.substring(lastIdx).trim()); // Object[] ret = new Object[array.size()]; // // for(int i = 0; i < ret.length; i++) { // String str = array.get(i); // if(str.isEmpty()) // return null; //Nah... // // if(str.charAt(0) == '\"') //String // ret[i] = str.substring(1, str.length() - 1); // else { // try { // ret[i] = Double.parseDouble(str); // } catch(NumberFormatException ex) { // return null; // } // } // } // // return ret; // } // // public void register(String query, IScreenQueryHandler handler) { // handlers.put(query.toLowerCase(), handler); // } // // public ServerQuery fulfillQuery(int id) { // int toRemove = -1; // // for(int i = 0; i < serverQueries.size(); i++) { // ServerQuery sq = serverQueries.get(i); // // if(sq.id == id) { // toRemove = i; // break; // } // } // // if(toRemove < 0) // return null; // else // return serverQueries.remove(toRemove); // } // // private void makeServerQuery(TileEntityScreen tes, BlockSide side, IJSQueryCallback cb, JSServerRequest type, Object ... data) { // ServerQuery ret = new ServerQuery(tes, side, cb); // serverQueries.add(ret); // // WDNetworkRegistry.INSTANCE.sendToServer(C2SMessageScreenCtrl.jsRequest(tes, side, ret.id, type, data)); // } // // private void registerDefaults() { // VideoType.registerQueries(this); // // register("GetSize", (cb, tes, side, args) -> { // Vector2i size = tes.getScreen(side).size; // cb.success("{\"x\":" + size.x + ",\"y\":" + size.y + "}"); // }); // // register("GetRedstoneAt", (cb, tes, side, args) -> { // if(!tes.hasUpgrade(side, DefaultUpgrade.REDINPUT)) { // cb.failure(403, "Missing upgrade"); // return; // } // // if(args.length == 2 && args[0] instanceof Double && args[1] instanceof Double) { // TileEntityScreen.Screen scr = tes.getScreen(side); // int x = ((Double) args[0]).intValue(); // int y = ((Double) args[1]).intValue(); // // if(x < 0 || x >= scr.size.x || y < 0 || y >= scr.size.y) // cb.failure(403, "Out of range"); // else { // BlockPos bpos = (new Vector3i(tes.getBlockPos())).addMul(side.right, x).addMul(side.up, y).toBlock(); // int level = tes.getLevel().getBlockState(bpos).getValue(BlockScreen.emitting) ? 0 : tes.getLevel().getSignal(bpos, Direction.values()[side.reverse().ordinal()]); // cb.success("{\"level\":" + level + "}"); // } // } else // cb.failure(400, "Wrong arguments"); // }); // // register("GetRedstoneArray", (cb, tes, side, args) -> { // if(tes.hasUpgrade(side, DefaultUpgrade.REDINPUT)) { // final Direction facing = Direction.values()[side.reverse().ordinal()]; // final StringJoiner resp = new StringJoiner(",", "{\"levels\":[", "]}"); // // tes.forEachScreenBlocks(side, bp -> { // if(tes.getLevel().getBlockState(bp).getValue(BlockScreen.emitting)) // resp.add("0"); // else // resp.add("" + tes.getLevel().getSignal(bp, facing)); // }); // // cb.success(resp.toString()); // } else // cb.failure(403, "Missing upgrade"); // }); // // register("ClearRedstone", (cb, tes, side, args) -> { // if(tes.hasUpgrade(side, DefaultUpgrade.REDOUTPUT)) { // if(tes.getScreen(side).owner.uuid.equals(mc.player.getGameProfile().getId())) // makeServerQuery(tes, side, cb, JSServerRequest.CLEAR_REDSTONE); // else // cb.success("{\"status\":\"notOwner\"}"); // } else // cb.failure(403, "Missing upgrade"); // }); // // register("SetRedstoneAt", (cb, tes, side, args) -> { // if(args.length != 3 || !Arrays.stream(args).allMatch((obj) -> obj instanceof Double)) { // cb.failure(400, "Wrong arguments"); // return; // } // // if(!tes.hasUpgrade(side, DefaultUpgrade.REDOUTPUT)) { // cb.failure(403, "Missing upgrade"); // return; // } // // if(!tes.getScreen(side).owner.uuid.equals(mc.player.getGameProfile().getId())) { // cb.success("{\"status\":\"notOwner\"}"); // return; // } // // int x = ((Double) args[0]).intValue(); // int y = ((Double) args[1]).intValue(); // boolean state = ((Double) args[2]) > 0.0; // // Vector2i size = tes.getScreen(side).size; // if(x < 0 || x >= size.x || y < 0 || y >= size.y) { // cb.failure(403, "Out of range"); // return; // } // // makeServerQuery(tes, side, cb, JSServerRequest.SET_REDSTONE_AT, x, y, state); // }); // // register("IsEmitting", (cb, tes, side, args) -> { // if(!tes.hasUpgrade(side, DefaultUpgrade.REDOUTPUT)) { // cb.failure(403, "Missing upgrade"); // return; // } // // if(args.length == 2 && args[0] instanceof Double && args[1] instanceof Double) { // TileEntityScreen.Screen scr = tes.getScreen(side); // int x = ((Double) args[0]).intValue(); // int y = ((Double) args[1]).intValue(); // // if(x < 0 || x >= scr.size.x || y < 0 || y >= scr.size.y) // cb.failure(403, "Out of range"); // else { // BlockPos bpos = (new Vector3i(tes.getBlockPos())).addMul(side.right, x).addMul(side.up, y).toBlock(); // boolean e = tes.getLevel().getBlockState(bpos).getValue(BlockScreen.emitting); // cb.success("{\"emitting\":" + (e ? "true" : "false") + "}"); // } // } else // cb.failure(400, "Wrong arguments"); // }); // // register("GetEmissionArray", (cb, tes, side, args) -> { // if(tes.hasUpgrade(side, DefaultUpgrade.REDOUTPUT)) { // final StringJoiner resp = new StringJoiner(",", "{\"emission\":[", "]}"); // tes.forEachScreenBlocks(side, bp -> resp.add(tes.getLevel().getBlockState(bp).getValue(BlockScreen.emitting) ? "1" : "0")); // cb.success(resp.toString()); // } else // cb.failure(403, "Missing upgrade"); // }); // // register("GetLocation", (cb, tes, side, args) -> { // if(!tes.hasUpgrade(side, DefaultUpgrade.GPS)) { // cb.failure(403, "Missing upgrade"); // return; // } // // BlockPos bp = tes.getBlockPos(); // cb.success("{\"x\":" + bp.getX() + ",\"y\":" + bp.getY() + ",\"z\":" + bp.getZ() + ",\"side\":\"" + side + "\"}"); // }); // // register("GetUpgrades", (cb, tes, side, args) -> { // final StringBuilder sb = new StringBuilder("{\"upgrades\":["); // final ArrayList upgrades = tes.getScreen(side).upgrades; // // for(int i = 0; i < upgrades.size(); i++) { // if(i > 0) // sb.append(','); // // sb.append('\"'); // sb.append(Util.addSlashes(((IUpgrade) upgrades.get(i).getItem()).getJSName(upgrades.get(i)))); // sb.append('\"'); // } // // cb.success(sb.append("]}").toString()); // }); // // register("IsOwner", (cb, tes, side, args) -> { // boolean res = (tes.getScreen(side).owner != null && tes.getScreen(side).owner.uuid.equals(mc.player.getGameProfile().getId())); // cb.success("{\"isOwner\":" + (res ? "true}" : "false}")); // }); // // register("GetRotation", (cb, tes, side, args) -> cb.success("{\"rotation\":" + tes.getScreen(side).rotation.ordinal() + "}")); // register("GetSide", (cb, tes, side, args) -> cb.success("{\"side\":" + tes.getScreen(side).side.ordinal() + "}")); // } // //}