Faction homes should no longer be lost if their target world isn't already loaded when Factions loads at server startup. This is done using a new lazy-load Location container class which only initializes the Location when it's actually needed.
This commit is contained in:
		@@ -65,16 +65,18 @@ public class Faction extends Entity implements EconomyParticipator
 | 
			
		||||
	public void setDescription(String value) { this.description = value; }
 | 
			
		||||
	
 | 
			
		||||
	// FIELD: home
 | 
			
		||||
	private Location home;
 | 
			
		||||
	public void setHome(Location home) { this.home = home; }
 | 
			
		||||
	public Location getHome() { confirmValidHome(); return home; }
 | 
			
		||||
	private LazyLocation home;
 | 
			
		||||
	public void setHome(Location home) { this.home = new LazyLocation(home); }
 | 
			
		||||
	public boolean hasHome() { return this.getHome() != null; }
 | 
			
		||||
	public Location getHome()
 | 
			
		||||
	{
 | 
			
		||||
		confirmValidHome();
 | 
			
		||||
		return (this.home != null) ? this.home.getLocation() : null;
 | 
			
		||||
	}
 | 
			
		||||
	public void confirmValidHome()
 | 
			
		||||
	{
 | 
			
		||||
		if (!Conf.homesMustBeInClaimedTerritory || this.home == null || Board.getFactionAt(new FLocation(this.home)) == this)
 | 
			
		||||
		{
 | 
			
		||||
		if (!Conf.homesMustBeInClaimedTerritory || this.home == null || Board.getFactionAt(new FLocation(this.home.getLocation())) == this)
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		msg("<b>Your faction home has been un-set since it is no longer in your territory.");
 | 
			
		||||
		this.home = null;
 | 
			
		||||
 
 | 
			
		||||
@@ -37,6 +37,7 @@ import com.massivecraft.factions.struct.FFlag;
 | 
			
		||||
import com.massivecraft.factions.struct.FPerm;
 | 
			
		||||
import com.massivecraft.factions.struct.Rel;
 | 
			
		||||
import com.massivecraft.factions.util.AutoLeaveTask;
 | 
			
		||||
import com.massivecraft.factions.util.LazyLocation;
 | 
			
		||||
import com.massivecraft.factions.zcore.MPlugin;
 | 
			
		||||
import com.massivecraft.factions.zcore.util.TextUtil;
 | 
			
		||||
 | 
			
		||||
@@ -131,7 +132,7 @@ public class P extends MPlugin
 | 
			
		||||
		.setPrettyPrinting()
 | 
			
		||||
		.disableHtmlEscaping()
 | 
			
		||||
		.excludeFieldsWithModifiers(Modifier.TRANSIENT, Modifier.VOLATILE)
 | 
			
		||||
		.registerTypeAdapter(Location.class, new LocationTypeAdapter())
 | 
			
		||||
		.registerTypeAdapter(LazyLocation.class, new LocationTypeAdapter())
 | 
			
		||||
		.registerTypeAdapter(mapFLocToStringSetType, new FLocToStringSetTypeAdapter())
 | 
			
		||||
		.registerTypeAdapter(Rel.class, new RelTypeAdapter())
 | 
			
		||||
		.registerTypeAdapter(FPerm.class, new FPermTypeAdapter())
 | 
			
		||||
 
 | 
			
		||||
@@ -3,8 +3,8 @@ package com.massivecraft.factions.adapters;
 | 
			
		||||
import java.lang.reflect.Type;
 | 
			
		||||
import java.util.logging.Level;
 | 
			
		||||
 | 
			
		||||
import org.bukkit.Location;
 | 
			
		||||
import org.bukkit.World;
 | 
			
		||||
import com.massivecraft.factions.P;
 | 
			
		||||
import com.massivecraft.factions.util.LazyLocation;
 | 
			
		||||
 | 
			
		||||
import com.google.gson.JsonDeserializationContext;
 | 
			
		||||
import com.google.gson.JsonDeserializer;
 | 
			
		||||
@@ -13,10 +13,9 @@ import com.google.gson.JsonObject;
 | 
			
		||||
import com.google.gson.JsonParseException;
 | 
			
		||||
import com.google.gson.JsonSerializationContext;
 | 
			
		||||
import com.google.gson.JsonSerializer;
 | 
			
		||||
import com.massivecraft.factions.P;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
public class LocationTypeAdapter implements JsonDeserializer<Location>, JsonSerializer<Location>
 | 
			
		||||
public class LocationTypeAdapter implements JsonDeserializer<LazyLocation>, JsonSerializer<LazyLocation>
 | 
			
		||||
{
 | 
			
		||||
	private static final String WORLD = "world";
 | 
			
		||||
	private static final String X = "x";
 | 
			
		||||
@@ -26,49 +25,37 @@ public class LocationTypeAdapter implements JsonDeserializer<Location>, JsonSeri
 | 
			
		||||
	private static final String PITCH = "pitch";
 | 
			
		||||
	
 | 
			
		||||
	@Override
 | 
			
		||||
	public Location deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException
 | 
			
		||||
	public LazyLocation deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException
 | 
			
		||||
	{
 | 
			
		||||
		try
 | 
			
		||||
		{
 | 
			
		||||
			JsonObject obj = json.getAsJsonObject();
 | 
			
		||||
 | 
			
		||||
			String worldname = obj.get(WORLD).getAsString();
 | 
			
		||||
			World world = P.p.getServer().getWorld(worldname);
 | 
			
		||||
			if (world == null) {
 | 
			
		||||
				P.p.log(Level.WARNING, "Stored location's world \"" + worldname + "\" not found on server; dropping the location.");
 | 
			
		||||
				return null;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			String worldName = obj.get(WORLD).getAsString();
 | 
			
		||||
			double x = obj.get(X).getAsDouble();
 | 
			
		||||
			double y = obj.get(Y).getAsDouble();
 | 
			
		||||
			double z = obj.get(Z).getAsDouble();
 | 
			
		||||
			float yaw = obj.get(YAW).getAsFloat();
 | 
			
		||||
			float pitch = obj.get(PITCH).getAsFloat();
 | 
			
		||||
 | 
			
		||||
			return new Location(world, x, y, z, yaw, pitch);
 | 
			
		||||
			return new LazyLocation(worldName, x, y, z, yaw, pitch);
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
		catch (Exception ex)
 | 
			
		||||
		{
 | 
			
		||||
			ex.printStackTrace();
 | 
			
		||||
			P.p.log(Level.WARNING, "Error encountered while deserializing a location.");
 | 
			
		||||
			P.p.log(Level.WARNING, "Error encountered while deserializing a LazyLocation.");
 | 
			
		||||
			return null;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public JsonElement serialize(Location src, Type typeOfSrc, JsonSerializationContext context) {
 | 
			
		||||
	public JsonElement serialize(LazyLocation src, Type typeOfSrc, JsonSerializationContext context) {
 | 
			
		||||
		JsonObject obj = new JsonObject();
 | 
			
		||||
 | 
			
		||||
		try
 | 
			
		||||
		{
 | 
			
		||||
			if (src.getWorld() == null)
 | 
			
		||||
			{
 | 
			
		||||
				P.p.log(Level.WARNING, "Passed location's world was not found on the server. Dropping the location.");
 | 
			
		||||
				return obj;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			obj.addProperty(WORLD, src.getWorld().getName());
 | 
			
		||||
			obj.addProperty(WORLD, src.getWorldName());
 | 
			
		||||
			obj.addProperty(X, src.getX());
 | 
			
		||||
			obj.addProperty(Y, src.getY());
 | 
			
		||||
			obj.addProperty(Z, src.getZ());
 | 
			
		||||
@@ -76,12 +63,11 @@ public class LocationTypeAdapter implements JsonDeserializer<Location>, JsonSeri
 | 
			
		||||
			obj.addProperty(PITCH, src.getPitch());
 | 
			
		||||
 | 
			
		||||
			return obj;
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
		catch (Exception ex)
 | 
			
		||||
		{
 | 
			
		||||
			ex.printStackTrace();
 | 
			
		||||
			P.p.log(Level.WARNING, "Error encountered while serializing a location.");
 | 
			
		||||
			P.p.log(Level.WARNING, "Error encountered while serializing a LazyLocation.");
 | 
			
		||||
			return obj;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -58,7 +58,7 @@ public class CmdHome extends FCommand
 | 
			
		||||
		
 | 
			
		||||
		if ( ! myFaction.hasHome())
 | 
			
		||||
		{
 | 
			
		||||
			fme.msg("<b>You faction does not have a home. " + (fme.getRole().isLessThan(Rel.OFFICER) ? "<i> Ask your leader to:" : "<i>You should:"));
 | 
			
		||||
			fme.msg("<b>Your faction does not have a home. " + (fme.getRole().isLessThan(Rel.OFFICER) ? "<i> Ask your leader to:" : "<i>You should:"));
 | 
			
		||||
			fme.sendMessage(p.cmdBase.cmdSethome.getUseageTemplate());
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										107
									
								
								src/com/massivecraft/factions/util/LazyLocation.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										107
									
								
								src/com/massivecraft/factions/util/LazyLocation.java
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,107 @@
 | 
			
		||||
package com.massivecraft.factions.util;
 | 
			
		||||
 | 
			
		||||
import org.bukkit.Bukkit;
 | 
			
		||||
import org.bukkit.Location;
 | 
			
		||||
import org.bukkit.World;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * This class provides a lazy-load Location, so that World doesn't need to be initialized
 | 
			
		||||
 * yet when an object of this class is created, only when the Location is first accessed.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
public class LazyLocation
 | 
			
		||||
{
 | 
			
		||||
	private Location location = null;
 | 
			
		||||
	private String worldName;
 | 
			
		||||
	private double x;
 | 
			
		||||
	private double y;
 | 
			
		||||
	private double z;
 | 
			
		||||
	private float pitch;
 | 
			
		||||
	private float yaw;
 | 
			
		||||
 | 
			
		||||
	public LazyLocation(Location loc)
 | 
			
		||||
	{
 | 
			
		||||
		setLocation(loc);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public LazyLocation(final String worldName, final double x, final double y, final double z)
 | 
			
		||||
	{
 | 
			
		||||
		this(worldName, x, y, z, 0, 0);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public LazyLocation(final String worldName, final double x, final double y, final double z, final float yaw, final float pitch)
 | 
			
		||||
	{
 | 
			
		||||
		this.worldName = worldName;
 | 
			
		||||
		this.x = x;
 | 
			
		||||
		this.y = y;
 | 
			
		||||
		this.z = z;
 | 
			
		||||
		this.yaw = yaw;
 | 
			
		||||
		this.pitch = pitch;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// This returns the actual Location
 | 
			
		||||
	public final Location getLocation()
 | 
			
		||||
	{
 | 
			
		||||
		// make sure Location is initialized before returning it
 | 
			
		||||
		initLocation();
 | 
			
		||||
		return location;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// change the Location
 | 
			
		||||
	public final void setLocation(Location loc)
 | 
			
		||||
	{
 | 
			
		||||
		this.location = loc;
 | 
			
		||||
		this.worldName = loc.getWorld().getName();
 | 
			
		||||
		this.x = loc.getX();
 | 
			
		||||
		this.y = loc.getY();
 | 
			
		||||
		this.z = loc.getZ();
 | 
			
		||||
		this.yaw = loc.getYaw();
 | 
			
		||||
		this.pitch = loc.getPitch();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	// This initializes the Location
 | 
			
		||||
	private void initLocation()
 | 
			
		||||
	{
 | 
			
		||||
		// if location is already initialized, simply return
 | 
			
		||||
		if (location != null) return;
 | 
			
		||||
 | 
			
		||||
		// get World; hopefully it's initialized at this point
 | 
			
		||||
		World world = Bukkit.getWorld(worldName);
 | 
			
		||||
		if (world == null) return;
 | 
			
		||||
 | 
			
		||||
		// store the Location for future calls, and pass it on
 | 
			
		||||
		location = new Location(world, x, y, z, yaw, pitch);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	public final String getWorldName()
 | 
			
		||||
	{
 | 
			
		||||
		return worldName;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public final double getX()
 | 
			
		||||
	{
 | 
			
		||||
		return x;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public final double getY()
 | 
			
		||||
	{
 | 
			
		||||
		return y;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public final double getZ()
 | 
			
		||||
	{
 | 
			
		||||
		return z;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public final double getPitch()
 | 
			
		||||
	{
 | 
			
		||||
		return pitch;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	public final double getYaw()
 | 
			
		||||
	{
 | 
			
		||||
		return yaw;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user