Remove Maven

This commit is contained in:
Olof Larsson
2015-01-19 09:58:05 +01:00
parent 1c42916d5b
commit 76a98248a3
635 changed files with 138 additions and 101 deletions

View File

@@ -0,0 +1,59 @@
package com.massivecraft.massivecore;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import com.massivecraft.massivecore.store.Entity;
import com.massivecraft.massivecore.xlib.gson.annotations.SerializedName;
public class Aspect extends Entity<Aspect>
{
// -------------------------------------------- //
// META
// -------------------------------------------- //
public static Aspect get(Object oid)
{
return AspectColl.get().get(oid);
}
// -------------------------------------------- //
// TRANSIENT FIELDS
// -------------------------------------------- //
private transient boolean registered = false;
public boolean isRegistered() { return this.registered; }
public void register() { this.registered = true; }
private transient Collection<String> desc = new ArrayList<String>();
public Collection<String> getDesc() { return this.desc; }
public void setDesc(Collection<String> val) { this.desc = val; }
public void setDesc(String... val) { this.desc = Arrays.asList(val); }
// -------------------------------------------- //
// STORED FIELDS
// -------------------------------------------- //
@SerializedName("mid")
private String multiverseId;
public String getMultiverseId() { return this.multiverseId; }
public void setMultiverseId(String multiverseId) { this.multiverseId = multiverseId; }
public Multiverse getMultiverse()
{
Multiverse ret = MultiverseColl.get().get(this.multiverseId);
if (ret == null) ret = MultiverseColl.get().get(MassiveCore.DEFAULT);
return ret;
}
public void setMultiverse(Multiverse val) { this.multiverseId = val.getId(); }
// -------------------------------------------- //
// CONSTRUCT
// -------------------------------------------- //
public Aspect()
{
}
}

View File

@@ -0,0 +1,49 @@
package com.massivecraft.massivecore;
import java.util.ArrayList;
import java.util.List;
import com.massivecraft.massivecore.store.Coll;
import com.massivecraft.massivecore.store.MStore;
public class AspectColl extends Coll<Aspect>
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static AspectColl i = new AspectColl();
public static AspectColl get() { return i; }
private AspectColl()
{
super("massivecore_aspect", Aspect.class, MStore.getDb("default"), MassiveCore.get());
}
// -------------------------------------------- //
// EXTRAS
// -------------------------------------------- //
public List<Aspect> getAllRegistered()
{
List<Aspect> ret = new ArrayList<Aspect>();
for (Aspect aspect : this.getAll())
{
if(aspect.isRegistered() == false) continue;
ret.add(aspect);
}
return ret;
}
public List<Aspect> getAllRegisteredForMultiverse(Multiverse multiverse, boolean normal)
{
List<Aspect> ret = new ArrayList<Aspect>();
for (Aspect aspect : this.getAll())
{
if(aspect.isRegistered() == false) continue;
if((aspect.getMultiverse() != multiverse) == normal) continue;
ret.add(aspect);
}
return ret;
}
}

View File

@@ -0,0 +1,24 @@
package com.massivecraft.massivecore;
import java.util.Comparator;
public class CaseInsensitiveComparator implements Comparator<String>
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static CaseInsensitiveComparator i = new CaseInsensitiveComparator();
public static CaseInsensitiveComparator get() { return i; }
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public int compare(String o1, String o2)
{
return String.CASE_INSENSITIVE_ORDER.compare(o1, o2);
}
}

View File

@@ -0,0 +1,32 @@
package com.massivecraft.massivecore;
import java.util.Map;
import java.util.UUID;
import com.massivecraft.massivecore.util.MUtil;
public class ConfServer extends SimpleConfig
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static transient ConfServer i = new ConfServer();
public static ConfServer get() { return i; }
public ConfServer() { super(MassiveCore.get()); }
// -------------------------------------------- //
// FIELDS
// -------------------------------------------- //
public static String serverid = UUID.randomUUID().toString();
public static String dburi = "default";
public static Map<String, String> alias2uri = MUtil.map(
"default", "flatfile",
"flatfile", "flatfile://mstore",
"mongodb", "mongodb://localhost:27017/mstore"
);
}

View File

@@ -0,0 +1,103 @@
package com.massivecraft.massivecore;
import java.io.Serializable;
import java.util.Map.Entry;
import com.massivecraft.massivecore.util.MUtil;
public class Couple<A, B> implements Entry<A, B>, Cloneable, Serializable
{
// -------------------------------------------- //
// CONSTANTS
// -------------------------------------------- //
private static final transient long serialVersionUID = 1L;
// -------------------------------------------- //
// FIELDS: RAW
// -------------------------------------------- //
private final A first;
public A getFirst() { return this.first; };
private final B second;
public B getSecond() { return this.second; };
// -------------------------------------------- //
// FIELDS: WITH
// -------------------------------------------- //
public Couple<A, B> withFirst(A first) { return valueOf(first, second); }
public Couple<A, B> withSecond(B second) { return valueOf(first, second); }
// -------------------------------------------- //
// CONSTRUCT
// -------------------------------------------- //
public Couple()
{
this(null, null);
}
public Couple(A first, B second)
{
this.first = first;
this.second = second;
}
// -------------------------------------------- //
// OVERRIDE: ENTRY
// -------------------------------------------- //
@Override
public A getKey()
{
return this.first;
}
@Override
public B getValue()
{
return this.second;
}
@Override
public B setValue(B arg0)
{
throw new IllegalStateException("This entry is a couple which is immutable.");
}
// -------------------------------------------- //
// FACTORY: VALUE OF
// -------------------------------------------- //
public static <A, B> Couple<A, B> valueOf(A first, B second)
{
return new Couple<A, B>(first, second);
}
// -------------------------------------------- //
// EQUALS
// -------------------------------------------- //
@Override
public boolean equals(Object derpObject)
{
if (derpObject == null) return false;
if (!(derpObject instanceof Couple<?, ?>)) return false;
Couple<?, ?> derp = (Couple<?, ?>)derpObject;
return MUtil.equals(this.getFirst(), derp.getFirst()) && MUtil.equals(this.getSecond(), derp.getSecond());
}
// -------------------------------------------- //
// CLONE
// -------------------------------------------- //
@Override
public Couple<A, B> clone()
{
return this;
}
}

View File

@@ -0,0 +1,22 @@
package com.massivecraft.massivecore;
import org.bukkit.event.Listener;
import org.bukkit.plugin.Plugin;
import org.bukkit.scheduler.BukkitTask;
public interface Engine extends Listener, Runnable
{
public Plugin getPlugin();
public void activate();
public void deactivate();
public Long getDelay();
public Long getPeriod();
public Integer getTaskId();
public BukkitTask getBukkitTask();
public boolean isSync();
}

View File

@@ -0,0 +1,78 @@
package com.massivecraft.massivecore;
import org.bukkit.Bukkit;
import org.bukkit.event.HandlerList;
import org.bukkit.scheduler.BukkitTask;
public abstract class EngineAbstract implements Engine
{
// -------------------------------------------- //
// FIELDS
// -------------------------------------------- //
private BukkitTask task;
@Override public Integer getTaskId() { return this.task.getTaskId(); }
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public void activate()
{
Bukkit.getPluginManager().registerEvents(this, this.getPlugin());
if (this.getPeriod() != null)
{
if (this.isSync())
{
Bukkit.getScheduler().runTaskTimer(this.getPlugin(), this, this.getDelay(), this.getPeriod());
}
else
{
Bukkit.getScheduler().runTaskTimerAsynchronously(this.getPlugin(), this, this.getDelay(), this.getPeriod());
}
}
}
@Override
public void deactivate()
{
HandlerList.unregisterAll(this);
if (this.task != null)
{
this.task.cancel();
this.task = null;
}
}
@Override
public Long getDelay()
{
return 0L;
}
@Override
public Long getPeriod()
{
return null;
}
@Override
public void run()
{
}
@Override
public BukkitTask getBukkitTask()
{
return this.task;
}
@Override
public boolean isSync()
{
return true;
}
}

View File

@@ -0,0 +1,24 @@
package com.massivecraft.massivecore;
import java.util.*;
public class HashCodeComparator implements Comparator<Object>
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static transient HashCodeComparator i = new HashCodeComparator();
public static HashCodeComparator get() { return i; }
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public int compare(Object o1, Object o2)
{
return o2.hashCode() - o1.hashCode();
}
}

View File

@@ -0,0 +1,85 @@
package com.massivecraft.massivecore;
public final class HeatData
{
// -------------------------------------------- //
// CONSTANTS
// -------------------------------------------- //
public static final transient double HEAT_MIN = 0D;
public static final transient double HEAT_HIGH = 1D;
public static final transient long MILLIS_CALC_EPSILON = 50;
// -------------------------------------------- //
// FIELDS: RAW
// -------------------------------------------- //
private final double heat;
public double getHeat() { return this.heat; }
private final long lastCalcMillis;
public long getLastCalcMillis() { return this.lastCalcMillis; }
// -------------------------------------------- //
// FIELDS: INSPECT
// -------------------------------------------- //
public double getOverheat()
{
return this.getHeat() - HEAT_HIGH;
}
public boolean isOverheated()
{
return this.getOverheat() > 0;
}
// -------------------------------------------- //
// FIELDS: WITH
// -------------------------------------------- //
public HeatData withHeat(double heat) { return new HeatData(heat, lastCalcMillis); }
public HeatData withLastCalcMillis(long lastCalcMillis) { return new HeatData(heat, lastCalcMillis); }
// -------------------------------------------- //
// CONSTRUCT
// -------------------------------------------- //
private HeatData(double heat, long lastCalcMillis)
{
this.heat = Math.max(0, heat);
this.lastCalcMillis = lastCalcMillis;
}
private HeatData()
{
this.heat = 0;
this.lastCalcMillis = 0;
}
// -------------------------------------------- //
// FACTORY: VALUE OF
// -------------------------------------------- //
public static HeatData valueOf(double heat, long lastCalcMillis)
{
return new HeatData(heat, lastCalcMillis);
}
// -------------------------------------------- //
// FACTORY: RECALCULATED
// -------------------------------------------- //
public HeatData recalculated(long now, double heatPerMilli)
{
if (this.lastCalcMillis + MILLIS_CALC_EPSILON >= now) return this;
long deltaMillis = now - this.lastCalcMillis;
double heatDelta = heatPerMilli * deltaMillis;
double heatTarget = this.heat + heatDelta;
heatTarget = Math.max(0, heatTarget);
return valueOf(heatTarget, now);
}
}

View File

@@ -0,0 +1,107 @@
package com.massivecraft.massivecore;
public abstract class Heatable
{
// -------------------------------------------- //
// ABSTRACT
// -------------------------------------------- //
public abstract HeatData getData();
public abstract void setData(HeatData data);
public abstract double getHeatPerMilli();
public abstract double getHeatPerExecution();
// -------------------------------------------- //
// CUSTOM
// -------------------------------------------- //
private HeatData getRecalculatedData(double heatPerMilli)
{
long now = System.currentTimeMillis();
HeatData data = this.getData().recalculated(now, heatPerMilli);
this.setData(data);
return data;
}
public void addHeat(double heatPerMilli, double heat)
{
long now = System.currentTimeMillis();
HeatData data = this.getData().recalculated(now, heatPerMilli);
data = data.withHeat(data.getHeat() + heat);
this.setData(data);
}
public double getHeat(double heatPerMilli)
{
HeatData data = getRecalculatedData(heatPerMilli);
return data.getHeat();
}
public boolean isOverheated(double heatPerMilli)
{
HeatData data = getRecalculatedData(heatPerMilli);
return data.isOverheated();
}
public double getOverheat(double heatPerMilli)
{
HeatData data = getRecalculatedData(heatPerMilli);
return data.getOverheat();
}
public long getCooldownMillisLeft(double heatPerMilli)
{
double overheat = this.getOverheat(heatPerMilli);
return (long) (-overheat / heatPerMilli);
}
// -------------------------------------------- //
// DEFAULT
// -------------------------------------------- //
public void addHeat(double heat)
{
this.addHeat(this.getHeatPerMilli(), heat);
}
public void addHeat()
{
this.addHeat(this.getHeatPerExecution());
}
public double getHeat()
{
return this.getHeat(this.getHeatPerMilli());
}
public boolean isOverheated()
{
return this.isOverheated(this.getHeatPerMilli());
}
public double getOverheat()
{
return this.getOverheat(this.getHeatPerMilli());
}
public long getCooldownMillisLeft()
{
return this.getCooldownMillisLeft(this.getHeatPerMilli());
}
// -------------------------------------------- //
// UTIL
// -------------------------------------------- //
public static double calcHeatPerExecution(long executionCount, long periodMillis)
{
return 1D / (double)executionCount;
}
public static double calcHeatPerMilli(long executionCount, long periodMillis)
{
return - 1D / (double)periodMillis;
}
}

View File

@@ -0,0 +1,13 @@
package com.massivecraft.massivecore;
public class Lang
{
public static final String PERM_DEFAULT_DENIED_FORMAT = "<b>You don't have permission to %s.";
public static final String PERM_DEFAULT_DESCRIPTION = "do that";
public static final String COMMAND_SENDER_MUST_BE_PLAYER = "<b>This command can only be used by ingame players.";
public static final String COMMAND_SENDER_MUSNT_BE_PLAYER = "<b>This command can not be used by ingame players.";
public static final String COMMAND_TO_FEW_ARGS = "<b>Too few arguments. <i>Use like this:";
public static final String COMMAND_TO_MANY_ARGS = "<b>Strange arguments %s<b>.";
public static final String COMMAND_TO_MANY_ARGS2 = "<i>Use the command like this:";
}

View File

@@ -0,0 +1,252 @@
package com.massivecraft.massivecore;
import java.lang.reflect.Modifier;
import java.util.List;
import java.util.Random;
import java.util.Set;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.PlayerInventory;
import com.massivecraft.massivecore.adapter.BackstringEnumSetAdapter;
import com.massivecraft.massivecore.adapter.InventoryAdapter;
import com.massivecraft.massivecore.adapter.ItemStackAdapter;
import com.massivecraft.massivecore.adapter.JsonElementAdapter;
import com.massivecraft.massivecore.adapter.MassiveListAdapter;
import com.massivecraft.massivecore.adapter.MassiveMapAdapter;
import com.massivecraft.massivecore.adapter.MassiveSetAdapter;
import com.massivecraft.massivecore.adapter.MassiveTreeSetAdapter;
import com.massivecraft.massivecore.adapter.ModdedEnumTypeAdapter;
import com.massivecraft.massivecore.adapter.PlayerInventoryAdapter;
import com.massivecraft.massivecore.adapter.MassiveTreeMapAdapter;
import com.massivecraft.massivecore.adapter.UUIDAdapter;
import com.massivecraft.massivecore.cmd.massivecore.CmdMassiveCore;
import com.massivecraft.massivecore.cmd.massivecore.CmdMassiveCoreBuffer;
import com.massivecraft.massivecore.cmd.massivecore.CmdMassiveCoreCmdurl;
import com.massivecraft.massivecore.cmd.massivecore.CmdMassiveCoreStore;
import com.massivecraft.massivecore.cmd.massivecore.CmdMassiveCoreUsys;
import com.massivecraft.massivecore.collections.BackstringEnumSet;
import com.massivecraft.massivecore.collections.MassiveList;
import com.massivecraft.massivecore.collections.MassiveListDef;
import com.massivecraft.massivecore.collections.MassiveMap;
import com.massivecraft.massivecore.collections.MassiveMapDef;
import com.massivecraft.massivecore.collections.MassiveSet;
import com.massivecraft.massivecore.collections.MassiveSetDef;
import com.massivecraft.massivecore.collections.MassiveTreeMap;
import com.massivecraft.massivecore.collections.MassiveTreeMapDef;
import com.massivecraft.massivecore.collections.MassiveTreeSet;
import com.massivecraft.massivecore.collections.MassiveTreeSetDef;
import com.massivecraft.massivecore.event.EventMassiveCoreUuidUpdate;
import com.massivecraft.massivecore.integration.vault.IntegrationVault;
import com.massivecraft.massivecore.mixin.EngineTeleportMixinCause;
import com.massivecraft.massivecore.ps.PS;
import com.massivecraft.massivecore.ps.PSAdapter;
import com.massivecraft.massivecore.store.Coll;
import com.massivecraft.massivecore.store.ExamineThread;
import com.massivecraft.massivecore.teleport.EngineScheduledTeleport;
import com.massivecraft.massivecore.util.IdUtil;
import com.massivecraft.massivecore.util.MUtil;
import com.massivecraft.massivecore.util.PlayerUtil;
import com.massivecraft.massivecore.util.Txt;
import com.massivecraft.massivecore.xlib.gson.Gson;
import com.massivecraft.massivecore.xlib.gson.GsonBuilder;
import com.massivecraft.massivecore.xlib.gson.JsonArray;
import com.massivecraft.massivecore.xlib.gson.JsonNull;
import com.massivecraft.massivecore.xlib.gson.JsonObject;
import com.massivecraft.massivecore.xlib.gson.JsonPrimitive;
public class MassiveCore extends MassivePlugin
{
// -------------------------------------------- //
// COMMON CONSTANTS
// -------------------------------------------- //
public final static String INSTANCE = "instance";
public final static String DEFAULT = "default";
public final static Set<String> NOTHING = MUtil.treeset("", "none", "null", "nothing");
public final static Set<String> REMOVE = MUtil.treeset("clear", "c", "delete", "del", "d", "erase", "e", "remove", "rem", "r", "reset", "res");
public final static Set<String> NOTHING_REMOVE = MUtil.treeset("", "none", "null", "nothing", "clear", "c", "delete", "del", "d", "erase", "e", "remove", "rem", "r", "reset", "res");
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static MassiveCore i;
public static MassiveCore get() { return i; }
public MassiveCore() { i = this; }
// -------------------------------------------- //
// STATIC
// -------------------------------------------- //
public static Random random = new Random();
public static Gson gson = getMassiveCoreGsonBuilder().create();
public static GsonBuilder getMassiveCoreGsonBuilder()
{
return new GsonBuilder()
.setPrettyPrinting()
.disableHtmlEscaping()
.excludeFieldsWithModifiers(Modifier.TRANSIENT)
.registerTypeAdapter(JsonNull.class, JsonElementAdapter.get())
.registerTypeAdapter(JsonPrimitive.class, JsonElementAdapter.get())
.registerTypeAdapter(JsonArray.class, JsonElementAdapter.get())
.registerTypeAdapter(JsonObject.class, JsonElementAdapter.get())
.registerTypeAdapter(UUID.class, UUIDAdapter.get())
.registerTypeAdapter(ItemStack.class, ItemStackAdapter.get())
.registerTypeAdapter(Inventory.class, InventoryAdapter.get())
.registerTypeAdapter(PlayerInventory.class, PlayerInventoryAdapter.get())
.registerTypeAdapter(PS.class, PSAdapter.get())
.registerTypeAdapter(MassiveList.class, MassiveListAdapter.get())
.registerTypeAdapter(MassiveListDef.class, MassiveListAdapter.get())
.registerTypeAdapter(MassiveMap.class, MassiveMapAdapter.get())
.registerTypeAdapter(MassiveMapDef.class, MassiveMapAdapter.get())
.registerTypeAdapter(MassiveSet.class, MassiveSetAdapter.get())
.registerTypeAdapter(MassiveSetDef.class, MassiveSetAdapter.get())
.registerTypeAdapter(MassiveTreeMap.class, MassiveTreeMapAdapter.get())
.registerTypeAdapter(MassiveTreeMapDef.class, MassiveTreeMapAdapter.get())
.registerTypeAdapter(MassiveTreeSet.class, MassiveTreeSetAdapter.get())
.registerTypeAdapter(MassiveTreeSetDef.class, MassiveTreeSetAdapter.get())
.registerTypeAdapter(BackstringEnumSet.class, BackstringEnumSetAdapter.get())
.registerTypeAdapterFactory(ModdedEnumTypeAdapter.ENUM_FACTORY);
}
public static String getServerId() { return ConfServer.serverid; }
// -------------------------------------------- //
// FIELDS
// -------------------------------------------- //
// Commands
private CmdMassiveCore outerCmdMassiveCore;
public CmdMassiveCore getOuterCmdMassiveCore() { return this.outerCmdMassiveCore; }
private CmdMassiveCoreUsys outerCmdMassiveCoreUsys;
public CmdMassiveCoreUsys getOuterCmdMassiveCoreUsys() { return this.outerCmdMassiveCoreUsys; }
private CmdMassiveCoreStore outerCmdMassiveCoreStore;
public CmdMassiveCoreStore getOuterCmdMassiveCoreStore() { return this.outerCmdMassiveCoreStore; }
private CmdMassiveCoreBuffer outerCmdMassiveCoreBuffer;
public CmdMassiveCoreBuffer getOuterCmdMassiveCoreBuffer() { return this.outerCmdMassiveCoreBuffer; }
private CmdMassiveCoreCmdurl outerCmdMassiveCoreCmdurl;
public CmdMassiveCoreCmdurl getOuterCmdMassiveCoreCmdurl() { return this.outerCmdMassiveCoreCmdurl; }
// Runnables
// TODO: Make this one a singleton
private Runnable collTickTask = new Runnable()
{
public void run()
{
for (Coll<?> coll : Coll.getInstances())
{
coll.onTick();
}
}
};
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public void onEnable()
{
// This is safe since all plugins using Persist should bukkit-depend this plugin.
// Note this one must be before preEnable. dooh.
// TODO: Create something like "deinit all" (perhaps a forloop) to readd this.
// TODO: Test and ensure reload compat.
// Coll.instances.clear();
// Start the examine thread
ExamineThread.get().start();
if ( ! preEnable()) return;
// Load Server Config
ConfServer.get().load();
// Setup IdUtil
IdUtil.setup();
// Register events
MassiveCoreEngineMain.get().activate();
MassiveCoreEngineVariable.get().activate();
EngineScheduledTeleport.get().activate();
EngineTeleportMixinCause.get().activate();
MassiveCoreEngineWorldNameSet.get().activate();
MassiveCoreEngineCommandRegistration.get().activate();
PlayerUtil.get().activate();
// Tasks
Bukkit.getScheduler().scheduleSyncRepeatingTask(this, this.collTickTask, 1, 1);
// Collections
MultiverseColl.get().init();
AspectColl.get().init();
MassiveCoreMConfColl.get().init();
// Register commands
this.outerCmdMassiveCore = new CmdMassiveCore() { public List<String> getAliases() { return MassiveCoreMConf.get().aliasesOuterMassiveCore; } };
this.outerCmdMassiveCore.register(this);
this.outerCmdMassiveCoreUsys = new CmdMassiveCoreUsys() { public List<String> getAliases() { return MassiveCoreMConf.get().aliasesOuterMassiveCoreUsys; } };
this.outerCmdMassiveCoreUsys.register(this);
this.outerCmdMassiveCoreStore = new CmdMassiveCoreStore() { public List<String> getAliases() { return MassiveCoreMConf.get().aliasesOuterMassiveCoreStore; } };
this.outerCmdMassiveCoreStore.register(this);
this.outerCmdMassiveCoreBuffer = new CmdMassiveCoreBuffer() { public List<String> getAliases() { return MassiveCoreMConf.get().aliasesOuterMassiveCoreBuffer; } };
this.outerCmdMassiveCoreBuffer.register(this);
this.outerCmdMassiveCoreCmdurl = new CmdMassiveCoreCmdurl() { public List<String> getAliases() { return MassiveCoreMConf.get().aliasesOuterMassiveCoreCmdurl; } };
this.outerCmdMassiveCoreCmdurl.register(this);
// Integration
this.integrate(
IntegrationVault.get()
);
// Delete Files (at once and additionally after all plugins loaded)
MassiveCoreTaskDeleteFiles.get().run();
Bukkit.getScheduler().scheduleSyncDelayedTask(this, MassiveCoreTaskDeleteFiles.get());
Bukkit.getScheduler().scheduleSyncDelayedTask(this, new Runnable()
{
@Override
public void run()
{
IdUtil.loadDatas();
log(Txt.parse("<i>Upgrading from player name to player uuid..."));
EventMassiveCoreUuidUpdate event = new EventMassiveCoreUuidUpdate();
event.run();
log(Txt.parse("<g> ... done!"));
log(Txt.parse("<i>(database saving will now commence which might lock the server for a while)"));
}
});
this.postEnable();
}
@Override
public void onDisable()
{
super.onDisable();
ExamineThread.get().interrupt();
MassiveCoreTaskDeleteFiles.get().run();
IdUtil.saveCachefileDatas();
}
}

View File

