package ttftcuts.physis.common.file;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.UUID;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
import cpw.mods.fml.common.gameevent.PlayerEvent.PlayerLoggedInEvent;
import cpw.mods.fml.relauncher.Side;
import ttftcuts.physis.Physis;
import ttftcuts.physis.common.network.PhysisPacketHandler;
import ttftcuts.physis.common.network.packet.PacketWorldData;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.world.World;
import net.minecraft.world.WorldSavedData;
public class PhysisWorldSavedData extends WorldSavedData {
public static class WorldDataHandler {
@SubscribeEvent
public void onPlayerLogin(PlayerLoggedInEvent event) {
instance.sendDataToPlayer(event.player);
}
}
private static final String PLAYERDATATAG = "PlayerData";
private static final String WORLDDATATAG = "WorldData";
private static final String SERVERDATATAG = "ServerData";
private static final String UUIDTAG1 = "UUIDMost";
private static final String UUIDTAG2 = "UUIDLeast";
public static NBTTagCompound clientWorldData = new NBTTagCompound();
public static NBTTagCompound clientPlayerData = new NBTTagCompound();
private Map<UUID, NBTTagCompound> playerData;
private NBTTagCompound worldData;
private NBTTagCompound serverData;
public static PhysisWorldSavedData instance;
private static List<IDataCallback> callbacks = new ArrayList<IDataCallback>();
public PhysisWorldSavedData(String discard) {
this();
}
public PhysisWorldSavedData() {
super(Physis.MOD_ID);
playerData = new HashMap<UUID, NBTTagCompound>();
worldData = new NBTTagCompound();
serverData = new NBTTagCompound();
instance = this;
}
@Override
public void readFromNBT(NBTTagCompound tag) {
NBTTagList list = tag.getTagList(PLAYERDATATAG, 10);
for (int i=0; i<list.tagCount(); i++) {
NBTTagCompound data = list.getCompoundTagAt(i);
UUID uuid = new UUID(data.getLong(UUIDTAG1), data.getLong(UUIDTAG2));
playerData.put(uuid, data);
}
if(!tag.hasKey(WORLDDATATAG)) {
tag.setTag(WORLDDATATAG, new NBTTagCompound());
}
worldData = tag.getCompoundTag(WORLDDATATAG);
if(!tag.hasKey(SERVERDATATAG)) {
tag.setTag(SERVERDATATAG, new NBTTagCompound());
}
serverData = tag.getCompoundTag(SERVERDATATAG);
//Physis.logger.info("Read world data from NBT");
doCallbacksLoad();
}
@Override
public void writeToNBT(NBTTagCompound tag) {
doCallbacksSave();
NBTTagList list = new NBTTagList();
for (Entry<UUID, NBTTagCompound> entry : playerData.entrySet()) {
NBTTagCompound ptag = entry.getValue();
ptag.setLong(UUIDTAG1, entry.getKey().getMostSignificantBits());
ptag.setLong(UUIDTAG2, entry.getKey().getLeastSignificantBits());
list.appendTag(ptag);
}
tag.setTag(PLAYERDATATAG, list);
tag.setTag(WORLDDATATAG, worldData);
tag.setTag(SERVERDATATAG, serverData);
//Physis.logger.info("Saved world data to NBT");
}
private static NBTTagCompound getWorldData() {
if (FMLCommonHandler.instance().getEffectiveSide() == Side.CLIENT) {
return clientWorldData;
}
return instance.worldData;
}
private static NBTTagCompound getPlayerData(EntityPlayer player) {
return getPlayerData(player.getUniqueID());
}
private static NBTTagCompound getPlayerData(UUID uuid) {
if (FMLCommonHandler.instance().getEffectiveSide() == Side.CLIENT) {
if (uuid == Minecraft.getMinecraft().thePlayer.getUniqueID()) {
return clientPlayerData;
}
return null;
}
NBTTagCompound data = instance.playerData.get(uuid);
if (data == null) {
data = new NBTTagCompound();
instance.playerData.put(uuid, data);
}
return data;
}
public static void load(World world) {
instance = (PhysisWorldSavedData) world.loadItemData(PhysisWorldSavedData.class, Physis.MOD_ID);
if (instance == null) {
instance = new PhysisWorldSavedData();
world.setItemData(Physis.MOD_ID, instance);
}
//Physis.logger.info("Loaded server data");
}
public static void registerCallback(IDataCallback cb) {
if (!callbacks.contains(cb)) {
callbacks.add(cb);
}
}
public static void doCallbacksPre() {
for (IDataCallback cb : callbacks) {
cb.dataPacketSending();
}
}
public static void doCallbacksPost() {
for (IDataCallback cb : callbacks) {
cb.dataPacketReceived();
}
}
private static void doCallbacksSave() {
for (IDataCallback cb : callbacks) {
cb.dataSaving();
}
}
private static void doCallbacksLoad() {
for (IDataCallback cb : callbacks) {
cb.dataLoaded();
}
}
public static void safeMarkDirty() {
if (FMLCommonHandler.instance().getEffectiveSide() == Side.CLIENT) { return; }
instance.markDirty();
}
// network
public void sendDataToPlayer(EntityPlayer player) {
if (player instanceof EntityPlayerMP) {
PhysisPacketHandler.bus.sendTo(PacketWorldData.createPacket(getPlayerData(player), worldData), (EntityPlayerMP)player);
}
}
public static void safeSendDataToPlayer(EntityPlayer player) {
if (FMLCommonHandler.instance().getEffectiveSide() == Side.CLIENT) { return; }
instance.sendDataToPlayer(player);
}
// data getting/setting
// WORLD DATA
public static void setWorldInt(String name, int value) {
getWorldData().setInteger(name, value);
safeMarkDirty();
}
public static int getWorldInt(String name) {
return getWorldData().getInteger(name);
}
public static void setWorldTag(String name, NBTTagCompound tag) {
getWorldData().setTag(name, tag);
safeMarkDirty();
}
public static NBTTagCompound getWorldTag(String name) {
NBTTagCompound wd = getWorldData();
if (!wd.hasKey(name)) {
NBTTagCompound compound = new NBTTagCompound();
wd.setTag(name, compound);
return compound;
}
return getWorldData().getCompoundTag(name);
}
public static void setWorldLong(String name, long value) {
getWorldData().setLong(name, value);
safeMarkDirty();
}
public static long getWorldLong(String name) {
return getWorldData().getLong(name);
}
// SERVER-ONLY DATA
public static void setServerTag(String name, NBTTagCompound tag) {
if (FMLCommonHandler.instance().getEffectiveSide() == Side.CLIENT) { return; }
//Physis.logger.info("SERVER TAG SET: name: "+name+", tag: "+tag+", server data: "+instance.serverData);
instance.serverData.setTag(name, tag);
safeMarkDirty();
}
public static NBTTagCompound getServerTag(String name) {
if (FMLCommonHandler.instance().getEffectiveSide() == Side.CLIENT) { return null; }
if (!instance.serverData.hasKey(name)) {
NBTTagCompound compound = new NBTTagCompound();
instance.serverData.setTag(name, compound);
return compound;
}
return instance.serverData.getCompoundTag(name);
}
// PLAYER DATA
public static void setPlayerInt(EntityPlayer player, String name, int value) {
NBTTagCompound p = getPlayerData(player);
if (p != null) {
p.setInteger(name, value);
safeMarkDirty();
}
}
public static int getPlayerInt(EntityPlayer player, String name) {
NBTTagCompound p = getPlayerData(player);
if (p != null) {
return p.getInteger(name);
}
return 0;
}
public static void setPlayerTag(EntityPlayer player, String name, NBTTagCompound tag) {
NBTTagCompound p = getPlayerData(player);
if (p != null) {
getPlayerData(player).setTag(name, tag);
safeMarkDirty();
}
}
public static NBTTagCompound getPlayerTag(EntityPlayer player, String name) {
NBTTagCompound p = getPlayerData(player);
if (p != null) {
if (!p.hasKey(name)) {
p.setTag(name, new NBTTagCompound());
}
return p.getCompoundTag(name);
}
return null;
}
}