Package crazypants.enderio.enderface

Source Code of crazypants.enderio.enderface.PacketOpenRemoteUi$PlayerProxy

package crazypants.enderio.enderface;

import io.netty.buffer.ByteBuf;

import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.Set;

import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.inventory.ContainerBeacon;
import net.minecraft.inventory.ContainerRepair;
import net.minecraft.network.play.server.S2DPacketOpenWindow;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.management.ItemInWorldManager;
import net.minecraft.tileentity.TileEntityBeacon;
import net.minecraft.world.WorldServer;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import com.mojang.authlib.GameProfile;

import cpw.mods.fml.common.network.simpleimpl.IMessage;
import cpw.mods.fml.common.network.simpleimpl.IMessageHandler;
import cpw.mods.fml.common.network.simpleimpl.MessageContext;

public class PacketOpenRemoteUi implements IMessage, IMessageHandler<PacketOpenRemoteUi, IMessage> {

  int x;
  int y;
  int z;

  public PacketOpenRemoteUi() {
  }

  public PacketOpenRemoteUi(int x, int y, int z) {
    this.x = x;
    this.y = y;
    this.z = z;
  }

  @Override
  public void toBytes(ByteBuf buffer) {
    buffer.writeInt(x);
    buffer.writeInt(y);
    buffer.writeInt(z);
  }

  @Override
  public void fromBytes(ByteBuf buffer) {
    x = buffer.readInt();
    y = buffer.readInt();
    z = buffer.readInt();

  }

  public IMessage onMessage(PacketOpenRemoteUi message, MessageContext ctx) {
    EntityPlayerMP player = (EntityPlayerMP) ctx.getServerHandler().playerEntity;
    net.minecraft.inventory.Container c = player.openContainer;
    PlayerProxy pp = new PlayerProxy(player, message.x, message.y, message.z);
    EntityPlayerMP proxy = createPlayerProxy(player, pp);
    proxy.playerNetServerHandler = player.playerNetServerHandler;
    proxy.inventory = player.inventory;
    proxy.currentWindowId = player.currentWindowId;
    proxy.inventoryContainer = player.inventoryContainer;
    proxy.openContainer = player.openContainer;
    proxy.worldObj = player.worldObj;

    player.theItemInWorldManager.activateBlockOrUseItem(proxy, player.worldObj, null, message.x, message.y, message.z, 0, 0, 0, 0);
    player.theItemInWorldManager.thisPlayerMP = player;
    if(c != proxy.openContainer) {
      player.openContainer = proxy.openContainer;
    }
    return null;
  }

  public static <T> T createPlayerProxy(EntityPlayerMP player, PlayerProxy proxy) {
    Enhancer e = new Enhancer();
    e.setCallback(proxy);

    e.setSuperclass(player.getClass());
    Class<?>[] argTypes = new Class[] { MinecraftServer.class, WorldServer.class, GameProfile.class, ItemInWorldManager.class };
    Object[] args = new Object[] { player.mcServer, player.worldObj, player.getGameProfile(), player.theItemInWorldManager };

    e.setInterceptDuringConstruction(false);
    @SuppressWarnings("unchecked")
    T proxifiedObj = (T) e.create(argTypes, args);

    return proxifiedObj;
  }

  public static class PlayerProxy implements MethodInterceptor {

    private EntityPlayerMP realObj;

    private Set<String> interceptNames = new HashSet<String>();

    private Set<String> beaconNames = new HashSet<String>();
    private Set<String> anvilNames = new HashSet<String>();

    private Set<String> distanceNames = new HashSet<String>();

    int x;
    int y;
    int z;

    public PlayerProxy(EntityPlayerMP obj, int x, int y, int z) {

      this.x = x;
      this.y = y;
      this.z = z;

      // TODO: Move to config? or use reflectioon helper?
      this.realObj = obj;
      interceptNames.add("openGui");
      interceptNames.add("func_146100_a");

      interceptNames.add("displayGUIBrewingStand");
      interceptNames.add("func_71017_a");
      interceptNames.add("func_146098_a");

      interceptNames.add("displayGUIChest");
      interceptNames.add("func_71007_a");

      interceptNames.add("displayGUIDispenser");
      interceptNames.add("func_71006_a");
      interceptNames.add("func_146102_a");

      interceptNames.add("displayGUIEnchantment");
      interceptNames.add("func_71002_c");

      interceptNames.add("displayGUIFurnace");
      interceptNames.add("func_71042_a");
      interceptNames.add("func_146101_a");

      interceptNames.add("displayGUIWorkbench");
      interceptNames.add("func_71058_b");

      interceptNames.add("displayGuiHopper"); // for when its added
      interceptNames.add("func_94064_a"); // displayGuiHopper

      interceptNames.add("displayGUIHopper");
      interceptNames.add("func_146093_a");

      beaconNames.add("displayGUIBeacon");
      beaconNames.add("func_82240_a");
      beaconNames.add("func_146104_a");

      anvilNames.add("displayGUIAnvil");
      anvilNames.add("func_82244_d");

      distanceNames.add("getDistanceSq");
      distanceNames.add("getDistance");
      distanceNames.add("func_70092_e");
      distanceNames.add("func_70011_f");
      distanceNames.add("func_71569_e");

    }

    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {

      if(interceptNames.contains(method.getName())) {

        Object res = method.invoke(realObj, objects);
        if(realObj.openContainer != null) {
          realObj.openContainer = new ContainerWrapper(realObj.openContainer);
        }
        return res;

      } else if(beaconNames.contains(method.getName())) {

        // Beacon needs to be done manually for some reason to work properly
        TileEntityBeacon par1TileEntityBeacon = (TileEntityBeacon) objects[0];
        realObj.getNextWindowId();

        realObj.playerNetServerHandler.sendPacket(new S2DPacketOpenWindow(realObj.currentWindowId, 7, par1TileEntityBeacon.getInventoryName(),
            par1TileEntityBeacon.getSizeInventory(), true));

        realObj.openContainer = new ContainerBeacon(realObj.inventory, par1TileEntityBeacon) {
          @Override
          public boolean canInteractWith(EntityPlayer par1EntityPlayer) {
            return true;
          }
        };
        realObj.openContainer.windowId = realObj.currentWindowId;
        realObj.openContainer.addCraftingToCrafters(realObj);
        return null;

      } else if(anvilNames.contains(method.getName())) {

        realObj.getNextWindowId();
        realObj.playerNetServerHandler.sendPacket(new S2DPacketOpenWindow(realObj.currentWindowId, 8, "Repairing", 9, true));

        realObj.openContainer = new ContainerRepair(realObj.inventory, realObj.worldObj, ((Integer) objects[0]).intValue(), ((Integer) objects[1]).intValue(),
            ((Integer) objects[2]).intValue(), realObj) {

          @Override
          public boolean canInteractWith(EntityPlayer par1EntityPlayer) {
            return true;
          }

        };
        realObj.openContainer.windowId = realObj.currentWindowId;
        realObj.openContainer.addCraftingToCrafters(realObj);
        return null;

      } else if(distanceNames.contains(method.getName())) {
        return 6;
      }
      method.setAccessible(true);
      return method.invoke(realObj, objects);
    }
  }

}
TOP

Related Classes of crazypants.enderio.enderface.PacketOpenRemoteUi$PlayerProxy

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.