@@ -0,0 +1,168 @@
package com.massivecraft.massivecore;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import org.bukkit.Bukkit;
import org.bukkit.Server;
import org.bukkit.command.Command;
import org.bukkit.command.SimpleCommandMap;
import org.bukkit.plugin.Plugin;
import com.massivecraft.massivecore.cmd.MassiveCommand;
import com.massivecraft.massivecore.cmd.MassiveCoreBukkitCommand;
import com.massivecraft.massivecore.util.ReflectionUtil;
public class MassiveCoreEngineCommandRegistration extends EngineAbstract
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static MassiveCoreEngineCommandRegistration i = new MassiveCoreEngineCommandRegistration();
public static MassiveCoreEngineCommandRegistration get() { return i; }
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public Plugin getPlugin()
{
return MassiveCore.get();
}
@Override
public Long getPeriod()
{
// Every second
return 1 * 20L;
}
// -------------------------------------------- //
// TASK
// -------------------------------------------- //
@Override
public void run()
{
updateRegistrations();
}
// -------------------------------------------- //
// UPDATE REGISTRATIONS
// -------------------------------------------- //
public static void updateRegistrations()
{
// Step #1: Hack into Bukkit and get the SimpleCommandMap and it's knownCommands.
SimpleCommandMap simpleCommandMap = getSimpleCommandMap();
Map<String, Command> knownCommands = getSimpleCommandMapDotKnownCommands(simpleCommandMap);
// Step #2: Create a "name --> target" map that contains the MassiveCommands that /should/ be registered in Bukkit.
Map<String, MassiveCommand> nameTargets = new HashMap<String, MassiveCommand>();
// For each MassiveCommand that is supposed to be registered ...
for (MassiveCommand massiveCommand : MassiveCommand.getRegisteredCommands())
{
// ... and for each of it's aliases ...
for (String alias : massiveCommand.getAliases())
{
// ... that aren't null ...
if (alias == null) continue;
// ... clean the alias ...
alias = alias.trim().toLowerCase();
// ... and put it in the map.
// NOTE: In case the same alias is used by many commands the overwrite occurs here!
nameTargets.put(alias, massiveCommand);
}
}
// Step #3: Ensure the nameTargets created in Step #2 are registered in Bukkit.
// For each nameTarget entry ...
for (Entry<String, MassiveCommand> entry : nameTargets.entrySet())
{
String name = entry.getKey();
MassiveCommand target = entry.getValue();
// ... find the current command registered in Bukkit under that name (if any) ...
Command current = knownCommands.get(name);
MassiveCommand massiveCurrent = getMassiveCommand(current);
// ... and if the current command is not the target ...
// NOTE: We do this check since it's important we don't create new MassiveCoreBukkitCommands unless required.
// NOTE: Before I implemented this check I caused a memory leak in tandem with Spigots timings system.
if (target == massiveCurrent) continue;
// ... unregister the current command if there is one ...
if (current != null)
{
knownCommands.remove(name);
current.unregister(simpleCommandMap);
}
// ... create a new MassiveCoreBukkitCommand ...
MassiveCoreBukkitCommand command = new MassiveCoreBukkitCommand(name, target);
// ... and finally register it.
simpleCommandMap.register("MassiveCore", command);
}
// Step #4: Remove/Unregister MassiveCommands from Bukkit that are but should not be that any longer.
// For each known command ...
Iterator<Entry<String, Command>> iter = knownCommands.entrySet().iterator();
while (iter.hasNext())
{
Entry<String, Command> entry = iter.next();
String name = entry.getKey();
Command command = entry.getValue();
// ... that is a MassiveCoreBukkitCommand ...
MassiveCommand massiveCommand = getMassiveCommand(command);
if (massiveCommand == null) continue;
// ... and not a target ...
if (nameTargets.containsKey(name)) continue;
// ... unregister it.
command.unregister(simpleCommandMap);
iter.remove();
}
}
// -------------------------------------------- //
// GETTERS
// -------------------------------------------- //
protected static Field SERVER_DOT_COMMAND_MAP = ReflectionUtil.getField(Bukkit.getServer().getClass(), "commandMap");
public static SimpleCommandMap getSimpleCommandMap()
{
Server server = Bukkit.getServer();
return (SimpleCommandMap) ReflectionUtil.getField(SERVER_DOT_COMMAND_MAP, server);
}
protected static Field SIMPLE_COMMAND_MAP_DOT_KNOWN_COMMANDS = ReflectionUtil.getField(SimpleCommandMap.class, "knownCommands");
@SuppressWarnings("unchecked")
public static Map<String, Command> getSimpleCommandMapDotKnownCommands(SimpleCommandMap simpleCommandMap)
{
return (Map<String, Command>) ReflectionUtil.getField(SIMPLE_COMMAND_MAP_DOT_KNOWN_COMMANDS, simpleCommandMap);
}
// -------------------------------------------- //
// UTIL
// -------------------------------------------- //
public static MassiveCommand getMassiveCommand(Command command)
{
if (command == null) return null;
if (!(command instanceof MassiveCoreBukkitCommand)) return null;
MassiveCoreBukkitCommand mcbc = (MassiveCoreBukkitCommand)command;
return mcbc.getMassiveCommand();
}
}

View File

@@ -0,0 +1,355 @@
package com.massivecraft.massivecore;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.entity.EntityDamageByBlockEvent;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.event.player.AsyncPlayerChatEvent;
import org.bukkit.event.player.PlayerKickEvent;
import org.bukkit.event.player.PlayerLoginEvent;
import org.bukkit.event.player.PlayerChatTabCompleteEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.event.player.PlayerRespawnEvent;
import org.bukkit.event.player.PlayerTeleportEvent;
import org.bukkit.plugin.Plugin;
import com.massivecraft.massivecore.event.EventMassiveCoreAfterPlayerRespawn;
import com.massivecraft.massivecore.event.EventMassiveCoreAfterPlayerTeleport;
import com.massivecraft.massivecore.event.EventMassiveCorePermissionDeniedFormat;
import com.massivecraft.massivecore.event.EventMassiveCorePlayerLeave;
import com.massivecraft.massivecore.event.EventMassiveCorePlayerToRecipientChat;
import com.massivecraft.massivecore.event.EventMassiveCoreSenderRegister;
import com.massivecraft.massivecore.event.EventMassiveCoreSenderUnregister;
import com.massivecraft.massivecore.mixin.Mixin;
import com.massivecraft.massivecore.store.Coll;
import com.massivecraft.massivecore.store.SenderColl;
import com.massivecraft.massivecore.util.IdUtil;
import com.massivecraft.massivecore.util.SmokeUtil;
public class MassiveCoreEngineMain extends EngineAbstract
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static MassiveCoreEngineMain i = new MassiveCoreEngineMain();
public static MassiveCoreEngineMain get() { return i; }
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public Plugin getPlugin()
{
return MassiveCore.get();
}
@Override
public void activate()
{
super.activate();
EventMassiveCorePlayerLeave.player2event.clear();
}
// -------------------------------------------- //
// RECIPIENT CHAT
// -------------------------------------------- //
// A system to create per recipient events.
// It clears the recipient set so the event isn't cancelled completely.
// It will cause non async chat events not to fire.
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void recipientChat(final AsyncPlayerChatEvent event)
{
// Return unless we are using the recipient chat event
if (!MassiveCoreMConf.get().usingRecipientChatEvent) return;
// Prepare vars
EventMassiveCorePlayerToRecipientChat recipientEvent;
final Player sender = event.getPlayer();
String message = event.getMessage();
String format = event.getFormat();
// Pick the recipients to avoid the message getting sent without canceling the event.
Set<Player> players = new HashSet<Player>(event.getRecipients());
event.getRecipients().clear();
// For each of the players
for (Player recipient : players)
{
// Run the event for this unique recipient
recipientEvent = new EventMassiveCorePlayerToRecipientChat(event.isAsynchronous(), sender, recipient, message, format);
recipientEvent.run();
// Format and send with the format and message from this recipient's own event.
String recipientMessage = String.format(recipientEvent.getFormat(), sender.getDisplayName(), recipientEvent.getMessage());
recipient.sendMessage(recipientMessage);
}
// For the console
recipientEvent = new EventMassiveCorePlayerToRecipientChat(event.isAsynchronous(), sender, Bukkit.getConsoleSender(), message, format);
recipientEvent.run();
event.setMessage(recipientEvent.getMessage());
event.setFormat(recipientEvent.getFormat());
}
// -------------------------------------------- //
// PERMISSION DENIED FORMAT
// -------------------------------------------- //
@EventHandler(priority = EventPriority.NORMAL)
public void permissionDeniedFormat(EventMassiveCorePermissionDeniedFormat event)
{
// If noone set a format already ...
if (event.hasFormat()) return;
// ... and we have a custom format in the config ...
String customFormat = MassiveCoreMConf.get().getPermissionDeniedFormat(event.getPermissionName());
if (customFormat == null) return;
// ... then make use of that format.
event.setFormat(customFormat);
}
// -------------------------------------------- //
// CHAT TAB COMPLETE
// -------------------------------------------- //
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void chatTabComplete(PlayerChatTabCompleteEvent event)
{
// So the player is watching ...
Player watcher = event.getPlayer();
// Get the lowercased token
String tokenlc = event.getLastToken().toLowerCase();
// Create a case insensitive set to check for already added stuff
Set<String> current = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
current.addAll(event.getTabCompletions());
// Add names of all online senders that match and isn't added yet.
for (String senderName : IdUtil.getOnlineNames())
{
if (!senderName.toLowerCase().startsWith(tokenlc)) continue;
if (current.contains(senderName)) continue;
if (!Mixin.canSee(watcher, senderName)) continue;
event.getTabCompletions().add(senderName);
}
}
// -------------------------------------------- //
// EXPLOSION FX
// -------------------------------------------- //
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
public void explosionFx(EntityDamageByBlockEvent event)
{
// If an entity is taking damage from a block explosion ...
DamageCause cause = event.getCause();
if (cause != DamageCause.BLOCK_EXPLOSION) return;
// ... and that explosion is a fake ...
if (!SmokeUtil.fakeExplosion.booleanValue()) return;
// ... then cancel the event and the damage.
event.setCancelled(true);
}
// -------------------------------------------- //
// PLAYER AND SENDER REFERENCES
// -------------------------------------------- //
// Note: For now we update both names and ids.
// That way collections in plugins that haven't yet undergone update will still work.
// This method sets the sender reference to what you decide.
public static void setSenderReferences(CommandSender sender, CommandSender reference)
{
String id = IdUtil.getId(sender);
if (id != null)
{
SenderColl.setSenderReferences(id, reference);
}
String name = IdUtil.getName(sender);
if (name != null)
{
SenderColl.setSenderReferences(name, reference);
}
}
// This method sets the sender reference based on it's online state.
public static void setSenderReferences(Player player)
{
Player reference = player;
if ( ! player.isOnline()) reference = null;
setSenderReferences(player, reference);
}
// Same as above but next tick.
public static void setSenderReferencesSoon(final Player player)
{
Bukkit.getScheduler().scheduleSyncDelayedTask(MassiveCore.get(), new Runnable()
{
@Override
public void run()
{
setSenderReferences(player);
}
});
}
@EventHandler(priority = EventPriority.LOWEST)
public void setSenderReferencesLoginLowest(PlayerLoginEvent event)
{
final Player player = event.getPlayer();
// We set the reference at LOWEST so that it's present during this PlayerLoginEvent event.
setSenderReferences(player, player);
// And the next tick we update the reference based on it's online state.
// Not all players succeed in logging in. They may for example be banned.
setSenderReferencesSoon(player);
}
@EventHandler(priority = EventPriority.MONITOR)
public void setSenderReferencesQuitMonitor(PlayerQuitEvent event)
{
// PlayerQuitEvents are /probably/ trustworthy.
// We check ourselves the next tick just to be on the safe side.
setSenderReferencesSoon(event.getPlayer());
}
@EventHandler(priority = EventPriority.MONITOR)
public void setSenderReferencesRegisterMonitor(EventMassiveCoreSenderRegister event)
{
// This one we can however trust.
setSenderReferences(event.getSender(), event.getSender());
}
@EventHandler(priority = EventPriority.MONITOR)
public void setSenderReferencesUnregisterMonitor(EventMassiveCoreSenderUnregister event)
{
// This one we can however trust.
setSenderReferences(event.getSender(), null);
}
// -------------------------------------------- //
// AFTER EVENTS
// -------------------------------------------- //
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void after(PlayerTeleportEvent event)
{
Bukkit.getScheduler().scheduleSyncDelayedTask(MassiveCore.get(), new EventMassiveCoreAfterPlayerTeleport(event), 0);
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void after(PlayerRespawnEvent event)
{
Bukkit.getScheduler().scheduleSyncDelayedTask(MassiveCore.get(), new EventMassiveCoreAfterPlayerRespawn(event, event.getPlayer().getLocation()), 0);
}
// -------------------------------------------- //
// EVENT TOOL: causedByKick
// -------------------------------------------- //
public static Map<String,String> kickedPlayerReasons = new HashMap<String,String>();
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void causedByKick(PlayerKickEvent event)
{
final String name = event.getPlayer().getName();
kickedPlayerReasons.put(name, event.getReason());
}
@EventHandler(priority = EventPriority.MONITOR)
public void causedByKick(PlayerQuitEvent event)
{
// We do the schedule in order for the set to be correct through out the whole MONITOR priority state.
final String name = event.getPlayer().getName();
Bukkit.getScheduler().scheduleSyncDelayedTask(MassiveCore.get(), new Runnable()
{
@Override
public void run()
{
kickedPlayerReasons.remove(name);
}
});
}
// -------------------------------------------- //
// PLAYER LEAVE EVENT
// -------------------------------------------- //
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void leaveEventKickCall(PlayerKickEvent event)
{
new EventMassiveCorePlayerLeave(event.getPlayer(), true, "kick", event.getReason()).run();
}
@EventHandler(priority = EventPriority.MONITOR)
public void leaveEventQuitCall(PlayerQuitEvent event)
{
new EventMassiveCorePlayerLeave(event.getPlayer(), false, "quit", null).run();
}
@EventHandler(priority = EventPriority.MONITOR)
public void leaveEventQuitClear(PlayerQuitEvent event)
{
// We do the schedule in order for the set to be correct through out the whole MONITOR priority state.
final String name = event.getPlayer().getName();
Bukkit.getScheduler().scheduleSyncDelayedTask(MassiveCore.get(), new Runnable()
{
@Override
public void run()
{
EventMassiveCorePlayerLeave.player2event.remove(name);
}
});
}
// -------------------------------------------- //
// SYNC PLAYER ON LOGON AND LEAVE
// -------------------------------------------- //
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
public void syncOnPlayerLogin(PlayerLoginEvent event)
{
//MassiveCore.get().log("LOWEST syncOnPlayerLogin", event.getPlayer().getName());
this.syncAllForPlayer(event.getPlayer());
}
@EventHandler(priority = EventPriority.MONITOR)
public void syncOnPlayerLeave(EventMassiveCorePlayerLeave event)
{
//MassiveCore.get().log("MONITOR syncOnPlayerLeave", event.getPlayer().getName());
this.syncAllForPlayer(event.getPlayer());
}
public void syncAllForPlayer(Player player)
{
// TODO: For now we sync them both!
String playerName = player.getName();
String playerId = player.getUniqueId().toString();
for (Coll<?> coll : Coll.getInstances())
{
if (!(coll instanceof SenderColl)) continue;
SenderColl<?> pcoll = (SenderColl<?>)coll;
pcoll.syncId(playerName);
pcoll.syncId(playerId);
}
}
}

View File

@@ -0,0 +1,139 @@
package com.massivecraft.massivecore;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.player.AsyncPlayerChatEvent;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.BookMeta;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.plugin.Plugin;
import com.massivecraft.massivecore.util.IdUtil;
import com.massivecraft.massivecore.util.Txt;
public class MassiveCoreEngineVariable extends EngineAbstract
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static MassiveCoreEngineVariable i = new MassiveCoreEngineVariable();
public static MassiveCoreEngineVariable get() { return i; }
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public Plugin getPlugin()
{
return MassiveCore.get();
}
// -------------------------------------------- //
// VARIABLE
// -------------------------------------------- //
@EventHandler(priority = EventPriority.NORMAL)
public void variable(PlayerCommandPreprocessEvent event)
{
event.setMessage(variable(event.getPlayer(), event.getMessage()));
}
@EventHandler(priority = EventPriority.LOW)
public void variable(AsyncPlayerChatEvent event)
{
event.setMessage(variable(event.getPlayer(), event.getMessage()));
}
public static String variable(Player player, String message)
{
message = variableBook(player, message);
message = variableBuffer(player, message);
return message;
}
// -------------------------------------------- //
// VARIABLE BOOK
// -------------------------------------------- //
public static String getBookText(CommandSender sender)
{
if (sender == null) return null;
if (!(sender instanceof HumanEntity)) return null;
HumanEntity human = (HumanEntity)sender;
ItemStack item = human.getItemInHand();
if (item == null) return null;
if (!item.hasItemMeta()) return null;
ItemMeta itemMeta = item.getItemMeta();
if (!(itemMeta instanceof BookMeta)) return null;
BookMeta bookMeta = (BookMeta)itemMeta;
if (!bookMeta.hasPages()) return null;
List<String> pages = bookMeta.getPages();
String ret = Txt.implode(pages, " ");
ret = ret.replaceAll("\\n+", " ");
return ret;
}
public static String variableBook(Player player, String message)
{
// If we are using this variable ...
if (!MassiveCoreMConf.get().usingVariableBook) return message;
// ... get the variable content ...
String content = getBookText(player);
if (content == null) return message;
// ... check use permission ...
if (!MassiveCorePerm.VARIABLE_BOOK.has(player, false)) return message;
// ... and replace.
return StringUtils.replace(message, MassiveCoreMConf.get().variableBook, content);
}
// -------------------------------------------- //
// VARIABLE BUFFER
// -------------------------------------------- //
public static final Map<String, String> idToBuffer = new HashMap<String, String>();
public static String getBuffer(Object senderObject)
{
String id = IdUtil.getId(senderObject);
if (id == null) return null;
String ret = idToBuffer.get(id);
if (ret == null) ret = "";
return ret;
}
public static void setBuffer(Object senderObject, String buffer)
{
String id = IdUtil.getId(senderObject);
idToBuffer.put(id, buffer);
}
public static String variableBuffer(Player player, String message)
{
// If we are using this variable ...
if (!MassiveCoreMConf.get().usingVariableBuffer) return message;
// ... get the variable content ...
String content = getBuffer(player);
if (content == null) return message;
// ... check use permission ...
if (!MassiveCorePerm.VARIABLE_BUFFER.has(player, false)) return message;
// ... and replace.
return StringUtils.replace(message, MassiveCoreMConf.get().variableBuffer, content);
}
}

View File

@@ -0,0 +1,70 @@
package com.massivecraft.massivecore;
import java.util.Collections;
import java.util.Set;
import java.util.TreeSet;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.world.WorldLoadEvent;
import org.bukkit.event.world.WorldUnloadEvent;
import org.bukkit.plugin.Plugin;
public class MassiveCoreEngineWorldNameSet extends EngineAbstract
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static MassiveCoreEngineWorldNameSet i = new MassiveCoreEngineWorldNameSet();
public static MassiveCoreEngineWorldNameSet get() { return i; }
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public Plugin getPlugin()
{
return MassiveCore.get();
}
@Override
public void activate()
{
super.activate();
this.worldNamesInner.clear();
for (World world : Bukkit.getWorlds())
{
this.worldNamesInner.add(world.getName());
}
}
// -------------------------------------------- //
// FIELDS
// -------------------------------------------- //
private final TreeSet<String> worldNamesInner = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
private final Set<String> worldNamesOuter = Collections.unmodifiableSet(this.worldNamesInner);
public Set<String> getWorldNames() { return this.worldNamesOuter; }
// -------------------------------------------- //
// LISTENER
// -------------------------------------------- //
@EventHandler(priority = EventPriority.NORMAL)
public void onWorldLoad(WorldLoadEvent event)
{
this.worldNamesInner.add(event.getWorld().getName());
}
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
public void onWorldUnload(WorldUnloadEvent event)
{
this.worldNamesInner.remove(event.getWorld().getName());
}
}

View File

@@ -0,0 +1,94 @@
package com.massivecraft.massivecore;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.bukkit.permissions.Permissible;
import com.massivecraft.massivecore.store.Entity;
import com.massivecraft.massivecore.util.MUtil;
import com.massivecraft.massivecore.util.PermUtil;
import com.massivecraft.massivecore.xlib.mongodb.WriteConcern;
public class MassiveCoreMConf extends Entity<MassiveCoreMConf>
{
// -------------------------------------------- //
// META
// -------------------------------------------- //
protected static transient MassiveCoreMConf i;
public static MassiveCoreMConf get() { return i; }
// -------------------------------------------- //
// FIELDS
// -------------------------------------------- //
public List<String> aliasesOuterMassiveCore = MUtil.list("massivecore", "mcore");
public List<String> aliasesOuterMassiveCoreUsys = MUtil.list("usys");
public List<String> aliasesOuterMassiveCoreStore = MUtil.list("massivestore", "mstore");
public List<String> aliasesOuterMassiveCoreBuffer = MUtil.list("buffer");
public List<String> aliasesOuterMassiveCoreCmdurl = MUtil.list("cmdurl");
public boolean usingRecipientChatEvent = true;
public Map<String, String> permissionDeniedFormats = MUtil.map(
"some.awesome.permission.node", "<b>You must be awesome to %s<b>.",
"some.derp.permission.node.1", "derp",
"some.derp.permission.node.2", "derp",
"some.derp.permission.node.3", "derp",
"derp", "<b>Only derp people can %s<b>.\n<i>Ask a moderator to become derp."
);
public String getPermissionDeniedFormat(String permissionName)
{
Map<String, String> map = this.permissionDeniedFormats;
String ret = map.get(permissionName);
if (ret == null) return null;
ret = MUtil.recurseResolveMap(ret, map);
return ret;
}
public Map<String, Integer> permissionToTpdelay = MUtil.map(
"massivecore.notpdelay", 0,
"default", 10
);
public int getTpdelay(Permissible permissible)
{
Integer ret = PermUtil.pickFirstVal(permissible, permissionToTpdelay);
if (ret == null) ret = 0;
return ret;
}
public List<String> deleteFiles = new ArrayList<String>();
// Used in the MongoDB mstore driver.
public boolean catchingMongoDbErrorsOnSave = true;
public boolean catchingMongoDbErrorsOnDelete = true;
public static WriteConcern getMongoDbWriteConcern(boolean catchingErrors)
{
return catchingErrors ? WriteConcern.ACKNOWLEDGED : WriteConcern.UNACKNOWLEDGED;
}
public WriteConcern getMongoDbWriteConcernSave()
{
return getMongoDbWriteConcern(this.catchingMongoDbErrorsOnSave);
}
public WriteConcern getMongoDbWriteConcernDelete()
{
return getMongoDbWriteConcern(this.catchingMongoDbErrorsOnDelete);
}
public String variableBook = "***book***";
public boolean usingVariableBook = true;
public String variableBuffer = "***buffer***";
public boolean usingVariableBuffer = true;
}

View File

@@ -0,0 +1,31 @@
package com.massivecraft.massivecore;
import com.massivecraft.massivecore.MassiveCore;
import com.massivecraft.massivecore.store.Coll;
import com.massivecraft.massivecore.store.MStore;
public class MassiveCoreMConfColl extends Coll<MassiveCoreMConf>
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static MassiveCoreMConfColl i = new MassiveCoreMConfColl();
public static MassiveCoreMConfColl get() { return i; }
private MassiveCoreMConfColl()
{
super("massivecore_mconf", MassiveCoreMConf.class, MStore.getDb(ConfServer.dburi), MassiveCore.get());
}
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public void init()
{
super.init();
MassiveCoreMConf.i = this.get(MassiveCore.INSTANCE, true);
}
}

View File

@@ -0,0 +1,79 @@
package com.massivecraft.massivecore;
import org.bukkit.permissions.Permissible;
import com.massivecraft.massivecore.util.PermUtil;
public enum MassiveCorePerm
{
// -------------------------------------------- //
// ENUM
// -------------------------------------------- //
BASECOMMAND("basecommand"),
TEST("test"),
ID("id"),
VERSION("version"),
HEARSOUND("hearsound"),
STORE("store"),
STORE_STATS("store.stats"),
STORE_LISTCOLLS("store.listcolls"),
STORE_COPYDB("store.copydb"),
USYS("usys"),
USYS_MULTIVERSE("usys.multiverse"),
USYS_MULTIVERSE_LIST("usys.multiverse.list"),
USYS_MULTIVERSE_SHOW("usys.multiverse.show"),
USYS_MULTIVERSE_NEW("usys.multiverse.new"),
USYS_MULTIVERSE_DEL("usys.multiverse.del"),
USYS_UNIVERSE("usys.universe"),
USYS_UNIVERSE_NEW("usys.universe.new"),
USYS_UNIVERSE_DEL("usys.universe.del"),
USYS_UNIVERSE_CLEAR("usys.universe.clear"),
USYS_WORLD("usys.world"),
USYS_ASPECT("usys.aspect"),
USYS_ASPECT_LIST("usys.aspect.list"),
USYS_ASPECT_SHOW("usys.aspect.show"),
USYS_ASPECT_USE("usys.aspect.use"),
BUFFER("buffer"),
BUFFER_PRINT("buffer.print"),
BUFFER_CLEAR("buffer.clear"),
BUFFER_SET("buffer.set"),
BUFFER_ADD("buffer.add"),
BUFFER_WHITESPACE("buffer.whitespace"),
CMDURL("cmdurl"),
NOTPDELAY("notpdelay"),
VARIABLE_BOOK("variable.book"),
VARIABLE_BUFFER("variable.buffer"),
// END OF LIST
;
// -------------------------------------------- //
// FIELDS
// -------------------------------------------- //
public final String node;
// -------------------------------------------- //
// CONSTRUCT
// -------------------------------------------- //
MassiveCorePerm(final String permissionNode)
{
this.node = "massivecore."+permissionNode;
}
// -------------------------------------------- //
// HAS
// -------------------------------------------- //
public boolean has(Permissible permissible, boolean informSenderIfNot)
{
return PermUtil.has(permissible, this.node, informSenderIfNot);
}
public boolean has(Permissible permissible)
{
return has(permissible, false);
}
}

View File

@@ -0,0 +1,28 @@
package com.massivecraft.massivecore;
import java.io.File;
public class MassiveCoreTaskDeleteFiles implements Runnable
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static MassiveCoreTaskDeleteFiles i = new MassiveCoreTaskDeleteFiles();
public static MassiveCoreTaskDeleteFiles get() { return i; }
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public void run()
{
for (String deleteFile : MassiveCoreMConf.get().deleteFiles)
{
File file = new File(deleteFile);
file.delete();
}
}
}

View File

@@ -0,0 +1,143 @@
package com.massivecraft.massivecore;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.event.Listener;
import org.bukkit.plugin.java.JavaPlugin;
import com.massivecraft.massivecore.cmd.MassiveCommand;
import com.massivecraft.massivecore.integration.IntegrationGlue;
import com.massivecraft.massivecore.integration.Integration;
import com.massivecraft.massivecore.store.Coll;
import com.massivecraft.massivecore.util.Txt;
import com.massivecraft.massivecore.xlib.gson.Gson;
import com.massivecraft.massivecore.xlib.gson.GsonBuilder;
public abstract class MassivePlugin extends JavaPlugin implements Listener
{
// Gson
public Gson gson;
// -------------------------------------------- //
// ENABLE
// -------------------------------------------- //
private long timeEnableStart;
public boolean preEnable()
{
timeEnableStart = System.currentTimeMillis();
this.logPrefixColored = Txt.parse("<teal>[<aqua>%s %s<teal>] <i>", this.getDescription().getName(), this.getDescription().getVersion());
this.logPrefixPlain = ChatColor.stripColor(this.logPrefixColored);
log("=== ENABLE START ===");
// Create Gson
this.gson = this.getGsonBuilder().create();
// Listener
Bukkit.getPluginManager().registerEvents(this, this);
// Metrics
try
{
MetricsLite metrics = new MetricsLite(this);
metrics.start();
}
catch (IOException e)
{
String message = Txt.parse("<b>Metrics Initialization Failed :'(");
log(message);
}
return true;
}
public void postEnable()
{
log(Txt.parse("=== ENABLE <g>COMPLETE <i>(Took <h>"+(System.currentTimeMillis()-timeEnableStart)+"ms<i>) ==="));
}
@Override
public void onEnable()
{
if (!this.preEnable()) return;
this.postEnable();
}
// -------------------------------------------- //
// DISABLE
// -------------------------------------------- //
@Override
public void onDisable()
{
// Commands
MassiveCommand.unregister(this);
// Collections
for (Coll<?> coll : Coll.getInstances())
{
if (coll.getPlugin() != this) continue;
coll.deinit();
}
log("Disabled");
}
// -------------------------------------------- //
// GSON
// -------------------------------------------- //
public GsonBuilder getGsonBuilder()
{
return MassiveCore.getMassiveCoreGsonBuilder();
}
// -------------------------------------------- //
// CONVENIENCE
// -------------------------------------------- //
public void suicide()
{
log(Txt.parse("<b>Now I suicide!"));
Bukkit.getPluginManager().disablePlugin(this);
}
public void integrate(Integration... features)
{
for (Integration f : features)
{
new IntegrationGlue(this, f);
}
}
// -------------------------------------------- //
// LOGGING
// -------------------------------------------- //
private String logPrefixColored = null;
private String logPrefixPlain = null;
public void log(Object... msg)
{
log(Level.INFO, msg);
}
public void log(Level level, Object... msg)
{
String imploded = Txt.implode(msg, " ");
ConsoleCommandSender sender = Bukkit.getConsoleSender();
if (level == Level.INFO && sender != null)
{
Bukkit.getConsoleSender().sendMessage(this.logPrefixColored + imploded);
}
else
{
Logger.getLogger("Minecraft").log(level, this.logPrefixPlain + imploded);
}
}
}

