Rewrite LP network data saving system

Instead of creating a new file for each player with their UUID as the name, we create a single file and store it all in a List. That List gets converted to a UUID -> SoulNetwork map when read from the file.

MigrateNetworkDataHandler is used to migrate players from the old system to the new one. It reads both data files and sets the LP of the new network to the LP of the old network (if the old network is larger). Once conversion is done, we delete the old file so that it doesn't happen again and overwrite player progress.

This is an API breaking change due to an import change.
This commit is contained in:
Nicholas Ignoffo 2016-06-12 13:41:02 -07:00
parent f8859dbf56
commit f99b21cffc
40 changed files with 423 additions and 283 deletions

View file

@ -0,0 +1,64 @@
package WayofTime.bloodmagic.api.saving;
import WayofTime.bloodmagic.api.util.helper.PlayerHelper;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.world.WorldSavedData;
import java.util.*;
public class BMWorldSavedData extends WorldSavedData
{
public static final String ID = "BloodMagic-SoulNetworks";
private Map<UUID, SoulNetwork> soulNetworks = new HashMap<UUID, SoulNetwork>();
public BMWorldSavedData(String id)
{
super(id);
}
public BMWorldSavedData()
{
this(ID);
}
public SoulNetwork getNetwork(EntityPlayer player)
{
return getNetwork(PlayerHelper.getUUIDFromPlayer(player));
}
public SoulNetwork getNetwork(UUID playerId)
{
if (!soulNetworks.containsKey(playerId))
soulNetworks.put(playerId, SoulNetwork.newEmpty(playerId).setParent(this));
return soulNetworks.get(playerId);
}
@Override
public void readFromNBT(NBTTagCompound tagCompound)
{
NBTTagList networkData = tagCompound.getTagList("networkData", 10);
for (int i = 0; i < networkData.tagCount(); i++)
{
NBTTagCompound data = networkData.getCompoundTagAt(i);
SoulNetwork network = SoulNetwork.fromNBT(data);
network.setParent(this);
soulNetworks.put(network.getPlayerId(), network);
}
}
@Override
public NBTTagCompound writeToNBT(NBTTagCompound tagCompound)
{
NBTTagList networkData = new NBTTagList();
for (SoulNetwork soulNetwork : soulNetworks.values())
networkData.appendTag(soulNetwork.serializeNBT());
tagCompound.setTag("networkData", networkData);
return tagCompound;
}
}

View file

