feat(global): support only latest major versions, bump to jre17

This commit is contained in:
ineanto 2023-12-13 16:09:00 +01:00
parent 3949113dee
commit 2fc3194c8c
31 changed files with 99 additions and 199 deletions

2
.idea/gradle.xml generated
View file

@ -6,6 +6,7 @@
<GradleProjectSettings>
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="gradleHome" value="/usr/share/java/gradle" />
<option name="gradleJvm" value="17" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
@ -13,5 +14,6 @@
</option>
</GradleProjectSettings>
</option>
<option name="parallelModelFetch" value="true" />
</component>
</project>

5
.idea/misc.xml generated
View file

@ -5,7 +5,10 @@
<option name="description" value="" />
</component>
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="17" project-jdk-type="JavaSDK">
<component name="PWA">
<option name="wasEnabledAtLeastOnce" value="true" />
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="17" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

View file

@ -1,4 +1,8 @@
Update n°4 (11/12/23):
1.0.7-RC1: Update n°4 (11/12/23)
[OTHER]
• In line with my thinking that Minecraft servers should always be in one of the latest versions to give developers more freedom and less maintenance hassle,
Nicko will now only be supporting the previous major version and current major version.
This results in this version of Nicko now needing at minimum of JRE 17 and a server running 1.19.
If you can't upgrade, consider skipping the plugin altogether. I'm sorry.
• Various optimizations and improvements.

View file

@ -6,15 +6,17 @@ plugins {
}
group = "xyz.ineanto"
version = "1.0.6-RC1"
version = "1.0.7-RC1"
val shadowImplementation: Configuration by configurations.creating
configurations["implementation"].extendsFrom(shadowImplementation)
configurations["testImplementation"].extendsFrom(shadowImplementation)
java {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
toolchain {
languageVersion = JavaLanguageVersion.of(8)
languageVersion = JavaLanguageVersion.of(17)
}
}

View file