View File

@@ -0,0 +1,68 @@
package com.massivecraft.massivecore;
import java.util.List;
import org.bukkit.metadata.MetadataValue;
import org.bukkit.metadata.MetadataValueAdapter;
import org.bukkit.metadata.Metadatable;
import org.bukkit.plugin.Plugin;
public class MetadataSimple extends MetadataValueAdapter
{
// -------------------------------------------- //
// FIELDS
// -------------------------------------------- //
private Object value;
// -------------------------------------------- //
// CONSTRUCT
// -------------------------------------------- //
public MetadataSimple(Plugin plugin, Object value)
{
super(plugin);
this.value = value;
}
// -------------------------------------------- //
// CONSTRUCT
// -------------------------------------------- //
@Override
public Object value()
{
return this.value;
}
@Override
public void invalidate()
{
// This can not be invalidated
}
// -------------------------------------------- //
// UTIL
// -------------------------------------------- //
public static void set(Plugin plugin, Metadatable metadatable, String key, Object value)
{
metadatable.setMetadata(key, new MetadataSimple(plugin, value));
}
public static MetadataValue getMeta(Metadatable metadatable, String key)
{
List<MetadataValue> metaValues = metadatable.getMetadata(key);
if (metaValues == null) return null;
if (metaValues.size() < 1) return null;
return metaValues.get(0);
}
public static Object get(Metadatable metadatable, String key)
{
MetadataValue metaValue = getMeta(metadatable, key);
if (metaValue == null) return null;
return metaValue.value();
}
}

View File

@@ -0,0 +1,515 @@
/*
* Copyright 2011-2013 Tyler Blair. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ''AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and contributors and should not be interpreted as representing official policies,
* either expressed or implied, of anybody else.
*/
package com.massivecraft.massivecore;
import org.bukkit.Bukkit;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginDescriptionFile;
import org.bukkit.scheduler.BukkitTask;
import com.massivecraft.massivecore.util.MUtil;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.Proxy;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.UUID;
import java.util.logging.Level;
import java.util.zip.GZIPOutputStream;
public class MetricsLite {
/**
* The current revision number
*/
private final static int REVISION = 7;
/**
* The base url of the metrics domain
*/
private static final String BASE_URL = "http://report.mcstats.org";
/**
* The url used to report a server's status
*/
private static final String REPORT_URL = "/plugin/%s";
/**
* Interval of time to ping (in minutes)
*/
private final static int PING_INTERVAL = 15;
/**
* The plugin this metrics submits for
*/
private final Plugin plugin;
/**
* The plugin configuration file
*/
private final YamlConfiguration configuration;
/**
* The plugin configuration file
*/
private final File configurationFile;
/**
* Unique server id
*/
private final String guid;
/**
* Debug mode
*/
private final boolean debug;
/**
* Lock for synchronization
*/
private final Object optOutLock = new Object();
/**
* Id of the scheduled task
*/
private volatile BukkitTask task = null;
public MetricsLite(Plugin plugin) throws IOException {
if (plugin == null) {
throw new IllegalArgumentException("Plugin cannot be null");
}
this.plugin = plugin;
// load the config
configurationFile = getConfigFile();
configuration = YamlConfiguration.loadConfiguration(configurationFile);
// add some defaults
configuration.addDefault("opt-out", false);
configuration.addDefault("guid", UUID.randomUUID().toString());
configuration.addDefault("debug", false);
// Do we need to create the file?
if (configuration.get("guid", null) == null) {
configuration.options().header("http://mcstats.org").copyDefaults(true);
configuration.save(configurationFile);
}
// Load the guid then
guid = configuration.getString("guid");
debug = configuration.getBoolean("debug", false);
}
/**
* Start measuring statistics. This will immediately create an async repeating task as the plugin and send
* the initial data to the metrics backend, and then after that it will post in increments of
* PING_INTERVAL * 1200 ticks.
*
* @return True if statistics measuring is running, otherwise false.
*/
public boolean start() {
synchronized (optOutLock) {
// Did we opt out?
if (isOptOut()) {
return false;
}
// Is metrics already running?
if (task != null) {
return true;
}
// Begin hitting the server with glorious data
task = plugin.getServer().getScheduler().runTaskTimerAsynchronously(plugin, new Runnable() {
private boolean firstPost = true;
public void run() {
try {
// This has to be synchronized or it can collide with the disable method.
synchronized (optOutLock) {
// Disable Task, if it is running and the server owner decided to opt-out
if (isOptOut() && task != null) {
task.cancel();
task = null;
}
}
// We use the inverse of firstPost because if it is the first time we are posting,
// it is not a interval ping, so it evaluates to FALSE
// Each time thereafter it will evaluate to TRUE, i.e PING!
postPlugin(!firstPost);
// After the first post we set firstPost to false
// Each post thereafter will be a ping
firstPost = false;
} catch (IOException e) {
if (debug) {
Bukkit.getLogger().log(Level.INFO, "[Metrics] " + e.getMessage());
}
}
}
}, 0, PING_INTERVAL * 1200);
return true;
}
}
/**
* Has the server owner denied plugin metrics?
*
* @return true if metrics should be opted out of it
*/
public boolean isOptOut() {
synchronized (optOutLock) {
try {
// Reload the metrics file
configuration.load(getConfigFile());
} catch (IOException ex) {
if (debug) {
Bukkit.getLogger().log(Level.INFO, "[Metrics] " + ex.getMessage());
}
return true;
} catch (InvalidConfigurationException ex) {
if (debug) {
Bukkit.getLogger().log(Level.INFO, "[Metrics] " + ex.getMessage());
}
return true;
}
return configuration.getBoolean("opt-out", false);
}
}
/**
* Enables metrics for the server by setting "opt-out" to false in the config file and starting the metrics task.
*
* @throws java.io.IOException
*/
public void enable() throws IOException {
// This has to be synchronized or it can collide with the check in the task.
synchronized (optOutLock) {
// Check if the server owner has already set opt-out, if not, set it.
if (isOptOut()) {
configuration.set("opt-out", false);
configuration.save(configurationFile);
}
// Enable Task, if it is not running
if (task == null) {
start();
}
}
}
/**
* Disables metrics for the server by setting "opt-out" to true in the config file and canceling the metrics task.
*
* @throws java.io.IOException
*/
public void disable() throws IOException {
// This has to be synchronized or it can collide with the check in the task.
synchronized (optOutLock) {
// Check if the server owner has already set opt-out, if not, set it.
if (!isOptOut()) {
configuration.set("opt-out", true);
configuration.save(configurationFile);
}
// Disable Task, if it is running
if (task != null) {
task.cancel();
task = null;
}
}
}
/**
* Gets the File object of the config file that should be used to store data such as the GUID and opt-out status
*
* @return the File object for the config file
*/
public File getConfigFile() {
// I believe the easiest way to get the base folder (e.g craftbukkit set via -P) for plugins to use
// is to abuse the plugin object we already have
// plugin.getDataFolder() => base/plugins/PluginA/
// pluginsFolder => base/plugins/
// The base is not necessarily relative to the startup directory.
File pluginsFolder = plugin.getDataFolder().getParentFile();
// return => base/plugins/PluginMetrics/config.yml
return new File(new File(pluginsFolder, "PluginMetrics"), "config.yml");
}
/**
* Generic method that posts a plugin to the metrics website
*/
private void postPlugin(boolean isPing) throws IOException {
// Server software specific section
PluginDescriptionFile description = plugin.getDescription();
String pluginName = description.getName();
boolean onlineMode = Bukkit.getServer().getOnlineMode(); // TRUE if online mode is enabled
String pluginVersion = description.getVersion();
String serverVersion = Bukkit.getVersion();
int playersOnline = MUtil.getOnlinePlayers().size();
// END server software specific section -- all code below does not use any code outside of this class / Java
// Construct the post data
StringBuilder json = new StringBuilder(1024);
json.append('{');
// The plugin's description file containg all of the plugin data such as name, version, author, etc
appendJSONPair(json, "guid", guid);
appendJSONPair(json, "plugin_version", pluginVersion);
appendJSONPair(json, "server_version", serverVersion);
appendJSONPair(json, "players_online", Integer.toString(playersOnline));
// New data as of R6
String osname = System.getProperty("os.name");
String osarch = System.getProperty("os.arch");
String osversion = System.getProperty("os.version");
String java_version = System.getProperty("java.version");
int coreCount = Runtime.getRuntime().availableProcessors();
// normalize os arch .. amd64 -> x86_64
if (osarch.equals("amd64")) {
osarch = "x86_64";
}
appendJSONPair(json, "osname", osname);
appendJSONPair(json, "osarch", osarch);
appendJSONPair(json, "osversion", osversion);
appendJSONPair(json, "cores", Integer.toString(coreCount));
appendJSONPair(json, "auth_mode", onlineMode ? "1" : "0");
appendJSONPair(json, "java_version", java_version);
// If we're pinging, append it
if (isPing) {
appendJSONPair(json, "ping", "1");
}
// close json
json.append('}');
// Create the url
URL url = new URL(BASE_URL + String.format(REPORT_URL, urlEncode(pluginName)));
// Connect to the website
URLConnection connection;
// Mineshafter creates a socks proxy, so we can safely bypass it
// It does not reroute POST requests so we need to go around it
if (isMineshafterPresent()) {
connection = url.openConnection(Proxy.NO_PROXY);
} else {
connection = url.openConnection();
}
byte[] uncompressed = json.toString().getBytes();
byte[] compressed = gzip(json.toString());
// Headers
connection.addRequestProperty("User-Agent", "MCStats/" + REVISION);
connection.addRequestProperty("Content-Type", "application/json");
connection.addRequestProperty("Content-Encoding", "gzip");
connection.addRequestProperty("Content-Length", Integer.toString(compressed.length));
connection.addRequestProperty("Accept", "application/json");
connection.addRequestProperty("Connection", "close");
connection.setDoOutput(true);
if (debug) {
System.out.println("[Metrics] Prepared request for " + pluginName + " uncompressed=" + uncompressed.length + " compressed=" + compressed.length);
}
// Write the data
OutputStream os = connection.getOutputStream();
os.write(compressed);
os.flush();
// Now read the response
final BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String response = reader.readLine();
// close resources
os.close();
reader.close();
if (response == null || response.startsWith("ERR") || response.startsWith("7")) {
if (response == null) {
response = "null";
} else if (response.startsWith("7")) {
response = response.substring(response.startsWith("7,") ? 2 : 1);
}
throw new IOException(response);
}
}
/**
* GZip compress a string of bytes
*
* @param input
* @return
*/
public static byte[] gzip(String input) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
GZIPOutputStream gzos = null;
try {
gzos = new GZIPOutputStream(baos);
gzos.write(input.getBytes("UTF-8"));
} catch (IOException e) {
e.printStackTrace();
} finally {
if (gzos != null) try {
gzos.close();
} catch (IOException ignore) {
}
}
return baos.toByteArray();
}
/**
* Check if mineshafter is present. If it is, we need to bypass it to send POST requests
*
* @return true if mineshafter is installed on the server
*/
private boolean isMineshafterPresent() {
try {
Class.forName("mineshafter.MineServer");
return true;
} catch (Exception e) {
return false;
}
}
/**
* Appends a json encoded key/value pair to the given string builder.
*
* @param json
* @param key
* @param value
* @throws UnsupportedEncodingException
*/
private static void appendJSONPair(StringBuilder json, String key, String value) throws UnsupportedEncodingException {
boolean isValueNumeric = false;
try {
if (value.equals("0") || !value.endsWith("0")) {
Double.parseDouble(value);
isValueNumeric = true;
}
} catch (NumberFormatException e) {
isValueNumeric = false;
}
if (json.charAt(json.length() - 1) != '{') {
json.append(',');
}
json.append(escapeJSON(key));
json.append(':');
if (isValueNumeric) {
json.append(value);
} else {
json.append(escapeJSON(value));
}
}
/**
* Escape a string to create a valid JSON string
*
* @param text
* @return
*/
private static String escapeJSON(String text) {
StringBuilder builder = new StringBuilder();
builder.append('"');
for (int index = 0; index < text.length(); index++) {
char chr = text.charAt(index);
switch (chr) {
case '"':
case '\\':
builder.append('\\');
builder.append(chr);
break;
case '\b':
builder.append("\\b");
break;
case '\t':
builder.append("\\t");
break;
case '\n':
builder.append("\\n");
break;
case '\r':
builder.append("\\r");
break;
default:
if (chr < ' ') {
String t = "000" + Integer.toHexString(chr);
builder.append("\\u" + t.substring(t.length() - 4));
} else {
builder.append(chr);
}
break;
}
}
builder.append('"');
return builder.toString();
}
/**
* Encode text as UTF-8
*
* @param text the text to encode
* @return the encoded text, as UTF-8
*/
private static String urlEncode(final String text) throws UnsupportedEncodingException {
return URLEncoder.encode(text, "UTF-8");
}
}

View File

@@ -0,0 +1,91 @@
package com.massivecraft.massivecore;
/**
* This class will allow you to create non-tps-dependent repeating tasks.
* It makes use of the Bukkit scheduler internally.
*/
public abstract class ModuloRepeatTask extends EngineAbstract
{
// -------------------------------------------- //
// FIELDS: RAW
// -------------------------------------------- //
// How many milliseconds should approximately pass between each invocation?
private long delayMillis;
public long getDelayMillis() { return this.delayMillis; }
public void setDelayMillis(long delayMillis) { this.delayMillis = delayMillis; }
// When did the last invocation occur?
private long previousMillis;
public long getPreviousMillis() { return this.previousMillis; }
public void setPreviousMillis(long previousMillis) { this.previousMillis = previousMillis; }
// TODO: Convertion Dust
// private Integer taskId = null;
// -------------------------------------------- //
// INVOCATION NUMBER CALCULATION
// -------------------------------------------- //
public long getInvocation(long now)
{
return now / this.getDelayMillis();
}
// -------------------------------------------- //
// CONSTRUCT
// -------------------------------------------- //
public ModuloRepeatTask()
{
this(0);
}
public ModuloRepeatTask(long delayMilis)
{
this(delayMilis, System.currentTimeMillis());
}
public ModuloRepeatTask(long delayMilis, long previousMillis)
{
this.delayMillis = delayMilis;
this.previousMillis = previousMillis;
}
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public Long getPeriod()
{
return 1L;
}
@Override
public void run()
{
// So the delay millis is lower than one? (could for example be zero)
// This probably means the task should not be executed at all.
if (this.getDelayMillis() < 1) return;
long nowMillis = System.currentTimeMillis();
long previousMillis = this.getPreviousMillis();
long currentInvocation = this.getInvocation(nowMillis);
long previousInvocation = this.getInvocation(previousMillis);
if (currentInvocation == previousInvocation) return;
this.invoke(nowMillis);
this.setPreviousMillis(nowMillis);
}
// -------------------------------------------- //
// ABSTRACT
// -------------------------------------------- //
public abstract void invoke(long now);
}

View File

@@ -0,0 +1,178 @@
package com.massivecraft.massivecore;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeSet;
import com.massivecraft.massivecore.cmd.arg.ARUniverse;
import com.massivecraft.massivecore.store.Entity;
import com.massivecraft.massivecore.util.MUtil;
public class Multiverse extends Entity<Multiverse>
{
// -------------------------------------------- //
// META
// -------------------------------------------- //
public static Multiverse get(Object oid)
{
return MultiverseColl.get().get(oid);
}
// -------------------------------------------- //
// FIELDS
// -------------------------------------------- //
protected Map<String, Set<String>> uw = new HashMap<String, Set<String>>();
// -------------------------------------------- //
// CONSTRUCT
// -------------------------------------------- //
public Multiverse()
{
}
// -------------------------------------------- //
// ASPECTS
// -------------------------------------------- //
public List<Aspect> myAspects()
{
return AspectColl.get().getAllRegisteredForMultiverse(this, true);
}
public List<Aspect> otherAspects()
{
return AspectColl.get().getAllRegisteredForMultiverse(this, false);
}
// -------------------------------------------- //
// UNIVERSE
// -------------------------------------------- //
public boolean containsUniverse(String universe)
{
return this.getUniverses().contains(universe);
}
public Set<String> newUniverse(String universe)
{
if (universe.equals(MassiveCore.DEFAULT)) return null;
Set<String> ret = this.uw.get(universe);
if (ret == null)
{
ret = new HashSet<String>();
this.uw.put(universe, ret);
}
return ret;
}
public Set<String> delUniverse(String universe)
{
return this.uw.remove(universe);
}
public Set<String> getUniverses()
{
Set<String> ret = new TreeSet<String>();
ret.addAll(this.uw.keySet());
ret.add(MassiveCore.DEFAULT);
return ret;
}
public String getUniverseForWorldName(String worldName)
{
for (Entry<String, Set<String>> entry : this.uw.entrySet())
{
String universe = entry.getKey();
Set<String> worlds = entry.getValue();
if (worlds.contains(worldName)) return universe;
}
return MassiveCore.DEFAULT;
}
public String getUniverse(Object worldNameExtractable)
{
String worldName = MUtil.extract(String.class, "worldName", worldNameExtractable);
return this.getUniverseForWorldName(worldName);
}
// -------------------------------------------- //
// UNIVERSE AND WORLD
// -------------------------------------------- //
public boolean clearUniverse(String universe)
{
Set<String> worlds = this.uw.get(universe);
if (worlds == null) return false;
worlds.clear();
return true;
}
public boolean setWorldUniverse(String worldName, String universe)
{
if (this.getUniverseForWorldName(worldName).equals(universe)) return false;
this.removeWorld(worldName);
if (!universe.equals(MassiveCore.DEFAULT))
{
this.newUniverse(universe).add(worldName);
}
return true;
}
// -------------------------------------------- //
// WORLD
// -------------------------------------------- //
public boolean containsWorld(String worldName)
{
return this.getWorlds().contains(worldName);
}
public Set<String> getWorlds()
{
Set<String> ret = new TreeSet<String>();
for (Set<String> uworlds : this.uw.values())
{
ret.addAll(uworlds);
}
return ret;
}
public Set<String> getWorlds(String universe)
{
Set<String> orig = this.uw.get(universe);
if (orig == null) return null;
Set<String> ret = new TreeSet<String>();
ret.addAll(orig);
return ret;
}
public boolean removeWorld(String worldName)
{
for (Set<String> worldNames : this.uw.values())
{
if(worldNames.remove(worldName)) return true;
}
return false;
}
// -------------------------------------------- //
// ARG READERS
// -------------------------------------------- //
public ARUniverse argReaderUniverse()
{
return new ARUniverse(this);
}
}

View File

@@ -0,0 +1,32 @@
package com.massivecraft.massivecore;
import com.massivecraft.massivecore.store.Coll;
import com.massivecraft.massivecore.store.MStore;
public class MultiverseColl extends Coll<Multiverse>
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static MultiverseColl i = new MultiverseColl();
public static MultiverseColl get() { return i; }
private MultiverseColl()
{
super("massivecore_multiverse", Multiverse.class, MStore.getDb("default"), MassiveCore.get());
}
// -------------------------------------------- //
// EXTRAS
// -------------------------------------------- //
@Override
public void init()
{
super.init();
// Ensure the default multiverse exits
this.get(MassiveCore.DEFAULT, true);
}
}

View File

@@ -0,0 +1,188 @@
/*
NaturalOrderComparator.java -- Perform 'natural order' comparisons of strings in Java.
Copyright (C) 2003 by Pierre-Luc Paour <natorder@paour.com>
Based on the C version by Martin Pool, of which this is more or less a straight conversion.
Copyright (C) 2000 by Martin Pool <mbp@humbug.org.au>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
/*
This version has been slightly modified for usage in the MassiveCore library.
Check out the original at: https://github.com/paour/natorder/blob/master/NaturalOrderComparator.java
*/
package com.massivecraft.massivecore;
import java.util.*;
public class NaturalOrderComparator implements Comparator<Object>
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static transient NaturalOrderComparator i = new NaturalOrderComparator();
public static NaturalOrderComparator get() { return i; }
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public int compare(Object o1, Object o2)
{
String a = o1.toString();
String b = o2.toString();
int ia = 0, ib = 0;
int nza = 0, nzb = 0;
char ca, cb;
int result;
while (true)
{
// only count the number of zeroes leading the last number compared
nza = nzb = 0;
ca = charAt(a, ia);
cb = charAt(b, ib);
// skip over leading spaces or zeros
while (Character.isSpaceChar(ca) || ca == '0')
{
if (ca == '0')
{
nza++;
}
else
{
// only count consecutive zeroes
nza = 0;
}
ca = charAt(a, ++ia);
}
while (Character.isSpaceChar(cb) || cb == '0')
{
if (cb == '0')
{
nzb++;
}
else
{
// only count consecutive zeroes
nzb = 0;
}
cb = charAt(b, ++ib);
}
// process run of digits
if (Character.isDigit(ca) && Character.isDigit(cb))
{
if ((result = compareRight(a.substring(ia), b.substring(ib))) != 0)
{
return result;
}
}
if (ca == 0 && cb == 0)
{
// The strings compare the same. Perhaps the caller
// will want to call strcmp to break the tie.
return nza - nzb;
}
if (ca < cb)
{
return -1;
}
else if (ca > cb)
{
return +1;
}
++ia;
++ib;
}
}
// -------------------------------------------- //
// UTIL
// -------------------------------------------- //
int compareRight(String a, String b)
{
int bias = 0;
int ia = 0;
int ib = 0;
// The longest run of digits wins. That aside, the greatest
// value wins, but we can't know that it will until we've scanned
// both numbers to know that they have the same magnitude, so we
// remember it in BIAS.
for (;; ia++, ib++)
{
char ca = charAt(a, ia);
char cb = charAt(b, ib);
if (!Character.isDigit(ca) && !Character.isDigit(cb))
{
return bias;
}
else if (!Character.isDigit(ca))
{
return -1;
}
else if (!Character.isDigit(cb))
{
return +1;
}
else if (ca < cb)
{
if (bias == 0)
{
bias = -1;
}
}
else if (ca > cb)
{
if (bias == 0)
bias = +1;
}
else if (ca == 0 && cb == 0)
{
return bias;
}
}
}
static char charAt(String s, int i)
{
if (i >= s.length())
{
return 0;
}
else
{
return s.charAt(i);
}
}
}

View File

@@ -0,0 +1,6 @@
package com.massivecraft.massivecore;
public interface Predictate<T>
{
public boolean apply(T type);
}

View File

@@ -0,0 +1,49 @@
package com.massivecraft.massivecore;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
public class PredictateAnd<T> implements Predictate<T>
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
@SafeVarargs
public static <T> PredictateAnd<T> get(Predictate<T>... predictates) { return new PredictateAnd<T>(predictates); }
@SafeVarargs
public PredictateAnd(Predictate<T>... predictates)
{
this(Arrays.asList(predictates));
}
public static <T> PredictateAnd<T> get(Collection<Predictate<T>> predictates) { return new PredictateAnd<T>(predictates); }
public PredictateAnd(Collection<Predictate<T>> predictates)
{
this.predictates = Collections.unmodifiableList(new ArrayList<Predictate<T>>(predictates));
}
// -------------------------------------------- //
// FIELDS
// -------------------------------------------- //
private final List<Predictate<T>> predictates;
public List<Predictate<T>> getPredictates() { return this.predictates; }
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public boolean apply(T type)
{
for (Predictate<T> predictate : this.getPredictates())
{
if (!predictate.apply(type)) return false;
}
return true;
}
}

View File

@@ -0,0 +1,22 @@
package com.massivecraft.massivecore;
public class PredictateIsRegistered implements Predictate<Registerable>
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static PredictateIsRegistered i = new PredictateIsRegistered();
public static PredictateIsRegistered get() { return i; }
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public boolean apply(Registerable registerable)
{
return registerable.isRegistered();
}
}

View File

@@ -0,0 +1,24 @@
package com.massivecraft.massivecore;
import com.massivecraft.massivecore.store.Entity;
public class PredictateIsntDefaultEntity implements Predictate<Entity<?>>
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static PredictateIsntDefaultEntity i = new PredictateIsntDefaultEntity();
public static PredictateIsntDefaultEntity get() { return i; }
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public boolean apply(Entity<?> entity)
{
return !entity.isDefault();
}
}

View File

@@ -0,0 +1,6 @@
package com.massivecraft.massivecore;
public interface Prioritized
{
public int getPriority();
}

View File

@@ -0,0 +1,36 @@
package com.massivecraft.massivecore;
import java.util.Comparator;
public class PriorityComparator implements Comparator<Prioritized>
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static PriorityComparator i = new PriorityComparator();
public static PriorityComparator get() { return i; }
// -------------------------------------------- //
// OVERRIDE: COMPARATOR
// -------------------------------------------- //
@Override
public int compare(Prioritized one, Prioritized two)
{
if (one == null && two == null) return 0;
if (two == null) return 1;
if (one == null) return -1;
int ret = Integer.valueOf(one.getPriority()).compareTo(two.getPriority());
// We should only return 0 if the items actually are equal.
if (ret == 0 && ! one.equals(two))
{
ret = two.hashCode() - one.hashCode();
}
return ret;
}
}

View File

@@ -0,0 +1,104 @@
package com.massivecraft.massivecore;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import com.massivecraft.massivecore.Prioritized;
import com.massivecraft.massivecore.util.MUtil;
public class PriorityLines implements Prioritized, Comparable<PriorityLines>
{
// -------------------------------------------- //
// FIELDS
// -------------------------------------------- //
private int priority;
@Override public int getPriority() { return this.priority; }
public void setPriority(int priority) { this.priority = priority; }
private List<String> lines;
public List<String> getLines() { return this.lines; }
public void setLines(List<String> lines) { this.lines = lines; }
public void setLines(String... lines) { this.setLines(Arrays.asList(lines)); }
// -------------------------------------------- //
// CONSTRUCT
// -------------------------------------------- //
public PriorityLines(int priority, List<String> lines)
{
this.priority = priority;
this.lines = lines;
}
public PriorityLines(int priority, String... lines)
{
this(priority, Arrays.asList(lines));
}
public PriorityLines(int priority)
{
this(priority, new LinkedList<String>());
}
// -------------------------------------------- //
// TO STRING
// -------------------------------------------- //
@Override
public String toString()
{
return MassiveCore.gson.toJson(this);
}
// -------------------------------------------- //
// COMPARABLE
// -------------------------------------------- //
@Override
public int compareTo(PriorityLines that)
{
int ret;
ret = Integer.valueOf(this.priority).compareTo(that.priority);
if (ret != 0) return ret;
if (MUtil.equals(this.lines, that.lines)) return 0;
ret = HashCodeComparator.get().compare(this.lines, that.lines);
if (ret != 0) return ret;
return ret;
}
// -------------------------------------------- //
// HASH CODE & EQUALS
// -------------------------------------------- //
@Override
public int hashCode()
{
final int prime = 31;
int result = 1;
result = prime * result + ((lines == null) ? 0 : lines.hashCode());
result = prime * result + priority;
return result;
}
@Override
public boolean equals(Object obj)
{
if (this == obj) return true;
if (obj == null) return false;
if (!(obj instanceof PriorityLines)) return false;
PriorityLines other = (PriorityLines) obj;
if (lines == null)
{
if (other.lines != null) return false;
}
else if (!lines.equals(other.lines)) return false;
if (priority != other.priority) return false;
return true;
}
}

View File

@@ -0,0 +1,217 @@
package com.massivecraft.massivecore;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import com.massivecraft.massivecore.util.MUtil;
import com.massivecraft.massivecore.util.Txt;
public class Progressbar
{
// -------------------------------------------- //
// STANDARD INSTANCES
// -------------------------------------------- //
public static final transient Progressbar HEALTHBAR_CLASSIC = Progressbar.valueOf(1D, 30, "{c}[", "|", "&8", "|", "{c}]", 1D, "{c}", MUtil.map(
1.0D, "&2",
0.8D, "&a",
0.5D, "&e",
0.4D, "&6",
0.3D, "&c",
0.2D, "&4"
));
// -------------------------------------------- //
// FIELDS: RAW
// -------------------------------------------- //
private final double quota;
public double getQuota() { return this.quota; }
private final int width;
public int getWidth() { return this.width; }
private final String left;
public String getLeft() { return this.left; }
private final String solid;
public String getSolid() { return this.solid; }
private final String between;
public String getBetween() { return this.between; }
private final String empty;
public String getEmpty() { return this.empty; }
private final String right;
public String getRight() { return this.right; }
private final double solidsPerEmpty;
public double getSolidsPerEmpty() { return this.solidsPerEmpty; }
private final String colorTag;
public String getColorTag() { return this.colorTag; }
private final Map<Double, String> roofToColor;
public Map<Double, String> getRoofToColor() { return this.roofToColor; }
// -------------------------------------------- //
// FIELDS: WITH
// -------------------------------------------- //
public Progressbar withQuota(double quota) { return new Progressbar(quota, width, left, solid, between, empty, right, solidsPerEmpty, colorTag, roofToColor); }
public Progressbar withWidth(int width) { return new Progressbar(quota, width, left, solid, between, empty, right, solidsPerEmpty, colorTag, roofToColor); }
public Progressbar withLeft(String left) { return new Progressbar(quota, width, left, solid, between, empty, right, solidsPerEmpty, colorTag, roofToColor); }
public Progressbar withSolid(String solid) { return new Progressbar(quota, width, left, solid, between, empty, right, solidsPerEmpty, colorTag, roofToColor); }
public Progressbar withBetween(String between) { return new Progressbar(quota, width, left, solid, between, empty, right, solidsPerEmpty, colorTag, roofToColor); }
public Progressbar withEmpty(String empty) { return new Progressbar(quota, width, left, solid, between, empty, right, solidsPerEmpty, colorTag, roofToColor); }
public Progressbar withRight(String right) { return new Progressbar(quota, width, left, solid, between, empty, right, solidsPerEmpty, colorTag, roofToColor); }
public Progressbar withSolidsPerEmpty(double solidsPerEmpty) { return new Progressbar(quota, width, left, solid, between, empty, right, solidsPerEmpty, colorTag, roofToColor); }
public Progressbar withColorTag(String colorTag) { return new Progressbar(quota, width, left, solid, between, empty, right, solidsPerEmpty, colorTag, roofToColor); }
public Progressbar withRoofToColor(Map<Double, String> roofToColor) { return new Progressbar(quota, width, left, solid, between, empty, right, solidsPerEmpty, colorTag, roofToColor); }
// -------------------------------------------- //
// PRIVATE CONSTRUCTOR
// -------------------------------------------- //
private Progressbar(double quota, int width, String left, String solid, String between, String empty, String right, double solidsPerEmpty, String colorTag, Map<Double, String> roofToColor)
{
this.quota = quota;
this.width = width;
this.left = left;
this.solid = solid;
this.between = between;
this.empty = empty;
this.right = right;
this.solidsPerEmpty = solidsPerEmpty;
this.colorTag = colorTag;
this.roofToColor = Collections.unmodifiableMap(roofToColor);
}
// -------------------------------------------- //
// FACTORY: VALUE OF
// -------------------------------------------- //
public static Progressbar valueOf(double quota, int width, String left, String solid, String between, String empty, String right, double solidsPerEmpty, String colorTag, Map<Double, String> roofToColor)
{
return new Progressbar(quota, width, left, solid, between, empty, right, solidsPerEmpty, colorTag, roofToColor);
}
// -------------------------------------------- //
// INSTANCE METHODS
// -------------------------------------------- //
public String render()
{
return render(quota, width, left, solid, between, empty, right, solidsPerEmpty, colorTag, roofToColor);
}
public List<String> renderList()
{
return renderList(quota, width, left, solid, between, empty, right, solidsPerEmpty, colorTag, roofToColor);
}
// -------------------------------------------- //
// STATIC UTIL
// -------------------------------------------- //
public static String render(double quota, int width, String left, String solid, String between, String empty, String right, double solidsPerEmpty, String colorTag, Map<Double, String> roofToColor)
{
return Txt.implode(renderList(quota, width, left, solid, between, empty, right, solidsPerEmpty, colorTag, roofToColor), "");
}
public static List<String> renderList(double quota, int width, String left, String solid, String between, String empty, String right, double solidsPerEmpty, String colorTag, Map<Double, String> roofToColor)
{
// Create Ret
List<String> ret = new ArrayList<String>();
// Ensure between 0 and 1;
quota = limit(quota);
// What color is the health bar?
String color = pick(quota, roofToColor);
// how much solid should there be?
int solidCount = (int) Math.ceil(width * quota);
// The rest is empty
int emptyCount = (int) ((width - solidCount) / solidsPerEmpty);
// Color Parse Parts
left = colorParse(left, colorTag, color);
solid = colorParse(solid, colorTag, color);
between = colorParse(between, colorTag, color);
empty = colorParse(empty, colorTag, color);
right = colorParse(right, colorTag, color);
// Combine Parts
if (left != null)
{
ret.add(left);
}
if (solid != null)
{
for (int i = 1; i <= solidCount; i++)
{
ret.add(solid);
}
}
if (between != null)
{
ret.add(between);
}
if (empty != null)
{
for (int i = 1; i <= emptyCount; i++)
{
ret.add(empty);
}
}
if (right != null)
{
ret.add(right);
}
return ret;
}
public static String colorParse(String string, String colorTag, String color)
{
if (string == null) return null;
string = string.replace(colorTag, color);
string = Txt.parse(string);
return string;
}
public static double limit(double quota)
{
if (quota > 1) return 1;
if (quota < 0) return 0;
return quota;
}
public static <T> T pick(double quota, Map<Double, T> roofToValue)
{
Double currentRoof = null;
T ret = null;
for (Entry<Double, T> entry : roofToValue.entrySet())
{
double roof = entry.getKey();
T value = entry.getValue();
if (quota <= roof && (currentRoof == null || roof <= currentRoof))
{
currentRoof = roof;
ret = value;
}
}
return ret;
}
}

View File

@@ -0,0 +1,6 @@
package com.massivecraft.massivecore;
public interface Registerable
{
public boolean isRegistered();
}

View File

@@ -0,0 +1,36 @@
package com.massivecraft.massivecore;
import java.util.Comparator;
public class ReversePriorityComparator implements Comparator<Prioritized>
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static ReversePriorityComparator i = new ReversePriorityComparator();
public static ReversePriorityComparator get() { return i; }
// -------------------------------------------- //
// OVERRIDE: COMPARATOR
// -------------------------------------------- //
@Override
public int compare(Prioritized one, Prioritized two)
{
if (one == null && two == null) return 0;
if (two == null) return -1;
if (one == null) return 1;
int ret = Integer.valueOf(two.getPriority()).compareTo(one.getPriority());
// We should only return 0 if the items actually are equal.
if (ret == 0 && ! one.equals(two))
{
ret = one.hashCode() - two.hashCode();
}
return ret;
}
}

View File

@@ -0,0 +1,95 @@
package com.massivecraft.massivecore;
import java.io.File;
import org.bukkit.plugin.Plugin;
import com.massivecraft.massivecore.store.accessor.Accessor;
import com.massivecraft.massivecore.util.DiscUtil;
import com.massivecraft.massivecore.xlib.gson.Gson;
public class SimpleConfig
{
// -------------------------------------------- //
// FIELDS
// -------------------------------------------- //
protected transient Plugin plugin;
protected Plugin getPlugin() { return this.plugin; }
protected transient File file;
protected File getFile() { return this.file; }
public SimpleConfig(Plugin plugin, File file)
{
this.plugin = plugin;
this.file = file;
}
public SimpleConfig(Plugin plugin, String confname)
{
this(plugin, new File(plugin.getDataFolder(), confname+".json"));
}
public SimpleConfig(Plugin plugin)
{
this(plugin, "conf");
}
// -------------------------------------------- //
// IO
// -------------------------------------------- //
private Gson getGson()
{
if (this.plugin instanceof MassivePlugin)
{
return ((MassivePlugin)this.plugin).gson;
}
return MassiveCore.gson;
}
protected static boolean contentRequestsDefaults(String content)
{
if (content == null) return false;
if (content.length() == 0) return false;
char c = content.charAt(0);
return c == 'd' || c == 'D';
}
public void load()
{
if (this.getFile().isFile())
{
String content = DiscUtil.readCatch(this.getFile());
content = content.trim();
Object toShallowLoad = null;
if (contentRequestsDefaults(content))
{
try
{
toShallowLoad = this.getClass().newInstance();
}
catch (Exception e)
{
e.printStackTrace();
return;
}
}
else
{
toShallowLoad = this.getGson().fromJson(content, this.getClass());
}
Accessor.get(this.getClass()).copy(toShallowLoad, this);
}
save();
}
public void save()
{
String content = DiscUtil.readCatch(this.getFile());
if (contentRequestsDefaults(content)) return;
content = this.getGson().toJson(this);
DiscUtil.writeCatch(file, content);
}
}

View File

@@ -0,0 +1,172 @@
package com.massivecraft.massivecore;
import java.io.Serializable;
import java.util.Collection;
import org.bukkit.Location;
import org.bukkit.Sound;
import org.bukkit.entity.Player;
import com.massivecraft.massivecore.cmd.arg.ARSound;
public final class SoundEffect implements Cloneable, Serializable
{
private static final transient long serialVersionUID = 1L;
// -------------------------------------------- //
// FIELDS: RAW
// -------------------------------------------- //
private final Sound sound;
public Sound getSound() { return this.sound; }
private final float volume;
public float getVolume() { return this.volume; }
private final float pitch;
public float getPitch() { return this.pitch; }
// -------------------------------------------- //
// FIELDS: WITH
// -------------------------------------------- //
public SoundEffect withSound(Sound sound) { return new SoundEffect(sound, volume, pitch); }
public SoundEffect withVolume(float volume) { return new SoundEffect(sound, volume, pitch); }
public SoundEffect withPitch(float pitch) { return new SoundEffect(sound, volume, pitch); }
// -------------------------------------------- //
// CONSTUCT
// -------------------------------------------- //
private SoundEffect(Sound sound, float volume, float pitch)
{
this.sound = sound;
this.volume = volume;
this.pitch = pitch;
}
private SoundEffect()
{
// No Arg Constructor for GSON
this(null, 1.0f, 1.0f);
}
// -------------------------------------------- //
// VALUE OF
// -------------------------------------------- //
public static SoundEffect valueOf(Sound sound, float volume, float pitch)
{
return new SoundEffect(sound, volume, pitch);
}
public static SoundEffect valueOf(String soundString) throws Exception
{
if (soundString == null) throw new NullPointerException("soundString was null");
soundString = soundString.trim();
String[] parts = soundString.split("[^a-zA-Z0-9_.]+");
Sound sound = ARSound.getSoundFromString(parts[0]);
if (sound == null) throw new IllegalArgumentException("Unknown sound \"" + parts[0] + "\"");
float volume = 1.0f;
if (parts.length >= 2)
{
volume = Float.parseFloat(parts[1]);
}
float pitch = 1.0f;
if (parts.length >= 3)
{
pitch = Float.parseFloat(parts[2]);
}
return SoundEffect.valueOf(sound, volume, pitch);
}
// -------------------------------------------- //
// RUN
// -------------------------------------------- //
public void run(Location location)
{
location.getWorld().playSound(location, this.getSound(), this.getVolume(), this.getPitch());
}
public void run(Player player, Location location)
{
player.playSound(location, this.getSound(), this.getVolume(), this.getPitch());
}
public void run(Player player)
{
this.run(player, player.getEyeLocation());
}
// -------------------------------------------- //
// RUN ALL
// -------------------------------------------- //
public static void runAll(Collection<SoundEffect> soundEffects, Location location)
{
for (SoundEffect soundEffect : soundEffects)
{
soundEffect.run(location);
}
}
public static void runAll(Collection<SoundEffect> soundEffects, Player player, Location location)
{
for (SoundEffect soundEffect : soundEffects)
{
soundEffect.run(player, location);
}
}
public static void runAll(Collection<SoundEffect> soundEffects, Player player)
{
for (SoundEffect soundEffect : soundEffects)
{
soundEffect.run(player);
}
}
// -------------------------------------------- //
// CLONE
// -------------------------------------------- //
@Override
public SoundEffect clone()
{
return this;
}
// -------------------------------------------- //
// EQUALS & HASHCODE
// -------------------------------------------- //
@Override
public int hashCode()
{
final int prime = 31;
int result = 1;
result = prime * result + Float.floatToIntBits(pitch);
result = prime * result + ((sound == null) ? 0 : sound.hashCode());
result = prime * result + Float.floatToIntBits(volume);
return result;
}
@Override
public boolean equals(Object obj)
{
if (this == obj) return true;
if (obj == null) return false;
if (!(obj instanceof SoundEffect)) return false;
SoundEffect other = (SoundEffect) obj;
if (Float.floatToIntBits(pitch) != Float.floatToIntBits(other.pitch)) return false;
if (sound != other.sound) return false;
if (Float.floatToIntBits(volume) != Float.floatToIntBits(other.volume)) return false;
return true;
}
}

View File

@@ -0,0 +1,84 @@
package com.massivecraft.massivecore;
import java.io.Serializable;
import com.massivecraft.massivecore.util.MUtil;
public class Triple<A, B, C> implements Cloneable, Serializable
{
// -------------------------------------------- //
// CONSTANTS
// -------------------------------------------- //
private static final transient long serialVersionUID = 1L;
// -------------------------------------------- //
// FIELDS: RAW
// -------------------------------------------- //
private final A first;
public A getFirst() { return this.first; };
private final B second;
public B getSecond() { return this.second; };
private final C third;
public C getThird() { return this.third; };
// -------------------------------------------- //
// FIELDS: WITH
// -------------------------------------------- //
public Triple<A, B, C> withFirst(A first) { return valueOf(first, second, third); }
public Triple<A, B, C> withSecond(B second) { return valueOf(first, second, third); }
// -------------------------------------------- //
// CONSTRUCT
// -------------------------------------------- //
public Triple()
{
this(null, null, null);
}
public Triple(A first, B second, C third)
{
this.first = first;
this.second = second;
this.third = third;
}
// -------------------------------------------- //
// FACTORY: VALUE OF
// -------------------------------------------- //
public static <A, B, C> Triple<A, B, C> valueOf(A first, B second, C third)
{
return new Triple<A, B, C>(first, second, third);
}
// -------------------------------------------- //
// EQUALS
// -------------------------------------------- //
@Override
public boolean equals(Object derpObject)
{
if (derpObject == null) return false;
if (!(derpObject instanceof Triple<?, ?, ?>)) return false;
Triple<?, ?, ?> derp = (Triple<?, ?, ?>)derpObject;
return MUtil.equals(this.getFirst(), derp.getFirst()) && MUtil.equals(this.getSecond(), derp.getSecond()) && MUtil.equals(this.getThird(), derp.getThird());
}
// -------------------------------------------- //
// CLONE
// -------------------------------------------- //
@Override
public Triple<A, B, C> clone()
{
return this;
}
}

View File

@@ -0,0 +1,54 @@
package com.massivecraft.massivecore.adapter;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Set;
import com.massivecraft.massivecore.collections.BackstringEnumSet;
import com.massivecraft.massivecore.xlib.gson.JsonDeserializationContext;
import com.massivecraft.massivecore.xlib.gson.JsonDeserializer;
import com.massivecraft.massivecore.xlib.gson.JsonElement;
import com.massivecraft.massivecore.xlib.gson.JsonParseException;
import com.massivecraft.massivecore.xlib.gson.JsonSerializationContext;
import com.massivecraft.massivecore.xlib.gson.JsonSerializer;
import com.massivecraft.massivecore.xlib.gson.reflect.TypeToken;
public class BackstringEnumSetAdapter implements JsonDeserializer<BackstringEnumSet<?>>, JsonSerializer<BackstringEnumSet<?>>
{
// -------------------------------------------- //
// CONSTANTS
// -------------------------------------------- //
public final static Type stringSetType = new TypeToken<Set<String>>(){}.getType();
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static BackstringEnumSetAdapter i = new BackstringEnumSetAdapter();
public static BackstringEnumSetAdapter get() { return i; }
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public JsonElement serialize(BackstringEnumSet<?> src, Type type, JsonSerializationContext context)
{
return context.serialize(src.getStringSet(), stringSetType);
}
@SuppressWarnings({ "unchecked", "rawtypes" })
@Override
public BackstringEnumSet<?> deserialize(JsonElement json, Type type, JsonDeserializationContext context) throws JsonParseException
{
Set<String> stringSet = context.deserialize(json, stringSetType);
ParameterizedType ptype = (ParameterizedType) type;
Type[] args = ptype.getActualTypeArguments();
Class<?> clazz = (Class<?>) args[0];
return new BackstringEnumSet(clazz, stringSet);
}
}

View File

@@ -0,0 +1,145 @@
package com.massivecraft.massivecore.adapter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import org.bukkit.Color;
import org.bukkit.FireworkEffect;
import org.bukkit.FireworkEffect.Type;
import com.massivecraft.massivecore.util.MUtil;
import com.massivecraft.massivecore.xlib.gson.JsonArray;
import com.massivecraft.massivecore.xlib.gson.JsonElement;
import com.massivecraft.massivecore.xlib.gson.JsonObject;
import com.massivecraft.massivecore.xlib.gson.JsonPrimitive;
public class FireworkEffectAdapter
{
// -------------------------------------------- //
// FIELD CONSTANTS
// -------------------------------------------- //
public static final String FLICKER = "flicker";
public static final String TRAIL = "trail";
public static final String COLORS = "colors";
public static final String FADE_COLORS = "fade-colors";
public static final String TYPE = "type";
public static final boolean FLICKER_DEFAULT = false;
public static final boolean TRAIL_DEFAULT = false;
public static final List<Color> COLORS_DEFAULT = Collections.unmodifiableList(MUtil.list(Color.GREEN));
public static final List<Color> FADE_COLORS_DEFAULT = Collections.unmodifiableList(new ArrayList<Color>());
public static final Type TYPE_DEFAULT = Type.BALL_LARGE;
// -------------------------------------------- //
// TO JSON
// -------------------------------------------- //
public static JsonObject toJson(FireworkEffect fireworkEffect)
{
if (fireworkEffect == null) return null;
JsonObject ret = new JsonObject();
ret.addProperty(FLICKER, fireworkEffect.hasFlicker());
ret.addProperty(TRAIL, fireworkEffect.hasTrail());
ret.add(COLORS, fromColorCollection(fireworkEffect.getColors()));
ret.add(FADE_COLORS, fromColorCollection(fireworkEffect.getFadeColors()));
ret.addProperty(TYPE, fireworkEffect.getType().name());
return ret;
}
// -------------------------------------------- //
// FROM JSON
// -------------------------------------------- //
public static FireworkEffect fromJson(JsonElement jsonElement)
{
if (jsonElement == null) return null;
if ( ! jsonElement.isJsonObject()) return null;
JsonObject json = jsonElement.getAsJsonObject();
boolean flicker = FLICKER_DEFAULT;
boolean trail = TRAIL_DEFAULT;
List<Color> colors = COLORS_DEFAULT;
List<Color> fadeColors = FADE_COLORS_DEFAULT;
Type type = TYPE_DEFAULT;
JsonElement element;
element = json.get(FLICKER);
if (element != null)
{
flicker = element.getAsBoolean();
}
element = json.get(TRAIL);
if (element != null)
{
trail = element.getAsBoolean();
}
element = json.get(COLORS);
if (element != null)
{
colors = toColorCollection(element);
}
element = json.get(FADE_COLORS);
if (element != null)
{
fadeColors = toColorCollection(element);
}
element = json.get(TYPE);
if (element != null)
{
type = Type.valueOf(element.getAsString());
}
FireworkEffect ret = FireworkEffect.builder()
.flicker(flicker)
.trail(trail)
.withColor(colors)
.withFade(fadeColors)
.with(type)
.build();
return ret;
}
// -------------------------------------------- //
// MINI UTILS
// -------------------------------------------- //
public static JsonArray fromColorCollection(Collection<Color> colors)
{
JsonArray ret = new JsonArray();
for (Color color : colors)
{
ret.add(new JsonPrimitive(color.asRGB()));
}
return ret;
}
public static List<Color> toColorCollection(JsonElement json)
{
JsonArray array = json.getAsJsonArray();
List<Color> ret = new ArrayList<Color>();
Iterator<JsonElement> iter = array.iterator();
while (iter.hasNext())
{
JsonElement element = iter.next();
ret.add(Color.fromRGB(element.getAsInt()));
}
return ret;
}
}

View File

@@ -0,0 +1,222 @@
package com.massivecraft.massivecore.adapter;
import java.lang.reflect.Type;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.PlayerInventory;
import com.massivecraft.massivecore.MassiveCore;
import com.massivecraft.massivecore.mixin.Mixin;
import com.massivecraft.massivecore.xlib.gson.JsonDeserializationContext;
import com.massivecraft.massivecore.xlib.gson.JsonDeserializer;
import com.massivecraft.massivecore.xlib.gson.JsonElement;
import com.massivecraft.massivecore.xlib.gson.JsonObject;
import com.massivecraft.massivecore.xlib.gson.JsonParseException;
import com.massivecraft.massivecore.xlib.gson.JsonPrimitive;
import com.massivecraft.massivecore.xlib.gson.JsonSerializationContext;
import com.massivecraft.massivecore.xlib.gson.JsonSerializer;
/**
* This is my Gson adapter for Inventories.
* It handles all inventories as CraftInventoryCustom "Chest"s with size of your choice
* except for PlayerInventory which it handles pretty darn well!
*/
public class InventoryAdapter implements JsonDeserializer<Inventory>, JsonSerializer<Inventory>
{
// -------------------------------------------- //
// FIELD NAME CONSTANTS
// -------------------------------------------- //
public static final String SIZE = "size";
public static final String PLAYER = "player";
public static final String HELMET = "helmet";
public static final String CHESTPLATE = "chestplate";
public static final String LEGGINGS = "leggings";
public static final String BOOTS = "boots";
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static InventoryAdapter i = new InventoryAdapter();
public static InventoryAdapter get() { return i; }
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public JsonElement serialize(Inventory src, Type typeOfSrc, JsonSerializationContext context)
{
return toJson(src);
}
@Override
public Inventory deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException
{
return fromJson(json);
}
// -------------------------------------------- //
// IMPLEMENTATION
// -------------------------------------------- //
public static JsonElement toJson(Inventory src)
{
// The return value is this object:
JsonObject jsonInventory = new JsonObject();
// These variables are used in loops and repetitive logic.
ItemStack itemStack = null;
JsonElement jsonItemStack = null;
// Every inventory has a content part.
ItemStack[] itemStacks = src.getContents();
if (src instanceof PlayerInventory)
{
// Add the size "player"
jsonInventory.addProperty(SIZE, PLAYER);
// Cast to PlayerInventory
PlayerInventory psrc = (PlayerInventory)src;
// helmet
itemStack = psrc.getHelmet();
if (itemStack != null)
{
jsonItemStack = MassiveCore.gson.toJsonTree(itemStack, ItemStack.class);
jsonInventory.add(HELMET, jsonItemStack);
}
// chestplate
itemStack = psrc.getChestplate();
if (itemStack != null)
{
jsonItemStack = MassiveCore.gson.toJsonTree(itemStack, ItemStack.class);
jsonInventory.add(CHESTPLATE, jsonItemStack);
}
// leggings
itemStack = psrc.getLeggings();
if (itemStack != null)
{
jsonItemStack = MassiveCore.gson.toJsonTree(itemStack, ItemStack.class);
jsonInventory.add(LEGGINGS, jsonItemStack);
}
// boots
itemStack = psrc.getBoots();
if (itemStack != null)
{
jsonItemStack = MassiveCore.gson.toJsonTree(itemStack, ItemStack.class);
jsonInventory.add(BOOTS, jsonItemStack);
}
}
else
{
// Add the size *length*
jsonInventory.addProperty(SIZE, itemStacks.length);
}
// Add the content at the end since we like to have it at the bottom of return json.
for (int i = 0; i < itemStacks.length; i++)
{
itemStack = itemStacks[i];
jsonItemStack = MassiveCore.gson.toJsonTree(itemStack, ItemStack.class);
if (jsonItemStack == null) continue;
jsonInventory.add(String.valueOf(i), jsonItemStack);
}
return jsonInventory;
}
public static Inventory fromJson(JsonElement json)
{
// If must be an object!
if ( ! json.isJsonObject()) return null;
JsonObject jsonInventory = json.getAsJsonObject();
// The return value
Inventory ret = null;
// These variables are used in loops and repetitive logic.
ItemStack itemStack = null;
JsonElement jsonItemStack = null;
// There must be a size entry!
if ( ! jsonInventory.has(SIZE)) return null;
JsonPrimitive jsonSize = jsonInventory.get(SIZE).getAsJsonPrimitive();
int size = 0;
// What size/type is it?
if (jsonSize.isString() && jsonSize.getAsString().equals(PLAYER))
{
// We use 36 here since it's the size of the player inventory (without armor)
size = 36;
// This is a PlayerInventory
ret = Mixin.createPlayerInventory();
PlayerInventory pret = (PlayerInventory)ret;
// helmet
if (jsonInventory.has(HELMET))
{
jsonItemStack = jsonInventory.get(HELMET);
itemStack = MassiveCore.gson.fromJson(jsonItemStack, ItemStack.class);
pret.setHelmet(itemStack);
}
// chestplate
if (jsonInventory.has(CHESTPLATE))
{
jsonItemStack = jsonInventory.get(CHESTPLATE);
itemStack = MassiveCore.gson.fromJson(jsonItemStack, ItemStack.class);
pret.setChestplate(itemStack);
}
// leggings
if (jsonInventory.has(LEGGINGS))
{
jsonItemStack = jsonInventory.get(LEGGINGS);
itemStack = MassiveCore.gson.fromJson(jsonItemStack, ItemStack.class);
pret.setLeggings(itemStack);
}
// boots
if (jsonInventory.has(BOOTS))
{
jsonItemStack = jsonInventory.get(BOOTS);
itemStack = MassiveCore.gson.fromJson(jsonItemStack, ItemStack.class);
pret.setBoots(itemStack);
}
}
else
{
// A custom size were specified
size = jsonSize.getAsInt();
// This is a "Custom" Inventory (content only).
ret = Mixin.createInventory(null, size, null);
}
// Now process content
ItemStack[] itemStacks = new ItemStack[size];
for (int i = 0; i < size; i++)
{
// Fetch the jsonItemStack or mark it as empty and continue
String stackIdx = String.valueOf(i);
jsonItemStack = jsonInventory.get(stackIdx);
itemStack = MassiveCore.gson.fromJson(jsonItemStack, ItemStack.class);
itemStacks[i] = itemStack;
}
ret.setContents(itemStacks);
return ret;
}
}

