fix: data save bug
This commit is contained in:
parent
8e32264087
commit
bcea10c9db
9 changed files with 73 additions and 44 deletions
|
@ -4,18 +4,23 @@
|
||||||
|
|
||||||
1.2.0-RC1: Update n°12 (XX/XX/25)
|
1.2.0-RC1: Update n°12 (XX/XX/25)
|
||||||
[FEATURES]
|
[FEATURES]
|
||||||
- Updated to support up to Minecraft 1.21.4.
|
- Updated to support Minecraft 1.21.5.
|
||||||
|
- Added a sub-command (/nicko about) to get information about Nicko.
|
||||||
- Modernized the messages and added various sound effects upon interacting with the plugin.
|
- Modernized the messages and added various sound effects upon interacting with the plugin.
|
||||||
- Made GUIs names cleaner.
|
- Cleaned up GUI titles.
|
||||||
|
|
||||||
[FIXES]
|
[FIXES]
|
||||||
- Cleaned up the codebase to prepare for future updates.
|
|
||||||
- Fixed an oversight preventing the configuration from properly being migrated.
|
- Fixed an oversight preventing the configuration from properly being migrated.
|
||||||
|
- Fixed a rare bug that could prevent data from being saved.
|
||||||
- Fixed the placeholder item in the skin cache invalidation not being translated.
|
- Fixed the placeholder item in the skin cache invalidation not being translated.
|
||||||
|
- Fixed a oversight about a column name using SQL storage.
|
||||||
|
|
||||||
[LANGUAGE]
|
[LANGUAGE]
|
||||||
- Moved the prefix to the language file.
|
- Moved the prefix to the language file.
|
||||||
|
|
||||||
|
[OTHER]
|
||||||
|
- Cleaned up the codebase to prepare for future updates.
|
||||||
|
|
||||||
1.1.7-RC1: Hotfix n°5 (04/05/24)
|
1.1.7-RC1: Hotfix n°5 (04/05/24)
|
||||||
[OTHER]
|
[OTHER]
|
||||||
- Restored download link again on spigotmc.org
|
- Restored download link again on spigotmc.org
|
||||||
|
|
|
@ -44,7 +44,7 @@ dependencies {
|
||||||
implementation("com.mysql:mysql-connector-j:9.2.0")
|
implementation("com.mysql:mysql-connector-j:9.2.0")
|
||||||
implementation("org.mariadb.jdbc:mariadb-java-client:3.5.2")
|
implementation("org.mariadb.jdbc:mariadb-java-client:3.5.2")
|
||||||
implementation("redis.clients:jedis:5.2.0")
|
implementation("redis.clients:jedis:5.2.0")
|
||||||
implementation("com.google.code.gson:gson:2.10.1")
|
implementation("com.google.code.gson:gson:2.13.1")
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks {
|
tasks {
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
package xyz.ineanto.nicko.appearance;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
public record Appearance(
|
||||||
|
@Nullable String name,
|
||||||
|
@Nullable String skin
|
||||||
|
) {}
|
|
@ -30,13 +30,13 @@ public class NickoCommand implements BasicCommand {
|
||||||
|
|
||||||
if (args.length >= 1 && args[0].equalsIgnoreCase("about")) {
|
if (args.length >= 1 && args[0].equalsIgnoreCase("about")) {
|
||||||
final Component firstAboutMessage = MiniMessage.miniMessage().deserialize(
|
final Component firstAboutMessage = MiniMessage.miniMessage().deserialize(
|
||||||
"<prefix> <gray>v<version></gray>",
|
"<prefix> <dark_gray>(© Ineanto 2023-2025) </dark_gray><gray>v<version></gray> ",
|
||||||
Placeholder.component("prefix", playerLanguage.getPrefixComponent()),
|
Placeholder.component("prefix", playerLanguage.getPrefixComponent()),
|
||||||
Placeholder.unparsed("version", Nicko.getInstance().getPluginMeta().getVersion())
|
Placeholder.unparsed("version", Nicko.getInstance().getPluginMeta().getVersion())
|
||||||
);
|
);
|
||||||
|
|
||||||
final Component secondAboutMessage = MiniMessage.miniMessage().deserialize(
|
final Component secondAboutMessage = MiniMessage.miniMessage().deserialize(
|
||||||
"<gradient:#01a97c:#8ffd54>Configuration</gradient> <gray>v<configversion></gray>, <gradient:#01a97c:#8ffd54>I18N</gradient> <gray>v<i18nversion></gray>",
|
"<gradient:#01a97c:#8ffd54>Configuration</gradient> <gray>v<configversion></gray>, <gradient:#01a97c:#8ffd54>I18N</gradient> <gray><i18nversion></gray>",
|
||||||
Placeholder.component("prefix", playerLanguage.getPrefixComponent()),
|
Placeholder.component("prefix", playerLanguage.getPrefixComponent()),
|
||||||
Placeholder.unparsed("configversion", Configuration.VERSION.toString()),
|
Placeholder.unparsed("configversion", Configuration.VERSION.toString()),
|
||||||
Placeholder.unparsed("i18nversion", Language.VERSION.toString())
|
Placeholder.unparsed("i18nversion", Language.VERSION.toString())
|
||||||
|
|
|
@ -2,28 +2,36 @@ package xyz.ineanto.nicko.profile;
|
||||||
|
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import xyz.ineanto.nicko.Nicko;
|
import xyz.ineanto.nicko.Nicko;
|
||||||
|
import xyz.ineanto.nicko.appearance.Appearance;
|
||||||
import xyz.ineanto.nicko.language.Language;
|
import xyz.ineanto.nicko.language.Language;
|
||||||
import xyz.ineanto.nicko.storage.PlayerDataStore;
|
import xyz.ineanto.nicko.storage.PlayerDataStore;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
public class NickoProfile implements Cloneable {
|
public class NickoProfile implements Cloneable {
|
||||||
public static final NickoProfile EMPTY_PROFILE = new NickoProfile(null, null, Language.ENGLISH, true);
|
public static final NickoProfile EMPTY_PROFILE = new NickoProfile(
|
||||||
|
new Appearance(null, null),
|
||||||
|
Language.ENGLISH,
|
||||||
|
true,
|
||||||
|
Collections.emptyList()
|
||||||
|
);
|
||||||
|
|
||||||
private static final Nicko instance = Nicko.getInstance();
|
private static final Nicko instance = Nicko.getInstance();
|
||||||
private static final PlayerDataStore dataStore = instance.getDataStore();
|
private static final PlayerDataStore dataStore = instance.getDataStore();
|
||||||
|
|
||||||
private String name;
|
private Appearance appearance;
|
||||||
private String skin;
|
|
||||||
private Language language;
|
private Language language;
|
||||||
private boolean randomSkin;
|
private boolean randomSkin;
|
||||||
|
private transient List<Appearance> favorites;
|
||||||
|
|
||||||
public NickoProfile(String name, String skin, Language language, boolean randomSkin) {
|
public NickoProfile(Appearance appearance, Language language, boolean randomSkin, List<Appearance> favorites) {
|
||||||
this.name = name;
|
this.appearance = appearance;
|
||||||
this.skin = skin;
|
|
||||||
this.language = language;
|
this.language = language;
|
||||||
this.randomSkin = randomSkin;
|
this.randomSkin = randomSkin;
|
||||||
|
this.favorites = favorites;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Optional<NickoProfile> get(Player player) {
|
public static Optional<NickoProfile> get(Player player) {
|
||||||
|
@ -35,23 +43,31 @@ public class NickoProfile implements Cloneable {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasData() {
|
public boolean hasData() {
|
||||||
return name != null || skin != null;
|
return appearance.name() != null || appearance.skin() != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return name;
|
return appearance.name();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setName(String name) {
|
public void setName(String name) {
|
||||||
this.name = name;
|
this.appearance = new Appearance(name, appearance.skin() == null ? null : appearance.skin());
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getSkin() {
|
public String getSkin() {
|
||||||
return skin;
|
return appearance.skin();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSkin(String skin) {
|
public void setSkin(String skin) {
|
||||||
this.skin = skin;
|
this.appearance = new Appearance(appearance.name() == null ? null : appearance.name(), skin);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Appearance> getFavorites() {
|
||||||
|
return favorites;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFavorites(List<Appearance> favorites) {
|
||||||
|
this.favorites = favorites;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Language getLocale() {
|
public Language getLocale() {
|
||||||
|
@ -70,16 +86,6 @@ public class NickoProfile implements Cloneable {
|
||||||
this.randomSkin = randomSkin;
|
this.randomSkin = randomSkin;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "NickoProfile{" +
|
|
||||||
"name='" + name + '\'' +
|
|
||||||
", skin='" + skin + '\'' +
|
|
||||||
", locale=" + language +
|
|
||||||
", randomSkin=" + randomSkin +
|
|
||||||
'}';
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NickoProfile clone() {
|
public NickoProfile clone() {
|
||||||
Object o;
|
Object o;
|
||||||
|
|
|
@ -46,6 +46,7 @@ public class JSONStorage extends Storage {
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
logger.warning("Could not create file.");
|
logger.warning("Could not create file.");
|
||||||
|
e.printStackTrace();
|
||||||
return ActionResult.error();
|
return ActionResult.error();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,14 +55,12 @@ public class JSONStorage extends Storage {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isStored(UUID uuid) {
|
public boolean isStored(UUID uuid) {
|
||||||
final File directory = new File(Nicko.getInstance().getDataFolder() + "/players/");
|
|
||||||
final File file = new File(directory, uuid.toString() + ".json");
|
final File file = new File(directory, uuid.toString() + ".json");
|
||||||
return file.exists();
|
return file.exists();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Optional<NickoProfile> retrieve(UUID uuid) {
|
public Optional<NickoProfile> retrieve(UUID uuid) {
|
||||||
final File directory = new File(Nicko.getInstance().getDataFolder() + "/players/");
|
|
||||||
final File file = new File(directory, uuid.toString() + ".json");
|
final File file = new File(directory, uuid.toString() + ".json");
|
||||||
try (FileReader fileReader = new FileReader(file)) {
|
try (FileReader fileReader = new FileReader(file)) {
|
||||||
try (BufferedReader reader = new BufferedReader(fileReader)) {
|
try (BufferedReader reader = new BufferedReader(fileReader)) {
|
||||||
|
@ -75,7 +74,6 @@ public class JSONStorage extends Storage {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ActionResult delete(UUID uuid) {
|
public ActionResult delete(UUID uuid) {
|
||||||
final File directory = new File(Nicko.getInstance().getDataFolder() + "/players/");
|
|
||||||
final File file = new File(directory, uuid.toString() + ".json");
|
final File file = new File(directory, uuid.toString() + ".json");
|
||||||
if (file.delete() || !file.exists()) {
|
if (file.delete() || !file.exists()) {
|
||||||
return ActionResult.ok();
|
return ActionResult.ok();
|
||||||
|
@ -84,6 +82,11 @@ public class JSONStorage extends Storage {
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean checkFileExists(File file) throws IOException {
|
private boolean checkFileExists(File file) throws IOException {
|
||||||
|
// Additional check if the folder gets deleted while the plugin is running.
|
||||||
|
if (!file.getParentFile().exists()) {
|
||||||
|
file.getParentFile().mkdirs();
|
||||||
|
}
|
||||||
|
|
||||||
if (!file.exists()) {
|
if (!file.exists()) {
|
||||||
return file.createNewFile();
|
return file.createNewFile();
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,11 +12,12 @@ public class JSONStorageProvider implements StorageProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean init()
|
public boolean init() {
|
||||||
{
|
|
||||||
return directory.exists() || directory.mkdirs();
|
return directory.exists() || directory.mkdirs();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean close() { return true; }
|
public boolean close() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package xyz.ineanto.nicko.storage.mariadb;
|
package xyz.ineanto.nicko.storage.mariadb;
|
||||||
|
|
||||||
import xyz.ineanto.nicko.appearance.ActionResult;
|
import xyz.ineanto.nicko.appearance.ActionResult;
|
||||||
|
import xyz.ineanto.nicko.appearance.Appearance;
|
||||||
import xyz.ineanto.nicko.config.Configuration;
|
import xyz.ineanto.nicko.config.Configuration;
|
||||||
import xyz.ineanto.nicko.language.Language;
|
import xyz.ineanto.nicko.language.Language;
|
||||||
import xyz.ineanto.nicko.profile.NickoProfile;
|
import xyz.ineanto.nicko.profile.NickoProfile;
|
||||||
|
@ -10,6 +11,7 @@ import java.sql.Connection;
|
||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
@ -83,15 +85,16 @@ public class MariaDBStorage extends Storage {
|
||||||
String name = "";
|
String name = "";
|
||||||
String skin = "";
|
String skin = "";
|
||||||
String locale = "";
|
String locale = "";
|
||||||
boolean bungeecord = false;
|
boolean randomSkin = false;
|
||||||
while (resultSet.next()) {
|
while (resultSet.next()) {
|
||||||
name = resultSet.getString("name");
|
name = resultSet.getString("name");
|
||||||
skin = resultSet.getString("skin");
|
skin = resultSet.getString("skin");
|
||||||
locale = resultSet.getString("locale");
|
locale = resultSet.getString("locale");
|
||||||
bungeecord = resultSet.getBoolean("bungeecord");
|
randomSkin = resultSet.getBoolean("randomskin");
|
||||||
}
|
}
|
||||||
|
|
||||||
final NickoProfile profile = new NickoProfile(name, skin, Language.fromCode(locale), bungeecord);
|
// TODO (Ineanto, 17/05/2025): Retrieve favorites
|
||||||
|
final NickoProfile profile = new NickoProfile(new Appearance(name, skin), Language.fromCode(locale), randomSkin, Collections.emptyList());
|
||||||
return Optional.of(profile);
|
return Optional.of(profile);
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
logger.warning("Couldn't fetch profile: " + e.getMessage());
|
logger.warning("Couldn't fetch profile: " + e.getMessage());
|
||||||
|
@ -117,7 +120,7 @@ public class MariaDBStorage extends Storage {
|
||||||
}
|
}
|
||||||
|
|
||||||
private PreparedStatement getInsertStatement(Connection connection, UUID uuid, NickoProfile profile) throws SQLException {
|
private PreparedStatement getInsertStatement(Connection connection, UUID uuid, NickoProfile profile) throws SQLException {
|
||||||
final String sql = "INSERT IGNORE INTO nicko.DATA (`uuid`, `name`, `skin`, `locale`, `bungeecord`) VALUES (?, ?, ?, ?, ?)";
|
final String sql = "INSERT IGNORE INTO nicko.DATA (`uuid`, `name`, `skin`, `locale`, `randomskin`) VALUES (?, ?, ?, ?, ?)";
|
||||||
final PreparedStatement statement = connection.prepareStatement(sql);
|
final PreparedStatement statement = connection.prepareStatement(sql);
|
||||||
statement.setString(1, uuid.toString());
|
statement.setString(1, uuid.toString());
|
||||||
statement.setString(2, profile.getName() == null ? null : profile.getName());
|
statement.setString(2, profile.getName() == null ? null : profile.getName());
|
||||||
|
@ -128,7 +131,7 @@ public class MariaDBStorage extends Storage {
|
||||||
}
|
}
|
||||||
|
|
||||||
private PreparedStatement getUpdateStatement(Connection connection, UUID uuid, NickoProfile profile) throws SQLException {
|
private PreparedStatement getUpdateStatement(Connection connection, UUID uuid, NickoProfile profile) throws SQLException {
|
||||||
final String sql = "UPDATE nicko.DATA SET name = ?, skin = ?, locale = ?, bungeecord = ? WHERE uuid = ?";
|
final String sql = "UPDATE nicko.DATA SET name = ?, skin = ?, locale = ?, randomskin = ? WHERE uuid = ?";
|
||||||
final PreparedStatement statement = connection.prepareStatement(sql);
|
final PreparedStatement statement = connection.prepareStatement(sql);
|
||||||
statement.setString(1, profile.getName() == null ? null : profile.getName());
|
statement.setString(1, profile.getName() == null ? null : profile.getName());
|
||||||
statement.setString(2, profile.getSkin() == null ? null : profile.getSkin());
|
statement.setString(2, profile.getSkin() == null ? null : profile.getSkin());
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package xyz.ineanto.nicko.storage.mysql;
|
package xyz.ineanto.nicko.storage.mysql;
|
||||||
|
|
||||||
import xyz.ineanto.nicko.appearance.ActionResult;
|
import xyz.ineanto.nicko.appearance.ActionResult;
|
||||||
|
import xyz.ineanto.nicko.appearance.Appearance;
|
||||||
import xyz.ineanto.nicko.config.Configuration;
|
import xyz.ineanto.nicko.config.Configuration;
|
||||||
import xyz.ineanto.nicko.language.Language;
|
import xyz.ineanto.nicko.language.Language;
|
||||||
import xyz.ineanto.nicko.profile.NickoProfile;
|
import xyz.ineanto.nicko.profile.NickoProfile;
|
||||||
|
@ -10,6 +11,7 @@ import java.sql.Connection;
|
||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
@ -83,15 +85,16 @@ public class MySQLStorage extends Storage {
|
||||||
String name = "";
|
String name = "";
|
||||||
String skin = "";
|
String skin = "";
|
||||||
String locale = "";
|
String locale = "";
|
||||||
boolean bungeecord = false;
|
boolean randomSkin = false;
|
||||||
while (resultSet.next()) {
|
while (resultSet.next()) {
|
||||||
name = resultSet.getString("name");
|
name = resultSet.getString("name");
|
||||||
skin = resultSet.getString("skin");
|
skin = resultSet.getString("skin");
|
||||||
locale = resultSet.getString("locale");
|
locale = resultSet.getString("locale");
|
||||||
bungeecord = resultSet.getBoolean("bungeecord");
|
randomSkin = resultSet.getBoolean("randomskin");
|
||||||
}
|
}
|
||||||
|
|
||||||
final NickoProfile profile = new NickoProfile(name, skin, Language.fromCode(locale), bungeecord);
|
// TODO (Ineanto, 17/05/2025): Retrieve favorites
|
||||||
|
final NickoProfile profile = new NickoProfile(new Appearance(name, skin), Language.fromCode(locale), randomSkin, Collections.emptyList());
|
||||||
return Optional.of(profile);
|
return Optional.of(profile);
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
logger.warning("Couldn't fetch profile: " + e.getMessage());
|
logger.warning("Couldn't fetch profile: " + e.getMessage());
|
||||||
|
@ -117,7 +120,7 @@ public class MySQLStorage extends Storage {
|
||||||
}
|
}
|
||||||
|
|
||||||
private PreparedStatement getInsertStatement(Connection connection, UUID uuid, NickoProfile profile) throws SQLException {
|
private PreparedStatement getInsertStatement(Connection connection, UUID uuid, NickoProfile profile) throws SQLException {
|
||||||
final String sql = "INSERT IGNORE INTO nicko.DATA (`uuid`, `name`, `skin`, `locale`, `bungeecord`) VALUES (?, ?, ?, ?, ?)";
|
final String sql = "INSERT IGNORE INTO nicko.DATA (`uuid`, `name`, `skin`, `locale`, `randomskin`) VALUES (?, ?, ?, ?, ?)";
|
||||||
final PreparedStatement statement = connection.prepareStatement(sql);
|
final PreparedStatement statement = connection.prepareStatement(sql);
|
||||||
statement.setString(1, uuid.toString());
|
statement.setString(1, uuid.toString());
|
||||||
statement.setString(2, profile.getName() == null ? null : profile.getName());
|
statement.setString(2, profile.getName() == null ? null : profile.getName());
|
||||||
|
@ -128,7 +131,7 @@ public class MySQLStorage extends Storage {
|
||||||
}
|
}
|
||||||
|
|
||||||
private PreparedStatement getUpdateStatement(Connection connection, UUID uuid, NickoProfile profile) throws SQLException {
|
private PreparedStatement getUpdateStatement(Connection connection, UUID uuid, NickoProfile profile) throws SQLException {
|
||||||
final String sql = "UPDATE nicko.DATA SET name = ?, skin = ?, locale = ?, bungeecord = ? WHERE uuid = ?";
|
final String sql = "UPDATE nicko.DATA SET name = ?, skin = ?, locale = ?, randomskin = ? WHERE uuid = ?";
|
||||||
final PreparedStatement statement = connection.prepareStatement(sql);
|
final PreparedStatement statement = connection.prepareStatement(sql);
|
||||||
statement.setString(1, profile.getName() == null ? null : profile.getName());
|
statement.setString(1, profile.getName() == null ? null : profile.getName());
|
||||||
statement.setString(2, profile.getSkin() == null ? null : profile.getSkin());
|
statement.setString(2, profile.getSkin() == null ? null : profile.getSkin());
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue