Moved Faction entity to useage of MStore as well.

This commit is contained in:
Olof Larsson
2013-04-12 09:47:43 +02:00
parent 76f3f044ca
commit 3036b0a157
24 changed files with 265 additions and 904 deletions

View File

@@ -6,8 +6,6 @@ import java.util.logging.Level;
import org.bukkit.Bukkit;
import org.bukkit.plugin.java.JavaPlugin;
import com.massivecraft.factions.zcore.persist.EM;
import com.massivecraft.factions.zcore.persist.SaveTask;
import com.massivecraft.mcore.util.Txt;
import com.massivecraft.mcore.xlib.gson.Gson;
import com.massivecraft.mcore.xlib.gson.GsonBuilder;
@@ -17,14 +15,6 @@ public abstract class MPlugin extends JavaPlugin
{
// Persist related
public Gson gson;
private Integer saveTask = null;
private boolean autoSave = true;
protected boolean loadSuccessful = false;
public boolean getAutoSave() {return this.autoSave;}
public void setAutoSave(boolean val) {this.autoSave = val;}
// Listeners
public MPluginSecretPlayerListener mPluginSecretPlayerListener;
// -------------------------------------------- //
// ENABLE
@@ -39,18 +29,7 @@ public abstract class MPlugin extends JavaPlugin
this.getDataFolder().mkdirs();
this.gson = this.getGsonBuilder().create();
// Create and register listeners
this.mPluginSecretPlayerListener = new MPluginSecretPlayerListener(this);
// Register recurring tasks
long saveTicks = 20 * 60 * 30; // Approximately every 30 min
if (saveTask == null)
{
saveTask = Bukkit.getServer().getScheduler().scheduleSyncRepeatingTask(this, new SaveTask(this), saveTicks, saveTicks);
}
loadSuccessful = true;
return true;
}
@@ -61,14 +40,6 @@ public abstract class MPlugin extends JavaPlugin
public void onDisable()
{
if (saveTask != null)
{
this.getServer().getScheduler().cancelTask(saveTask);
saveTask = null;
}
// only save data if plugin actually loaded successfully
if (loadSuccessful)
EM.saveAllToDisc();
log("Disabled");
}
@@ -93,56 +64,6 @@ public abstract class MPlugin extends JavaPlugin
.excludeFieldsWithModifiers(Modifier.TRANSIENT, Modifier.VOLATILE);
}
// -------------------------------------------- //
// LANG AND TAGS
// -------------------------------------------- //
/*
// These are not supposed to be used directly.
// They are loaded and used through the TextUtil instance for the plugin.
public Map<String, String> rawTags = new LinkedHashMap<String, String>();
public void addRawTags()
{
this.rawTags.put("l", "<green>"); // logo
this.rawTags.put("a", "<gold>"); // art
this.rawTags.put("n", "<silver>"); // notice
this.rawTags.put("i", "<yellow>"); // info
this.rawTags.put("g", "<lime>"); // good
this.rawTags.put("b", "<rose>"); // bad
this.rawTags.put("h", "<pink>"); // highligh
this.rawTags.put("c", "<aqua>"); // command
this.rawTags.put("p", "<teal>"); // parameter
}
public void initTXT()
{
this.addRawTags();
Type type = new TypeToken<Map<String, String>>(){}.getType();
Map<String, String> tagsFromFile = this.persist.load(type, "tags");
if (tagsFromFile != null) this.rawTags.putAll(tagsFromFile);
this.persist.save(this.rawTags, "tags");
for (Entry<String, String> rawTag : this.rawTags.entrySet())
{
this.txt.tags.put(rawTag.getKey(), TextUtil.parseColor(rawTag.getValue()));
}
}*/
// -------------------------------------------- //
// HOOKS
// -------------------------------------------- //
public void preAutoSave()
{
}
public void postAutoSave()
{
}
// -------------------------------------------- //
// LOGGING
// -------------------------------------------- //

View File