View File

@@ -0,0 +1,753 @@
package com.massivecraft.massivecore.adapter;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.bukkit.Bukkit;
import org.bukkit.Color;
import org.bukkit.FireworkEffect;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.BookMeta;
import org.bukkit.inventory.meta.EnchantmentStorageMeta;
import org.bukkit.inventory.meta.FireworkEffectMeta;
import org.bukkit.inventory.meta.FireworkMeta;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.inventory.meta.LeatherArmorMeta;
import org.bukkit.inventory.meta.MapMeta;
import org.bukkit.inventory.meta.PotionMeta;
import org.bukkit.inventory.meta.Repairable;
import org.bukkit.inventory.meta.SkullMeta;
import org.bukkit.potion.PotionEffect;
import com.massivecraft.massivecore.xlib.gson.JsonArray;
import com.massivecraft.massivecore.xlib.gson.JsonDeserializationContext;
import com.massivecraft.massivecore.xlib.gson.JsonDeserializer;
import com.massivecraft.massivecore.xlib.gson.JsonElement;
import com.massivecraft.massivecore.xlib.gson.JsonObject;
import com.massivecraft.massivecore.xlib.gson.JsonParseException;
import com.massivecraft.massivecore.xlib.gson.JsonPrimitive;
import com.massivecraft.massivecore.xlib.gson.JsonSerializationContext;
import com.massivecraft.massivecore.xlib.gson.JsonSerializer;
/**
* This is a GSON serializer/deserializer for the Bukkit ItemStack. Why not use
* the built in Bukkit serializer/deserializer? I would have loved to do that :)
* but sadly that one is YAML centric and cannot be used with json in a good
* way. This serializer requires manual updating to work but produces clean
* json. See the file itemstackformat.txt for more info.
*/
@SuppressWarnings("deprecation")
public class ItemStackAdapter implements JsonDeserializer<ItemStack>, JsonSerializer<ItemStack>
{
// -------------------------------------------- //
// FIELD NAME CONSTANTS
// -------------------------------------------- //
public static final String ID = "id";
public static final String COUNT = "count";
public static final String DAMAGE = "damage";
public static final String NAME = "name";
public static final String LORE = "lore";
public static final String ENCHANTS = "enchants";
public static final String REPAIRCOST = "repaircost";
public static final String BOOK_TITLE = "title";
public static final String BOOK_AUTHOR = "author";
public static final String BOOK_PAGES = "pages";
public static final String LEATHER_ARMOR_COLOR = "color";
public static final String MAP_SCALING = "scaling";
public static final String SKULL_OWNER = "skull";
// We renamed "effects" to "potion-effects".
public static final String POTION_EFFECTS_OLD = "effects";
public static final String POTION_EFFECTS = "potion-effects";
public static final String FIREWORK_EFFECT = "firework-effect";
public static final String FIREWORK_EFFECTS = "firework-effects";
public static final String FIREWORK_FLIGHT = "firework-flight";
public static final String STORED_ENCHANTS = "stored-enchants";
// -------------------------------------------- //
// OTHER CONSTANTS
// -------------------------------------------- //
public static final int DEFAULT_ID;
public static final int DEFAULT_COUNT;
public static final int DEFAULT_DAMAGE;
static
{
ItemStack stack = createItemStack();
DEFAULT_ID = stack.getTypeId();
DEFAULT_COUNT = stack.getAmount();
DEFAULT_DAMAGE = stack.getDurability();
}
// -------------------------------------------- //
// GSON INTERFACE IMPLEMENTATION
// -------------------------------------------- //
@Override
public JsonElement serialize(ItemStack src, Type typeOfSrc, JsonSerializationContext context)
{
return erialize(src);
}
@Override
public ItemStack deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException
{
return erialize(json);
}
// -------------------------------------------- //
// WRITE
// -------------------------------------------- //
public static JsonObject erialize(ItemStack stack)
{
// Check for "nothing"
if (stack == null) return null;
if (stack.getTypeId() == 0) return null;
if (stack.getAmount() == 0) return null;
// Create a new JsonObject
JsonObject json = new JsonObject();
// Transfer data from stack to json
transferAll(stack, json, true);
return json;
}
public static ItemStack erialize(JsonElement jsonElement)
{
// Check for "nothing"
if (jsonElement == null) return null;
// Must be a JsonObject
if (jsonElement.isJsonObject() == false) return null;
JsonObject json = jsonElement.getAsJsonObject();
// Create a new ItemStack
ItemStack stack = createItemStack();
// Transfer data from json to stack
transferAll(stack, json, false);
return stack;
}
// -------------------------------------------- //
// NOARG STACK CONSTRUCTOR
// -------------------------------------------- //
public static ItemStack createItemStack()
{
return new ItemStack(0);
}
// -------------------------------------------- //
// ALL
// -------------------------------------------- //
public static void transferAll(ItemStack stack, JsonObject json, boolean stack2json)
{
transferBasic(stack, json, stack2json);
ItemMeta meta = stack.getItemMeta();
transferMeta(meta, json, stack2json);
if (stack2json == false)
{
stack.setItemMeta(meta);
}
}
// -------------------------------------------- //
// BASIC
// -------------------------------------------- //
public static void transferBasic(ItemStack stack, JsonObject json, boolean stack2json)
{
transferId(stack, json, stack2json);
transferCount(stack, json, stack2json);
transferDamage(stack, json, stack2json);
}
// -------------------------------------------- //
// BASIC: ID
// -------------------------------------------- //
public static void transferId(ItemStack stack, JsonObject json,
boolean stack2json)
{
if (stack2json)
{
int id = stack.getTypeId();
if (id == DEFAULT_ID) return;
json.addProperty(ID, id);
}
else
{
JsonElement element = json.get(ID);
if (element == null) return;
stack.setTypeId(element.getAsInt());
}
}
// -------------------------------------------- //
// BASIC: COUNT
// -------------------------------------------- //
public static void transferCount(ItemStack stack, JsonObject json, boolean stack2json)
{
if (stack2json)
{
int count = stack.getAmount();
if (count == DEFAULT_COUNT) return;
json.addProperty(COUNT, count);
}
else
{
JsonElement element = json.get(COUNT);
if (element == null) return;
stack.setAmount(element.getAsInt());
}
}
// -------------------------------------------- //
// BASIC: DAMAGE
// -------------------------------------------- //
public static void transferDamage(ItemStack stack, JsonObject json, boolean stack2json)
{
// Durability is a weird name since it is the amount of damage.
if (stack2json)
{
int damage = stack.getDurability();
if (damage == DEFAULT_DAMAGE) return;
json.addProperty(DAMAGE, damage);
}
else
{
JsonElement element = json.get(DAMAGE);
if (element == null) return;
stack.setDurability(element.getAsShort());
}
}
// -------------------------------------------- //
// META
// -------------------------------------------- //
public static void transferMeta(ItemMeta meta, JsonObject json, boolean meta2json)
{
transferUnspecificMeta(meta, json, meta2json);
transferSpecificMeta(meta, json, meta2json);
}
// -------------------------------------------- //
// UNSPECIFIC META
// -------------------------------------------- //
public static void transferUnspecificMeta(ItemMeta meta, JsonObject json, boolean meta2json)
{
transferName(meta, json, meta2json);
transferLore(meta, json, meta2json);
transferEnchants(meta, json, meta2json);
transferRepaircost(meta, json, meta2json);
}
// -------------------------------------------- //
// UNSPECIFIC META: NAME
// -------------------------------------------- //
public static void transferName(ItemMeta meta, JsonObject json, boolean meta2json)
{
if (meta2json)
{
if (!meta.hasDisplayName()) return;
json.addProperty(NAME, meta.getDisplayName());
}
else
{
JsonElement element = json.get(NAME);
if (element == null) return;
meta.setDisplayName(element.getAsString());
}
}
// -------------------------------------------- //
// UNSPECIFIC META: LORE
// -------------------------------------------- //
public static void transferLore(ItemMeta meta, JsonObject json, boolean meta2json)
{
if (meta2json)
{
if (!meta.hasLore()) return;
json.add(LORE, convertStringList(meta.getLore()));
}
else
{
JsonElement element = json.get(LORE);
if (element == null) return;
meta.setLore(convertStringList(element));
}
}
// -------------------------------------------- //
// UNSPECIFIC META: ENCHANTS
// -------------------------------------------- //
public static void transferEnchants(ItemMeta meta, JsonObject json, boolean meta2json)
{
if (meta2json)
{
if (!meta.hasEnchants()) return;
json.add(ENCHANTS, convertEnchantLevelMap(meta.getEnchants()));
}
else
{
JsonElement element = json.get(ENCHANTS);
if (element == null) return;
for (Entry<Enchantment, Integer> entry : convertEnchantLevelMap(element).entrySet())
{
meta.addEnchant(entry.getKey(), entry.getValue(), true);
}
}
}
// -------------------------------------------- //
// UNSPECIFIC META: REPAIRCOST
// -------------------------------------------- //
public static void transferRepaircost(ItemMeta meta, JsonObject json, boolean meta2json)
{
if (!(meta instanceof Repairable)) return;
Repairable repairable = (Repairable) meta;
if (meta2json)
{
if (!repairable.hasRepairCost()) return;
json.addProperty(REPAIRCOST, repairable.getRepairCost());
}
else
{
JsonElement element = json.get(REPAIRCOST);
if (element == null) return;
repairable.setRepairCost(element.getAsInt());
}
}
// -------------------------------------------- //
// SPECIFIC META
// -------------------------------------------- //
public static void transferSpecificMeta(ItemMeta meta, JsonObject json, boolean meta2json)
{
if (meta instanceof BookMeta)
{
transferBookMeta((BookMeta) meta, json, meta2json);
}
else if (meta instanceof LeatherArmorMeta)
{
transferLeatherArmorMeta((LeatherArmorMeta) meta, json, meta2json);
}
else if (meta instanceof MapMeta)
{
transferMapMeta((MapMeta) meta, json, meta2json);
}
else if (meta instanceof PotionMeta)
{
transferPotionMeta((PotionMeta) meta, json, meta2json);
}
else if (meta instanceof SkullMeta)
{
transferSkullMeta((SkullMeta) meta, json, meta2json);
}
else if (meta instanceof FireworkEffectMeta)
{
transferFireworkEffectMeta((FireworkEffectMeta) meta, json, meta2json);
}
else if (meta instanceof FireworkMeta)
{
transferFireworkMeta((FireworkMeta) meta, json, meta2json);
}
else if (meta instanceof EnchantmentStorageMeta)
{
transferEnchantmentStorageMeta((EnchantmentStorageMeta) meta, json, meta2json);
}
}
// -------------------------------------------- //
// SPECIFIC META: BOOK
// -------------------------------------------- //
public static void transferBookMeta(BookMeta meta, JsonObject json, boolean meta2json)
{
transferTitle(meta, json, meta2json);
transferAuthor(meta, json, meta2json);
transferPages(meta, json, meta2json);
}
public static void transferTitle(BookMeta meta, JsonObject json, boolean meta2json)
{
if (meta2json)
{
if (!meta.hasTitle()) return;
json.addProperty(BOOK_TITLE, meta.getTitle());
}
else
{
JsonElement element = json.get(BOOK_TITLE);
if (element == null) return;
meta.setTitle(element.getAsString());
}
}
public static void transferAuthor(BookMeta meta, JsonObject json, boolean meta2json)
{
if (meta2json)
{
if (!meta.hasTitle()) return;
json.addProperty(BOOK_AUTHOR, meta.getAuthor());
}
else
{
JsonElement element = json.get(BOOK_AUTHOR);
if (element == null) return;
meta.setAuthor(element.getAsString());
}
}
public static void transferPages(BookMeta meta, JsonObject json, boolean meta2json)
{
if (meta2json)
{
if (!meta.hasTitle()) return;
try
{
json.add(BOOK_PAGES, convertStringList(meta.getPages()));
}
catch (Exception e)
{
e.printStackTrace();
// It seems CraftMetaBook#getPages some times throw an NPE.
}
}
else
{
JsonElement element = json.get(BOOK_PAGES);
if (element == null) return;
meta.setPages(convertStringList(element));
}
}
// -------------------------------------------- //
// SPECIFIC META: LEATHER ARMOR
// -------------------------------------------- //
public static void transferLeatherArmorMeta(LeatherArmorMeta meta, JsonObject json, boolean meta2json)
{
if (meta2json)
{
Color color = meta.getColor();
if (Bukkit.getItemFactory().getDefaultLeatherColor().equals(color)) return;
json.addProperty(LEATHER_ARMOR_COLOR, color.asRGB());
}
else
{
JsonElement element = json.get(LEATHER_ARMOR_COLOR);
if (element == null) return;
meta.setColor(Color.fromRGB(element.getAsInt()));
}
}
// -------------------------------------------- //
// SPECIFIC META: MAP
// -------------------------------------------- //
public static void transferMapMeta(MapMeta meta, JsonObject json, boolean meta2json)
{
if (meta2json)
{
if (!meta.isScaling()) return;
json.addProperty(MAP_SCALING, true);
}
else
{
JsonElement element = json.get(MAP_SCALING);
if (element == null) return;
meta.setScaling(element.getAsBoolean());
}
}
// -------------------------------------------- //
// SPECIFIC META: POTION
// -------------------------------------------- //
public static void transferPotionMeta(PotionMeta meta, JsonObject json, boolean meta2json)
{
if (meta2json)
{
if (!meta.hasCustomEffects()) return;
json.add(POTION_EFFECTS, convertPotionEffectList(meta.getCustomEffects()));
}
else
{
JsonElement element = json.get(POTION_EFFECTS);
if (element == null) element = json.get(POTION_EFFECTS_OLD);
if (element == null) return;
meta.clearCustomEffects();
for (PotionEffect pe : convertPotionEffectList(element))
{
meta.addCustomEffect(pe, false);
}
}
}
// -------------------------------------------- //
// SPECIFIC META: SKULL
// -------------------------------------------- //
public static void transferSkullMeta(SkullMeta meta, JsonObject json, boolean meta2json)
{
if (meta2json)
{
if (!meta.hasOwner()) return;
json.addProperty(SKULL_OWNER, meta.getOwner());
}
else
{
JsonElement element = json.get(SKULL_OWNER);
if (element == null) return;
meta.setOwner(element.getAsString());
}
}
// -------------------------------------------- //
// SPECIFIC META: FIREWORK EFFECT
// -------------------------------------------- //
public static void transferFireworkEffectMeta(FireworkEffectMeta meta, JsonObject json, boolean meta2json)
{
if (meta2json)
{
if (!meta.hasEffect()) return;
json.add(FIREWORK_EFFECT, FireworkEffectAdapter.toJson(meta.getEffect()));
}
else
{
JsonElement element = json.get(FIREWORK_EFFECT);
if (element == null) return;
meta.setEffect(FireworkEffectAdapter.fromJson(element));
}
}
// -------------------------------------------- //
// SPECIFIC META: FIREWORK
// -------------------------------------------- //
public static void transferFireworkMeta(FireworkMeta meta, JsonObject json, boolean meta2json)
{
transferFireworkMetaEffects(meta, json, meta2json);
transferFireworkMetaPower(meta, json, meta2json);
}
public static void transferFireworkMetaEffects(FireworkMeta meta, JsonObject json, boolean meta2json)
{
if (meta2json)
{
if (!meta.hasEffects()) return;
json.add(FIREWORK_EFFECTS, convertFireworkEffectList(meta.getEffects()));
}
else
{
JsonElement element = json.get(FIREWORK_EFFECTS);
if (element == null) return;
meta.clearEffects();
meta.addEffects(convertFireworkEffectList(element));
}
}
public static void transferFireworkMetaPower(FireworkMeta meta, JsonObject json, boolean meta2json)
{
if (meta2json)
{
json.addProperty(FIREWORK_FLIGHT, meta.getPower());
}
else
{
JsonElement element = json.get(FIREWORK_FLIGHT);
if (element == null) return;
meta.setPower(element.getAsInt());
}
}
// -------------------------------------------- //
// SPECIFIC META: ENCHANTMENT STORAGE
// -------------------------------------------- //
public static void transferEnchantmentStorageMeta(EnchantmentStorageMeta meta, JsonObject json, boolean meta2json)
{
if (meta2json)
{
if (!meta.hasStoredEnchants()) return;
json.add(STORED_ENCHANTS, convertEnchantLevelMap(meta.getStoredEnchants()));
}
else
{
JsonElement element = json.get(STORED_ENCHANTS);
if (element == null) return;
// TODO: Add a pull request to get rid of this entry set loop!
// TODO: A set, clear, remove all system is missing
for (Entry<Enchantment, Integer> entry : convertEnchantLevelMap(element).entrySet())
{
meta.addStoredEnchant(entry.getKey(), entry.getValue(), true);
}
}
}
// -------------------------------------------- //
// MINI UTILS
// -------------------------------------------- //
// String List
public static JsonArray convertStringList(Collection<String> strings)
{
JsonArray ret = new JsonArray();
for (String string : strings)
{
ret.add(new JsonPrimitive(string));
}
return ret;
}
public static List<String> convertStringList(JsonElement jsonElement)
{
JsonArray array = jsonElement.getAsJsonArray();
List<String> ret = new ArrayList<String>();
Iterator<JsonElement> iter = array.iterator();
while (iter.hasNext())
{
JsonElement element = iter.next();
ret.add(element.getAsString());
}
return ret;
}
// PotionEffect List
public static JsonArray convertPotionEffectList(Collection<PotionEffect> potionEffects)
{
JsonArray ret = new JsonArray();
for (PotionEffect e : potionEffects)
{
ret.add(PotionEffectAdapter.toJson(e));
}
return ret;
}
public static List<PotionEffect> convertPotionEffectList(JsonElement jsonElement)
{
if (jsonElement == null) return null;
if ( ! jsonElement.isJsonArray()) return null;
JsonArray array = jsonElement.getAsJsonArray();
List<PotionEffect> ret = new ArrayList<PotionEffect>();
Iterator<JsonElement> iter = array.iterator();
while(iter.hasNext())
{
PotionEffect e = PotionEffectAdapter.fromJson(iter.next());
if (e == null) continue;
ret.add(e);
}
return ret;
}
// FireworkEffect List
public static JsonArray convertFireworkEffectList(Collection<FireworkEffect> fireworkEffects)
{
JsonArray ret = new JsonArray();
for (FireworkEffect fe : fireworkEffects)
{
ret.add(FireworkEffectAdapter.toJson(fe));
}
return ret;
}
public static List<FireworkEffect> convertFireworkEffectList(JsonElement jsonElement)
{
if (jsonElement == null) return null;
if ( ! jsonElement.isJsonArray()) return null;
JsonArray array = jsonElement.getAsJsonArray();
List<FireworkEffect> ret = new ArrayList<FireworkEffect>();
Iterator<JsonElement> iter = array.iterator();
while(iter.hasNext())
{
FireworkEffect fe = FireworkEffectAdapter.fromJson(iter.next());
if (fe == null) continue;
ret.add(fe);
}
return ret;
}
// EnchantLevelMap
public static JsonObject convertEnchantLevelMap(Map<Enchantment, Integer> enchantLevelMap)
{
JsonObject ret = new JsonObject();
for (Entry<Enchantment, Integer> entry : enchantLevelMap.entrySet())
{
ret.addProperty(String.valueOf(entry.getKey().getId()), entry.getValue());
}
return ret;
}
public static Map<Enchantment, Integer> convertEnchantLevelMap(JsonElement jsonElement)
{
JsonObject json = jsonElement.getAsJsonObject();
Map<Enchantment, Integer> ret = new HashMap<Enchantment, Integer>();
for (Entry<String, JsonElement> entry : json.entrySet())
{
int id = Integer.valueOf(entry.getKey());
Enchantment ench = Enchantment.getById(id);
int lvl = entry.getValue().getAsInt();
ret.put(ench, lvl);
}
return ret;
}
// -------------------------------------------- //
// INSTANCE
// -------------------------------------------- //
public static ItemStackAdapter i = new ItemStackAdapter();
public static ItemStackAdapter get() { return i; }
}

View File

@@ -0,0 +1,37 @@
package com.massivecraft.massivecore.adapter;
import java.lang.reflect.Type;
import com.massivecraft.massivecore.xlib.gson.JsonDeserializationContext;
import com.massivecraft.massivecore.xlib.gson.JsonDeserializer;
import com.massivecraft.massivecore.xlib.gson.JsonElement;
import com.massivecraft.massivecore.xlib.gson.JsonParseException;
import com.massivecraft.massivecore.xlib.gson.JsonSerializationContext;
import com.massivecraft.massivecore.xlib.gson.JsonSerializer;
public class JsonElementAdapter implements JsonDeserializer<JsonElement>, JsonSerializer<JsonElement>
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static JsonElementAdapter i = new JsonElementAdapter();
public static JsonElementAdapter get() { return i; }
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public JsonElement serialize(JsonElement src, Type typeOfSrc, JsonSerializationContext context)
{
return src;
}
@Override
public JsonElement deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException
{
return json;
}
}

View File

@@ -0,0 +1,38 @@
package com.massivecraft.massivecore.adapter;
import java.lang.reflect.Type;
import java.util.Collection;
import com.massivecraft.massivecore.collections.MassiveList;
import com.massivecraft.massivecore.collections.MassiveListDef;
import com.massivecraft.massivecore.xlib.gson.JsonDeserializationContext;
import com.massivecraft.massivecore.xlib.gson.JsonElement;
public class MassiveListAdapter extends MassiveXAdapter<MassiveList<?>>
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static MassiveListAdapter i = new MassiveListAdapter();
public static MassiveListAdapter get() { return i; }
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@SuppressWarnings({ "rawtypes", "unchecked" })
@Override
public MassiveList<?> create(Object parent, boolean def, JsonElement json, Type typeOfT, JsonDeserializationContext context)
{
if (def)
{
return new MassiveListDef((Collection)parent);
}
else
{
return new MassiveList((Collection)parent);
}
}
}

View File

@@ -0,0 +1,38 @@
package com.massivecraft.massivecore.adapter;
import java.lang.reflect.Type;
import java.util.Map;
import com.massivecraft.massivecore.collections.MassiveMap;
import com.massivecraft.massivecore.collections.MassiveMapDef;
import com.massivecraft.massivecore.xlib.gson.JsonDeserializationContext;
import com.massivecraft.massivecore.xlib.gson.JsonElement;
public class MassiveMapAdapter extends MassiveXAdapter<MassiveMap<?, ?>>
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static MassiveMapAdapter i = new MassiveMapAdapter();
public static MassiveMapAdapter get() { return i; }
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@SuppressWarnings({ "rawtypes", "unchecked" })
@Override
public MassiveMap<?,?> create(Object parent, boolean def, JsonElement json, Type typeOfT, JsonDeserializationContext context)
{
if (def)
{
return new MassiveMapDef((Map)parent);
}
else
{
return new MassiveMap((Map)parent);
}
}
}

View File

@@ -0,0 +1,38 @@
package com.massivecraft.massivecore.adapter;
import java.lang.reflect.Type;
import java.util.Collection;
import com.massivecraft.massivecore.collections.MassiveSet;
import com.massivecraft.massivecore.collections.MassiveSetDef;
import com.massivecraft.massivecore.xlib.gson.JsonDeserializationContext;
import com.massivecraft.massivecore.xlib.gson.JsonElement;
public class MassiveSetAdapter extends MassiveXAdapter<MassiveSet<?>>
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static MassiveSetAdapter i = new MassiveSetAdapter();
public static MassiveSetAdapter get() { return i; }
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@SuppressWarnings({ "rawtypes", "unchecked" })
@Override
public MassiveSet<?> create(Object parent, boolean def, JsonElement json, Type typeOfT, JsonDeserializationContext context)
{
if (def)
{
return new MassiveSetDef((Collection)parent);
}
else
{
return new MassiveSet((Collection)parent);
}
}
}

View File

