mirror of
https://github.com/mcMMO-Dev/mcMMO.git
synced 2024-11-22 21:26:46 +01:00
SQLDatabaseManager optimizations, async profile loading -t00thpick1, zreed
This commit changes our shared connection into a connection pool utility to prevent thread locks from multiple actions attempting to access the database at the same time. In additon, profile loading has been moved off the main thread at login time, to allieviate the performance issues caused by it. Fixes #2138, Fixes #2119, Fixes #1982, Fixes #1953
This commit is contained in:
parent
c10525ada9
commit
857e12b96e
@ -10,6 +10,7 @@ Key:
|
|||||||
Version 1.5.01-dev
|
Version 1.5.01-dev
|
||||||
+ Added new child skill; Salvage
|
+ Added new child skill; Salvage
|
||||||
+ Added UUID support!
|
+ Added UUID support!
|
||||||
|
+ Added SQL connection pooling and async loading!
|
||||||
+ Added new feature to Herbalism. Instantly-regrown crops are protected from being broken for 1 second
|
+ Added new feature to Herbalism. Instantly-regrown crops are protected from being broken for 1 second
|
||||||
+ Added option to config.yml to show the /mcstats scoreboard automatically after logging in
|
+ Added option to config.yml to show the /mcstats scoreboard automatically after logging in
|
||||||
+ Added option to config.yml for Alchemy. Skills.Alchemy.Prevent_Hopper_Transfer_Bottles
|
+ Added option to config.yml for Alchemy. Skills.Alchemy.Prevent_Hopper_Transfer_Bottles
|
||||||
|
15
pom.xml
15
pom.xml
@ -76,6 +76,8 @@
|
|||||||
<artifactSet>
|
<artifactSet>
|
||||||
<includes>
|
<includes>
|
||||||
<include>com.turt2live.metrics:MetricsExtension</include>
|
<include>com.turt2live.metrics:MetricsExtension</include>
|
||||||
|
<include>commons-logging:commons-logging</include>
|
||||||
|
<include>net.snaq:dbpool</include>
|
||||||
</includes>
|
</includes>
|
||||||
</artifactSet>
|
</artifactSet>
|
||||||
<relocations>
|
<relocations>
|
||||||
@ -83,6 +85,14 @@
|
|||||||
<pattern>com.turt2live.metrics</pattern>
|
<pattern>com.turt2live.metrics</pattern>
|
||||||
<shadedPattern>com.gmail.nossr50.metrics.mcstats</shadedPattern>
|
<shadedPattern>com.gmail.nossr50.metrics.mcstats</shadedPattern>
|
||||||
</relocation>
|
</relocation>
|
||||||
|
<relocation>
|
||||||
|
<pattern>org.apache.commons.logging</pattern>
|
||||||
|
<shadedPattern>com.gmail.nossr50.commons.logging</shadedPattern>
|
||||||
|
</relocation>
|
||||||
|
<relocation>
|
||||||
|
<pattern>net.snaq</pattern>
|
||||||
|
<shadedPattern>com.gmail.nossr50.dbpool</shadedPattern>
|
||||||
|
</relocation>
|
||||||
</relocations>
|
</relocations>
|
||||||
</configuration>
|
</configuration>
|
||||||
<executions>
|
<executions>
|
||||||
@ -136,6 +146,11 @@
|
|||||||
<artifactId>MetricsExtension</artifactId>
|
<artifactId>MetricsExtension</artifactId>
|
||||||
<version>0.0.5-SNAPSHOT</version>
|
<version>0.0.5-SNAPSHOT</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>net.snaq</groupId>
|
||||||
|
<artifactId>dbpool</artifactId>
|
||||||
|
<version>5.1</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<distributionManagement>
|
<distributionManagement>
|
||||||
<repository>
|
<repository>
|
||||||
|
@ -930,7 +930,7 @@ public final class ExperienceAPI {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static PlayerProfile getOfflineProfile(UUID uuid) {
|
private static PlayerProfile getOfflineProfile(UUID uuid) {
|
||||||
PlayerProfile profile = mcMMO.getDatabaseManager().loadPlayerProfile(uuid, false);
|
PlayerProfile profile = mcMMO.getDatabaseManager().loadPlayerProfile(uuid);
|
||||||
|
|
||||||
if (!profile.isLoaded()) {
|
if (!profile.isLoaded()) {
|
||||||
throw new InvalidPlayerException();
|
throw new InvalidPlayerException();
|
||||||
@ -942,7 +942,7 @@ public final class ExperienceAPI {
|
|||||||
@Deprecated
|
@Deprecated
|
||||||
private static PlayerProfile getOfflineProfile(String playerName) {
|
private static PlayerProfile getOfflineProfile(String playerName) {
|
||||||
UUID uuid = mcMMO.p.getServer().getOfflinePlayer(playerName).getUniqueId();
|
UUID uuid = mcMMO.p.getServer().getOfflinePlayer(playerName).getUniqueId();
|
||||||
PlayerProfile profile = mcMMO.getDatabaseManager().loadPlayerProfile(uuid, false);
|
PlayerProfile profile = mcMMO.getDatabaseManager().loadPlayerProfile(uuid);
|
||||||
|
|
||||||
if (!profile.isLoaded()) {
|
if (!profile.isLoaded()) {
|
||||||
throw new InvalidPlayerException();
|
throw new InvalidPlayerException();
|
||||||
|
@ -12,6 +12,7 @@ import com.gmail.nossr50.datatypes.database.DatabaseType;
|
|||||||
import com.gmail.nossr50.datatypes.player.PlayerProfile;
|
import com.gmail.nossr50.datatypes.player.PlayerProfile;
|
||||||
import com.gmail.nossr50.locale.LocaleLoader;
|
import com.gmail.nossr50.locale.LocaleLoader;
|
||||||
import com.gmail.nossr50.runnables.database.DatabaseConversionTask;
|
import com.gmail.nossr50.runnables.database.DatabaseConversionTask;
|
||||||
|
import com.gmail.nossr50.runnables.player.PlayerProfileLoadingTask;
|
||||||
import com.gmail.nossr50.util.player.UserManager;
|
import com.gmail.nossr50.util.player.UserManager;
|
||||||
|
|
||||||
public class ConvertDatabaseCommand implements CommandExecutor {
|
public class ConvertDatabaseCommand implements CommandExecutor {
|
||||||
@ -55,13 +56,13 @@ public class ConvertDatabaseCommand implements CommandExecutor {
|
|||||||
UserManager.clearAll();
|
UserManager.clearAll();
|
||||||
|
|
||||||
for (Player player : mcMMO.p.getServer().getOnlinePlayers()) {
|
for (Player player : mcMMO.p.getServer().getOnlinePlayers()) {
|
||||||
PlayerProfile profile = oldDatabase.loadPlayerProfile(player.getUniqueId(), false);
|
PlayerProfile profile = oldDatabase.loadPlayerProfile(player.getUniqueId());
|
||||||
|
|
||||||
if (profile.isLoaded()) {
|
if (profile.isLoaded()) {
|
||||||
mcMMO.getDatabaseManager().saveUser(profile);
|
mcMMO.getDatabaseManager().saveUser(profile);
|
||||||
}
|
}
|
||||||
|
|
||||||
UserManager.addUser(player);
|
new PlayerProfileLoadingTask(player).runTaskTimerAsynchronously(mcMMO.p, 1, 20); // 1 Tick delay to ensure the player is marked as online before we begin loading
|
||||||
}
|
}
|
||||||
|
|
||||||
new DatabaseConversionTask(oldDatabase, sender, previousType.toString(), newType.toString()).runTaskAsynchronously(mcMMO.p);
|
new DatabaseConversionTask(oldDatabase, sender, previousType.toString(), newType.toString()).runTaskAsynchronously(mcMMO.p);
|
||||||
|
@ -9,6 +9,7 @@ import com.gmail.nossr50.mcMMO;
|
|||||||
import com.gmail.nossr50.datatypes.experience.FormulaType;
|
import com.gmail.nossr50.datatypes.experience.FormulaType;
|
||||||
import com.gmail.nossr50.locale.LocaleLoader;
|
import com.gmail.nossr50.locale.LocaleLoader;
|
||||||
import com.gmail.nossr50.runnables.database.FormulaConversionTask;
|
import com.gmail.nossr50.runnables.database.FormulaConversionTask;
|
||||||
|
import com.gmail.nossr50.runnables.player.PlayerProfileLoadingTask;
|
||||||
import com.gmail.nossr50.util.player.UserManager;
|
import com.gmail.nossr50.util.player.UserManager;
|
||||||
|
|
||||||
public class ConvertExperienceCommand implements CommandExecutor {
|
public class ConvertExperienceCommand implements CommandExecutor {
|
||||||
@ -37,7 +38,7 @@ public class ConvertExperienceCommand implements CommandExecutor {
|
|||||||
new FormulaConversionTask(sender, newType).runTaskLater(mcMMO.p, 1);
|
new FormulaConversionTask(sender, newType).runTaskLater(mcMMO.p, 1);
|
||||||
|
|
||||||
for (Player player : mcMMO.p.getServer().getOnlinePlayers()) {
|
for (Player player : mcMMO.p.getServer().getOnlinePlayers()) {
|
||||||
UserManager.addUser(player);
|
new PlayerProfileLoadingTask(player).runTaskTimerAsynchronously(mcMMO.p, 1, 20); // 1 Tick delay to ensure the player is marked as online before we begin loading
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -232,6 +232,7 @@ public class Config extends AutoUpdateConfigLoader {
|
|||||||
/* General Settings */
|
/* General Settings */
|
||||||
public String getLocale() { return config.getString("General.Locale", "en_us"); }
|
public String getLocale() { return config.getString("General.Locale", "en_us"); }
|
||||||
public boolean getMOTDEnabled() { return config.getBoolean("General.MOTD_Enabled", true); }
|
public boolean getMOTDEnabled() { return config.getBoolean("General.MOTD_Enabled", true); }
|
||||||
|
public boolean getShowProfileLoadedMessage() { return config.getBoolean("General.Show_Profile_Loaded", true); }
|
||||||
public boolean getDonateMessageEnabled() { return config.getBoolean("Commands.mcmmo.Donate_Message", true); }
|
public boolean getDonateMessageEnabled() { return config.getBoolean("Commands.mcmmo.Donate_Message", true); }
|
||||||
public int getSaveInterval() { return config.getInt("General.Save_Interval", 10); }
|
public int getSaveInterval() { return config.getInt("General.Save_Interval", 10); }
|
||||||
public boolean getStatsTrackingEnabled() { return config.getBoolean("General.Stats_Tracking", true); }
|
public boolean getStatsTrackingEnabled() { return config.getBoolean("General.Stats_Tracking", true); }
|
||||||
@ -313,6 +314,8 @@ public class Config extends AutoUpdateConfigLoader {
|
|||||||
public int getMySQLServerPort() { return config.getInt("MySQL.Server.Port", 3306); }
|
public int getMySQLServerPort() { return config.getInt("MySQL.Server.Port", 3306); }
|
||||||
public String getMySQLServerName() { return config.getString("MySQL.Server.Address", "localhost"); }
|
public String getMySQLServerName() { return config.getString("MySQL.Server.Address", "localhost"); }
|
||||||
public String getMySQLUserPassword() { return getStringIncludingInts("MySQL.Database.User_Password"); }
|
public String getMySQLUserPassword() { return getStringIncludingInts("MySQL.Database.User_Password"); }
|
||||||
|
public int getMySQLMaxConnections() { return config.getInt("MySQL.Database.MaxConnections"); }
|
||||||
|
public int getMySQLMaxPoolSize() { return config.getInt("MySQL.Database.MaxPoolSize"); }
|
||||||
|
|
||||||
private String getStringIncludingInts(String key) {
|
private String getStringIncludingInts(String key) {
|
||||||
String str = config.getString(key);
|
String str = config.getString(key);
|
||||||
|
@ -73,7 +73,7 @@ public interface DatabaseManager {
|
|||||||
/**
|
/**
|
||||||
* Load a player from the database.
|
* Load a player from the database.
|
||||||
*
|
*
|
||||||
* @deprecated replaced by {@link #loadPlayerProfile(UUID uuid, boolean createNew)}
|
* @deprecated replaced by {@link #loadPlayerProfile(String playerName, UUID uuid, boolean createNew)}
|
||||||
*
|
*
|
||||||
* @param playerName The name of the player to load from the database
|
* @param playerName The name of the player to load from the database
|
||||||
* @param createNew Whether to create a new record if the player is not
|
* @param createNew Whether to create a new record if the player is not
|
||||||
@ -88,12 +88,9 @@ public interface DatabaseManager {
|
|||||||
* Load a player from the database.
|
* Load a player from the database.
|
||||||
*
|
*
|
||||||
* @param uuid The uuid of the player to load from the database
|
* @param uuid The uuid of the player to load from the database
|
||||||
* @param createNew Whether to create a new record if the player is not
|
|
||||||
* found
|
|
||||||
* @return The player's data, or an unloaded PlayerProfile if not found
|
* @return The player's data, or an unloaded PlayerProfile if not found
|
||||||
* and createNew is false
|
|
||||||
*/
|
*/
|
||||||
public PlayerProfile loadPlayerProfile(UUID uuid, boolean createNew);
|
public PlayerProfile loadPlayerProfile(UUID uuid);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load a player from the database. Attempt to use uuid, fall back on playername
|
* Load a player from the database. Attempt to use uuid, fall back on playername
|
||||||
@ -132,4 +129,9 @@ public interface DatabaseManager {
|
|||||||
* @return The type of database
|
* @return The type of database
|
||||||
*/
|
*/
|
||||||
public DatabaseType getDatabaseType();
|
public DatabaseType getDatabaseType();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the plugin disables
|
||||||
|
*/
|
||||||
|
public void onDisable();
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,6 @@ package com.gmail.nossr50.database;
|
|||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.BufferedWriter;
|
import java.io.BufferedWriter;
|
||||||
import java.io.Closeable;
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileReader;
|
import java.io.FileReader;
|
||||||
import java.io.FileWriter;
|
import java.io.FileWriter;
|
||||||
@ -10,6 +9,7 @@ import java.io.IOException;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
|
import java.util.EnumMap;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -98,8 +98,22 @@ public final class FlatfileDatabaseManager implements DatabaseManager {
|
|||||||
mcMMO.p.getLogger().severe("Exception while reading " + usersFilePath + " (Are you sure you formatted it correctly?)" + e.toString());
|
mcMMO.p.getLogger().severe("Exception while reading " + usersFilePath + " (Are you sure you formatted it correctly?)" + e.toString());
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
tryClose(in);
|
if (in != null) {
|
||||||
tryClose(out);
|
try {
|
||||||
|
in.close();
|
||||||
|
}
|
||||||
|
catch (IOException e) {
|
||||||
|
// Ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (out != null) {
|
||||||
|
try {
|
||||||
|
out.close();
|
||||||
|
}
|
||||||
|
catch (IOException e) {
|
||||||
|
// Ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,8 +178,22 @@ public final class FlatfileDatabaseManager implements DatabaseManager {
|
|||||||
mcMMO.p.getLogger().severe("Exception while reading " + usersFilePath + " (Are you sure you formatted it correctly?)" + e.toString());
|
mcMMO.p.getLogger().severe("Exception while reading " + usersFilePath + " (Are you sure you formatted it correctly?)" + e.toString());
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
tryClose(in);
|
if (in != null) {
|
||||||
tryClose(out);
|
try {
|
||||||
|
in.close();
|
||||||
|
}
|
||||||
|
catch (IOException e) {
|
||||||
|
// Ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (out != null) {
|
||||||
|
try {
|
||||||
|
out.close();
|
||||||
|
}
|
||||||
|
catch (IOException e) {
|
||||||
|
// Ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -203,8 +231,22 @@ public final class FlatfileDatabaseManager implements DatabaseManager {
|
|||||||
mcMMO.p.getLogger().severe("Exception while reading " + usersFilePath + " (Are you sure you formatted it correctly?)" + e.toString());
|
mcMMO.p.getLogger().severe("Exception while reading " + usersFilePath + " (Are you sure you formatted it correctly?)" + e.toString());
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
tryClose(in);
|
if (in != null) {
|
||||||
tryClose(out);
|
try {
|
||||||
|
in.close();
|
||||||
|
}
|
||||||
|
catch (IOException e) {
|
||||||
|
// Ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (out != null) {
|
||||||
|
try {
|
||||||
|
out.close();
|
||||||
|
}
|
||||||
|
catch (IOException e) {
|
||||||
|
// Ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -294,8 +336,22 @@ public final class FlatfileDatabaseManager implements DatabaseManager {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
tryClose(in);
|
if (in != null) {
|
||||||
tryClose(out);
|
try {
|
||||||
|
in.close();
|
||||||
|
}
|
||||||
|
catch (IOException e) {
|
||||||
|
// Ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (out != null) {
|
||||||
|
try {
|
||||||
|
out.close();
|
||||||
|
}
|
||||||
|
catch (IOException e) {
|
||||||
|
// Ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -311,7 +367,7 @@ public final class FlatfileDatabaseManager implements DatabaseManager {
|
|||||||
public Map<SkillType, Integer> readRank(String playerName) {
|
public Map<SkillType, Integer> readRank(String playerName) {
|
||||||
updateLeaderboards();
|
updateLeaderboards();
|
||||||
|
|
||||||
Map<SkillType, Integer> skills = new HashMap<SkillType, Integer>();
|
Map<SkillType, Integer> skills = new EnumMap<SkillType, Integer>(SkillType.class);
|
||||||
|
|
||||||
for (SkillType skill : SkillType.NON_CHILD_SKILLS) {
|
for (SkillType skill : SkillType.NON_CHILD_SKILLS) {
|
||||||
skills.put(skill, getPlayerRank(playerName, playerStatHash.get(skill)));
|
skills.put(skill, getPlayerRank(playerName, playerStatHash.get(skill)));
|
||||||
@ -381,18 +437,25 @@ public final class FlatfileDatabaseManager implements DatabaseManager {
|
|||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
tryClose(out);
|
if (out != null) {
|
||||||
|
try {
|
||||||
|
out.close();
|
||||||
|
}
|
||||||
|
catch (IOException e) {
|
||||||
|
// Ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public PlayerProfile loadPlayerProfile(String playerName, boolean create) {
|
public PlayerProfile loadPlayerProfile(String playerName, boolean create) {
|
||||||
return loadPlayerProfile(playerName, "", create);
|
return loadPlayerProfile(playerName, "", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public PlayerProfile loadPlayerProfile(UUID uuid, boolean create) {
|
public PlayerProfile loadPlayerProfile(UUID uuid) {
|
||||||
return loadPlayerProfile("", uuid.toString(), create);
|
return loadPlayerProfile("", uuid.toString(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public PlayerProfile loadPlayerProfile(String playerName, UUID uuid, boolean create) {
|
public PlayerProfile loadPlayerProfile(String playerName, UUID uuid, boolean create) {
|
||||||
@ -448,7 +511,7 @@ public final class FlatfileDatabaseManager implements DatabaseManager {
|
|||||||
in.close();
|
in.close();
|
||||||
}
|
}
|
||||||
catch (IOException e) {
|
catch (IOException e) {
|
||||||
e.printStackTrace();
|
// Ignore
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -491,7 +554,14 @@ public final class FlatfileDatabaseManager implements DatabaseManager {
|
|||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
tryClose(in);
|
if (in != null) {
|
||||||
|
try {
|
||||||
|
in.close();
|
||||||
|
}
|
||||||
|
catch (IOException e) {
|
||||||
|
// Ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -532,8 +602,22 @@ public final class FlatfileDatabaseManager implements DatabaseManager {
|
|||||||
mcMMO.p.getLogger().severe("Exception while reading " + usersFilePath + " (Are you sure you formatted it correctly?)" + e.toString());
|
mcMMO.p.getLogger().severe("Exception while reading " + usersFilePath + " (Are you sure you formatted it correctly?)" + e.toString());
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
tryClose(in);
|
if (in != null) {
|
||||||
tryClose(out);
|
try {
|
||||||
|
in.close();
|
||||||
|
}
|
||||||
|
catch (IOException e) {
|
||||||
|
// Ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (out != null) {
|
||||||
|
try {
|
||||||
|
out.close();
|
||||||
|
}
|
||||||
|
catch (IOException e) {
|
||||||
|
// Ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -573,8 +657,22 @@ public final class FlatfileDatabaseManager implements DatabaseManager {
|
|||||||
mcMMO.p.getLogger().severe("Exception while reading " + usersFilePath + " (Are you sure you formatted it correctly?)" + e.toString());
|
mcMMO.p.getLogger().severe("Exception while reading " + usersFilePath + " (Are you sure you formatted it correctly?)" + e.toString());
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
tryClose(in);
|
if (in != null) {
|
||||||
tryClose(out);
|
try {
|
||||||
|
in.close();
|
||||||
|
}
|
||||||
|
catch (IOException e) {
|
||||||
|
// Ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (out != null) {
|
||||||
|
try {
|
||||||
|
out.close();
|
||||||
|
}
|
||||||
|
catch (IOException e) {
|
||||||
|
// Ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -601,7 +699,14 @@ public final class FlatfileDatabaseManager implements DatabaseManager {
|
|||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
tryClose(in);
|
if (in != null) {
|
||||||
|
try {
|
||||||
|
in.close();
|
||||||
|
}
|
||||||
|
catch (IOException e) {
|
||||||
|
// Ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return users;
|
return users;
|
||||||
@ -671,7 +776,14 @@ public final class FlatfileDatabaseManager implements DatabaseManager {
|
|||||||
mcMMO.p.getLogger().severe("Exception while reading " + usersFilePath + " during user " + playerName + " (Are you sure you formatted it correctly?) " + e.toString());
|
mcMMO.p.getLogger().severe("Exception while reading " + usersFilePath + " during user " + playerName + " (Are you sure you formatted it correctly?) " + e.toString());
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
tryClose(in);
|
if (in != null) {
|
||||||
|
try {
|
||||||
|
in.close();
|
||||||
|
}
|
||||||
|
catch (IOException e) {
|
||||||
|
// Ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -897,8 +1009,22 @@ public final class FlatfileDatabaseManager implements DatabaseManager {
|
|||||||
mcMMO.p.getLogger().severe("Exception while reading " + usersFilePath + " (Are you sure you formatted it correctly?)" + e.toString());
|
mcMMO.p.getLogger().severe("Exception while reading " + usersFilePath + " (Are you sure you formatted it correctly?)" + e.toString());
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
tryClose(in);
|
if (in != null) {
|
||||||
tryClose(out);
|
try {
|
||||||
|
in.close();
|
||||||
|
}
|
||||||
|
catch (IOException e) {
|
||||||
|
// Ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (out != null) {
|
||||||
|
try {
|
||||||
|
out.close();
|
||||||
|
}
|
||||||
|
catch (IOException e) {
|
||||||
|
// Ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -923,18 +1049,6 @@ public final class FlatfileDatabaseManager implements DatabaseManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void tryClose(Closeable c) {
|
|
||||||
if (c == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
c.close();
|
|
||||||
}
|
|
||||||
catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Integer getPlayerRank(String playerName, List<PlayerStat> statsList) {
|
private Integer getPlayerRank(String playerName, List<PlayerStat> statsList) {
|
||||||
if (statsList == null) {
|
if (statsList == null) {
|
||||||
return null;
|
return null;
|
||||||
@ -967,8 +1081,8 @@ public final class FlatfileDatabaseManager implements DatabaseManager {
|
|||||||
|
|
||||||
private PlayerProfile loadFromLine(String[] character) {
|
private PlayerProfile loadFromLine(String[] character) {
|
||||||
Map<SkillType, Integer> skills = getSkillMapFromLine(character); // Skill levels
|
Map<SkillType, Integer> skills = getSkillMapFromLine(character); // Skill levels
|
||||||
Map<SkillType, Float> skillsXp = new HashMap<SkillType, Float>(); // Skill & XP
|
Map<SkillType, Float> skillsXp = new EnumMap<SkillType, Float>(SkillType.class); // Skill & XP
|
||||||
Map<AbilityType, Integer> skillsDATS = new HashMap<AbilityType, Integer>(); // Ability & Cooldown
|
Map<AbilityType, Integer> skillsDATS = new EnumMap<AbilityType, Integer>(AbilityType.class); // Ability & Cooldown
|
||||||
MobHealthbarType mobHealthbarType;
|
MobHealthbarType mobHealthbarType;
|
||||||
|
|
||||||
// TODO on updates, put new values in a try{} ?
|
// TODO on updates, put new values in a try{} ?
|
||||||
@ -1019,7 +1133,7 @@ public final class FlatfileDatabaseManager implements DatabaseManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Map<SkillType, Integer> getSkillMapFromLine(String[] character) {
|
private Map<SkillType, Integer> getSkillMapFromLine(String[] character) {
|
||||||
Map<SkillType, Integer> skills = new HashMap<SkillType, Integer>(); // Skill & Level
|
Map<SkillType, Integer> skills = new EnumMap<SkillType, Integer>(SkillType.class); // Skill & Level
|
||||||
|
|
||||||
skills.put(SkillType.TAMING, Integer.valueOf(character[24]));
|
skills.put(SkillType.TAMING, Integer.valueOf(character[24]));
|
||||||
skills.put(SkillType.MINING, Integer.valueOf(character[1]));
|
skills.put(SkillType.MINING, Integer.valueOf(character[1]));
|
||||||
@ -1041,4 +1155,7 @@ public final class FlatfileDatabaseManager implements DatabaseManager {
|
|||||||
public DatabaseType getDatabaseType() {
|
public DatabaseType getDatabaseType() {
|
||||||
return DatabaseType.FLATFILE;
|
return DatabaseType.FLATFILE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDisable() { }
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -7,12 +7,10 @@ import java.util.UUID;
|
|||||||
|
|
||||||
import org.bukkit.GameMode;
|
import org.bukkit.GameMode;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Server;
|
|
||||||
import org.bukkit.Sound;
|
import org.bukkit.Sound;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.bukkit.metadata.FixedMetadataValue;
|
import org.bukkit.metadata.FixedMetadataValue;
|
||||||
import org.bukkit.scheduler.BukkitRunnable;
|
|
||||||
|
|
||||||
import com.gmail.nossr50.mcMMO;
|
import com.gmail.nossr50.mcMMO;
|
||||||
import com.gmail.nossr50.config.AdvancedConfig;
|
import com.gmail.nossr50.config.AdvancedConfig;
|
||||||
@ -93,13 +91,13 @@ public class McMMOPlayer {
|
|||||||
private boolean isUsingUnarmed;
|
private boolean isUsingUnarmed;
|
||||||
private final FixedMetadataValue playerMetadata;
|
private final FixedMetadataValue playerMetadata;
|
||||||
|
|
||||||
public McMMOPlayer(Player player) {
|
public McMMOPlayer(Player player, PlayerProfile profile) {
|
||||||
String playerName = player.getName();
|
String playerName = player.getName();
|
||||||
UUID uuid = player.getUniqueId();
|
UUID uuid = player.getUniqueId();
|
||||||
|
|
||||||
this.player = player;
|
this.player = player;
|
||||||
playerMetadata = new FixedMetadataValue(mcMMO.p, playerName);
|
playerMetadata = new FixedMetadataValue(mcMMO.p, playerName);
|
||||||
profile = mcMMO.getDatabaseManager().loadPlayerProfile(playerName, uuid, true);
|
this.profile = profile;
|
||||||
party = PartyManager.getPlayerParty(playerName);
|
party = PartyManager.getPlayerParty(playerName);
|
||||||
ptpRecord = new PartyTeleportRecord();
|
ptpRecord = new PartyTeleportRecord();
|
||||||
|
|
||||||
@ -130,70 +128,6 @@ public class McMMOPlayer {
|
|||||||
for (ToolType toolType : ToolType.values()) {
|
for (ToolType toolType : ToolType.values()) {
|
||||||
toolMode.put(toolType, false);
|
toolMode.put(toolType, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!profile.isLoaded()) {
|
|
||||||
mcMMO.p.getLogger().warning("Unable to load the PlayerProfile for " + playerName + ". Will retry over the next several seconds.");
|
|
||||||
new RetryProfileLoadingTask().runTaskTimerAsynchronously(mcMMO.p, 11L, 31L);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class RetryProfileLoadingTask extends BukkitRunnable {
|
|
||||||
private static final int MAX_TRIES = 5;
|
|
||||||
private final String playerName = McMMOPlayer.this.player.getName();
|
|
||||||
private final UUID uniqueId = McMMOPlayer.this.player.getUniqueId();
|
|
||||||
private int attempt = 0;
|
|
||||||
|
|
||||||
// WARNING: ASYNC TASK
|
|
||||||
// DO NOT MODIFY THE McMMOPLAYER FROM THIS CODE
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
// Quit if they logged out
|
|
||||||
if (!player.isOnline()) {
|
|
||||||
mcMMO.p.getLogger().info("Aborting profile loading recovery for " + playerName + " - player logged out");
|
|
||||||
this.cancel();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Send the message that we're doing the recovery
|
|
||||||
if (attempt == 0) {
|
|
||||||
player.sendMessage(LocaleLoader.getString("Recovery.Notice"));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Increment attempt counter and try
|
|
||||||
attempt++;
|
|
||||||
PlayerProfile profile = mcMMO.getDatabaseManager().loadPlayerProfile(uniqueId, true);
|
|
||||||
// If successful, schedule the apply
|
|
||||||
if (profile.isLoaded()) {
|
|
||||||
new ApplySuccessfulProfile(profile).runTask(mcMMO.p);
|
|
||||||
player.sendMessage(LocaleLoader.getString("Recovery.Success"));
|
|
||||||
this.cancel();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we've failed five times, give up
|
|
||||||
if (attempt >= MAX_TRIES) {
|
|
||||||
mcMMO.p.getLogger().severe("Giving up on attempting to load the PlayerProfile for " + playerName);
|
|
||||||
mcMMO.p.getServer().broadcast(LocaleLoader.getString("Recovery.AdminFailureNotice", playerName), Server.BROADCAST_CHANNEL_ADMINISTRATIVE);
|
|
||||||
player.sendMessage(LocaleLoader.getString("Recovery.Failure").split("\n"));
|
|
||||||
this.cancel();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class ApplySuccessfulProfile extends BukkitRunnable {
|
|
||||||
private final PlayerProfile profile;
|
|
||||||
|
|
||||||
private ApplySuccessfulProfile(PlayerProfile profile) {
|
|
||||||
this.profile = profile;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Synchronized task
|
|
||||||
// No database access permitted
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
McMMOPlayer.this.profile = profile;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public AcrobaticsManager getAcrobaticsManager() {
|
public AcrobaticsManager getAcrobaticsManager() {
|
||||||
|
@ -41,7 +41,7 @@ import com.gmail.nossr50.datatypes.skills.AbilityType;
|
|||||||
import com.gmail.nossr50.datatypes.skills.SkillType;
|
import com.gmail.nossr50.datatypes.skills.SkillType;
|
||||||
import com.gmail.nossr50.locale.LocaleLoader;
|
import com.gmail.nossr50.locale.LocaleLoader;
|
||||||
import com.gmail.nossr50.party.ShareHandler;
|
import com.gmail.nossr50.party.ShareHandler;
|
||||||
import com.gmail.nossr50.runnables.commands.McScoreboardKeepTask;
|
import com.gmail.nossr50.runnables.player.PlayerProfileLoadingTask;
|
||||||
import com.gmail.nossr50.runnables.skills.BleedTimerTask;
|
import com.gmail.nossr50.runnables.skills.BleedTimerTask;
|
||||||
import com.gmail.nossr50.skills.fishing.FishingManager;
|
import com.gmail.nossr50.skills.fishing.FishingManager;
|
||||||
import com.gmail.nossr50.skills.herbalism.HerbalismManager;
|
import com.gmail.nossr50.skills.herbalism.HerbalismManager;
|
||||||
@ -387,9 +387,7 @@ public class PlayerListener implements Listener {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
McMMOPlayer mcMMOPlayer = UserManager.addUser(player);
|
new PlayerProfileLoadingTask(player).runTaskTimerAsynchronously(mcMMO.p, 1, 20); // 1 Tick delay to ensure the player is marked as online before we begin loading
|
||||||
mcMMOPlayer.actualizeRespawnATS();
|
|
||||||
ScoreboardManager.setupPlayer(player);
|
|
||||||
|
|
||||||
if (Config.getInstance().getMOTDEnabled() && Permissions.motd(player)) {
|
if (Config.getInstance().getMOTDEnabled() && Permissions.motd(player)) {
|
||||||
Motd.displayAll(player);
|
Motd.displayAll(player);
|
||||||
@ -403,11 +401,6 @@ public class PlayerListener implements Listener {
|
|||||||
player.sendMessage(LocaleLoader.getString("UpdateChecker.Outdated"));
|
player.sendMessage(LocaleLoader.getString("UpdateChecker.Outdated"));
|
||||||
player.sendMessage(LocaleLoader.getString("UpdateChecker.NewAvailable"));
|
player.sendMessage(LocaleLoader.getString("UpdateChecker.NewAvailable"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Config.getInstance().getShowStatsAfterLogin()) {
|
|
||||||
ScoreboardManager.enablePlayerStatsScoreboard(player);
|
|
||||||
new McScoreboardKeepTask(player).runTaskLater(mcMMO.p, 1 * Misc.TICK_CONVERSION_FACTOR);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -38,6 +38,7 @@ import com.gmail.nossr50.runnables.UpdaterResultAsyncTask;
|
|||||||
import com.gmail.nossr50.runnables.backups.CleanBackupsTask;
|
import com.gmail.nossr50.runnables.backups.CleanBackupsTask;
|
||||||
import com.gmail.nossr50.runnables.database.UserPurgeTask;
|
import com.gmail.nossr50.runnables.database.UserPurgeTask;
|
||||||
import com.gmail.nossr50.runnables.party.PartyAutoKickTask;
|
import com.gmail.nossr50.runnables.party.PartyAutoKickTask;
|
||||||
|
import com.gmail.nossr50.runnables.player.PlayerProfileLoadingTask;
|
||||||
import com.gmail.nossr50.runnables.player.PowerLevelUpdatingTask;
|
import com.gmail.nossr50.runnables.player.PowerLevelUpdatingTask;
|
||||||
import com.gmail.nossr50.runnables.skills.BleedTimerTask;
|
import com.gmail.nossr50.runnables.skills.BleedTimerTask;
|
||||||
import com.gmail.nossr50.skills.alchemy.Alchemy;
|
import com.gmail.nossr50.skills.alchemy.Alchemy;
|
||||||
@ -167,8 +168,7 @@ public class mcMMO extends JavaPlugin {
|
|||||||
holidayManager = new HolidayManager();
|
holidayManager = new HolidayManager();
|
||||||
|
|
||||||
for (Player player : getServer().getOnlinePlayers()) {
|
for (Player player : getServer().getOnlinePlayers()) {
|
||||||
UserManager.addUser(player); // In case of reload add all users back into UserManager
|
new PlayerProfileLoadingTask(player).runTaskTimerAsynchronously(mcMMO.p, 1, 20); // 1 Tick delay to ensure the player is marked as online before we begin loading
|
||||||
ScoreboardManager.setupPlayer(player);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
debug("Version " + getDescription().getVersion() + " is enabled!");
|
debug("Version " + getDescription().getVersion() + " is enabled!");
|
||||||
@ -242,6 +242,7 @@ public class mcMMO extends JavaPlugin {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
databaseManager.onDisable();
|
||||||
debug("Was disabled."); // How informative!
|
debug("Was disabled."); // How informative!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,39 +0,0 @@
|
|||||||
package com.gmail.nossr50.runnables.database;
|
|
||||||
|
|
||||||
import java.lang.ref.WeakReference;
|
|
||||||
|
|
||||||
import org.bukkit.scheduler.BukkitRunnable;
|
|
||||||
|
|
||||||
import com.gmail.nossr50.database.SQLDatabaseManager;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This task is in charge of sending a MySQL ping over the MySQL connection
|
|
||||||
* every hour to prevent the connection from timing out and losing players'
|
|
||||||
* data when they join.
|
|
||||||
* <p/>
|
|
||||||
* A WeakReference is used to keep the database instance, because
|
|
||||||
* {@link com.gmail.nossr50.commands.database.ConvertDatabaseCommand database
|
|
||||||
* conversion} may create a SQLDatabaseManager that will be thrown out. If a
|
|
||||||
* normal reference was used, the conversion would cause a combined data and
|
|
||||||
* resource leak through this task.
|
|
||||||
*/
|
|
||||||
public class SQLDatabaseKeepaliveTask extends BukkitRunnable {
|
|
||||||
WeakReference<SQLDatabaseManager> databaseInstance;
|
|
||||||
|
|
||||||
public SQLDatabaseKeepaliveTask(SQLDatabaseManager dbman) {
|
|
||||||
databaseInstance = new WeakReference<SQLDatabaseManager>(dbman);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void run() {
|
|
||||||
SQLDatabaseManager dbman = databaseInstance.get();
|
|
||||||
if (dbman != null) {
|
|
||||||
dbman.checkConnected();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// This happens when the database was started for a conversion,
|
|
||||||
// or discarded by its creator for any other reason. If this code
|
|
||||||
// was not present, we would leak the connection resources.
|
|
||||||
this.cancel();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,22 +0,0 @@
|
|||||||
package com.gmail.nossr50.runnables.database;
|
|
||||||
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.scheduler.BukkitRunnable;
|
|
||||||
|
|
||||||
import com.gmail.nossr50.mcMMO;
|
|
||||||
import com.gmail.nossr50.database.SQLDatabaseManager;
|
|
||||||
import com.gmail.nossr50.util.player.UserManager;
|
|
||||||
|
|
||||||
public class SQLReconnectTask extends BukkitRunnable {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
if (((SQLDatabaseManager) mcMMO.getDatabaseManager()).checkConnected()) {
|
|
||||||
UserManager.saveAll(); // Save all profiles
|
|
||||||
UserManager.clearAll(); // Clear the profiles
|
|
||||||
|
|
||||||
for (Player player : mcMMO.p.getServer().getOnlinePlayers()) {
|
|
||||||
UserManager.addUser(player); // Add in new profiles, forcing them to 'load' again from MySQL
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,51 +0,0 @@
|
|||||||
package com.gmail.nossr50.runnables.database;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Map.Entry;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
import org.bukkit.scheduler.BukkitRunnable;
|
|
||||||
|
|
||||||
import com.gmail.nossr50.mcMMO;
|
|
||||||
import com.gmail.nossr50.util.uuid.UUIDFetcher;
|
|
||||||
|
|
||||||
public class UUIDFetcherRunnable extends BukkitRunnable {
|
|
||||||
private List<String> names;
|
|
||||||
|
|
||||||
public UUIDFetcherRunnable(List<String> names) {
|
|
||||||
this.names = names;
|
|
||||||
}
|
|
||||||
|
|
||||||
public UUIDFetcherRunnable(String name) {
|
|
||||||
this.names = new ArrayList<String>();
|
|
||||||
this.names.add(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
try {
|
|
||||||
Map<String, UUID> returns = new UUIDFetcher(this.names).call();
|
|
||||||
new CacheReturnedNames(returns).runTask(mcMMO.p);
|
|
||||||
}
|
|
||||||
catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class CacheReturnedNames extends BukkitRunnable {
|
|
||||||
private Map<String, UUID> returns;
|
|
||||||
|
|
||||||
public CacheReturnedNames(Map<String, UUID> returns) {
|
|
||||||
this.returns = returns;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
for (Entry<String, UUID> entry : this.returns.entrySet()) {
|
|
||||||
mcMMO.getDatabaseManager().saveUserUUID(entry.getKey(), entry.getValue());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,108 @@
|
|||||||
|
package com.gmail.nossr50.runnables.player;
|
||||||
|
|
||||||
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
|
||||||
|
import org.bukkit.Server;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.scheduler.BukkitRunnable;
|
||||||
|
|
||||||
|
import com.gmail.nossr50.mcMMO;
|
||||||
|
import com.gmail.nossr50.config.Config;
|
||||||
|
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
|
||||||
|
import com.gmail.nossr50.datatypes.player.PlayerProfile;
|
||||||
|
import com.gmail.nossr50.locale.LocaleLoader;
|
||||||
|
import com.gmail.nossr50.runnables.commands.McScoreboardKeepTask;
|
||||||
|
import com.gmail.nossr50.util.Misc;
|
||||||
|
import com.gmail.nossr50.util.player.UserManager;
|
||||||
|
import com.gmail.nossr50.util.scoreboards.ScoreboardManager;
|
||||||
|
|
||||||
|
public class PlayerProfileLoadingTask extends BukkitRunnable {
|
||||||
|
private static final int MAX_TRIES = 5;
|
||||||
|
private final Player player;
|
||||||
|
private int attempt = 0;
|
||||||
|
private ReentrantLock lock = new ReentrantLock();
|
||||||
|
private boolean cancelled = false;
|
||||||
|
|
||||||
|
public PlayerProfileLoadingTask(Player player) {
|
||||||
|
this.player = player;
|
||||||
|
}
|
||||||
|
|
||||||
|
// WARNING: ASYNC TASK
|
||||||
|
// DO NOT MODIFY THE McMMOPLAYER FROM THIS CODE
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
lock.lock();
|
||||||
|
|
||||||
|
if (this.cancelled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Quit if they logged out
|
||||||
|
if (!player.isOnline()) {
|
||||||
|
mcMMO.p.getLogger().info("Aborting profile loading recovery for " + player.getName() + " - player logged out");
|
||||||
|
this.cancel();
|
||||||
|
cancelled = true;
|
||||||
|
lock.unlock();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Increment attempt counter and try
|
||||||
|
attempt++;
|
||||||
|
|
||||||
|
PlayerProfile profile = mcMMO.getDatabaseManager().loadPlayerProfile(player.getName(), player.getUniqueId(), true);
|
||||||
|
// If successful, schedule the apply
|
||||||
|
if (profile.isLoaded()) {
|
||||||
|
new ApplySuccessfulProfile(profile).runTask(mcMMO.p);
|
||||||
|
this.cancel();
|
||||||
|
cancelled = true;
|
||||||
|
lock.unlock();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we've failed five times, give up
|
||||||
|
if (attempt >= MAX_TRIES) {
|
||||||
|
mcMMO.p.getLogger().severe("Giving up on attempting to load the PlayerProfile for " + player.getName());
|
||||||
|
mcMMO.p.getServer().broadcast(LocaleLoader.getString("Profile.Loading.AdminFailureNotice", player.getName()), Server.BROADCAST_CHANNEL_ADMINISTRATIVE);
|
||||||
|
player.sendMessage(LocaleLoader.getString("Profile.Loading.Failure").split("\n"));
|
||||||
|
this.cancel();
|
||||||
|
cancelled = true;
|
||||||
|
lock.unlock();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
lock.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ApplySuccessfulProfile extends BukkitRunnable {
|
||||||
|
private final PlayerProfile profile;
|
||||||
|
|
||||||
|
private ApplySuccessfulProfile(PlayerProfile profile) {
|
||||||
|
this.profile = profile;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Synchronized task
|
||||||
|
// No database access permitted
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
if (!player.isOnline()) {
|
||||||
|
mcMMO.p.getLogger().info("Aborting profile loading recovery for " + player.getName() + " - player logged out");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
McMMOPlayer mcMMOPlayer = new McMMOPlayer(player, profile);
|
||||||
|
UserManager.track(mcMMOPlayer);
|
||||||
|
mcMMOPlayer.actualizeRespawnATS();
|
||||||
|
ScoreboardManager.setupPlayer(player);
|
||||||
|
|
||||||
|
if (Config.getInstance().getShowProfileLoadedMessage()) {
|
||||||
|
player.sendMessage(LocaleLoader.getString("Profile.Loading.Success"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Config.getInstance().getShowStatsAfterLogin()) {
|
||||||
|
ScoreboardManager.enablePlayerStatsScoreboard(player);
|
||||||
|
new McScoreboardKeepTask(player).runTaskLater(mcMMO.p, 1 * Misc.TICK_CONVERSION_FACTOR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -13,6 +13,7 @@ import org.bukkit.inventory.ItemStack;
|
|||||||
|
|
||||||
import com.gmail.nossr50.mcMMO;
|
import com.gmail.nossr50.mcMMO;
|
||||||
import com.gmail.nossr50.events.items.McMMOItemSpawnEvent;
|
import com.gmail.nossr50.events.items.McMMOItemSpawnEvent;
|
||||||
|
import com.gmail.nossr50.runnables.player.PlayerProfileLoadingTask;
|
||||||
import com.gmail.nossr50.util.player.UserManager;
|
import com.gmail.nossr50.util.player.UserManager;
|
||||||
|
|
||||||
public final class Misc {
|
public final class Misc {
|
||||||
@ -112,7 +113,7 @@ public final class Misc {
|
|||||||
|
|
||||||
if (player != null) {
|
if (player != null) {
|
||||||
UserManager.remove(player);
|
UserManager.remove(player);
|
||||||
UserManager.addUser(player);
|
new PlayerProfileLoadingTask(player).runTaskTimerAsynchronously(mcMMO.p, 1, 20); // 1 Tick delay to ensure the player is marked as online before we begin loading
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,16 +18,12 @@ public final class UserManager {
|
|||||||
private UserManager() {}
|
private UserManager() {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a new user.
|
* Track a new user.
|
||||||
*
|
*
|
||||||
* @param player The player to create a user record for
|
* @param mcMMOPlayer the player profile to start tracking
|
||||||
* @return the player's {@link McMMOPlayer} object
|
|
||||||
*/
|
*/
|
||||||
public static McMMOPlayer addUser(Player player) {
|
public static void track(McMMOPlayer mcMMOPlayer) {
|
||||||
McMMOPlayer mcMMOPlayer = new McMMOPlayer(player);
|
mcMMOPlayer.getPlayer().setMetadata(mcMMO.playerDataKey, new FixedMetadataValue(mcMMO.p, mcMMOPlayer));
|
||||||
player.setMetadata(mcMMO.playerDataKey, new FixedMetadataValue(mcMMO.p, mcMMOPlayer));
|
|
||||||
|
|
||||||
return mcMMOPlayer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -10,6 +10,8 @@
|
|||||||
General:
|
General:
|
||||||
Locale: en_US
|
Locale: en_US
|
||||||
MOTD_Enabled: true
|
MOTD_Enabled: true
|
||||||
|
# Send a message to the player when his profile was successfully loaded
|
||||||
|
Show_Profile_Loaded: false
|
||||||
# Amount of time (in minutes) to wait between saves of player information
|
# Amount of time (in minutes) to wait between saves of player information
|
||||||
Save_Interval: 10
|
Save_Interval: 10
|
||||||
# Allow mcMMO to report on basic anonymous usage
|
# Allow mcMMO to report on basic anonymous usage
|
||||||
@ -122,6 +124,12 @@ MySQL:
|
|||||||
User_Password: UserPassword
|
User_Password: UserPassword
|
||||||
Name: DataBaseName
|
Name: DataBaseName
|
||||||
TablePrefix: mcmmo_
|
TablePrefix: mcmmo_
|
||||||
|
# This setting is the max simultaneous mysql connections allowed at a time, needs to be
|
||||||
|
# high enough to support multiple player logins in quick succession
|
||||||
|
MaxConnections: 30
|
||||||
|
# This setting is the max size of the pool of cached connections that we hold available
|
||||||
|
# at any given time
|
||||||
|
MaxPoolSize: 20
|
||||||
Server:
|
Server:
|
||||||
Port: 3306
|
Port: 3306
|
||||||
Address: localhost
|
Address: localhost
|
||||||
|
@ -960,7 +960,6 @@ Scoreboard.Misc.Cooldown=[[LIGHT_PURPLE]]Cooldown
|
|||||||
Scoreboard.Misc.Overall=[[GOLD]]Overall
|
Scoreboard.Misc.Overall=[[GOLD]]Overall
|
||||||
|
|
||||||
#DATABASE RECOVERY
|
#DATABASE RECOVERY
|
||||||
Recovery.Notice=[[RED]]Notice: mcMMO was [[DARK_RED]]unable to load your data.[[RED]] Retrying 5 times...
|
Profile.Loading.Success=[[GREEN]]Your mcMMO profile has been loaded.
|
||||||
Recovery.Success=[[GREEN]]Success! Your mcMMO data was loaded.
|
Profile.Loading.Failure=[[RED]]mcMMO still cannot load your data. You may want to [[AQUA]]contact the server owner.\n[[YELLOW]]You can still play on the server, but you will have [[BOLD]]no mcMMO levels[[YELLOW]] and any XP you get [[BOLD]]will not be saved[[YELLOW]].
|
||||||
Recovery.Failure=[[RED]]mcMMO still cannot load your data. You may want to [[AQUA]]contact the server owner.\n[[YELLOW]]You can still play on the server, but you will have [[BOLD]]no mcMMO levels[[YELLOW]] and any XP you get [[BOLD]]will not be saved[[YELLOW]].
|
Profile.Loading.AdminFailureNotice=[[DARK_RED]][A][[RED]] mcMMO was unable to load the player data for [[YELLOW]]{0}[[RED]]. [[LIGHT_PURPLE]]Please inspect your database setup.
|
||||||
Recovery.AdminFailureNotice=[[DARK_RED]][A][[RED]] mcMMO was unable to load the player data for [[YELLOW]]{0}[[RED]]. [[LIGHT_PURPLE]]Please inspect your database setup.
|
|
||||||
|
Loading…
Reference in New Issue
Block a user