@@ -1,34 +0,0 @@
package com.massivecraft.factions.zcore;
import org.bukkit.Bukkit;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerLoginEvent;
import com.massivecraft.factions.zcore.persist.EM;
import com.massivecraft.factions.zcore.persist.Entity;
import com.massivecraft.factions.zcore.persist.EntityCollection;
import com.massivecraft.factions.zcore.persist.PlayerEntityCollection;
public class MPluginSecretPlayerListener implements Listener
{
public MPlugin p;
public MPluginSecretPlayerListener(MPlugin p)
{
this.p = p;
Bukkit.getPluginManager().registerEvents(this, this.p);
}
@EventHandler(priority = EventPriority.LOWEST)
public void onPlayerPreLogin(PlayerLoginEvent event)
{
for (EntityCollection<? extends Entity> ecoll : EM.class2Entities.values())
{
if (ecoll instanceof PlayerEntityCollection)
{
ecoll.get(event.getPlayer().getName());
}
}
}
}

View File

@@ -1,74 +0,0 @@
package com.massivecraft.factions.zcore.persist;
import java.util.*;
import com.massivecraft.factions.zcore.persist.Entity;
import com.massivecraft.factions.zcore.persist.EntityCollection;
public class EM
{
public static Map<Class<? extends Entity>, EntityCollection<? extends Entity>> class2Entities = new LinkedHashMap<Class<? extends Entity>, EntityCollection<? extends Entity>>();
@SuppressWarnings("unchecked")
public static <T extends Entity> EntityCollection<T> getEntitiesCollectionForEntityClass(Class<T> entityClass)
{
return (EntityCollection<T>) class2Entities.get(entityClass);
}
public static void setEntitiesCollectionForEntityClass(Class<? extends Entity> entityClass, EntityCollection<? extends Entity> entities)
{
class2Entities.put(entityClass, entities);
}
// -------------------------------------------- //
// ATTACH AND DETACH
// -------------------------------------------- //
@SuppressWarnings("unchecked")
public static <T extends Entity> void attach(T entity)
{
EntityCollection<T> ec = (EntityCollection<T>) getEntitiesCollectionForEntityClass(entity.getClass());
ec.attach(entity);
}
@SuppressWarnings("unchecked")
public static <T extends Entity> void detach(T entity)
{
EntityCollection<T> ec = (EntityCollection<T>) getEntitiesCollectionForEntityClass(entity.getClass());
ec.detach(entity);
}
@SuppressWarnings("unchecked")
public static <T extends Entity> boolean attached(T entity)
{
EntityCollection<T> ec = (EntityCollection<T>) getEntitiesCollectionForEntityClass(entity.getClass());
return ec.attached(entity);
}
@SuppressWarnings("unchecked")
public static <T extends Entity> boolean detached(T entity)
{
EntityCollection<T> ec = (EntityCollection<T>) getEntitiesCollectionForEntityClass(entity.getClass());
return ec.detached(entity);
}
// -------------------------------------------- //
// DISC
// -------------------------------------------- //
public static void saveAllToDisc()
{
for (EntityCollection<? extends Entity> ec : class2Entities.values())
{
ec.saveToDisc();
}
}
public static void loadAllFromDisc()
{
for (EntityCollection<? extends Entity> ec : class2Entities.values())
{
ec.loadFromDisc();
}
}
}

View File

@@ -1,65 +0,0 @@
package com.massivecraft.factions.zcore.persist;
public abstract class Entity
{
public Entity()
{
}
protected transient String id = null;
public String getId()
{
return id;
}
protected void setId(String id)
{
this.id = id;
}
public boolean shouldBeSaved()
{
return true;
}
// -------------------------------------------- //
// ATTACH AND DETACH
// -------------------------------------------- //
public void attach()
{
EM.attach(this);
}
public void detach()
{
EM.detach(this);
}
public boolean attached()
{
return EM.attached(this);
}
public boolean detached()
{
return EM.detached(this);
}
// -------------------------------------------- //
// EVENTS
// -------------------------------------------- //
public void preDetach()
{
}
public void postDetach()
{
}
}

View File

@@ -1,292 +0,0 @@
package com.massivecraft.factions.zcore.persist;
import java.io.File;
import java.lang.reflect.Type;
import java.util.*;
import java.util.logging.Level;
import java.util.Map.Entry;
import org.bukkit.Bukkit;
import com.massivecraft.mcore.util.DiscUtil;
import com.massivecraft.mcore.util.Txt;
import com.massivecraft.mcore.xlib.gson.Gson;
import com.massivecraft.mcore.xlib.gson.JsonSyntaxException;
public abstract class EntityCollection<E extends Entity>
{
// -------------------------------------------- //
// FIELDS
// -------------------------------------------- //
// These must be instantiated in order to allow for different configuration (orders, comparators etc)
private Collection<E> entities;
protected Map<String, E> id2entity;
// If the entities are creative they will create a new instance if a non existent id was requested
private boolean creative;
public boolean isCreative() { return creative; }
public void setCreative(boolean creative) { this.creative = creative; }
// This is the auto increment for the primary key "id"
private int nextId;
// This ugly crap is necessary due to java type erasure
private Class<E> entityClass;
public abstract Type getMapType(); // This is special stuff for GSON.
// Info on how to persist
private Gson gson;
public Gson getGson() { return gson; }
public void setGson(Gson gson) { this.gson = gson; }
private File file;
public File getFile() { return file; }
public void setFile(File file) { this.file = file; }
// -------------------------------------------- //
// CONSTRUCTORS
// -------------------------------------------- //
public EntityCollection(Class<E> entityClass, Collection<E> entities, Map<String, E> id2entity, File file, Gson gson, boolean creative)
{
this.entityClass = entityClass;
this.entities = entities;
this.id2entity = id2entity;
this.file = file;
this.gson = gson;
this.creative = creative;
this.nextId = 1;
EM.setEntitiesCollectionForEntityClass(this.entityClass, this);
}
public EntityCollection(Class<E> entityClass, Collection<E> entities, Map<String, E> id2entity, File file, Gson gson)
{
this(entityClass, entities, id2entity, file, gson, false);
}
// -------------------------------------------- //
// GET
// -------------------------------------------- //
public Collection<E> get()
{
return entities;
}
public Map<String, E> getMap()
{
return this.id2entity;
}
public E get(String id)
{
if (this.creative) return this.getCreative(id);
return id2entity.get(id);
}
public E getCreative(String id)
{
E e = id2entity.get(id);
if (e != null) return e;
return this.create(id);
}
public boolean exists(String id)
{
if (id == null) return false;
return id2entity.get(id) != null;
}
public E getBestIdMatch(String pattern)
{
String id = Txt.getBestCIStart(this.id2entity.keySet(), pattern);
if (id == null) return null;
return this.id2entity.get(id);
}
// -------------------------------------------- //
// CREATE
// -------------------------------------------- //
public synchronized E create()
{
return this.create(this.getNextId());
}
public synchronized E create(String id)
{
if ( ! this.isIdFree(id)) return null;
E e = null;
try
{
e = this.entityClass.newInstance();
} catch (Exception ignored) {
ignored.printStackTrace();
}
e.setId(id);
this.entities.add(e);
this.id2entity.put(e.getId(), e);
this.updateNextIdForId(id);
return e;
}
// -------------------------------------------- //
// ATTACH AND DETACH
// -------------------------------------------- //
public void attach(E entity)
{
if (entity.getId() != null) return;
entity.setId(this.getNextId());
this.entities.add(entity);
this.id2entity.put(entity.getId(), entity);
}
public void detach(E entity)
{
entity.preDetach();
this.entities.remove(entity);
this.id2entity.remove(entity.getId());
entity.postDetach();
}
public void detach(String id)
{
E entity = this.id2entity.get(id);
if (entity == null) return;
this.detach(entity);
}
public boolean attached(E entity)
{
return this.entities.contains(entity);
}
public boolean detached(E entity)
{
return ! this.attached(entity);
}
// -------------------------------------------- //
// DISC
// -------------------------------------------- //
public boolean saveToDisc()
{
Map<String, E> entitiesThatShouldBeSaved = new HashMap<String, E>();
for (E entity : this.entities)
{
if (entity.shouldBeSaved())
{
entitiesThatShouldBeSaved.put(entity.getId(), entity);
}
}
return this.saveCore(entitiesThatShouldBeSaved);
}
private boolean saveCore(Map<String, E> entities)
{
return DiscUtil.writeCatch(this.file, this.gson.toJson(entities));
}
public boolean loadFromDisc()
{
Map<String, E> id2entity = this.loadCore();
if (id2entity == null) return false;
this.entities.clear();
this.entities.addAll(id2entity.values());
this.id2entity.clear();
this.id2entity.putAll(id2entity);
this.fillIds();
return true;
}
private Map<String, E> loadCore()
{
if ( ! this.file.exists())
{
return new HashMap<String, E>();
}
String content = DiscUtil.readCatch(this.file);
if (content == null)
{
return null;
}
Type type = this.getMapType();
try
{
return this.gson.fromJson(content, type);
}
catch(JsonSyntaxException ex)
{
Bukkit.getLogger().log(Level.WARNING, "JSON error encountered loading \"" + file + "\": " + ex.getLocalizedMessage());
// backup bad file, so user can attempt to recover something from it
File backup = new File(file.getPath()+"_bad");
if (backup.exists()) backup.delete();
Bukkit.getLogger().log(Level.WARNING, "Backing up copy of bad file to: "+backup);
file.renameTo(backup);
return null;
}
}
// -------------------------------------------- //
// ID MANAGEMENT
// -------------------------------------------- //
public String getNextId()
{
while ( ! isIdFree(this.nextId) )
{
this.nextId += 1;
}
return Integer.toString(this.nextId);
}
public boolean isIdFree(String id)
{
return ! this.id2entity.containsKey(id);
}
public boolean isIdFree(int id)
{
return this.isIdFree(Integer.toString(id));
}
protected synchronized void fillIds()
{
this.nextId = 1;
for(Entry<String, E> entry : this.id2entity.entrySet())
{
String id = entry.getKey();
E entity = entry.getValue();
entity.id = id;
this.updateNextIdForId(id);
}
}
protected synchronized void updateNextIdForId(int id)
{
if (this.nextId < id)
{
this.nextId = id + 1;
}
}
protected void updateNextIdForId(String id)
{
try
{
int idAsInt = Integer.parseInt(id);
this.updateNextIdForId(idAsInt);
}
catch (Exception ignored) { }
}
}