@@ -0,0 +1,48 @@
package com.massivecraft.massivecore.adapter;
import java.lang.reflect.Type;
import java.util.Map;
import com.massivecraft.massivecore.collections.MassiveTreeMap;
import com.massivecraft.massivecore.collections.MassiveTreeMapDef;
import com.massivecraft.massivecore.xlib.gson.JsonDeserializationContext;
import com.massivecraft.massivecore.xlib.gson.JsonElement;
public class MassiveTreeMapAdapter extends MassiveXAdapter<MassiveTreeMap<?, ?, ?>>
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static MassiveTreeMapAdapter i = new MassiveTreeMapAdapter();
public static MassiveTreeMapAdapter get() { return i; }
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@SuppressWarnings({ "rawtypes", "unchecked" })
@Override
public MassiveTreeMap<?, ?, ?> create(Object parent, boolean def, JsonElement json, Type typeOfT, JsonDeserializationContext context)
{
Object comparator = getComparator(typeOfT);
if (def)
{
return new MassiveTreeMapDef(comparator, (Map)parent);
}
else
{
return new MassiveTreeMap(comparator, (Map)parent);
}
}
// -------------------------------------------- //
// GET COMPARATOR
// -------------------------------------------- //
public static Object getComparator(Type typeOfT)
{
return getNewArgumentInstance(typeOfT, 2);
}
}

View File

@@ -0,0 +1,48 @@
package com.massivecraft.massivecore.adapter;
import java.lang.reflect.Type;
import java.util.Collection;
import com.massivecraft.massivecore.collections.MassiveTreeSet;
import com.massivecraft.massivecore.collections.MassiveTreeSetDef;
import com.massivecraft.massivecore.xlib.gson.JsonDeserializationContext;
import com.massivecraft.massivecore.xlib.gson.JsonElement;
public class MassiveTreeSetAdapter extends MassiveXAdapter<MassiveTreeSet<?, ?>>
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static MassiveTreeSetAdapter i = new MassiveTreeSetAdapter();
public static MassiveTreeSetAdapter get() { return i; }
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@SuppressWarnings({ "rawtypes", "unchecked" })
@Override
public MassiveTreeSet<?, ?> create(Object parent, boolean def, JsonElement json, Type typeOfT, JsonDeserializationContext context)
{
Object comparator = getComparator(typeOfT);
if (def)
{
return new MassiveTreeSetDef(comparator, (Collection)parent);
}
else
{
return new MassiveTreeSet(comparator, (Collection)parent);
}
}
// -------------------------------------------- //
// GET COMPARATOR
// -------------------------------------------- //
public static Object getComparator(Type typeOfT)
{
return getNewArgumentInstance(typeOfT, 1);
}
}

View File

@@ -0,0 +1,193 @@
package com.massivecraft.massivecore.adapter;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.Collection;
import java.util.Map;
import com.massivecraft.massivecore.collections.Def;
import com.massivecraft.massivecore.xlib.gson.JsonDeserializationContext;
import com.massivecraft.massivecore.xlib.gson.JsonDeserializer;
import com.massivecraft.massivecore.xlib.gson.JsonElement;
import com.massivecraft.massivecore.xlib.gson.JsonNull;
import com.massivecraft.massivecore.xlib.gson.JsonParseException;
import com.massivecraft.massivecore.xlib.gson.JsonSerializationContext;
import com.massivecraft.massivecore.xlib.gson.JsonSerializer;
import com.massivecraft.massivecore.xlib.gson.internal.$Gson$Types;
/**
* This is the abstract adapter for all "Massive structures".
* It makes sure Def instances "handle empty as null".
* It makes sure we avoid infinite GSON recurse loops by recursing with supertype.
*/
public abstract class MassiveXAdapter<T> implements JsonDeserializer<T>, JsonSerializer<T>
{
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public JsonElement serialize(T src, Type type, JsonSerializationContext context)
{
ParameterizedType ptype = (ParameterizedType) type;
// Calculate def
Class<?> clazz = getClazz(ptype);
boolean def = Def.class.isAssignableFrom(clazz);
// If this is a Def ...
if (def)
{
// ... and the instance is null or contains no elements ...
if (isEmpty(src))
{
// ... then serialize as a JsonNull!
return JsonNull.INSTANCE;
}
// ... and it's non null and contains something ...
else
{
// ... then serialize it as if it were the regular Java collection!
// SUPER TYPE x2 EXAMPLE: MassiveListDef --> MassiveList --> ArrayList
return context.serialize(src, getSuperType(getSuperType(ptype)));
}
}
// If this a regular Massive structure and not a Def ...
else
{
// ... then serialize it as if it were the regular java collection!
// SUPER TYPE x1 EXAMPLE: MassiveList --> ArrayList
return context.serialize(src, getSuperType(ptype));
}
}
@Override
public T deserialize(JsonElement json, Type type, JsonDeserializationContext context) throws JsonParseException
{
ParameterizedType ptype = (ParameterizedType) type;
/*// TODO: Temporary Debug
if (MUtil.getStackTraceString().contains("com.massivecraft.factions.entity.FactionColl.init"))
{
typeDebug(ptype);
typeDebug(getSuperType(ptype));
typeDebug(getSuperType(getSuperType(ptype)));
}*/
// Calculate def
Class<?> clazz = getClazz(ptype);
boolean def = Def.class.isAssignableFrom(clazz);
// If this is a Def ...
if (def)
{
// ... then deserialize it as if it were the regular Java collection!
// SUPER TYPE x2 EXAMPLE: MassiveListDef --> MassiveList --> ArrayList
Object parent = context.deserialize(json, getSuperType(getSuperType(ptype)));
return create(parent, def, json, type, context);
}
// If this a regular Massive structure and not a Def ...
else
{
// ... and the json is null or a JsonNull ...
if (json == null || json instanceof JsonNull)
{
// ... then deserialize as a null!
return null;
}
// ... and it's non null and contains something ...
else
{
// ... then deserialize it as if it were the regular java collection!
// SUPER TYPE x1 EXAMPLE: MassiveList --> ArrayList
Object parent = context.deserialize(json, getSuperType(ptype));
return create(parent, def, json, type, context);
}
}
}
/*
public static void typeDebug(ParameterizedType ptype)
{
System.out.println("=== Type Debug Start ===");
System.out.println(ptype.toString());
ParameterizedType parameterizedType = (ParameterizedType) ptype;
System.out.println("Actual Type Arguments: " + Txt.implode(parameterizedType.getActualTypeArguments(), ", "));
System.out.println("=== Type Debug End ===");
}*/
// -------------------------------------------- //
// ABSTRACT
// -------------------------------------------- //
public abstract T create(Object parent, boolean def, JsonElement json, Type typeOfT, JsonDeserializationContext context);
// -------------------------------------------- //
// UTIL
// -------------------------------------------- //
public static Class<?> getClazz(ParameterizedType ptype)
{
return (Class<?>)ptype.getRawType();
}
public static ParameterizedType getSuperType(ParameterizedType ptype)
{
// ------- SELF -------
// Get args
Type[] args = ptype.getActualTypeArguments();
// Get clazz
Class<?> clazz = (Class<?>)ptype.getRawType();
// ------- SUPER -------
// Get stype
ParameterizedType sptype = (ParameterizedType) clazz.getGenericSuperclass();
// Get sargs
// NOTE: These will be broken! we can however look at the count!
Type[] sargs = sptype.getActualTypeArguments();
// Get sclazz
Class<?> sclazz = (Class<?>)sptype.getRawType();
// ------- CONSTRUCTED -------
Type[] typeArguments = Arrays.copyOfRange(args, 0, sargs.length);
return $Gson$Types.newParameterizedTypeWithOwner(null, sclazz, typeArguments);
}
public static Object getNewArgumentInstance(Type type, int index)
{
ParameterizedType parameterizedType = (ParameterizedType) type;
Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
Class<?> clazz = (Class<?>) actualTypeArguments[index];
try
{
return clazz.newInstance();
}
catch (Exception e)
{
throw new RuntimeException(e);
}
}
@SuppressWarnings("rawtypes")
public static boolean isEmpty(Object object)
{
// A Map is not a Collection.
// Thus we have to use isEmpty() declared in different interfaces.
if (object == null) return true;
if (object instanceof Map) return ((Map)object).isEmpty();
if (object instanceof Collection) return ((Collection)object).isEmpty();
return false;
}
}

View File

@@ -0,0 +1,89 @@
package com.massivecraft.massivecore.adapter;
import com.massivecraft.massivecore.xlib.gson.Gson;
import com.massivecraft.massivecore.xlib.gson.TypeAdapter;
import com.massivecraft.massivecore.xlib.gson.TypeAdapterFactory;
import com.massivecraft.massivecore.xlib.gson.annotations.SerializedName;
import com.massivecraft.massivecore.xlib.gson.reflect.TypeToken;
import com.massivecraft.massivecore.xlib.gson.stream.JsonReader;
import com.massivecraft.massivecore.xlib.gson.stream.JsonToken;
import com.massivecraft.massivecore.xlib.gson.stream.JsonWriter;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
/**
* This type adapter and factory handles modified Java Enums.
* It's based upon: https://github.com/MassiveCraft/MassiveCore/blob/91f9ec7c0c7d9a11a35db905be520f5cf6b6743e/src/com/massivecraft/MassiveCore/xlib/gson/internal/bind/TypeAdapters.java#L670
* The only change is the try-catch around the annotation code.
*
* https://github.com/MassiveCraft/MassiveCore/pull/62
*
* # Problem
* The problem that was occurring is Forge modifies Vanilla Minecraft Enums
* (see https://github.com/MinecraftForge/MinecraftForge/blob/master/common/net/minecraftforge/common/EnumHelper.java)
* the way that it modifies the Enum is pure Java hackery modifying $VALUES on the underlying Enum.
* This will update the calls to Class.getEnumContants but won't update any fields on the Enum.
* So when the built-in Gson EnumTypeAdaper tries to see if any SerializedName annotations are on the fields of the Enum,
* it can't find a field with the new names and throws an exception.
*
* # Reasoning
* There is really not any way that we could put any fix in on the MCPC+ side since we can't add fields to Java enums at runtime.
*
* # Solution
* This ModdedEnumTypeAdapter is basically just a straight copy of the built-in one,
* but ignores when it can't find the field/annotation (which is the desired behavior in this case anyways).
* I tested this with Factions on the latest MCPC+ release and it resolves the issue that was logged.
* Hopefully this will reduce the number of people opening issues on both sides.
* If you have any questions, feel free to hit me up on IRC.
*
* @author OniBait
*/
public final class ModdedEnumTypeAdapter<T extends Enum<T>> extends TypeAdapter<T> {
private final Map<String, T> nameToConstant = new HashMap<String, T>();
private final Map<T, String> constantToName = new HashMap<T, String>();
public ModdedEnumTypeAdapter(Class<T> classOfT) {
for (T constant : classOfT.getEnumConstants()) {
String name = constant.name();
try { // MassiveCore - Ignore when the field can't be found since modified enums won't have it.
SerializedName annotation = classOfT.getField(name).getAnnotation(SerializedName.class);
if (annotation != null) {
name = annotation.value();
}
} catch (NoSuchFieldException ex) {} // MassiveCore
nameToConstant.put(name, constant);
constantToName.put(constant, name);
}
}
public T read(JsonReader in) throws IOException {
if (in.peek() == JsonToken.NULL) {
in.nextNull();
return null;
}
return nameToConstant.get(in.nextString());
}
public void write(JsonWriter out, T value) throws IOException {
out.value(value == null ? null : constantToName.get(value));
}
public static final TypeAdapterFactory ENUM_FACTORY = newEnumTypeHierarchyFactory();
public static <TT> TypeAdapterFactory newEnumTypeHierarchyFactory() {
return new TypeAdapterFactory() {
@SuppressWarnings({"rawtypes", "unchecked"})
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
Class<? super T> rawType = typeToken.getRawType();
if (!Enum.class.isAssignableFrom(rawType) || rawType == Enum.class) {
return null;
}
if (!rawType.isEnum()) {
rawType = rawType.getSuperclass(); // handle anonymous subclasses
}
return (TypeAdapter<T>) new ModdedEnumTypeAdapter(rawType);
}
};
}
}

View File

@@ -0,0 +1,39 @@
package com.massivecraft.massivecore.adapter;
import java.lang.reflect.Type;
import org.bukkit.inventory.PlayerInventory;
import com.massivecraft.massivecore.xlib.gson.JsonDeserializationContext;
import com.massivecraft.massivecore.xlib.gson.JsonDeserializer;
import com.massivecraft.massivecore.xlib.gson.JsonElement;
import com.massivecraft.massivecore.xlib.gson.JsonParseException;
import com.massivecraft.massivecore.xlib.gson.JsonSerializationContext;
import com.massivecraft.massivecore.xlib.gson.JsonSerializer;
public class PlayerInventoryAdapter implements JsonDeserializer<PlayerInventory>, JsonSerializer<PlayerInventory>
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static PlayerInventoryAdapter i = new PlayerInventoryAdapter();
public static PlayerInventoryAdapter get() { return i; }
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public JsonElement serialize(PlayerInventory src, Type typeOfSrc, JsonSerializationContext context)
{
return InventoryAdapter.toJson(src);
}
@Override
public PlayerInventory deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException
{
return (PlayerInventory) InventoryAdapter.fromJson(json);
}
}

View File

@@ -0,0 +1,74 @@
package com.massivecraft.massivecore.adapter;
import java.lang.reflect.Type;
import com.massivecraft.massivecore.xlib.gson.JsonDeserializationContext;
import com.massivecraft.massivecore.xlib.gson.JsonDeserializer;
import com.massivecraft.massivecore.xlib.gson.JsonElement;
import com.massivecraft.massivecore.xlib.gson.JsonNull;
import com.massivecraft.massivecore.xlib.gson.JsonObject;
import com.massivecraft.massivecore.xlib.gson.JsonParseException;
import com.massivecraft.massivecore.xlib.gson.JsonPrimitive;
import com.massivecraft.massivecore.xlib.gson.JsonSerializationContext;
import com.massivecraft.massivecore.xlib.gson.JsonSerializer;
public class PolymorphicAdapter<T> implements JsonDeserializer<T>, JsonSerializer<T>
{
public static final String TYPE = "type";
public static final String VALUE = "value";
@Override
public JsonElement serialize(T src, Type typeOfSrc, JsonSerializationContext context)
{
if (src == null)
{
return JsonNull.INSTANCE;
}
JsonObject ret = new JsonObject();
String type = src.getClass().getCanonicalName();
ret.addProperty(TYPE, type);
JsonElement value = context.serialize(src);
ret.add(VALUE, value);
return ret;
}
@Override
public T deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException
{
if (!json.isJsonObject())
{
throw new JsonParseException("A polymorph must be an object.");
}
JsonObject jsonObject = json.getAsJsonObject();
if (!jsonObject.has(TYPE))
{
throw new JsonParseException("A polymorph must be have a \""+TYPE+"\" field.");
}
if (!jsonObject.has(VALUE))
{
throw new JsonParseException("A polymorph must be have a \"+VALUE+\" field.");
}
String type = ((JsonPrimitive)jsonObject.get(TYPE)).getAsString();
Class<?> typeClass = null;
try
{
typeClass = Class.forName(type);
}
catch (ClassNotFoundException e)
{
e.printStackTrace();
throw new JsonParseException(e.getMessage());
}
return context.deserialize(jsonObject.get(VALUE), typeClass);
}
}

View File

@@ -0,0 +1,80 @@
package com.massivecraft.massivecore.adapter;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import com.massivecraft.massivecore.xlib.gson.JsonElement;
import com.massivecraft.massivecore.xlib.gson.JsonObject;
@SuppressWarnings("deprecation")
public class PotionEffectAdapter
{
// -------------------------------------------- //
// FIELD CONSTANTS
// -------------------------------------------- //
public static final String POTION_EFFECT_ID = "id";
public static final String POTION_DURATION = "duration";
public static final String POTION_AMPLIFIER = "amplifier";
public static final String POTION_AMBIENT = "ambient";
public static final int POTION_DURATION_DEFAULT = 20*3*60;
public static final int POTION_AMPLIFIER_DEFAULT = 0;
public static final boolean POTION_AMBIENT_DEFAULT = false;
// -------------------------------------------- //
// TO JSON
// -------------------------------------------- //
public static JsonObject toJson(PotionEffect potionEffect)
{
if (potionEffect == null) return null;
JsonObject ret = new JsonObject();
ret.addProperty(POTION_EFFECT_ID, potionEffect.getType().getId());
ret.addProperty(POTION_DURATION, potionEffect.getDuration());
ret.addProperty(POTION_AMPLIFIER, potionEffect.getAmplifier());
ret.addProperty(POTION_AMBIENT, potionEffect.isAmbient());
return ret;
}
// -------------------------------------------- //
// FROM JSON
// -------------------------------------------- //
public static PotionEffect fromJson(JsonElement jsonElement)
{
if (jsonElement == null) return null;
if ( ! jsonElement.isJsonObject()) return null;
JsonObject json = jsonElement.getAsJsonObject();
PotionEffectType pet = PotionEffectType.getById(json.get(POTION_EFFECT_ID).getAsInt());
int duration = POTION_DURATION_DEFAULT;
JsonElement durationElement = json.get(POTION_DURATION);
if (durationElement != null)
{
duration = durationElement.getAsInt();
}
int amplifier = POTION_AMPLIFIER_DEFAULT;
JsonElement amplifierElement = json.get(POTION_AMPLIFIER);
if (amplifierElement != null)
{
amplifier = amplifierElement.getAsInt();
}
boolean ambient = POTION_AMBIENT_DEFAULT;
JsonElement ambientElement = json.get(POTION_AMBIENT);
if (ambientElement != null)
{
ambient = ambientElement.getAsBoolean();
}
return new PotionEffect(pet, duration, amplifier, ambient);
}
}

View File

@@ -0,0 +1,63 @@
package com.massivecraft.massivecore.adapter;
import java.lang.reflect.Type;
import java.util.UUID;
import com.massivecraft.massivecore.xlib.gson.JsonDeserializationContext;
import com.massivecraft.massivecore.xlib.gson.JsonDeserializer;
import com.massivecraft.massivecore.xlib.gson.JsonElement;
import com.massivecraft.massivecore.xlib.gson.JsonParseException;
import com.massivecraft.massivecore.xlib.gson.JsonPrimitive;
import com.massivecraft.massivecore.xlib.gson.JsonSerializationContext;
import com.massivecraft.massivecore.xlib.gson.JsonSerializer;
public class UUIDAdapter implements JsonDeserializer<UUID>, JsonSerializer<UUID>
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static UUIDAdapter i = new UUIDAdapter();
public static UUIDAdapter get() { return i; }
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public JsonElement serialize(UUID src, Type typeOfSrc, JsonSerializationContext context)
{
return convertUUIDToJsonPrimitive(src);
}
@Override
public UUID deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException
{
return convertJsonElementToUUID(json);
}
// -------------------------------------------- //
// STATIC LOGIC
// -------------------------------------------- //
public static String convertUUIDToString(UUID uuid)
{
return uuid.toString();
}
public static JsonPrimitive convertUUIDToJsonPrimitive(UUID uuid)
{
return new JsonPrimitive(convertUUIDToString(uuid));
}
public static UUID convertStringToUUID(String string)
{
return UUID.fromString(string);
}
public static UUID convertJsonElementToUUID(JsonElement jsonElement)
{
return convertStringToUUID(jsonElement.getAsString());
}
}

View File

@@ -0,0 +1,54 @@
package com.massivecraft.massivecore.cmd;
import java.util.ArrayList;
import com.massivecraft.massivecore.cmd.MassiveCommand;
import com.massivecraft.massivecore.cmd.arg.ARInteger;
import com.massivecraft.massivecore.util.Txt;
public class HelpCommand extends MassiveCommand
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static HelpCommand i = new HelpCommand();
public static HelpCommand get() { return i; }
private HelpCommand()
{
this.addAliases("?", "h", "help");
this.setDesc("");
this.addOptionalArg("page","1");
}
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public void perform()
{
if (this.getCommandChain().size() == 0) return;
MassiveCommand parentCommand = this.getCommandChain().get(this.getCommandChain().size()-1);
ArrayList<String> lines = new ArrayList<String>();
for (String helpline : parentCommand.getHelp())
{
lines.add(Txt.parse("<a>#<i> "+helpline));
}
for (MassiveCommand subCommand : parentCommand.getSubCommands())
{
if (subCommand.isVisibleTo(sender))
{
lines.add(subCommand.getUseageTemplate(this.getCommandChain(), true, true, sender));
}
}
Integer pagenumber = this.arg(0, ARInteger.get(), 1);
if (pagenumber == null) return;
sendMessage(Txt.getPage(lines, pagenumber, "Help for command \""+parentCommand.getAliases().get(0)+"\"", sender));
}
}

View File