@ -0,0 +1,220 @@
package WayofTime.bloodmagic.api.saving;
import WayofTime.bloodmagic.api.BloodMagicAPI;
import WayofTime.bloodmagic.api.event.AddToNetworkEvent;
import WayofTime.bloodmagic.api.event.SoulNetworkEvent;
import WayofTime.bloodmagic.api.util.helper.PlayerHelper;
import com.google.common.base.Strings;
import lombok.Getter;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.MobEffects;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.potion.PotionEffect;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.common.util.INBTSerializable;
import net.minecraftforge.fml.common.FMLCommonHandler;
import net.minecraftforge.fml.common.eventhandler.Event;
import javax.annotation.Nullable;
import java.util.UUID;
@Getter
public class SoulNetwork implements INBTSerializable<NBTTagCompound>
{
private BMWorldSavedData parent;
private EntityPlayer cachedPlayer;
private UUID playerId;
private int currentEssence;
private int orbTier;
private SoulNetwork()
{
// No-op - For creation via NBT only
}
public int add(int toAdd, int maximum)
{
AddToNetworkEvent event = new AddToNetworkEvent(playerId.toString(), toAdd, maximum);
if (MinecraftForge.EVENT_BUS.post(event))
return 0;
if (FMLCommonHandler.instance().getMinecraftServerInstance() == null)
return 0;
int currEss = getCurrentEssence();
if (currEss >= event.maximum)
return 0;
int newEss = Math.min(event.maximum, currEss + event.addedAmount);
if (event.getResult() != Event.Result.DENY)
setCurrentEssence(newEss);
return newEss - currEss;
}
/**
* @deprecated - Please use {@link #add(int, int)}
*/
@Deprecated
public int addLifeEssence(int toAdd, int maximum)
{
return add(toAdd, maximum);
}
public int syphon(int syphon)
{
if (getCurrentEssence() >= syphon)
{
setCurrentEssence(getCurrentEssence() - syphon);
return syphon;
}
return 0;
}
public boolean syphonAndDamage(EntityPlayer user, int toSyphon)
{
if (user != null)
{
if (user.worldObj.isRemote)
return false;
if (!Strings.isNullOrEmpty(playerId.toString()))
{
SoulNetworkEvent.ItemDrainNetworkEvent event = new SoulNetworkEvent.ItemDrainNetworkEvent(user, playerId.toString(), null, toSyphon);
if (MinecraftForge.EVENT_BUS.post(event))
return false;
int drainAmount = syphon(event.syphon);
if (drainAmount <= 0 || event.shouldDamage)
hurtPlayer(user, event.syphon);
return event.getResult() != Event.Result.DENY;
}
int amount = syphon(toSyphon);
hurtPlayer(user, toSyphon - amount);
return true;
}
return false;
}
public void causeNausea()
{
if (getPlayer() != null)
getPlayer().addPotionEffect(new PotionEffect(MobEffects.NAUSEA, 99));
}
/**
* @deprecated - Please use {@link #causeNausea()}
*/
@Deprecated
public void causeNauseaToPlayer()
{
causeNausea();
}
public void hurtPlayer(EntityPlayer user, float syphon)
{
if (user != null)
{
if (syphon < 100 && syphon > 0)
{
if (!user.capabilities.isCreativeMode)
{
user.hurtResistantTime = 0;
user.attackEntityFrom(BloodMagicAPI.getDamageSource(), 1.0F);
}
} else if (syphon >= 100)
{
if (!user.capabilities.isCreativeMode)
{
for (int i = 0; i < ((syphon + 99) / 100); i++)
{
user.hurtResistantTime = 0;
user.attackEntityFrom(BloodMagicAPI.getDamageSource(), 1.0F);
}
}
}
}
}
private void markDirty()
{
if (getParent() != null)
getParent().markDirty();
else
BloodMagicAPI.getLogger().error("A SoulNetwork was created, but a parent was not set to allow saving.");
}
@Nullable
public EntityPlayer getPlayer()
{
if (cachedPlayer == null)
cachedPlayer = PlayerHelper.getPlayerFromUUID(playerId);
return cachedPlayer;
}
public SoulNetwork setCurrentEssence(int currentEssence)
{
this.currentEssence = currentEssence;
markDirty();
return this;
}
public SoulNetwork setOrbTier(int orbTier)
{
this.orbTier = orbTier;
markDirty();
return this;
}
public SoulNetwork setParent(BMWorldSavedData parent)
{
this.parent = parent;
markDirty();
return this;
}
// INBTSerializable
@Override
public NBTTagCompound serializeNBT()
{
NBTTagCompound tagCompound = new NBTTagCompound();
tagCompound.setString("playerId", getPlayerId().toString());
tagCompound.setInteger("currentEssence", getCurrentEssence());
tagCompound.setInteger("orbTier", getOrbTier());
return tagCompound;
}
@Override
public void deserializeNBT(NBTTagCompound nbt)
{
this.playerId = UUID.fromString(nbt.getString("playerId"));
this.currentEssence = nbt.getInteger("currentEssence");
this.orbTier = nbt.getInteger("orbTier");
}
public static SoulNetwork fromNBT(NBTTagCompound tagCompound)
{
SoulNetwork soulNetwork = new SoulNetwork();
soulNetwork.deserializeNBT(tagCompound);
return soulNetwork;
}
public static SoulNetwork newEmpty(UUID uuid)
{
SoulNetwork network = new SoulNetwork();
network.playerId = uuid;
return network;
}
}