feat: compartmentalization

This commit is contained in:
ineanto 2023-08-19 14:59:11 +02:00
parent b64f56a0bb
commit e471d86801
18 changed files with 300 additions and 267 deletions

View file

@ -11,20 +11,28 @@ import xyz.atnrch.nicko.appearance.AppearanceManager;
import xyz.atnrch.nicko.i18n.I18N;
import xyz.atnrch.nicko.i18n.I18NDict;
import xyz.atnrch.nicko.mojang.MojangUtils;
import xyz.atnrch.nicko.profile.AppearanceData;
import xyz.atnrch.nicko.profile.NickoProfile;
import xyz.atnrch.nicko.storage.PlayerDataStore;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
public class AnvilManager {
private final Player player;
private final AppearanceManager appearanceManager;
private final PlayerDataStore dataStore;
private final AppearanceData appearanceData;
private final PlayerDataStore dataStore = NickoBukkit.getInstance().getDataStore();
private final NickoProfile profile;
public AnvilManager(Player player) {
this.player = player;
this.appearanceManager = AppearanceManager.get(player);
this.dataStore = NickoBukkit.getInstance().getDataStore();
final Optional<NickoProfile> optionalProfile = dataStore.getData(player.getUniqueId());
this.profile = optionalProfile.orElse(NickoProfile.EMPTY_PROFILE.clone());
this.appearanceManager = optionalProfile.map(NickoProfile::getAppearanceManager).orElse(null);
this.appearanceData = optionalProfile.map(NickoProfile::getAppearanceData).orElse(null);
}
public void openNameThenSkinAnvil() {
@ -49,8 +57,8 @@ public class AnvilManager {
if (MojangUtils.isUsernameInvalid(snapshot.getText())) {
return Collections.singletonList(AnvilGUI.ResponseAction.replaceInputText("Invalid username!"));
} else {
appearanceManager.setName(snapshot.getText());
dataStore.updateCache(player.getUniqueId(), appearanceManager.getProfile());
appearanceData.setName(snapshot.getText());
dataStore.updateCache(player.getUniqueId(), profile);
openSkinAnvil();
return Collections.singletonList(AnvilGUI.ResponseAction.close());
}
@ -70,8 +78,8 @@ public class AnvilManager {
if (MojangUtils.isUsernameInvalid(snapshot.getText())) {
return Collections.singletonList(AnvilGUI.ResponseAction.replaceInputText("Invalid username!"));
} else {
appearanceManager.setName(snapshot.getText());
dataStore.updateCache(player.getUniqueId(), appearanceManager.getProfile());
appearanceData.setName(snapshot.getText());
dataStore.updateCache(player.getUniqueId(), profile);
final ActionResult actionResult = appearanceManager.updatePlayer(false, false);
return sendResultAndClose(actionResult);
}
@ -91,8 +99,8 @@ public class AnvilManager {
if (MojangUtils.isUsernameInvalid(snapshot.getText())) {
return Collections.singletonList(AnvilGUI.ResponseAction.replaceInputText("Invalid username!"));
} else {
appearanceManager.setSkin(snapshot.getText());
dataStore.updateCache(player.getUniqueId(), appearanceManager.getProfile());
appearanceData.setSkin(snapshot.getText());
dataStore.updateCache(player.getUniqueId(), profile);
final ActionResult actionResult = appearanceManager.updatePlayer(true, false);
return sendResultAndClose(actionResult);
}

View file

@ -11,9 +11,9 @@ import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerTeleportEvent;
import xyz.atnrch.nicko.NickoBukkit;
import xyz.atnrch.nicko.i18n.I18NDict;
import xyz.atnrch.nicko.i18n.Locale;
import xyz.atnrch.nicko.mojang.MojangAPI;
import xyz.atnrch.nicko.mojang.MojangSkin;
import xyz.atnrch.nicko.profile.AppearanceData;
import xyz.atnrch.nicko.profile.NickoProfile;
import xyz.atnrch.nicko.storage.PlayerDataStore;
import xyz.atnrch.nicko.storage.name.PlayerNameStore;
@ -26,93 +26,45 @@ import java.util.UUID;
import java.util.concurrent.ExecutionException;
public class AppearanceManager {
private final NickoProfile profile;
private final Player player;
private final UUID uuid;
private final NickoBukkit instance = NickoBukkit.getInstance();
private final PlayerDataStore dataStore = instance.getDataStore();
private final PlayerNameStore nameStore = instance.getNameStore();
private AppearanceManager(UUID uuid) {
this.player = Bukkit.getPlayer(uuid);
this.uuid = uuid;
this.profile = dataStore.getData(uuid).orElse(NickoProfile.EMPTY_PROFILE.clone());
}
private final NickoProfile profile;
private final AppearanceData appearanceData;
private final Player player;
private final UUID uuid;
private AppearanceManager(String name) {
this.player = null;
this.uuid = null;
this.profile = dataStore.getOfflineData(name).orElse(NickoProfile.EMPTY_PROFILE.clone());
}
public AppearanceManager(Player player) {
this.uuid = player.getUniqueId();
this.player = player;
public static AppearanceManager get(Player player) {
return new AppearanceManager(player.getUniqueId());
}
public static AppearanceManager get(String name) {
return new AppearanceManager(name);
}
public boolean hasData() {
return !profile.isEmpty();
}
public void setSkin(String skin) {
profile.setSkin(skin);
dataStore.getCache().cache(uuid, profile);
}
public String getSkin() {
return profile.getSkin();
}
public boolean needsASkinChange() {
return profile.getSkin() != null && !profile.getSkin().equals(player.getName());
}
public void setName(String name) {
profile.setName(name);
dataStore.getCache().cache(uuid, profile);
}
public String getName() {
return profile.getName();
}
public void setLocale(Locale locale) {
profile.setLocale(locale);
dataStore.getCache().cache(uuid, profile);
}
public Locale getLocale() {
return profile.getLocale();
}
public NickoProfile getProfile() {
return profile;
}
public void setNameAndSkin(String name, String skin) {
this.profile.setName(name);
this.profile.setSkin(skin);
dataStore.getCache().cache(uuid, profile);
final Optional<NickoProfile> optionalProfile = dataStore.getData(player.getUniqueId());
if (!optionalProfile.isPresent()) {
this.profile = NickoProfile.EMPTY_PROFILE.clone();
this.appearanceData = profile.getAppearanceData();
instance.getLogger().warning("Unable to appearance data for: " + player.getUniqueId() + ".");
} else {
this.profile = optionalProfile.get();
this.appearanceData = profile.getAppearanceData();
}
}
public ActionResult reset() {
final String defaultName = nameStore.getStoredName(player);
this.profile.setName(defaultName);
this.profile.setSkin(defaultName);
appearanceData.setName(defaultName);
appearanceData.setSkin(defaultName);
final ActionResult actionResult = updatePlayer(true, true);
if (!actionResult.isError()) {
this.profile.setSkin(null);
this.profile.setName(null);
appearanceData.setSkin(null);
appearanceData.setName(null);
dataStore.getCache().cache(uuid, profile);
}
return actionResult;
}
public ActionResult updatePlayer(boolean skinChange, boolean reset) {
final String displayName = profile.getName() == null ? player.getName() : profile.getName();
final String displayName = appearanceData.getName() == null ? player.getName() : appearanceData.getName();
final WrappedGameProfile gameProfile = WrappedGameProfile.fromPlayer(player).withName(displayName);
final ActionResult result = updateGameProfileSkin(gameProfile, skinChange, reset);
if (!result.isError()) {
@ -139,15 +91,15 @@ public class AppearanceManager {
private ActionResult updateGameProfileSkin(WrappedGameProfile gameProfile, boolean skinChange, boolean reset) {
final boolean changeOnlyName = profile.getSkin() != null && !profile.getSkin().equalsIgnoreCase(player.getName());
final boolean changeOnlyName = appearanceData.getSkin() != null && !appearanceData.getSkin().equalsIgnoreCase(player.getName());
if (skinChange || changeOnlyName) {
Optional<MojangSkin> skin;
try {
final MojangAPI mojang = NickoBukkit.getInstance().getMojangAPI();
final Optional<String> uuid = mojang.getUUID(profile.getSkin());
final MojangAPI mojangAPI = NickoBukkit.getInstance().getMojangAPI();
final Optional<String> uuid = mojangAPI.getUUID(appearanceData.getSkin());
if (uuid.isPresent()) {
skin = reset ? mojang.getSkinWithoutCaching(uuid.get()) : mojang.getSkin(uuid.get());
skin = reset ? mojangAPI.getSkinWithoutCaching(uuid.get()) : mojangAPI.getSkin(uuid.get());
if (skin.isPresent()) {
final MojangSkin skinResult = skin.get();
final Multimap<String, WrappedSignedProperty> properties = gameProfile.getProperties();
@ -187,7 +139,7 @@ public class AppearanceManager {
respawn.sendPacket(player);
player.setFlying(wasFlying);
player.teleport(player.getLocation(), PlayerTeleportEvent.TeleportCause.PLUGIN);
player.updateInventory();
player.updateInventory(); // Marked as unstable.
}
@SuppressWarnings("deprecation")

View file

@ -1,8 +1,7 @@
package xyz.atnrch.nicko.command;
import org.jetbrains.annotations.NotNull;
import xyz.atnrch.nicko.NickoBukkit;
import xyz.atnrch.nicko.command.sub.NickoCheckSubCmd;
import xyz.atnrch.nicko.command.sub.NickoDebugSubCmd;
import xyz.atnrch.nicko.gui.HomeGUI;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
@ -17,25 +16,19 @@ public class NickoCommand implements CommandExecutor {
"§6/nicko help §f- §7Print this help message.\n";
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) {
if (sender instanceof Player) {
final Player player = (Player) sender;
if (args.length >= 1) {
switch (args[0]) {
case "debug":
new NickoDebugSubCmd().execute(player, args);
break;
case "check":
new NickoCheckSubCmd().execute(player, args);
break;
default:
sendHelpMessage(sender);
break;
if (args[0].equals("debug")) {
new NickoDebugCmd().execute(player, args);
} else {
sendHelpMessage(sender);
}
return false;
}
if(player.isOp() || player.hasPermission("nicko.use") || player.hasPermission("nicko.*")) {
if (player.isOp() || player.hasPermission("nicko.use") || player.hasPermission("nicko.*")) {
new HomeGUI(player).open();
} else {
final I18N i18N = new I18N(player);

View file

@ -1,21 +1,27 @@
package xyz.atnrch.nicko.command.sub;
package xyz.atnrch.nicko.command;
import org.bukkit.Bukkit;
import org.bukkit.Sound;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import xyz.atnrch.nicko.NickoBukkit;
import xyz.atnrch.nicko.appearance.ActionResult;
import xyz.atnrch.nicko.appearance.AppearanceManager;
import xyz.atnrch.nicko.i18n.I18N;
import xyz.atnrch.nicko.mojang.MojangUtils;
import org.bukkit.Bukkit;
import org.bukkit.Sound;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import xyz.atnrch.nicko.profile.AppearanceData;
import xyz.atnrch.nicko.profile.NickoProfile;
import xyz.atnrch.nicko.storage.PlayerDataStore;
public class NickoDebugSubCmd {
import java.util.Optional;
public class NickoDebugCmd {
public void execute(CommandSender sender, String[] args) {
final String prefix = NickoBukkit.getInstance().getNickoConfig().getPrefix();
Player target;
String name, skin;
String playerName = null;
if (args.length == 3) {
target = (Player) sender;
name = args[1];
@ -26,7 +32,7 @@ public class NickoDebugSubCmd {
return;
}
final String playerName = args[1];
playerName = args[1];
name = args[2];
skin = args[3];
@ -47,15 +53,25 @@ public class NickoDebugSubCmd {
return;
}
final AppearanceManager appearanceManager = AppearanceManager.get(target.getPlayer());
appearanceManager.setNameAndSkin(name, skin);
final ActionResult result = appearanceManager.updatePlayer(true, false);
if (!result.isError()) {
target.sendMessage(prefix + "§aWhoosh!");
target.playSound(target.getLocation(), Sound.ENTITY_ITEM_FRAME_PLACE, 1, 1);
} else {
final I18N i18n = new I18N(target);
target.sendMessage(prefix + "§cWhoops. Something happened: " + i18n.translatePrefixless(result.getErrorKey()));
final Optional<NickoProfile> optionalProfile = NickoProfile.get(target);
if (optionalProfile.isPresent()) {
final NickoProfile profile = optionalProfile.get();
final PlayerDataStore dataStore = NickoBukkit.getInstance().getDataStore();
final AppearanceData appearanceData = profile.getAppearanceData();
final AppearanceManager appearanceManager = profile.getAppearanceManager();
appearanceData.setName(name);
appearanceData.setSkin(skin);
dataStore.updateCache(target.getUniqueId(), profile);
final ActionResult result = appearanceManager.updatePlayer(true, false);
if (!result.isError()) {
target.sendMessage(prefix + "§aWhoosh!");
target.playSound(target.getLocation(), Sound.ENTITY_ITEM_FRAME_PLACE, 1, 1);
} else {
final I18N i18n = new I18N(target);
target.sendMessage(prefix + "§cWhoops. Something happened: " + i18n.translatePrefixless(result.getErrorKey()));
}
}
}
}

View file

@ -1,44 +0,0 @@
package xyz.atnrch.nicko.command.sub;
import xyz.atnrch.nicko.NickoBukkit;
import xyz.atnrch.nicko.appearance.AppearanceManager;
import xyz.atnrch.nicko.i18n.I18N;
import xyz.atnrch.nicko.i18n.I18NDict;
import xyz.atnrch.nicko.mojang.MojangUtils;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import java.util.StringJoiner;
public class NickoCheckSubCmd {
public void execute(Player player, String[] args) {
final String targetName = args[1];
final Player target = Bukkit.getPlayerExact(targetName);
final I18N i18n = new I18N(player);
AppearanceManager appearanceManager;
if (MojangUtils.isUsernameInvalid(targetName)) {
player.sendMessage(i18n.translate(I18NDict.Error.INVALID_USERNAME));
return;
}
if (target == null) {
appearanceManager = AppearanceManager.get(targetName);
} else {
appearanceManager = AppearanceManager.get(target);
}
final StringJoiner builder = new StringJoiner("\n");
builder.add("§c" + NickoBukkit.getInstance().getNickoConfig().getPrefix() + "§cCheck for: §f§o" + targetName);
if (appearanceManager.hasData()) {
builder.add("§cNicked: §a✔");
builder.add("§cName: §6" + appearanceManager.getName());
builder.add("§cSkin: §6" + appearanceManager.getSkin());
} else {
builder.add("§cNicked: §c❌");
builder.add("§cName: §7N/A");
builder.add("§cSkin: §7N/A");
}
player.sendMessage(builder.toString());
}
}

View file

@ -10,8 +10,12 @@ import xyz.atnrch.nicko.appearance.ActionResult;
import xyz.atnrch.nicko.appearance.AppearanceManager;
import xyz.atnrch.nicko.i18n.I18N;
import xyz.atnrch.nicko.i18n.I18NDict;
import xyz.atnrch.nicko.profile.NickoProfile;
import xyz.atnrch.nicko.storage.PlayerDataStore;
import xyz.atnrch.nicko.storage.name.PlayerNameStore;
import java.util.Optional;
public class PlayerJoinListener implements Listener {
@EventHandler
public void onPlayerJoin(PlayerJoinEvent event) {
@ -19,20 +23,25 @@ public class PlayerJoinListener implements Listener {
final NickoBukkit instance = NickoBukkit.getInstance();
final I18N i18n = new I18N(player);
final PlayerNameStore nameStore = instance.getNameStore();
final PlayerDataStore dataStore = instance.getDataStore();
// TODO: 2/20/23 Fetch data from BungeeCord
nameStore.storeName(player);
Bukkit.getScheduler().runTaskLater(instance, () -> {
final AppearanceManager appearanceManager = AppearanceManager.get(player);
if (appearanceManager.hasData()) {
final ActionResult actionResult = appearanceManager.updatePlayer(appearanceManager.needsASkinChange(), false);
if (!actionResult.isError()) {
player.sendMessage(i18n.translate(I18NDict.Event.Appearance.Restore.OK));
} else {
player.sendMessage(i18n.translate(I18NDict.Event.Appearance.Restore.ERROR, i18n.translatePrefixless(actionResult.getErrorKey())));
final Optional<NickoProfile> optionalProfile = dataStore.getData(player.getUniqueId());
optionalProfile.map(NickoProfile::getAppearanceData).ifPresent(appearanceData -> {
final AppearanceManager appearanceManager = new AppearanceManager(player);
if (!appearanceData.isEmpty()) {
final boolean needsASkinChange = appearanceData.getSkin() != null && !appearanceData.getSkin().equals(player.getName());
final ActionResult actionResult = appearanceManager.updatePlayer(needsASkinChange, false);
if (!actionResult.isError()) {
player.sendMessage(i18n.translate(I18NDict.Event.Appearance.Restore.OK));
} else {
player.sendMessage(i18n.translate(I18NDict.Event.Appearance.Restore.ERROR, i18n.translatePrefixless(actionResult.getErrorKey())));
}
}
}
});
}, 20L);
System.out.println("i18n.getPlayerLocale().getCode() = " + i18n.getPlayerLocale().getCode());
}
}

View file

@ -4,12 +4,15 @@ import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import xyz.atnrch.nicko.NickoBukkit;
import xyz.atnrch.nicko.appearance.AppearanceManager;
import xyz.atnrch.nicko.mojang.MojangAPI;
import xyz.atnrch.nicko.profile.AppearanceData;
import xyz.atnrch.nicko.profile.NickoProfile;
import xyz.atnrch.nicko.storage.PlayerDataStore;
import xyz.xenondevs.invui.item.builder.ItemBuilder;
import xyz.xenondevs.invui.item.builder.SkullBuilder;
import xyz.xenondevs.invui.item.impl.AsyncItem;
import java.util.Optional;
import java.util.UUID;
public class PlayerInformationItem extends AsyncItem {
@ -19,23 +22,28 @@ public class PlayerInformationItem extends AsyncItem {
super(new ItemBuilder(Material.PAINTING).setDisplayName("§7§oLoading..."), () -> {
final Player player = Bukkit.getPlayer(uuid);
final SkullBuilder skull = new SkullBuilder(uuid);
final PlayerDataStore dataStore = NickoBukkit.getInstance().getDataStore();
final Optional<NickoProfile> optionalProfile = dataStore.getData(uuid);
final AppearanceManager appearanceManager = AppearanceManager.get(player);
if (appearanceManager.hasData()) {
skull.addLoreLines(
"§cNicked: §a✔",
"§cName: §6" + appearanceManager.getName(),
"§cSkin: §6" + appearanceManager.getSkin()
);
} else {
skull.addLoreLines(
"§cNicked: §c❌",
"§cName: §7N/A",
"§cSkin: §7N/A"
);
}
optionalProfile.ifPresent(profile -> {
final AppearanceData appearanceData = profile.getAppearanceData();
if (!appearanceData.isEmpty()) {
skull.addLoreLines(
"§cNicked: §a✔",
"§cName: §6" + appearanceData.getName(),
"§cSkin: §6" + appearanceData.getSkin()
);
} else {
skull.addLoreLines(
"§cNicked: §c❌",
"§cName: §7N/A",
"§cSkin: §7N/A"
);
}
skull.setDisplayName("§6" + player.getName());
});
skull.setDisplayName("§6" + player.getName());
return skull;
});
}

View file

@ -1,14 +1,17 @@
package xyz.atnrch.nicko.gui.items.home;
import xyz.atnrch.nicko.appearance.AppearanceManager;
import xyz.atnrch.nicko.i18n.I18N;
import xyz.atnrch.nicko.i18n.I18NDict;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import xyz.atnrch.nicko.i18n.I18N;
import xyz.atnrch.nicko.i18n.I18NDict;
import xyz.atnrch.nicko.profile.NickoProfile;
import xyz.xenondevs.invui.item.builder.ItemBuilder;
import xyz.xenondevs.invui.item.impl.SuppliedItem;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicBoolean;
public class ResetItem extends SuppliedItem {
public ResetItem() {
super(() -> {
@ -22,21 +25,24 @@ public class ResetItem extends SuppliedItem {
final ClickType clickType = event.getClickType();
if (clickType.isLeftClick() || clickType.isRightClick()) {
final AppearanceManager appearanceManager = AppearanceManager.get(player);
final Optional<NickoProfile> optionalProfile = NickoProfile.get(player);
final AtomicBoolean result = new AtomicBoolean(false);
optionalProfile.ifPresent(profile -> {
if (profile.getAppearanceData().isEmpty()) {
player.sendMessage(i18n.translate(I18NDict.Event.Appearance.Remove.MISSING));
event.getEvent().getView().close();
result.set(true);
}
if (!appearanceManager.hasData()) {
player.sendMessage(i18n.translate(I18NDict.Event.Appearance.Remove.MISSING));
event.getEvent().getView().close();
return true;
}
if (!appearanceManager.reset().isError()) {
player.sendMessage(i18n.translate(I18NDict.Event.Appearance.Remove.OK));
return true;
} else {
player.sendMessage(i18n.translate(I18NDict.Event.Appearance.Remove.ERROR));
return false;
}
if (!profile.getAppearanceManager().reset().isError()) {
player.sendMessage(i18n.translate(I18NDict.Event.Appearance.Remove.OK));
result.set(false);
} else {
player.sendMessage(i18n.translate(I18NDict.Event.Appearance.Remove.ERROR));
result.set(true);
}
});
return result.get();
}
return false;
});

View file

@ -8,6 +8,7 @@ import xyz.atnrch.nicko.i18n.I18N;
import xyz.atnrch.nicko.i18n.I18NDict;
import xyz.atnrch.nicko.i18n.ItemTranslation;
import xyz.atnrch.nicko.profile.NickoProfile;
import xyz.atnrch.nicko.storage.PlayerDataStore;
import xyz.xenondevs.invui.item.ItemProvider;
import xyz.xenondevs.invui.item.builder.ItemBuilder;
import xyz.xenondevs.invui.item.impl.AbstractItem;
@ -31,12 +32,14 @@ public class BungeeCordCyclingItem {
}
public AbstractItem get() {
final Optional<NickoProfile> profile = NickoBukkit.getInstance().getDataStore().getData(player.getUniqueId());
final PlayerDataStore dataStore = NickoBukkit.getInstance().getDataStore();
final Optional<NickoProfile> profile = dataStore.getData(player.getUniqueId());
if (profile.isPresent()) {
final NickoProfile nickoProfile = profile.get();
int startingState = nickoProfile.isBungeecordTransfer() ? 0 : 1;
return CycleItem.withStateChangeHandler((observer, integer) -> {
nickoProfile.setBungeecordTransfer(integer != 1);
dataStore.updateCache(player.getUniqueId(), nickoProfile);
observer.playSound(player, Sound.UI_BUTTON_CLICK, 1f, 0.707107f); // 0.707107 ~= C
}, startingState, providers);
}

View file

@ -1,5 +1,6 @@
package xyz.atnrch.nicko.gui.items.settings;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.entity.Player;
@ -29,6 +30,7 @@ public class LanguageCyclingItem {
public LanguageCyclingItem(Player player) {
this.player = player;
this.i18n = new I18N(player);
Bukkit.broadcastMessage(i18n.getPlayerLocale().getCode());
this.providers = getItems();
}

View file

@ -3,12 +3,13 @@ package xyz.atnrch.nicko.i18n;
import com.github.jsixface.YamlConfig;
import org.bukkit.entity.Player;
import xyz.atnrch.nicko.NickoBukkit;
import xyz.atnrch.nicko.appearance.AppearanceManager;
import xyz.atnrch.nicko.profile.NickoProfile;
import java.io.InputStream;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Optional;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@ -126,11 +127,10 @@ public class I18N {
}
public Locale getPlayerLocale() {
try {
final AppearanceManager appearanceManager = AppearanceManager.get(player);
return !appearanceManager.hasData() ? Locale.FALLBACK_LOCALE : appearanceManager.getLocale();
} catch (IllegalArgumentException exception) {
instance.getLogger().severe("Invalid locale provided by " + player.getName() + ", defaulting to " + Locale.FALLBACK_LOCALE.getCode() + ".");
final Optional<NickoProfile> optionalProfile = NickoProfile.get(player);
if (optionalProfile.isPresent()) {
return optionalProfile.get().getLocale();
} else {
return Locale.FALLBACK_LOCALE;
}
}

View file

@ -2,14 +2,17 @@ package xyz.atnrch.nicko.i18n;
public class I18NDict {
public static class Error {
public static final String GENERIC = "error.generic";
public static final String PERMISSION = "error.permission";
public static final String CACHE = "error.cache";
public static final String MOJANG_NAME = "error.mojang_name";
public static final String MOJANG_SKIN = "error.mojang_skin";
public static final String INVALID_USERNAME = "error.invalid_username";
public static final String SQL_ERROR = "error.sql";
public static final String JSON_ERROR = "error.json";
public static final String ERROR_KEY = "error.";
public static final String GENERIC = ERROR_KEY + "generic";
public static final String PERMISSION = ERROR_KEY + "permission";
public static final String CACHE = ERROR_KEY + "cache";
public static final String MOJANG_NAME = ERROR_KEY + "mojang_name";
public static final String MOJANG_SKIN = ERROR_KEY + "mojang_skin";
@Deprecated
public static final String INVALID_USERNAME = ERROR_KEY + "invalid_username";
public static final String SQL_ERROR = ERROR_KEY + "sql";
public static final String JSON_ERROR = ERROR_KEY + "json";
}
public static class Event {

View file

@ -5,6 +5,7 @@ import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import xyz.atnrch.nicko.NickoBukkit;
import xyz.atnrch.nicko.profile.AppearanceData;
import xyz.atnrch.nicko.profile.NickoProfile;
import java.util.Optional;
@ -51,20 +52,26 @@ public class NickoExpansion extends PlaceholderExpansion {
final Optional<NickoProfile> optionalProfile = instance.getDataStore().getData(player.getUniqueId());
if (optionalProfile.isPresent()) {
final NickoProfile profile = optionalProfile.get();
if (!profile.isEmpty()) {
name = profile.getName();
skin = profile.getSkin();
final AppearanceData appearanceData = profile.getAppearanceData();
if (!appearanceData.isEmpty()) {
name = appearanceData.getName();
skin = appearanceData.getSkin();
}
locale = profile.getLocale().getName();
bungeecord = profile.isBungeecordTransfer();
}
switch (params) {
case "name": return name;
case "skin": return skin;
case "locale": return locale;
case "bungeecord": return String.valueOf(bungeecord);
default: return null;
case "name":
return name;
case "skin":
return skin;
case "locale":
return locale;
case "bungeecord":
return String.valueOf(bungeecord);
default:
return null;
}
}
}

View file

@ -0,0 +1,31 @@
package xyz.atnrch.nicko.profile;
public class AppearanceData {
private String name;
private String skin;
public AppearanceData(String name, String skin) {
this.name = name;
this.skin = skin;
}
public boolean isEmpty() {
return name == null && skin == null;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSkin() {
return skin;
}
public void setSkin(String skin) {
this.skin = skin;
}
}

View file

@ -1,45 +1,70 @@
package xyz.atnrch.nicko.profile;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import xyz.atnrch.nicko.NickoBukkit;
import xyz.atnrch.nicko.appearance.AppearanceManager;
import xyz.atnrch.nicko.i18n.Locale;
import xyz.atnrch.nicko.storage.PlayerDataStore;
import java.util.Optional;
import java.util.UUID;
public class NickoProfile implements Cloneable {
public static final NickoProfile EMPTY_PROFILE = new NickoProfile(null, null, Locale.ENGLISH, true);
public static final PlayerDataStore dataStore = NickoBukkit.getInstance().getDataStore();
public static final NickoProfile EMPTY_PROFILE = new NickoProfile(new AppearanceData(null, null), Locale.ENGLISH, true);
private String name;
private String skin;
private final AppearanceData appearanceData;
private final Player player;
private Locale locale;
private boolean bungeecordTransfer;
public NickoProfile(String name, String skin, Locale locale, boolean bungeecordTransfer) {
this.name = name;
this.skin = skin;
public NickoProfile(AppearanceData appearanceData, Locale locale, boolean bungeecordTransfer) {
this.appearanceData = appearanceData;
this.locale = locale;
this.bungeecordTransfer = bungeecordTransfer;
this.player = null;
}
public NickoProfile(Player player, AppearanceData appearanceData, Locale locale, boolean bungeecordTransfer) {
this.player = player;
this.appearanceData = appearanceData;
this.locale = locale;
this.bungeecordTransfer = bungeecordTransfer;
}
public boolean isEmpty() {
return name == null && skin == null;
public NickoProfile(UUID uuid, AppearanceData appearanceData, Locale locale, boolean bungeecordTransfer) {
this.appearanceData = appearanceData;
this.locale = locale;
this.bungeecordTransfer = bungeecordTransfer;
this.player = Bukkit.getPlayer(uuid);
}
public String getName() {
return name;
public static Optional<NickoProfile> get(Player player) {
return dataStore.getData(player.getUniqueId());
}
public void setName(String name) {
this.name = name;
public static Optional<NickoProfile> get(UUID uuid) {
return dataStore.getData(uuid);
}
public String getSkin() {
return skin;
public AppearanceManager getAppearanceManager() {
if (player == null) return null;
return new AppearanceManager(player);
}
public void setSkin(String skin) {
this.skin = skin;
public AppearanceData getAppearanceData() {
return appearanceData;
}
public Locale getLocale() { return locale; }
public Locale getLocale() {
return locale;
}
public void setLocale(Locale locale) {
this.locale = locale;
}
public void setLocale(Locale locale) { this.locale = locale; }
public boolean isBungeecordTransfer() {
return bungeecordTransfer;
@ -52,11 +77,11 @@ public class NickoProfile implements Cloneable {
@Override
public String toString() {
return "NickoProfile{" +
"name='" + name + '\'' +
", skin='" + skin + '\'' +
", locale=" + locale +
", bungeecordTransfer=" + bungeecordTransfer +
'}';
"name='" + appearanceData.getName() + '\'' +
", skin='" + appearanceData.getSkin() + '\'' +
", locale=" + locale +
", bungeecordTransfer=" + bungeecordTransfer +
'}';
}
@Override

View file

@ -4,6 +4,7 @@ import xyz.atnrch.nicko.appearance.ActionResult;
import xyz.atnrch.nicko.config.Configuration;
import xyz.atnrch.nicko.i18n.I18NDict;
import xyz.atnrch.nicko.i18n.Locale;
import xyz.atnrch.nicko.profile.AppearanceData;
import xyz.atnrch.nicko.profile.NickoProfile;
import xyz.atnrch.nicko.storage.Storage;
@ -95,7 +96,7 @@ public class SQLStorage extends Storage {
System.out.println("skin = " + skin);
System.out.println("locale = " + locale);
final NickoProfile profile = new NickoProfile(name, skin, Locale.fromCode(locale), bungeecord);
final NickoProfile profile = new NickoProfile(new AppearanceData(name, skin), Locale.fromCode(locale), bungeecord);
return Optional.of(profile);
} catch (SQLException e) {
logger.warning("Couldn't fetch profile: " + e.getMessage());
@ -123,9 +124,10 @@ public class SQLStorage extends Storage {
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 PreparedStatement statement = connection.prepareStatement(sql);
final AppearanceData appearanceData = profile.getAppearanceData();
statement.setString(1, uuid.toString());
statement.setString(2, profile.getName() == null ? null : profile.getName());
statement.setString(3, profile.getSkin() == null ? null : profile.getSkin());
statement.setString(2, appearanceData.getName() == null ? null : appearanceData.getName());
statement.setString(3, appearanceData.getSkin() == null ? null : appearanceData.getSkin());
statement.setString(4, profile.getLocale().getCode());
statement.setBoolean(5, profile.isBungeecordTransfer());
return statement;
@ -134,8 +136,9 @@ public class SQLStorage extends Storage {
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 PreparedStatement statement = connection.prepareStatement(sql);
statement.setString(1, profile.getName() == null ? null : profile.getName());
statement.setString(2, profile.getSkin() == null ? null : profile.getSkin());
final AppearanceData appearanceData = profile.getAppearanceData();
statement.setString(1, appearanceData.getName() == null ? null : appearanceData.getName());
statement.setString(2, appearanceData.getSkin() == null ? null : appearanceData.getSkin());
statement.setString(3, profile.getLocale().getCode());
statement.setBoolean(4, profile.isBungeecordTransfer());
statement.setString(5, uuid.toString());

View file

@ -7,6 +7,7 @@ import xyz.atnrch.nicko.appearance.ActionResult;
import xyz.atnrch.nicko.config.Configuration;
import xyz.atnrch.nicko.config.DataSourceConfiguration;
import xyz.atnrch.nicko.i18n.Locale;
import xyz.atnrch.nicko.profile.AppearanceData;
import xyz.atnrch.nicko.profile.NickoProfile;
import xyz.atnrch.nicko.storage.PlayerDataStore;
@ -46,7 +47,7 @@ public class SQLStorageTest {
@DisplayName("Store empty profile")
@Order(2)
public void storeEmptyProfile() {
final Optional<NickoProfile> optionalProfile = dataStore.getData(uuid);
final Optional<NickoProfile> optionalProfile = NickoProfile.get(uuid);
assertTrue(optionalProfile.isPresent());
}
@ -54,15 +55,18 @@ public class SQLStorageTest {
@DisplayName("Update profile")
@Order(3)
public void updateProfile() {
final Optional<NickoProfile> optionalProfile = dataStore.getData(uuid);
final Optional<NickoProfile> optionalProfile = NickoProfile.get(uuid);
assertTrue(optionalProfile.isPresent());
final NickoProfile profile = optionalProfile.get();
assertNull(profile.getName());
assertNull(profile.getSkin());
final AppearanceData appearanceData = profile.getAppearanceData();
assertNull(appearanceData.getName());
assertNull(appearanceData.getSkin());
assertEquals(profile.getLocale(), Locale.ENGLISH);
assertTrue(profile.isBungeecordTransfer());
profile.setName("Notch");
profile.setSkin("Notch");
appearanceData.setName("Notch");
appearanceData.setSkin("Notch");
profile.setLocale(Locale.FRENCH);
profile.setBungeecordTransfer(false);
@ -74,12 +78,13 @@ public class SQLStorageTest {
@DisplayName("Get updated profile")
@Order(4)
public void hasProfileBeenUpdated() {
final Optional<NickoProfile> profile = dataStore.getData(uuid);
assertTrue(profile.isPresent());
final Optional<NickoProfile> optionalProfile = NickoProfile.get(uuid);
assertTrue(optionalProfile.isPresent());
final NickoProfile updatedProfile = profile.get();
assertEquals(updatedProfile.getName(), "Notch");
assertEquals(updatedProfile.getSkin(), "Notch");
final NickoProfile updatedProfile = optionalProfile.get();
final AppearanceData appearanceData = updatedProfile.getAppearanceData();
assertEquals(appearanceData.getName(), "Notch");
assertEquals(appearanceData.getSkin(), "Notch");
assertEquals(updatedProfile.getLocale(), Locale.FRENCH);
assertFalse(updatedProfile.isBungeecordTransfer());
}

View file

@ -6,9 +6,9 @@ import be.seeseemelk.mockbukkit.entity.PlayerMock;
import org.junit.jupiter.api.*;
import xyz.atnrch.nicko.NickoBukkit;
import xyz.atnrch.nicko.appearance.ActionResult;
import xyz.atnrch.nicko.appearance.AppearanceManager;
import xyz.atnrch.nicko.config.Configuration;
import xyz.atnrch.nicko.config.DataSourceConfiguration;
import xyz.atnrch.nicko.profile.AppearanceData;
import xyz.atnrch.nicko.profile.NickoProfile;
import xyz.atnrch.nicko.storage.PlayerDataStore;
@ -46,14 +46,20 @@ public class RedisCacheTest {
@DisplayName("Update Cache Profile")
@Order(2)
public void updateCache() {
final Optional<NickoProfile> optionalProfile = NickoProfile.get(player);
assertTrue(optionalProfile.isPresent());
final NickoProfile profile = optionalProfile.get();
final PlayerDataStore dataStore = plugin.getDataStore();
final AppearanceManager appearanceManager = AppearanceManager.get(player);
appearanceManager.setName("Notch");
dataStore.updateCache(player.getUniqueId(), appearanceManager.getProfile());
final AppearanceData appearanceData = profile.getAppearanceData();
appearanceData.setName("Notch");
dataStore.updateCache(player.getUniqueId(), profile);
final Optional<NickoProfile> retrieve = dataStore.getCache().retrieve(player.getUniqueId());
assertTrue(retrieve.isPresent());
final NickoProfile retrieved = retrieve.get();
assertEquals(retrieved.getName(), "Notch");
final AppearanceData retrievedAppearanceData = retrieved.getAppearanceData();
assertEquals(retrievedAppearanceData.getName(), "Notch");
}
@Test