@@ -0,0 +1,666 @@
package com.massivecraft.massivecore.cmd;
import java.util.*;
import java.util.Map.Entry;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import com.massivecraft.massivecore.Lang;
import com.massivecraft.massivecore.MassiveCore;
import com.massivecraft.massivecore.cmd.arg.ArgReader;
import com.massivecraft.massivecore.cmd.arg.ArgResult;
import com.massivecraft.massivecore.cmd.req.Req;
import com.massivecraft.massivecore.cmd.req.ReqHasPerm;
import com.massivecraft.massivecore.mixin.Mixin;
import com.massivecraft.massivecore.util.PermUtil;
import com.massivecraft.massivecore.util.Txt;
public class MassiveCommand
{
// -------------------------------------------- //
// REGISTER
// -------------------------------------------- //
// MassiveCore commands are a bit special when it comes to registration.
//
// I want my users to be able to edit the command aliases and I want
// them to be able to do so during server runtime without having to use the /reload command.
//
// To provide a truly neat experience I place the command aliases in a mstore database configuration file.
// As such these config files are polled for changes and loaded into the server automatically.
// If someone changed the command aliases we must update all Bukkit command registrations.
//
// In order to achieve this we run a task once a second (see com.massivecraft.massivecore.MassiveCoreEngineCommandRegistration).
// This task unregisters /all/ registered MCommands and then register them all again.
// When registering again we use the fresh and current aliases.
private static transient Map<MassiveCommand, Plugin> registry = new LinkedHashMap<MassiveCommand, Plugin>();
public static Set<MassiveCommand> getRegisteredCommands()
{
return registry.keySet();
}
public static Map<MassiveCommand, Plugin> getRegistry()
{
return registry;
}
public static void unregister(Plugin plugin)
{
Iterator<Entry<MassiveCommand, Plugin>> iter = registry.entrySet().iterator();
while (iter.hasNext())
{
Entry<MassiveCommand, Plugin> entry = iter.next();
if (plugin.equals(entry.getValue()))
{
iter.remove();
}
}
}
@Deprecated
public void register()
{
this.register(MassiveCore.get());
}
public Plugin register(Plugin plugin)
{
return registry.put(this, plugin);
}
public void unregister()
{
registry.remove(this);
}
public boolean isRegistered()
{
return registry.containsKey(this);
}
public Plugin getRegisteredPlugin()
{
return registry.get(this);
}
// -------------------------------------------- //
// COMMAND BEHAVIOR
// -------------------------------------------- //
// FIELD: subCommands
// The sub-commands to this command
protected List<MassiveCommand> subCommands;
public List<MassiveCommand> getSubCommands() { return this.subCommands; }
public void setSubCommands(List<MassiveCommand> subCommands) { this.subCommands = subCommands; }
public MassiveCommand getSubCommand(String alias)
{
for (MassiveCommand subCommand: this.getSubCommands())
{
for (String subAlias : subCommand.getAliases())
{
if (alias.equalsIgnoreCase(subAlias))
{
return subCommand;
}
}
}
return null;
}
public void addSubCommand(MassiveCommand subCommand)
{
this.addSubCommand(subCommand, this.subCommands.size());
}
public void addSubCommand(MassiveCommand subCommand, int index)
{
subCommand.commandChain.addAll(this.commandChain);
subCommand.commandChain.add(this);
this.subCommands.add(index, subCommand);
}
public void addSubCommandAfter(MassiveCommand subCommand, MassiveCommand after)
{
int index = this.subCommands.indexOf(after);
if (index == -1)
{
index = this.subCommands.size();
}
else
{
index++;
}
this.addSubCommand(subCommand, index);
}
public int removeSubCommand(MassiveCommand subCommand)
{
int index = this.subCommands.indexOf(subCommand);
this.subCommands.remove(index);
return index;
}
public int replaceSubCommand(MassiveCommand subCommand, MassiveCommand replaced)
{
int index = this.removeSubCommand(replaced);
if (index < 0) return index;
this.addSubCommand(subCommand, index);
return index;
}
// FIELD: aliases
// The different names this commands will react to
protected List<String> aliases;
public List<String> getAliases() { return this.aliases; }
public void setAliases(List<String> aliases) { this.aliases = aliases; }
public void addAliases(String... aliases) { this.aliases.addAll(Arrays.asList(aliases)); }
public void addAliases(List<String> aliases) { this.aliases.addAll(aliases); }
// FIELD: requiredArgs
// These args must always be sent
protected List<String> requiredArgs;
public List<String> getRequiredArgs() { return this.requiredArgs; }
public void setRequiredArgs(List<String> requiredArgs) { this.requiredArgs = requiredArgs; }
public void addRequiredArg(String arg) { this.requiredArgs.add(arg); }
// FIELD: optionalArgs
// These args are optional
protected Map<String, String> optionalArgs;
public Map<String, String> getOptionalArgs() { return this.optionalArgs; }
public void setOptionalArgs(Map<String, String> optionalArgs) { this.optionalArgs = optionalArgs; }
public void addOptionalArg(String arg, String def) { this.optionalArgs.put(arg, def); }
// FIELD: errorOnToManyArgs
// Should an error be thrown if "to many" args are sent.
protected boolean errorOnToManyArgs;
public boolean getErrorOnToManyArgs() { return this.errorOnToManyArgs; }
public void setErrorOnToManyArgs(boolean val) { this.errorOnToManyArgs = val; }
// FIELD: usingTokenizer
// Should the arguments be parsed considering quotes and backslashes and such?
protected boolean usingTokenizer;
public boolean isUsingTokenizer() { return this.usingTokenizer; }
public void setUsingTokenizer(boolean usingTokenizer) { this.usingTokenizer = usingTokenizer; }
// FIELD: usingSmartQuotesRemoval
// Are "smart" quotes replaced with normal characters?
protected boolean usingSmartQuotesRemoval;
public boolean isUsingSmartQuotesRemoval() { return this.usingSmartQuotesRemoval; }
public void setUsingSmartQuotesRemoval(boolean usingSmartQuotesRemoval) { this.usingSmartQuotesRemoval = usingSmartQuotesRemoval; }
// FIELD: requirements
// All these requirements must be met for the command to be executable;
protected List<Req> requirements;
public List<Req> getRequirements() { return this.requirements; }
public void getRequirements(List<Req> requirements) { this.requirements = requirements; }
public void addRequirements(Req... requirements) { this.requirements.addAll(Arrays.asList(requirements)); }
// FIELD: desc
// This field may be left blank and will in such case be loaded from the permissions node instead.
// Thus make sure the permissions node description is an action description like "eat hamburgers" or "do admin stuff".
protected String desc = null;
public void setDesc(String desc) { this.desc = desc; }
public String getDesc()
{
if (this.desc != null) return this.desc;
String perm = this.getDescPermission();
if (perm != null)
{
String pdesc = PermUtil.getDescription(this.getDescPermission());
if (pdesc != null)
{
return pdesc;
}
}
return "*info unavailable*";
}
// FIELD: descPermission
// This permission node IS NOT TESTED AT ALL. It is rather used in the method above.
protected String descPermission;
public void setDescPermission(String descPermission) { this.descPermission = descPermission; }
public String getDescPermission()
{
if (this.descPermission != null) return this.descPermission;
// Otherwise we try to find one.
for (Req req : this.getRequirements())
{
if ( ! (req instanceof ReqHasPerm)) continue;
return ((ReqHasPerm)req).getPerm();
}
return null;
}
// FIELD: help
// This is a multi-line help text for the command.
protected List<String> help = new ArrayList<String>();
public void setHelp(List<String> val) { this.help = val; }
public void setHelp(String... val) { this.help = Arrays.asList(val); }
public List<String> getHelp() { return this.help; }
// FIELD: visibilityMode
protected VisibilityMode visibilityMode;
public VisibilityMode getVisibilityMode() { return this.visibilityMode; }
public void setVisibilityMode(VisibilityMode visibilityMode) { this.visibilityMode = visibilityMode; }
// -------------------------------------------- //
// EXECUTION INFO
// -------------------------------------------- //
// FIELD: args
// Will contain the arguments, or and empty list if there are none.
protected List<String> args;
public List<String> getArgs() { return this.args; }
public void setArgs(List<String> args) { this.args = args; }
// FIELD: commandChain
// The command chain used to execute this command
protected List<MassiveCommand> commandChain = new ArrayList<MassiveCommand>();
public List<MassiveCommand> getCommandChain() { return this.commandChain; }
public void setCommandChain(List<MassiveCommand> commandChain) { this.commandChain = commandChain; }
// FIELDS: sender, me, senderIsConsole
public CommandSender sender;
public Player me;
public boolean senderIsConsole;
// -------------------------------------------- //
// CONSTRUCTORS AND EXECUTOR
// -------------------------------------------- //
public MassiveCommand()
{
this.subCommands = new ArrayList<MassiveCommand>();
this.aliases = new ArrayList<String>();
this.requiredArgs = new ArrayList<String>();
this.optionalArgs = new LinkedHashMap<String, String>();
this.requirements = new ArrayList<Req>();
this.errorOnToManyArgs = true;
this.usingTokenizer = true;
this.usingSmartQuotesRemoval = true;
this.desc = null;
this.descPermission = null;
this.visibilityMode = VisibilityMode.VISIBLE;
}
// The commandChain is a list of the parent command chain used to get to this command.
public void execute(CommandSender sender, List<String> args, List<MassiveCommand> commandChain)
{
this.setArgs(args);
this.setCommandChain(commandChain);
// Is there a matching sub command?
if (args.size() > 0)
{
MassiveCommand subCommand = this.getSubCommand(args.get(0));
if (subCommand != null)
{
args.remove(0);
commandChain.add(this);
subCommand.execute(sender, args, commandChain);
return;
}
}
try
{
// Set Sender Variables
this.sender = sender;
this.senderIsConsole = true;
this.me = null;
if (sender instanceof Player)
{
this.me = (Player) sender;
this.senderIsConsole = false;
}
this.fixSenderVars();
if ( ! isValidCall(this.sender, this.getArgs())) return;
perform();
}
finally
{
// Unset Sender Variables
this.sender = null;
this.me = null;
this.unsetSenderVars();
}
}
public void fixSenderVars()
{
}
public void unsetSenderVars()
{
}
public void execute(CommandSender sender, List<String> args)
{
execute(sender, args, new ArrayList<MassiveCommand>());
}
// This is where the command action is performed.
public void perform()
{
// Per default we just act as the help command!
List<MassiveCommand> commandChain = new ArrayList<MassiveCommand>(this.getCommandChain());
commandChain.add(this);
HelpCommand.get().execute(this.sender, this.getArgs(), commandChain);
}
// -------------------------------------------- //
// CALL VALIDATION
// -------------------------------------------- //
/**
* In this method we validate that all prerequisites to perform this command has been met.
*/
public boolean isValidCall(CommandSender sender, List<String> args)
{
if ( ! this.isRequirementsMet(sender, true))
{
return false;
}
if ( ! this.isArgsValid(args, sender))
{
return false;
}
return true;
}
public boolean isVisibleTo(CommandSender sender)
{
if (this.getVisibilityMode() == VisibilityMode.VISIBLE) return true;
if (this.getVisibilityMode() == VisibilityMode.INVISIBLE) return false;
return this.isRequirementsMet(sender, false);
}
public boolean isRequirementsMet(CommandSender sender, boolean informSenderIfNot)
{
for (Req req : this.getRequirements())
{
if ( ! req.apply(sender, this))
{
if (informSenderIfNot)
{
this.msg(req.createErrorMessage(sender, this));
}
return false;
}
}
return true;
}
public boolean isArgsValid(List<String> args, CommandSender sender)
{
if (args.size() < this.getRequiredArgs().size())
{
if (sender != null)
{
msg(Lang.COMMAND_TO_FEW_ARGS);
sender.sendMessage(this.getUseageTemplate());
}
return false;
}
if (args.size() > this.getRequiredArgs().size() + this.getOptionalArgs().size() && this.getErrorOnToManyArgs())
{
if (sender != null)
{
// Get the to many string slice
List<String> theToMany = args.subList(this.getRequiredArgs().size() + this.optionalArgs.size(), args.size());
msg(Lang.COMMAND_TO_MANY_ARGS, Txt.implodeCommaAndDot(theToMany, Txt.parse("<aqua>%s"), Txt.parse("<b>, "), Txt.parse("<b> and "), ""));
msg(Lang.COMMAND_TO_MANY_ARGS2);
sender.sendMessage(this.getUseageTemplate());
}
return false;
}
return true;
}
public boolean isArgsValid(List<String> args)
{
return this.isArgsValid(args, null);
}
// -------------------------------------------- //
// HELP AND USAGE INFORMATION
// -------------------------------------------- //
public String getUseageTemplate(List<MassiveCommand> commandChain, boolean addDesc, boolean onlyFirstAlias, CommandSender sender)
{
StringBuilder ret = new StringBuilder();
List<MassiveCommand> commands = new ArrayList<MassiveCommand>(commandChain);
commands.add(this);
String commandGoodColor = Txt.parse("<c>");
String commandBadColor = Txt.parse("<bad>");
ret.append(commandGoodColor);
ret.append('/');
boolean first = true;
Iterator<MassiveCommand> iter = commands.iterator();
while(iter.hasNext())
{
MassiveCommand mc = iter.next();
if (sender != null && !mc.isRequirementsMet(sender, false))
{
ret.append(commandBadColor);
}
else
{
ret.append(commandGoodColor);
}
if (first && onlyFirstAlias)
{
ret.append(mc.getAliases().get(0));
}
else
{
ret.append(Txt.implode(mc.getAliases(), ","));
}
if (iter.hasNext())
{
ret.append(' ');
}
first = false;
}
List<String> args = new ArrayList<String>();
for (String requiredArg : this.getRequiredArgs())
{
args.add("<"+requiredArg+">");
}
for (Entry<String, String> optionalArg : this.getOptionalArgs().entrySet())
{
String val = optionalArg.getValue();
if (val == null)
{
val = "";
}
else
{
val = "="+val;
}
args.add("["+optionalArg.getKey()+val+"]");
}
if (args.size() > 0)
{
ret.append(Txt.parse("<p>"));
ret.append(' ');
ret.append(Txt.implode(args, " "));
}
if (addDesc)
{
ret.append(' ');
ret.append(Txt.parse("<i>"));
ret.append(this.getDesc());
}
return ret.toString();
}
public String getUseageTemplate(List<MassiveCommand> commandChain, boolean addDesc, boolean onlyFirstAlias)
{
return getUseageTemplate(commandChain, addDesc, onlyFirstAlias, null);
}
public String getUseageTemplate(List<MassiveCommand> commandChain, boolean addDesc)
{
return getUseageTemplate(commandChain, addDesc, false);
}
public String getUseageTemplate(boolean addDesc)
{
return getUseageTemplate(this.getCommandChain(), addDesc);
}
public String getUseageTemplate()
{
return getUseageTemplate(false);
}
// -------------------------------------------- //
// MESSAGE SENDING HELPERS
// -------------------------------------------- //
// CONVENIENCE SEND MESSAGE
public boolean sendMessage(String message)
{
return Mixin.messageOne(this.sender, message);
}
public boolean sendMessage(String... messages)
{
return Mixin.messageOne(this.sender, messages);
}
public boolean sendMessage(Collection<String> messages)
{
return Mixin.messageOne(this.sender, messages);
}
// CONVENIENCE MSG
public boolean msg(String msg)
{
return Mixin.msgOne(this.sender, msg);
}
public boolean msg(String msg, Object... args)
{
return Mixin.msgOne(this.sender, msg, args);
}
public boolean msg(Collection<String> msgs)
{
return Mixin.msgOne(this.sender, msgs);
}
// -------------------------------------------- //
// ARGUMENT READERS
// -------------------------------------------- //
// argIsSet
public boolean argIsSet(int idx)
{
return ! (this.args.size() < idx+1);
}
// arg
public String arg(int idx)
{
if ( ! this.argIsSet(idx)) return null;
return this.getArgs().get(idx);
}
public <T> T arg(int idx, ArgReader<T> argReader)
{
String str = this.arg(idx);
return this.arg(str, argReader);
}
public <T> T arg(int idx, ArgReader<T> argReader, T defaultNotSet)
{
String str = this.arg(idx);
return this.arg(str, argReader, defaultNotSet);
}
// argConcatFrom
public String argConcatFrom(int idx)
{
if ( ! this.argIsSet(idx)) return null;
int from = idx;
int to = this.getArgs().size();
if (to <= from) return "";
return Txt.implode(this.getArgs().subList(from, to), " ");
}
public <T> T argConcatFrom(int idx, ArgReader<T> argReader)
{
String str = this.argConcatFrom(idx);
return this.arg(str, argReader);
}
public <T> T argConcatFrom(int idx, ArgReader<T> argReader, T defaultNotSet)
{
String str = this.argConcatFrom(idx);
return this.arg(str, argReader, defaultNotSet);
}
// Core & Other
public <T> T arg(ArgReader<T> argReader)
{
return this.arg(null, argReader);
}
public <T> T arg(String str, ArgReader<T> argReader)
{
ArgResult<T> result = argReader.read(str, this.sender);
if (result.hasErrors()) this.msg(result.getErrors());
return result.getResult();
}
public <T> T arg(String str, ArgReader<T> argReader, T defaultNotSet)
{
if (str == null) return defaultNotSet;
return this.arg(str, argReader);
}
}

View File

@@ -0,0 +1,177 @@
package com.massivecraft.massivecore.cmd;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.PluginIdentifiableCommand;
import org.bukkit.plugin.Plugin;
import com.massivecraft.massivecore.mixin.Mixin;
import com.massivecraft.massivecore.util.IdUtil;
import com.massivecraft.massivecore.util.Txt;
public class MassiveCoreBukkitCommand extends Command implements PluginIdentifiableCommand
{
// -------------------------------------------- //
// FIELDS
// -------------------------------------------- //
private final MassiveCommand massiveCommand;
public MassiveCommand getMassiveCommand() { return this.massiveCommand; }
// -------------------------------------------- //
// CONSTRUCT
// -------------------------------------------- //
public MassiveCoreBukkitCommand(String name, MassiveCommand massiveCommand)
{
super(
name,
massiveCommand.getDesc(),
massiveCommand.getUseageTemplate(),
new ArrayList<String>() // We don't use aliases
);
this.massiveCommand = massiveCommand;
}
// -------------------------------------------- //
// OVERRIDE: PLUGIN IDENTIFIABLE COMMAND
// -------------------------------------------- //
@Override
public Plugin getPlugin()
{
return massiveCommand.getRegisteredPlugin();
}
// -------------------------------------------- //
// OVERRIDE: EXECUTE
// -------------------------------------------- //
@Override
public boolean execute(CommandSender sender, String commandLabel, String[] args)
{
List<String> argList = this.createArgList(args);
this.massiveCommand.execute(sender, argList);
return true;
}
public List<String> createArgList(String[] args)
{
List<String> ret;
if (this.massiveCommand.isUsingTokenizer())
{
ret = Txt.tokenizeArguments(Txt.implode(args, " "));
}
else
{
ret = new ArrayList<String>(Arrays.asList(args));
}
if (this.massiveCommand.isUsingSmartQuotesRemoval())
{
List<String> oldArgList = ret;
ret = new ArrayList<String>();
for (String arg : oldArgList)
{
ret.add(Txt.removeSmartQuotes(arg));
}
}
return ret;
}
// -------------------------------------------- //
// OVERRIDE: TAB COMPLETE
// -------------------------------------------- //
@Override
public List<String> tabComplete(CommandSender sender, String alias, String[] args) throws IllegalArgumentException
{
Set<String> ret = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
String tokenlc = args[args.length - 1].toLowerCase();
// First we need a command to find the subcommands in.
MassiveCommand cmd = this.getSubCommand(args, massiveCommand);
// So if we found a command, and it has subcommands
// we will suggest the aliases instead of senders.
if (cmd != null && cmd.getSubCommands().size() > 0)
{
// If we compiled in Java 8, I could have used streams :(
for (MassiveCommand sub : cmd.getSubCommands())
{
if ( ! sub.isVisibleTo(sender)) continue;
for (String subAlias : sub.getAliases())
{
if ( ! subAlias.toLowerCase().startsWith(tokenlc)) continue;
ret.add(subAlias);
}
}
// return, so senders is not suggested.
return new ArrayList<String>(ret);
}
// If subcommands didn't work, we will try with senders.
List<String> superRet = super.tabComplete(sender, alias, args);
if (args.length == 0) return superRet;
ret.addAll(superRet);
// Add names of all online senders that match and isn't added yet.
for (String senderName : IdUtil.getOnlineNames())
{
if (!senderName.toLowerCase().startsWith(tokenlc)) continue;
if (!Mixin.canSee(sender, senderName)) continue;
ret.add(senderName);
}
return new ArrayList<String>(ret);
}
// -------------------------------------------- //
// PRIVATE: TAB COMPLETE
// -------------------------------------------- //
private MassiveCommand getSubCommand(String[] args, MassiveCommand cmd)
{
// First we look in the basecommand, then in its subcommands,
// and the next subcommand and so on.
// Until we run out of args or no subcommand is found.
for (int i = 0; i < args.length-1; i++)
{
String arg = args[i];
// If no subcommand is found we will not look further.
if (cmd == null) break;
// We have to loop through the subcommands to see if any match the arg.
// if none exists we will get null, thus we break in case of null.
cmd = this.getSubCommand(arg, cmd);
}
return cmd;
}
private MassiveCommand getSubCommand(String arg, MassiveCommand cmd)
{
if (cmd == null || arg == null) return null;
// We will look in all its subcommands
for (MassiveCommand sub : cmd.getSubCommands())
{
// and in all those look for an alias that matches
for (String subAlias : sub.getAliases())
{
// If it matched we had success
if (subAlias.equalsIgnoreCase(arg)) return sub;
}
}
return null;
}
}

View File

@@ -0,0 +1,92 @@
package com.massivecraft.massivecore.cmd;
import java.util.Collection;
import java.util.List;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginDescriptionFile;
import com.massivecraft.massivecore.cmd.MassiveCommand;
import com.massivecraft.massivecore.cmd.req.ReqHasPerm;
import com.massivecraft.massivecore.util.Txt;
public class VersionCommand extends MassiveCommand
{
// -------------------------------------------- //
// CONSTANTS
// -------------------------------------------- //
public static final String NOT_SPECIFIED = Txt.parse("<em><silver>not specified");
// -------------------------------------------- //
// FIELDS
// -------------------------------------------- //
private final Plugin plugin;
public Plugin getPlugin() { return this.plugin; }
// -------------------------------------------- //
// CONSTRUCT
// -------------------------------------------- //
public VersionCommand(Plugin plugin, String permissionName, Collection<String> aliases)
{
this(plugin, permissionName, aliases.toArray(new String[0]));
}
public VersionCommand(Plugin plugin, String permissionName, String... aliases)
{
this.plugin = plugin;
if (permissionName != null)
{
this.addRequirements(ReqHasPerm.get(permissionName));
}
this.setDesc("display plugin version");
this.addAliases(aliases);
}
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public void perform()
{
PluginDescriptionFile pdf = this.getPlugin().getDescription();
String name = pdf.getName();
String version = pdf.getVersion();
String website = pdf.getWebsite();
String description = pdf.getDescription();
if (description != null) description = Txt.parse("<i>"+description);
String authors = null;
List<String> authorList = pdf.getAuthors();
if (authorList != null && authorList.size() > 0)
{
authors = Txt.implodeCommaAndDot(authorList, "<aqua>%s", "<i> ", " <i>and ", "");
authors = Txt.parse(authors);
}
this.sendTitle();
this.sendEntry("name", name);
this.sendEntry("version", version);
this.sendEntry("website", website);
this.sendEntry("authors", authors);
this.sendEntry("description", description);
}
public void sendTitle()
{
sendMessage(Txt.titleize("Plugin Version & Information"));
}
public void sendEntry(String key, String value)
{
sendMessage(Txt.parse("<pink>%s: <aqua>%s", Txt.upperCaseFirst(key), value == null ? NOT_SPECIFIED : value));
}
}

View File

@@ -0,0 +1,9 @@
package com.massivecraft.massivecore.cmd;
public enum VisibilityMode
{
VISIBLE, // Visible commands are visible to anyone. Even those who don't have permission to use it or is of invalid sender type.
SECRET, // Secret commands are visible only to those who can use the command. These commands are usually some kind of admin commands.
INVISIBLE, // Invisible commands are invisible to everyone, even those who can use the command.
;
}

View File

@@ -0,0 +1,35 @@
package com.massivecraft.massivecore.cmd.arg;
import org.bukkit.command.CommandSender;
public abstract class ARAbstractPrimitive<T> extends ArgReaderAbstract<T>
{
// -------------------------------------------- //
// ABSTRACT
// -------------------------------------------- //
public abstract String typename();
public abstract T convert(String arg) throws Exception;
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public ArgResult<T> read(String arg, CommandSender sender)
{
ArgResult<T> result = new ArgResult<T>();
try
{
result.setResult(this.convert(arg));
}
catch (Exception e)
{
result.getErrors().add("<b>Invalid "+this.typename()+" \"<h>"+arg+"\"<b>.");
}
return result;
}
}

View File

@@ -0,0 +1,49 @@
package com.massivecraft.massivecore.cmd.arg;
import java.util.Collection;
import org.bukkit.command.CommandSender;
import com.massivecraft.massivecore.util.Txt;
public abstract class ARAbstractSelect<T> extends ArgReaderAbstract<T>
{
// -------------------------------------------- //
// ABSTRACT
// -------------------------------------------- //
public abstract String typename();
public abstract T select(String str, CommandSender sender);
public abstract Collection<String> altNames(CommandSender sender);
public boolean canList(CommandSender sender) { return this.altNames(sender).size() < 50; }
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public ArgResult<T> read(String arg, CommandSender sender)
{
ArgResult<T> result = new ArgResult<T>(this.select(arg, sender));
if (!result.hasResult())
{
result.getErrors().add("<b>No "+this.typename()+" matches \"<h>"+arg+"<b>\".");
if (this.canList(sender))
{
Collection<String> names = this.altNames(sender);
if (names.size() == 0)
{
result.getErrors().add("<i>Note: There is no "+this.typename()+" available.");
}
else
{
result.getErrors().add("<i>Use "+Txt.implodeCommaAndDot(names, "<h>%s", "<i>, ", " <i>or ", "<i>."));
}
}
}
return result;
}
}

View File

@@ -0,0 +1,48 @@
package com.massivecraft.massivecore.cmd.arg;
import java.util.Collection;
import org.bukkit.command.CommandSender;
import com.massivecraft.massivecore.Aspect;
import com.massivecraft.massivecore.AspectColl;
import com.massivecraft.massivecore.MassiveCorePerm;
public class ARAspect extends ARAbstractSelect<Aspect>
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static ARAspect i = new ARAspect();
public static ARAspect get() { return i; }
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public String typename()
{
return "aspect";
}
@Override
public Aspect select(String arg, CommandSender sender)
{
return AspectColl.get().get(arg);
}
@Override
public boolean canList(CommandSender sender)
{
return MassiveCorePerm.USYS_ASPECT_LIST.has(sender, false);
}
@Override
public Collection<String> altNames(CommandSender sender)
{
return AspectColl.get().getIds();
}
}

View File

@@ -0,0 +1,79 @@
package com.massivecraft.massivecore.cmd.arg;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.bukkit.block.Biome;
import org.bukkit.command.CommandSender;
public class ARBiome extends ARAbstractSelect<Biome>
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static ARBiome i = new ARBiome();
public static ARBiome get() { return i; }
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public String typename()
{
return "biome";
}
@Override
public Biome select(String arg, CommandSender sender)
{
arg = getComparable(arg);
String biomestr;
for (Biome biome : Biome.values())
{
biomestr = getComparable(biome.name());
if (biomestr.equals(arg))
{
return biome;
}
biomestr = String.valueOf(biome.ordinal());
if (biomestr.equals(arg))
{
return biome;
}
}
return null;
}
@Override
public Collection<String> altNames(CommandSender sender)
{
List<String> ret = new ArrayList<String>();
for (Biome biome : Biome.values())
{
ret.add(String.valueOf(biome.ordinal()));
ret.add(biome.toString());
}
return ret;
}
// -------------------------------------------- //
// UTIL
// -------------------------------------------- //
public static String getComparable(String str)
{
str = str.toLowerCase();
str = str.replace("_", "");
str = str.replace(" ", "");
return str;
}
}

View File

@@ -0,0 +1,33 @@
package com.massivecraft.massivecore.cmd.arg;
public class ARBoolean extends ARAbstractPrimitive<Boolean>
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static ARBoolean i = new ARBoolean();
public static ARBoolean get() { return i; }
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public String typename()
{
return "boolean";
}
@Override
public Boolean convert(String arg) throws Exception
{
arg = arg.toLowerCase();
if (arg.startsWith("y") || arg.startsWith("t") || arg.startsWith("on") || arg.startsWith("+") || arg.startsWith("1"))
{
return true;
}
return false;
}
}

View File

@@ -0,0 +1,28 @@
package com.massivecraft.massivecore.cmd.arg;
public class ARByte extends ARAbstractPrimitive<Byte>
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static ARByte i = new ARByte();
public static ARByte get() { return i; }
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public String typename()
{
return "byte";
}
@Override
public Byte convert(String arg) throws Exception
{
return Byte.parseByte(arg);
}
}

View File

@@ -0,0 +1,76 @@
package com.massivecraft.massivecore.cmd.arg;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
public class ARChatColor extends ARAbstractSelect<ChatColor>
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static ARChatColor i = new ARChatColor();
public static ARChatColor get() { return i; }
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public String typename()
{
return "chat color";
}
@Override
public ChatColor select(String arg, CommandSender sender)
{
ChatColor ret = null;
arg = getToCompare(arg);
for (ChatColor cc : ChatColor.values())
{
String ccstr = getToCompare(cc.name());
if ( ! ccstr.equals(arg)) continue;
ret = cc;
break;
}
return ret;
}
@Override
public Collection<String> altNames(CommandSender sender)
{
List<String> ret = new ArrayList<String>();
for (ChatColor cc : ChatColor.values())
{
ret.add(cc.toString()+getToCompare(cc.name()));
}
return ret;
}
// -------------------------------------------- //
// UTIL
// -------------------------------------------- //
// "DARK_RED" --> "darkred"
// "DARK RED" --> "darkred"
public static String getToCompare(String str)
{
str = str.toLowerCase();
str = str.replace("_", "");
str = str.replace(" ", "");
return str;
}
}

View File

@@ -0,0 +1,40 @@
package com.massivecraft.massivecore.cmd.arg;
import java.util.Collection;
import org.bukkit.command.CommandSender;
import com.massivecraft.massivecore.store.Coll;
public class ARColl extends ARAbstractSelect<Coll<?>>
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static ARColl i = new ARColl();
public static ARColl get() { return i; }
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public String typename()
{
return "coll";
}
@Override
public Coll<?> select(String arg, CommandSender sender)
{
return Coll.getMap().get(arg);
}
@Override
public Collection<String> altNames(CommandSender sender)
{
return Coll.getNames();
}
}

View File

@@ -0,0 +1,34 @@
package com.massivecraft.massivecore.cmd.arg;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
public class ARDate extends ARAbstractPrimitive<Date>
{
protected final static DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static ARDate i = new ARDate();
public static ARDate get() { return i; }
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public String typename()
{
return "YYYY-MM-DD date";
}
@Override
public Date convert(String arg) throws Exception
{
return df.parse(arg);
}
}

View File

@@ -0,0 +1,62 @@
package com.massivecraft.massivecore.cmd.arg;
import java.util.Collection;
import org.bukkit.Difficulty;
import org.bukkit.command.CommandSender;
import com.massivecraft.massivecore.util.MUtil;
public class ARDifficulty extends ARAbstractSelect<Difficulty>
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static ARDifficulty i = new ARDifficulty();
public static ARDifficulty get() { return i; }
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public String typename()
{
return "difficulty";
}
@Override
public Difficulty select(String arg, CommandSender sender)
{
Difficulty ret = null;
arg = arg.toLowerCase();
if (arg.startsWith("p"))
{
ret = Difficulty.PEACEFUL;
}
else if (arg.startsWith("e"))
{
ret = Difficulty.EASY;
}
else if (arg.startsWith("n"))
{
ret = Difficulty.NORMAL;
}
else if (arg.startsWith("h"))
{
ret = Difficulty.HARD;
}
return ret;
}
@Override
public Collection<String> altNames(CommandSender sender)
{
return MUtil.list("peaceful", "easy", "normal", "hard");
}
}

View File

