Merge branch 'core-dev' into spigot-dev

This commit is contained in:
Sekwah 2018-06-04 03:43:55 +01:00
commit 1d8d331bce
69 changed files with 1618 additions and 433 deletions

4
.gitignore vendored
View File

@ -1,6 +1,6 @@
*.class
.*
/target/
/build/
# Package Files #
*.jar
@ -8,3 +8,5 @@
*.ear
*.iml
*.iws
*.ipr

25
build.gradle Normal file
View File

@ -0,0 +1,25 @@
apply plugin: 'java'
apply plugin: 'maven'
apply plugin: 'idea'
apply plugin: 'eclipse'
group = 'com.sekwah.advancedportals'
version = '1.0.0'
description = ""
sourceCompatibility = 1.8
targetCompatibility = 1.8
tasks.withType(JavaCompile) {
options.encoding = 'UTF-8'
}
repositories {
maven { url "http://repo.maven.apache.org/maven2" }
}
dependencies {
compile group: 'com.google.code.gson', name: 'gson', version:'2.8.2'
compile group: 'com.google.inject', name: 'guice', version:'4.0'
}

39
pom.xml
View File

@ -1,39 +0,0 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.sekwah.advancedportals</groupId>
<artifactId>Advanced-Portals-Spigot</artifactId>
<build>
<sourceDirectory>${basedir}/src/</sourceDirectory>
<resources>
<resource>
<directory>${basedir}/Resources</directory>
</resource>
</resources>
</build>
<repositories>
<repository>
<id>spigot-repo</id>
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
</repository>
</repositories>
<version>1.0.0-snapshot</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
</properties>
<dependencies>
<!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.2</version>
</dependency>
<dependency>
<groupId>org.bukkit</groupId>
<artifactId>bukkit</artifactId>
<version>1.12.1-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

View File

@ -1,252 +0,0 @@
package com.sekwah.advancedportals.core.api.managers;
import com.google.gson.reflect.TypeToken;
import com.sekwah.advancedportals.core.AdvancedPortalsCore;
import com.sekwah.advancedportals.core.api.portal.AdvancedPortal;
import com.sekwah.advancedportals.core.api.portal.DataTag;
import com.sekwah.advancedportals.core.api.portal.PortalException;
import com.sekwah.advancedportals.core.api.warphandler.TagHandler;
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.coreconnector.container.PlayerContainer;
import java.lang.reflect.Type;
import java.util.*;
/**
* When a player leaves the server any data stored on them is removed to free memory.
*
* @author sekwah41
*/
public class PortalManager {
private final AdvancedPortalsCore portalsCore;
/**
* Store data of when the player last entered the portal
*/
private HashMap<String, Long> lastAttempt = new HashMap();
/**
* Tracks the name of portal a player has selected
*/
private HashMap<String, String> selectedPortal = new HashMap();
private HashMap<String, PortalLocation> portalSelectorLeftClick = new HashMap();
private HashMap<String, PortalLocation> portalSelectorRightClick = new HashMap();
/**
* Contains all the data for the portals
*/
private HashMap<String, AdvancedPortal> portalHashMap;
private AdvancedPortal[] portals;
public PortalManager(AdvancedPortalsCore portalsCore) {
this.portalsCore = portalsCore;
}
/**
* A player has left the server
*
* @param player
*/
public void playerLeave(PlayerContainer player) {
this.lastAttempt.remove(player.getUUID().toString());
this.selectedPortal.remove(player.getUUID().toString());
this.portalSelectorLeftClick.remove(player.getUUID().toString());
this.portalSelectorRightClick.remove(player.getUUID().toString());
}
/**
* Load the default data into the portals.
*/
public void loadPortals() {
Type type = new TypeToken<HashMap<String, AdvancedPortal>>() {
}.getType();
this.portalHashMap = this.portalsCore.getDataStorage().loadJson(type, "portals.json");
this.savePortals();
this.updatePortalArray();
}
public void savePortals() {
if (this.portalHashMap == null) {
this.portalHashMap = new HashMap<>();
}
this.portalsCore.getDataStorage().storeJson(this.portalHashMap, "portals.json");
}
public void activateCooldown(PlayerContainer player) {
this.lastAttempt.put(player.getUUID().toString(), System.currentTimeMillis());
}
public void playerSelectorActivate(PlayerContainer player, PortalLocation blockLoc, boolean leftClick) {
int side = leftClick ? 1 : 2;
if(leftClick) {
this.portalSelectorLeftClick.put(player.getUUID().toString(), blockLoc);
}
else {
this.portalSelectorRightClick.put(player.getUUID().toString(), blockLoc);
}
player.sendMessage(Lang.translateInsertVariablesColor("portal.selector.poschange", side, blockLoc.posX,
blockLoc.posY, blockLoc.posZ));
}
public boolean playerMove(PlayerContainer player, PlayerLocation fromLoc, PlayerLocation toLoc) {
return false;
}
public AdvancedPortal createPortal(String name, PlayerContainer player, ArrayList<DataTag> tags) throws PortalException {
if (this.portalSelectorLeftClick.containsKey(player.getUUID().toString())
&& this.portalSelectorRightClick.containsKey(player.getUUID().toString())) {
return this.createPortal(name, player, this.portalSelectorLeftClick.get(player.getUUID().toString()),
this.portalSelectorRightClick.get(player.getUUID().toString()), tags);
} else {
throw new PortalException("portal.error.invalidselection");
}
}
/**
*
* @param loc1
* @param loc2
* @param tags
* @return
* @throws PortalException
*/
public void createPortal(String name, PortalLocation loc1, PortalLocation loc2, ArrayList<DataTag> tags) throws PortalException {
createPortal(name, null, loc1, loc2, tags);
}
/**
* Maybe add detection for overlapping however thats not a major issue for now and portals may overlap inside
* solid blocks
*
* @param player null if no player
* @param loc1
* @param loc2
* @param tags
* @throws PortalException
*/
public AdvancedPortal createPortal(String name, PlayerContainer player, PortalLocation loc1, PortalLocation loc2, ArrayList<DataTag> tags) throws PortalException {
int maxX = Math.max(loc1.posX, loc2.posX);
int maxY = Math.max(loc1.posY, loc2.posY);
int maxZ = Math.max(loc1.posZ, loc2.posZ);
int minX = Math.min(loc1.posX, loc2.posX);
int minY = Math.min(loc1.posY, loc2.posY);
int minZ = Math.min(loc1.posZ, loc2.posZ);
if(!loc1.worldName.equalsIgnoreCase(loc2.worldName)) {
throw new PortalException("portal.error.selection.differentworlds");
}
PortalLocation maxLoc = new PortalLocation(loc1.worldName, maxX, maxY, maxZ);
PortalLocation minLoc = new PortalLocation(loc1.worldName, minX, minY, minZ);
if(name == null || name.equals("")) {
throw new PortalException("portal.error.noname");
}
else if(this.portalHashMap.containsKey(name)) {
throw new PortalException("portal.error.takenname");
}
AdvancedPortal portal = new AdvancedPortal(maxLoc, minLoc);
for(DataTag portalTag : tags) {
if(portalTag.NAME.equalsIgnoreCase("triggerblock")) {
ArrayList<String> triggers = new ArrayList<>();
for(String trigger : portalTag.VALUE.split(",")) {
if(AdvancedPortalsCore.getDataCollector().materialExists(trigger)) {
triggers.add(trigger.toLowerCase());
}
}
if(triggers.size() != 0) {
portal.setTriggerBlocks(triggers.toArray(new String[0]));
}
}
else {
portal.setArg(portalTag);
}
}
for(DataTag portalTag : tags) {
TagHandler.Creation<AdvancedPortal> creation = AdvancedPortalsCore.getPortalTagRegistry().getCreationHandler(portalTag.NAME);
if(creation != null) {
creation.created(portal, player, portalTag.VALUE);
}
}
this.portalHashMap.put(name, portal);
this.updatePortalArray();
AdvancedPortalsCore.getPortalManager().savePortals();
return portal;
}
private void updatePortalArray() {
Collection<AdvancedPortal> portalValues = this.portalHashMap.values();
this.portals = portalValues.toArray(new AdvancedPortal[0]);
}
public void removePlayerSelection(PlayerContainer player) throws PortalException {
String portal = this.selectedPortal.get(player.getUUID().toString());
if(portal != null) {
try {
this.removePortal(portal, player);
}
catch(PortalException e) {
if(e.getMessage().equals("command.remove.noname")) {
this.selectedPortal.remove(player.getUUID().toString());
throw new PortalException("command.remove.invalidselection");
}
else {
throw e;
}
}
}
throw new PortalException("command.remove.noselection");
}
/**
* @param portalName name of portal
* @param player null if a player didnt send it
* @throws PortalException
*/
public void removePortal(String portalName, PlayerContainer player) throws PortalException {
AdvancedPortal portal = this.getPortal(portalName);
if(portal == null) {
throw new PortalException("command.remove.noname");
}
for(DataTag portalTag : portal.getArgs()) {
TagHandler.Creation<AdvancedPortal> creation = AdvancedPortalsCore.getPortalTagRegistry().getCreationHandler(portalTag.NAME);
if(creation != null) {
creation.destroyed(portal, player, portalTag.VALUE);
}
}
this.portalHashMap.remove(portalName);
AdvancedPortalsCore.getPortalManager().savePortals();
}
private AdvancedPortal getPortal(String portalName) {
return this.portalHashMap.get(portalName);
}
/**
* Get an array of portals without a reference to the main array
* @return
*/
public Set<Map.Entry<String, AdvancedPortal>> getPortals() {
return this.portalHashMap.entrySet();
}
public boolean inPortalRegion(PlayerLocation loc) {
return this.inPortalRegion(loc, 0);
}
private boolean inPortalRegion(PlayerLocation loc, int additionalArea) {
return true;
}
}

