feat(i18n): version checking
This commit is contained in:
parent
2b71bd18eb
commit
e9d6f33930
13 changed files with 125 additions and 24 deletions
5
.gitignore
vendored
5
.gitignore
vendored
|
@ -23,4 +23,7 @@ out/
|
||||||
.sts4-cache
|
.sts4-cache
|
||||||
bin/
|
bin/
|
||||||
!**/src/main/**/bin/
|
!**/src/main/**/bin/
|
||||||
!**/src/test/**/bin/
|
!**/src/test/**/bin/
|
||||||
|
|
||||||
|
### Server ###
|
||||||
|
run/
|
|
@ -1,6 +1,7 @@
|
||||||
1.0.8-RC1: Update n°5 (XX/XX/XX)
|
1.0.8-RC1: Update n°5 (XX/XX/XX)
|
||||||
[FEATURES]
|
[FEATURES]
|
||||||
- Persistence and cache will now fallback to local alternatives when unreachable.
|
- Persistence and cache will now fallback to local alternatives when unreachable.
|
||||||
|
- Developers can now listen to the PlayerDisguiseEvent and cancel the disguise process.
|
||||||
|
|
||||||
[OTHER]
|
[OTHER]
|
||||||
- Various optimizations and improvements.
|
- Various optimizations and improvements.
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
|
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id("io.github.goooler.shadow") version "8.1.2"
|
|
||||||
id("java")
|
id("java")
|
||||||
|
id("io.github.goooler.shadow") version "8.1.2"
|
||||||
|
id("xyz.jpenilla.run-paper") version "2.2.2"
|
||||||
}
|
}
|
||||||
|
|
||||||
group = "xyz.ineanto"
|
group = "xyz.ineanto"
|
||||||
|
@ -67,16 +66,16 @@ dependencies {
|
||||||
testImplementation("org.junit.jupiter:junit-jupiter:5.10.1")
|
testImplementation("org.junit.jupiter:junit-jupiter:5.10.1")
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.processResources {
|
|
||||||
from("src/main/resources")
|
|
||||||
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
|
||||||
filesMatching("plugin.yml") {
|
|
||||||
expand("version" to version)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
tasks {
|
tasks {
|
||||||
named<ShadowJar>("shadowJar") {
|
processResources {
|
||||||
|
from("src/main/resources")
|
||||||
|
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
||||||
|
filesMatching("plugin.yml") {
|
||||||
|
expand("version" to version)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
shadowJar {
|
||||||
mustRunAfter(test)
|
mustRunAfter(test)
|
||||||
configurations = listOf(shadowImplementation)
|
configurations = listOf(shadowImplementation)
|
||||||
|
|
||||||
|
@ -122,6 +121,17 @@ tasks {
|
||||||
exclude(dependency("net.wesjd:.*"))
|
exclude(dependency("net.wesjd:.*"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
runServer {
|
||||||
|
downloadPlugins {
|
||||||
|
url("https://download.luckperms.net/1526/bukkit/loader/LuckPerms-Bukkit-5.4.113.jar")
|
||||||
|
url("https://ci.dmulloy2.net/job/ProtocolLib/lastSuccessfulBuild/artifact/build/libs/ProtocolLib.jar")
|
||||||
|
}
|
||||||
|
// Configure the Minecraft version for our task.
|
||||||
|
// This is the only required configuration besides applying the plugin.
|
||||||
|
// Your plugin's jar (or shadowJar if present) will be used automatically.
|
||||||
|
minecraftVersion("1.20.2")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.named("jar").configure {
|
tasks.named("jar").configure {
|
||||||
|
|
|
@ -36,6 +36,7 @@ public class NickoBukkit extends JavaPlugin {
|
||||||
private Configuration configuration;
|
private Configuration configuration;
|
||||||
private LocaleFileManager localeFileManager;
|
private LocaleFileManager localeFileManager;
|
||||||
private PlayerNameStore nameStore;
|
private PlayerNameStore nameStore;
|
||||||
|
private Metrics metrics;
|
||||||
|
|
||||||
public NickoBukkit() {
|
public NickoBukkit() {
|
||||||
this.unitTesting = false;
|
this.unitTesting = false;
|
||||||
|
@ -120,7 +121,7 @@ public class NickoBukkit extends JavaPlugin {
|
||||||
|
|
||||||
getServer().getPluginManager().registerEvents(new PlayerJoinListener(), this);
|
getServer().getPluginManager().registerEvents(new PlayerJoinListener(), this);
|
||||||
getServer().getPluginManager().registerEvents(new PlayerQuitListener(), this);
|
getServer().getPluginManager().registerEvents(new PlayerQuitListener(), this);
|
||||||
new Metrics(this, 20483);
|
metrics = new Metrics(this, 20483);
|
||||||
}
|
}
|
||||||
|
|
||||||
getLogger().info("Nicko has been enabled.");
|
getLogger().info("Nicko has been enabled.");
|
||||||
|
@ -138,6 +139,7 @@ public class NickoBukkit extends JavaPlugin {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!unitTesting) metrics.shutdown();
|
||||||
getLogger().info("Nicko (Bukkit) has been disabled.");
|
getLogger().info("Nicko (Bukkit) has been disabled.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ package xyz.ineanto.nicko.anvil;
|
||||||
|
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.wesjd.anvilgui.AnvilGUI;
|
import net.wesjd.anvilgui.AnvilGUI;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
@ -9,6 +10,7 @@ import org.bukkit.inventory.meta.ItemMeta;
|
||||||
import xyz.ineanto.nicko.NickoBukkit;
|
import xyz.ineanto.nicko.NickoBukkit;
|
||||||
import xyz.ineanto.nicko.appearance.ActionResult;
|
import xyz.ineanto.nicko.appearance.ActionResult;
|
||||||
import xyz.ineanto.nicko.appearance.AppearanceManager;
|
import xyz.ineanto.nicko.appearance.AppearanceManager;
|
||||||
|
import xyz.ineanto.nicko.event.custom.PlayerDisguiseEvent;
|
||||||
import xyz.ineanto.nicko.i18n.I18N;
|
import xyz.ineanto.nicko.i18n.I18N;
|
||||||
import xyz.ineanto.nicko.i18n.I18NDict;
|
import xyz.ineanto.nicko.i18n.I18NDict;
|
||||||
import xyz.ineanto.nicko.mojang.MojangUtils;
|
import xyz.ineanto.nicko.mojang.MojangUtils;
|
||||||
|
@ -77,8 +79,7 @@ public class AnvilManager {
|
||||||
} else {
|
} else {
|
||||||
profile.setName(snapshot.getText());
|
profile.setName(snapshot.getText());
|
||||||
dataStore.updateCache(player.getUniqueId(), profile);
|
dataStore.updateCache(player.getUniqueId(), profile);
|
||||||
final ActionResult actionResult = appearanceManager.updatePlayer(false, false);
|
return sendResultAndClose(false);
|
||||||
return sendResultAndClose(actionResult);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
|
@ -98,8 +99,7 @@ public class AnvilManager {
|
||||||
} else {
|
} else {
|
||||||
profile.setSkin(snapshot.getText());
|
profile.setSkin(snapshot.getText());
|
||||||
dataStore.updateCache(player.getUniqueId(), profile);
|
dataStore.updateCache(player.getUniqueId(), profile);
|
||||||
final ActionResult actionResult = appearanceManager.updatePlayer(true, false);
|
return sendResultAndClose(true);
|
||||||
return sendResultAndClose(actionResult);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
|
@ -107,8 +107,13 @@ public class AnvilManager {
|
||||||
.text("New skin...");
|
.text("New skin...");
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<AnvilGUI.ResponseAction> sendResultAndClose(ActionResult actionResult) {
|
private List<AnvilGUI.ResponseAction> sendResultAndClose(boolean skinChange) {
|
||||||
|
final PlayerDisguiseEvent event = new PlayerDisguiseEvent(player, profile.getSkin(), player.getName());
|
||||||
|
Bukkit.getPluginManager().callEvent(event);
|
||||||
|
if (event.isCancelled()) { return Collections.singletonList(AnvilGUI.ResponseAction.close()); }
|
||||||
|
|
||||||
final I18N i18n = new I18N(player);
|
final I18N i18n = new I18N(player);
|
||||||
|
final ActionResult actionResult = appearanceManager.updatePlayer(skinChange, false);
|
||||||
if (!actionResult.isError()) {
|
if (!actionResult.isError()) {
|
||||||
player.sendMessage(i18n.translate(I18NDict.Event.Appearance.Set.OK));
|
player.sendMessage(i18n.translate(I18NDict.Event.Appearance.Set.OK));
|
||||||
} else {
|
} else {
|
||||||
|
@ -120,7 +125,7 @@ public class AnvilManager {
|
||||||
private ItemStack getLeftItem(boolean skin) {
|
private ItemStack getLeftItem(boolean skin) {
|
||||||
final ItemStack item = new ItemStack(Material.PAPER);
|
final ItemStack item = new ItemStack(Material.PAPER);
|
||||||
final ItemMeta meta = item.getItemMeta();
|
final ItemMeta meta = item.getItemMeta();
|
||||||
if (meta != null) meta.displayName(Component.text("§0New " + (skin ? "skin" : "name") + "..."));
|
if (meta != null) meta.displayName(Component.text("New " + (skin ? "skin" : "name") + "..."));
|
||||||
item.setItemMeta(meta);
|
item.setItemMeta(meta);
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,6 @@ import java.util.ArrayList;
|
||||||
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;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
public class PlayerJoinListener implements Listener {
|
public class PlayerJoinListener implements Listener {
|
||||||
private final Logger logger = Logger.getLogger("PlayerJoinListener");
|
private final Logger logger = Logger.getLogger("PlayerJoinListener");
|
||||||
|
@ -53,7 +52,7 @@ public class PlayerJoinListener implements Listener {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
for (Player online : Bukkit.getOnlinePlayers().stream().filter(op -> op.getUniqueId() != player.getUniqueId()).collect(Collectors.toList())) {
|
for (Player online : Bukkit.getOnlinePlayers().stream().filter(op -> op.getUniqueId() != player.getUniqueId()).toList()) {
|
||||||
final Optional<NickoProfile> optionalOnlinePlayerProfile = dataStore.getData(online.getUniqueId());
|
final Optional<NickoProfile> optionalOnlinePlayerProfile = dataStore.getData(online.getUniqueId());
|
||||||
|
|
||||||
optionalOnlinePlayerProfile.ifPresent(profile -> {
|
optionalOnlinePlayerProfile.ifPresent(profile -> {
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
package xyz.ineanto.nicko.event.custom;
|
||||||
|
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.Cancellable;
|
||||||
|
import org.bukkit.event.Event;
|
||||||
|
import org.bukkit.event.HandlerList;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
public class PlayerDisguiseEvent extends Event implements Cancellable {
|
||||||
|
private static final HandlerList HANDLERS_LIST = new HandlerList();
|
||||||
|
private boolean isCancelled;
|
||||||
|
private final Player player;
|
||||||
|
private final String skin, name;
|
||||||
|
|
||||||
|
public PlayerDisguiseEvent(Player player, String skin, String name) {
|
||||||
|
this.player = player;
|
||||||
|
this.skin = skin;
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isCancelled() {
|
||||||
|
return isCancelled;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setCancelled(boolean isCancelled) {
|
||||||
|
this.isCancelled = isCancelled;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @NotNull HandlerList getHandlers() {
|
||||||
|
return HANDLERS_LIST;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Player getPlayer() {
|
||||||
|
return player;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSkin() {
|
||||||
|
return skin;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
}
|
|
@ -50,7 +50,7 @@ public class I18N {
|
||||||
final ArrayList<String> lore = readList(loreKey);
|
final ArrayList<String> lore = readList(loreKey);
|
||||||
|
|
||||||
if (name == null) {
|
if (name == null) {
|
||||||
logger.warning(nameKey + " doesn't exists! Please translate this entry.");
|
logger.warning(nameKey + " doesn't exists! Is your language file outdated?");
|
||||||
return new ItemTranslation(nameKey, new ArrayList<>() {{
|
return new ItemTranslation(nameKey, new ArrayList<>() {{
|
||||||
add(loreKey);
|
add(loreKey);
|
||||||
}});
|
}});
|
||||||
|
|
|
@ -3,8 +3,10 @@ package xyz.ineanto.nicko.storage.redis;
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import com.google.gson.GsonBuilder;
|
import com.google.gson.GsonBuilder;
|
||||||
import redis.clients.jedis.Jedis;
|
import redis.clients.jedis.Jedis;
|
||||||
|
import redis.clients.jedis.exceptions.JedisException;
|
||||||
import xyz.ineanto.nicko.appearance.ActionResult;
|
import xyz.ineanto.nicko.appearance.ActionResult;
|
||||||
import xyz.ineanto.nicko.config.Configuration;
|
import xyz.ineanto.nicko.config.Configuration;
|
||||||
|
import xyz.ineanto.nicko.i18n.I18NDict;
|
||||||
import xyz.ineanto.nicko.profile.NickoProfile;
|
import xyz.ineanto.nicko.profile.NickoProfile;
|
||||||
import xyz.ineanto.nicko.storage.Cache;
|
import xyz.ineanto.nicko.storage.Cache;
|
||||||
import xyz.ineanto.nicko.storage.CacheProvider;
|
import xyz.ineanto.nicko.storage.CacheProvider;
|
||||||
|
@ -37,6 +39,8 @@ public class RedisCache extends Cache {
|
||||||
try (Jedis jedis = provider.getJedis()) {
|
try (Jedis jedis = provider.getJedis()) {
|
||||||
jedis.set("nicko:" + uuid.toString(), gson.toJson(profile));
|
jedis.set("nicko:" + uuid.toString(), gson.toJson(profile));
|
||||||
return ActionResult.ok();
|
return ActionResult.ok();
|
||||||
|
} catch (JedisException exception) {
|
||||||
|
return ActionResult.error(I18NDict.Error.CACHE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,6 +48,8 @@ public class RedisCache extends Cache {
|
||||||
public boolean isCached(UUID uuid) {
|
public boolean isCached(UUID uuid) {
|
||||||
try (Jedis jedis = provider.getJedis()) {
|
try (Jedis jedis = provider.getJedis()) {
|
||||||
return jedis.exists("nicko:" + uuid.toString());
|
return jedis.exists("nicko:" + uuid.toString());
|
||||||
|
} catch (JedisException exception) {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,6 +61,8 @@ public class RedisCache extends Cache {
|
||||||
final String data = jedis.get("nicko:" + uuid.toString());
|
final String data = jedis.get("nicko:" + uuid.toString());
|
||||||
final NickoProfile profile = gson.fromJson(data, NickoProfile.class);
|
final NickoProfile profile = gson.fromJson(data, NickoProfile.class);
|
||||||
return Optional.of(profile);
|
return Optional.of(profile);
|
||||||
|
} catch (JedisException exception) {
|
||||||
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,6 +71,8 @@ public class RedisCache extends Cache {
|
||||||
try (Jedis jedis = provider.getJedis()) {
|
try (Jedis jedis = provider.getJedis()) {
|
||||||
jedis.del("nicko:" + uuid.toString());
|
jedis.del("nicko:" + uuid.toString());
|
||||||
return ActionResult.ok();
|
return ActionResult.ok();
|
||||||
|
} catch (JedisException exception) {
|
||||||
|
return ActionResult.error(I18NDict.Error.CACHE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
16
src/main/java/xyz/ineanto/nicko/version/Version.java
Normal file
16
src/main/java/xyz/ineanto/nicko/version/Version.java
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
package xyz.ineanto.nicko.version;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.Comparator;
|
||||||
|
|
||||||
|
public record Version(int major, int minor, int patch) implements Comparable<Version> {
|
||||||
|
@Override
|
||||||
|
public int compareTo(@NotNull Version otherVersion) {
|
||||||
|
final Comparator<Version> comparator = Comparator
|
||||||
|
.comparingInt(Version::major)
|
||||||
|
.thenComparingInt(Version::minor)
|
||||||
|
.thenComparingInt(Version::patch);
|
||||||
|
return comparator.compare(this, otherVersion);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,9 @@
|
||||||
# Nicko ${project.version} - Config:
|
# Nicko ${project.version} - Config:
|
||||||
|
|
||||||
|
# Don't modify this.
|
||||||
|
# No, like... really.
|
||||||
|
version: "1.0.8"
|
||||||
|
|
||||||
############
|
############
|
||||||
# LANGUAGE #
|
# LANGUAGE #
|
||||||
############
|
############
|
||||||
|
@ -49,7 +53,7 @@ redis:
|
||||||
# Accepted values: false (Disabled), true (Enabled)
|
# Accepted values: false (Disabled), true (Enabled)
|
||||||
enabled: false
|
enabled: false
|
||||||
# Redis server's address
|
# Redis server's address
|
||||||
# Accepted values: valid IP address (e.g. localhost, 127.0.0.1)
|
# Accepted values: valid IP address (e.g.: localhost, 127.0.0.1)
|
||||||
address: "localhost"
|
address: "localhost"
|
||||||
# Redis server's port
|
# Redis server's port
|
||||||
# Accepted values: valid integer (e.g. 3306, 25565)
|
# Accepted values: valid integer (e.g. 3306, 25565)
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
version: "1.0.8"
|
||||||
|
|
||||||
error:
|
error:
|
||||||
generic: "An unknown error occurred."
|
generic: "An unknown error occurred."
|
||||||
permission: "§cYou do not have the required permission."
|
permission: "§cYou do not have the required permission."
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
version: "1.0.8"
|
||||||
|
|
||||||
error:
|
error:
|
||||||
generic: "Une erreur inconnue c'est produite."
|
generic: "Une erreur inconnue c'est produite."
|
||||||
permission: "§cVous ne possédez pas la permission."
|
permission: "§cVous ne possédez pas la permission."
|
||||||
|
|
Loading…
Reference in a new issue