@@ -0,0 +1,28 @@
package com.massivecraft.massivecore.cmd.arg;
public class ARDouble extends ARAbstractPrimitive<Double>
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static ARDouble i = new ARDouble();
public static ARDouble get() { return i; }
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public String typename()
{
return "double";
}
@Override
public Double convert(String arg) throws Exception
{
return Double.parseDouble(arg);
}
}

View File

@@ -0,0 +1,63 @@
package com.massivecraft.massivecore.cmd.arg;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.EntityType;
public class AREntityType extends ARAbstractSelect<EntityType>
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static AREntityType i = new AREntityType();
public static AREntityType get() { return i; }
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public String typename()
{
return "entity type";
}
@Override
public EntityType select(String arg, CommandSender sender)
{
arg = getComparable(arg);
// Custom Detection
if (arg.contains("pig") && (arg.contains("man") || arg.contains("zombie"))) return EntityType.PIG_ZOMBIE;
// Algorithmic General Detection
for (EntityType entityType : EntityType.values())
{
if (getComparable(entityType.toString()).equals(arg)) return entityType;
}
// Nothing found
return null;
}
@Override
public Collection<String> altNames(CommandSender sender)
{
List<String> ret = new ArrayList<String>();
for (EntityType entityType : EntityType.values())
{
ret.add(getComparable(entityType.toString()));
}
return ret;
}
public static String getComparable(String string)
{
return string.toLowerCase().replaceAll("[_\\-\\s]+", "");
}
}

View File

@@ -0,0 +1,112 @@
package com.massivecraft.massivecore.cmd.arg;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.bukkit.command.CommandSender;
import com.massivecraft.massivecore.util.Txt;
public class AREnum<T> extends ARAbstractSelect<T>
{
// -------------------------------------------- //
// FIELD
// -------------------------------------------- //
private final Class<T> clazz;
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
public static <T> AREnum<T> get(Class<T> clazz)
{
return new AREnum<T>(clazz);
}
public AREnum(Class<T> clazz)
{
this.clazz = clazz;
}
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public String typename()
{
return Txt.getNicedEnumString(clazz.getSimpleName());
}
@Override
public T select(String arg, CommandSender sender)
{
if (arg == null) return null;
arg = getComparable(arg);
// Algorithmic General Detection
int startswithCount = 0;
T startswith = null;
for (T value : getEnumValues(this.clazz))
{
String comparable = getComparable(value.toString());
if (comparable.equals(arg)) return value;
if (comparable.startsWith(arg))
{
startswith = value;
startswithCount++;
}
}
if (startswithCount == 1)
{
return startswith;
}
// Nothing found
return null;
}
@Override
public Collection<String> altNames(CommandSender sender)
{
List<String> ret = new ArrayList<String>();
for (T value : getEnumValues(this.clazz))
{
ret.add(getComparable(value.toString()));
}
return ret;
}
// -------------------------------------------- //
// UTIL
// -------------------------------------------- //
public static String getComparable(String string)
{
return string.toLowerCase().replaceAll("[_\\-\\s]+", "");
}
@SuppressWarnings("unchecked")
public static <T> T[] getEnumValues(Class<T> clazz)
{
try
{
Method method = clazz.getMethod("values");
Object o = method.invoke(null);
return (T[]) o;
}
catch (Exception e)
{
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}
}
}

View File

@@ -0,0 +1,64 @@
package com.massivecraft.massivecore.cmd.arg;
import java.util.Collection;
import org.bukkit.World.Environment;
import org.bukkit.command.CommandSender;
import com.massivecraft.massivecore.util.MUtil;
public class AREnvironment extends ARAbstractSelect<Environment>
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static AREnvironment i = new AREnvironment();
public static AREnvironment get() { return i; }
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public String typename()
{
return "environment";
}
@Override
public Environment select(String arg, CommandSender sender)
{
Environment ret = null;
// "THE_END" --> "end"
arg = arg.toLowerCase();
arg = arg.replace("_", "");
arg = arg.replace("the", "");
if (arg.startsWith("no") || arg.startsWith("d"))
{
// "normal" or "default"
ret = Environment.NORMAL;
}
else if (arg.startsWith("ne"))
{
// "nether"
ret = Environment.NETHER;
}
else if (arg.startsWith("e"))
{
// "end"
ret = Environment.THE_END;
}
return ret;
}
@Override
public Collection<String> altNames(CommandSender sender)
{
return MUtil.list("normal", "end", "nether");
}
}

View File

@@ -0,0 +1,28 @@
package com.massivecraft.massivecore.cmd.arg;
public class ARFloat extends ARAbstractPrimitive<Float>
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static ARFloat i = new ARFloat();
public static ARFloat get() { return i; }
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public String typename()
{
return "integer";
}
@Override
public Float convert(String arg) throws Exception
{
return Float.parseFloat(arg);
}
}

View File

@@ -0,0 +1,58 @@
package com.massivecraft.massivecore.cmd.arg;
import java.util.Collection;
import org.bukkit.GameMode;
import org.bukkit.command.CommandSender;
import com.massivecraft.massivecore.util.MUtil;
public class ARGameMode extends ARAbstractSelect<GameMode>
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static ARGameMode i = new ARGameMode();
public static ARGameMode get() { return i; }
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public String typename()
{
return "game mode";
}
@Override
public GameMode select(String arg, CommandSender sender)
{
GameMode ret = null;
arg = arg.toLowerCase();
if (arg.startsWith("s") || arg.equals("0"))
{
ret = GameMode.SURVIVAL;
}
else if (arg.startsWith("c") || arg.equals("1"))
{
ret = GameMode.CREATIVE;
}
else if (arg.startsWith("a") || arg.equals("2"))
{
ret = GameMode.ADVENTURE;
}
return ret;
}
@Override
public Collection<String> altNames(CommandSender sender)
{
return MUtil.list("survival", "creative", "adventure");
}
}

View File

@@ -0,0 +1,28 @@
package com.massivecraft.massivecore.cmd.arg;
public class ARInteger extends ARAbstractPrimitive<Integer>
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static ARInteger i = new ARInteger();
public static ARInteger get() { return i; }
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public String typename()
{
return "integer";
}
@Override
public Integer convert(String arg) throws Exception
{
return Integer.parseInt(arg);
}
}

View File

@@ -0,0 +1,67 @@
package com.massivecraft.massivecore.cmd.arg;
import java.util.ArrayList;
import java.util.List;
import org.bukkit.command.CommandSender;
public class ARList<T> extends ArgReaderAbstract<List<T>>
{
// -------------------------------------------- //
// FIELDS
// -------------------------------------------- //
protected ArgReader<T> innerArgReader;
public ArgReader<T> getInnerArgReader() { return this.innerArgReader; }
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
public static <T> ARList<T> get(ArgReader<T> innerArgReader)
{
return new ARList<T>(innerArgReader);
}
public ARList(ArgReader<T> innerArgReader)
{
this.innerArgReader = innerArgReader;
}
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
// NOTE: Must be used with argConcatFrom and setErrorOnTooManyArgs(false).
@Override
public ArgResult<List<T>> read(String arg, CommandSender sender)
{
// Split into inner args
String[] innerArgs = arg.split("\\s+");
// Create Ret
ArgResult<List<T>> ret = new ArgResult<List<T>>();
List<T> result = new ArrayList<T>();
// For Each
for (String innerArg : innerArgs)
{
ArgResult<T> innerArgResult = this.getInnerArgReader().read(innerArg, sender);
if (innerArgResult.hasErrors())
{
ret.setErrors(innerArgResult.getErrors());
return ret;
}
result.add(innerArgResult.getResult());
}
// Set Result
ret.setResult(result);
// Return Ret
return ret;
}
}

View File

@@ -0,0 +1,28 @@
package com.massivecraft.massivecore.cmd.arg;
public class ARLong extends ARAbstractPrimitive<Long>
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static ARLong i = new ARLong();
public static ARLong get() { return i; }
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public String typename()
{
return "long";
}
@Override
public Long convert(String arg) throws Exception
{
return Long.parseLong(arg);
}
}

View File

@@ -0,0 +1,31 @@
package com.massivecraft.massivecore.cmd.arg;
import org.bukkit.Material;
import org.bukkit.command.CommandSender;
public class ARMaterial extends ArgReaderAbstract<Material>
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static ARMaterial i = new ARMaterial();
public static ARMaterial get() { return i; }
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public ArgResult<Material> read(String arg, CommandSender sender)
{
ArgResult<Material> result = new ArgResult<Material>(Material.matchMaterial(arg));
if (!result.hasResult())
{
result.getErrors().add("<b>No material matches <h>"+arg+"<b>.");
result.getErrors().add("<i>Suggestion: <aqua>http://www.minecraftwiki.net/wiki/Data_values");
}
return result;
}
}

View File

@@ -0,0 +1,36 @@
package com.massivecraft.massivecore.cmd.arg;
import org.bukkit.command.CommandSender;
import com.massivecraft.massivecore.util.TimeDiffUtil;
import com.massivecraft.massivecore.util.Txt;
public class ARMillisDiff extends ArgReaderAbstract<Long>
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static ARMillisDiff i = new ARMillisDiff();
public static ARMillisDiff get() { return i; }
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public ArgResult<Long> read(String arg, CommandSender sender)
{
ArgResult<Long> ret = new ArgResult<Long>();
try
{
ret.setResult(TimeDiffUtil.millis(arg));
}
catch (Exception e)
{
ret.setErrors(Txt.parse("<b>")+e.getMessage());
}
return ret;
}
}

View File

@@ -0,0 +1,48 @@
package com.massivecraft.massivecore.cmd.arg;
import java.util.Collection;
import org.bukkit.command.CommandSender;
import com.massivecraft.massivecore.MassiveCorePerm;
import com.massivecraft.massivecore.Multiverse;
import com.massivecraft.massivecore.MultiverseColl;
public class ARMultiverse extends ARAbstractSelect<Multiverse>
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static ARMultiverse i = new ARMultiverse();
public static ARMultiverse get() { return i; }
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public String typename()
{
return "multiverse";
}
@Override
public Multiverse select(String arg, CommandSender sender)
{
return MultiverseColl.get().get(arg);
}
@Override
public boolean canList(CommandSender sender)
{
return MassiveCorePerm.USYS_MULTIVERSE_LIST.has(sender, false);
}
@Override
public Collection<String> altNames(CommandSender sender)
{
return MultiverseColl.get().getIds();
}
}

View File

@@ -0,0 +1,40 @@
package com.massivecraft.massivecore.cmd.arg;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.permissions.Permission;
public class ARPermission extends ArgReaderAbstract<Permission>
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static ARPermission i = new ARPermission();
public static ARPermission get() { return i; }
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public ArgResult<Permission> read(String arg, CommandSender sender)
{
ArgResult<Permission> ret = new ArgResult<Permission>();
for (Permission permission : Bukkit.getPluginManager().getPermissions())
{
if (!permission.getName().equals(arg)) continue;
ret.setResult(permission);
break;
}
if (!ret.hasResult())
{
ret.setErrors("<b>No permission with the name \"<h>"+arg+"<b>\" was found.");
}
return ret;
}
}

View File

@@ -0,0 +1,32 @@
package com.massivecraft.massivecore.cmd.arg;
import org.bukkit.entity.Player;
import com.massivecraft.massivecore.store.SenderIdSourceMixinAllSenderIds;
import com.massivecraft.massivecore.util.IdUtil;
public class ARPlayer extends ARSenderIdAbstract<Player>
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static final ARPlayer i = new ARPlayer();
public static ARPlayer get() { return i; }
private ARPlayer()
{
super(SenderIdSourceMixinAllSenderIds.get());
}
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public Player getResultForSenderId(String senderId)
{
if (senderId == null) return null;
return IdUtil.getPlayer(senderId);
}
}

View File

@@ -0,0 +1,32 @@
package com.massivecraft.massivecore.cmd.arg;
import org.bukkit.command.CommandSender;
import com.massivecraft.massivecore.store.SenderIdSourceMixinAllSenderIds;
import com.massivecraft.massivecore.util.IdUtil;
public class ARSender extends ARSenderIdAbstract<CommandSender>
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static final ARSender i = new ARSender();
public static ARSender get() { return i; }
private ARSender()
{
super(SenderIdSourceMixinAllSenderIds.get());
}
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public CommandSender getResultForSenderId(String senderId)
{
if (senderId == null) return null;
return IdUtil.getSender(senderId);
}
}

View File

@@ -0,0 +1,48 @@
package com.massivecraft.massivecore.cmd.arg;
import com.massivecraft.massivecore.store.SenderColl;
import com.massivecraft.massivecore.store.SenderEntity;
public class ARSenderEntity<T extends SenderEntity<T>> extends ARSenderIdAbstract<T>
{
// -------------------------------------------- //
// FIELDS
// -------------------------------------------- //
private final SenderColl<T> coll;
// -------------------------------------------- //
// CONSTRUCT
// -------------------------------------------- //
private ARSenderEntity(SenderColl<T> coll, boolean online)
{
super(coll, online);
this.coll = coll;
}
private ARSenderEntity(SenderColl<T> coll)
{
super(coll);
this.coll = coll;
}
// -------------------------------------------- //
// GET
// -------------------------------------------- //
public static <T extends SenderEntity<T>> ARSenderEntity<T> get(SenderColl<T> coll, boolean online) { return new ARSenderEntity<T>(coll, online); }
public static <T extends SenderEntity<T>> ARSenderEntity<T> get(SenderColl<T> coll) { return new ARSenderEntity<T>(coll); }
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public T getResultForSenderId(String senderId)
{
if (senderId == null) return null;
return this.coll.get(senderId);
}
}

View File

@@ -0,0 +1,46 @@
package com.massivecraft.massivecore.cmd.arg;
import com.massivecraft.massivecore.store.SenderIdSource;
import com.massivecraft.massivecore.store.SenderIdSourceMixinAllSenderIds;
public class ARSenderId extends ARSenderIdAbstract<String>
{
// -------------------------------------------- //
// CONSTRUCT
// -------------------------------------------- //
private ARSenderId(SenderIdSource source, boolean online)
{
super(source, online);
}
private ARSenderId(SenderIdSource source)
{
super(source);
}
// -------------------------------------------- //
// INSTANCE
// -------------------------------------------- //
private static final ARSenderId i = new ARSenderId(SenderIdSourceMixinAllSenderIds.get());
public static ARSenderId get() { return i; }
// -------------------------------------------- //
// GET
// -------------------------------------------- //
public static ARSenderId get(SenderIdSource source, boolean online) { return new ARSenderId(source, online); }
public static ARSenderId get(SenderIdSource source) { return new ARSenderId(source); }
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public String getResultForSenderId(String senderId)
{
return senderId;
}
}

View File

@@ -0,0 +1,101 @@
package com.massivecraft.massivecore.cmd.arg;
import java.util.Collection;
import org.bukkit.command.CommandSender;
import com.massivecraft.massivecore.mixin.Mixin;
import com.massivecraft.massivecore.store.SenderIdSource;
import com.massivecraft.massivecore.util.IdUtil;
public abstract class ARSenderIdAbstract<T> extends ArgReaderAbstract<T>
{
// -------------------------------------------- //
// FIELDS
// -------------------------------------------- //
private final SenderIdSource source;
private final boolean online;
// -------------------------------------------- //
// CONSTRUCT
// -------------------------------------------- //
public ARSenderIdAbstract(SenderIdSource source, boolean online)
{
this.source = source;
this.online = online;
}
public ARSenderIdAbstract(SenderIdSource source)
{
this(source, false);
}
// -------------------------------------------- //
// ABSTRACT
// -------------------------------------------- //
public abstract T getResultForSenderId(String senderId);
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public ArgResult<T> read(String arg, CommandSender sender)
{
// Create Ret
ArgResult<T> ret = new ArgResult<T>();
// arg --> senderId
String senderId = this.getSenderIdFor(arg);
// Populate Ret
if (senderId == null)
{
// No alternatives found
ret.setErrors("<b>No player matches \"<h>"+arg+"<b>\".");
}
else
{
ret.setResult(this.getResultForSenderId(senderId));
}
// Return Ret
return ret;
}
// -------------------------------------------- //
// UTIL
// -------------------------------------------- //
public String getSenderIdFor(String arg)
{
// Get senderId from the arg.
// Usually it's just the lowercase form.
// It might also be a name resolution.
String senderId = arg.toLowerCase();
String betterId = IdUtil.getId(senderId);
if (betterId != null) senderId = betterId;
for (Collection<String> coll : this.source.getSenderIdCollections())
{
// If the senderId exists ...
if (!coll.contains(senderId)) continue;
// ... and the online check passes ...
if (this.online && !Mixin.isOnline(senderId)) continue;
// ... and the result is non null ...
T result = this.getResultForSenderId(senderId);
if (result == null) continue;
// ... then we are go!
return senderId;
}
return null;
}
}

View File

@@ -0,0 +1,53 @@
package com.massivecraft.massivecore.cmd.arg;
import org.bukkit.Sound;
import org.bukkit.command.CommandSender;
public class ARSound extends ArgReaderAbstract<Sound>
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static ARSound i = new ARSound();
public static ARSound get() { return i; }
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public ArgResult<Sound> read(String arg, CommandSender sender)
{
ArgResult<Sound> result = new ArgResult<Sound>(getSoundFromString(arg));
if (!result.hasResult())
{
result.getErrors().add("<b>No sound matches \"<h>"+arg+"<b>\".");
result.getErrors().add("<aqua>https://github.com/Bukkit/Bukkit/blob/master/src/main/java/org/bukkit/Sound.java");
}
return result;
}
// -------------------------------------------- //
// UTIL
// -------------------------------------------- //
public static Sound getSoundFromString(String string)
{
String string1 = getCompareString(string);
for (Sound sound : Sound.values())
{
String string2 = getCompareString(sound.name());
if (string1.equals(string2)) return sound;
}
return null;
}
public static String getCompareString(String string)
{
string = string.toLowerCase();
string = string.replaceAll("[^a-zA-Z0-9]", "");
return string;
}
}

View File

@@ -0,0 +1,37 @@
package com.massivecraft.massivecore.cmd.arg;
import org.bukkit.command.CommandSender;
import com.massivecraft.massivecore.SoundEffect;
import com.massivecraft.massivecore.util.Txt;
public class ARSoundEffect extends ArgReaderAbstract<SoundEffect>
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static ARSoundEffect i = new ARSoundEffect();
public static ARSoundEffect get() { return i; }
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public ArgResult<SoundEffect> read(String arg, CommandSender sender)
{
ArgResult<SoundEffect> ret = new ArgResult<SoundEffect>();
try
{
ret.setResult(SoundEffect.valueOf(arg));
}
catch (Exception e)
{
ret.setErrors(Txt.parse("<b>") + e.getMessage());
}
return ret;
}
}

View File

@@ -0,0 +1,49 @@
package com.massivecraft.massivecore.cmd.arg;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.bukkit.command.CommandSender;
import com.massivecraft.massivecore.SoundEffect;
import com.massivecraft.massivecore.util.Txt;
public class ARSoundEffects extends ArgReaderAbstract<List<SoundEffect>>
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static ARSoundEffects i = new ARSoundEffects();
public static ARSoundEffects get() { return i; }
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public ArgResult<List<SoundEffect>> read(String arg, CommandSender sender)
{
ArgResult<List<SoundEffect>> ret = new ArgResult<List<SoundEffect>>();
List<SoundEffect> result = new ArrayList<SoundEffect>();
arg = arg.trim();
List<String> soundStrings = Arrays.asList(arg.split("\\s+"));
try
{
for (String soundString : soundStrings)
{
result.add(SoundEffect.valueOf(soundString));
}
ret.setResult(result);
}
catch (Exception e)
{
ret.setErrors(Txt.parse("<b>") + e.getMessage());
}
return ret;
}
}

View File

@@ -0,0 +1,28 @@
package com.massivecraft.massivecore.cmd.arg;
public class ARString extends ARAbstractPrimitive<String>
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static ARString i = new ARString();
public static ARString get() { return i; }
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public String typename()
{
return "string";
}
@Override
public String convert(String arg) throws Exception
{
return arg;
}
}

View File

@@ -0,0 +1,53 @@
package com.massivecraft.massivecore.cmd.arg;
import java.util.ArrayList;
import java.util.Collection;
import org.bukkit.command.CommandSender;
import com.massivecraft.massivecore.Multiverse;
import com.massivecraft.massivecore.util.Txt;
public class ARUniverse extends ArgReaderAbstract<String>
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
public ARUniverse(Multiverse multiverse)
{
this.multiverse = multiverse;
}
// -------------------------------------------- //
// FIELDS
// -------------------------------------------- //
protected Multiverse multiverse;
public Multiverse multiverse() { return this.multiverse; }
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public ArgResult<String> read(String arg, CommandSender sender)
{
ArgResult<String> result = new ArgResult<String>();
if (multiverse.containsUniverse(arg))
{
result.setResult(arg);
}
else
{
result.getErrors().add("<b>No universe \"<h>"+arg+"<b>\" exists in multiverse <h>"+this.multiverse.getId()+"<b>.");
Collection<String> names = new ArrayList<String>(multiverse.getUniverses());
result.getErrors().add("<i>Use "+Txt.implodeCommaAndDot(names, "<h>%s", "<i>, ", " <i>or ", "<i>."));
}
return result;
}
}

View File

@@ -0,0 +1,47 @@
package com.massivecraft.massivecore.cmd.arg;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.command.CommandSender;
public class ARWorld extends ArgReaderAbstract<World>
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static ARWorld i = new ARWorld();
public static ARWorld get() { return i; }
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public ArgResult<World> read(String arg, CommandSender sender)
{
ArgResult<World> ret = new ArgResult<World>();
ArgResult<String> inner = ARWorldId.get().read(arg, sender);
if (inner.hasErrors())
{
ret.setErrors(inner.getErrors());
return ret;
}
String worldId = inner.getResult();
World world = Bukkit.getWorld(worldId);
if (world == null)
{
ret.setErrors("<b>The world could not be found.");
}
else
{
ret.setResult(world);
}
return ret;
}
}

View File

@@ -0,0 +1,64 @@
package com.massivecraft.massivecore.cmd.arg;
import java.util.ArrayList;
import java.util.List;
import org.bukkit.command.CommandSender;
import com.massivecraft.massivecore.mixin.Mixin;
public class ARWorldId extends ARAbstractSelect<String>
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static ARWorldId i = new ARWorldId();
public static ARWorldId get() { return i; }
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public String typename()
{
return "world";
}
@Override
public String select(String arg, CommandSender sender)
{
List<String> visibleWorldIds = Mixin.getVisibleWorldIds(sender);
for (String worldId : visibleWorldIds)
{
if (!Mixin.canSeeWorld(sender, worldId)) continue;
if (arg.equalsIgnoreCase(worldId)) return worldId;
}
for (String worldId : visibleWorldIds)
{
if (!Mixin.canSeeWorld(sender, worldId)) continue;
for (String worldAlias : Mixin.getWorldAliases(worldId))
{
if (arg.equalsIgnoreCase(worldAlias)) return worldId;
}
}
return null;
}
@Override
public List<String> altNames(CommandSender sender)
{
List<String> ret = new ArrayList<String>();
for (String worldId : Mixin.getWorldIds())
{
if (!Mixin.canSeeWorld(sender, worldId)) continue;
ret.add(Mixin.getWorldDisplayName(worldId));
}
return ret;
}
}

View File

@@ -0,0 +1,74 @@
package com.massivecraft.massivecore.cmd.arg;
import java.util.Collection;
import org.bukkit.WorldType;
import org.bukkit.command.CommandSender;
import com.massivecraft.massivecore.util.MUtil;
public class ARWorldType extends ARAbstractSelect<WorldType>
{
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static ARWorldType i = new ARWorldType();
public static ARWorldType get() { return i; }
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public String typename()
{
return "world type";
}
@Override
public WorldType select(String arg, CommandSender sender)
{
WorldType ret = null;
// "DEFAULT_1_1" --> "11"
// "LARGE_BIOMES" --> "large"
// "Default" --> ""
arg = arg.toLowerCase();
arg = arg.replace("_", "");
arg = arg.replace(".", "");
arg = arg.replace("normal", "");
arg = arg.replace("default", "");
arg = arg.replace("large", "");
if (arg.equals(""))
{
// "normal" or "default"
ret = WorldType.NORMAL;
}
else if (arg.startsWith("flat"))
{
// "flat"
ret = WorldType.FLAT;
}
else if (arg.contains("11"))
{
// "VERSION_1_1"
ret = WorldType.VERSION_1_1;
}
else if (arg.contains("large"))
{
// "LARGE_BIOMES"
ret = WorldType.LARGE_BIOMES;
}
return ret;
}
@Override
public Collection<String> altNames(CommandSender sender)
{
return MUtil.list("normal", "flat", "1.1", "largebiomes");
}
}

View File

@@ -0,0 +1,11 @@
package com.massivecraft.massivecore.cmd.arg;
import org.bukkit.command.CommandSender;
public interface ArgReader<T>
{
public ArgResult<T> read(String arg, CommandSender sender);
public ArgResult<T> read(CommandSender sender);
public ArgResult<T> read(String arg);
public ArgResult<T> read();
}

View File

@@ -0,0 +1,29 @@
package com.massivecraft.massivecore.cmd.arg;
import org.bukkit.command.CommandSender;
public abstract class ArgReaderAbstract<T> implements ArgReader<T>
{
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public ArgResult<T> read(CommandSender sender)
{
return this.read(null, sender);
}
@Override
public ArgResult<T> read(String arg)
{
return this.read(arg, null);
}
@Override
public ArgResult<T> read()
{
return this.read(null, null);
}
}

View File

@@ -0,0 +1,72 @@
package com.massivecraft.massivecore.cmd.arg;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class ArgResult<T>
{
// -------------------------------------------- //
// FIELD: RESULT
// -------------------------------------------- //
protected T result = null;
public T getResult() { return this.result; }
public void setResult(T result) { this.result = result; }
public boolean hasResult() { return this.getResult() != null; }
// -------------------------------------------- //
// FIELD: ERRORS
// -------------------------------------------- //
protected List<String> errors = new ArrayList<String>();
public List<String> getErrors() { return this.errors; }
public void setErrors(List<String> val)
{
if (val == null)
{
this.errors = new ArrayList<String>();
}
else
{
this.errors = val;
}
}
public void setErrors(String... val)
{
this.setErrors(Arrays.asList(val));
}
public boolean hasErrors()
{
return this.errors.size() > 0;
}
// -------------------------------------------- //
// CONSTRUCT
// -------------------------------------------- //
public ArgResult()
{
}
public ArgResult(T result)
{
this.setResult(result);
}
public ArgResult(T result, List<String> errors)
{
this.setResult(result);
this.setErrors(errors);
}
public ArgResult(T result, String... errors)
{
this.setResult(result);
this.setErrors(errors);
}
}

Some files were not shown because too many files have changed in this diff Show More