package de.maxgb.minecraft.second_screen.world_observer; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import net.minecraft.block.Block; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.BlockPos; import net.minecraft.util.EnumFacing; import net.minecraft.world.IBlockAccess; import net.minecraft.world.World; import net.minecraft.world.WorldServer; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import de.maxgb.minecraft.second_screen.data.ObservingManager; import de.maxgb.minecraft.second_screen.util.Logger; public class ObservedBlock { /** * Interface for observingtypes e.g. InventoryObserver or FluidTankObserver * @author Max * */ public static interface ObservingType { /** * Adds the informations about the given block to the next update * * @param block * @param world * World the block is in * @return false if the block should be removed from the list */ public boolean addInfoForBlock(World world, ObservedBlock block); /** * Tests if this block/tile can be observed by this observer type * * @param block * @param tile * tile can be null * @return */ public boolean canObserve(Block block, TileEntity tile); /** * Adds all information collected by * {@link #addInfoForBlock(ObservedBlock) addInfoForBlock} method. Does * not change anything if nothing to add * * @param parent * JSONObject the info shall be added to */ public void finishInfoCreation(JSONObject parent); /** * * @return ID for this type */ public int getId(); /** * * @return A string which can be used to indentify this type in commands * etc */ public String getIdentifier(); /** * * @return A short string which can be used to indentify this type in * commands etc */ public String getShortIndentifier(); } private final static String TAG = "ObservedBlock"; private static List<ObservingType> observingTypes; /** * Collects the data from all observed blocks, seperates them by types and * puts the results in the parent JSON * * @param parent * JSONObject to store data * @param worlds * Minecraftworlds which contain the blocks */ public static void addObservingInfo(JSONObject parent, HashMap<Integer, WorldServer> worlds, String username) { ArrayList<ObservedBlock> blocks = ObservingManager.getObservedBlocks(username, true); for (int i = 0; i < blocks.size(); i++) { ObservedBlock block = blocks.get(i); WorldServer world = worlds.get(block.dimensionId); if (world == null) { Logger.w(TAG, "Dimension corrosponding to the block not found: " + block.dimensionId); ObservingManager.removeObservedBlock(username, block.label); } else { if (world.getBlockState(block.pos).getBlock().getMaterial() == net.minecraft.block.material.Material.air) { Logger.w(TAG, "Blocks material is air -> remove"); ObservingManager.removeObservedBlock(username, block.label); } else { for (ObservingType t : getObservingTypes()) { if (t.getId() == block.type) { if (!t.addInfoForBlock(world, block)) { ObservingManager.removeObservedBlock(username, block.label); } break; } } } } } for (ObservingType t : getObservingTypes()) { t.finishInfoCreation(parent); } } /** * Creates an ObservedBlock from its json save data * * @param json * @return */ public static ObservedBlock createFromJson(JSONObject json) { try { ObservedBlock b = new ObservedBlock(); b.label = json.getString("label"); JSONArray coord = json.getJSONArray("coord"); b.pos=new BlockPos(coord.getInt(0),coord.getInt(1),coord.getInt(2)); b.dimensionId = coord.getInt(3); b.type = json.getInt("type"); if (json.has("side_str")) { b.side = EnumFacing.byName(json.getString("side_str")); } else { b.side = EnumFacing.UP; } return b; } catch (JSONException e) { Logger.e(TAG, "Failed to parse block", e); return null; } } /** * @return A list of all available ObservingTypes */ public static List<ObservingType> getObservingTypes() { if (observingTypes == null) { observingTypes = new ArrayList<ObservingType>(); observingTypes.add(new RedstoneObserver()); observingTypes.add(new InventoryObserver()); observingTypes.add(new FluidTankObserver()); //observingTypes.add(new NodeObserver()); //observingTypes.add(new RFEnergyStorageObserver()); } return observingTypes; } protected String label; protected int dimensionId; protected BlockPos pos; protected EnumFacing side; protected int type; private ObservedBlock() { } /** * Creates a ObservedBlock * @param label Name/Label * @param x X-Coord * @param y Y-Coord * @param z Z-Coord * @param dimensionId Worlddimension id * @param type ObservingType given by the corrosponding observer class * @param sideHit Side it was registered from */ public ObservedBlock(String label, BlockPos pos, int dimensionId, int type, EnumFacing sideHit) { this.pos=pos; this.label = label; this.dimensionId = dimensionId; this.type = type; this.side = sideHit; } /** * Returns the block assosiated with the coordinated in the given world * * @param world * world * @return block */ public Block getBlock(IBlockAccess world) { return world.getBlockState(pos).getBlock(); } public String getLabel() { return label; } /** * Created a JsonObject representing this block * * @return */ public JSONObject toJSON() { JSONObject json = new JSONObject(); json.put("label", label); JSONArray coord = new JSONArray(); coord.put(pos.getX()); coord.put(pos.getY()); coord.put(pos.getZ()); coord.put(dimensionId); json.put("coord", coord); json.put("side_str", side.getName()); json.put("type", type); return json; } }