@ -65,7 +65,7 @@ public class NickoBukkit extends JavaPlugin {
}
if (!MinecraftVersion.VILLAGE_UPDATE.atOrAbove()) {
if (!MinecraftVersion.WILD_UPDATE.atOrAbove()) {
getLogger().severe("This version (" + MinecraftVersion.getCurrentVersion().getVersion() + ") is not supported by Nicko!");
dataStore.getStorage().setError(true);
Bukkit.getPluginManager().disablePlugin(this);

View file

@ -112,7 +112,7 @@ public class AppearanceManager {
final MojangSkin skinResult = skin.get();
final Multimap<String, WrappedSignedProperty> properties = gameProfile.getProperties();
properties.get("textures").clear();
properties.put("textures", new WrappedSignedProperty("textures", skinResult.getValue(), skinResult.getSignature()));
properties.put("textures", new WrappedSignedProperty("textures", skinResult.value(), skinResult.signature()));
} else {
return ActionResult.error(I18NDict.Error.MOJANG_SKIN);
}
@ -144,7 +144,6 @@ public class AppearanceManager {
respawn.setSeed(world.getSeed());
respawn.setGameMode(player.getGameMode());
respawn.setPreviousGameMode(player.getGameMode());
respawn.setDifficulty(world.getDifficulty());
respawn.setCopyMetadata(true);
respawn.sendPacket(player);
player.teleport(player.getLocation(), PlayerTeleportEvent.TeleportCause.PLUGIN);

View file

@ -12,8 +12,7 @@ import xyz.ineanto.nicko.i18n.I18NDict;
public class NickoCommand implements CommandExecutor {
@Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) {
if (sender instanceof Player) {
final Player player = (Player) sender;
if (sender instanceof Player player) {
if (player.isOp() || player.hasPermission("nicko.use") || player.hasPermission("nicko.*")) {
new HomeGUI(player).open();
} else {

View file

@ -53,7 +53,6 @@ public class PlayerJoinListener implements Listener {
}
});
// TODO (Ineanto, 12/6/23): Make this cleaner.
for (Player online : Bukkit.getOnlinePlayers().stream().filter(op -> op.getUniqueId() != player.getUniqueId()).collect(Collectors.toList())) {
final Optional<NickoProfile> optionalOnlinePlayerProfile = dataStore.getData(online.getUniqueId());

View file

@ -23,7 +23,6 @@ public class SettingsGUI {
"B # # # # # # # #"
};
// TODO: 3/6/23 Replace when Redis is not enabled
dynamicStructure[1] = dynamicStructure[1].replace("T", "U");
final I18N i18n = new I18N(player);

View file

@ -21,8 +21,8 @@ public class ScrollDownItem extends ScrollItem {
public ItemProvider getItemProvider(ScrollGui gui) {
final ItemBuilder builder = new ItemBuilder(Material.GREEN_STAINED_GLASS_PANE);
final ItemTranslation translation = i18n.fetchTranslation(I18NDict.GUI.SCROLL_DOWN);
builder.setDisplayName(translation.getName());
if (!gui.canScroll(1)) translation.getLore().forEach(builder::addLoreLines);
builder.setDisplayName(translation.name());
if (!gui.canScroll(1)) translation.lore().forEach(builder::addLoreLines);
return builder;
}
}

View file

@ -21,8 +21,8 @@ public class ScrollUpItem extends ScrollItem {
public ItemProvider getItemProvider(ScrollGui gui) {
final ItemBuilder builder = new ItemBuilder(Material.RED_STAINED_GLASS_PANE);
final ItemTranslation translation = i18n.fetchTranslation(I18NDict.GUI.SCROLL_UP);
builder.setDisplayName(translation.getName());
if (!gui.canScroll(-1)) translation.getLore().forEach(builder::addLoreLines);
builder.setDisplayName(translation.name());
if (!gui.canScroll(-1)) translation.lore().forEach(builder::addLoreLines);
return builder;
}

View file

@ -51,8 +51,8 @@ public class BungeeCordCyclingItem {
final ItemBuilder builder = new ItemBuilder(Material.COMPASS);
final ItemTranslation translation = i18n.fetchTranslation(I18NDict.GUI.Settings.BUNGEECORD);
builder.setDisplayName(translation.getName());
translation.getLore().forEach(builder::addLoreLines);
builder.setDisplayName(translation.name());
translation.lore().forEach(builder::addLoreLines);
/*
if (enabled) {
builder.addLoreLines("§7> §cDisabled");

View file

@ -43,7 +43,6 @@ public class LanguageCyclingItem {
nickoProfile.setLocale(Locale.values()[integer]);
observer.playSound(player, Sound.UI_BUTTON_CLICK, 1f, 0.707107f); // 0.707107 ~= C
player.getOpenInventory().close();
// TODO (Ineanto, 7/14/23): This checks a 2nd time for the profile.
if (dataStore.updateCache(player.getUniqueId(), nickoProfile).isError()) {
player.sendMessage(i18n.translate(I18NDict.Event.Settings.ERROR));
} else {
@ -59,7 +58,7 @@ public class LanguageCyclingItem {
final ItemBuilder builder = new ItemBuilder(Material.OAK_SIGN);
final ItemTranslation translation = i18n.fetchTranslation(I18NDict.GUI.Settings.LANGUAGE);
builder.setDisplayName(translation.getName());
builder.setDisplayName(translation.name());
for (Locale value : locales) {
if (locale != value) {
builder.addLoreLines("§7> " + value.getName());
@ -67,7 +66,7 @@ public class LanguageCyclingItem {
builder.addLoreLines("§6§l> §f" + value.getName());
}
}
translation.getLore().forEach(builder::addLoreLines);
translation.lore().forEach(builder::addLoreLines);
return builder;
}

View file

@ -38,8 +38,8 @@ public class I18N {
public AbstractItemBuilder<?> translateItem(AbstractItemBuilder<?> item, String key, Object... args) {
final ItemTranslation translation = fetchTranslation(key, args);
item.setDisplayName(translation.getName());
translation.getLore().forEach(item::addLoreLines);
item.setDisplayName(translation.name());
translation.lore().forEach(item::addLoreLines);
return item;
}
@ -51,7 +51,7 @@ public class I18N {
if (name == null) {
logger.warning(nameKey + " doesn't exists! Please translate this entry.");
return new ItemTranslation(nameKey, new ArrayList<String>() {{
return new ItemTranslation(nameKey, new ArrayList<>() {{
add(loreKey);
}});
}

View file

@ -9,8 +9,8 @@ public class I18NDict {
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";
public static final String SQL_ERROR = ERROR_KEY + "sql";
public static final String JSON_ERROR = ERROR_KEY + "json";
public static final String SQL = ERROR_KEY + "sql";
public static final String JSON = ERROR_KEY + "json";
}
public static class Event {
@ -74,7 +74,6 @@ public class I18NDict {
public static final String GO_BACK = GUI_KEY + "go_back";
public static final String UNAVAILABLE = GUI_KEY + "unavailable";
public static final String LOADING = GUI_KEY + "loading";
public static final String ERROR = GUI_KEY + "error";
public static final String SCROLL_UP = GUI_KEY + "scroll_up";
public static final String SCROLL_DOWN = GUI_KEY + "scroll_down";

View file

@ -2,20 +2,4 @@ package xyz.ineanto.nicko.i18n;
import java.util.ArrayList;
public class ItemTranslation {
private final String name;
private final ArrayList<String> lore;
public ItemTranslation(String name, ArrayList<String> lore) {
this.name = name;
this.lore = lore;
}
public String getName() {
return name;
}
public ArrayList<String> getLore() {
return lore;
}
}
public record ItemTranslation(String name, ArrayList<String> lore) {}

View file

@ -27,7 +27,7 @@ public class MojangAPI {
private final Logger logger = Logger.getLogger("MojangAPI");
private final HashMap<String, String> uuidToName = new HashMap<>();
private final CacheLoader<String, Optional<MojangSkin>> skinLoader = new CacheLoader<String, Optional<MojangSkin>>() {
private final CacheLoader<String, Optional<MojangSkin>> skinLoader = new CacheLoader<>() {
@Nonnull
public Optional<MojangSkin> load(@Nonnull String uuid) throws Exception {
return getSkinFromMojang(uuid);
@ -40,7 +40,7 @@ public class MojangAPI {
.expireAfterWrite(24, TimeUnit.HOURS)
.build(skinLoader);
private final CacheLoader<String, Optional<String>> uuidLoader = new CacheLoader<String, Optional<String>>() {
private final CacheLoader<String, Optional<String>> uuidLoader = new CacheLoader<>() {
@Nonnull
public Optional<String> load(@Nonnull String name) throws Exception {
return getUUIDFromMojang(name);

View file

@ -2,27 +2,11 @@ package xyz.ineanto.nicko.mojang;
import com.google.gson.JsonObject;
public class MojangSkin {
private final String value;
private final String signature;
public MojangSkin(String value, String signature) {
this.value = value;
this.signature = signature;
}
public record MojangSkin(String value, String signature) {
public static MojangSkin buildFromJson(JsonObject object) {
final JsonObject properties = object.get("properties").getAsJsonArray().get(0).getAsJsonObject();
final String value = properties.get("value").getAsString();
final String signature = properties.get("signature").getAsString();
return new MojangSkin(value, signature);
}
public String getValue() {
return value;
}
public String getSignature() {
return signature;
}
}

View file

@ -64,17 +64,12 @@ public class NickoExpansion extends PlaceholderExpansion {
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;
}
return switch (params) {
case "name" -> name;
case "skin" -> skin;
case "locale" -> locale;
case "bungeecord" -> String.valueOf(bungeecord);
default -> null;
};
}
}

View file

@ -32,12 +32,12 @@ public class PlayerDataStore {
}
public ActionResult updateCache(UUID uuid, NickoProfile profile) {
final Optional<NickoProfile> retrieved = getData(uuid);
if (retrieved.isPresent()) {
getCache().cache(uuid, profile);
return ActionResult.ok();
if (storage.isError() || cache.isError()) {
return ActionResult.error(I18NDict.Error.CACHE);
}
return ActionResult.error(I18NDict.Error.CACHE);
getCache().cache(uuid, profile);
return ActionResult.ok();
}
public Optional<NickoProfile> getData(UUID uuid) {
@ -59,7 +59,7 @@ public class PlayerDataStore {
}
public Optional<NickoProfile> getOfflineData(String name) {
if (storage.isError()) {
if (storage.isError() || cache.isError()) {
return Optional.empty();
}
@ -76,12 +76,12 @@ public class PlayerDataStore {
}
public ActionResult saveData(Player player) {
if (storage.isError()) return ActionResult.error(I18NDict.Error.GENERIC);
if (storage.isError()) return ActionResult.error(I18NDict.Error.SQL);
if (cache.isError()) return ActionResult.error(I18NDict.Error.CACHE);
if (!cache.isCached(player.getUniqueId())) return ActionResult.error(I18NDict.Error.GENERIC);
if (!cache.isCached(player.getUniqueId())) return ActionResult.error(I18NDict.Error.CACHE);
final Optional<NickoProfile> cachedProfile = cache.retrieve(player.getUniqueId());
if (!cachedProfile.isPresent()) return ActionResult.error(I18NDict.Error.GENERIC);
if (!cachedProfile.isPresent()) return ActionResult.error(I18NDict.Error.CACHE);
cache.delete(player.getUniqueId());
return storage.store(player.getUniqueId(), cachedProfile.get());

View file

@ -42,12 +42,12 @@ public class JSONStorage extends Storage {
}
} catch (IOException e) {
logger.warning("Could not write to file.");
return ActionResult.error(I18NDict.Error.JSON_ERROR);
return ActionResult.error(I18NDict.Error.JSON);
}
}
} catch (IOException e) {
logger.warning("Could not create file.");
return ActionResult.error(I18NDict.Error.JSON_ERROR);
return ActionResult.error(I18NDict.Error.JSON);
}
return ActionResult.ok();
@ -81,7 +81,7 @@ public class JSONStorage extends Storage {
if (file.delete() || !file.exists()) {
return ActionResult.ok();
}
return ActionResult.error(I18NDict.Error.JSON_ERROR);
return ActionResult.error(I18NDict.Error.JSON);
}
private boolean checkFileExists(File file) throws IOException {

View file

@ -36,7 +36,7 @@ public class MariaDBStorage extends Storage {
@Override
public ActionResult store(UUID uuid, NickoProfile profile) {
final Connection connection = getProvider().getConnection();
if (connection == null) return ActionResult.error(I18NDict.Error.SQL_ERROR);
if (connection == null) return ActionResult.error(I18NDict.Error.SQL);
try {
final PreparedStatement statement = isStored(uuid) ?
@ -45,7 +45,7 @@ public class MariaDBStorage extends Storage {
return ActionResult.ok();
} catch (SQLException e) {
logger.warning("Couldn't send SQL Request: " + e.getMessage());
return ActionResult.error(I18NDict.Error.SQL_ERROR);
return ActionResult.error(I18NDict.Error.SQL);
}
}
@ -103,17 +103,17 @@ public class MariaDBStorage extends Storage {
@Override
public ActionResult delete(UUID uuid) {
final Connection connection = getProvider().getConnection();
if (connection == null) return ActionResult.error(I18NDict.Error.SQL_ERROR);
if (connection == null) return ActionResult.error(I18NDict.Error.SQL);
try {
final String sql = "DELETE FROM nicko.DATA WHERE uuid = ?";
final PreparedStatement statement = connection.prepareStatement(sql);
statement.setString(1, uuid.toString());
int rows = statement.executeUpdate();
return (rows == 1 ? ActionResult.ok() : ActionResult.error(I18NDict.Error.SQL_ERROR));
return (rows == 1 ? ActionResult.ok() : ActionResult.error(I18NDict.Error.SQL));
} catch (SQLException e) {
logger.warning("Couldn't delete profile: " + e.getMessage());
return ActionResult.error(I18NDict.Error.SQL_ERROR);
return ActionResult.error(I18NDict.Error.SQL);
}
}

View file

@ -58,15 +58,13 @@ public class MariaDBStorageProvider implements StorageProvider {
private void createTable() throws SQLException {
final Connection connection = getConnection();
String query = "CREATE TABLE IF NOT EXISTS %s.DATA " +
"(uuid varchar(36) NOT NULL," +
"name varchar(16)," +
"skin varchar(16)," +
"locale char(2) NOT NULL," +
"bungeecord boolean NOT NULL," +
"PRIMARY KEY (uuid))";
query = query.replace("%s", schemaName);
final String query = "CREATE TABLE IF NOT EXISTS %s.DATA ".replace("%s", schemaName) +
"(uuid varchar(36) NOT NULL," +
"name varchar(16)," +
"skin varchar(16)," +
"locale char(2) NOT NULL," +
"bungeecord boolean NOT NULL," +
"PRIMARY KEY (uuid))";
final PreparedStatement statement = connection.prepareStatement(query);
statement.executeUpdate();
@ -74,9 +72,7 @@ public class MariaDBStorageProvider implements StorageProvider {
private void createDatabase() throws SQLException {
final Connection connection = getConnection();
String query = "CREATE DATABASE IF NOT EXISTS %s";
query = query.replace("%s", schemaName);
final String query = "CREATE DATABASE IF NOT EXISTS %s".replace("%s", schemaName);
final PreparedStatement statement = connection.prepareStatement(query);
statement.executeUpdate();

View file

@ -36,7 +36,7 @@ public class MySQLStorage extends Storage {
@Override
public ActionResult store(UUID uuid, NickoProfile profile) {
final Connection connection = getProvider().getConnection();
if (connection == null) return ActionResult.error(I18NDict.Error.SQL_ERROR);
if (connection == null) return ActionResult.error(I18NDict.Error.SQL);
try {
final PreparedStatement statement = isStored(uuid) ?
@ -45,7 +45,7 @@ public class MySQLStorage extends Storage {
return ActionResult.ok();
} catch (SQLException e) {
logger.warning("Couldn't send SQL Request: " + e.getMessage());
return ActionResult.error(I18NDict.Error.SQL_ERROR);
return ActionResult.error(I18NDict.Error.SQL);
}
}
@ -103,17 +103,17 @@ public class MySQLStorage extends Storage {
@Override
public ActionResult delete(UUID uuid) {
final Connection connection = getProvider().getConnection();
if (connection == null) return ActionResult.error(I18NDict.Error.SQL_ERROR);
if (connection == null) return ActionResult.error(I18NDict.Error.SQL);
try {
final String sql = "DELETE FROM nicko.DATA WHERE uuid = ?";
final PreparedStatement statement = connection.prepareStatement(sql);
statement.setString(1, uuid.toString());
int rows = statement.executeUpdate();
return (rows == 1 ? ActionResult.ok() : ActionResult.error(I18NDict.Error.SQL_ERROR));
return (rows == 1 ? ActionResult.ok() : ActionResult.error(I18NDict.Error.SQL));
} catch (SQLException e) {
logger.warning("Couldn't delete profile: " + e.getMessage());
return ActionResult.error(I18NDict.Error.SQL_ERROR);
return ActionResult.error(I18NDict.Error.SQL);
}
}

View file

@ -58,15 +58,13 @@ public class MySQLStorageProvider implements StorageProvider {
private void createTable() throws SQLException {
final Connection connection = getConnection();
String query = "CREATE TABLE IF NOT EXISTS %s.DATA " +
"(uuid varchar(36) NOT NULL," +
"name varchar(16)," +
"skin varchar(16)," +
"locale char(2) NOT NULL," +
"bungeecord boolean NOT NULL," +
"PRIMARY KEY (uuid))";
query = query.replace("%s", schemaName);
final String query = "CREATE TABLE IF NOT EXISTS %s.DATA ".replace("%s", schemaName) +
"(uuid varchar(36) NOT NULL," +
"name varchar(16)," +
"skin varchar(16)," +
"locale char(2) NOT NULL," +
"bungeecord boolean NOT NULL," +
"PRIMARY KEY (uuid))";
final PreparedStatement statement = connection.prepareStatement(query);
statement.executeUpdate();
@ -74,9 +72,7 @@ public class MySQLStorageProvider implements StorageProvider {
private void createDatabase() throws SQLException {
final Connection connection = getConnection();
String query = "CREATE DATABASE IF NOT EXISTS %s";
query = query.replace("%s", schemaName);
final String query = "CREATE DATABASE IF NOT EXISTS %s".replace("%s", schemaName);
final PreparedStatement statement = connection.prepareStatement(query);
statement.executeUpdate();

View file

@ -51,7 +51,7 @@ public class RedisCache extends Cache {
public Optional<NickoProfile> retrieve(UUID uuid) {
try (Jedis jedis = provider.getJedis()) {
// 08/29/23: what the fuck was I talking about?
// TODO (Ineanto, 05/20/23): Check if cached before because Jedis returns a bulk reply so this is unsafe
// old_todo (Ineanto, 05/20/23): Check if cached before because Jedis returns a bulk reply so this is unsafe
final String data = jedis.get("nicko:" + uuid.toString());
final NickoProfile profile = gson.fromJson(data, NickoProfile.class);
return Optional.of(profile);

View file

@ -70,19 +70,4 @@ public abstract class AbstractPacket {
public void broadcastPacket() {
ProtocolLibrary.getProtocolManager().broadcastServerPacket(getHandle());
}
/**
* Simulate receiving the current packet from the given sender.
*
* @param sender - the sender.
* @throws RuntimeException if the packet cannot be received.
*/
public void receivePacket(Player sender) {
try {
ProtocolLibrary.getProtocolManager().receiveClientPacket(sender,
getHandle());
} catch (Exception e) {
throw new RuntimeException("Cannot receive packet.", e);
}
}
}

View file

@ -20,15 +20,6 @@ public class WrapperPlayServerEntityDestroy extends AbstractPacket {
handle.getModifier().writeDefaults();
}
/**
* Gets a list of entity ids to remove
*
* @return 'entityIds' to remove
*/
public IntList getEntityIds() {
return this.handle.getModifier().withType(IntList.class, Converters.passthrough(IntList.class)).read(0);
}
/**
* Sets the list of entity ids to remove
*

View file

@ -3,37 +3,21 @@ package xyz.ineanto.nicko.wrapper;
import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.events.InternalStructure;
import com.comphenix.protocol.events.PacketContainer;
import com.comphenix.protocol.utility.MinecraftReflection;
import com.comphenix.protocol.reflect.StructureModifier;
import com.comphenix.protocol.utility.MinecraftVersion;
import com.comphenix.protocol.wrappers.BukkitConverters;
import com.comphenix.protocol.wrappers.EnumWrappers;
import com.comphenix.protocol.wrappers.MinecraftKey;
import com.google.common.hash.Hashing;
import org.bukkit.Difficulty;
import org.bukkit.GameMode;
import org.bukkit.World;
/**
* Up-to-date version of the Wrapper class
* for the PacketPlayServerRespawn.
* PacketPlayServerRespawn Wrapper class (1.19 to 1.20.2)
*
* @author ineanto, based on work from dmulloy2 and Kristian S. Strangeland
* <p>
* <p>
* Packet changes history (not accurate)
* <p>
* In 1.20.2, all the fields were replaced with a
* single "CommonPlayerSpawnInfo" record object.
* <p>
* The dimension field was changed numerous times:
* - 1.8 through 1.17 (?) required an integer,
* - 1.18 need an instance of a Holder of a ResourceKey,
* - 1.19 and after dropped this requirement.
* N.b.: this field is a nightmare please mojang stop refactoring
* your code to change things that were working perfectly fine before
* <p>
* The Seed field was added in 1.15.
* The Difficulty field was removed in 1.14.
*/
public class WrapperPlayServerRespawn extends AbstractPacket {
public static final PacketType TYPE = PacketType.Play.Server.RESPAWN;
@ -51,28 +35,10 @@ public class WrapperPlayServerRespawn extends AbstractPacket {
public void setDimension(World value) {
if (MinecraftVersion.CONFIG_PHASE_PROTOCOL_UPDATE.atOrAbove()) {
// 1.20.2
final InternalStructure dimensionType = commonPlayerSpawnInfoStructure.getStructures().read(0);
dimensionType.getMinecraftKeys().writeSafely(0, new MinecraftKey("minecraft", "dimension_type"));
dimensionType.getMinecraftKeys().writeSafely(1, new MinecraftKey("minecraft", "overworld"));
commonPlayerSpawnInfoStructure.getStructures().writeSafely(0, dimensionType);
commonPlayerSpawnInfoStructure.getWorldKeys().writeSafely(0, value);
writeDimensionToStructure(value, commonPlayerSpawnInfoStructure.getStructures(), commonPlayerSpawnInfoStructure.getWorldKeys());
} else if (MinecraftVersion.WILD_UPDATE.atOrAbove()) {
// 1.19 to 1.20.1
// Thank you lukalt!
final InternalStructure dimensionType = handle.getStructures().read(0);
dimensionType.getMinecraftKeys().writeSafely(0, new MinecraftKey("minecraft", "dimension_type"));
dimensionType.getMinecraftKeys().writeSafely(1, new MinecraftKey("minecraft", "overworld"));
handle.getStructures().writeSafely(0, dimensionType);
handle.getWorldKeys().writeSafely(0, value);
} else if (MinecraftVersion.CAVES_CLIFFS_2.atOrAbove()) {
// 1.18
handle.getHolders(
MinecraftReflection.getDimensionManager(),
BukkitConverters.getDimensionConverter()
).writeSafely(0, value);
} else {
// 1.17 and below (untested)
handle.getDimensions().writeSafely(0, value.getEnvironment().ordinal());
// 1.19 to 1.20.1, props to lukalt for helping me figure this out.
writeDimensionToStructure(value, handle.getStructures(), handle.getWorldKeys());
}
}
@ -81,7 +47,6 @@ public class WrapperPlayServerRespawn extends AbstractPacket {
commonPlayerSpawnInfoStructure.getGameModes().writeSafely(0, EnumWrappers.NativeGameMode.fromBukkit(value));
return;
}
handle.getGameModes().writeSafely(0, EnumWrappers.NativeGameMode.fromBukkit(value));
}
@ -103,14 +68,16 @@ public class WrapperPlayServerRespawn extends AbstractPacket {
}
public void setSeed(long value) {
if (MinecraftVersion.BEE_UPDATE.atOrAbove() && !MinecraftVersion.CONFIG_PHASE_PROTOCOL_UPDATE.atOrAbove()) {
if (MinecraftVersion.WILD_UPDATE.atOrAbove() && !MinecraftVersion.CONFIG_PHASE_PROTOCOL_UPDATE.atOrAbove()) {
handle.getLongs().writeSafely(0, Hashing.sha256().hashLong(value).asLong());
}
}
public void setDifficulty(Difficulty difficulty) {
if (difficulty != null && !MinecraftVersion.VILLAGE_UPDATE.atOrAbove()) {
handle.getDifficulties().writeSafely(0, EnumWrappers.Difficulty.valueOf(difficulty.name()));
}
private void writeDimensionToStructure(World value, StructureModifier<InternalStructure> structures, StructureModifier<World> worldKeys) {
final InternalStructure dimensionType = structures.read(0);
dimensionType.getMinecraftKeys().writeSafely(0, new MinecraftKey("minecraft", "dimension_type"));
dimensionType.getMinecraftKeys().writeSafely(1, new MinecraftKey("minecraft", "overworld"));
structures.writeSafely(0, dimensionType);
worldKeys.writeSafely(0, value);
}
}

View file

@ -35,8 +35,8 @@ public class ItemTranslationTest {
public void translateItemTranslationWithoutLore() {
final I18N i18n = new I18N(Locale.FRENCH);
final ItemTranslation translation = i18n.fetchTranslation(I18NDict.GUI.GO_BACK);
assertTrue(translation.getLore().isEmpty());
assertEquals(translation.getName(), "Retour");
assertTrue(translation.lore().isEmpty());
assertEquals(translation.name(), "Retour");
}
@Test
@ -44,10 +44,10 @@ public class ItemTranslationTest {
public void translateItemLore() {
final I18N i18n = new I18N(Locale.FRENCH);
final ItemTranslation translation = i18n.fetchTranslation(I18NDict.GUI.Admin.Cache.STATISTICS, "1", "1");
assertFalse(translation.getLore().isEmpty());
assertEquals("§fNombre de requêtes: §b1", translation.getLore().get(0));
assertEquals("§fNb. de skin dans le cache: §b1", translation.getLore().get(1));
assertEquals("§8§oLe cache est vidé toutes les 24 heures.", translation.getLore().get(2));
assertFalse(translation.lore().isEmpty());
assertEquals("§fNombre de requêtes: §b1", translation.lore().get(0));
assertEquals("§fNb. de skin dans le cache: §b1", translation.lore().get(1));
assertEquals("§8§oLe cache est vidé toutes les 24 heures.", translation.lore().get(2));
}
@AfterAll

View file

@ -1,7 +1,6 @@
package xyz.ineanto.nicko.test.i18n;
import be.seeseemelk.mockbukkit.MockBukkit;
import be.seeseemelk.mockbukkit.entity.PlayerMock;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.DisplayName;
@ -16,8 +15,6 @@ import xyz.ineanto.nicko.i18n.Locale;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class TranslationTest {
private static PlayerMock player;
@BeforeAll
public static void setup() {
final Configuration config = new Configuration(