gt22 icon

Untitled

gt22 | PRO | 06/02/17 06:50:43 PM UTC | 0 ⭐ | 539 👁️ | Never ⏰ | []
Java |

6.35 KB

|

None

|

0 👍

/

0 👎

package com.uadaf.astral.apiimpl;
 
import cofh.api.energy.EnergyStorage;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.uadaf.astral.AstralMod;
import com.uadaf.astral.api.energy.IAstralBindableTile;
import com.uadaf.astral.api.energy.IAstralEnergyStorer;
import com.uadaf.astral.api.energy.IAstralNetwork;
import com.uadaf.astral.api.event.network.AstralNetworkAccessBlockedEvent;
import com.uadaf.astral.api.event.network.AstralNetworkAccessGrantedEvent;
import com.uadaf.astral.utils.SideCheck;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
import net.minecraftforge.common.MinecraftForge;
 
import javax.annotation.Nullable;
import java.util.*;
 
class AstralNetworkImpl implements IAstralNetwork {
 
    private final int color;
    private final UUID owner;
    private final Set<IAstralBindableTile> bound = Sets.newHashSet(), immutableBoundView = Collections.unmodifiableSet(bound);
    private final Set<UUID> accessedPlayers = Sets.newHashSet(), immutableAccessedPlayersView = Collections.unmodifiableSet(accessedPlayers);
    private final List<PlayerDiff> playerDiff = Lists.newArrayList(), immutablePlayerDiffView = Collections.unmodifiableList(playerDiff);
    private final List<BoundDiff> boundDiff = Lists.newArrayList(), immutableBoundDiffView = Collections.unmodifiableList(boundDiff);
    private final EnergyStorage energyStorage = new EnergyStorage(0);
    private final HashMap<Integer, List<BoundDiff>> queuedBindings = Maps.newHashMap();
    private int energyDiff = 0;
    AstralNetworkImpl(int color, UUID owner) {
        this.color = color;
        this.owner = owner;
        accessedPlayers.add(owner);
    }
 
    @Override
    public int getNetworkColor() {
        return color;
    }
 
    @Override
    public void destroy() {
        bound.forEach(b -> b.onUnbound(this));
        bound.clear();
    }
 
    @Override
    public Set<IAstralBindableTile> getBound() {
        return immutableBoundView; //Unmodifiable set reflects all changes int base set
    }
 
    @Override
    public void bind(IAstralBindableTile bindable) {
        if(SideCheck.isServer() && bound.add(bindable)) {
            bindable.onBound(this);
            boundDiff.add(new BoundDiff(bindable.getPos(), true, bindable.getWorld().provider.getDimension()));
            if(bindable instanceof IAstralEnergyStorer) {
                recalculateStorage();
            }
        }
    }
 
    @Override
    public void unbind(IAstralBindableTile bindable) {
        if(SideCheck.isServer() && bound.remove(bindable)) {
            bindable.onUnbound(this);
            boundDiff.add(new BoundDiff(bindable.getPos(), false, bindable.getWorld().provider.getDimension()));
            if(bindable instanceof IAstralEnergyStorer) {
                recalculateStorage();
            }
        }
    }
 
    @Override
    public void queueBinding(BoundDiff binding) {
        queuedBindings.compute(binding.dimension, (dim, queue) -> {
            if(queue == null) {
                queue = Lists.newArrayList();
            }
            queue.add(binding);
            return queue;
        });
    }
 
    @Override
    public void performQueue(World world) {
        List<BoundDiff> queue = queuedBindings.get(world.provider.getDimension());
        if(queue != null) {
            queue.forEach(diff -> {
                TileEntity t = world.getTileEntity(diff.pos);
                if(!(t instanceof IAstralBindableTile)) {
                    AstralMod.log.warn("TileEntity " + t + "---" + diff.pos + " doesn't implement " + IAstralBindableTile.class + ", but was received from sync packet");
                    return;
                }
                bind((IAstralBindableTile) t);
            });
        }
    }
 
    @Override
    public List<BoundDiff> getBoundDiff() {
        return immutableBoundDiffView;
    }
 
    @Override
    public void resetBoundDiff() {
        boundDiff.clear();
    }
 
    private void recalculateStorage() {
        int newCapacity = getBound().stream()
            .filter(b -> b instanceof IAstralEnergyStorer)
            .map(b -> (IAstralEnergyStorer) b)
            .map(s -> {
                AstralMod.log.info("Storer: " + s + ", en: " + s.getMaxStoredEnergy() + ", pos: " + s.getPos());
                return s.getMaxStoredEnergy();
            })
            .reduce((i, j) -> i + j)
            .orElse(0);
        energyStorage.setCapacity(newCapacity);
        energyStorage.setMaxTransfer(newCapacity);
    }
 
    @Override
    public void modifyEnergy(int mod) {
        energyDiff += mod;
        energyStorage.modifyEnergyStored(mod);
    }
 
    @Override
    public int getEnergyDiff() {
        return energyDiff;
    }
 
    @Override
    public void resetEnergyDiff() {
        energyDiff = 0;
    }
 
    @Nullable
    @Override
    public UUID getOwner() {
        return owner;
    }
 
    @Override
    public List<PlayerDiff> getPlayerDiff() {
        return immutablePlayerDiffView; //Unmodifiable set reflects all changes int base set
    }
 
    @Override
    public Set<UUID> getAccessedPlayers() {
        return immutableAccessedPlayersView; //Unmodifiable set reflects all changes int base set
    }
 
    @Override
    public boolean allowAccess(UUID player) {
        playerDiff.add(new PlayerDiff(player, true));
        boolean ret = accessedPlayers.add(player);
        if(ret) {
            MinecraftForge.EVENT_BUS.post(new AstralNetworkAccessGrantedEvent(this, player));
        }
        return ret;
    }
 
    @Override
    public boolean blockAccess(UUID player) {
        playerDiff.add(new PlayerDiff(player, false));
        boolean ret = accessedPlayers.remove(player);
        if(ret) {
            MinecraftForge.EVENT_BUS.post(new AstralNetworkAccessBlockedEvent(this, player));
        }
        return ret;
    }
 
    @Override
    public boolean hasAccess(EntityPlayer player) {
        return hasAccess(player.getGameProfile().getId());
    }
 
    @Override
    public boolean hasAccess(UUID player) {
        return accessedPlayers.contains(player);
    }
 
    @Override
    public void resetPlayerDiff() {
        playerDiff.clear();
    }
 
    @Override
    public int receiveEnergy(int maxReceive, boolean simulate) {
        int e = energyStorage.receiveEnergy(maxReceive, simulate);
        if(!simulate) {
            energyDiff += e;
        }
        return e;
    }
 
    @Override
    public int extractEnergy(int maxExtract, boolean simulate) {
        int e = energyStorage.extractEnergy(maxExtract, simulate);
        if(!simulate) {
            energyDiff -= maxExtract;
        }
        return e;
    }
 
    @Override
    public int getEnergyStored() {
        return energyStorage.getEnergyStored();
    }
 
    @Override
    public int getMaxEnergyStored() {
        return energyStorage.getMaxEnergyStored();
    }
 
    @Override
    public boolean canExtract() {
        return energyStorage.extractEnergy(1, true) == 1;
    }
 
    @Override
    public boolean canReceive() {
        return energyStorage.receiveEnergy(1, true) == 1;
    }
}

Comments