Removing everything preparing for re-code.

Sorry in advance for any mess with this part. Setting up a project from the get go I am not sure how to follow the commit structure as easily as I jump around a bit. Once we have some structure ready or planned out I will be following the standards we put back in place.
This commit is contained in:
Sekwah 2021-05-24 00:19:12 +01:00 committed by Sekwah
parent 1462c3ed05
commit dcb4463de9
75 changed files with 18 additions and 4066 deletions

View File

@ -51,10 +51,18 @@ if (branch != null) {
}
def isCanary = version.toString().contains('canary')
apply plugin: 'java'
apply plugin: 'maven-publish'
apply plugin: 'idea'
apply plugin: 'eclipse'
// A little messier/not advised but
allprojects {
apply plugin: 'java'
sourceCompatibility = 1.8
targetCompatibility = 1.8
}
buildscript {
repositories {
@ -75,11 +83,6 @@ group = 'com.sekwah.advancedportals'
description = ""
allprojects {
sourceCompatibility = 1.8
targetCompatibility = 1.8
}
def branch = System.getenv("GITHUB_REF");
def sha = System.getenv("GITHUB_SHA");
def isDevBranch = branch == null || !(branch.startsWith("refs/tags/") && !branch.contains("-"))

View File

@ -1,8 +1,3 @@
apply plugin: 'java'
apply plugin: 'maven'
apply plugin: 'idea'
apply plugin: 'eclipse'
tasks.withType(JavaCompile) {
options.encoding = 'UTF-8'

View File

@ -1,29 +0,0 @@
package com.sekwah.advancedportals;
import java.lang.reflect.Type;
public class Config {
public Config(String key, String classType, String value) {
this.key = key;
this.value = value;
}
private String key;
private Type type;
private String value;
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}

View File

@ -1,16 +0,0 @@
package com.sekwah.advancedportals;
import com.sekwah.advancedportals.core.data.DataStorage;
public interface ConfigRepository {
boolean getUseOnlySpecialAxe();
void setUseOnlySpecialAxe(boolean useOnlyServerMadeAxe);
String getTranslation();
String getSelectorMaterial();
void loadConfig(DataStorage dataStorage);
}

View File

@ -1,51 +0,0 @@
package com.sekwah.advancedportals;
import com.google.inject.Singleton;
import com.sekwah.advancedportals.core.config.Config;
import com.sekwah.advancedportals.core.data.DataStorage;
import java.util.HashMap;
import java.util.Map;
@Singleton
public class ConfigRepositoryImpl implements ConfigRepository {
private Map<String, Config> configs;
private Config config;
public ConfigRepositoryImpl() {
configs = new HashMap<>();
}
public <T> T getValue(String output) {
try {
return (T) configs.get(output);
} catch (ClassCastException ignored) {
}
return null;
}
public boolean getUseOnlySpecialAxe() {
return this.config.useOnlySpecialAxe;
}
public void setUseOnlySpecialAxe(boolean useOnlyServerMadeAxe) {
this.config.useOnlySpecialAxe = useOnlyServerMadeAxe;
}
public String getTranslation() {
return this.config.translationFile;
}
public String getSelectorMaterial() {
return this.config.selectorMaterial;
}
@Override
public void loadConfig(DataStorage dataStorage) {
this.config = dataStorage.loadJson(Config.class, "config.json");
}
}

View File

@ -1,233 +0,0 @@
package com.sekwah.advancedportals.core;
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.sekwah.advancedportals.core.api.commands.SubCommand;
import com.sekwah.advancedportals.core.api.destination.Destination;
import com.sekwah.advancedportals.core.api.portal.AdvancedPortal;
import com.sekwah.advancedportals.core.registry.TagRegistry;
import com.sekwah.advancedportals.core.registry.WarpEffectRegistry;
import com.sekwah.advancedportals.core.services.DestinationServices;
import com.sekwah.advancedportals.core.services.PortalServices;
import com.sekwah.advancedportals.core.services.PortalTempDataServices;
import com.sekwah.advancedportals.core.commands.CommandWithSubCommands;
import com.sekwah.advancedportals.core.commands.subcommands.desti.CreateDestiSubCommand;
import com.sekwah.advancedportals.core.commands.subcommands.portal.*;
import com.sekwah.advancedportals.core.config.RepositoryModule;
import com.sekwah.advancedportals.core.data.DataStorage;
import com.sekwah.advancedportals.ConfigRepository;
import com.sekwah.advancedportals.core.util.InfoLogger;
import com.sekwah.advancedportals.core.util.Lang;
import com.sekwah.advancedportals.core.connector.command.CommandRegister;
import com.sekwah.advancedportals.core.connector.info.DataCollector;
import java.io.File;
public class AdvancedPortalsCore {
private static AdvancedPortalsCore instance;
private final InfoLogger infoLogger;
private final int mcMinorVer;
private final DataCollector dataCollector;
private Injector injector = Guice.createInjector(new RepositoryModule(this));
private WarpEffectRegistry warpEffectRegistry = injector.getInstance(WarpEffectRegistry.class);
private TagRegistry<AdvancedPortal> portalTagRegistry;
private TagRegistry<Destination> destiTagRegistry;
private CoreListeners coreListeners = injector.getInstance(CoreListeners.class);
private final DataStorage dataStorage;
private CommandWithSubCommands portalCommand;
private CommandWithSubCommands destiCommand;
private PortalServices portalServices = injector.getInstance(PortalServices.class);
private DestinationServices destiServices = injector.getInstance(DestinationServices.class);
private PortalTempDataServices portalTempDataServices = injector.getInstance(PortalTempDataServices.class);
private ConfigRepository configRepository = injector.getInstance(ConfigRepository.class);
public static final String version = "1.0.0";
public static final String lastTranslationUpdate = "1.0.0";
/**
* @param dataStorageLoc - Where the files will be located
* @param infoLogger - The implementation of the logger for the specific platform
* @param mcVer Minecraft version e.g. 1.12.2
*/
public AdvancedPortalsCore(File dataStorageLoc, InfoLogger infoLogger,
DataCollector dataCollector, int[] mcVer) {
this.dataStorage = new DataStorage(dataStorageLoc);
this.infoLogger = infoLogger;
instance = this;
this.dataCollector = dataCollector;
this.mcMinorVer = this.checkMcVer(mcVer);
this.onEnable();
}
private int checkMcVer(int[] mcVer) {
int maxSupportedVer = 13;
int minSupportedVer = 13;
if(mcVer.length == 2 || mcVer.length == 3) {
if(mcVer[0] == 1) {
if(mcVer[1] < minSupportedVer) {
this.infoLogger.logWarning("Older version of mc detected than officially supported. This is very likely not to work.");
return minSupportedVer;
}
else if (mcVer[1] > maxSupportedVer) {
this.infoLogger.logWarning("Newer version of mc detected than currently supported by this version. The plugin may not work.");
return maxSupportedVer;
}
else {
return mcVer[1];
}
}
else {
this.infoLogger.logWarning("It seems you are using a very strange version of Minecraft or something is " +
"seriously wrong with the plugin for getting the version of Minecraft.");
return maxSupportedVer;
}
}
else {
String version = String.valueOf(mcVer[0]);
for (int i = 0; i < mcVer.length; i++) {
version += "." + mcVer[i];
}
this.infoLogger.logWarning(version + " is definitely not a valid or currently supported mc version. " +
"Advanced Portals will try to use the newest available logic and see if it works though results " +
"may be unreliable. ");
return maxSupportedVer;
}
}
public static String getTranslationName() {
return instance.configRepository.getTranslation();
}
private void onEnable() {
this.portalTagRegistry = new TagRegistry<>();
this.destiTagRegistry = new TagRegistry<>();
this.dataStorage.copyDefaultFile("lang/en_GB.lang", false);
this.loadPortalConfig();
Lang.loadLanguage(configRepository.getTranslation());
this.portalServices.loadPortals();
this.destiServices.loadDestinations();
this.infoLogger.log(Lang.translate("logger.pluginenable"));
}
/**
*
* @param commandRegister - Handles the command registry, different on each platform
*/
public void registerCommands(CommandRegister commandRegister) {
this.registerPortalCommand(commandRegister);
this.registerDestinationCommand(commandRegister);
// TODO run annotation grabbing shit
}
private void registerPortalCommand(CommandRegister commandRegister) {
this.portalCommand = new CommandWithSubCommands();
// TODO remove once annotations are done
this.portalCommand.registerSubCommand("version", new VersionSubCommand());
this.portalCommand.registerSubCommand("langupdate", new LangUpdateSubCommand());
this.portalCommand.registerSubCommand("reload", new ReloadSubCommand());
this.portalCommand.registerSubCommand("selector", new SelectorSubCommand(), "wand");
this.portalCommand.registerSubCommand("portalblock", new PortalBlockSubCommand());
this.portalCommand.registerSubCommand("endportalblock", new EndPortalBlockSubCommand());
this.portalCommand.registerSubCommand("endgatewayblock", new EndGatewayBlockSubCommand());
this.portalCommand.registerSubCommand("create", new CreatePortalSubCommand());
this.portalCommand.registerSubCommand("remove", new RemoveSubCommand());
commandRegister.registerCommand("portal", this.portalCommand);
}
private void registerDestinationCommand(CommandRegister commandRegister) {
this.destiCommand = new CommandWithSubCommands();
// TODO remove once annotations are done
this.destiCommand.registerSubCommand("create", new CreateDestiSubCommand());
commandRegister.registerCommand("destination", this.destiCommand);
}
public static boolean registerDestiSubCommand(String arg, SubCommand subCommand) {
return instance.destiCommand.registerSubCommand(arg, subCommand);
}
public static boolean registerPortalSubCommand(String arg, SubCommand subCommand) {
return instance.portalCommand.registerSubCommand(arg, subCommand);
}
/**
* Loads the portal config into the memory and saves from the memory to check in case certain things have changed
* (basically if values are missing or whatever)
*/
public void loadPortalConfig() {
this.configRepository.loadConfig(this.dataStorage);
this.dataStorage.storeJson(this.configRepository, "config.json");
}
/**
* This cannot be called to disable the plugin, it just performs any saves or anything needed after if they are required
*/
public void onDisable() {
this.infoLogger.log(Lang.translate("logger.plugindisable"));
}
public static AdvancedPortalsCore getInstance() {
return instance;
}
public ConfigRepository getConfigRepo() {
return this.configRepository;
}
public DataStorage getDataStorage() {
return this.dataStorage;
}
public InfoLogger getInfoLogger() {
return this.infoLogger;
}
public DataCollector getDataCollector() {
return this.dataCollector;
}
public CoreListeners getCoreListeners() {
return this.coreListeners;
}
public static PortalServices getPortalServices() {
return instance.portalServices;
}
public static DestinationServices getDestinationServices() {
return instance.destiServices;
}
public PortalTempDataServices getPortalTempDataServices() {
return instance.portalTempDataServices;
}
public static TagRegistry<AdvancedPortal> getPortalTagRegistry() {
return instance.portalTagRegistry;
}
public static TagRegistry<Destination> getDestinationTagRegistry() {
return instance.destiTagRegistry;
}
}

View File

@ -1,143 +0,0 @@
package com.sekwah.advancedportals.core;
import com.google.inject.Inject;
import com.sekwah.advancedportals.core.services.PortalServices;
import com.sekwah.advancedportals.core.services.PortalTempDataServices;
import com.sekwah.advancedportals.core.data.PlayerLocation;
import com.sekwah.advancedportals.core.data.PortalLocation;
import com.sekwah.advancedportals.core.util.Lang;
import com.sekwah.advancedportals.core.connector.container.PlayerContainer;
import com.sekwah.advancedportals.core.connector.container.WorldContainer;
public class CoreListeners {
@Inject
private PortalTempDataServices portalTempDataServices;
@Inject
private PortalServices portalServices;
@Inject
private AdvancedPortalsCore portalsCore;
public void playerJoin(PlayerContainer player) {
this.portalTempDataServices.activateCooldown(player);
if(player.isOp()) {
if(!Lang.translate("translatedata.lastchange").equals(AdvancedPortalsCore.lastTranslationUpdate)) {
player.sendMessage(Lang.translateColor("messageprefix.negative")
+ Lang.translateInsertVariablesColor("translatedata.translationsoutdated", AdvancedPortalsCore.getTranslationName()));
player.sendMessage(Lang.translateColor("messageprefix.negative")
+ Lang.translateColor("translatedata.replacecommand"));
}
}
}
public void teleportEvent(PlayerContainer player) {
this.portalTempDataServices.activateCooldown(player);
}
public void playerLeave(PlayerContainer player) {
this.portalTempDataServices.playerLeave(player);
}
/**
* @param loc where the entity spawns
* @return if the entity is allowed to spawn
*/
public boolean mobSpawn(PlayerLocation loc) {
return !this.portalServices.inPortalRegion(loc);
}
/**
* @param player
* @param fromLoc
* @param toLoc
* @return if the player is allowed to move
*/
public boolean playerMove(PlayerContainer player, PlayerLocation fromLoc, PlayerLocation toLoc) {
return this.portalServices.playerMove(player, fromLoc, toLoc);
}
/**
*
* @param fromPos
* @param toPos
* @return if movement is allowed
*/
public boolean liquidFlow(PortalLocation fromPos, PortalLocation toPos) {
return true;
}
/**
* @player player causing the event (or null if not a player)
* @param blockPos
* @param blockMaterial
* @return if the block is allowed to break
*/
public boolean blockBreak(PlayerContainer player, PortalLocation blockPos, String blockMaterial) {
return true;
}
/**
* @player player causing the event (or null if not a player)
* @param blockPos
* @param blockMaterial
* @return if the block is allowed to be placed
*/
public boolean blockPlace(PlayerContainer player, PortalLocation blockPos, String blockMaterial, String itemInHandMaterial, String itemInHandName) {
if(itemInHandName != null && player != null && player.hasPermission("advancedportals.build")) {
WorldContainer world = player.getWorld();
if(itemInHandName.equals("\u00A75Portal Block Placer")) {
world.setBlock(blockPos, "PORTAL");
return false;
}
else if(itemInHandName.equals("\u00A78End Portal Block Placer")) {
world.setBlock(blockPos, "ENDER_PORTAL");
return false;
}
else if(itemInHandName.equals("\u00A78Gateway Block Placer")) {
world.setBlock(blockPos, "END_GATEWAY");
return false;
}
}
return true;
}
/**
* If the block is allowed to be interacted with e.g. a lever
* @player player causing the event (or null if not a player)
* @param blockPos
* @return
*/
public boolean blockInteract(PlayerContainer player, PortalLocation blockPos) {
return true;
}
/**
* @param player
* @param blockLoc
* @param leftClick true = left click, false = right click
* @return if player is allowed to interact with block
*/
public boolean playerInteractWithBlock(PlayerContainer player, String materialName, String itemName,
PortalLocation blockLoc, boolean leftClick) {
if(itemName != null && (player.isOp() || player.hasPermission("advancedportals.createportal")) &&
materialName.equalsIgnoreCase(this.portalsCore.getConfigRepo().getSelectorMaterial())
&& (!this.portalsCore.getConfigRepo().getUseOnlySpecialAxe() || itemName.equals("\u00A7ePortal Region Selector"))) {
this.portalTempDataServices.playerSelectorActivate(player, blockLoc, leftClick);
return false;
}
else if(itemName != null && leftClick && itemName.equals("\u00A75Portal Block Placer") && player.hasPermission("advancedportals.build")) {
WorldContainer world = player.getWorld();
if(world.getBlockData(blockLoc) == 1) {
world.setBlockData(blockLoc, (byte) 2);
}
else {
world.setBlockData(blockLoc, (byte) 1);
}
}
return true;
}
}

View File

@ -1,42 +0,0 @@
package com.sekwah.advancedportals.core.api.commands;
import com.sekwah.advancedportals.core.connector.container.CommandSenderContainer;
import java.util.List;
/**
* Subcommand that can be registered under e.g. /portal show or /portal edit
*
* @author sekwah41
*/
public interface SubCommand {
/**
* @param sender
* @param args arguments including the subcommand that has been specified.
* @return if the command has worked (if false it will just display a message from the command suggesting to check help)
*/
void onCommand(CommandSenderContainer sender, String[] args);
boolean hasPermission(CommandSenderContainer sender);
/**
*
*
* @param sender
* @param args arguments including the subcommand that has been specified.
* @return tab completion for the subcommand
*/
List<String> onTabComplete(CommandSenderContainer sender, String[] args);
/**
* @return the string to show next to the tag on the help menu.
*/
String getBasicHelpText();
/**
* @return the string to show if help then the tag is listed.
*/
String getDetailedHelpText();
}

View File

@ -1,107 +0,0 @@
package com.sekwah.advancedportals.core.api.destination;
import com.google.gson.annotations.SerializedName;
import com.sekwah.advancedportals.core.AdvancedPortalsCore;
import com.sekwah.advancedportals.core.registry.TagRegistry;
import com.sekwah.advancedportals.core.api.warphandler.ActivationData;
import com.sekwah.advancedportals.core.api.warphandler.TagHandler;
import com.sekwah.advancedportals.core.data.DataTag;
import com.sekwah.advancedportals.core.data.PlayerLocation;
import com.sekwah.advancedportals.core.connector.container.PlayerContainer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* Possibly look at adding the ability to add some tags to destinations such as permissions. Would make it easier
* to add permissions to block access to certain areas and such. Could be a different permission system or just
* it takes the tags on the destination and automatically applies them when a portal wants to warp to there.
* (Of course it would not work cross server unless the data was communicated and checked first however that
* could effect performance and would definitely effect speed)
*
* @author sekwah41
*/
public class Destination {
@SerializedName("l")
private PlayerLocation loc;
@SerializedName("a")
private HashMap<String, String> args = new HashMap<>();
private transient Set<String> argsCol;
public Destination(PlayerLocation loc) {
this.loc = loc;
}
public String getArg(String argName) {
return this.args.get(argName);
}
public void setArg(String argName, String argValue) {
this.args.put(argName, argValue);
}
public void setArg(DataTag portalTag) {
this.setArg(portalTag.NAME, portalTag.VALUE);
}
public void removeArg(String arg) {
this.args.remove(arg);
}
public boolean activate(PlayerContainer player) {
ActivationData data = new ActivationData();
this.portalActivate(player, data);
this.postActivate(player, data);
return true;
}
public boolean portalActivate(PlayerContainer player, ActivationData data) {
TagRegistry<Destination> tagRegistry = AdvancedPortalsCore.getDestinationTagRegistry();
DataTag[] destiTags = new DataTag[args.size()];
int i = 0;
for(Map.Entry<String, String> entry : args.entrySet()) {
destiTags[i++] = new DataTag(entry.getKey(), entry.getValue());
}
for(DataTag destiTag : destiTags) {
TagHandler.Activation<Destination> activationHandler = tagRegistry.getActivationHandler(destiTag.NAME);
if(activationHandler != null) {
activationHandler.preActivated(this, player, data, this.getArg(destiTag.NAME));
}
}
for(DataTag destiTag : destiTags) {
TagHandler.Activation<Destination> activationHandler = tagRegistry.getActivationHandler(destiTag.NAME);
if(activationHandler != null) {
activationHandler.activated(this, player, data, this.getArg(destiTag.NAME));
}
}
return true;
}
public void postActivate(PlayerContainer player, ActivationData data) {
TagRegistry<Destination> tagRegistry = AdvancedPortalsCore.getDestinationTagRegistry();
DataTag[] destiTags = new DataTag[args.size()];
int i = 0;
for(Map.Entry<String, String> entry : args.entrySet()) {
destiTags[i++] = new DataTag(entry.getKey(), entry.getValue());
}
for(DataTag destiTag : destiTags) {
TagHandler.Activation<Destination> activationHandler = tagRegistry.getActivationHandler(destiTag.NAME);
if(activationHandler != null) {
activationHandler.postActivated(this, player, data, this.getArg(destiTag.NAME));
}
}
}
public ArrayList<DataTag> getArgs() {
ArrayList<DataTag> tagList = new ArrayList<>();
for(Map.Entry<String, String> entry : this.args.entrySet()){
tagList.add(new DataTag(entry.getKey(), entry.getValue()));
}
return tagList;
}
}

View File

@ -1,15 +0,0 @@
package com.sekwah.advancedportals.core.api.effect;
import com.sekwah.advancedportals.core.api.portal.AdvancedPortal;
import com.sekwah.advancedportals.core.data.PortalLocation;
import com.sekwah.advancedportals.core.connector.container.PlayerContainer;
/**
* @author sekwah41
*/
public class TestEffect extends WarpEffect {
@Override
protected void onWarp(PlayerContainer player, PortalLocation loc, Action action, Type type, AdvancedPortal portal) {
}
}

View File

@ -1,30 +0,0 @@
package com.sekwah.advancedportals.core.api.effect;
import com.sekwah.advancedportals.core.api.portal.AdvancedPortal;
import com.sekwah.advancedportals.core.data.PortalLocation;
import com.sekwah.advancedportals.core.connector.container.PlayerContainer;
/**
* Effects to be registered to the list.
* <p>
* Fires once at each end.
* <p>
* Can be a Visual effect or a Sound. Just register to the correct one
*
* @author sekwah41
*/
public abstract class WarpEffect {
protected abstract void onWarp(PlayerContainer player, PortalLocation loc, Action action, Type type, AdvancedPortal portal);
public enum Action {
ENTER,
EXIT;
}
public enum Type {
SOUND,
VISUAL;
}
}

View File

@ -1,21 +0,0 @@
package com.sekwah.advancedportals.core.api.events;
/**
* Activated when something about the event is edited.
*
* @author sekwah41
*/
public class PortalEditEvent {
public class TagChange {
}
public class Renamed {
}
public class Moved {
}
}

View File

@ -1,16 +0,0 @@
package com.sekwah.advancedportals.core.api.events;
/**
* Triggered once all the portals are loaded
*
* TODO Need to make a custom event handler to be able to register against
*
* @author sekwah41
*/
public class PortalsLoadedEvent/* extends Event*/ {
/*@Override
public HandlerList getHandlers() {
return null;
}*/
}

View File

@ -1,116 +0,0 @@
package com.sekwah.advancedportals.core.api.portal;
import com.google.gson.annotations.SerializedName;
import com.sekwah.advancedportals.core.AdvancedPortalsCore;
import com.sekwah.advancedportals.core.registry.TagRegistry;
import com.sekwah.advancedportals.core.api.warphandler.ActivationData;
import com.sekwah.advancedportals.core.api.warphandler.TagHandler;
import com.sekwah.advancedportals.core.data.DataTag;
import com.sekwah.advancedportals.core.data.PortalLocation;
import com.sekwah.advancedportals.core.connector.container.PlayerContainer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
/**
* @author sekwah41
*/
public class AdvancedPortal {
@SerializedName("max")
private PortalLocation maxLoc;
@SerializedName("min")
private PortalLocation minLoc;
@SerializedName("t")
private String[] triggerBlocks = {"PORTAL"};
@SerializedName("a")
private HashMap<String, String> args = new HashMap<>();
public AdvancedPortal(PortalLocation maxLoc, PortalLocation minLoc) {
this.maxLoc = maxLoc;
this.minLoc = minLoc;
}
public PortalLocation getMaxLoc() {
return this.maxLoc;
}
public PortalLocation getMinLoc() {
return this.minLoc;
}
public String getArg(String argName) {
return this.args.get(argName);
}
public void setArg(String argName, String argValue) {
this.args.put(argName, argValue);
}
public void removeArg(String arg) {
this.args.remove(arg);
}
public boolean hasTriggerBlock(String blockMaterial) {
for(String triggerBlock : triggerBlocks) {
if(blockMaterial.equals(triggerBlock)) {
return true;
}
}
return false;
}
public boolean activate(PlayerContainer player) {
TagRegistry<AdvancedPortal> tagRegistry = AdvancedPortalsCore.getPortalTagRegistry();
ActivationData data = new ActivationData();
DataTag[] portalTags = new DataTag[args.size()];
int i = 0;
for(Map.Entry<String, String> entry : args.entrySet()) {
portalTags[i++] = new DataTag(entry.getKey(), entry.getValue());
}
for(DataTag portalTag : portalTags) {
TagHandler.Activation<AdvancedPortal> activationHandler = tagRegistry.getActivationHandler(portalTag.NAME);
if(activationHandler != null) {
activationHandler.preActivated(this, player, data, this.getArg(portalTag.NAME));
}
}
for(DataTag portalTag : portalTags) {
TagHandler.Activation<AdvancedPortal> activationHandler = tagRegistry.getActivationHandler(portalTag.NAME);
if(activationHandler != null) {
activationHandler.activated(this, player, data, this.getArg(portalTag.NAME));
}
}
for(DataTag portalTag : portalTags) {
TagHandler.Activation<AdvancedPortal> activationHandler = tagRegistry.getActivationHandler(portalTag.NAME);
if(activationHandler != null) {
activationHandler.postActivated(this, player, data, this.getArg(portalTag.NAME));
}
}
return true;
}
public void setArg(DataTag portalTag) {
this.setArg(portalTag.NAME, portalTag.VALUE);
}
public ArrayList<DataTag> getArgs() {
ArrayList<DataTag> tagList = new ArrayList<>();
for(Map.Entry<String, String> entry : this.args.entrySet()){
tagList.add(new DataTag(entry.getKey(), entry.getValue()));
}
return tagList;
}
public void setTriggerBlocks(String[] triggerBlocks) {
this.triggerBlocks = triggerBlocks;
}
public String[] getTriggerBlocks() {
return triggerBlocks;
}
}

View File

@ -1,24 +0,0 @@
package com.sekwah.advancedportals.core.commands;
import com.sekwah.advancedportals.core.connector.container.CommandSenderContainer;
import java.util.List;
/**
* Already know spigot's auto complete possibilities
*
* Sponge https://docs.spongepowered.org/stable/en/plugin/commands/arguments.html#custom-command-elements
*/
public interface CommandTemplate {
void onCommand(CommandSenderContainer sender, String commandExecuted, String[] args);
/**
* Fired when someone asks for a tab complete action.
* @param sender
* @param args
* @return
*/
List<String> onTabComplete(CommandSenderContainer sender, String[] args);
}

View File

@ -1,157 +0,0 @@
package com.sekwah.advancedportals.core.commands;
import com.sekwah.advancedportals.core.api.commands.SubCommand;
import com.sekwah.advancedportals.core.registry.SubCommandRegistry;
import com.sekwah.advancedportals.core.util.Lang;
import com.sekwah.advancedportals.core.connector.container.CommandSenderContainer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class CommandWithSubCommands implements CommandTemplate {
private final SubCommandRegistry subCommandRegistry;
private final int subCommandsPerPage = 7;
public CommandWithSubCommands() {
this.subCommandRegistry = new SubCommandRegistry();
}
public boolean registerSubCommand(String arg, SubCommand subCommand, String... aliasArgs) {
boolean hasRegistered = false;
for(String additionalArg : aliasArgs) {
hasRegistered = hasRegistered || this.subCommandRegistry.registerSubCommand(additionalArg,subCommand);
}
return hasRegistered || this.subCommandRegistry.registerSubCommand(arg,subCommand);
}
public ArrayList<String> getSubCommands(){
return this.subCommandRegistry.getSubCommands();
}
public boolean isArgRegistered(String arg){
return this.subCommandRegistry.isArgRegistered(arg);
}
public SubCommand getSubCommand(String arg){
return this.subCommandRegistry.getSubCommand(arg);
}
@Override
public void onCommand(CommandSenderContainer sender, String commandExecuted, String[] args) {
if(args.length > 0) {
if(args[0].equalsIgnoreCase("help")) {
int helpPage = 1;
String[] subCommands = this.subCommandRegistry.getSubCommands().toArray(new String[0]);
int pages = (int) Math.ceil(subCommands.length / (float) this.subCommandsPerPage);
if(args.length > 1) {
try {
helpPage = Integer.parseInt(args[1]);
if(helpPage > pages) {
helpPage = pages;
}
if(helpPage <= 0) {
helpPage = 1;
}
}
catch(NumberFormatException e) {
String subCommand = args[1].toLowerCase();
if(this.subCommandRegistry.isArgRegistered(subCommand)) {
sender.sendMessage(Lang.translateInsertVariablesColor("command.help.subcommandheader",
commandExecuted.substring(0,1).toUpperCase() + commandExecuted.substring(1).toLowerCase(), subCommand));
sender.sendMessage("\u00A77" + this.getSubCommand(subCommand).getDetailedHelpText());
}
else {
sender.sendMessage(Lang.translateColor("messageprefix.negative") + Lang.translateInsertVariablesColor("command.help.invalidhelp", args[1]));
}
return;
}
}
sender.sendMessage(Lang.translateInsertVariablesColor("command.help.header",
commandExecuted.substring(0,1).toUpperCase() + commandExecuted.substring(1).toLowerCase(), helpPage, pages));
sender.sendMessage("\u00A7a█\u00A77 = Permission \u00A7c█\u00A77 = No Permission");
int subCommandOffset = (helpPage - 1) * this.subCommandsPerPage;
int displayEnd = subCommandOffset + this.subCommandsPerPage;
if(displayEnd > subCommands.length) {
displayEnd = subCommands.length;
}
for(; subCommandOffset < displayEnd; subCommandOffset++) {
SubCommand subCommand = this.getSubCommand(subCommands[subCommandOffset]);
String colorCode = "\u00A7" + (subCommand.hasPermission(sender) ? "a" : "c");
sender.sendMessage("\u00A7e/" + commandExecuted + " " + subCommands[subCommandOffset]
+ colorCode + " - " + subCommand.getBasicHelpText());
}
}
else {
for(String subCommandName : this.subCommandRegistry.getSubCommands()) {
if(subCommandName.equalsIgnoreCase(args[0])) {
SubCommand subCommand = this.getSubCommand(subCommandName);
if(subCommand.hasPermission(sender)) {
subCommand.onCommand(sender, args);
}
else {
sender.sendMessage(Lang.translateColor("messageprefix.negative") + Lang.translateInsertVariablesColor("command.subcommand.nopermission",
commandExecuted));
}
return;
}
}
sender.sendMessage(Lang.translateColor("messageprefix.negative") + Lang.translateColor("command.subcommand.invalid"));
}
}
else {
sender.sendMessage(Lang.translateColor("messageprefix.negative") + Lang.translateInsertVariablesColor("command.noargs", commandExecuted));
}
}
@Override
public List<String> onTabComplete(CommandSenderContainer sender, String[] args) {
if(args.length > 1) {
if(args[0].equalsIgnoreCase("help")) {
List<String> allowedCommands = new ArrayList<>(this.subCommandRegistry.getSubCommands());
Collections.sort(allowedCommands);
return this.filterTabResults(allowedCommands, args[args.length - 1]);
}
else {
for (String subCommandName : this.subCommandRegistry.getSubCommands()) {
if (subCommandName.equalsIgnoreCase(args[0])) {
SubCommand subCommand = this.getSubCommand(subCommandName);
if (subCommand.hasPermission(sender)) {
return this.filterTabResults(this.getSubCommand(subCommandName).onTabComplete(sender, args),
args[args.length - 1]);
} else {
return null;
}
}
}
}
}
else {
List<String> allowedCommands = new ArrayList<>();
for (String subCommandName : this.subCommandRegistry.getSubCommands()) {
SubCommand subCommand = this.getSubCommand(subCommandName);
if(subCommand.hasPermission(sender)) {
allowedCommands.add(subCommandName);
}
}
allowedCommands.add("help");
Collections.sort(allowedCommands);
return this.filterTabResults(allowedCommands, args[0]);
}
return null;
}
public List<String> filterTabResults(List<String> tabList, String lastArg) {
if(tabList == null) {
return null;
}
for(String arg : tabList.toArray(new String[0])) {
if(!arg.startsWith(lastArg.toLowerCase())) {
tabList.remove(arg);
}
}
return tabList;
}
}

View File

@ -1,68 +0,0 @@
package com.sekwah.advancedportals.core.commands.subcommands.desti;
import com.sekwah.advancedportals.core.AdvancedPortalsCore;
import com.sekwah.advancedportals.core.api.commands.SubCommand;
import com.sekwah.advancedportals.core.api.destination.Destination;
import com.sekwah.advancedportals.core.data.DataTag;
import com.sekwah.advancedportals.core.util.Lang;
import com.sekwah.advancedportals.core.connector.container.CommandSenderContainer;
import com.sekwah.advancedportals.core.connector.container.PlayerContainer;
import com.sekwah.advancedportals.core.util.TagReader;
import java.util.ArrayList;
import java.util.List;
public class CreateDestiSubCommand implements SubCommand {
@Override
public void onCommand(CommandSenderContainer sender, String[] args) {
if(args.length > 1) {
PlayerContainer player = sender.getPlayerContainer();
if(player == null) {
sender.sendMessage(Lang.translateColor("messageprefix.negative") + Lang.translate("command.createdesti.console"));
return;
}
ArrayList<DataTag> destiTags = TagReader.getTagsFromArgs(args);
Destination desti = AdvancedPortalsCore.getDestinationServices().createDesti(args[1], player, player.getLoc(), destiTags);
if(desti != null) {
sender.sendMessage(Lang.translateColor("messageprefix.positive") + Lang.translateColor("command.createdesti.complete"));
sender.sendMessage(Lang.translateColor("command.create.tags"));
ArrayList<DataTag> destiArgs = desti.getArgs();
if(destiArgs.size() == 0) {
sender.sendMessage(Lang.translateColor("desti.info.noargs"));
}
else {
for (DataTag tag : destiArgs) {
sender.sendMessage("\u00A7a" + tag.NAME + "\u00A77:\u00A7e" + tag.VALUE);
}
}
}
else {
sender.sendMessage(Lang.translateColor("messageprefix.negative") + Lang.translateColor("command.createdesti.error"));
}
}
else {
sender.sendMessage(Lang.translateColor("messageprefix.positive") + Lang.translate("command.error.noname"));
}
}
@Override
public boolean hasPermission(CommandSenderContainer sender) {
return sender.isOp() || sender.hasPermission("advancedportals.createportal");
}
@Override
public List<String> onTabComplete(CommandSenderContainer sender, String[] args) {
return null;
}
@Override
public String getBasicHelpText() {
return Lang.translate("command.createdesti.help");
}
@Override
public String getDetailedHelpText() {
return Lang.translate("command.createdesti.detailedhelp");
}
}

View File

@ -1,63 +0,0 @@
package com.sekwah.advancedportals.core.commands.subcommands.portal;
import com.sekwah.advancedportals.core.AdvancedPortalsCore;
import com.sekwah.advancedportals.core.api.commands.SubCommand;
import com.sekwah.advancedportals.core.api.portal.AdvancedPortal;
import com.sekwah.advancedportals.core.data.DataTag;
import com.sekwah.advancedportals.core.util.Lang;
import com.sekwah.advancedportals.core.connector.container.CommandSenderContainer;
import com.sekwah.advancedportals.core.connector.container.PlayerContainer;
import com.sekwah.advancedportals.core.util.TagReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class CreatePortalSubCommand implements SubCommand {
@Override
public void onCommand(CommandSenderContainer sender, String[] args) {
if(args.length > 1) {
PlayerContainer player = sender.getPlayerContainer();
if(player == null) {
sender.sendMessage(Lang.translateColor("messageprefix.negative") + Lang.translate("command.create.console"));
return;
}
ArrayList<DataTag> portalTags = TagReader.getTagsFromArgs(args);
AdvancedPortal portal = AdvancedPortalsCore.getPortalServices().createPortal(args[1], player, portalTags);
if(portal != null) {
sender.sendMessage(Lang.translateColor("messageprefix.positive") + Lang.translateColor("command.create.complete"));
sender.sendMessage(Lang.translateColor("command.create.tags"));
sender.sendMessage("\u00A7a" + "triggerBlock\u00A77:\u00A7e" + Arrays.toString(portal.getTriggerBlocks()));
for (DataTag tag: portal.getArgs()) {
sender.sendMessage("\u00A7a" + tag.NAME + "\u00A77:\u00A7e" + tag.VALUE);
}
}
sender.sendMessage(Lang.translateColor("messageprefix.negative") + Lang.translateColor("command.create.error"));
}
else {
sender.sendMessage(Lang.translateColor("messageprefix.positive") + Lang.translate("command.error.noname"));
}
}
@Override
public boolean hasPermission(CommandSenderContainer sender) {
return sender.isOp() || sender.hasPermission("advancedportals.createportal");
}
@Override
public List<String> onTabComplete(CommandSenderContainer sender, String[] args) {
return null;
}
@Override
public String getBasicHelpText() {
return Lang.translate("command.create.help");
}
@Override
public String getDetailedHelpText() {
return Lang.translate("command.create.detailedhelp");
}
}

View File

@ -1,51 +0,0 @@
package com.sekwah.advancedportals.core.commands.subcommands.portal;
import com.google.inject.Inject;
import com.sekwah.advancedportals.core.AdvancedPortalsCore;
import com.sekwah.advancedportals.core.api.commands.SubCommand;
import com.sekwah.advancedportals.core.util.Lang;
import com.sekwah.advancedportals.core.connector.container.CommandSenderContainer;
import com.sekwah.advancedportals.core.connector.container.PlayerContainer;
import java.util.List;
public class EndGatewayBlockSubCommand implements SubCommand {
@Inject
private AdvancedPortalsCore portalsCore;
@Override
public void onCommand(CommandSenderContainer sender, String[] args) {
PlayerContainer player = sender.getPlayerContainer();
if(player == null) {
sender.sendMessage(Lang.translateColor("messageprefix.negative") + Lang.translate("command.playeronly"));
}
else {
player.giveWool("BLACK", "\u00A78Gateway Block Placer"
, "\u00A7rThis wool is made of a magical substance",
"\u00A7rRight Click: Place portal block");
sender.sendMessage(Lang.translateColor("messageprefix.positive") + Lang.translate("command.gatewayblock"));
}
}
@Override
public boolean hasPermission(CommandSenderContainer sender) {
return sender.isOp() || sender.hasPermission("advancedportals.createportal");
}
@Override
public List<String> onTabComplete(CommandSenderContainer sender, String[] args) {
return null;
}
@Override
public String getBasicHelpText() {
return Lang.translate("command.selector.help");
}
@Override
public String getDetailedHelpText() {
return Lang.translate("command.selector.detailedhelp");
}
}

View File

@ -1,51 +0,0 @@
package com.sekwah.advancedportals.core.commands.subcommands.portal;
import com.google.inject.Inject;
import com.sekwah.advancedportals.core.AdvancedPortalsCore;
import com.sekwah.advancedportals.core.api.commands.SubCommand;
import com.sekwah.advancedportals.core.util.Lang;
import com.sekwah.advancedportals.core.connector.container.CommandSenderContainer;
import com.sekwah.advancedportals.core.connector.container.PlayerContainer;
import java.util.List;
public class EndPortalBlockSubCommand implements SubCommand {
@Inject
private AdvancedPortalsCore portalsCore;
@Override
public void onCommand(CommandSenderContainer sender, String[] args) {
PlayerContainer player = sender.getPlayerContainer();
if(player == null) {
sender.sendMessage(Lang.translateColor("messageprefix.negative") + Lang.translate("command.playeronly"));
}
else {
player.giveWool("BLACK", "\u00A78End Portal Block Placer"
, "\u00A7rThis wool is made of a magical substance",
"\u00A7rRight Click: Place portal block");
sender.sendMessage(Lang.translateColor("messageprefix.positive") + Lang.translate("command.endportalblock"));
}
}
@Override
public boolean hasPermission(CommandSenderContainer sender) {
return sender.isOp() || sender.hasPermission("advancedportals.createportal");
}
@Override
public List<String> onTabComplete(CommandSenderContainer sender, String[] args) {
return null;
}
@Override
public String getBasicHelpText() {
return Lang.translate("command.selector.help");
}
@Override
public String getDetailedHelpText() {
return Lang.translate("command.selector.detailedhelp");
}
}

View File

@ -1,44 +0,0 @@
package com.sekwah.advancedportals.core.commands.subcommands.portal;
import com.google.inject.Inject;
import com.sekwah.advancedportals.core.AdvancedPortalsCore;
import com.sekwah.advancedportals.core.api.commands.SubCommand;
import com.sekwah.advancedportals.core.util.Lang;
import com.sekwah.advancedportals.core.connector.container.CommandSenderContainer;
import java.util.List;
public class LangUpdateSubCommand implements SubCommand {
@Inject
private AdvancedPortalsCore portalsCore;
public LangUpdateSubCommand() {
}
@Override
public void onCommand(CommandSenderContainer sender, String[] args) {
this.portalsCore.getDataStorage().copyDefaultFile("lang/en_GB.lang", true);
sender.sendMessage(Lang.translateColor("messageprefix.positive") + Lang.translateColor("translatedata.replaced"));
}
@Override
public boolean hasPermission(CommandSenderContainer sender) {
return sender.isOp() || sender.hasPermission("advancedportals.transupdate");
}
@Override
public List<String> onTabComplete(CommandSenderContainer sender, String[] args) {
return null;
}
@Override
public String getBasicHelpText() {
return Lang.translate("command.trans.help");
}
@Override
public String getDetailedHelpText() {
return Lang.translate("command.trans.help");
}
}

View File

@ -1,53 +0,0 @@
package com.sekwah.advancedportals.core.commands.subcommands.portal;
import com.google.inject.Inject;
import com.sekwah.advancedportals.core.AdvancedPortalsCore;
import com.sekwah.advancedportals.core.api.commands.SubCommand;
import com.sekwah.advancedportals.core.util.Lang;
import com.sekwah.advancedportals.core.connector.container.CommandSenderContainer;
import com.sekwah.advancedportals.core.connector.container.PlayerContainer;
import java.util.List;
public class PortalBlockSubCommand implements SubCommand {
@Inject
private AdvancedPortalsCore portalsCore;
@Override
public void onCommand(CommandSenderContainer sender, String[] args) {
PlayerContainer player = sender.getPlayerContainer();
if(player == null) {
sender.sendMessage(Lang.translateColor("messageprefix.negative") + Lang.translate("command.playeronly"));
}
else {
player.giveWool("PURPLE", "\u00A75Portal Block Placer"
, "\u00A7rThis wool is made of a magical substance",
"\u00A7rRight Click: Place portal block",
"\u00A7rLeft Click: Rotate portal block");
sender.sendMessage(Lang.translateColor("messageprefix.positive") + Lang.translate("command.portalblock"));
}
}
@Override
public boolean hasPermission(CommandSenderContainer sender) {
return sender.isOp() || sender.hasPermission("advancedportals.createportal");
}
@Override
public List<String> onTabComplete(CommandSenderContainer sender, String[] args) {
return null;
}
@Override
public String getBasicHelpText() {
return Lang.translate("command.selector.help");
}
@Override
public String getDetailedHelpText() {
return Lang.translate("command.selector.detailedhelp");
}
}

View File

@ -1,43 +0,0 @@
package com.sekwah.advancedportals.core.commands.subcommands.portal;
import com.google.inject.Inject;
import com.sekwah.advancedportals.core.AdvancedPortalsCore;
import com.sekwah.advancedportals.core.api.commands.SubCommand;
import com.sekwah.advancedportals.core.util.Lang;
import com.sekwah.advancedportals.core.connector.container.CommandSenderContainer;
import java.util.List;
public class ReloadSubCommand implements SubCommand {
@Inject
private AdvancedPortalsCore portalsCore;
@Override
public void onCommand(CommandSenderContainer sender, String[] args) {
portalsCore.loadPortalConfig();
portalsCore.getPortalServices().loadPortals();
portalsCore.getDestinationServices().loadDestinations();
sender.sendMessage(Lang.translateColor("messageprefix.positive") + Lang.translateColor("command.reload.reloaded"));
}
@Override
public boolean hasPermission(CommandSenderContainer sender) {
return sender.isOp() || sender.hasPermission("advancedportals.reload");
}
@Override
public List<String> onTabComplete(CommandSenderContainer sender, String[] args) {
return null;
}
@Override
public String getBasicHelpText() {
return Lang.translate("command.reload.help");
}
@Override
public String getDetailedHelpText() {
return Lang.translate("command.reload.detailedhelp");
}
}

View File

@ -1,70 +0,0 @@
package com.sekwah.advancedportals.core.commands.subcommands.portal;
import com.sekwah.advancedportals.core.AdvancedPortalsCore;
import com.sekwah.advancedportals.core.api.commands.SubCommand;
import com.sekwah.advancedportals.core.api.portal.AdvancedPortal;
import com.sekwah.advancedportals.core.util.Lang;
import com.sekwah.advancedportals.core.connector.container.CommandSenderContainer;
import com.sekwah.advancedportals.core.connector.container.PlayerContainer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
public class RemoveSubCommand implements SubCommand {
@Override
public void onCommand(CommandSenderContainer sender, String[] args) {
if(args.length > 1) {
if(AdvancedPortalsCore.getPortalServices().removePortal(args[1], sender.getPlayerContainer())) {
sender.sendMessage(Lang.translateColor("messageprefix.positive") + Lang.translateColor("command.remove.complete"));
}
else {
sender.sendMessage(Lang.translateColor("messageprefix.negative")
+ Lang.translateColor("command.remove.error"));
}
}
else {
PlayerContainer player = sender.getPlayerContainer();
if(player == null) {
sender.sendMessage(Lang.translate("command.remove.noname"));
}
else {
if(AdvancedPortalsCore.getPortalServices().removePlayerSelection(player)) {
}
else {
sender.sendMessage(Lang.translateColor("messageprefix.negative")
+ Lang.translateColor("command.remove.error"));
}
}
}
}
@Override
public boolean hasPermission(CommandSenderContainer sender) {
return sender.isOp() || sender.hasPermission("advancedportals.createportal");
}
@Override
public List<String> onTabComplete(CommandSenderContainer sender, String[] args) {
List<String> portalNames = new ArrayList<>();
for(Map.Entry<String, AdvancedPortal> portal : AdvancedPortalsCore.getPortalServices().getPortals()) {
portalNames.add(portal.getKey());
}
Collections.sort(portalNames);
return portalNames;
}
@Override
public String getBasicHelpText() {
return Lang.translate("command.create.help");
}
@Override
public String getDetailedHelpText() {
return Lang.translate("command.create.detailedhelp");
}
}

View File

@ -1,50 +0,0 @@
package com.sekwah.advancedportals.core.commands.subcommands.portal;
import com.google.inject.Inject;
import com.sekwah.advancedportals.core.AdvancedPortalsCore;
import com.sekwah.advancedportals.core.api.commands.SubCommand;
import com.sekwah.advancedportals.core.util.Lang;
import com.sekwah.advancedportals.core.connector.container.CommandSenderContainer;
import com.sekwah.advancedportals.core.connector.container.PlayerContainer;
import java.util.List;
public class SelectorSubCommand implements SubCommand {
@Inject
private AdvancedPortalsCore portalsCore;
@Override
public void onCommand(CommandSenderContainer sender, String[] args) {
PlayerContainer player = sender.getPlayerContainer();
if(player == null) {
sender.sendMessage(Lang.translateColor("messageprefix.negative") + Lang.translate("command.playeronly"));
}
else {
player.giveItem(this.portalsCore.getConfigRepo().getSelectorMaterial(), "\u00A7ePortal Region Selector"
, "\u00A7rThis wand with has the power to help", "\u00A7r create portals bistowed upon it!");
sender.sendMessage(Lang.translateColor("messageprefix.positive") + Lang.translate("command.selector"));
}
}
@Override
public boolean hasPermission(CommandSenderContainer sender) {
return sender.isOp() || sender.hasPermission("advancedportals.createportal");
}
@Override
public List<String> onTabComplete(CommandSenderContainer sender, String[] args) {
return null;
}
@Override
public String getBasicHelpText() {
return Lang.translate("command.selector.help");
}
@Override
public String getDetailedHelpText() {
return Lang.translate("command.selector.detailedhelp");
}
}

View File

@ -1,36 +0,0 @@
package com.sekwah.advancedportals.core.commands.subcommands.portal;
import com.sekwah.advancedportals.core.AdvancedPortalsCore;
import com.sekwah.advancedportals.core.api.commands.SubCommand;
import com.sekwah.advancedportals.core.util.Lang;
import com.sekwah.advancedportals.core.connector.container.CommandSenderContainer;
import java.util.List;
public class VersionSubCommand implements SubCommand {
@Override
public void onCommand(CommandSenderContainer sender, String[] args) {
sender.sendMessage(Lang.translateColor("messageprefix.positive") + " Advanced Portals v" + AdvancedPortalsCore.version);
}
@Override
public boolean hasPermission(CommandSenderContainer sender) {
return true;
}
@Override
public List<String> onTabComplete(CommandSenderContainer sender, String[] args) {
return null;
}
@Override
public String getBasicHelpText() {
return Lang.translate("command.version.help");
}
@Override
public String getDetailedHelpText() {
return Lang.translate("command.version.help");
}
}

View File

@ -1,34 +0,0 @@
package com.sekwah.advancedportals.core.config;
/**
* To store the data for config
*/
public class Config {
public boolean useOnlySpecialAxe = true;
public String selectorMaterial = "IRON_AXE";
public boolean portalProtection = true;
public int portalProtectionRaduis = 5;
public String defaultTriggerBlock = "PORTAL";
public boolean stopWaterFlow = true;
public int portalCooldown = 5;
public String warpParticles = "ENDER";
public String warpSound = "ENDER";
public String selectionBlock_BELOW_1_13 = "STAINED_GLASS";
public String selectionBlock = "RED_STAINED_GLASS";
public String translationFile = "en_GB";
public int selectionSubID_BELOW_1_13 = 14;
}

View File

@ -1,31 +0,0 @@
package com.sekwah.advancedportals.core.config;
import com.google.inject.AbstractModule;
import com.google.inject.Provides;
import com.google.inject.Scopes;
import com.sekwah.advancedportals.*;
import com.sekwah.advancedportals.core.AdvancedPortalsCore;
import com.sekwah.advancedportals.repository.*;
public class RepositoryModule extends AbstractModule {
private final AdvancedPortalsCore portalsCore;
public RepositoryModule(AdvancedPortalsCore portalsCore) {
this.portalsCore = portalsCore;
}
@Override
protected void configure() {
bind(IPortalRepository.class).to(PortalRepository.class).in(Scopes.SINGLETON);
bind(IDestinationRepository.class).to(DestinationRepository.class).in(Scopes.SINGLETON);
bind(IPortalRepository.class).to(PortalRepository.class).in(Scopes.SINGLETON);
bind(ConfigRepository.class).to(ConfigRepositoryImpl.class).in(Scopes.SINGLETON);
//bindListener(Matchers.Any(), new Log4JTypeListenr());
}
@Provides
AdvancedPortalsCore providePortalsCore() {
return this.portalsCore;
}
}

View File

@ -1,14 +0,0 @@
package com.sekwah.advancedportals.core.connector.command;
import com.sekwah.advancedportals.core.commands.CommandTemplate;
public abstract class CommandHandler {
private final CommandTemplate commandExecutor;
public CommandHandler(CommandTemplate commandExecutor) {
this.commandExecutor = commandExecutor;
}
}

View File

@ -1,14 +0,0 @@
package com.sekwah.advancedportals.core.connector.command;
import com.sekwah.advancedportals.core.commands.CommandTemplate;
public interface CommandRegister {
/**
* Registers the command to the appropriate system
* @param commandName
* @param commandExecutor
*/
void registerCommand(String commandName, CommandTemplate commandExecutor);
}

View File

@ -1,16 +0,0 @@
package com.sekwah.advancedportals.core.connector.container;
public interface CommandSenderContainer {
void sendMessage(String message);
boolean isOp();
/**
* @return null if there isnt a player e.g. the console
*/
PlayerContainer getPlayerContainer();
boolean hasPermission(String permission);
}

View File

@ -1,7 +0,0 @@
package com.sekwah.advancedportals.core.connector.container;
public interface ServerContainer {
WorldContainer getWorld(String name);
}

View File

@ -1,14 +0,0 @@
package com.sekwah.advancedportals.core.connector.info;
import java.util.List;
/**
* Gets info from the specific implementation
*/
public interface DataCollector {
boolean materialExists(String materialName);
List<String> getMaterials();
}

View File

@ -1,147 +0,0 @@
package com.sekwah.advancedportals.core.data;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.inject.Inject;
import com.sekwah.advancedportals.core.AdvancedPortalsCore;
import java.io.*;
import java.lang.reflect.Type;
public class DataStorage {
private Gson gson = new GsonBuilder().setPrettyPrinting().create();
private File dataFolder;
@Inject
private AdvancedPortalsCore portalsCore;
public DataStorage(File dataStorageLoc) {
this.dataFolder = dataStorageLoc;
}
/**
* Copies the default file, defaults to true to keep true to the name
*
* @param fileLoc
* @return
*/
public boolean copyDefaultFile(String fileLoc) {
return this.copyDefaultFile(fileLoc, true);
}
public void copyDefaultFiles(boolean override, String... fileLocs) {
for (String fileLoc : fileLocs) {
this.copyDefaultFile(fileLoc, override);
}
}
public <T> T loadJson(Type dataHolder, String location) {
InputStream jsonResource = this.loadResource(location);
if(jsonResource == null) {
return null;
}
BufferedReader bufReader = new BufferedReader(new InputStreamReader(jsonResource));
T object = gson.fromJson(bufReader, dataHolder);
return object;
}
public <T> T loadJson(Class<T> dataHolder, String location) {
InputStream jsonResource = this.loadResource(location);
if(jsonResource == null) {
try {
return dataHolder.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return null;
}
BufferedReader bufReader = new BufferedReader(new InputStreamReader(jsonResource));
return gson.fromJson(bufReader, dataHolder);
}
public void storeJson(Object dataHolder, String location) {
String json = gson.toJson(dataHolder);
try {
FileWriter fileWriter = new FileWriter(new File(this.dataFolder, location));
fileWriter.write(json);
fileWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Copies the specified file out of the plugin and into the plugins folder.
*
* @param fileLoc
* @return if the file is copied, will be false if override is false and the file already existed.
*/
public boolean copyDefaultFile(String fileLoc, boolean overwrite) {
File outFile = new File(this.dataFolder, fileLoc);
if (!outFile.exists()) {
outFile.getParentFile().mkdirs();
}
if (!outFile.exists() || overwrite) {
try {
InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(fileLoc);
if(inputStream == null) {
return false;
}
FileOutputStream outStream = new FileOutputStream(outFile);
byte[] buf = new byte[1024];
int len;
while ((len = inputStream.read(buf)) > 0) {
outStream.write(buf, 0, len);
}
inputStream.close();
outStream.close();
} catch (NullPointerException e) {
e.printStackTrace();
this.portalsCore.getInfoLogger().logWarning("Could not load " + fileLoc + ". The file does" +
"not exist or there has been an error reading the file.");
return false;
} catch (FileNotFoundException e) {
e.printStackTrace();
this.portalsCore.getInfoLogger().logWarning("Could not create " + fileLoc);
} catch (IOException e) {
e.printStackTrace();
this.portalsCore.getInfoLogger().logWarning("File error reading " + fileLoc);
}
}
return true;
}
/**
* A method to try to grab the files from the plugin and if its in the plugin folder load from there instead.
* <p>
* @param location
* @return
*/
public InputStream loadResource(String location) {
File inFile = new File(dataFolder, location);
if (inFile.exists() && !inFile.isDirectory()) {
try {
return new FileInputStream(inFile);
} catch (FileNotFoundException e) {
e.printStackTrace();
return null;
}
} else {
try {
copyDefaultFile(location, false);
return this.getClass().getClassLoader().getResourceAsStream(location);
} catch (NullPointerException e) {
e.printStackTrace();
this.portalsCore.getInfoLogger().logWarning("Could not load " + location + ". The file does" +
"not exist or there has been an error reading the file.");
return null;
}
}
}
}

View File

@ -1,13 +0,0 @@
package com.sekwah.advancedportals.core.data;
public class DataTag {
public final String NAME;
public final String VALUE;
public DataTag(String argName, String value) {
this.NAME = argName;
this.VALUE = value;
}
}

View File

@ -1,67 +0,0 @@
package com.sekwah.advancedportals.core.data;
import com.google.gson.annotations.SerializedName;
public class PlayerLocation {
@SerializedName("x")
private final double posX;
@SerializedName("y")
private final double posY;
@SerializedName("z")
private final double posZ;
@SerializedName("w")
private final String worldName;
@SerializedName("yaw")
private final float yaw;
@SerializedName("p")
private final float pitch;
public PlayerLocation(String worldName, double posX, double posY, double posZ) {
this.worldName = worldName;
this.posX = posX;
this.posY = posY;
this.posZ = posZ;
this.yaw = 0;
this.pitch = 0;
}
public PlayerLocation(String worldName, double posX, double posY, double posZ, float yaw, float pitch) {
this.worldName = worldName;
this.posX = posX;
this.posY = posY;
this.posZ = posZ;
this.yaw = yaw;
this.pitch = pitch;
}
public double getPosX() {
return posX;
}
public double getPosY() {
return posY;
}
public double getPosZ() {
return posZ;
}
public String getWorldName() {
return worldName;
}
public float getYaw() {
return yaw;
}
public float getPitch() {
return pitch;
}
}

View File

@ -1,13 +0,0 @@
package com.sekwah.advancedportals.core.data;
public class PlayerTempData {
private PortalLocation pos1;
private PortalLocation pos2;
private long lastAttempt;
private String selectedPortal;
}

View File

@ -1,25 +0,0 @@
package com.sekwah.advancedportals.core.data;
import com.google.gson.annotations.SerializedName;
public class PortalLocation {
@SerializedName("x")
public final int posX;
@SerializedName("y")
public final int posY;
@SerializedName("z")
public final int posZ;
@SerializedName("w")
public final String worldName;
public PortalLocation(String worldName, int posX, int posY, int posZ) {
this.worldName = worldName;
this.posX = posX;
this.posY = posY;
this.posZ = posZ;
}
}

View File

@ -1,9 +0,0 @@
package com.sekwah.advancedportals.core.registry;
public class AnnotationScanner {
public void registerSubCommands() {
//AnnotationScanner.class.getClassLoader()
}
}

View File

@ -1,18 +0,0 @@
package com.sekwah.advancedportals.core.registry;
import com.google.common.collect.ImmutableList;
import com.sekwah.advancedportals.core.connector.container.CommandSenderContainer;
public class CommandDemo implements CommandHandler {
@Override
public void onExecute(String commandName, String parentCommand, CommandSenderContainer sender, ImmutableList<String> args) {
}
@Override
public void onCommandFailure(String[] command, CommandSenderContainer sender, CommandException exception, ImmutableList<String> args) {
}
}

View File

@ -1,6 +0,0 @@
package com.sekwah.advancedportals.core.registry;
//TODO
public class CommandErrorException extends Exception {
private String reason;
}

View File

@ -1,19 +0,0 @@
package com.sekwah.advancedportals.core.registry;
public class CommandException {
private ErrorCode errorCode;
private String message;
public CommandException(ErrorCode errorCode, String message) {
this.errorCode = errorCode;
this.message = message;
}
public ErrorCode getErrorCode() {
return errorCode;
}
public String getMessage() {
return message;
}
}

View File

@ -1,12 +0,0 @@
package com.sekwah.advancedportals.core.registry;
import com.google.common.collect.ImmutableList;
import com.sekwah.advancedportals.core.connector.container.CommandSenderContainer;
public interface CommandHandler {
void onExecute(String commandName, String parentCommand, CommandSenderContainer sender, ImmutableList<String> args);
default void onCommandFailure(String[] command, CommandSenderContainer sender, CommandException exception, ImmutableList<String> args) {
sender.sendMessage(exception.getMessage());
}
}

View File

@ -1,12 +0,0 @@
package com.sekwah.advancedportals.core.registry;
public enum ErrorCode {
INSUFFICIENT_ARGUMENTS(""),
NO_PERMISSION("");
;
ErrorCode(String message) {
}
}

View File

@ -1,85 +0,0 @@
package com.sekwah.advancedportals.core.registry;
import com.sekwah.advancedportals.core.AdvancedPortalsCore;
import com.sekwah.advancedportals.core.api.commands.SubCommand;
import com.sekwah.advancedportals.core.util.InfoLogger;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
/**
* Do not register to here. Register to the sprcific subcommand registry classes.
* <p>
* Designed to let addons add new command sections to access, edit or add new functonality.
*
* @author sekwah41
*/
public class SubCommandRegistry {
protected Map<String, SubCommand> subCommandMap = new HashMap<>();
/**
* List of subcommand names which should be in order alphabetically
*/
protected ArrayList<String> subCommands = new ArrayList<>();
private InfoLogger infoLogger = AdvancedPortalsCore.getInstance().getInfoLogger();
/**
* @param arg argument needed to activate
* @param subCommand
* @return if the subcommand is registered or not
*/
public boolean registerSubCommand(String arg, SubCommand subCommand) {
if (subCommand == null) {
this.infoLogger.logWarning("The subcommand '" + arg + "' cannot be null.");
return false;
}
if(this.subCommandMap.containsKey(arg)){
this.infoLogger.logWarning("The subcommand '" + arg + "' already exists.");
return false;
}
this.subCommandMap.put(arg.toLowerCase(), subCommand);
this.subCommands.add(arg.toLowerCase());
Collections.sort(this.subCommands);
return true;
}
/**
* @return a list of arguments of registered subcommands
*/
public ArrayList<String> getSubCommands(){
return this.subCommands;
}
/**
* I may be wrong but for larger lists containsKey is faster with a hashmap than arraylist.
*
* Though im not sure at what size it becomes more efficient.
* @param arg
* @return if the argument is registered
*/
public boolean isArgRegistered(String arg){
return this.subCommandMap.containsKey(arg.toLowerCase());
}
/**
* Gets the subcommand corresponding to the string argument
* @param arg
* @return the subcommand linked to the arg
*/
public SubCommand getSubCommand(String arg){
if(this.subCommandMap.containsKey(arg.toLowerCase())){
return this.subCommandMap.get(arg.toLowerCase());
}
return null;
}
}

View File

@ -1,157 +0,0 @@
package com.sekwah.advancedportals.core.registry;
import com.google.inject.Inject;
import com.sekwah.advancedportals.core.AdvancedPortalsCore;
import com.sekwah.advancedportals.core.api.warphandler.TagHandler;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
/**
* Allows a portal to register a tag and add a handler. If a plugin wants to add functionality
* to someone elses tag then they should use the events.
*
* @author sekwah41
*/
public class TagRegistry<T> {
@Inject
private AdvancedPortalsCore portalsCore;
/**
* List of tag names which should be in order alphabetically
*/
private ArrayList<String> tags = new ArrayList();
/**
* Description of tags for help commands
*/
private Map<String, String> tagDesc = new HashMap();
private Map<String, TagHandler.Activation<T>> activationHandlers = new HashMap();
private Map<String, TagHandler.Creation<T>> creationHandlers = new HashMap();
private Map<String, TagHandler.TagStatus<T>> statusHandlers = new HashMap();
/**
*
* @param arg
* @return
*/
public TagHandler.Activation<T> getActivationHandler(String arg) {
return this.activationHandlers.get(arg);
}
/**
*
* @param arg
* @return
*/
public TagHandler.Creation<T> getCreationHandler(String arg) {
return this.creationHandlers.get(arg);
}
/**
*
* @param arg
* @return
*/
public TagHandler.TagStatus<T> getTagStatusHandler(String arg) {
return this.statusHandlers.get(arg);
}
/**
*
* @param tag
* @param desc
* @param tagHandler
* @return if the tag was registered
*/
public boolean registerTag(String tag, String desc, TagHandler tagHandler) {
if (registerTag(tag, tagHandler)) {
this.tagDesc.put(tag, desc);
}
return false;
}
/**
* It is reccomended that you use the taghandlers to add tag functionality. However
* if needed such as extra data for a tag then this is here.
*
* @param tag
* @return if the tag was registered
*/
public boolean registerTag(String tag) {
if (tag.contains(" ")) {
this.portalsCore.getInfoLogger().logWarning("The tag '"
+ tag + "' is invalid as it contains spaces.");
return false;
}
if (this.tags.contains(tag)) {
this.portalsCore.getInfoLogger().logWarning("The tag "
+ tag + " has already been registered.");
return false;
}
this.tags.add(tag);
Collections.sort(this.tags);
return true;
}
/**
* Same as registerTag(String tag) but allows a description to be added.
*
* @param tag Tag to be used on command line
* @param desc
* @return if the tag was registered
*/
public boolean registerTag(String tag, String desc) {
if (registerTag(tag)) {
this.tagDesc.put(tag, desc);
return true;
}
return false;
}
/**
* Returns a non referenced copy of the array list.
* @return
*/
public ArrayList<String> getTags() {
ArrayList<String> newArrayList = new ArrayList<>();
newArrayList.addAll(this.tags);
return newArrayList;
}
public boolean isTagRegistered(String tag){
return this.tagDesc.containsKey(tag);
}
/**
* File must extend
* @return if the tag has been registered or if it already exists.
*/
public boolean registerTag(String tag, Object tagHandler) {
if (tag == null) {
this.portalsCore.getInfoLogger().logWarning("A tag cannot be null.");
return false;
}
if (!this.registerTag(tag)) {
return false;
}
if (tagHandler instanceof TagHandler.Activation) {
this.activationHandlers.put(tag, (TagHandler.Activation<T>) tagHandler);
}
if (tagHandler instanceof TagHandler.TagStatus) {
this.statusHandlers.put(tag, (TagHandler.TagStatus<T>) tagHandler);
}
if (tagHandler instanceof TagHandler.Creation) {
this.creationHandlers.put(tag, (TagHandler.Creation<T>) tagHandler);
}
return true;
}
}

View File

@ -1,78 +0,0 @@
package com.sekwah.advancedportals.core.registry;
import com.google.inject.Inject;
import com.sekwah.advancedportals.core.AdvancedPortalsCore;
import com.sekwah.advancedportals.core.api.effect.WarpEffect;
import java.util.HashMap;
import java.util.Map;
/**
* @author sekwah41
*/
public class WarpEffectRegistry {
private Map<String, WarpEffect> visualEffects = new HashMap();
private Map<String, WarpEffect> soundEffects = new HashMap();
@Inject
private AdvancedPortalsCore portalsCore;
/**
* Register a new warp effect.
*
* @param name
* @param effect
* @return if the effect was registered
*/
public boolean registerEffect(String name, WarpEffect effect, WarpEffect.Type type) {
if(name == null){
return false;
}
Map<String, WarpEffect> list = null;
switch (type){
case SOUND:
list = this.soundEffects;
break;
case VISUAL:
list = this.visualEffects;
break;
default:
this.portalsCore.getInfoLogger().logWarning(type.toString()
+ " effect type not recognised");
return false;
}
if(list.containsKey(name)){
return false;
}
list.put(name, effect);
return true;
}
public WarpEffect getEffect(String name, WarpEffect.Type type){
Map<String, WarpEffect> list = null;
switch (type){
case SOUND:
list = this.soundEffects;
break;
case VISUAL:
list = this.visualEffects;
break;
default:
this.portalsCore.getInfoLogger().logWarning(type.toString()
+ " effect type not recognised");
return null;
}
if(list.containsKey(name)) {
return list.get(name);
}
else{
this.portalsCore.getInfoLogger().logWarning("No effect of type:"
+ type.toString() + " was registered with the name: " + name);
return null;
}
}
}

View File

@ -1,30 +0,0 @@
package com.sekwah.advancedportals.core.services;
import com.sekwah.advancedportals.core.api.destination.Destination;
import com.sekwah.advancedportals.core.data.DataTag;
import com.sekwah.advancedportals.core.data.PlayerLocation;
import com.sekwah.advancedportals.core.connector.container.PlayerContainer;
import java.util.ArrayList; /**
* https://github.com/sekwah41/Advanced-Portals/blob/24175610892152828e21f4ff824eb1589ccb0338/src/com/sekwah/advancedportals/core/api/managers/DestinationManager.java
* Based off the old manager with the data storage and handling moved to
*/
public final class DestinationServices {
/**
*/
public void loadDestinations() {
}
/**
* @param name
* @param player
* @param loc
* @param destiTags
* @return null if not created
*/
public Destination createDesti(String name, PlayerContainer player, PlayerLocation loc, ArrayList<DataTag> destiTags) {
return null;
}
}

View File

@ -1,51 +0,0 @@
package com.sekwah.advancedportals.core.services;
import com.google.common.collect.ImmutableList;
import com.sekwah.advancedportals.repository.IPortalRepository;
import com.sekwah.advancedportals.core.api.portal.AdvancedPortal;
import com.sekwah.advancedportals.core.data.DataTag;
import com.sekwah.advancedportals.core.data.PlayerLocation;
import com.sekwah.advancedportals.core.connector.container.PlayerContainer;
import java.util.ArrayList;
import java.util.Map;
/**
* https://github.com/sekwah41/Advanced-Portals/blob/24175610892152828e21f4ff824eb1589ccb0338/src/com/sekwah/advancedportals/core/api/managers/PortalManager.java
*
* Based off the old manager with the data storage and handling moved to {@link IPortalRepository}
*
* Excluding the temp data like selections
*/
public final class PortalServices {
public void loadPortals() {
}
public boolean inPortalRegion(PlayerLocation loc) {
return false;
}
public boolean playerMove(PlayerContainer player, PlayerLocation fromLoc, PlayerLocation toLoc) {
return false;
}
public ImmutableList<? extends Map.Entry<String, AdvancedPortal>> getPortals() {
return null;
}
public boolean removePortal(String name, PlayerContainer player) {
return false;
}
public AdvancedPortal createPortal(String name, PlayerContainer player, ArrayList<DataTag> portalTags) {
return null;
}
public boolean removePlayerSelection(PlayerContainer player) {
return false;
}
}

View File

@ -1,26 +0,0 @@
package com.sekwah.advancedportals.core.services;
import com.sekwah.advancedportals.core.data.PlayerTempData;
import com.sekwah.advancedportals.core.data.PortalLocation;
import com.sekwah.advancedportals.core.connector.container.PlayerContainer;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
public final class PortalTempDataServices {
/**
* Possibly change to the cache map Aztec was talking about
*/
private Map<UUID, PlayerTempData> tempDataMap = new HashMap<>();
public void activateCooldown(PlayerContainer player) {
}
public void playerLeave(PlayerContainer player) {
}
public void playerSelectorActivate(PlayerContainer player, PortalLocation blockLoc, boolean leftClick) {
}
}

View File

@ -1,16 +0,0 @@
package com.sekwah.advancedportals.core.util;
public abstract class InfoLogger {
/**
* Problematic messages
* @param s warning message
*/
public abstract void logWarning(String s);
/**
* General information logging
* @param s info message
*/
public abstract void log(String s);
}

View File

@ -1,112 +0,0 @@
package com.sekwah.advancedportals.core.util;
import com.sekwah.advancedportals.core.AdvancedPortalsCore;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
/**
* @author sekwah41
* <p>
* The language translation file for the game. Will always load english first
* so that if the translations are missing any then they are still readable and can then be translated.
* (Its better than a raw translate string)
* <p>
* TODO add a loaddefault where it only loads from the plugins version of the data rather than paying attention to any
* possible changed versions in the lang folder.
*/
public class Lang {
private static final Lang instance = new Lang();
private final HashMap<String, String> languageMap = new HashMap<>();
//private final String DEFAULT_LANG = "en_GB";
/*public Lang() {
injectTranslations(this, DEFAULT_LANG);
}*/
public static void loadLanguage(String fileName) {
instance.injectTranslations(instance, fileName);
}
public static String translate(String s) {
if (instance.languageMap.containsKey(s)) {
return instance.languageMap.get(s);
} else {
return s;
}
}
public static String translateInsertVariables(String s, Object... args) {
String translation = instance.translate(s);
for (int i = 1; i <= args.length; i++) {
translation = translation.replaceAll("%" + i + "\\$s", args[i-1].toString());
}
return translation;
}
public static String translateInsertVariablesColor(String s, Object... args) {
String translation = instance.translateColor(s);
for (int i = 1; i <= args.length; i++) {
translation = translation.replaceAll("%" + i + "\\$s", args[i-1].toString());
}
return translation;
}
public static String translateColor(String s) {
String translation = instance.translate(s);
translation = translation.replaceAll("\\\\u00A7", "\u00A7");
return translation;
}
private void injectTranslations(Lang lang, String fileName) {
try {
//URL url = lang.getClass().getClassLoader().getResource("lang/" + fileName + ".lang");
//System.out.println(url);
//Map<String, String> newLangMap = lang.parseLang(url.openStream());
InputStream stream = AdvancedPortalsCore.getInstance().getDataStorage().loadResource("lang/" + fileName + ".lang");
if (stream != null) {
Map<String, String> newLangMap = lang.parseLang(stream);
if (newLangMap != null) {
lang.languageMap.putAll(newLangMap);
}
}
} catch (NullPointerException e) {
e.printStackTrace();
AdvancedPortalsCore.getInstance().getInfoLogger().logWarning("Could not load " + fileName + ".lang The file does" +
"not exist or there has been an error reading the file. Canceled loading language file.");
}
}
private Map<String, String> parseLang(InputStream inputStream) {
Scanner scanner = new Scanner(inputStream, "UTF-8");
String line = getNextLine(scanner);
HashMap<String, String> newMap = new HashMap<>();
while (scanner != null && line != null) {
//System.out.println(line);
if (!line.startsWith("#") && line.indexOf('=') > -1) {
int split = line.indexOf('=');
String key = line.substring(0, split);
String value = line.substring(split + 1, line.length());
newMap.put(key, value);
}
line = getNextLine(scanner);
}
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
return newMap;
}
private String getNextLine(Scanner scanner) {
if (scanner.hasNextLine()) {
return scanner.nextLine();
}
return null;
}
}

View File

@ -1,51 +0,0 @@
package com.sekwah.advancedportals.core.util;
import com.sekwah.advancedportals.core.data.DataTag;
import java.util.ArrayList;
public class TagReader {
public static ArrayList<DataTag> getTagsFromArgs(String[] args) {
ArrayList<DataTag> tags = new ArrayList<>();
boolean partingValueWithSpaces = false;
String argBeingParsed = "";
String currentParsedValue = "";
for (int i = 1; i < args.length; i++) {
if(partingValueWithSpaces) {
if(args[i].charAt(args[i].length() - 1) == '"') {
args[i] = args[i].substring(0, args[i].length() - 1);
partingValueWithSpaces = false;
tags.add(new DataTag(argBeingParsed.toLowerCase(), currentParsedValue));
}
else {
currentParsedValue += " " + args[i];
}
}
else {
String detectedTag = TagReader.getTag(args[i].toLowerCase());
if(detectedTag != null) {
String arg = args[i].substring(detectedTag.length() + 1);
if(arg.length() > 0 && arg.charAt(0) == '"') {
argBeingParsed = detectedTag;
currentParsedValue = arg;
}
else {
tags.add(new DataTag(detectedTag.toLowerCase(), arg));
}
}
}
}
return tags;
}
public static String getTag(String arg) {
int splitLoc = arg.indexOf(":");
if(splitLoc != -1) {
return arg.substring(0,splitLoc);
}
return null;
}
}

View File

@ -1,60 +0,0 @@
package com.sekwah.advancedportals.repository;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableMap;
import com.sekwah.advancedportals.core.api.destination.Destination;
import javax.inject.Singleton;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
@Singleton
public class DestinationRepository implements IDestinationRepository<Destination> {
private final String fileLocation = "";
private Map<String, Destination> destinationCache = new HashMap<String, Destination>();
/*Is there any reason to load it into the array if it's not been used or connected? Q for Sekwah*/
public void AddDestination(String name, Destination destination) throws IOException {
gson.toJson(destination, new FileWriter(fileLocation + name + ".json"));
}
private void test() {
destinationCache.get("");
}
@Override
public boolean save(String name, Destination destination) {
return false;
}
public boolean containsKey(String name) {
return Files.exists(Paths.get(fileLocation + "\\" + name + ".json"));
}
@Override
public boolean delete(String name) {
try {
Files.deleteIfExists(Paths.get(fileLocation + "\\" + name + ".json"));
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
@Override
public boolean update(String name, Destination destination) {
return false;
}
public ImmutableMap<String, Destination> get(String s) {
return null;
}
}

View File

@ -1,4 +0,0 @@
package com.sekwah.advancedportals.repository;
public interface IDestinationRepository<T> extends IJsonRepository<T> {
}

View File

@ -1,14 +0,0 @@
package com.sekwah.advancedportals.repository;
import com.google.gson.Gson;
public interface IJsonRepository<T> {
Gson gson = new Gson();
public boolean save(String name, T t);
public boolean containsKey(String name);
public boolean delete(String name);
public boolean update(String name, T t);
}

View File

@ -1,7 +0,0 @@
package com.sekwah.advancedportals.repository;
import com.sekwah.advancedportals.core.data.PortalLocation;
public interface IPortalRepository extends IJsonRepository<PortalLocation> {
}

View File

@ -1,25 +0,0 @@
package com.sekwah.advancedportals.repository;
import com.sekwah.advancedportals.core.data.PlayerLocation;
import com.sekwah.advancedportals.core.data.PortalLocation;
import com.sekwah.advancedportals.core.connector.container.PlayerContainer;
import java.util.UUID;
public interface IPortalTempDataRepository {
void addSelectedPortal(UUID selectedPlayer, String portal);
void removeSelectedPortal(UUID uuid);
void addSelectedPosition(UUID uuid, boolean isPos1, PortalLocation portalLocation);
void removeSelectedPosition(UUID uuid, boolean isPos1);
void removeAllSelectedHand(UUID uuid);
void activateCooldown(PlayerContainer player);
void playerLeave(PlayerContainer player);
boolean inPortalRegion(PlayerLocation loc);
}

View File

@ -1,41 +0,0 @@
package com.sekwah.advancedportals.repository;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.inject.Singleton;
import com.sekwah.advancedportals.core.data.PortalLocation;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
@Singleton
public class PortalRepository implements IPortalRepository {
Cache<UUID, String> selectedPortal = CacheBuilder.newBuilder()
.concurrencyLevel(4)
.expireAfterAccess(30, TimeUnit.DAYS)
.build();
public String getSelectedPortal(UUID uuid) {
return selectedPortal.getIfPresent(uuid);
}
@Override
public boolean save(String name, PortalLocation portalLocation) {
return false;
}
@Override
public boolean containsKey(String name) {
return false;
}
@Override
public boolean delete(String name) {
return false;
}
@Override
public boolean update(String name, PortalLocation portalLocation) {
return false;
}
}

View File

@ -1,105 +0,0 @@
package com.sekwah.advancedportals.services;
import com.google.common.collect.ImmutableMap;
import com.google.gson.reflect.TypeToken;
import com.sekwah.advancedportals.core.data.DataTag;
import com.sekwah.advancedportals.core.data.PlayerLocation;
import com.sekwah.advancedportals.core.api.destination.Destination;
import com.sekwah.advancedportals.core.api.warphandler.TagHandler;
import com.sekwah.advancedportals.core.AdvancedPortalsCore;
import com.sekwah.advancedportals.core.util.Lang;
import com.sekwah.advancedportals.core.connector.container.PlayerContainer;
import com.sekwah.advancedportals.repository.DestinationRepository;
import javax.inject.Inject;
import java.io.IOException;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashMap;
/**
* Handles logic for all destination, this is a transient layer so it should
* not store any information.
*/
public class DestinationServices {
DestinationRepository destinationRepository;
@Inject
private DestinationServices(DestinationRepository destinationRepository) {
this.destinationRepository = destinationRepository;
}
public Response.Creation create(String name, Destination destination) {
if (!destinationRepository.containsKey(name)) {
destinationRepository.save(name, destination);
return Response.Creation.SUCCESS;
}
return Response.Creation.NAME_IN_USE;
}
public Boolean delete(String name) {
if (!destinationRepository.containsKey(name)) {
destinationRepository.delete(name);
}
return false;
}
public ImmutableMap<String, Destination> getDestination() {
return destinationRepository.get("");
}
public ImmutableMap<String, Destination> getDestinations() {
return ImmutableMap.copyOf(destinationRepository.get(""));
}
public Destination createDesti(String name, PlayerContainer player, PlayerLocation playerLocation, ArrayList<DataTag> tags) {
// TODO change to write messages
if(name == null || name.equals("")) {
player.sendMessage(Lang.translateColor("messageprefix.positive") + Lang.translate("desti.error.noname"));
return null;
}
else if(this.destinationRepository.containsKey(name)) {
player.sendMessage(Lang.translateColor("messageprefix.positive") + Lang.translate("desti.error.takenname"));
return null;
}
Destination desti = new Destination(playerLocation);
for(DataTag portalTag : tags) {
desti.setArg(portalTag);
}
for(DataTag destiTag : tags) {
TagHandler.Creation<Destination> creation = AdvancedPortalsCore.getDestinationTagRegistry().getCreationHandler(destiTag.NAME);
if(creation != null) {
creation.created(desti, player, destiTag.VALUE);
}
}
try {
this.destinationRepository.AddDestination(name, desti);
} catch (IOException e) {
e.printStackTrace();
}
this.saveDestinations();
return desti;
}
//TODO Change to repository
public void loadDestinations() {
Type type = new TypeToken<HashMap<String, Destination>>() {
}.getType();
//this.destiHashMap = this.portalsCore.getDataStorage().loadJson(type, "destinations.json");
this.saveDestinations();
}
public void saveDestinations() {
/*if (this.destiHashMap == null) {
this.destiHashMap = new HashMap<>();
}
this.portalsCore.getDataStorage().storeJson(this.destiHashMap, "destinations.json");*/
}
}

View File

@ -1,52 +0,0 @@
package com.sekwah.advancedportals.services;
import com.google.inject.Inject;
import com.sekwah.advancedportals.core.data.PlayerLocation;
import com.sekwah.advancedportals.core.data.PortalLocation;
import com.sekwah.advancedportals.core.connector.container.PlayerContainer;
import com.sekwah.advancedportals.repository.IPortalRepository;
import java.util.UUID;
public class PortalServices {
private final IPortalRepository portalRepository;
@Inject
public PortalServices(IPortalRepository portalRepository) {
this.portalRepository = portalRepository;
}
public void addSelectedPortal(UUID selectedPlayer, String portal) {
//portalRepository.save(selectedPlayer, portal);
}
public void removeSelectedPortal(UUID uuid) {
//selectedPortal.invalidate(uuid);
}
public void addSelectedPosition(UUID uuid, boolean isPos1, PortalLocation portalLocation) {
//selectedPositions.put(uuid, isPos1, portalLocation);
}
public void removeSelectedPosition(UUID uuid, boolean isPos1) {
//selectedPositions.remove(uuid, isPos1);
}
public void removeAllSelectedHand(UUID uuid) {
//selectedPositions.remove(uuid, true);
//selectedPositions.remove(uuid, false);
}
public void activateCooldown(PlayerContainer player) {
}
public void playerLeave(PlayerContainer player) {
}
public boolean inPortalRegion(PlayerLocation loc) {
return false;
}
}

View File

@ -1,10 +0,0 @@
package com.sekwah.advancedportals.services;
public class Response {
public enum Creation {
SUCCESS,
NAME_IN_USE,
}
}

View File

@ -1,5 +1,11 @@
rootProject.name = "advanced-portals"
// Core modules
include 'core'
include 'api'
// Implementations
include 'spigot'
// Proxies
include 'velocity'
include 'bungee'
include 'core'

View File

@ -1,8 +1,3 @@
apply plugin: 'java'
apply plugin: 'maven'
apply plugin: 'idea'
apply plugin: 'eclipse'
tasks.withType(JavaCompile) {
options.encoding = 'UTF-8'
@ -16,7 +11,6 @@ configurations {
repositories {
maven { url "https://repo.maven.apache.org/maven2" }
maven { url "https://hub.spigotmc.org/nexus/content/repositories/snapshots/" }
maven { url "https://oss.sonatype.org/content/repositories/snapshots/" }
}
// includeLibs just says to include the library in the final jar
@ -24,7 +18,7 @@ dependencies {
implementation project(":core")
// For spigot api
implementation "org.spigotmc:spigot-api:1.16.1-R0.1-SNAPSHOT"
implementation "org.spigotmc:spigot-api:1.16.5-R0.1-SNAPSHOT"
}
jar {

View File

@ -1,22 +0,0 @@
package com.sekwah.advancedportals.spigot;
import com.sekwah.advancedportals.core.util.InfoLogger;
public class SpigotInfoLogger extends InfoLogger {
private final AdvancedPortalsPlugin plugin;
public SpigotInfoLogger(AdvancedPortalsPlugin plugin) {
this.plugin = plugin;
}
@Override
public void logWarning(String s) {
plugin.getLogger().warning(s);
}
@Override
public void log(String s) {
plugin.getLogger().info(s);
}
}

View File

@ -1,66 +0,0 @@
package com.sekwah.advancedportals.spigot.convertolddata;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.plugin.java.JavaPlugin;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
public class ConfigAccessor {
private final String fileName;
private final JavaPlugin plugin;
private File configFile;
private FileConfiguration fileConfiguration;
public ConfigAccessor(JavaPlugin plugin, String fileName) {
this.plugin = plugin;
this.fileName = fileName;
}
public void reloadConfig() {
if (configFile == null) {
File dataFolder = plugin.getDataFolder();
if (dataFolder == null)
throw new IllegalStateException();
configFile = new File(dataFolder, fileName);
}
fileConfiguration = YamlConfiguration.loadConfiguration(configFile);
YamlConfiguration defConfig = YamlConfiguration.loadConfiguration(new File(this.getClass()
.getClassLoader().getResource(fileName).getPath()));
fileConfiguration.setDefaults(defConfig);
}
public FileConfiguration getConfig() {
if (fileConfiguration == null) {
this.reloadConfig();
}
return fileConfiguration;
}
public void saveConfig() {
if (fileConfiguration == null || configFile == null) {
return;
} else {
try {
getConfig().save(configFile);
} catch (IOException ex) {
plugin.getLogger().log(Level.SEVERE, "Could not save config to " + configFile, ex);
}
}
}
public void saveDefaultConfig() {
if (configFile == null) {
configFile = new File(plugin.getDataFolder(), fileName);
}
if (!configFile.exists()) {
plugin.saveResource(fileName, false);
}
}
}

View File

@ -1,41 +0,0 @@
package com.sekwah.advancedportals.spigot.convertolddata;
import com.sekwah.advancedportals.core.api.commands.SubCommand;
import com.sekwah.advancedportals.core.util.Lang;
import com.sekwah.advancedportals.core.connector.container.CommandSenderContainer;
import java.util.List;
/**
* TODO this is for spigot only for a few releases
*/
public class ConvertOldSubCommand implements SubCommand {
@Override
public void onCommand(CommandSenderContainer sender, String[] args) {
sender.sendMessage(Lang.translateColor("messageprefix.positive") + Lang.translateColor(" Old portal data found."));
sender.sendMessage(Lang.translateColor("messageprefix.positive") + Lang.translateColor(" Old portal data successfully converted."));
sender.sendMessage(Lang.translateColor("messageprefix.positive") + Lang.translateColor(" Old desti data found."));
sender.sendMessage(Lang.translateColor("messageprefix.positive") + Lang.translateColor(" Old desti data successfully converted."));
sender.sendMessage(Lang.translateColor("messageprefix.positive") + Lang.translateColor(" Those were just sample outputs, it doesnt work yet."));
}
@Override
public boolean hasPermission(CommandSenderContainer sender) {
return sender.isOp();
}
@Override
public List<String> onTabComplete(CommandSenderContainer sender, String[] args) {
return null;
}
@Override
public String getBasicHelpText() {
return null;
}
@Override
public String getDetailedHelpText() {
return null;
}
}

View File

@ -1,30 +0,0 @@
package com.sekwah.advancedportals.spigot.coreconnector.command;
import com.sekwah.advancedportals.core.commands.CommandTemplate;
import com.sekwah.advancedportals.spigot.coreconnector.container.SpigotCommandSenderContainer;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabCompleter;
import java.util.List;
public class SpigotCommandHandler implements CommandExecutor, TabCompleter {
private final CommandTemplate commandExecutor;
public SpigotCommandHandler(CommandTemplate commandExecutor) {
this.commandExecutor = commandExecutor;
}
@Override
public boolean onCommand(CommandSender commandSender, Command command, String s, String[] args) {
this.commandExecutor.onCommand(new SpigotCommandSenderContainer(commandSender), command.getName(), args);
return true;
}
@Override
public List<String> onTabComplete(CommandSender commandSender, Command command, String s, String[] args) {
return this.commandExecutor.onTabComplete(new SpigotCommandSenderContainer(commandSender), args);
}
}

View File

@ -1,26 +0,0 @@
package com.sekwah.advancedportals.spigot.coreconnector.command;
import com.sekwah.advancedportals.core.commands.CommandTemplate;
import com.sekwah.advancedportals.core.connector.command.CommandRegister;
import com.sekwah.advancedportals.spigot.AdvancedPortalsPlugin;
/**
* Register the CommandTemplate files to the appropriate system
*/
public class SpigotCommandRegister implements CommandRegister {
private final AdvancedPortalsPlugin plugin;
public SpigotCommandRegister(AdvancedPortalsPlugin plugin) {
this.plugin = plugin;
}
/**
* Registers the command to the appropriate system
* @param commandName
* @param commandExecutor
*/
public void registerCommand(String commandName, CommandTemplate commandExecutor) {
this.plugin.getCommand(commandName).setExecutor(new SpigotCommandHandler(commandExecutor));
}
}

View File

@ -1,36 +0,0 @@
package com.sekwah.advancedportals.spigot.coreconnector.container;
import com.sekwah.advancedportals.core.connector.container.CommandSenderContainer;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
public class SpigotCommandSenderContainer implements CommandSenderContainer {
private final CommandSender sender;
public SpigotCommandSenderContainer(CommandSender commandSender) {
this.sender = commandSender;
}
public void sendMessage(String message) {
sender.sendMessage(message);
}
public boolean isOp() {
return sender.isOp();
}
/**
* @return null if there isnt a player e.g. the console
*/
public SpigotPlayerContainer getPlayerContainer() {
if (sender instanceof Player) {
return new SpigotPlayerContainer((Player) sender);
}
return null;
}
public boolean hasPermission(String permission) {
return sender.hasPermission(permission);
}
}

View File

@ -1,103 +0,0 @@
package com.sekwah.advancedportals.spigot.coreconnector.container;
import com.google.inject.Inject;
import com.sekwah.advancedportals.core.AdvancedPortalsCore;
import com.sekwah.advancedportals.core.data.PlayerLocation;
import com.sekwah.advancedportals.core.data.PortalLocation;
import com.sekwah.advancedportals.core.connector.container.PlayerContainer;
import com.sekwah.advancedportals.core.connector.container.WorldContainer;
import org.bukkit.Bukkit;
import org.bukkit.DyeColor;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.material.Wool;
import java.util.Arrays;
import java.util.UUID;
/**
* Just a temporary container for whenever advanced portals needs to get data from a player
*/
public class SpigotPlayerContainer implements PlayerContainer {
@Inject
private AdvancedPortalsCore portalsCore;
private final Player player;
public SpigotPlayerContainer(Player player) {
this.player = player;
}
public UUID getUUID() {
return player.getUniqueId();
}
public void sendMessage(String message) {
player.sendMessage(message);
}
public boolean isOp() {
return this.player.isOp();
}
public PlayerLocation getLoc() {
Location loc = this.player.getLocation();
return new PlayerLocation(loc.getWorld().getName(), loc.getX(), loc.getY(), loc.getZ());
}
public double getEyeHeight() {
return 0;
}
public void teleport(PlayerLocation location) {
this.player.teleport(new Location(Bukkit.getWorld(location.getWorldName()), location.getPosX(), location.getPosY(), location.getPosZ()));
}
public boolean hasPermission(String permission) {
return this.player.hasPermission(permission);
}
public WorldContainer getWorld() {
return new SpigotWorldContainer(this.player.getWorld());
}
/**
* @param blockPos
* @param material
*/
public void sendFakeBlock(PortalLocation blockPos, String material) {
}
/**
* Only 1.12 and below supported
* @param blockPos
* @param material
* @param data
*/
public void sendFakeBlockWithData(PortalLocation blockPos, String material, byte data) {
}
public void giveWool(String dyeColor, String itemName, String... itemDescription) {
ItemStack regionselector = new Wool(DyeColor.valueOf(dyeColor)).toItemStack(1);
ItemMeta selectorname = regionselector.getItemMeta();
selectorname.setDisplayName(itemName);
selectorname.setLore(Arrays.asList(itemDescription));
regionselector.setItemMeta(selectorname);
this.player.getInventory().addItem(regionselector);
}
public void giveItem(String material, String itemName, String... itemDescription) {
ItemStack regionselector = new ItemStack(Material.getMaterial(material));
ItemMeta selectorname = regionselector.getItemMeta();
selectorname.setDisplayName(itemName);
selectorname.setLore(Arrays.asList(itemDescription));
regionselector.setItemMeta(selectorname);
this.player.getInventory().addItem(regionselector);
}
}

View File

@ -1,39 +0,0 @@
package com.sekwah.advancedportals.spigot.coreconnector.container;
import com.sekwah.advancedportals.core.data.PortalLocation;
import com.sekwah.advancedportals.core.connector.container.WorldContainer;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.BlockFace;
import org.bukkit.material.Directional;
import org.bukkit.material.MaterialData;
public class SpigotWorldContainer implements WorldContainer {
private final World world;
public SpigotWorldContainer(World world) {
this.world = world;
}
public void setBlock(PortalLocation location, String material) {
this.world.getBlockAt(location.posX, location.posY, location.posZ).setType(Material.getMaterial(material));
}
public void setBlockData(PortalLocation location, byte data) {
MaterialData matData = world.getBlockAt(location.posX, location.posY, location.posZ).getState().getData();
if(matData instanceof Directional) {
Directional dir = (Directional) world.getBlockAt(location.posX, location.posY, location.posZ).getState().getData();
dir.setFacingDirection(BlockFace.NORTH);
}
}
public String getBlock(PortalLocation location) {
return this.world.getBlockAt(location.posX, location.posY, location.posZ).getType().toString();
}
public byte getBlockData(PortalLocation location) {
return 0;
}
}

View File

@ -1,28 +0,0 @@
package com.sekwah.advancedportals.spigot.coreconnector.info;
import com.sekwah.advancedportals.core.connector.info.DataCollector;
import org.bukkit.Material;
import java.util.ArrayList;
import java.util.List;
public class SpigotDataCollector implements DataCollector {
private final List<String> blockMaterialList = new ArrayList<>();
public SpigotDataCollector() {
for(Material material : Material.values()) {
this.blockMaterialList.add(material.name());
}
}
public boolean materialExists(String materialName) {
String sameCase = materialName.toUpperCase();
return Material.getMaterial(sameCase) != null;
}
@Override
public List<String> getMaterials() {
return blockMaterialList;
}
}

View File

@ -1,13 +0,0 @@
package com.sekwah.advancedportals.spigot.effect;
import com.sekwah.advancedportals.core.api.effect.WarpEffect;
import com.sekwah.advancedportals.core.api.portal.AdvancedPortal;
import com.sekwah.advancedportals.core.data.PortalLocation;
import com.sekwah.advancedportals.core.connector.container.PlayerContainer;
public class WarpEffectEnder extends WarpEffect {
@Override
protected void onWarp(PlayerContainer player, PortalLocation loc, Action action, Type type, AdvancedPortal portal) {
}
}

View File

@ -1,718 +0,0 @@
package com.sekwah.advancedportals.spigot.metrics;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import org.bukkit.Bukkit;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.RegisteredServiceProvider;
import org.bukkit.plugin.ServicePriority;
import javax.net.ssl.HttpsURLConnection;
import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.concurrent.Callable;
import java.util.logging.Level;
import java.util.zip.GZIPOutputStream;
/**
* bStats collects some data for plugin authors.
* <p>
* Check out https://bStats.org/ to learn more about bStats!
*/
@SuppressWarnings({"WeakerAccess", "unused"})
public class Metrics {
static {
// You can use the property to disable the check in your test environment
if (System.getProperty("bstats.relocatecheck") == null || !System.getProperty("bstats.relocatecheck").equals("false")) {
// Maven's Relocate is clever and changes strings, too. So we have to use this little "trick" ... :D
final String defaultPackage = new String(
new byte[]{'o', 'r', 'g', '.', 'b', 's', 't', 'a', 't', 's', '.', 'b', 'u', 'k', 'k', 'i', 't'});
final String examplePackage = new String(new byte[]{'y', 'o', 'u', 'r', '.', 'p', 'a', 'c', 'k', 'a', 'g', 'e'});
// We want to make sure nobody just copy & pastes the example and use the wrong package names
if (Metrics.class.getPackage().getName().equals(defaultPackage) || Metrics.class.getPackage().getName().equals(examplePackage)) {
throw new IllegalStateException("bStats Metrics class has not been relocated correctly!");
}
}
}
// The version of this bStats class
public static final int B_STATS_VERSION = 1;
// The url to which the data is sent
private static final String URL = "https://bStats.org/submitData/bukkit";
// Is bStats enabled on this server?
private boolean enabled;
// Should failed requests be logged?
private static boolean logFailedRequests;
// Should the sent data be logged?
private static boolean logSentData;
// Should the response text be logged?
private static boolean logResponseStatusText;
// The uuid of the server
private static String serverUUID;
// The plugin
private final Plugin plugin;
// A list with all custom charts
private final List<CustomChart> charts = new ArrayList<>();
/**
* Class constructor.
*
* @param plugin The plugin which stats should be submitted.
*/
public Metrics(Plugin plugin) {
if (plugin == null) {
throw new IllegalArgumentException("Plugin cannot be null!");
}
this.plugin = plugin;
// Get the config file
File bStatsFolder = new File(plugin.getDataFolder().getParentFile(), "bStats");
File configFile = new File(bStatsFolder, "config.yml");
YamlConfiguration config = YamlConfiguration.loadConfiguration(configFile);
// Check if the config file exists
if (!config.isSet("serverUuid")) {
// Add default values
config.addDefault("enabled", true);
// Every server gets it's unique random id.
config.addDefault("serverUuid", UUID.randomUUID().toString());
// Should failed request be logged?
config.addDefault("logFailedRequests", false);
// Should the sent data be logged?
config.addDefault("logSentData", false);
// Should the response text be logged?
config.addDefault("logResponseStatusText", false);
// Inform the server owners about bStats
config.options().header(
"bStats collects some data for plugin authors like how many servers are using their plugins.\n" +
"To honor their work, you should not disable it.\n" +
"This has nearly no effect on the server performance!\n" +
"Check out https://bStats.org/ to learn more :)"
).copyDefaults(true);
try {
config.save(configFile);
} catch (IOException ignored) { }
}
// Load the data
enabled = config.getBoolean("enabled", true);
serverUUID = config.getString("serverUuid");
logFailedRequests = config.getBoolean("logFailedRequests", false);
logSentData = config.getBoolean("logSentData", false);
logResponseStatusText = config.getBoolean("logResponseStatusText", false);
if (enabled) {
boolean found = false;
// Search for all other bStats Metrics classes to see if we are the first one
for (Class<?> service : Bukkit.getServicesManager().getKnownServices()) {
try {
service.getField("B_STATS_VERSION"); // Our identifier :)
found = true; // We aren't the first
break;
} catch (NoSuchFieldException ignored) { }
}
// Register our service
Bukkit.getServicesManager().register(Metrics.class, this, plugin, ServicePriority.Normal);
if (!found) {
// We are the first!
startSubmitting();
}
}
}
/**
* Checks if bStats is enabled.
*
* @return Whether bStats is enabled or not.
*/
public boolean isEnabled() {
return enabled;
}
/**
* Adds a custom chart.
*
* @param chart The chart to add.
*/
public void addCustomChart(CustomChart chart) {
if (chart == null) {
throw new IllegalArgumentException("Chart cannot be null!");
}
charts.add(chart);
}
/**
* Starts the Scheduler which submits our data every 30 minutes.
*/
private void startSubmitting() {
final Timer timer = new Timer(true); // We use a timer cause the Bukkit scheduler is affected by server lags
timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
if (!plugin.isEnabled()) { // Plugin was disabled
timer.cancel();
return;
}
// Nevertheless we want our code to run in the Bukkit main thread, so we have to use the Bukkit scheduler
// Don't be afraid! The connection to the bStats server is still async, only the stats collection is sync ;)
Bukkit.getScheduler().runTask(plugin, () -> submitData());
}
}, 1000 * 60 * 5, 1000 * 60 * 30);
// Submit the data every 30 minutes, first time after 5 minutes to give other plugins enough time to start
// WARNING: Changing the frequency has no effect but your plugin WILL be blocked/deleted!
// WARNING: Just don't do it!
}
/**
* Gets the plugin specific data.
* This method is called using Reflection.
*
* @return The plugin specific data.
*/
public JsonObject getPluginData() {
JsonObject data = new JsonObject();
String pluginName = plugin.getDescription().getName();
String pluginVersion = plugin.getDescription().getVersion();
data.addProperty("pluginName", pluginName); // Append the name of the plugin
data.addProperty("pluginVersion", pluginVersion); // Append the version of the plugin
JsonArray customCharts = new JsonArray();
for (CustomChart customChart : charts) {
// Add the data of the custom charts
JsonObject chart = customChart.getRequestJsonObject();
if (chart == null) { // If the chart is null, we skip it
continue;
}
customCharts.add(chart);
}
data.add("customCharts", customCharts);
return data;
}
/**
* Gets the server specific data.
*
* @return The server specific data.
*/
private JsonObject getServerData() {
// Minecraft specific data
int playerAmount;
try {
// Around MC 1.8 the return type was changed to a collection from an array,
// This fixes java.lang.NoSuchMethodError: org.bukkit.Bukkit.getOnlinePlayers()Ljava/util/Collection;
Method onlinePlayersMethod = Class.forName("org.bukkit.Server").getMethod("getOnlinePlayers");
playerAmount = onlinePlayersMethod.getReturnType().equals(Collection.class)
? ((Collection<?>) onlinePlayersMethod.invoke(Bukkit.getServer())).size()
: ((Player[]) onlinePlayersMethod.invoke(Bukkit.getServer())).length;
} catch (Exception e) {
playerAmount = Bukkit.getOnlinePlayers().size(); // Just use the new method if the Reflection failed
}
int onlineMode = Bukkit.getOnlineMode() ? 1 : 0;
String bukkitVersion = Bukkit.getVersion();
String bukkitName = Bukkit.getName();
// OS/Java specific data
String javaVersion = System.getProperty("java.version");
String osName = System.getProperty("os.name");
String osArch = System.getProperty("os.arch");
String osVersion = System.getProperty("os.version");
int coreCount = Runtime.getRuntime().availableProcessors();
JsonObject data = new JsonObject();
data.addProperty("serverUUID", serverUUID);
data.addProperty("playerAmount", playerAmount);
data.addProperty("onlineMode", onlineMode);
data.addProperty("bukkitVersion", bukkitVersion);
data.addProperty("bukkitName", bukkitName);
data.addProperty("javaVersion", javaVersion);
data.addProperty("osName", osName);
data.addProperty("osArch", osArch);
data.addProperty("osVersion", osVersion);
data.addProperty("coreCount", coreCount);
return data;
}
/**
* Collects the data and sends it afterwards.
*/
private void submitData() {
final JsonObject data = getServerData();
JsonArray pluginData = new JsonArray();
// Search for all other bStats Metrics classes to get their plugin data
for (Class<?> service : Bukkit.getServicesManager().getKnownServices()) {
try {
service.getField("B_STATS_VERSION"); // Our identifier :)
for (RegisteredServiceProvider<?> provider : Bukkit.getServicesManager().getRegistrations(service)) {
try {
Object plugin = provider.getService().getMethod("getPluginData").invoke(provider.getProvider());
if (plugin instanceof JsonObject) {
pluginData.add((JsonObject) plugin);
} else { // old bstats version compatibility
try {
Class<?> jsonObjectJsonSimple = Class.forName("org.json.simple.JSONObject");
if (plugin.getClass().isAssignableFrom(jsonObjectJsonSimple)) {
Method jsonStringGetter = jsonObjectJsonSimple.getDeclaredMethod("toJSONString");
jsonStringGetter.setAccessible(true);
String jsonString = (String) jsonStringGetter.invoke(plugin);
JsonObject object = new JsonParser().parse(jsonString).getAsJsonObject();
pluginData.add(object);
}
} catch (ClassNotFoundException e) {
// minecraft version 1.14+
if (logFailedRequests) {
this.plugin.getLogger().log(Level.SEVERE, "Encountered unexpected exception", e);
}
continue; // continue looping since we cannot do any other thing.
}
}
} catch (NullPointerException | NoSuchMethodException | IllegalAccessException | InvocationTargetException ignored) { }
}
} catch (NoSuchFieldException ignored) { }
}
data.add("plugins", pluginData);
// Create a new thread for the connection to the bStats server
new Thread(new Runnable() {
@Override
public void run() {
try {
// Send the data
sendData(plugin, data);
} catch (Exception e) {
// Something went wrong! :(
if (logFailedRequests) {
plugin.getLogger().log(Level.WARNING, "Could not submit plugin stats of " + plugin.getName(), e);
}
}
}
}).start();
}
/**
* Sends the data to the bStats server.
*
* @param plugin Any plugin. It's just used to get a logger instance.
* @param data The data to send.
* @throws Exception If the request failed.
*/
private static void sendData(Plugin plugin, JsonObject data) throws Exception {
if (data == null) {
throw new IllegalArgumentException("Data cannot be null!");
}
if (Bukkit.isPrimaryThread()) {
throw new IllegalAccessException("This method must not be called from the main thread!");
}
if (logSentData) {
plugin.getLogger().info("Sending data to bStats: " + data.toString());
}
HttpsURLConnection connection = (HttpsURLConnection) new URL(URL).openConnection();
// Compress the data to save bandwidth
byte[] compressedData = compress(data.toString());
// Add headers
connection.setRequestMethod("POST");
connection.addRequestProperty("Accept", "application/json");
connection.addRequestProperty("Connection", "close");
connection.addRequestProperty("Content-Encoding", "gzip"); // We gzip our request
connection.addRequestProperty("Content-Length", String.valueOf(compressedData.length));
connection.setRequestProperty("Content-Type", "application/json"); // We send our data in JSON format
connection.setRequestProperty("User-Agent", "MC-Server/" + B_STATS_VERSION);
// Send data
connection.setDoOutput(true);
DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream());
outputStream.write(compressedData);
outputStream.flush();
outputStream.close();
InputStream inputStream = connection.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
StringBuilder builder = new StringBuilder();
String line;
while ((line = bufferedReader.readLine()) != null) {
builder.append(line);
}
bufferedReader.close();
if (logResponseStatusText) {
plugin.getLogger().info("Sent data to bStats and received response: " + builder.toString());
}
}
/**
* Gzips the given String.
*
* @param str The string to gzip.
* @return The gzipped String.
* @throws IOException If the compression failed.
*/
private static byte[] compress(final String str) throws IOException {
if (str == null) {
return null;
}
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
GZIPOutputStream gzip = new GZIPOutputStream(outputStream);
gzip.write(str.getBytes(StandardCharsets.UTF_8));
gzip.close();
return outputStream.toByteArray();
}
/**
* Represents a custom chart.
*/
public static abstract class CustomChart {
// The id of the chart
final String chartId;
/**
* Class constructor.
*
* @param chartId The id of the chart.
*/
CustomChart(String chartId) {
if (chartId == null || chartId.isEmpty()) {
throw new IllegalArgumentException("ChartId cannot be null or empty!");
}
this.chartId = chartId;
}
private JsonObject getRequestJsonObject() {
JsonObject chart = new JsonObject();
chart.addProperty("chartId", chartId);
try {
JsonObject data = getChartData();
if (data == null) {
// If the data is null we don't send the chart.
return null;
}
chart.add("data", data);
} catch (Throwable t) {
if (logFailedRequests) {
Bukkit.getLogger().log(Level.WARNING, "Failed to get data for custom chart with id " + chartId, t);
}
return null;
}
return chart;
}
protected abstract JsonObject getChartData() throws Exception;
}
/**
* Represents a custom simple pie.
*/
public static class SimplePie extends CustomChart {
private final Callable<String> callable;
/**
* Class constructor.
*
* @param chartId The id of the chart.
* @param callable The callable which is used to request the chart data.
*/
public SimplePie(String chartId, Callable<String> callable) {
super(chartId);
this.callable = callable;
}
@Override
protected JsonObject getChartData() throws Exception {
JsonObject data = new JsonObject();
String value = callable.call();
if (value == null || value.isEmpty()) {
// Null = skip the chart
return null;
}
data.addProperty("value", value);
return data;
}
}
/**
* Represents a custom advanced pie.
*/
public static class AdvancedPie extends CustomChart {
private final Callable<Map<String, Integer>> callable;
/**
* Class constructor.
*
* @param chartId The id of the chart.
* @param callable The callable which is used to request the chart data.
*/
public AdvancedPie(String chartId, Callable<Map<String, Integer>> callable) {
super(chartId);
this.callable = callable;
}
@Override
protected JsonObject getChartData() throws Exception {
JsonObject data = new JsonObject();
JsonObject values = new JsonObject();
Map<String, Integer> map = callable.call();
if (map == null || map.isEmpty()) {
// Null = skip the chart
return null;
}
boolean allSkipped = true;
for (Map.Entry<String, Integer> entry : map.entrySet()) {
if (entry.getValue() == 0) {
continue; // Skip this invalid
}
allSkipped = false;
values.addProperty(entry.getKey(), entry.getValue());
}
if (allSkipped) {
// Null = skip the chart
return null;
}
data.add("values", values);
return data;
}
}
/**
* Represents a custom drilldown pie.
*/
public static class DrilldownPie extends CustomChart {
private final Callable<Map<String, Map<String, Integer>>> callable;
/**
* Class constructor.
*
* @param chartId The id of the chart.
* @param callable The callable which is used to request the chart data.
*/
public DrilldownPie(String chartId, Callable<Map<String, Map<String, Integer>>> callable) {
super(chartId);
this.callable = callable;
}
@Override
public JsonObject getChartData() throws Exception {
JsonObject data = new JsonObject();
JsonObject values = new JsonObject();
Map<String, Map<String, Integer>> map = callable.call();
if (map == null || map.isEmpty()) {
// Null = skip the chart
return null;
}
boolean reallyAllSkipped = true;
for (Map.Entry<String, Map<String, Integer>> entryValues : map.entrySet()) {
JsonObject value = new JsonObject();
boolean allSkipped = true;
for (Map.Entry<String, Integer> valueEntry : map.get(entryValues.getKey()).entrySet()) {
value.addProperty(valueEntry.getKey(), valueEntry.getValue());
allSkipped = false;
}
if (!allSkipped) {
reallyAllSkipped = false;
values.add(entryValues.getKey(), value);
}
}
if (reallyAllSkipped) {
// Null = skip the chart
return null;
}
data.add("values", values);
return data;
}
}
/**
* Represents a custom single line chart.
*/
public static class SingleLineChart extends CustomChart {
private final Callable<Integer> callable;
/**
* Class constructor.
*
* @param chartId The id of the chart.
* @param callable The callable which is used to request the chart data.
*/
public SingleLineChart(String chartId, Callable<Integer> callable) {
super(chartId);
this.callable = callable;
}
@Override
protected JsonObject getChartData() throws Exception {
JsonObject data = new JsonObject();
int value = callable.call();
if (value == 0) {
// Null = skip the chart
return null;
}
data.addProperty("value", value);
return data;
}
}
/**
* Represents a custom multi line chart.
*/
public static class MultiLineChart extends CustomChart {
private final Callable<Map<String, Integer>> callable;
/**
* Class constructor.
*
* @param chartId The id of the chart.
* @param callable The callable which is used to request the chart data.
*/
public MultiLineChart(String chartId, Callable<Map<String, Integer>> callable) {
super(chartId);
this.callable = callable;
}
@Override
protected JsonObject getChartData() throws Exception {
JsonObject data = new JsonObject();
JsonObject values = new JsonObject();
Map<String, Integer> map = callable.call();
if (map == null || map.isEmpty()) {
// Null = skip the chart
return null;
}
boolean allSkipped = true;
for (Map.Entry<String, Integer> entry : map.entrySet()) {
if (entry.getValue() == 0) {
continue; // Skip this invalid
}
allSkipped = false;
values.addProperty(entry.getKey(), entry.getValue());
}
if (allSkipped) {
// Null = skip the chart
return null;
}
data.add("values", values);
return data;
}
}
/**
* Represents a custom simple bar chart.
*/
public static class SimpleBarChart extends CustomChart {
private final Callable<Map<String, Integer>> callable;
/**
* Class constructor.
*
* @param chartId The id of the chart.
* @param callable The callable which is used to request the chart data.
*/
public SimpleBarChart(String chartId, Callable<Map<String, Integer>> callable) {
super(chartId);
this.callable = callable;
}
@Override
protected JsonObject getChartData() throws Exception {
JsonObject data = new JsonObject();
JsonObject values = new JsonObject();
Map<String, Integer> map = callable.call();
if (map == null || map.isEmpty()) {
// Null = skip the chart
return null;
}
for (Map.Entry<String, Integer> entry : map.entrySet()) {
JsonArray categoryValues = new JsonArray();
categoryValues.add(entry.getValue());
values.add(entry.getKey(), categoryValues);
}
data.add("values", values);
return data;
}
}
/**
* Represents a custom advanced bar chart.
*/
public static class AdvancedBarChart extends CustomChart {
private final Callable<Map<String, int[]>> callable;
/**
* Class constructor.
*
* @param chartId The id of the chart.
* @param callable The callable which is used to request the chart data.
*/
public AdvancedBarChart(String chartId, Callable<Map<String, int[]>> callable) {
super(chartId);
this.callable = callable;
}
@Override
protected JsonObject getChartData() throws Exception {
JsonObject data = new JsonObject();
JsonObject values = new JsonObject();
Map<String, int[]> map = callable.call();
if (map == null || map.isEmpty()) {
// Null = skip the chart
return null;
}
boolean allSkipped = true;
for (Map.Entry<String, int[]> entry : map.entrySet()) {
if (entry.getValue().length == 0) {
continue; // Skip this invalid
}
allSkipped = false;
JsonArray categoryValues = new JsonArray();
for (int categoryValue : entry.getValue()) {
categoryValues.add(categoryValue);
}
values.add(entry.getKey(), categoryValues);
}
if (allSkipped) {
// Null = skip the chart
return null;
}
data.add("values", values);
return data;
}
}
}