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; }
 | 
						public void setDescription(String value) { this.description = value; }
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	// FIELD: home
 | 
						// FIELD: home
 | 
				
			||||||
	private Location home;
 | 
						private LazyLocation home;
 | 
				
			||||||
	public void setHome(Location home) { this.home = home; }
 | 
						public void setHome(Location home) { this.home = new LazyLocation(home); }
 | 
				
			||||||
	public Location getHome() { confirmValidHome(); return home; }
 | 
					 | 
				
			||||||
	public boolean hasHome() { return this.getHome() != null; }
 | 
						public boolean hasHome() { return this.getHome() != null; }
 | 
				
			||||||
 | 
						public Location getHome()
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							confirmValidHome();
 | 
				
			||||||
 | 
							return (this.home != null) ? this.home.getLocation() : null;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	public void confirmValidHome()
 | 
						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;
 | 
								return;
 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		msg("<b>Your faction home has been un-set since it is no longer in your territory.");
 | 
							msg("<b>Your faction home has been un-set since it is no longer in your territory.");
 | 
				
			||||||
		this.home = null;
 | 
							this.home = null;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -37,6 +37,7 @@ import com.massivecraft.factions.struct.FFlag;
 | 
				
			|||||||
import com.massivecraft.factions.struct.FPerm;
 | 
					import com.massivecraft.factions.struct.FPerm;
 | 
				
			||||||
import com.massivecraft.factions.struct.Rel;
 | 
					import com.massivecraft.factions.struct.Rel;
 | 
				
			||||||
import com.massivecraft.factions.util.AutoLeaveTask;
 | 
					import com.massivecraft.factions.util.AutoLeaveTask;
 | 
				
			||||||
 | 
					import com.massivecraft.factions.util.LazyLocation;
 | 
				
			||||||
import com.massivecraft.factions.zcore.MPlugin;
 | 
					import com.massivecraft.factions.zcore.MPlugin;
 | 
				
			||||||
import com.massivecraft.factions.zcore.util.TextUtil;
 | 
					import com.massivecraft.factions.zcore.util.TextUtil;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -131,7 +132,7 @@ public class P extends MPlugin
 | 
				
			|||||||
		.setPrettyPrinting()
 | 
							.setPrettyPrinting()
 | 
				
			||||||
		.disableHtmlEscaping()
 | 
							.disableHtmlEscaping()
 | 
				
			||||||
		.excludeFieldsWithModifiers(Modifier.TRANSIENT, Modifier.VOLATILE)
 | 
							.excludeFieldsWithModifiers(Modifier.TRANSIENT, Modifier.VOLATILE)
 | 
				
			||||||
		.registerTypeAdapter(Location.class, new LocationTypeAdapter())
 | 
							.registerTypeAdapter(LazyLocation.class, new LocationTypeAdapter())
 | 
				
			||||||
		.registerTypeAdapter(mapFLocToStringSetType, new FLocToStringSetTypeAdapter())
 | 
							.registerTypeAdapter(mapFLocToStringSetType, new FLocToStringSetTypeAdapter())
 | 
				
			||||||
		.registerTypeAdapter(Rel.class, new RelTypeAdapter())
 | 
							.registerTypeAdapter(Rel.class, new RelTypeAdapter())
 | 
				
			||||||
		.registerTypeAdapter(FPerm.class, new FPermTypeAdapter())
 | 
							.registerTypeAdapter(FPerm.class, new FPermTypeAdapter())
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,8 +3,8 @@ package com.massivecraft.factions.adapters;
 | 
				
			|||||||
import java.lang.reflect.Type;
 | 
					import java.lang.reflect.Type;
 | 
				
			||||||
import java.util.logging.Level;
 | 
					import java.util.logging.Level;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import org.bukkit.Location;
 | 
					import com.massivecraft.factions.P;
 | 
				
			||||||
