package Factory.CustomMessages; import EnvironmentPluginAPI.CustomNetworkMessages.NetworkMessage; import Factory.GameLogic.Enums.Direction; import Factory.GameLogic.Enums.Faction; import Factory.GameLogic.Exceptions.ConsistencyFaultException; import Factory.GameLogic.TransportTypes.TAction; import Factory.GameLogic.TransportTypes.TActionsInTurn; import Factory.GameLogic.TransportTypes.TUnit; import Factory.Interfaces.IHasConsistencyCheck; import java.io.*; import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.List; import java.util.UUID; /** * This message is used to transport ActionLists across the network connection. */ public class ActionListMessage extends NetworkMessage implements IHasConsistencyCheck, Serializable { // ------------------------------ FIELDS ------------------------------ private TActionsInTurn actions; private byte[] raw; public TActionsInTurn getAction() { return actions; } // --------------------------- CONSTRUCTORS --------------------------- public ActionListMessage(int clientId, TActionsInTurn actionsInTurn) { super(clientId); actions = actionsInTurn; if(!isConsistent()) { throw new ConsistencyFaultException(); } } /** * only for serialization!! */ public ActionListMessage() throws ConsistencyFaultException { super(-1); } private TActionsInTurn decodeTActionsInTurn(ByteBuffer buffer) { List<TAction> actions = new ArrayList<TAction>(); while (buffer.remaining() > 0) { actions.add(decodeTAction(buffer)); } return new TActionsInTurn(actions); } private TAction decodeTAction(ByteBuffer buffer) { TUnit unit = decodeTUnit(buffer); Direction direction = Direction.values()[buffer.getInt()]; return new TAction(unit, direction); } private TUnit decodeTUnit(ByteBuffer buffer) { long unitIdMSB = buffer.getLong(); long unitIdLSB = buffer.getLong(); Faction faction = Faction.values()[buffer.getInt()]; return new TUnit(new UUID(unitIdMSB, unitIdLSB), faction); } // ------------------------ CANONICAL METHODS ------------------------ @Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof ActionListMessage)) return false; ActionListMessage that = (ActionListMessage) o; if (actions != null ? !actions.equals(that.actions) : that.actions != null) return false; return true; } @Override public int hashCode() { return actions != null ? actions.hashCode() : 0; } // ------------------------ INTERFACE METHODS ------------------------ // --------------------- Interface IHasConsistencyCheck --------------------- @Override public boolean isConsistent() { return actions.isConsistent(); } // -------------------------- PRIVATE METHODS -------------------------- private byte[] encodeTActionsInTurn(TActionsInTurn actionsInTurn) { byte[] actions = new byte[0]; for (TAction action : actionsInTurn.getActions()) { actions = NetworkMessage.concatByteArrays(actions, encodeTAction(action)); } return actions; } private byte[] encodeTAction(TAction action) { byte[] unit = encodeTUnit(action.getUnit()); byte[] direction = ByteBuffer.allocate(4).putInt(action.getDirection().ordinal()).array(); return NetworkMessage.concatByteArrays(unit, direction); } private byte[] encodeTUnit(TUnit unit) { byte[] unitIdMSB = ByteBuffer.allocate(8).putLong(unit.getUnitId().getMostSignificantBits()).array(); byte[] unitIdLSB = ByteBuffer.allocate(8).putLong(unit.getUnitId().getLeastSignificantBits()).array(); byte[] factionOrdinal = ByteBuffer.allocate(4).putInt(unit.getControllingFaction().ordinal()).array(); byte[] unitUUID = NetworkMessage.concatByteArrays(unitIdMSB, unitIdLSB); return NetworkMessage.concatByteArrays(unitUUID, factionOrdinal); } // @Override // public void writeExternal(ObjectOutput out) throws IOException { // raw = encodeTActionsInTurn(actions); // out.writeInt(raw.length); // System.out.println("action list encoded length of raw: " + raw.length); // out.write(raw); // System.out.println("action list writing succeeded"); // } // // @Override // public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { // int length = in.readInt(); // raw = new byte[length]; // in.readFully(raw, 0, length); // actions = decodeTActionsInTurn(ByteBuffer.wrap(raw)); // System.out.println("action list received length: " + length); // } }