Avoid PlayerPreLogin event, PS improvements and Store improvements.

This commit is contained in:
Olof Larsson 2012-09-08 12:16:41 +02:00
parent 14756e79fd
commit 3c9a0a4640
10 changed files with 314 additions and 103 deletions

View File

@ -5,10 +5,13 @@ import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority; import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerPreLoginEvent; import org.bukkit.event.player.PlayerLoginEvent;
import com.massivecraft.mcore4.persist.IClassManager; import com.massivecraft.mcore4.persist.IClassManager;
import com.massivecraft.mcore4.persist.Persist; import com.massivecraft.mcore4.persist.Persist;
import com.massivecraft.mcore4.store.Coll;
import com.massivecraft.mcore4.store.ModificationState;
import com.massivecraft.mcore4.store.PlayerColl;
public class InternalListener implements Listener public class InternalListener implements Listener
{ {
@ -21,10 +24,10 @@ public class InternalListener implements Listener
} }
// TODO: Does this even trigger? If not we have an issue. // TODO: Does this even trigger? If not we have an issue.
@EventHandler(priority = EventPriority.LOWEST) @EventHandler(priority = EventPriority.LOW)
public void onPlayerPreLogin(PlayerPreLoginEvent event) public void onPlayerPreLogin(PlayerLoginEvent event)
{ {
String id = event.getName(); String id = event.getPlayer().getName();
for (Persist instance : Persist.instances) for (Persist instance : Persist.instances)
{ {
@ -36,4 +39,22 @@ public class InternalListener implements Listener
} }
} }
} }
/**
* We sync the player in all player collections at PlayerLoginEvent LOW. LOWEST is left for anti flood and bans.
* The syncs are not to heavy to do and other events can rest assure the data is up to date.
*/
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void syncPlayerEntities(PlayerLoginEvent event)
{
String playerName = event.getPlayer().getName();
for (Coll<?, ?> coll : Coll.instances)
{
if (!(coll instanceof PlayerColl)) continue;
PlayerColl<?> pcoll = (PlayerColl<?>)coll;
ModificationState mstate = pcoll.syncId(playerName);
p.log("syncPlayerEntities", coll.name(), playerName, mstate);
}
}
} }

View File

@ -14,6 +14,7 @@ import com.massivecraft.mcore4.persist.Persist;
import com.massivecraft.mcore4.store.Coll; import com.massivecraft.mcore4.store.Coll;
import com.massivecraft.mcore4.store.Db; import com.massivecraft.mcore4.store.Db;
import com.massivecraft.mcore4.store.MStore; import com.massivecraft.mcore4.store.MStore;
import com.massivecraft.mcore4.store.USelColl;
import com.massivecraft.mcore4.util.PlayerUtil; import com.massivecraft.mcore4.util.PlayerUtil;
import com.massivecraft.mcore4.xlib.gson.Gson; import com.massivecraft.mcore4.xlib.gson.Gson;
import com.massivecraft.mcore4.xlib.gson.GsonBuilder; import com.massivecraft.mcore4.xlib.gson.GsonBuilder;
@ -68,6 +69,8 @@ public class MCore extends MPlugin
} }
}; };
public InternalListener internalListener;
@Override @Override
public void onEnable() public void onEnable()
{ {
@ -87,11 +90,14 @@ public class MCore extends MPlugin
new PlayerUtil(this); new PlayerUtil(this);
// Register events // Register events
new InternalListener(this); this.internalListener = new InternalListener(this);
// Schedule the collection ticker. // Schedule the collection ticker.
Bukkit.getScheduler().scheduleSyncRepeatingTask(this, this.collTickTask, 1, 1); Bukkit.getScheduler().scheduleSyncRepeatingTask(this, this.collTickTask, 1, 1);
// Init internal collections
USelColl.i.init();
this.postEnable(); this.postEnable();
} }

View File