View File

@@ -1,51 +0,0 @@
package com.massivecraft.factions.zcore.persist;
import java.util.List;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
public class PlayerEntity extends Entity
{
public Player getPlayer()
{
return Bukkit.getPlayerExact(this.getId());
}
public boolean isOnline()
{
return this.getPlayer() != null;
}
// make sure target player should be able to detect that this player is online
public boolean isOnlineAndVisibleTo(Player player)
{
Player target = this.getPlayer();
return target != null && player.canSee(target);
}
public boolean isOffline()
{
return ! isOnline();
}
// -------------------------------------------- //
// Message Sending Helpers
// -------------------------------------------- //
public void sendMessage(String msg)
{
Player player = this.getPlayer();
if (player == null) return;
player.sendMessage(msg);
}
public void sendMessage(List<String> msgs)
{
for(String msg : msgs)
{
this.sendMessage(msg);
}
}
}

View File

@@ -1,45 +0,0 @@
package com.massivecraft.factions.zcore.persist;
import java.io.File;
import java.util.Collection;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import com.massivecraft.mcore.xlib.gson.Gson;
/**
* The PlayerEntityCollection is an EntityCollection with the extra features
* a player skin usually requires.
*
* This entity collection is not only creative. It even creates the instance for the player
* when the player logs in to the server.
*
* This way we can be sure that PlayerEntityCollection.get() will contain
* all entities in PlayerEntityCollection.getOnline()
*/
public abstract class PlayerEntityCollection<E extends Entity> extends EntityCollection<E>
{
public PlayerEntityCollection(Class<E> entityClass, Collection<E> entities, Map<String, E> id2entity, File file, Gson gson)
{
super(entityClass, entities, id2entity, file, gson, true);
}
public E get(Player player)
{
return this.get(player.getName());
}
public Set<E> getOnline()
{
Set<E> entities = new HashSet<E>();
for (Player player : Bukkit.getServer().getOnlinePlayers())
{
entities.add(this.get(player));
}
return entities;
}
}

View File

@@ -1,20 +0,0 @@
package com.massivecraft.factions.zcore.persist;
import com.massivecraft.factions.zcore.MPlugin;
public class SaveTask implements Runnable
{
MPlugin p;
public SaveTask(MPlugin p)
{
this.p = p;
}
public void run()
{
if ( ! p.getAutoSave()) return;
p.preAutoSave();
EM.saveAllToDisc();
p.postAutoSave();
}
}