import org.bukkit.World;
 | 
					import com.massivecraft.factions.util.LazyLocation;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import com.google.gson.JsonDeserializationContext;
 | 
					import com.google.gson.JsonDeserializationContext;
 | 
				
			||||||
import com.google.gson.JsonDeserializer;
 | 
					import com.google.gson.JsonDeserializer;
 | 
				
			||||||
@@ -13,10 +13,9 @@ import com.google.gson.JsonObject;
 | 
				
			|||||||
import com.google.gson.JsonParseException;
 | 
					import com.google.gson.JsonParseException;
 | 
				
			||||||
import com.google.gson.JsonSerializationContext;
 | 
					import com.google.gson.JsonSerializationContext;
 | 
				
			||||||
import com.google.gson.JsonSerializer;
 | 
					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 WORLD = "world";
 | 
				
			||||||
	private static final String X = "x";
 | 
						private static final String X = "x";
 | 
				
			||||||
@@ -26,49 +25,37 @@ public class LocationTypeAdapter implements JsonDeserializer<Location>, JsonSeri
 | 
				
			|||||||
	private static final String PITCH = "pitch";
 | 
						private static final String PITCH = "pitch";
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	@Override
 | 
						@Override
 | 
				
			||||||
	public Location deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException
 | 
						public LazyLocation deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		try
 | 
							try
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			JsonObject obj = json.getAsJsonObject();
 | 
								JsonObject obj = json.getAsJsonObject();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			String worldname = obj.get(WORLD).getAsString();
 | 
								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;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			double x = obj.get(X).getAsDouble();
 | 
								double x = obj.get(X).getAsDouble();
 | 
				
			||||||
			double y = obj.get(Y).getAsDouble();
 | 
								double y = obj.get(Y).getAsDouble();
 | 
				
			||||||
			double z = obj.get(Z).getAsDouble();
 | 
								double z = obj.get(Z).getAsDouble();
 | 
				
			||||||
			float yaw = obj.get(YAW).getAsFloat();
 | 
								float yaw = obj.get(YAW).getAsFloat();
 | 
				
			||||||
			float pitch = obj.get(PITCH).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)
 | 
							catch (Exception ex)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			ex.printStackTrace();
 | 
								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;
 | 
								return null;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	@Override
 | 
						@Override
 | 
				
			||||||
	public JsonElement serialize(Location src, Type typeOfSrc, JsonSerializationContext context) {
 | 
						public JsonElement serialize(LazyLocation src, Type typeOfSrc, JsonSerializationContext context) {
 | 
				
			||||||
		JsonObject obj = new JsonObject();
 | 
							JsonObject obj = new JsonObject();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		try
 | 
							try
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			if (src.getWorld() == null)
 | 
								obj.addProperty(WORLD, src.getWorldName());
 | 
				
			||||||
			{
 | 
					 | 
				
			||||||
				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(X, src.getX());
 | 
								obj.addProperty(X, src.getX());
 | 
				
			||||||
			obj.addProperty(Y, src.getY());
 | 
								obj.addProperty(Y, src.getY());
 | 
				
			||||||
			obj.addProperty(Z, src.getZ());
 | 
								obj.addProperty(Z, src.getZ());
 | 
				
			||||||
@@ -76,12 +63,11 @@ public class LocationTypeAdapter implements JsonDeserializer<Location>, JsonSeri
 | 
				
			|||||||
			obj.addProperty(PITCH, src.getPitch());
 | 
								obj.addProperty(PITCH, src.getPitch());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			return obj;
 | 
								return obj;
 | 
				
			||||||
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		catch (Exception ex)
 | 
							catch (Exception ex)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			ex.printStackTrace();
 | 
								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;
 | 
								return obj;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -58,7 +58,7 @@ public class CmdHome extends FCommand
 | 
				
			|||||||
		
 | 
							
 | 
				
			||||||
		if ( ! myFaction.hasHome())
 | 
							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());
 | 
								fme.sendMessage(p.cmdBase.cmdSethome.getUseageTemplate());
 | 
				
			||||||
			return;
 | 
								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