@ -5,6 +5,8 @@ import org.bukkit.Chunk;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.util.Vector;
import com.massivecraft.mcore4.store.accessor.Accessor; import com.massivecraft.mcore4.store.accessor.Accessor;
import com.massivecraft.mcore4.xlib.gson.annotations.SerializedName; import com.massivecraft.mcore4.xlib.gson.annotations.SerializedName;
@ -16,7 +18,7 @@ import com.massivecraft.mcore4.xlib.gson.annotations.SerializedName;
* Another time you may want to store the player location but without the worldName info. * Another time you may want to store the player location but without the worldName info.
* Another time you may want to store pitch and yaw only. * Another time you may want to store pitch and yaw only.
* This class is supposed to be usable in all those cases. * This class is supposed to be usable in all those cases.
* Hopefully this class will save you from implementing special classes for all those compinations. * Hopefully this class will save you from implementing special classes for all those combinations.
*/ */
public class PS implements Cloneable public class PS implements Cloneable
{ {
@ -31,7 +33,11 @@ public class PS implements Cloneable
public void worldName(String val) { this.worldName = val; } public void worldName(String val) { this.worldName = val; }
// FakeField: world // FakeField: world
public World world() { return Bukkit.getWorld(this.worldName); } public World world()
{
if (this.worldName == null) return null;
return Bukkit.getWorld(this.worldName);
}
public PS world(World val) { this.worldName = val.getName(); return this; } public PS world(World val) { this.worldName = val.getName(); return this; }
// --------------------- // ---------------------
@ -149,7 +155,12 @@ public class PS implements Cloneable
// Field: pitch // Field: pitch
@SerializedName("p") @SerializedName("p")
protected Float pitch; protected Float pitch;
public PS pitch(Float val) { this.pitch = val; return this; } public PS pitch(Float val)
{
if (val == null) this.pitch = null;
this.pitch = (val + 360F) % 360F;
return this;
}
public Float pitch() { return this.pitch; } public Float pitch() { return this.pitch; }
// Field: yaw // Field: yaw
@ -160,39 +171,63 @@ public class PS implements Cloneable
// --------------------- // ---------------------
// Field: motionX // Field: velocityX
@SerializedName("mx") @SerializedName("vx")
protected Double motionX; protected Double velocityX;
public PS motionX(Double val) { this.motionX = val; return this; } public PS velocityX(Double val) { this.velocityX = val; return this; }
public Double motionX() { return this.motionX; } public Double velocityX() { return this.velocityX; }
public Double velocityXCalc()
{
return velocityCalc(this.locationX, this.blockX, this.chunkX, this.velocityX);
}
// Field: motionY // Field: velocityY
@SerializedName("my") @SerializedName("vy")
protected Double motionY; protected Double velocityY;
public PS motionY(Double val) { this.motionY = val; return this; } public PS velocityY(Double val) { this.velocityY = val; return this; }
public Double motionY() { return this.motionY; } public Double velocityY() { return this.velocityY; }
public Double velocityYCalc()
{
return velocityCalc(this.locationY, this.blockY, 0, this.velocityY);
}
// Field: motionZ // Field: velocityZ
@SerializedName("mz") @SerializedName("vz")
protected Double motionZ; protected Double velocityZ;
public PS motionZ(Double val) { this.motionZ = val; return this; } public PS velocityZ(Double val) { this.velocityZ = val; return this; }
public Double motionZ() { return this.motionZ; } public Double velocityZ() { return this.velocityZ; }
public Double velocityZCalc()
{
return velocityCalc(this.locationZ, this.blockZ, this.chunkZ, this.velocityZ);
}
protected static synchronized Double velocityCalc(Double location, Integer block, Integer chunk, Double velocity)
{
if (velocity != null) return velocity;
if (location != null) return location;
if (block != null) return (double) block;
if (chunk != null) return chunk * 16D;
return null;
}
//----------------------------------------------// //----------------------------------------------//
// CONVERTERS // CONVERTERS
//----------------------------------------------// //----------------------------------------------//
public synchronized Location asLocation() public synchronized Location location()
{
return this.locationInner(this.locationX(), this.locationY(), this.locationZ());
}
public synchronized Location locationCalc()
{
return this.locationInner(this.locationXCalc(), this.locationYCalc(), this.locationZCalc());
}
protected synchronized Location locationInner(Double x, Double y, Double z)
{ {
World world = this.world(); World world = this.world();
Double x = this.locationXCalc();
if (x == null) return null; if (x == null) return null;
Double y = this.locationYCalc();
if (y == null) return null; if (y == null) return null;
Double z = this.locationZCalc();
if (z == null) return null; if (z == null) return null;
Float pitch = this.pitch(); Float pitch = this.pitch();
@ -204,42 +239,66 @@ public class PS implements Cloneable
return new Location(world, x, y, z, pitch, yaw); return new Location(world, x, y, z, pitch, yaw);
} }
public synchronized Block asBlock() public synchronized Block block()
{
return this.blockInner(this.blockX(), this.blockY(), this.blockZ());
}
public synchronized Block blockCalc()
{
return this.blockInner(this.blockXCalc(), this.blockYCalc(), this.blockZCalc());
}
public synchronized Block blockInner(Integer x, Integer y, Integer z)
{ {
World world = this.world(); World world = this.world();
if (world == null) return null; if (world == null) return null;
Integer x = this.blockXCalc();
if (x == null) return null; if (x == null) return null;
Integer y = this.blockYCalc();
if (y == null) return null; if (y == null) return null;
Integer z = this.blockZCalc();
if (z == null) return null; if (z == null) return null;
return world.getBlockAt(x, y, z); return world.getBlockAt(x, y, z);
} }
public synchronized Chunk asChunk() public synchronized Chunk chunk()
{
return this.chunkInner(this.chunkX(), this.chunkZ());
}
public synchronized Chunk chunkCalc()
{
return this.chunkInner(this.chunkXCalc(), this.chunkZCalc());
}
public synchronized Chunk chunkInner(Integer x, Integer z)
{ {
World world = this.world(); World world = this.world();
if (world == null) return null; if (world == null) return null;
Integer x = this.chunkXCalc();
if (x == null) return null; if (x == null) return null;
Integer z = this.chunkZCalc();
if (z == null) return null; if (z == null) return null;
return world.getChunkAt(x, z); return world.getChunkAt(x, z);
} }
public synchronized Vector velocity()
{
return this.velocityInner(this.velocityX(), this.velocityY(), this.velocityZ());
}
public synchronized Vector velocityCalc()
{
return this.velocityInner(this.velocityXCalc(), this.velocityYCalc(), this.velocityZCalc());
}
public synchronized Vector velocityInner(Double x, Double y, Double z)
{
if (x == null) return null;
if (y == null) return null;
if (z == null) return null;
return new Vector(x, y, z);
}
//----------------------------------------------// //----------------------------------------------//
// LOADERS // READERS
//----------------------------------------------// //----------------------------------------------//
public synchronized PS loadDefault() public synchronized PS readDefault()
{ {
this.worldName = null; this.worldName = null;
@ -257,20 +316,20 @@ public class PS implements Cloneable
this.pitch = null; this.pitch = null;
this.yaw = null; this.yaw = null;
this.motionX = null; this.velocityX = null;
this.motionY = null; this.velocityY = null;
this.motionZ = null; this.velocityZ = null;
return this; return this;
} }
public synchronized PS loadTransparent(PS ps) public synchronized PS readTransparent(PS ps)
{ {
Accessor.get(PS.class).copy(ps, this, true); Accessor.get(PS.class).copy(ps, this, true);
return this; return this;
} }
public synchronized PS load(PS ps) public synchronized PS read(PS ps)
{ {
Accessor.get(PS.class).copy(ps, this); Accessor.get(PS.class).copy(ps, this);
return this; return this;
@ -278,18 +337,18 @@ public class PS implements Cloneable
// --------------------- // ---------------------
public synchronized PS load(Location location) public synchronized PS read(Location location)
{ {
return this.loadDefault().loadTransparent(location); return this.readDefault().readTransparent(location);
} }
public synchronized PS loadTransparent(Location location) public synchronized PS readTransparent(Location location)
{ {
this.worldName = location.getWorld().getName(); this.worldName = location.getWorld().getName();
this.locationX = location.getX(); this.locationX = location.getX();
this.locationY = location.getY(); this.locationY = location.getY();
this.locationZ = location.getZ(); this.locationZ = location.getZ();
this.pitch = location.getPitch(); this.pitch(location.getPitch());
this.yaw = location.getYaw(); this.yaw = location.getYaw();
return this; return this;
@ -297,12 +356,42 @@ public class PS implements Cloneable
// --------------------- // ---------------------
public synchronized PS load(Block block) public synchronized PS read(Vector vector)
{ {
return this.loadDefault().loadTransparent(block); return this.readDefault().readTransparent(vector);
} }
public synchronized PS loadTransparent(Block block) public synchronized PS readTransparent(Vector vector)
{
this.velocityX = vector.getX();
this.velocityY = vector.getY();
this.velocityZ = vector.getZ();
return this;
}
// ---------------------
public synchronized PS read(Player player)
{
return this.readDefault().readTransparent(player);
}
public synchronized PS readTransparent(Player player)
{
this.readTransparent(player.getLocation());
this.readTransparent(player.getVelocity());
return this;
}
// ---------------------
public synchronized PS read(Block block)
{
return this.readDefault().readTransparent(block);
}
public synchronized PS readTransparent(Block block)
{ {
this.worldName = block.getWorld().getName(); this.worldName = block.getWorld().getName();
this.blockX = block.getX(); this.blockX = block.getX();
@ -313,12 +402,12 @@ public class PS implements Cloneable
// --------------------- // ---------------------
public synchronized PS load(Chunk chunk) public synchronized PS read(Chunk chunk)
{ {
return this.loadDefault().loadTransparent(chunk); return this.readDefault().readTransparent(chunk);
} }
public synchronized PS loadTransparent(Chunk chunk) public synchronized PS readTransparent(Chunk chunk)
{ {
this.worldName = chunk.getWorld().getName(); this.worldName = chunk.getWorld().getName();
this.chunkX = chunk.getX(); this.chunkX = chunk.getX();
@ -326,6 +415,19 @@ public class PS implements Cloneable
return this; return this;
} }
//----------------------------------------------//
// WRITERS
//----------------------------------------------//
public synchronized void write(Player player)
{
Location location = this.locationCalc();
if (location != null) player.teleport(location);
Vector velocity = this.velocity();
if (velocity != null) player.setVelocity(velocity);
}
//----------------------------------------------// //----------------------------------------------//
// CONSTRUCTORS // CONSTRUCTORS
//----------------------------------------------// //----------------------------------------------//
@ -337,7 +439,32 @@ public class PS implements Cloneable
public PS(PS ps) public PS(PS ps)
{ {
this.load(ps); this.read(ps);
}
public PS(Location location)
{
this.read(location);
}
public PS(Vector vector)
{
this.read(vector);
}
public PS(Player player)
{
this.read(player);
}
public PS(Block block)
{
this.read(block);
}
public PS(Chunk chunk)
{
this.read(chunk);
} }
//----------------------------------------------// //----------------------------------------------//
@ -378,9 +505,9 @@ public class PS implements Cloneable
result = prime * result + ((locationX == null) ? 0 : locationX.hashCode()); result = prime * result + ((locationX == null) ? 0 : locationX.hashCode());
result = prime * result + ((locationY == null) ? 0 : locationY.hashCode()); result = prime * result + ((locationY == null) ? 0 : locationY.hashCode());
result = prime * result + ((locationZ == null) ? 0 : locationZ.hashCode()); result = prime * result + ((locationZ == null) ? 0 : locationZ.hashCode());
result = prime * result + ((motionX == null) ? 0 : motionX.hashCode()); result = prime * result + ((velocityX == null) ? 0 : velocityX.hashCode());
result = prime * result + ((motionY == null) ? 0 : motionY.hashCode()); result = prime * result + ((velocityY == null) ? 0 : velocityY.hashCode());
result = prime * result + ((motionZ == null) ? 0 : motionZ.hashCode()); result = prime * result + ((velocityZ == null) ? 0 : velocityZ.hashCode());
result = prime * result + ((pitch == null) ? 0 : pitch.hashCode()); result = prime * result + ((pitch == null) ? 0 : pitch.hashCode());
result = prime * result + ((worldName == null) ? 0 : worldName.hashCode()); result = prime * result + ((worldName == null) ? 0 : worldName.hashCode());
result = prime * result + ((yaw == null) ? 0 : yaw.hashCode()); result = prime * result + ((yaw == null) ? 0 : yaw.hashCode());
@ -434,21 +561,21 @@ public class PS implements Cloneable
if (other.locationZ != null) return false; if (other.locationZ != null) return false;
} }
else if (!locationZ.equals(other.locationZ)) return false; else if (!locationZ.equals(other.locationZ)) return false;
if (motionX == null) if (velocityX == null)
{ {
if (other.motionX != null) return false; if (other.velocityX != null) return false;
} }
else if (!motionX.equals(other.motionX)) return false; else if (!velocityX.equals(other.velocityX)) return false;
if (motionY == null) if (velocityY == null)
{ {
if (other.motionY != null) return false; if (other.velocityY != null) return false;
} }
else if (!motionY.equals(other.motionY)) return false; else if (!velocityY.equals(other.velocityY)) return false;
if (motionZ == null) if (velocityZ == null)
{ {
if (other.motionZ != null) return false; if (other.velocityZ != null) return false;
} }
else if (!motionZ.equals(other.motionZ)) return false; else if (!velocityZ.equals(other.velocityZ)) return false;
if (pitch == null) if (pitch == null)
{ {
if (other.pitch != null) return false; if (other.pitch != null) return false;

View File

@ -33,8 +33,8 @@ public class Coll<E, L> implements CollInterface<E, L>
protected final String name; protected final String name;
@Override public String name() { return this.name; } @Override public String name() { return this.name; }
protected final String nameBase; protected final String nameContext;
@Override public String nameBase() { return this.nameBase; } @Override public String nameContext() { return this.nameContext; }
protected final String nameUniverse; protected final String nameUniverse;
@Override public String nameUniverse() { return this.nameUniverse; } @Override public String nameUniverse() { return this.nameUniverse; }
@ -436,7 +436,7 @@ public class Coll<E, L> implements CollInterface<E, L>
} }
@Override @Override
public void syncId(L id) public ModificationState syncId(L id)
{ {
ModificationState mstate = this.examineId(id); ModificationState mstate = this.examineId(id);
@ -462,6 +462,8 @@ public class Coll<E, L> implements CollInterface<E, L>
this.clearIdentifiedChanges(id); this.clearIdentifiedChanges(id);
break; break;
} }
return mstate;
} }
@Override @Override
@ -534,7 +536,7 @@ public class Coll<E, L> implements CollInterface<E, L>
// Setup the name and the parsed parts // Setup the name and the parsed parts
this.name = name; this.name = name;
String[] nameParts = this.name.split("\\@"); String[] nameParts = this.name.split("\\@");
this.nameBase = nameParts[0]; this.nameContext = nameParts[0];
if (nameParts.length > 1) if (nameParts.length > 1)
{ {
this.nameUniverse = nameParts[1]; this.nameUniverse = nameParts[1];

View File

@ -15,7 +15,7 @@ public interface CollInterface<E, L>
// WHAT DO WE HANDLE? // WHAT DO WE HANDLE?
// -------------------------------------------- // // -------------------------------------------- //
public String name(); public String name();
public String nameBase(); public String nameContext();
public String nameUniverse(); public String nameUniverse();
public Class<E> entityClass(); public Class<E> entityClass();
public Class<L> idClass(); public Class<L> idClass();
@ -121,7 +121,7 @@ public interface CollInterface<E, L>
public ModificationState examineId(L id); public ModificationState examineId(L id);
public ModificationState examineId(L id, Long remoteMtime); public ModificationState examineId(L id, Long remoteMtime);
public void syncId(L id); public ModificationState syncId(L id);
public void syncSuspects(); public void syncSuspects();
public void syncAll(); public void syncAll();
public void findSuspects(); public void findSuspects();

View File

@ -13,12 +13,63 @@ public abstract class Colls<C extends Coll<E, L>, E, L>
public abstract String getContext(); public abstract String getContext();
public abstract Db<?> getDb();
// -------------------------------------------- //
// CONSTRUCT
// -------------------------------------------- //
public void init()
{
String start = this.collnameStart();
for (String collname : this.getDb().collnames())
{
if ( ! collname.startsWith(start)) continue;
this.getForCollname(collname);
}
}
// -------------------------------------------- //
// UTIL
// -------------------------------------------- //
public String collnameStart()
{
return this.getContext() + "@";
}
public String universeFromWorldName(String worldName) public String universeFromWorldName(String worldName)
{ {
USel selector = USelColl.i.get(this.getContext()); USel selector = USelColl.i.get(this.getContext());
return selector.select(worldName); return selector.select(worldName);
} }
// -------------------------------------------- //
// GET
// -------------------------------------------- //
public C getForWorld(String worldName)
{
return this.getForUniverse(this.universeFromWorldName(worldName));
}
public C getForUniverse(String universe)
{
String collname = this.collnameStart() + universe;
return this.getForCollname(collname);
}
public C getForCollname(String collname)
{
C ret = this.name2coll.get(collname);
if (ret == null)
{
ret = this.createColl(collname);
this.name2coll.put(collname, ret);
}
return ret;
}
public C get(Object worldNameExtractable) public C get(Object worldNameExtractable)
{ {
String worldName = MUtil.extract(String.class, "worldName", worldNameExtractable); String worldName = MUtil.extract(String.class, "worldName", worldNameExtractable);
@ -31,23 +82,4 @@ public abstract class Colls<C extends Coll<E, L>, E, L>
if (coll == null) return null; if (coll == null) return null;
return coll.get(worldNameExtractable); return coll.get(worldNameExtractable);
} }
public C getForWorld(String worldName)
{
return this.getForUniverse(this.universeFromWorldName(worldName));
}
public C getForUniverse(String universe)
{
String collName = this.getContext() + "@" + universe;
C ret = this.name2coll.get(collName);
if (ret == null)
{
ret = this.createColl(collName);
this.name2coll.put(collName, ret);
}
return ret;
}
} }

View File

@ -72,12 +72,11 @@ public abstract class Entity<E extends Entity<E, L>, L>
this.getColl().changedIds.add(id); this.getColl().changedIds.add(id);
} }
public void sync() public ModificationState sync()
{ {
L id = this.getId(); L id = this.getId();
if (id == null) return; if (id == null) return ModificationState.UNKNOWN;
return this.getColl().syncId(id);
this.getColl().syncId(id);
} }
public void saveToRemote() public void saveToRemote()
@ -112,9 +111,9 @@ public abstract class Entity<E extends Entity<E, L>, L>
return this.getThis(); return this.getThis();
} }
public E load(E entity) public E load(E that)
{ {
Accessor.get(this.getClazz()).copy(entity, this.getThis()); Accessor.get(this.getClazz()).copy(that, this.getThis());
return this.getThis(); return this.getThis();
} }
} }

