/** * Copyright (c) Lambda Innovation, 2013-2016 * This file is part of the AcademyCraft mod. * https://github.com/LambdaInnovation/AcademyCraft * Licensed under GPLv3, see project root for more information. */ package cn.academy.ability.api.ctrl; import cn.lambdalib.annoreg.core.Registrant; import cn.lambdalib.s11n.network.NetworkS11n.NetworkS11nType; import cpw.mods.fml.common.FMLCommonHandler; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import net.minecraft.client.Minecraft; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.nbt.NBTTagCompound; import java.util.UUID; /** * @author EAirPeter * @deprecated Use {@link cn.academy.ability.api.context.Context} instead. */ @Deprecated @Registrant @NetworkS11nType public abstract class SyncAction { protected UUID uuid; int intv = -1; int lastInformed = 0; protected final boolean isRemote = FMLCommonHandler.instance().getEffectiveSide().equals(Side.CLIENT); /** * The associated player * null for started from server */ protected EntityPlayer player = null; /** * Construct a SyncAction * Notice: Every subclass of SyncAction must have a constructor with no parameter * @param interval Server side will send an update to client side every interval ticks, while -1 for never. */ protected SyncAction(int interval) { intv = interval; state = State.CREATED; uuid = UUID.randomUUID(); } private State state; public static enum State { CREATED, STARTED, ENDED, ABORTED, } /* start from client * send to server(start) * server reply, server.onStart or nothing * corresponding: client.onStart or nothing */ /* start from server * send to client(start), server.onStart * client.onStart or abortAtServer */ /** * Called when this start at both sides */ public void onStart() { } /* (server) tick and send(every ${interval}) * server inform */ /** * Called every tick at both sides */ public void onTick() { } /* end from client * send to server * server reply, server inform(final) and (server.onAbort or server.onEnd) * client.onUpdate and (corresponding: client.onAbort or client.onEnd) */ /* end from server * send to client, server inform(final) and server.onEnd * client.onUpdate and client.onEnd */ /** * Called when ended at both sides */ public void onEnd() { } /* abort from client * send to server * server inform(final) and server.onAbort * client.onUpdate and client.onAbort */ /* abort from server * server inform(final) and server.onAbort * client.onUpdate and client.onAbort */ /** * Called when aborted at both sides * This is nothing to do with network * If any, please use NBT operation(Final) */ public void onAbort() { } /** * called after onEnd or onAbort */ public void onFinalize() { } public void readNBTStart(NBTTagCompound tag) { } public void readNBTUpdate(NBTTagCompound tag) { } public void readNBTFinal(NBTTagCompound tag) { } public void writeNBTStart(NBTTagCompound tag) { } public void writeNBTUpdate(NBTTagCompound tag) { } public void writeNBTFinal(NBTTagCompound tag) { } /** * @return Whether this SyncAction is local. a.k.a. Is at the side where it started. * <br/>Returns true when: <br/> * * At server and started at server <br/> * * At the client that constructed this SyncAction */ public final boolean isLocal() { if(isRemote) return isLocalClient(); return player == null; } @SideOnly(Side.CLIENT) protected boolean isLocalClient() { return Minecraft.getMinecraft().thePlayer.equals(player); } /** * @return The action's state */ public final State getState() { return state; } private static final String NBT_UUID = "0"; private static final String NBT_STATE = "1"; private static final String NBT_INTERVAL = "2"; private static final String NBT_OBJECT = "3"; final void setNBTStart(NBTTagCompound tag) { uuid = UUID.fromString(tag.getString(NBT_UUID)); intv = tag.getInteger(NBT_INTERVAL); if (tag.hasKey(NBT_OBJECT)) readNBTStart(tag.getCompoundTag(NBT_OBJECT)); } final void setNBTUpdate(NBTTagCompound tag) { if (tag.hasKey(NBT_OBJECT)) readNBTUpdate(tag.getCompoundTag(NBT_OBJECT)); } final void setNBTFinal(NBTTagCompound tag) { if (tag.hasKey(NBT_OBJECT)) readNBTFinal(tag.getCompoundTag(NBT_OBJECT)); } final NBTTagCompound getNBTStart() { NBTTagCompound tag = new NBTTagCompound(); tag.setString(NBT_UUID, uuid.toString()); tag.setInteger(NBT_INTERVAL, intv); NBTTagCompound obj = new NBTTagCompound(); writeNBTStart(obj); tag.setTag(NBT_OBJECT, obj); return tag; } final NBTTagCompound getNBTUpdate() { NBTTagCompound tag = new NBTTagCompound(); NBTTagCompound obj = new NBTTagCompound(); writeNBTUpdate(obj); tag.setTag(NBT_OBJECT, obj); return tag; } final NBTTagCompound getNBTFinal() { NBTTagCompound tag = new NBTTagCompound(); NBTTagCompound obj = new NBTTagCompound(); writeNBTFinal(obj); tag.setTag(NBT_OBJECT, obj); return tag; } final void start() { state = State.STARTED; onStart(); } final void end(NBTTagCompound tag) { if (state.equals(State.STARTED)) { state = State.ENDED; setNBTFinal(tag); onEnd(); onFinalize(); } } final NBTTagCompound end() { NBTTagCompound tag = TAG_EMPTY; if (state.equals(State.STARTED)) { state = State.ENDED; tag = getNBTFinal(); onEnd(); onFinalize(); } return tag; } final void abort(NBTTagCompound tag) { if (state.equals(State.STARTED)) { state = State.ABORTED; setNBTFinal(tag); onAbort(); onFinalize(); } } final NBTTagCompound abort() { NBTTagCompound tag = TAG_EMPTY; if (state.equals(State.STARTED)) { state = State.ABORTED; tag = getNBTFinal(); onAbort(); onFinalize(); } return tag; } static final UUID getUUIDFromNBT(NBTTagCompound tag) { if (tag.hasKey(NBT_UUID)) return UUID.fromString(tag.getString(NBT_UUID)); else return null; } static final NBTTagCompound TAG_EMPTY = new NBTTagCompound(); }