View File

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

View File

@ -1,17 +1,23 @@
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.managers.DestinationManager;
import com.sekwah.advancedportals.core.api.managers.PortalManager;
import com.sekwah.advancedportals.core.api.services.DestinationServices;
import com.sekwah.advancedportals.core.api.services.PortalServices;
import com.sekwah.advancedportals.core.api.services.PortalTempDataServices;
import com.sekwah.advancedportals.core.config.RepositoryModule;
import com.sekwah.advancedportals.core.repository.ConfigRepository;
import com.sekwah.advancedportals.core.repository.DestinationRepositoryImpl;
import com.sekwah.advancedportals.core.repository.PortalRepositoryImpl;
import com.sekwah.advancedportals.core.api.portal.AdvancedPortal;
import com.sekwah.advancedportals.core.api.registry.TagRegistry;
import com.sekwah.advancedportals.core.api.registry.WarpEffectRegistry;
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.util.Config;
import com.sekwah.advancedportals.core.util.DataStorage;
import com.sekwah.advancedportals.core.data.DataStorage;
import com.sekwah.advancedportals.core.util.InfoLogger;
import com.sekwah.advancedportals.core.util.Lang;
import com.sekwah.advancedportals.coreconnector.ConnectorDataCollector;
@ -30,15 +36,17 @@ public class AdvancedPortalsCore {
private TagRegistry<AdvancedPortal> portalTagRegistry;
private TagRegistry<Destination> destiTagRegistry;
private CoreListeners coreListeners;
private Injector injector = Guice.createInjector(new RepositoryModule(this));
private Config config;
private CoreListeners coreListeners = injector.getInstance(CoreListeners.class);
private CommandWithSubCommands portalCommand;
private CommandWithSubCommands destiCommand;
private PortalManager portalManager;
private DestinationManager destiManager;
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";
@ -53,7 +61,7 @@ public class AdvancedPortalsCore {
ConnectorDataCollector dataCollector, int[] mcVer) {
this.dataStorage = dataStorage;
this.infoLogger = infoLogger;
this.instance = this;
instance = this;
this.commandRegister = commandRegister;
this.dataCollector = dataCollector;
this.mcMinorVer = this.checkMcVer(mcVer);
@ -98,13 +106,10 @@ public class AdvancedPortalsCore {
public static String getTranslationName() {
return instance.config.getTranslation();
return instance.configRepository.getTranslation();
}
private void onEnable() {
this.coreListeners = new CoreListeners(this);
this.portalManager = new PortalManager(this);
this.destiManager = new DestinationManager(this);
this.warpEffectRegistry = new WarpEffectRegistry();
this.portalTagRegistry = new TagRegistry<>();
this.destiTagRegistry = new TagRegistry<>();
@ -112,14 +117,14 @@ public class AdvancedPortalsCore {
this.dataStorage.copyDefaultFile("lang/en_GB.lang", false);
this.loadPortalConfig();
Lang.loadLanguage(config.getTranslation());
Lang.loadLanguage(configRepository.getTranslation());
this.registerPortalCommand();
this.registerDestinationCommand();
this.portalManager.loadPortals();
this.portalServices.loadPortals(this);
this.destiManager.loadDestinations();
this.destiServices.loadDestinations(this);
this.infoLogger.log(Lang.translate("logger.pluginenable"));
}
@ -161,8 +166,8 @@ public class AdvancedPortalsCore {
* (basically if values are missing or whatever)
*/
public void loadPortalConfig() {
this.config = this.dataStorage.loadJson(Config.class, "config.json");
this.dataStorage.storeJson(this.config, "config.json");
this.configRepository.loadConfig(this.dataStorage);
this.dataStorage.storeJson(this.configRepository, "config.json");
}
/**
@ -176,8 +181,8 @@ public class AdvancedPortalsCore {
return instance;
}
public Config getConfig() {
return this.config;
public ConfigRepository getConfigRepo() {
return this.configRepository;
}
public DataStorage getDataStorage() {
@ -196,12 +201,16 @@ public class AdvancedPortalsCore {
return instance.coreListeners;
}
public static PortalManager getPortalManager() {
return instance.portalManager;
public static PortalServices getPortalServices() {
return instance.portalServices;
}
public static DestinationManager getDestinationManager() {
return instance.destiManager;
public static DestinationServices getDestinationServices() {
return instance.destiServices;
}
public static PortalTempDataServices getPortalTempDataServices() {
return instance.portalTempDataServices;
}
public static TagRegistry<AdvancedPortal> getPortalTagRegistry() {

View File

@ -1,21 +1,30 @@
package com.sekwah.advancedportals.core;
import com.sekwah.advancedportals.core.data.PlayerLocation;
import com.sekwah.advancedportals.core.data.PortalLocation;
import com.google.inject.name.Named;
import com.sekwah.advancedportals.core.api.services.PortalServices;
import com.sekwah.advancedportals.core.api.services.PortalTempDataServices;
import com.sekwah.advancedportals.core.entities.PlayerLocation;
import com.sekwah.advancedportals.core.entities.PortalLocation;
import com.sekwah.advancedportals.core.repository.PortalRepository;
import com.sekwah.advancedportals.core.repository.PortalTempDataRepository;
import com.sekwah.advancedportals.core.util.Lang;
import com.sekwah.advancedportals.coreconnector.container.PlayerContainer;
import com.sekwah.advancedportals.coreconnector.container.WorldContainer;
import javax.inject.Inject;
public class CoreListeners {
private final AdvancedPortalsCore portalsCore;
private PortalTempDataServices portalTempDataServices;
public CoreListeners(AdvancedPortalsCore portalsCore) {
this.portalsCore = portalsCore;
}
private PortalServices portalServices;
@Inject
@Named("portals-core")
private AdvancedPortalsCore portalsCore;
public void playerJoin(PlayerContainer player) {
AdvancedPortalsCore.getPortalManager().activateCooldown(player);
this.portalTempDataServices.activateCooldown(player);
if(player.isOp()) {
if(!Lang.translate("translatedata.lastchange").equals(AdvancedPortalsCore.lastTranslationUpdate)) {
player.sendMessage(Lang.translateColor("messageprefix.negative")
@ -27,11 +36,11 @@ public class CoreListeners {
}
public void teleportEvent(PlayerContainer player) {
AdvancedPortalsCore.getPortalManager().activateCooldown(player);
this.portalTempDataServices.activateCooldown(player);
}
public void playerLeave(PlayerContainer player) {
AdvancedPortalsCore.getPortalManager().playerLeave(player);
this.portalTempDataServices.playerLeave(player);
}
/**
@ -39,7 +48,7 @@ public class CoreListeners {
* @return if the entity is allowed to spawn
*/
public boolean mobSpawn(PlayerLocation loc) {
return !AdvancedPortalsCore.getPortalManager().inPortalRegion(loc);
return !this.portalServices.inPortalRegion(loc);
}
/**
@ -49,7 +58,7 @@ public class CoreListeners {
* @return if the player is allowed to move
*/
public boolean playerMove(PlayerContainer player, PlayerLocation fromLoc, PlayerLocation toLoc) {
return AdvancedPortalsCore.getPortalManager().playerMove(player, fromLoc, toLoc);
return this.portalServices.playerMove(player, fromLoc, toLoc);
}
/**
@ -115,13 +124,13 @@ public class CoreListeners {
*/
public boolean playerInteractWithBlock(PlayerContainer player, String materialName, String itemName,
PortalLocation blockLoc, boolean leftClick) {
if((player.isOp() || player.hasPermission("advancedportals.createportal")) &&
materialName.equalsIgnoreCase(this.portalsCore.getConfig().getSelectorMaterial())
&& (!this.portalsCore.getConfig().getUseOnlySpecialAxe() || itemName.equals("\u00A7ePortal Region Selector"))) {
AdvancedPortalsCore.getPortalManager().playerSelectorActivate(player, blockLoc, 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(leftClick && itemName.equals("\u00A75Portal Block Placer") && player.hasPermission("advancedportals.build")) {
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);

View File

@ -2,12 +2,12 @@ package com.sekwah.advancedportals.core.api.destination;
import com.google.gson.annotations.SerializedName;
import com.sekwah.advancedportals.core.AdvancedPortalsCore;
import com.sekwah.advancedportals.core.api.portal.DataTag;
import com.sekwah.advancedportals.core.entities.DataTag;
import com.sekwah.advancedportals.core.api.portal.PortalException;
import com.sekwah.advancedportals.core.api.registry.TagRegistry;
import com.sekwah.advancedportals.core.api.warphandler.ActivationData;
import com.sekwah.advancedportals.core.api.warphandler.TagHandler;
import com.sekwah.advancedportals.core.data.PlayerLocation;
import com.sekwah.advancedportals.core.entities.PlayerLocation;
import com.sekwah.advancedportals.coreconnector.container.PlayerContainer;
import java.util.ArrayList;

View File

@ -1,7 +1,7 @@
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.entities.PortalLocation;
import com.sekwah.advancedportals.coreconnector.container.PlayerContainer;
/**

View File

@ -1,7 +1,7 @@
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.entities.PortalLocation;
import com.sekwah.advancedportals.coreconnector.container.PlayerContainer;
/**

View File

@ -5,7 +5,8 @@ import com.sekwah.advancedportals.core.AdvancedPortalsCore;
import com.sekwah.advancedportals.core.api.registry.TagRegistry;
import com.sekwah.advancedportals.core.api.warphandler.ActivationData;
import com.sekwah.advancedportals.core.api.warphandler.TagHandler;
import com.sekwah.advancedportals.core.data.PortalLocation;
import com.sekwah.advancedportals.core.entities.DataTag;
import com.sekwah.advancedportals.core.entities.PortalLocation;
import com.sekwah.advancedportals.coreconnector.container.PlayerContainer;
import java.util.ArrayList;

View File

@ -0,0 +1,33 @@
package com.sekwah.advancedportals.core.api.services;
import com.sekwah.advancedportals.core.AdvancedPortalsCore;
import com.sekwah.advancedportals.core.api.destination.Destination;
import com.sekwah.advancedportals.core.api.portal.PortalException;
import com.sekwah.advancedportals.core.entities.DataTag;
import com.sekwah.advancedportals.core.entities.PlayerLocation;
import com.sekwah.advancedportals.coreconnector.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 {@link com.sekwah.advancedportals.core.repository.DestinationRepository}
*/
public final class DestinationServices {
/**
* @param portalsCore
*/
public void loadDestinations(AdvancedPortalsCore portalsCore) {
}
/**
* @param name
* @param player
* @param loc
* @param destiTags
* @return
*/
public Destination createDesti(String name, PlayerContainer player, PlayerLocation loc, ArrayList<DataTag> destiTags) throws PortalException {
return null;
}
}

View File

@ -0,0 +1,45 @@
package com.sekwah.advancedportals.core.api.services;
import com.google.common.collect.ImmutableList;
import com.sekwah.advancedportals.core.AdvancedPortalsCore;
import com.sekwah.advancedportals.core.api.portal.AdvancedPortal;
import com.sekwah.advancedportals.core.api.portal.PortalException;
import com.sekwah.advancedportals.core.entities.DataTag;
import com.sekwah.advancedportals.core.entities.PlayerLocation;
import com.sekwah.advancedportals.coreconnector.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 com.sekwah.advancedportals.core.repository.PortalRepository}
*
* Excluding the temp data like selections
*/
public final class PortalServices {
public void loadPortals(AdvancedPortalsCore advancedPortalsCore) {
}
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 void removePortal(String name, PlayerContainer player) throws PortalException {
}
public AdvancedPortal createPortal(String name, PlayerContainer player, ArrayList<DataTag> portalTags) throws PortalException {
return null;
}
}

View File

@ -0,0 +1,24 @@
package com.sekwah.advancedportals.core.api.services;
import com.sekwah.advancedportals.core.api.portal.PortalException;
import com.sekwah.advancedportals.core.entities.PortalLocation;
import com.sekwah.advancedportals.coreconnector.container.PlayerContainer;
public final class PortalTempDataServices {
public void activateCooldown(PlayerContainer player) {
}
public void playerLeave(PlayerContainer player) {
}
public void playerSelectorActivate(PlayerContainer player, PortalLocation blockLoc, boolean leftClick) {
}
public void removePlayerSelection(PlayerContainer player) throws PortalException {
}
}

View File

@ -1,7 +1,7 @@
package com.sekwah.advancedportals.core.api.warphandler;
import com.sekwah.advancedportals.core.data.PlayerLocation;
import com.sekwah.advancedportals.core.entities.PlayerLocation;
/**
* Created by on 30/07/2016.

View File

@ -1,7 +1,6 @@
package com.sekwah.advancedportals.core.commands.subcommands;
import com.sekwah.advancedportals.core.AdvancedPortalsCore;
import com.sekwah.advancedportals.core.api.portal.DataTag;
import com.sekwah.advancedportals.core.entities.DataTag;
import java.util.ArrayList;

View File

@ -3,7 +3,7 @@ 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.api.portal.DataTag;
import com.sekwah.advancedportals.core.entities.DataTag;
import com.sekwah.advancedportals.core.api.portal.PortalException;
import com.sekwah.advancedportals.core.commands.subcommands.CreateSubCommand;
import com.sekwah.advancedportals.core.util.Lang;
@ -25,7 +25,7 @@ public class CreateDestiSubCommand extends CreateSubCommand implements SubComman
}
ArrayList<DataTag> destiTags = this.getTagsFromArgs(args);
try {
Destination desti = AdvancedPortalsCore.getDestinationManager().createDesti(args[1], player, player.getLoc(), destiTags);
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"));

View File

@ -3,7 +3,7 @@ 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.api.portal.DataTag;
import com.sekwah.advancedportals.core.entities.DataTag;
import com.sekwah.advancedportals.core.api.portal.PortalException;
import com.sekwah.advancedportals.core.commands.subcommands.CreateSubCommand;
import com.sekwah.advancedportals.core.util.Lang;
@ -27,7 +27,7 @@ public class CreatePortalSubCommand extends CreateSubCommand implements SubComma
ArrayList<DataTag> portalTags = this.getTagsFromArgs(args);
try {
System.out.println(Arrays.toString(portalTags.toArray()));
AdvancedPortal portal = AdvancedPortalsCore.getPortalManager().createPortal(args[1], player, portalTags);
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"));

View File

@ -18,8 +18,8 @@ public class ReloadSubCommand implements SubCommand {
@Override
public void onCommand(CommandSenderContainer sender, String[] args) {
portalsCore.loadPortalConfig();
portalsCore.getPortalManager().loadPortals();
portalsCore.getDestinationManager().loadDestinations();
portalsCore.getPortalServices().loadPortals(portalsCore);
portalsCore.getDestinationServices().loadDestinations(portalsCore);
sender.sendMessage(Lang.translateColor("messageprefix.positive") + Lang.translateColor("command.reload.reloaded"));
}

View File

@ -19,7 +19,7 @@ public class RemoveSubCommand implements SubCommand {
public void onCommand(CommandSenderContainer sender, String[] args) {
if(args.length > 1) {
try {
AdvancedPortalsCore.getPortalManager().removePortal(args[1], sender.getPlayerContainer());
AdvancedPortalsCore.getPortalServices().removePortal(args[1], sender.getPlayerContainer());
sender.sendMessage(Lang.translateColor("messageprefix.positive") + Lang.translateColor("command.remove.complete"));
} catch (PortalException portalTagExeption) {
sender.sendMessage(Lang.translateColor("messageprefix.negative")
@ -33,7 +33,7 @@ public class RemoveSubCommand implements SubCommand {
}
else {
try {
AdvancedPortalsCore.getPortalManager().removePlayerSelection(player);
AdvancedPortalsCore.getPortalTempDataServices().removePlayerSelection(player);
} catch (PortalException portalTagExeption) {
sender.sendMessage(Lang.translateColor("messageprefix.negative")
+ Lang.translateColor("command.remove.error") + " " + Lang.translate(portalTagExeption.getMessage()));
@ -50,7 +50,7 @@ public class RemoveSubCommand implements SubCommand {
@Override
public List<String> onTabComplete(CommandSenderContainer sender, String[] args) {
List<String> portalNames = new ArrayList<>();
for(Map.Entry<String, AdvancedPortal> portal : AdvancedPortalsCore.getPortalManager().getPortals()) {
for(Map.Entry<String, AdvancedPortal> portal : AdvancedPortalsCore.getPortalServices().getPortals()) {
portalNames.add(portal.getKey());
}
Collections.sort(portalNames);

View File

@ -23,7 +23,7 @@ public class SelectorSubCommand implements SubCommand {
sender.sendMessage(Lang.translateColor("messageprefix.negative") + Lang.translate("command.playeronly"));
}
else {
player.giveItem(this.portalsCore.getConfig().getSelectorMaterial(), "\u00A7ePortal Region Selector"
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"));
}

View File

@ -0,0 +1,34 @@
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

@ -0,0 +1,33 @@
package com.sekwah.advancedportals.core.config;
import com.google.inject.AbstractModule;
import com.google.inject.Provides;
import com.google.inject.Scopes;
import com.google.inject.name.Named;
import com.sekwah.advancedportals.core.AdvancedPortalsCore;
import com.sekwah.advancedportals.core.repository.*;
import java.util.Properties;
public class RepositoryModule extends AbstractModule {
private final AdvancedPortalsCore portalsCore;
public RepositoryModule(AdvancedPortalsCore portalsCore) {
this.portalsCore = portalsCore;
}
@Override
protected void configure() {
bind(PortalRepository.class).to(PortalRepositoryImpl.class).in(Scopes.SINGLETON);
bind(DestinationRepository.class).to(DestinationRepositoryImpl.class).in(Scopes.SINGLETON);
bind(PortalTempDataRepository.class).to(PortalTempDataRepositoryImpl.class).in(Scopes.SINGLETON);
bind(ConfigRepository.class).to(ConfigRepositoryImpl.class).in(Scopes.SINGLETON);
}
@Provides
@Named("portals-core")
AdvancedPortalsCore providePortalsCore() {
return this.portalsCore;
}
}

View File

@ -1,4 +1,4 @@
package com.sekwah.advancedportals.core.util;
package com.sekwah.advancedportals.core.data;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
@ -83,7 +83,7 @@ public class DataStorage {
}
if (!outFile.exists() || overwrite) {
try {
InputStream inputStream = DataStorage.class.getClassLoader().getResourceAsStream(fileLoc);
InputStream inputStream = DataStorage.class.getResourceAsStream(fileLoc);
if(inputStream == null) {
return false;
}

View File

@ -1,4 +1,4 @@
package com.sekwah.advancedportals.core.api.portal;
package com.sekwah.advancedportals.core.entities;
public class DataTag {

View File

@ -1,4 +1,4 @@
package com.sekwah.advancedportals.core.data;
package com.sekwah.advancedportals.core.entities;
import com.google.gson.annotations.SerializedName;

View File

@ -1,4 +1,4 @@
package com.sekwah.advancedportals.core.data;
package com.sekwah.advancedportals.core.entities;
import com.google.gson.annotations.SerializedName;

View File

@ -0,0 +1,6 @@
package com.sekwah.advancedportals.core.enums;
public enum EnumHandSelection {
LEFTHAND,
RIGHTHAND
}

View File

@ -0,0 +1,16 @@
package com.sekwah.advancedportals.core.repository;
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

@ -0,0 +1,34 @@
package com.sekwah.advancedportals.core.repository;
import com.sekwah.advancedportals.core.config.Config;
import com.sekwah.advancedportals.core.data.DataStorage;
import javax.inject.Singleton;
@Singleton
public class ConfigRepositoryImpl implements ConfigRepository {
private Config config;
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

@ -0,0 +1,14 @@
package com.sekwah.advancedportals.core.repository;
import com.google.common.collect.ImmutableMap;
import com.sekwah.advancedportals.core.api.destination.Destination;
public interface DestinationRepository {
void create(String name, Destination destination);
void delete(String name);
ImmutableMap<String, Destination> getDestinations();
void loadDestinations();
}

View File

@ -1,33 +1,46 @@
package com.sekwah.advancedportals.core.api.managers;
package com.sekwah.advancedportals.core.repository;
import com.google.common.collect.ImmutableMap;
import com.google.gson.reflect.TypeToken;
import com.google.inject.Singleton;
import com.sekwah.advancedportals.core.AdvancedPortalsCore;
import com.sekwah.advancedportals.core.api.destination.Destination;
import com.sekwah.advancedportals.core.api.portal.DataTag;
import com.sekwah.advancedportals.core.entities.DataTag;
import com.sekwah.advancedportals.core.api.portal.PortalException;
import com.sekwah.advancedportals.core.api.warphandler.TagHandler;
import com.sekwah.advancedportals.core.data.PlayerLocation;
import com.sekwah.advancedportals.core.entities.PlayerLocation;
import com.sekwah.advancedportals.coreconnector.container.PlayerContainer;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
/**
* @author sekwah41
*/
public class DestinationManager {
@Singleton
public class DestinationRepositoryImpl implements DestinationRepository {
private Map<String, Destination> destiHashMap = new HashMap<>();
private final AdvancedPortalsCore portalsCore;
/**
* Contains all the data for the destinations
*/
private HashMap<String, Destination> destiHashMap = new HashMap<>();
public DestinationManager(AdvancedPortalsCore portalsCore) {
this.portalsCore = portalsCore;
@Override
public void create(String name, Destination destination) {
destiHashMap.put(name, destination);
}
@Override
public void delete(String name) {
destiHashMap.remove(name);
}
@Override
public ImmutableMap<String, Destination> getDestinations() {
return ImmutableMap.copyOf(destiHashMap);
}
@Override
public void loadDestinations() {
}
public Destination createDesti(String name, PlayerContainer player, PlayerLocation playerLocation, ArrayList<DataTag> tags) throws PortalException {
if(name == null || name.equals("")) {
throw new PortalException("desti.error.noname");
@ -47,23 +60,25 @@ public class DestinationManager {
}
}
this.destiHashMap.put(name, desti);
AdvancedPortalsCore.getDestinationManager().saveDestinations();
this.saveDestinations(AdvancedPortalsCore.getInstance());
return desti;
}
public void loadDestinations() {
/**
* TODO change these, may be good if the data storage was an inject as well as it would save time and clean up layout
* @param portalsCore
*/
public void loadDestinations(AdvancedPortalsCore portalsCore) {
Type type = new TypeToken<HashMap<String, Destination>>() {
}.getType();
this.destiHashMap = this.portalsCore.getDataStorage().loadJson(type, "destinations.json");
this.saveDestinations();
this.destiHashMap = portalsCore.getDataStorage().loadJson(type, "destinations.json");
this.saveDestinations(portalsCore);
}
public void saveDestinations() {
public void saveDestinations(AdvancedPortalsCore portalsCore) {
if (this.destiHashMap == null) {
this.destiHashMap = new HashMap<>();
}
this.portalsCore.getDataStorage().storeJson(this.destiHashMap, "destinations.json");
portalsCore.getDataStorage().storeJson(this.destiHashMap, "destinations.json");
}
}

View File

@ -0,0 +1,13 @@
package com.sekwah.advancedportals.core.repository;
import com.sekwah.advancedportals.core.entities.PlayerLocation;
import com.sekwah.advancedportals.coreconnector.container.PlayerContainer;
public interface PortalRepository {
void loadPortals();
void savePortals();
boolean playerMove(PlayerContainer player, PlayerLocation fromLoc, PlayerLocation toLoc);
}

View File

@ -0,0 +1,23 @@
package com.sekwah.advancedportals.core.repository;
import com.google.inject.Singleton;
import com.sekwah.advancedportals.core.entities.PlayerLocation;
import com.sekwah.advancedportals.coreconnector.container.PlayerContainer;
@Singleton
public class PortalRepositoryImpl implements PortalRepository {
@Override
public void loadPortals() {
}
@Override
public void savePortals() {
}
@Override
public boolean playerMove(PlayerContainer player, PlayerLocation fromLoc, PlayerLocation toLoc) {
return false;
}
}

View File

@ -0,0 +1,26 @@
package com.sekwah.advancedportals.core.repository;
import com.sekwah.advancedportals.core.entities.PlayerLocation;
import com.sekwah.advancedportals.core.entities.PortalLocation;
import com.sekwah.advancedportals.core.enums.EnumHandSelection;
import com.sekwah.advancedportals.coreconnector.container.PlayerContainer;
import java.util.UUID;
public interface PortalTempDataRepository {
void addSelectedPortal(UUID selectedPlayer, String portal);
void removeSelectedPortal(UUID uuid);
void addSelectedHand(UUID uuid, EnumHandSelection enumHandSelection, PortalLocation portalLocation);
void removeSelectedHand(UUID uuid, EnumHandSelection enumHandSelection);
void removeAllSelectedHand(UUID uuid);
void activateCooldown(PlayerContainer player);
void playerLeave(PlayerContainer player);
boolean inPortalRegion(PlayerLocation loc);
}

View File

@ -0,0 +1,65 @@
package com.sekwah.advancedportals.core.repository;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.collect.HashBasedTable;
import com.google.common.collect.Table;
import com.google.inject.Singleton;
import com.sekwah.advancedportals.core.entities.PlayerLocation;
import com.sekwah.advancedportals.core.entities.PortalLocation;
import com.sekwah.advancedportals.core.enums.EnumHandSelection;
import com.sekwah.advancedportals.coreconnector.container.PlayerContainer;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
@Singleton
public class PortalTempDataRepositoryImpl implements PortalTempDataRepository {
Cache<UUID, String> selectedPortal = CacheBuilder.newBuilder()
.concurrencyLevel(4)
.expireAfterAccess(30, TimeUnit.DAYS)
.build();
Table<UUID, EnumHandSelection, PortalLocation> selectedHand = HashBasedTable.create();
@Override
public void addSelectedPortal(UUID selectedPlayer, String portal) {
selectedPortal.put(selectedPlayer, portal);
}
@Override
public void removeSelectedPortal(UUID uuid) {
selectedPortal.invalidate(uuid);
}
@Override
public void addSelectedHand(UUID uuid, EnumHandSelection enumHandSelection, PortalLocation portalLocation) {
selectedHand.put(uuid, enumHandSelection, portalLocation);
}
@Override
public void removeSelectedHand(UUID uuid, EnumHandSelection enumHandSelection) {
selectedHand.remove(uuid, enumHandSelection);
}
@Override
public void removeAllSelectedHand(UUID uuid) {
selectedHand.remove(uuid, EnumHandSelection.LEFTHAND);
selectedHand.remove(uuid, EnumHandSelection.RIGHTHAND);
}
@Override
public void activateCooldown(PlayerContainer player) {
}
@Override
public void playerLeave(PlayerContainer player) {
}
@Override
public boolean inPortalRegion(PlayerLocation loc) {
return false;
}
}

View File

@ -4,13 +4,13 @@ public abstract class InfoLogger {
/**
* Problematic messages
* @param s
* @param s warning message
*/
public abstract void logWarning(String s);
/**
* General information logging
* @param s
* @param s info message
*/
public abstract void log(String s);
}

View File

@ -0,0 +1,30 @@
package com.sekwah.advancedportals.coreconnector.command;
import com.sekwah.advancedportals.core.commands.CommandTemplate;
import com.sekwah.advancedportals.coreconnector.container.CommandSenderContainer;
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 CommandHandler implements CommandExecutor, TabCompleter {
private final CommandTemplate commandExecutor;
public CommandHandler(CommandTemplate commandExecutor) {
this.commandExecutor = commandExecutor;
}
@Override
public boolean onCommand(CommandSender commandSender, Command command, String s, String[] args) {
this.commandExecutor.onCommand(new CommandSenderContainer(commandSender), command.getName(), args);
return true;
}
@Override
public List<String> onTabComplete(CommandSender commandSender, Command command, String s, String[] args) {
return this.commandExecutor.onTabComplete(new CommandSenderContainer(commandSender), args);
}
}

View File

@ -1,7 +1,5 @@
package com.sekwah.advancedportals.coreconnector.container;
import com.sekwah.advancedportals.core.data.PlayerLocation;
import com.sekwah.advancedportals.core.data.PortalLocation;
import org.bukkit.Bukkit;
import org.bukkit.DyeColor;
import org.bukkit.Location;
@ -10,8 +8,10 @@ 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 com.sekwah.advancedportals.core.entities.PlayerLocation;
import com.sekwah.advancedportals.core.entities.PortalLocation;
import java.util.UUID;
/**

View File

@ -1,11 +1,11 @@
package com.sekwah.advancedportals.coreconnector.container;
import com.sekwah.advancedportals.core.data.PortalLocation;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.BlockFace;
import org.bukkit.material.Directional;
import org.bukkit.material.MaterialData;
import com.sekwah.advancedportals.core.entities.PortalLocation;
public class WorldContainer {

View File

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

View File

@ -0,0 +1,27 @@
package com.sekwah.advancedportals.spigot;
import com.sekwah.advancedportals.core.AdvancedPortalsCore;
import com.sekwah.advancedportals.core.data.DataStorage;
import com.sekwah.advancedportals.coreconnector.ConnectorDataCollector;
import com.sekwah.advancedportals.coreconnector.command.CommandRegister;
import org.bukkit.plugin.java.JavaPlugin;
public class AdvancedPortalsPlugin extends JavaPlugin {
private AdvancedPortalsCore portalsCore;
public void onEnable() {
// TODO actually get the minecraft version
this.portalsCore = new AdvancedPortalsCore(new DataStorage(this.getDataFolder()),
new SpigotInfoLogger(this), new CommandRegister(this), new ConnectorDataCollector(), new int[]{1,12,2});
this.getServer().getPluginManager().registerEvents(new Listeners(this), this);
}
public void onDisable() {
this.portalsCore.onDisable();
}
public AdvancedPortalsCore getPortalsCore() {
return portalsCore;
}
}

View File

@ -0,0 +1,52 @@
package com.sekwah.advancedportals.spigot;
import com.sekwah.advancedportals.core.CoreListeners;
import com.sekwah.advancedportals.core.entities.PortalLocation;
import com.sekwah.advancedportals.coreconnector.container.PlayerContainer;
import org.bukkit.Location;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerJoinEvent;
public class Listeners implements Listener {
private final AdvancedPortalsPlugin plugin;
private final CoreListeners coreListeners;
public Listeners(AdvancedPortalsPlugin plugin) {
this.plugin = plugin;
this.coreListeners = plugin.getPortalsCore().getCoreListeners();
}
@EventHandler
public void onJoinEvent(PlayerJoinEvent event) {
coreListeners.playerJoin(new PlayerContainer(event.getPlayer()));
}
@EventHandler(priority = EventPriority.HIGH)
public void onBlockPlace(BlockPlaceEvent event) {
if (!event.isCancelled()) {
Location blockloc = event.getBlock().getLocation();
this.coreListeners.blockPlace(new PlayerContainer(event.getPlayer()),
new PortalLocation(blockloc.getWorld().getName(), blockloc.getBlockX(), blockloc.getBlockY(), blockloc.getBlockZ()), event.getBlockPlaced().getType().toString(),
event.getItemInHand().getType().toString(), event.getItemInHand().getItemMeta().getDisplayName());
}
}
@EventHandler
public void onItemInteract(PlayerInteractEvent event) {
if (!event.isCancelled() && (event.getAction() == Action.LEFT_CLICK_BLOCK || event.getAction() == Action.RIGHT_CLICK_BLOCK) && event.getItem() != null) {
Location blockloc = event.getClickedBlock().getLocation();
boolean allowEvent = this.coreListeners.playerInteractWithBlock(new PlayerContainer(event.getPlayer()), event.getMaterial().toString(),
event.getItem().getItemMeta().getDisplayName(),
new PortalLocation(blockloc.getWorld().getName(), blockloc.getBlockX(), blockloc.getBlockY(), blockloc.getBlockZ()),
event.getAction() == Action.LEFT_CLICK_BLOCK);
event.setCancelled(!allowEvent);
}
}
}

View File

@ -0,0 +1,22 @@
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

@ -0,0 +1,66 @@
package com.sekwah.advancedportals.spigot.convertolddata;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
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

@ -0,0 +1,41 @@
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.coreconnector.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

@ -0,0 +1,88 @@
# Ugyanaz, mint az alapértelmezett minecraft lang fájlok, de kezelheti a megjegyzéseket, ha a # az első karakter
# Bármi, amit a fordítások nem állítottak be, visszaáll az en_GB fájlra.
# Az alapértelmezett en_GB mindig betöltődik bármely más fájl előtt, még akkor is, ha új en_GB-t készít,
# hogy az új karakterláncoknak nincs üres értékei, amelyek esetleg új funkciókat használhatnak fel.
#
# A mellékelt karakterek formátuma %(argumentum száma)$s (kezdődik 1 nem 0)
# Tehát a változók sorrendje a stringbe nem egy sorrend. Csakúgy, mint a minecraft
#
# A színek használata \u00A7 vagy § (az alt megtartásával írható be, majd a számbillentyű lenyomásával 2 majd 1)
# http://minecraft.gamepedia.com/Formatting_codes
#
# Vegye figyelembe, hogy néhány hibaelhárító üzenet itt nem szerepel a fordításban.
#
translatedata.lastchange=1.0.0
translatedata.translationsoutdated= Néhány fordítás a jelenlegi fordítási fájlból \u00A7e%1$s\u00A7c elavultak.
translatedata.replacecommand= Használat \u00A7e/portal transupdate\u00A7c hogy új alapértelmezést másoljon ki az \u00A7een_GB\u00A7c fájlból.
translatedata.replaced= Az új \u00A7een_GB\u00A7a fájlt másolva az adatmappába.
messageprefix.positive=\u00A7a[\u00A7eAdvancedPortals\u00A7a]
messageprefix.negative=\u00A7c[\u00A77AdvancedPortals\u00A7c]
logger.pluginenable=Advanced portals sikeresen engedélyezve!
logger.plugindisable=Advanced portals letiltva!
logger.plugincrafterror=A craftbukkit ezen verziója még nem támogatott, vagy valami hibás, kérlek, írd be ezt az üzenetet a verziószámmal és a fenti stacktrace-szal a GitHub kiadásában v:%1$s
command.noargs= Sajnálom, de meg kell adni egy al parancsot, kérlek, használd \u00A7e/%1$s help \u00A7cha a lehetséges al parancsok listáját szeretnéd látni.
command.subcommand.invalid= Sajnáljuk, de ez nem érvényes al parancs.
command.help.header=\u00A7e--------------- \u00A7a%1$s Segítség - Oldal %2$s %3$s\u00A7e-ból/-ből ---------------
command.help.subcommandheader=\u00A7e--------- \u00A7a%1$s Segítség - %2$s\u00A7e ---------
command.help.invalidhelp= Sajnálom, de \u00A7e%1$s\u00A7c nem érvényes oldalszám vagy al parancs.
command.reload.help=Portál adat újratöltése
command.reload.detailedhelp=Újratölt minden portáladatot az adatmappában található fájlokból
command.reload.reloaded= Minden Advanced Portals adat újratöltve
command.create.help=Portál létrehozása
command.create.error= Hiba történt a portál létrehozásában:
command.create.console= A konzol segítségével nem hozhat létre portált.
command.create.detailedhelp=A formátum /portal create (név) [tag:tagvalue] Megadja a címkéket a létrehozás után a formátum tag:value, ha az értéknek szóközre van szüksége, használja a formátum tag:"érték a szóközökkel"
command.create.complete= A portál sikeresen létrehozva.
command.createdesti.help=Célállomások létrehozása
command.createdesti.error= Hiba történt a célállomásnál:
command.createdesti.console= Nem hozhatsz létre célállomást a konzol segítségével.
command.createdesti.detailedhelp=A formátum /desti create (név) [tag:tagvalue] Megadja a címkéket a létrehozás után a formátum tag:calue, ha az értéknek szóközre van szüksége, használja a formátum tag:"érték a szóközökkel"
command.createdesti.complete= A célállomás sikeresen létrehozva.
command.create.tags=\u00A7aCímkék:
command.playeronly= Sajnáljuk, de ezt a parancsot csak egy játékos futtathatja.
command.remove.noname= Meg kell adnod az eltávolítani kívánt portál nevét.
command.remove.error= A portál eltávolítása blokkolt:
command.remove.noname=Nincs ilyen portál ezzel a névvel
command.remove.invalidselection=Az általad választott portál már nem érvényes
command.remove.noselection=Nincs kiválasztott portál
command.remove.complete= A portál sikeresen törölve.
command.selector= Kaptál egy portálválasztót.
command.selector.help=Ad egy portál régió kiválasztót
command.selector.detailedhelp=Portál választót ad a portálok létrehozásának régiói számára.
command.portalblock= Kaptál egy \u00A7ePortál blokk\u00A7aot!
command.endportalblock= Kaptál egy \u00A78Végzet portál blokk helyező\u00A7at!
command.gatewayblock= Kaptál egy \u00A78Kapubejáró blokk helyező\u00A7at!
portal.error.invalidselection=A portál létrehozásához mind a pos1, mind a pos2 szükséges.
portal.error.takenname=A portálra megadott név már megtörtént.
portal.error.selection.differentworlds=Mindkét kiválasztott pontnak ugyanabban a világban kell lennie.
desti.info.noargs=\u00A7cNincsenek címkék megadva
command.error.noname= Nincs név megadva.
desti.error.takenname=A portálra megadott név már megtörtént.
error.notplayer=Csak a játékosok tehetik ezt.
portal.selector.poschange=\u00A7eKiválasztottad a pos%1$s X:%2$s Y:%3$s Z:%4$s
command.trans.help=Fordítás másolása fordítás új alapértelmezett fordítási fájl
command.version.help=Visszaadja a plugin jelenlegi verzióját
command.subcommand.nopermission= Sajnálom, de erre nincs jogod, kérlek, használd \u00A7e/%1$s help \u00A7cha a lehetséges al parancsok listáját szeretnéd látni.