package speedytools.common.network; import net.minecraftforge.fml.common.network.ByteBufUtils; 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 io.netty.buffer.ByteBuf; import speedytools.SpeedyToolsMod; import speedytools.common.utilities.ErrorLog; /** * This class is used by the server to acknowledge actions from the client */ public class Packet250CloneToolAcknowledge extends Packet250Base { /** * The packet will contain acknowledgement information for the action, the undo, or both. * If one of them is status rejected, an optional reason can be provided. * @param i_actionStatus * @param i_actionSequenceNumber * @param i_undoStatus * @param i_undoSequenceNumber * @param i_reason If a status is rejected, this human-readable message will be sent to the client * If not required - leave blank "", not null. */ public Packet250CloneToolAcknowledge(Acknowledgement i_actionStatus, int i_actionSequenceNumber, Acknowledgement i_undoStatus, int i_undoSequenceNumber, String i_reason) { actionAcknowledgement = i_actionStatus; actionSequenceNumber = i_actionSequenceNumber; undoAcknowledgement = i_undoStatus; undoSequenceNumber = i_undoSequenceNumber; reason = i_reason; packetIsValid = true; } /** * Is this packet valid to be received and acted on by the given side? * @param whichSide * @return true if yes */ public boolean validForSide(Side whichSide) { assert(checkInvariants()); return (whichSide == Side.CLIENT); } public Acknowledgement getActionAcknowledgement() { return actionAcknowledgement; } public int getActionSequenceNumber() { return actionSequenceNumber; } public Acknowledgement getUndoAcknowledgement() { return undoAcknowledgement; } public int getUndoSequenceNumber() { return undoSequenceNumber; } public String getReason() { return reason; } public Packet250CloneToolAcknowledge() {}; // used by Netty; invalid until populated by the packet handler @Override public void readFromBuffer(ByteBuf buf) { try { packetIsValid = false; actionAcknowledgement = Acknowledgement.byteToAcknowledgement(buf.readByte()); actionSequenceNumber = buf.readInt(); undoAcknowledgement = Acknowledgement.byteToAcknowledgement(buf.readByte()); undoSequenceNumber = buf.readInt(); reason = ByteBufUtils.readUTF8String(buf); } catch (IndexOutOfBoundsException ioe) { ErrorLog.defaultLog().info("Exception while reading Packet250CloneToolAcknowledge: " + ioe); return; } if (!checkInvariants()) return; packetIsValid = true; } @Override public void writeToBuffer(ByteBuf buf) { checkInvariants(); if (!isPacketIsValid()) return; buf.writeByte(actionAcknowledgement.getID()); buf.writeInt(actionSequenceNumber); buf.writeByte(undoAcknowledgement.getID()); buf.writeInt(undoSequenceNumber); ByteBufUtils.writeUTF8String(buf, reason); } /** * checks this class to see if it is internally consistent * @return true if ok, false if bad. */ private boolean checkInvariants() { if (actionAcknowledgement == null || undoAcknowledgement == null) return false; return true; } public enum Acknowledgement { NOUPDATE(100), REJECTED(101), ACCEPTED(102), COMPLETED(104); public byte getID() {return rawID;} public static Acknowledgement byteToAcknowledgement(byte value) { for (Acknowledgement acknowledgement : Acknowledgement.values()) { if (value == acknowledgement.getID()) return acknowledgement; } return null; } private Acknowledgement(int i_rawID) { rawID = (byte)i_rawID; } private final byte rawID; } /** * Register the handler for this packet * @param packetHandlerRegistry * @param packetHandlerMethod * @param side */ public static void registerHandler(PacketHandlerRegistry packetHandlerRegistry, PacketHandlerMethod packetHandlerMethod, Side side) { switch (side) { case CLIENT: { clientSideHandler = packetHandlerMethod; break; } case SERVER: { serverSideHandler = packetHandlerMethod; break; } default: { assert false : "Tried to register Packet250CloneToolAcknowledge on side " + side; } } packetHandlerRegistry.getSimpleNetworkWrapper().registerMessage(CommonMessageHandler.class, Packet250CloneToolAcknowledge.class, Packet250Types.PACKET250_TOOL_ACKNOWLEDGE_ID.getPacketTypeID(), side); } public interface PacketHandlerMethod { public boolean handlePacket(Packet250CloneToolAcknowledge packet250CloneToolAcknowledge, MessageContext ctx); } public static class CommonMessageHandler implements IMessageHandler<Packet250CloneToolAcknowledge, IMessage> { /** * Called when a message is received of the appropriate type. You can optionally return a reply message, or null if no reply * is needed. * * @param message The message * @return an optional return message */ public IMessage onMessage(final Packet250CloneToolAcknowledge message, final MessageContext ctx) { Runnable messageProcessor = null; switch (ctx.side) { case CLIENT: { if (clientSideHandler == null) { ErrorLog.defaultLog().severe("Packet250CloneToolAcknowledge received but not registered on side " + ctx.side); } else { messageProcessor = new Runnable() { @Override public void run() { clientSideHandler.handlePacket(message, ctx); } }; } break; } case SERVER: { if (serverSideHandler == null) { ErrorLog.defaultLog().severe("Packet250CloneToolAcknowledge received but not registered on side " + ctx.side); } else { messageProcessor = new Runnable() { @Override public void run() { serverSideHandler.handlePacket(message, ctx); } }; } break; } default: assert false : "Received message on invalid side: " + ctx.side; } if (messageProcessor != null) { boolean success = SpeedyToolsMod.proxy.enqueueMessageOnCorrectThread(ctx, messageProcessor); if (!success) { ErrorLog.defaultLog().severe("Packet250CloneToolAcknowledge failed to handle Packet"); } } return null; } } private static PacketHandlerMethod serverSideHandler; private static PacketHandlerMethod clientSideHandler; private Acknowledgement actionAcknowledgement; private int actionSequenceNumber; private Acknowledgement undoAcknowledgement; private int undoSequenceNumber; private String reason; }