mirror of
https://github.com/mcMMO-Dev/mcMMO.git
synced 2026-02-18 01:42:32 +01:00
Compare commits
2 Commits
1.4.06-rer
...
javadocs
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3b249aa4e6 | ||
|
|
1a2d586086 |
@@ -1,8 +1,8 @@
|
||||
# mcMMO
|
||||
## The RPG lovers mod
|
||||
|
||||
### Builds
|
||||
Currently, you can obtain our builds via the Spigot resource page: http://www.spigotmc.org/resources/mcmmo.2445/
|
||||
### Dev builds
|
||||
Our latest development builds are available ~~[here](http://ci.mcmmo.info)~~. Unfortunately, the mcMMO site is down; a temporary dev build location is hosted [here](http://ci.ecocitycraft.com/job/mcMMO/).
|
||||
|
||||
### Brief Description
|
||||
The goal of mcMMO is to take core Minecraft game mechanics and expand them into add an extensive and quality RPG experience. Everything in mcMMO has been carefully thought out and is constantly being improved upon. Currently, mcMMO adds fourteen unique skills to train and level in. Each of these skills is highly customizable through our configuration files, allowing server admins to tweak mcMMO to best suit the needs of his or her server. Know that the mcMMO team is dedicated to providing an ever-evolving experience, and that we carefully read all feedback and bug reports in order to evaluate and balance the mechanics of mcMMO in every update.
|
||||
|
||||
28
pom.xml
28
pom.xml
@@ -75,23 +75,23 @@
|
||||
<configuration>
|
||||
<artifactSet>
|
||||
<includes>
|
||||
<include>com.turt2live.metrics:MetricsExtension</include>
|
||||
<include>commons-logging:commons-logging</include>
|
||||
<include>org.apache.tomcat:tomcat-jdbc</include>
|
||||
<include>org.apache.tomcat:tomcat-juli</include>
|
||||
<include>net.snaq:dbpool</include>
|
||||
</includes>
|
||||
</artifactSet>
|
||||
<relocations>
|
||||
<relocation>
|
||||
<pattern>com.turt2live.metrics</pattern>
|
||||
<shadedPattern>com.gmail.nossr50.metrics.mcstats</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>org.apache.commons.logging</pattern>
|
||||
<shadedPattern>com.gmail.nossr50.commons.logging</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>org.apache.juli</pattern>
|
||||
<shadedPattern>com.gmail.nossr50.database.tomcat.juli</shadedPattern>
|
||||
</relocation>
|
||||
<relocation>
|
||||
<pattern>org.apache.tomcat</pattern>
|
||||
<shadedPattern>com.gmail.nossr50.database.tomcat</shadedPattern>
|
||||
<pattern>net.snaq</pattern>
|
||||
<shadedPattern>com.gmail.nossr50.dbpool</shadedPattern>
|
||||
</relocation>
|
||||
</relocations>
|
||||
</configuration>
|
||||
@@ -142,10 +142,14 @@
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.tomcat</groupId>
|
||||
<artifactId>tomcat-jdbc</artifactId>
|
||||
<version>7.0.52</version>
|
||||
<scope>compile</scope>
|
||||
<groupId>com.turt2live.metrics</groupId>
|
||||
<artifactId>MetricsExtension</artifactId>
|
||||
<version>0.0.5-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.snaq</groupId>
|
||||
<artifactId>dbpool</artifactId>
|
||||
<version>5.1</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<distributionManagement>
|
||||
|
||||
@@ -11,34 +11,106 @@ import com.gmail.nossr50.util.player.UserManager;
|
||||
public final class AbilityAPI {
|
||||
private AbilityAPI() {}
|
||||
|
||||
/**
|
||||
* Checks if the ability "Berserk" is active.
|
||||
* </br>
|
||||
* This function is designed for API usage.
|
||||
*
|
||||
* @param player The {@link Player} to check
|
||||
*
|
||||
* @return true if "Berserk" is active
|
||||
*/
|
||||
public static boolean berserkEnabled(Player player) {
|
||||
return UserManager.getPlayer(player).getAbilityMode(AbilityType.BERSERK);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the ability "Giga Drill Breaker" is active.
|
||||
* </br>
|
||||
* This function is designed for API usage.
|
||||
*
|
||||
* @param player The {@link Player} to check
|
||||
*
|
||||
* @return true if "Giga Drill Breaker" is active
|
||||
*/
|
||||
public static boolean gigaDrillBreakerEnabled(Player player) {
|
||||
return UserManager.getPlayer(player).getAbilityMode(AbilityType.GIGA_DRILL_BREAKER);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the ability "Green Terra" is active.
|
||||
* </br>
|
||||
* This function is designed for API usage.
|
||||
*
|
||||
* @param player The {@link Player} to check
|
||||
*
|
||||
* @return true if "Green Terra" is active
|
||||
*/
|
||||
public static boolean greenTerraEnabled(Player player) {
|
||||
return UserManager.getPlayer(player).getAbilityMode(AbilityType.GREEN_TERRA);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the ability "Serrated Strikes" is active.
|
||||
* </br>
|
||||
* This function is designed for API usage.
|
||||
*
|
||||
* @param player The {@link Player} to check
|
||||
*
|
||||
* @return true if "Serrated Strikes" is active
|
||||
*/
|
||||
public static boolean serratedStrikesEnabled(Player player) {
|
||||
return UserManager.getPlayer(player).getAbilityMode(AbilityType.SERRATED_STRIKES);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the ability "Skull Splitter" is active.
|
||||
* </br>
|
||||
* This function is designed for API usage.
|
||||
*
|
||||
* @param player The {@link Player} to check
|
||||
*
|
||||
* @return true if "Skull Splitter" is active
|
||||
*/
|
||||
public static boolean skullSplitterEnabled(Player player) {
|
||||
return UserManager.getPlayer(player).getAbilityMode(AbilityType.SKULL_SPLITTER);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the ability "Super Breaker" is active.
|
||||
* </br>
|
||||
* This function is designed for API usage.
|
||||
*
|
||||
* @param player The {@link Player} to check
|
||||
*
|
||||
* @return true if "Super Breaker" is active
|
||||
*/
|
||||
public static boolean superBreakerEnabled(Player player) {
|
||||
return UserManager.getPlayer(player).getAbilityMode(AbilityType.SUPER_BREAKER);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the ability "Tree Feller" is active.
|
||||
* </br>
|
||||
* This function is designed for API usage.
|
||||
*
|
||||
* @param player The {@link Player} to check
|
||||
*
|
||||
* @return true if "Tree Feller" is active
|
||||
*/
|
||||
public static boolean treeFellerEnabled(Player player) {
|
||||
return UserManager.getPlayer(player).getAbilityMode(AbilityType.TREE_FELLER);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if any ability is active.
|
||||
* </br>
|
||||
* This function is designed for API usage.
|
||||
*
|
||||
* @param player The {@link Player} to check
|
||||
*
|
||||
* @return true if any ability is active
|
||||
*/
|
||||
public static boolean isAnyAbilityEnabled(Player player) {
|
||||
McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
|
||||
|
||||
@@ -51,38 +123,110 @@ public final class AbilityAPI {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the ability cooldowns for a player
|
||||
* </br>
|
||||
* This function is designed for API usage.
|
||||
*
|
||||
* @param player The {@link Player} to reset the cooldowns for
|
||||
*/
|
||||
public static void resetCooldowns(Player player) {
|
||||
UserManager.getPlayer(player).resetCooldowns();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the cooldown for the "Berserk" ability
|
||||
* </br>
|
||||
* This function is designed for API usage.
|
||||
*
|
||||
* @param player The {@link Player} to set the cooldown for
|
||||
* @param cooldown The cooldown length to set
|
||||
*/
|
||||
public static void setBerserkCooldown(Player player, long cooldown) {
|
||||
UserManager.getPlayer(player).setAbilityDATS(AbilityType.BERSERK, cooldown);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the cooldown for the "Giga Drill Breaker" ability
|
||||
* </br>
|
||||
* This function is designed for API usage.
|
||||
*
|
||||
* @param player The {@link Player} to set the cooldown for
|
||||
* @param cooldown The cooldown length to set
|
||||
*/
|
||||
public static void setGigaDrillBreakerCooldown(Player player, long cooldown) {
|
||||
UserManager.getPlayer(player).setAbilityDATS(AbilityType.GIGA_DRILL_BREAKER, cooldown);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the cooldown for the "Green Terra" ability
|
||||
* </br>
|
||||
* This function is designed for API usage.
|
||||
*
|
||||
* @param player The {@link Player} to set the cooldown for
|
||||
* @param cooldown The cooldown length to set
|
||||
*/
|
||||
public static void setGreenTerraCooldown(Player player, long cooldown) {
|
||||
UserManager.getPlayer(player).setAbilityDATS(AbilityType.GREEN_TERRA, cooldown);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the cooldown for the "Serrated Strikes" ability
|
||||
* </br>
|
||||
* This function is designed for API usage.
|
||||
*
|
||||
* @param player The {@link Player} to set the cooldown for
|
||||
* @param cooldown The cooldown length to set
|
||||
*/
|
||||
public static void setSerratedStrikesCooldown(Player player, long cooldown) {
|
||||
UserManager.getPlayer(player).setAbilityDATS(AbilityType.SERRATED_STRIKES, cooldown);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the cooldown for the "Skull Splitter" ability
|
||||
* </br>
|
||||
* This function is designed for API usage.
|
||||
*
|
||||
* @param player The {@link Player} to set the cooldown for
|
||||
* @param cooldown The cooldown length to set
|
||||
*/
|
||||
public static void setSkullSplitterCooldown(Player player, long cooldown) {
|
||||
UserManager.getPlayer(player).setAbilityDATS(AbilityType.SKULL_SPLITTER, cooldown);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the cooldown for the "Super Breaker" ability
|
||||
* </br>
|
||||
* This function is designed for API usage.
|
||||
*
|
||||
* @param player The {@link Player} to set the cooldown for
|
||||
* @param cooldown The cooldown length to set
|
||||
*/
|
||||
public static void setSuperBreakerCooldown(Player player, long cooldown) {
|
||||
UserManager.getPlayer(player).setAbilityDATS(AbilityType.SUPER_BREAKER, cooldown);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the cooldown for the "Tree Feller" ability
|
||||
* </br>
|
||||
* This function is designed for API usage.
|
||||
*
|
||||
* @param player The {@link Player} to set the cooldown for
|
||||
* @param cooldown The cooldown length to set
|
||||
*/
|
||||
public static void setTreeFellerCooldown(Player player, long cooldown) {
|
||||
UserManager.getPlayer(player).setAbilityDATS(AbilityType.TREE_FELLER, cooldown);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if a LivingEntity is bleeding
|
||||
* </br>
|
||||
* This function is designed for API usage.
|
||||
*
|
||||
* @param entity The {@link LivingEntity} to check
|
||||
* @return true if entity is bleeding, false otherwise
|
||||
*/
|
||||
public static boolean isBleeding(LivingEntity entity) {
|
||||
return BleedTimerTask.isBleeding(entity);
|
||||
}
|
||||
|
||||
@@ -71,6 +71,8 @@ public final class ChatAPI {
|
||||
|
||||
/**
|
||||
* Check if a player is currently talking in party chat.
|
||||
* </br>
|
||||
* This function is designed for API usage.
|
||||
*
|
||||
* @param player The player to check
|
||||
* @return true if the player is using party chat, false otherwise
|
||||
@@ -81,6 +83,8 @@ public final class ChatAPI {
|
||||
|
||||
/**
|
||||
* Check if a player is currently talking in party chat.
|
||||
* </br>
|
||||
* This function is designed for API usage.
|
||||
*
|
||||
* @param playerName The name of the player to check
|
||||
* @return true if the player is using party chat, false otherwise
|
||||
@@ -91,6 +95,8 @@ public final class ChatAPI {
|
||||
|
||||
/**
|
||||
* Check if a player is currently talking in admin chat.
|
||||
* </br>
|
||||
* This function is designed for API usage.
|
||||
*
|
||||
* @param player The player to check
|
||||
* @return true if the player is using admin chat, false otherwise
|
||||
@@ -101,6 +107,8 @@ public final class ChatAPI {
|
||||
|
||||
/**
|
||||
* Check if a player is currently talking in admin chat.
|
||||
* </br>
|
||||
* This function is designed for API usage.
|
||||
*
|
||||
* @param playerName The name of the player to check
|
||||
* @return true if the player is using admin chat, false otherwise
|
||||
@@ -111,6 +119,8 @@ public final class ChatAPI {
|
||||
|
||||
/**
|
||||
* Toggle the party chat mode of a player.
|
||||
* </br>
|
||||
* This function is designed for API usage.
|
||||
*
|
||||
* @param player The player to toggle party chat on.
|
||||
*/
|
||||
@@ -120,6 +130,8 @@ public final class ChatAPI {
|
||||
|
||||
/**
|
||||
* Toggle the party chat mode of a player.
|
||||
* </br>
|
||||
* This function is designed for API usage.
|
||||
*
|
||||
* @param playerName The name of the player to toggle party chat on.
|
||||
*/
|
||||
@@ -129,6 +141,8 @@ public final class ChatAPI {
|
||||
|
||||
/**
|
||||
* Toggle the admin chat mode of a player.
|
||||
* </br>
|
||||
* This function is designed for API usage.
|
||||
*
|
||||
* @param player The player to toggle admin chat on.
|
||||
*/
|
||||
@@ -138,6 +152,8 @@ public final class ChatAPI {
|
||||
|
||||
/**
|
||||
* Toggle the admin chat mode of a player.
|
||||
* </br>
|
||||
* This function is designed for API usage.
|
||||
*
|
||||
* @param playerName The name of the player to toggle party chat on.
|
||||
*/
|
||||
|
||||
@@ -192,6 +192,14 @@ public final class PartyAPI {
|
||||
return PartyManager.getOnlineMembers(player);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check is a certain party has an ally
|
||||
* </br>
|
||||
* This function is designed for API usage.
|
||||
*
|
||||
* @param partyName The name of the party to check
|
||||
* @return true if the party has an ally, false otherwise
|
||||
*/
|
||||
public static boolean hasAlly(String partyName) {
|
||||
return getAllyName(partyName) != null;
|
||||
}
|
||||
|
||||
@@ -200,7 +200,7 @@ public class AdvancedConfig extends AutoUpdateConfigLoader {
|
||||
}
|
||||
|
||||
if (getSkullSplitterModifier() < 1) {
|
||||
reason.add("Skills.Axes.SkullSplitter.DamageModifier should be at least 1!");
|
||||
reason.add("Skills.Axes.SkullSplitter.DamagerModifier should be at least 1!");
|
||||
}
|
||||
|
||||
/* FISHING */
|
||||
@@ -733,7 +733,7 @@ public class AdvancedConfig extends AutoUpdateConfigLoader {
|
||||
public double getImpactChance() { return config.getDouble("Skills.Axes.ArmorImpact.Chance", 25.0D); }
|
||||
public double getArmorImpactMaxDurabilityDamage() { return config.getDouble("Skills.Axes.ArmorImpact.MaxPercentageDurabilityDamage", 20.0D); }
|
||||
|
||||
public double getSkullSplitterModifier() { return config.getDouble("Skills.Axes.SkullSplitter.DamageModifier", 2.0D); }
|
||||
public double getSkullSplitterModifier() { return config.getDouble("Skills.Axes.SkullSplitter.DamagerModifier", 2.0D); }
|
||||
|
||||
/* EXCAVATION */
|
||||
//Nothing to configure, everything is already configurable in config.yml
|
||||
@@ -802,9 +802,6 @@ public class AdvancedConfig extends AutoUpdateConfigLoader {
|
||||
public int getSmeltingVanillaXPBoostMultiplier(Smelting.Tier tier) { return config.getInt("Skills.Smelting.VanillaXPMultiplier.Rank_" + tier.toNumerical()); }
|
||||
|
||||
/* SWORDS */
|
||||
public double getBleedDamagePlayer() { return config.getDouble("Skills.Swords.Bleed.DamagePlayer", 1.0); }
|
||||
public double getBleedDamageMobs() { return config.getDouble("Skills.Swords.Bleed.DamageMobs", 2.0); }
|
||||
|
||||
public int getBleedMaxTicks() { return config.getInt("Skills.Swords.Bleed.MaxTicks", 3); }
|
||||
public int getBleedBaseTicks() { return config.getInt("Skills.Swords.Bleed.BaseTicks", 2); }
|
||||
|
||||
|
||||
@@ -12,6 +12,8 @@ import java.util.Set;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
|
||||
import com.gmail.nossr50.metrics.MetricsManager;
|
||||
|
||||
public abstract class AutoUpdateConfigLoader extends ConfigLoader {
|
||||
public AutoUpdateConfigLoader(String relativePath, String fileName) {
|
||||
super(relativePath, fileName);
|
||||
@@ -114,5 +116,13 @@ public abstract class AutoUpdateConfigLoader extends ConfigLoader {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (String key : configKeys) {
|
||||
if (!config.isConfigurationSection(key) && !config.get(key).equals(internalConfig.get(key))) {
|
||||
MetricsManager.customConfig();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ public interface DatabaseManager {
|
||||
/**
|
||||
* Retrieve rank info into a HashMap from SkillType to the rank.
|
||||
* <p>
|
||||
* The special value <code>null</code> is used to represent the Power
|
||||
* The special value {@code null} is used to represent the Power
|
||||
* Level rank (the combination of all skill levels).
|
||||
*
|
||||
* @param playerName The name of the user to retrieve the rankings for
|
||||
|
||||
@@ -11,11 +11,10 @@ import java.util.EnumMap;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
import org.apache.tomcat.jdbc.pool.DataSource;
|
||||
import org.apache.tomcat.jdbc.pool.PoolProperties;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
import com.gmail.nossr50.mcMMO;
|
||||
@@ -30,15 +29,19 @@ import com.gmail.nossr50.datatypes.skills.SkillType;
|
||||
import com.gmail.nossr50.runnables.database.UUIDUpdateAsyncTask;
|
||||
import com.gmail.nossr50.util.Misc;
|
||||
|
||||
import snaq.db.ConnectionPool;
|
||||
|
||||
public final class SQLDatabaseManager implements DatabaseManager {
|
||||
private static final String ALL_QUERY_VERSION = "taming+mining+woodcutting+repair+unarmed+herbalism+excavation+archery+swords+axes+acrobatics+fishing+alchemy";
|
||||
private String tablePrefix = Config.getInstance().getMySQLTablePrefix();
|
||||
|
||||
private final int POOL_FETCH_TIMEOUT = 360000;
|
||||
|
||||
private final Map<UUID, Integer> cachedUserIDs = new HashMap<UUID, Integer>();
|
||||
|
||||
private DataSource miscPool;
|
||||
private DataSource loadPool;
|
||||
private DataSource savePool;
|
||||
private ConnectionPool miscPool;
|
||||
private ConnectionPool loadPool;
|
||||
private ConnectionPool savePool;
|
||||
|
||||
private ReentrantLock massUpdateLock = new ReentrantLock();
|
||||
|
||||
@@ -55,54 +58,44 @@ public final class SQLDatabaseManager implements DatabaseManager {
|
||||
//throw e; // aborts onEnable() Riking if you want to do this, fully implement it.
|
||||
}
|
||||
|
||||
|
||||
PoolProperties poolProperties = new PoolProperties();
|
||||
poolProperties.setDriverClassName("com.mysql.jdbc.Driver");
|
||||
poolProperties.setUrl(connectionString);
|
||||
poolProperties.setUsername(Config.getInstance().getMySQLUserName());
|
||||
poolProperties.setPassword(Config.getInstance().getMySQLUserPassword());
|
||||
poolProperties.setMaxIdle(Config.getInstance().getMySQLMaxPoolSize(PoolIdentifier.MISC));
|
||||
poolProperties.setMaxActive(Config.getInstance().getMySQLMaxConnections(PoolIdentifier.MISC));
|
||||
poolProperties.setInitialSize(0);
|
||||
poolProperties.setMaxWait(-1);
|
||||
poolProperties.setRemoveAbandoned(true);
|
||||
poolProperties.setRemoveAbandonedTimeout(60);
|
||||
poolProperties.setTestOnBorrow(true);
|
||||
poolProperties.setValidationQuery("SELECT 1");
|
||||
poolProperties.setValidationInterval(30000);
|
||||
miscPool = new DataSource(poolProperties);
|
||||
poolProperties = new PoolProperties();
|
||||
poolProperties.setDriverClassName("com.mysql.jdbc.Driver");
|
||||
poolProperties.setUrl(connectionString);
|
||||
poolProperties.setUsername(Config.getInstance().getMySQLUserName());
|
||||
poolProperties.setPassword(Config.getInstance().getMySQLUserPassword());
|
||||
poolProperties.setInitialSize(0);
|
||||
poolProperties.setMaxIdle(Config.getInstance().getMySQLMaxPoolSize(PoolIdentifier.SAVE));
|
||||
poolProperties.setMaxActive(Config.getInstance().getMySQLMaxConnections(PoolIdentifier.SAVE));
|
||||
poolProperties.setMaxWait(-1);
|
||||
poolProperties.setRemoveAbandoned(true);
|
||||
poolProperties.setRemoveAbandonedTimeout(60);
|
||||
poolProperties.setTestOnBorrow(true);
|
||||
poolProperties.setValidationQuery("SELECT 1");
|
||||
poolProperties.setValidationInterval(30000);
|
||||
savePool = new DataSource(poolProperties);
|
||||
poolProperties = new PoolProperties();
|
||||
poolProperties.setDriverClassName("com.mysql.jdbc.Driver");
|
||||
poolProperties.setUrl(connectionString);
|
||||
poolProperties.setUsername(Config.getInstance().getMySQLUserName());
|
||||
poolProperties.setPassword(Config.getInstance().getMySQLUserPassword());
|
||||
poolProperties.setInitialSize(0);
|
||||
poolProperties.setMaxIdle(Config.getInstance().getMySQLMaxPoolSize(PoolIdentifier.LOAD));
|
||||
poolProperties.setMaxActive(Config.getInstance().getMySQLMaxConnections(PoolIdentifier.LOAD));
|
||||
poolProperties.setMaxWait(-1);
|
||||
poolProperties.setRemoveAbandoned(true);
|
||||
poolProperties.setRemoveAbandonedTimeout(60);
|
||||
poolProperties.setTestOnBorrow(true);
|
||||
poolProperties.setValidationQuery("SELECT 1");
|
||||
poolProperties.setValidationInterval(30000);
|
||||
loadPool = new DataSource(poolProperties);
|
||||
Properties connectionProperties = new Properties();
|
||||
connectionProperties.put("user", Config.getInstance().getMySQLUserName());
|
||||
connectionProperties.put("password", Config.getInstance().getMySQLUserPassword());
|
||||
connectionProperties.put("autoReconnect", "true");
|
||||
connectionProperties.put("cachePrepStmts", "true");
|
||||
connectionProperties.put("prepStmtCacheSize", "64");
|
||||
connectionProperties.put("prepStmtCacheSqlLimit", "2048");
|
||||
connectionProperties.put("useServerPrepStmts", "true");
|
||||
miscPool = new ConnectionPool("mcMMO-Misc-Pool",
|
||||
0 /*No Minimum really needed*/,
|
||||
Config.getInstance().getMySQLMaxPoolSize(PoolIdentifier.MISC) /*max pool size */,
|
||||
Config.getInstance().getMySQLMaxConnections(PoolIdentifier.MISC) /*max num connections*/,
|
||||
400 /* idle timeout of connections */,
|
||||
connectionString,
|
||||
connectionProperties);
|
||||
loadPool = new ConnectionPool("mcMMO-Load-Pool",
|
||||
1 /*Minimum of one*/,
|
||||
Config.getInstance().getMySQLMaxPoolSize(PoolIdentifier.LOAD) /*max pool size */,
|
||||
Config.getInstance().getMySQLMaxConnections(PoolIdentifier.LOAD) /*max num connections*/,
|
||||
400 /* idle timeout of connections */,
|
||||
connectionString,
|
||||
connectionProperties);
|
||||
savePool = new ConnectionPool("mcMMO-Save-Pool",
|
||||
1 /*Minimum of one*/,
|
||||
Config.getInstance().getMySQLMaxPoolSize(PoolIdentifier.SAVE) /*max pool size */,
|
||||
Config.getInstance().getMySQLMaxConnections(PoolIdentifier.SAVE) /*max num connections*/,
|
||||
400 /* idle timeout of connections */,
|
||||
connectionString,
|
||||
connectionProperties);
|
||||
miscPool.init(); // Init first connection
|
||||
miscPool.registerShutdownHook(); // Auto release on jvm exit just in case
|
||||
loadPool.init();
|
||||
loadPool.registerShutdownHook();
|
||||
savePool.init();
|
||||
savePool.registerShutdownHook();
|
||||
|
||||
checkStructure();
|
||||
|
||||
}
|
||||
|
||||
public void purgePowerlessUsers() {
|
||||
@@ -1101,13 +1094,13 @@ public final class SQLDatabaseManager implements DatabaseManager {
|
||||
Connection connection = null;
|
||||
switch (identifier) {
|
||||
case LOAD:
|
||||
connection = loadPool.getConnection();
|
||||
connection = loadPool.getConnection(POOL_FETCH_TIMEOUT);
|
||||
break;
|
||||
case MISC:
|
||||
connection = miscPool.getConnection();
|
||||
connection = miscPool.getConnection(POOL_FETCH_TIMEOUT);
|
||||
break;
|
||||
case SAVE:
|
||||
connection = savePool.getConnection();
|
||||
connection = savePool.getConnection(POOL_FETCH_TIMEOUT);
|
||||
break;
|
||||
}
|
||||
if (connection == null) {
|
||||
@@ -1601,9 +1594,9 @@ public final class SQLDatabaseManager implements DatabaseManager {
|
||||
@Override
|
||||
public void onDisable() {
|
||||
mcMMO.p.debug("Releasing connection pool resource...");
|
||||
miscPool.close();
|
||||
loadPool.close();
|
||||
savePool.close();
|
||||
miscPool.release();
|
||||
loadPool.release();
|
||||
savePool.release();
|
||||
}
|
||||
|
||||
public enum PoolIdentifier {
|
||||
|
||||
@@ -5,9 +5,6 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import com.gmail.nossr50.runnables.skills.BleedTimerTask;
|
||||
import com.gmail.nossr50.util.player.UserManager;
|
||||
import com.gmail.nossr50.util.scoreboards.ScoreboardManager;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Sound;
|
||||
@@ -588,6 +585,10 @@ public class McMMOPlayer {
|
||||
party.addOnlineMember(this.getPlayer());
|
||||
}
|
||||
|
||||
public void logoutParty() {
|
||||
party.removeOnlineMember(this.getPlayer());
|
||||
}
|
||||
|
||||
public int getItemShareModifier() {
|
||||
if (itemShareModifier < 10) {
|
||||
setItemShareModifier(10);
|
||||
@@ -878,28 +879,4 @@ public class McMMOPlayer {
|
||||
public FixedMetadataValue getPlayerMetadata() {
|
||||
return playerMetadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called by PlayerQuitEvent to tear down the mcMMOPlayer.
|
||||
*
|
||||
* @param syncSave if true, data is saved synchronously
|
||||
*/
|
||||
public void logout(boolean syncSave) {
|
||||
Player thisPlayer = getPlayer();
|
||||
resetAbilityMode();
|
||||
BleedTimerTask.bleedOut(thisPlayer);
|
||||
|
||||
if (syncSave) {
|
||||
getProfile().save();
|
||||
} else {
|
||||
getProfile().scheduleAsyncSave();
|
||||
}
|
||||
|
||||
UserManager.remove(thisPlayer);
|
||||
ScoreboardManager.teardownPlayer(thisPlayer);
|
||||
|
||||
if (inParty()) {
|
||||
party.removeOnlineMember(thisPlayer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,30 +85,67 @@ public enum AbilityType {
|
||||
this.abilityPlayerOff = abilityPlayerOff;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the cooldown time in seconds for this ability
|
||||
*
|
||||
* @return cooldown time in seconds
|
||||
*/
|
||||
public int getCooldown() {
|
||||
return Config.getInstance().getCooldown(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the maximum length in seconds for this ability
|
||||
*
|
||||
* @return maximum length in seconds
|
||||
*/
|
||||
public int getMaxLength() {
|
||||
return Config.getInstance().getMaxLength(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the locale string for when the ability activates
|
||||
*
|
||||
* @return localized activation message
|
||||
*/
|
||||
public String getAbilityOn() {
|
||||
return LocaleLoader.getString(this.abilityOn);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the locale string for when the ability deactivates
|
||||
*
|
||||
* @return localized deactivation message
|
||||
*/
|
||||
public String getAbilityOff() {
|
||||
return LocaleLoader.getString(this.abilityOff);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the locale string for nearby players when someone activates this ability
|
||||
*
|
||||
* @param player {@link Player} object that activates this ability
|
||||
* @return localized activation message
|
||||
*/
|
||||
public String getAbilityPlayer(Player player) {
|
||||
return LocaleLoader.getString(this.abilityPlayer, player.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the locale string for nearby players when someone deactivates this ability
|
||||
*
|
||||
* @param player {@link Player} object that deactivates this ability
|
||||
* @return localized deactivation message
|
||||
*/
|
||||
public String getAbilityPlayerOff(Player player) {
|
||||
return LocaleLoader.getString(this.abilityPlayerOff, player.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get ability refresh message
|
||||
*
|
||||
* @return Localized ability refresh message
|
||||
*/
|
||||
public String getAbilityRefresh() {
|
||||
return LocaleLoader.getString(this.abilityRefresh);
|
||||
}
|
||||
|
||||
@@ -42,6 +42,7 @@ import com.gmail.nossr50.datatypes.skills.SkillType;
|
||||
import com.gmail.nossr50.locale.LocaleLoader;
|
||||
import com.gmail.nossr50.party.ShareHandler;
|
||||
import com.gmail.nossr50.runnables.player.PlayerProfileLoadingTask;
|
||||
import com.gmail.nossr50.runnables.skills.BleedTimerTask;
|
||||
import com.gmail.nossr50.skills.fishing.FishingManager;
|
||||
import com.gmail.nossr50.skills.herbalism.HerbalismManager;
|
||||
import com.gmail.nossr50.skills.mining.MiningManager;
|
||||
@@ -61,6 +62,7 @@ import com.gmail.nossr50.util.MobHealthbarUtils;
|
||||
import com.gmail.nossr50.util.Motd;
|
||||
import com.gmail.nossr50.util.Permissions;
|
||||
import com.gmail.nossr50.util.player.UserManager;
|
||||
import com.gmail.nossr50.util.scoreboards.ScoreboardManager;
|
||||
import com.gmail.nossr50.util.skills.SkillUtils;
|
||||
|
||||
public class PlayerListener implements Listener {
|
||||
@@ -359,7 +361,16 @@ public class PlayerListener implements Listener {
|
||||
}
|
||||
|
||||
McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
|
||||
mcMMOPlayer.logout(false);
|
||||
|
||||
mcMMOPlayer.resetAbilityMode();
|
||||
BleedTimerTask.bleedOut(player);
|
||||
mcMMOPlayer.getProfile().scheduleAsyncSave();
|
||||
UserManager.remove(player);
|
||||
ScoreboardManager.teardownPlayer(player);
|
||||
|
||||
if (mcMMOPlayer.inParty()) {
|
||||
mcMMOPlayer.logoutParty();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -31,6 +31,7 @@ import com.gmail.nossr50.listeners.InventoryListener;
|
||||
import com.gmail.nossr50.listeners.PlayerListener;
|
||||
import com.gmail.nossr50.listeners.SelfListener;
|
||||
import com.gmail.nossr50.listeners.WorldListener;
|
||||
import com.gmail.nossr50.metrics.MetricsManager;
|
||||
import com.gmail.nossr50.party.PartyManager;
|
||||
import com.gmail.nossr50.runnables.CheckDateTask;
|
||||
import com.gmail.nossr50.runnables.SaveTimerTask;
|
||||
@@ -178,6 +179,8 @@ public class mcMMO extends JavaPlugin {
|
||||
scheduleTasks();
|
||||
CommandRegistrationManager.registerCommands();
|
||||
|
||||
MetricsManager.setup();
|
||||
|
||||
placeStore = ChunkManagerFactory.getChunkManager(); // Get our ChunkletManager
|
||||
|
||||
checkForUpdates();
|
||||
|
||||
353
src/main/java/com/gmail/nossr50/metrics/MetricsManager.java
Normal file
353
src/main/java/com/gmail/nossr50/metrics/MetricsManager.java
Normal file
@@ -0,0 +1,353 @@
|
||||
package com.gmail.nossr50.metrics;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.Locale;
|
||||
|
||||
import com.gmail.nossr50.mcMMO;
|
||||
import com.gmail.nossr50.config.Config;
|
||||
import com.gmail.nossr50.config.HiddenConfig;
|
||||
import com.gmail.nossr50.config.experience.ExperienceConfig;
|
||||
import com.gmail.nossr50.datatypes.experience.FormulaType;
|
||||
import com.gmail.nossr50.locale.LocaleLoader;
|
||||
|
||||
import com.turt2live.metrics.EMetrics;
|
||||
import com.turt2live.metrics.Metrics;
|
||||
import com.turt2live.metrics.Metrics.Graph;
|
||||
import com.turt2live.metrics.data.DataEvent;
|
||||
import com.turt2live.metrics.data.DataTracker;
|
||||
import com.turt2live.metrics.tracker.Tracker;
|
||||
|
||||
public class MetricsManager {
|
||||
private static boolean setup = false;
|
||||
|
||||
private static Tracker chimeraUseTracker;
|
||||
private static Tracker chimeraServerUseTracker;
|
||||
|
||||
private static boolean customConfig = false;
|
||||
|
||||
private static DataTracker tracker;
|
||||
private static EMetrics emetrics;
|
||||
|
||||
public static void setup() {
|
||||
if (setup) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (Config.getInstance().getStatsTrackingEnabled()) {
|
||||
try {
|
||||
emetrics = new EMetrics(mcMMO.p);
|
||||
Metrics metrics = emetrics.getMetrics();
|
||||
|
||||
// Timings Graph
|
||||
Graph timingsGraph = metrics.createGraph("Percentage of servers using timings");
|
||||
|
||||
if (mcMMO.p.getServer().getPluginManager().useTimings()) {
|
||||
timingsGraph.addPlotter(new Metrics.Plotter("Enabled") {
|
||||
@Override
|
||||
public int getValue() {
|
||||
return 1;
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
timingsGraph.addPlotter(new Metrics.Plotter("Disabled") {
|
||||
@Override
|
||||
public int getValue() {
|
||||
return 1;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Donut Version Graph
|
||||
Graph versionDonutGraph = metrics.createGraph("Donut Version");
|
||||
|
||||
boolean haveVersionInformation = false;
|
||||
boolean isOfficialBuild = false;
|
||||
String officialKey = "e14cfacdd442a953343ebd8529138680";
|
||||
|
||||
String version = mcMMO.p.getDescription().getVersion();
|
||||
|
||||
InputStreamReader isr = new InputStreamReader(mcMMO.p.getResource(".jenkins"));
|
||||
BufferedReader br = new BufferedReader(isr);
|
||||
char[] key = new char[32];
|
||||
br.read(key);
|
||||
if (officialKey.equals(String.valueOf(key))) {
|
||||
isOfficialBuild = true;
|
||||
}
|
||||
|
||||
if (version.contains("-")) {
|
||||
String majorVersion = version.substring(0, version.indexOf("-"));
|
||||
String subVersion;
|
||||
|
||||
if (isOfficialBuild) {
|
||||
int startIndex = version.indexOf("-");
|
||||
if (version.substring(startIndex + 1).contains("-")) {
|
||||
subVersion = version.substring(startIndex, version.indexOf("-", startIndex + 1));
|
||||
}
|
||||
else {
|
||||
subVersion = "-release";
|
||||
}
|
||||
}
|
||||
else {
|
||||
subVersion = "-custom";
|
||||
}
|
||||
|
||||
version = majorVersion + "~=~" + subVersion;
|
||||
haveVersionInformation = true;
|
||||
}
|
||||
|
||||
if (haveVersionInformation) {
|
||||
versionDonutGraph.addPlotter(new Metrics.Plotter(version) {
|
||||
@Override
|
||||
public int getValue() {
|
||||
return 1;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Official v Custom build Graph
|
||||
Graph officialGraph = metrics.createGraph("Built by official ci");
|
||||
|
||||
if (isOfficialBuild) {
|
||||
officialGraph.addPlotter(new Metrics.Plotter("Yes") {
|
||||
@Override
|
||||
public int getValue() {
|
||||
return 1;
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
officialGraph.addPlotter(new Metrics.Plotter("No") {
|
||||
@Override
|
||||
public int getValue() {
|
||||
return 1;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Chunkmeta enabled Graph
|
||||
Graph chunkmetaGraph = metrics.createGraph("Uses Chunkmeta");
|
||||
|
||||
if (HiddenConfig.getInstance().getChunkletsEnabled()) {
|
||||
chunkmetaGraph.addPlotter(new Metrics.Plotter("Yes") {
|
||||
@Override
|
||||
public int getValue() {
|
||||
return 1;
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
chunkmetaGraph.addPlotter(new Metrics.Plotter("No") {
|
||||
@Override
|
||||
public int getValue() {
|
||||
return 1;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Storage method Graph
|
||||
Graph storageGraph = metrics.createGraph("Storage method");
|
||||
|
||||
if (Config.getInstance().getUseMySQL()) {
|
||||
storageGraph.addPlotter(new Metrics.Plotter("SQL") {
|
||||
@Override
|
||||
public int getValue() {
|
||||
return 1;
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
storageGraph.addPlotter(new Metrics.Plotter("Flatfile") {
|
||||
@Override
|
||||
public int getValue() {
|
||||
return 1;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Locale Graph
|
||||
Graph localeGraph = metrics.createGraph("Locale");
|
||||
|
||||
localeGraph.addPlotter(new Metrics.Plotter(LocaleLoader.getCurrentLocale().getDisplayLanguage(Locale.US)) {
|
||||
@Override
|
||||
public int getValue() {
|
||||
return 1;
|
||||
}
|
||||
});
|
||||
|
||||
// ExperienceFormulaShape Graph
|
||||
Graph experienceFormulaShapeGraph = metrics.createGraph("Experience Formula Shape Graph");
|
||||
|
||||
experienceFormulaShapeGraph.addPlotter(new Metrics.Plotter(ExperienceConfig.getInstance().getFormulaType().toString()) {
|
||||
@Override
|
||||
public int getValue() {
|
||||
return 1;
|
||||
}
|
||||
});
|
||||
|
||||
// GlobalMultiplier Graph
|
||||
Graph globalMultiplierGraph = metrics.createGraph("Global Multiplier Graph");
|
||||
|
||||
globalMultiplierGraph.addPlotter(new Metrics.Plotter(ExperienceConfig.getInstance().getExperienceGainsGlobalMultiplier() + "") {
|
||||
@Override
|
||||
public int getValue() {
|
||||
return 1;
|
||||
}
|
||||
});
|
||||
|
||||
// GlobalCurveModifier Graph
|
||||
Graph globalCurveModifierGraph = metrics.createGraph("Global Curve Modifier Graph");
|
||||
|
||||
globalCurveModifierGraph.addPlotter(new Metrics.Plotter(ExperienceConfig.getInstance().getMultiplier(FormulaType.LINEAR) + "") {
|
||||
@Override
|
||||
public int getValue() {
|
||||
return 1;
|
||||
}
|
||||
});
|
||||
|
||||
// GlobalMultiplierGraph Fuzzy Logic Numbers
|
||||
Graph globalMultiplierGraphFuzzy = metrics.createGraph("Global Multiplier Fuzz");
|
||||
|
||||
if (ExperienceConfig.getInstance().getExperienceGainsGlobalMultiplier() > 1.0) {
|
||||
globalMultiplierGraphFuzzy.addPlotter(new Metrics.Plotter("Higher") {
|
||||
@Override
|
||||
public int getValue() {
|
||||
return 1;
|
||||
}
|
||||
});
|
||||
}
|
||||
else if (ExperienceConfig.getInstance().getExperienceGainsGlobalMultiplier() < 1.0) {
|
||||
globalMultiplierGraphFuzzy.addPlotter(new Metrics.Plotter("Lower") {
|
||||
@Override
|
||||
public int getValue() {
|
||||
return 1;
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
globalMultiplierGraphFuzzy.addPlotter(new Metrics.Plotter("Default") {
|
||||
@Override
|
||||
public int getValue() {
|
||||
return 1;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// GlobalCurveModifier Fuzzy Logic Numbers
|
||||
Graph globalCurveMultiplierGraphFuzzy = metrics.createGraph("Global Curve Multiplier Fuzz");
|
||||
|
||||
if (ExperienceConfig.getInstance().getMultiplier(FormulaType.LINEAR) > 20.0) {
|
||||
globalCurveMultiplierGraphFuzzy.addPlotter(new Metrics.Plotter("Higher") {
|
||||
@Override
|
||||
public int getValue() {
|
||||
return 1;
|
||||
}
|
||||
});
|
||||
}
|
||||
else if (ExperienceConfig.getInstance().getMultiplier(FormulaType.LINEAR) < 20.0) {
|
||||
globalCurveMultiplierGraphFuzzy.addPlotter(new Metrics.Plotter("Lower") {
|
||||
@Override
|
||||
public int getValue() {
|
||||
return 1;
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
globalCurveMultiplierGraphFuzzy.addPlotter(new Metrics.Plotter("Default") {
|
||||
@Override
|
||||
public int getValue() {
|
||||
return 1;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Chimera Wing Usage Trackers
|
||||
final String chimeraGraphName = "Chimera Wing Usage";
|
||||
|
||||
chimeraUseTracker = EMetrics.createBasicTracker(chimeraGraphName, "Player use");
|
||||
chimeraServerUseTracker = EMetrics.createEnabledTracker(chimeraGraphName, "Server use");
|
||||
|
||||
emetrics.addTracker(chimeraUseTracker);
|
||||
emetrics.addTracker(chimeraServerUseTracker);
|
||||
|
||||
// Chimera Wing Enabled Graph
|
||||
Graph chimeraGraph = metrics.createGraph("Chimera Wing");
|
||||
|
||||
if (Config.getInstance().getChimaeraEnabled()) {
|
||||
chimeraGraph.addPlotter(new Metrics.Plotter("Enabled") {
|
||||
@Override
|
||||
public int getValue() {
|
||||
return 1;
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
chimeraGraph.addPlotter(new Metrics.Plotter("Disabled") {
|
||||
@Override
|
||||
public int getValue() {
|
||||
return 1;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Vanilla v Modified config graph
|
||||
Graph customConfigGraph = metrics.createGraph("Modified Configs");
|
||||
|
||||
if (customConfig) {
|
||||
customConfigGraph.addPlotter(new Metrics.Plotter("Edited") {
|
||||
@Override
|
||||
public int getValue() {
|
||||
return 1;
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
customConfigGraph.addPlotter(new Metrics.Plotter("Vanilla") {
|
||||
@Override
|
||||
public int getValue() {
|
||||
return 1;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
* Debug stuff
|
||||
* tracker = emetrics.getDataTracker();
|
||||
* tracker.enable();
|
||||
* tracker.setFilter(new DataEvent.DataType [] { DataEvent.DataType.SEND_DATA });
|
||||
*/
|
||||
|
||||
emetrics.startMetrics();
|
||||
}
|
||||
catch (IOException e) {
|
||||
mcMMO.p.getLogger().warning("Failed to submit stats.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void chimeraWingUsed() {
|
||||
chimeraUseTracker.increment();
|
||||
chimeraServerUseTracker.increment();
|
||||
}
|
||||
|
||||
public static void customConfig() {
|
||||
customConfig = true;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static void debug() {
|
||||
emetrics.getMetrics().flush();
|
||||
|
||||
for (DataEvent event : tracker.getEvents()) {
|
||||
String graphName = event.getGraphName();
|
||||
String colName = event.getTrackerName();
|
||||
int value = event.getValueSent();
|
||||
|
||||
System.out.println("Graph: " + graphName + ", Column: " + colName + ", Value: " + value);
|
||||
}
|
||||
|
||||
tracker.resetEvents();
|
||||
}
|
||||
}
|
||||
@@ -20,7 +20,7 @@ public class UUIDUpdateAsyncTask extends BukkitRunnable {
|
||||
private static final int MAX_LOOKUP = Math.max(HiddenConfig.getInstance().getUUIDConvertAmount(), 100);
|
||||
private static final int RATE_LIMIT = HiddenConfig.getInstance().getMojangRateLimit();
|
||||
private static final long LIMIT_PERIOD = HiddenConfig.getInstance().getMojangLimitPeriod();
|
||||
private static final int BATCH_SIZE = MAX_LOOKUP * 3;
|
||||
private static final int BATCH_SIZE = 5000;
|
||||
|
||||
private List<String> userNames;
|
||||
private int size;
|
||||
@@ -68,17 +68,6 @@ public class UUIDUpdateAsyncTask extends BukkitRunnable {
|
||||
fetchedUUIDs.putAll(new UUIDFetcher(userNamesSection).call());
|
||||
}
|
||||
catch (Exception e) {
|
||||
// Handle 429
|
||||
if (e.getMessage().contains("429")) {
|
||||
try {
|
||||
Thread.sleep(LIMIT_PERIOD);
|
||||
} catch (InterruptedException ex) {
|
||||
e.printStackTrace();
|
||||
return;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
plugin.getLogger().log(Level.SEVERE, "Unable to fetch UUIDs!", e);
|
||||
return;
|
||||
}
|
||||
@@ -88,7 +77,7 @@ public class UUIDUpdateAsyncTask extends BukkitRunnable {
|
||||
size = userNames.size();
|
||||
|
||||
Misc.printProgress(checkedUsers, DatabaseManager.progressInterval, startMillis);
|
||||
if (fetchedUUIDs.size() >= BATCH_SIZE) {
|
||||
if (fetchedUUIDs.size() > BATCH_SIZE) {
|
||||
mcMMO.getDatabaseManager().saveUserUUIDs(fetchedUUIDs);
|
||||
fetchedUUIDs = new HashMap<String, UUID>();
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@ import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
import com.gmail.nossr50.config.AdvancedConfig;
|
||||
import com.gmail.nossr50.locale.LocaleLoader;
|
||||
import com.gmail.nossr50.util.skills.CombatUtils;
|
||||
import com.gmail.nossr50.util.skills.ParticleEffectUtils;
|
||||
@@ -29,10 +28,10 @@ public class BleedTimerTask extends BukkitRunnable {
|
||||
continue;
|
||||
}
|
||||
|
||||
double damage;
|
||||
int damage;
|
||||
|
||||
if (entity instanceof Player) {
|
||||
damage = AdvancedConfig.getInstance().getBleedDamagePlayer();
|
||||
damage = 1;
|
||||
Player player = (Player) entity;
|
||||
|
||||
if (!player.isOnline()) {
|
||||
@@ -45,14 +44,14 @@ public class BleedTimerTask extends BukkitRunnable {
|
||||
ParticleEffectUtils.playBleedEffect(entity);
|
||||
}
|
||||
|
||||
entry.setValue(entry.getValue() - 1);
|
||||
entry.setValue(entry.getValue() - damage);
|
||||
|
||||
if (entry.getValue() <= 0) {
|
||||
player.sendMessage(LocaleLoader.getString("Swords.Combat.Bleeding.Stopped"));
|
||||
}
|
||||
}
|
||||
else {
|
||||
damage = AdvancedConfig.getInstance().getBleedDamageMobs();
|
||||
damage = 2;
|
||||
|
||||
// Anticipate the entity's death to prevent CME because of our EntityDeathEvent listener
|
||||
if (entity.getHealth() - damage > 0) {
|
||||
|
||||
@@ -19,10 +19,26 @@ public final class Acrobatics {
|
||||
|
||||
private Acrobatics() {};
|
||||
|
||||
/**
|
||||
* Calculates how much damage should be dealt when Dodging
|
||||
*
|
||||
* @param damage the base damage
|
||||
* @param damageModifier the damage modifier
|
||||
*
|
||||
* @return modified damage
|
||||
*/
|
||||
protected static double calculateModifiedDodgeDamage(double damage, double damageModifier) {
|
||||
return Math.max(damage / damageModifier, 1.0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates how much damage should be dealt when Rolling
|
||||
*
|
||||
* @param damage the base damage
|
||||
* @param damageThreshold the damage threshold
|
||||
*
|
||||
* @return modified damage
|
||||
*/
|
||||
protected static double calculateModifiedRollDamage(double damage, double damageThreshold) {
|
||||
return Math.max(damage - damageThreshold, 0.0);
|
||||
}
|
||||
|
||||
@@ -28,10 +28,22 @@ public class AcrobaticsManager extends SkillManager {
|
||||
super(mcMMOPlayer, SkillType.ACROBATICS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the player is allowed to use Roll,
|
||||
* checks permissions and exploit prevention.
|
||||
*
|
||||
* @return true if the player is allowed to use Roll
|
||||
*/
|
||||
public boolean canRoll() {
|
||||
return !exploitPrevention() && Permissions.secondaryAbilityEnabled(getPlayer(), SecondaryAbility.ROLL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the player is allowed to use Dodge
|
||||
*
|
||||
* @param damager {@link Entity} that caused damage
|
||||
* @return true if the player can Dodge damage from damager
|
||||
*/
|
||||
public boolean canDodge(Entity damager) {
|
||||
if (Permissions.secondaryAbilityEnabled(getPlayer(), SecondaryAbility.DODGE)) {
|
||||
if (damager instanceof LightningStrike && Acrobatics.dodgeLightningDisabled) {
|
||||
@@ -152,10 +164,23 @@ public class AcrobaticsManager extends SkillManager {
|
||||
return fallTries + 1 > maxTries;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a fall is fatal
|
||||
*
|
||||
* @param damage amount of damage taken from the fall
|
||||
* @return true if the fall is fatal, false otherwise
|
||||
*/
|
||||
private boolean isFatal(double damage) {
|
||||
return getPlayer().getHealth() - damage <= 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the amount of XP gained from falling
|
||||
*
|
||||
* @param damage amount of damage taken in the fall
|
||||
* @param isRoll boolean if the player was rolling
|
||||
* @return amount of XP gained
|
||||
*/
|
||||
private float calculateRollXP(double damage, boolean isRoll) {
|
||||
ItemStack boots = getPlayer().getInventory().getBoots();
|
||||
float xp = (float) (damage * (isRoll ? Acrobatics.rollXpModifier : Acrobatics.fallXpModifier));
|
||||
|
||||
@@ -23,6 +23,12 @@ public class Archery {
|
||||
|
||||
public static final double DISTANCE_XP_MULTIPLIER = 0.025;
|
||||
|
||||
/**
|
||||
* Increment tracked arrow count for a LivingEntity,
|
||||
* if the entity isn't tracked yet it will get added to the tracker.
|
||||
*
|
||||
* @param livingEntity the {@link LivingEntity} to increment the arrow count for
|
||||
*/
|
||||
protected static void incrementTrackerValue(LivingEntity livingEntity) {
|
||||
for (TrackedEntity trackedEntity : trackedEntities) {
|
||||
if (trackedEntity.getLivingEntity().getEntityId() == livingEntity.getEntityId()) {
|
||||
@@ -34,6 +40,11 @@ public class Archery {
|
||||
addToTracker(livingEntity); // If the entity isn't tracked yet
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a LivingEntity to the tracker.
|
||||
*
|
||||
* @param livingEntity the {@link LivingEntity} to add.
|
||||
*/
|
||||
protected static void addToTracker(LivingEntity livingEntity) {
|
||||
TrackedEntity trackedEntity = new TrackedEntity(livingEntity);
|
||||
|
||||
@@ -41,6 +52,11 @@ public class Archery {
|
||||
trackedEntities.add(trackedEntity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a TrackedEntity from the tracker.
|
||||
*
|
||||
* @param trackedEntity the {@link TrackedEntity} to remove.
|
||||
*/
|
||||
protected static void removeFromTracker(TrackedEntity trackedEntity) {
|
||||
trackedEntities.remove(trackedEntity);
|
||||
}
|
||||
|
||||
@@ -23,14 +23,30 @@ public class ArcheryManager extends SkillManager {
|
||||
super(mcMMOPlayer, SkillType.ARCHERY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the target can be dazed. Checks if target is valid and if the player has sufficient permissions.
|
||||
*
|
||||
* @param target the {@link LivingEntity} object of the target to check
|
||||
* @return true if the target can be dazed, false otherwise
|
||||
*/
|
||||
public boolean canDaze(LivingEntity target) {
|
||||
return target instanceof Player && Permissions.secondaryAbilityEnabled(getPlayer(), SecondaryAbility.DAZE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the player can use SkillShot.
|
||||
*
|
||||
* @return true if the player can use SkillShot, false otherwise
|
||||
*/
|
||||
public boolean canSkillShot() {
|
||||
return getSkillLevel() >= Archery.skillShotIncreaseLevel && Permissions.secondaryAbilityEnabled(getPlayer(), SecondaryAbility.SKILL_SHOT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the player can use RetrieveArrows.
|
||||
*
|
||||
* @return true if the player can use RetrieveArrows, false otherwise
|
||||
*/
|
||||
public boolean canRetrieveArrows() {
|
||||
return Permissions.secondaryAbilityEnabled(getPlayer(), SecondaryAbility.RETRIEVE);
|
||||
}
|
||||
@@ -67,6 +83,8 @@ public class ArcheryManager extends SkillManager {
|
||||
* Handle the effects of the Daze ability
|
||||
*
|
||||
* @param defender The {@link Player} being affected by the ability
|
||||
*
|
||||
* @return amount of damage from Daze
|
||||
*/
|
||||
public double daze(Player defender) {
|
||||
if (!SkillUtils.activationSuccessful(SecondaryAbility.DAZE, getPlayer(), getSkillLevel(), activationChance)) {
|
||||
@@ -94,6 +112,7 @@ public class ArcheryManager extends SkillManager {
|
||||
* Handle the effects of the Skill Shot ability
|
||||
*
|
||||
* @param damage The amount of damage initially dealt by the event
|
||||
* @return amount of damage from Skill Shot
|
||||
*/
|
||||
public double skillShot(double damage) {
|
||||
if (!SkillUtils.activationSuccessful(SecondaryAbility.SKILL_SHOT, getPlayer())) {
|
||||
|
||||
@@ -23,6 +23,12 @@ public class Axes {
|
||||
|
||||
public static double skullSplitterModifier = AdvancedConfig.getInstance().getSkullSplitterModifier();
|
||||
|
||||
/**
|
||||
* Check if the target is wearing any armor.
|
||||
*
|
||||
* @param target the {@link LivingEntity} object of the target to check.
|
||||
* @return true if the target is wearing at least one piece of armor, false otherwise
|
||||
*/
|
||||
protected static boolean hasArmor(LivingEntity target) {
|
||||
for (ItemStack itemStack : target.getEquipment().getArmorContents()) {
|
||||
if (ItemUtils.isArmor(itemStack)) {
|
||||
|
||||
@@ -159,6 +159,9 @@ public class RepairManager extends SkillManager {
|
||||
/**
|
||||
* Check if the player has tried to use an Anvil before.
|
||||
*
|
||||
* @param anvilType The {@link Material} of the anvil block
|
||||
* @param actualize determines if last anvil use should be actualized
|
||||
*
|
||||
* @return true if the player has confirmed using an Anvil
|
||||
*/
|
||||
public boolean checkConfirmation(boolean actualize) {
|
||||
@@ -273,7 +276,7 @@ public class RepairManager extends SkillManager {
|
||||
/**
|
||||
* Handles removing & downgrading enchants.
|
||||
*
|
||||
* @param item Item being repaired
|
||||
* @param item {@link ItemStack} being repaired
|
||||
*/
|
||||
private void addEnchants(ItemStack item) {
|
||||
Player player = getPlayer();
|
||||
|
||||
@@ -52,10 +52,6 @@ public class TrackedTamingEntity extends BukkitRunnable {
|
||||
CombatUtils.dealDamage(livingEntity, livingEntity.getMaxHealth(), DamageCause.SUICIDE, livingEntity);
|
||||
}
|
||||
|
||||
if (!UserManager.hasPlayerDataKey(owner)) {
|
||||
return;
|
||||
}
|
||||
|
||||
McMMOPlayer mcMMOPlayer = UserManager.getPlayer(owner);
|
||||
TamingManager tamingManager = mcMMOPlayer.getTamingManager();
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ import com.gmail.nossr50.mcMMO;
|
||||
import com.gmail.nossr50.config.Config;
|
||||
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
|
||||
import com.gmail.nossr50.locale.LocaleLoader;
|
||||
import com.gmail.nossr50.metrics.MetricsManager;
|
||||
import com.gmail.nossr50.runnables.items.ChimaeraWingWarmup;
|
||||
import com.gmail.nossr50.util.player.UserManager;
|
||||
import com.gmail.nossr50.util.skills.CombatUtils;
|
||||
@@ -134,6 +135,10 @@ public final class ChimaeraWing {
|
||||
mcMMOPlayer.actualizeChimeraWingLastUse();
|
||||
mcMMOPlayer.setTeleportCommenceLocation(null);
|
||||
|
||||
if (Config.getInstance().getStatsTrackingEnabled()) {
|
||||
MetricsManager.chimeraWingUsed();
|
||||
}
|
||||
|
||||
if (Config.getInstance().getChimaeraSoundEnabled()) {
|
||||
player.playSound(location, Sound.BAT_TAKEOFF, Misc.BAT_VOLUME, Misc.BAT_PITCH);
|
||||
}
|
||||
|
||||
@@ -34,8 +34,6 @@ public final class HardcoreManager {
|
||||
int playerSkillXpLevel = playerProfile.getSkillXpLevel(skillType);
|
||||
|
||||
if (playerSkillLevel <= 0 || playerSkillLevel <= levelThreshold) {
|
||||
levelChanged.put(skillType.toString(), 0);
|
||||
experienceChanged.put(skillType.toString(), 0F);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -77,8 +75,6 @@ public final class HardcoreManager {
|
||||
int victimSkillLevel = victimProfile.getSkillLevel(skillType);
|
||||
|
||||
if (victimSkillLevel <= 0 || victimSkillLevel < killerSkillLevel / 2 || victimSkillLevel <= levelThreshold) {
|
||||
levelChanged.put(skillType.toString(), 0);
|
||||
experienceChanged.put(skillType.toString(), 0F);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ import org.json.simple.JSONObject;
|
||||
import org.json.simple.parser.JSONParser;
|
||||
|
||||
public class UUIDFetcher implements Callable<Map<String, UUID>> {
|
||||
private static final int PROFILES_PER_REQUEST = 50;
|
||||
private static final int PROFILES_PER_REQUEST = 100;
|
||||
private static final long RATE_LIMIT = 100L;
|
||||
private static final String PROFILE_URL = "https://api.mojang.com/profiles/minecraft";
|
||||
private final JSONParser jsonParser = new JSONParser();
|
||||
|
||||
@@ -447,11 +447,6 @@ Skills:
|
||||
ChanceMax: 75.0
|
||||
MaxBonusLevel: 750
|
||||
|
||||
# DamagePlayer: Bleeding damage dealt to players
|
||||
# DamageMobs: Bleeding damage dealt to mobs
|
||||
DamagePlayer: 1.0
|
||||
DamageMobs: 2.0
|
||||
|
||||
# These settings determine how long the Bleeding effect lasts
|
||||
MaxTicks: 3
|
||||
BaseTicks: 2
|
||||
|
||||
@@ -14,6 +14,6 @@ Options:
|
||||
UUIDConvertAmount: 100
|
||||
# Amount of users to be converted at a time before waiting MojangLimitPeriod milliseconds to begin again
|
||||
# This setting is for large servers to avoid being temp banned from mojang api
|
||||
MojangRateLimit: 300
|
||||
MojangRateLimit: 50000
|
||||
# Amount of time to wait after hitting the MojangRateLimit in UUID conversion
|
||||
MojangLimitPeriod: 6000
|
||||
MojangLimitPeriod: 600000
|
||||
|
||||
Reference in New Issue
Block a user