View File

@ -26,6 +26,26 @@ public abstract class PlayerEntity<E extends PlayerEntity<E>> extends Entity<E,
return ! isOnline(); return ! isOnline();
} }
public String getCurrentUniverse()
{
Player player = this.getPlayer();
if (player == null) return null;
String context = this.getColl().nameContext();
return USelColl.i.get(context).select(player.getWorld().getName());
}
public boolean isInThisUniverse()
{
String universe = this.getUniverse();
if (universe == null) return false;
String currentUniverse = this.getCurrentUniverse();
if (currentUniverse == null) return false;
return universe.equals(currentUniverse);
}
// -------------------------------------------- // // -------------------------------------------- //
// CHECKER UTILS // CHECKER UTILS
// -------------------------------------------- // // -------------------------------------------- //

View File

@ -66,6 +66,7 @@ public class USel extends Entity<USel, String>
public String select(String worldName) public String select(String worldName)
{ {
if (worldName == null) return null;
for (USelRule rule : this.rules()) for (USelRule rule : this.rules())
{ {
String name = rule.name(); String name = rule.name();

View File

@ -28,8 +28,11 @@ public class USelColl extends Coll<USel, String>
super.init(); super.init();
// Ensure the default WorldCategorizer is present. // Ensure the default WorldCategorizer is present.
USel d = this.get(USel._DEFAULT); if ( ! this.ids().contains(USel._DEFAULT))
d.rules(USel.DEFAULT_DEFAULT_RULES); {
USel d = this.get(USel._DEFAULT);
d.rules(USel.DEFAULT_DEFAULT_RULES);
}
} }
@Override @Override