Revision ID System

- Automatically update old items by assigning different revision IDs for your templates. More about this feature on the wiki.
- config.yml version detection. This will help users update their config file when we change things!
This commit is contained in:
ASangarin 2020-11-28 18:50:41 +01:00
parent dadb2a4277
commit 8149cb6ca2
8 changed files with 80 additions and 54 deletions

View File

@ -4,7 +4,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>net.Indyuce</groupId>
<artifactId>MMOItems</artifactId>
<version>6.3.1</version>
<version>6.4</version>
<name>MMOItems</name>
<description>A great item solution for your RPG server.</description>

View File

@ -153,8 +153,12 @@ public class MMOItems extends JavaPlugin {
public void onEnable() {
new SpigotPlugin(39267, this).checkForUpdate();
// Change this line if you change the config version!!!
if((int) (getConfig().getDouble("config-version") * 10) != 14)
final int configVersion = getConfig().contains("config-version", true) ? getConfig().getInt("config-version") : -1;
final int defConfigVersion = getConfig().getDefaults().getInt("config-version");
if(configVersion != defConfigVersion) {
getLogger().warning("You may be using an outdated config.yml!");
getLogger().warning("(Your config version: '" + configVersion + "' | Expected config version: '" + defConfigVersion + "')");
}
new MMOItemsMetrics();

View File

@ -2,7 +2,6 @@ package net.Indyuce.mmoitems.api;
import java.io.File;
import java.io.IOException;
import java.util.UUID;
import java.util.logging.Level;
import org.bukkit.configuration.file.FileConfiguration;

View File

@ -27,17 +27,17 @@ public class ItemModInstance {
this.nbtItem = nbt;
}
public ItemModInstance applySoulbound(Player p) {
return applySoulbound(p, MMOItems.plugin.getConfig().getInt("soulbound.auto-bind.level", 1));
public void applySoulbound(Player p) {
applySoulbound(p, MMOItems.plugin.getConfig().getInt("soulbound.auto-bind.level", 1));
}
public ItemModInstance applySoulbound(Player p, int level) {
getMMO().setData(ItemStats.SOULBOUND, ((Soulbound) ItemStats.SOULBOUND).newSoulboundData(p.getUniqueId(), p.getName(), level));
return this;
public void applySoulbound(Player p, int level) {
getMMO().setData(ItemStats.SOULBOUND, ((Soulbound) ItemStats.SOULBOUND)
.newSoulboundData(p.getUniqueId(), p.getName(), level));
}
public ItemModInstance reforge(Player p) {
return reforge(PlayerData.get(p).getRPG());
public void reforge(Player p) {
reforge(p == null ? null : PlayerData.get(p).getRPG());
}
/**
@ -45,15 +45,15 @@ public class ItemModInstance {
* If empty, it will use the old items level
* and tier, or default values if needed.
*/
public ItemModInstance reforge(RPGPlayer player) {
public void reforge(RPGPlayer player) {
MMOItemTemplate template = MMOItems.plugin.getTemplates().getTemplate(getMMO().getType(), getMMO().getId());
if(player == null) {
int level = getMMO().hasData(ItemStats.ITEM_LEVEL) ? (int)
((DoubleData) getMMO().getData(ItemStats.ITEM_LEVEL)).getValue() : 1;
ItemTier tier = MMOItems.plugin.getTiers().get(getMMO().getData(ItemStats.TIER).toString());
ItemTier tier = getMMO().hasData(ItemStats.TIER) ?
MMOItems.plugin.getTiers().get(getMMO().getData(ItemStats.TIER).toString()) : null;
mmoItem = template.newBuilder(level, tier).build();
} else mmoItem = template.newBuilder(player).build();
return this;
}
public boolean hasChanges() {
@ -64,6 +64,7 @@ public class ItemModInstance {
return mmoItem.newBuilder().build();
}
/* Initialize the MMOItem if it's null, else get it */
private MMOItem getMMO() {
return mmoItem == null ? mmoItem = new VolatileMMOItem(nbtItem) : mmoItem;
}

View File

@ -1,7 +1,6 @@
package net.Indyuce.mmoitems.listener;
import net.Indyuce.mmoitems.MMOItems;
import net.Indyuce.mmoitems.api.player.RPGPlayer;
import net.Indyuce.mmoitems.api.util.ItemModInstance;
import net.mmogroup.mmolib.api.item.NBTItem;
import org.bukkit.entity.EntityType;
@ -11,60 +10,83 @@ import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityPickupItemEvent;
import org.bukkit.event.inventory.CraftItemEvent;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryType;
import org.bukkit.event.player.PlayerDropItemEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.inventory.ItemStack;
public class ItemListener implements Listener {
@EventHandler(ignoreCancelled = true)
private void itemPickup(EntityPickupItemEvent e) {
if (!e.getEntity().getType().equals(EntityType.PLAYER)) return;
NBTItem nbt = NBTItem.get(e.getItem().getItemStack());
if (!nbt.hasType()) return;
ItemModInstance mod = new ItemModInstance(nbt);
if (shouldUpdate(nbt, "pickup")) mod.reforge(MMOItems.plugin.getLanguage().rerollOnItemUpdate ? (Player) e.getEntity() : null);
if (shouldSoulbind(nbt, "pickup")) mod.applySoulbound((Player) e.getEntity());
if (mod.hasChanges()) e.getItem().setItemStack(mod.applySoulbound((Player) e.getEntity()).toStack());
ItemStack newItem = modifyItem(e.getItem().getItemStack(), (Player) e.getEntity(), "pickup");
if (newItem != null) e.getItem().setItemStack(newItem);
}
@EventHandler(ignoreCancelled = true)
private void itemCraft(CraftItemEvent e) {
NBTItem nbt = NBTItem.get(e.getCurrentItem());
if (!nbt.hasType()) return;
ItemModInstance mod = new ItemModInstance(nbt);
if (shouldSoulbind(nbt, "craft")) mod.applySoulbound((Player) e.getWhoClicked());
if (mod.hasChanges()) e.setCurrentItem(mod.toStack());
if(!(e.getWhoClicked() instanceof Player)) return;
ItemStack newItem = modifyItem(e.getCurrentItem(), (Player) e.getWhoClicked(), "craft");
if (newItem != null) e.setCurrentItem(newItem);
}
@EventHandler(ignoreCancelled = true)
private void inventoryMove(InventoryClickEvent e) {
NBTItem nbt = NBTItem.get(e.getCurrentItem());
if (!nbt.hasType()) return;
ItemModInstance mod = new ItemModInstance(nbt);
if (shouldUpdate(nbt, "click")) mod.reforge(MMOItems.plugin.getLanguage().rerollOnItemUpdate ? (Player) e.getWhoClicked() : null);
if (shouldSoulbind(nbt, "click")) mod.applySoulbound((Player) e.getWhoClicked());
if (mod.hasChanges()) e.setCurrentItem(mod.toStack());
if (e.getInventory().getType() != InventoryType.CRAFTING || !(e.getWhoClicked() instanceof Player)) return;
ItemStack newItem = modifyItem(e.getCurrentItem(), (Player) e.getWhoClicked(), "click");
if (newItem != null) e.setCurrentItem(newItem);
}
@EventHandler(ignoreCancelled = true)
public void dropItem(PlayerDropItemEvent event) {
private void dropItem(PlayerDropItemEvent event) {
NBTItem nbt = NBTItem.get(event.getItemDrop().getItemStack());
if (!MMOItems.plugin.getConfig().getBoolean("soulbound.can-drop") && nbt.hasTag("MMOITEMS_SOULBOUND"))
event.setCancelled(true);
}
@EventHandler(ignoreCancelled = true)
public void playerJoin(PlayerJoinEvent event) {
Player player = event.getPlayer();
ItemStack newItem = modifyItem(player.getEquipment().getHelmet(), player, "join");
if(newItem != null) player.getEquipment().setHelmet(newItem);
newItem = modifyItem(player.getEquipment().getChestplate(), player, "join");
if(newItem != null) player.getEquipment().setChestplate(newItem);
newItem = modifyItem(player.getEquipment().getLeggings(), player, "join");
if(newItem != null) player.getEquipment().setLeggings(newItem);
newItem = modifyItem(player.getEquipment().getBoots(), player, "join");
if(newItem != null) player.getEquipment().setBoots(newItem);
for (int j = 0; j < 9; j++) {
newItem = modifyItem(player.getInventory().getItem(j), player, "join");
if (newItem != null) player.getInventory().setItem(j, newItem);
}
newItem = modifyItem(player.getEquipment().getItemInOffHand(), player, "join");
if(newItem != null) player.getEquipment().setItemInOffHand(newItem);
}
private ItemStack modifyItem(ItemStack stack, Player player, String type) {
NBTItem nbt = NBTItem.get(stack);
if (!nbt.hasType()) return null;
ItemModInstance mod = new ItemModInstance(nbt);
if (shouldUpdate(nbt, type, player))
mod.reforge(MMOItems.plugin.getLanguage().rerollOnItemUpdate ? player : null);
if (shouldSoulbind(nbt, type)) mod.applySoulbound(player);
return mod.hasChanges() ? mod.toStack() : null;
}
/* Checks whether or not an item should be automatically soulbound */
private boolean shouldSoulbind(NBTItem nbt, String type) {
return nbt.getBoolean("MMOITEMS_AUTO_SOULBIND") && !nbt.hasTag("MMOITEMS_SOULBOUND") && !MMOItems.plugin.getConfig().getBoolean("soulbound.auto-bind.disable-on." + type);
return nbt.getBoolean("MMOITEMS_AUTO_SOULBIND") && !nbt.hasTag("MMOITEMS_SOULBOUND")
&& !MMOItems.plugin.getConfig().getBoolean("soulbound.auto-bind.disable-on." + type);
}
/* Whether or not data should be kept when updating an item to latest revision. */
private boolean shouldUpdate(NBTItem nbt, String type) {
//if()
final int templateRevId = MMOItems.plugin.getTemplates().getTemplate(nbt).getRevisionId();
final int itemRevId = nbt.hasTag("MMOITEMS_REVISION_ID") ? nbt.getInteger("MMOITEMS_REVISION_ID") : 1;
System.out.println("REV ID: " + templateRevId + " | " + itemRevId);
return templateRevId <= itemRevId;
private boolean shouldUpdate(NBTItem nbt, String type, Player p) {
return !MMOItems.plugin.getConfig().getBoolean("item-revision.disable-on." + type) &&
(MMOItems.plugin.getTemplates().getTemplate(nbt).getRevisionId() > (nbt.hasTag("MMOITEMS_REVISION_ID")
? nbt.getInteger("MMOITEMS_REVISION_ID") : 1));
}
}

View File

@ -6,7 +6,6 @@ import net.Indyuce.mmoitems.MMOUtils;
import net.Indyuce.mmoitems.api.ConfigFile;
import net.Indyuce.mmoitems.api.ability.Ability;
import net.Indyuce.mmoitems.api.ability.Ability.CastingMode;
import net.Indyuce.mmoitems.api.item.mmoitem.MMOItem;
import net.Indyuce.mmoitems.api.item.util.ConfigItem;
import net.Indyuce.mmoitems.api.item.util.ConfigItems;
import net.Indyuce.mmoitems.api.util.NumericStatFormula;

View File

@ -1,7 +1,6 @@
package net.Indyuce.mmoitems.manager;
import net.Indyuce.mmoitems.MMOItems;
import net.Indyuce.mmoitems.api.ConfigFile;
import net.Indyuce.mmoitems.api.Type;
import net.Indyuce.mmoitems.api.item.mmoitem.MMOItem;
import net.Indyuce.mmoitems.api.item.mmoitem.VolatileMMOItem;
@ -11,7 +10,6 @@ import net.mmogroup.mmolib.MMOLib;
import net.mmogroup.mmolib.api.item.NBTItem;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
@ -23,7 +21,6 @@ import org.bukkit.inventory.meta.ItemMeta;
import java.util.Arrays;
import java.util.List;
import java.util.logging.Level;
public class UpdaterManager implements Listener {
/*public UpdaterManager() {

View File

@ -1,12 +1,14 @@
# ███  ███ ███  ███  ██████  ██ ████████ ███████ ███  ███ ███████ 
# ████  ████ ████  ████ ██..██ ██    ██    ██      ████  ████ ██      
# ██ ████ ██ ██ ████ ██ ██ ██ ██  ██  █████  ██ ████ ██ ███████ 
# ██  ██  ██ ██  ██  ██ ██\__/██ ██  ██  ██     ██  ██  ██      ██ 
# ██  ██ ██  ██  ██████  ██  ██  ███████ ██  ██ ███████ 
#
# ███ ███ ███ ███ ██████ ██ ████████ ███████ ███ ███ ███████
# ████ ████ ████ ████ ██. .██ ██ ██ ██ ████ ████ ██
# ██ ████ ██ ██ ████ ██ ██ ██ ██ ██ █████ ██ ████ ██ ███████
# ██ ██ ██ ██ ██ ██ ██\__/██ ██ ██ ██ ██ ██ ██ ██
# ██ ██ ██ ██ ██████ ██ ██ ███████ ██ ██ ███████
#
# a Spigot Plugin by Team Requiem
# DO NOT TOUCH
config-version: 1.5
config-version: 3
# Notifies players with the 'mmoitems.update-notify' perm node when
# they join the server if a new update is available for download.
@ -103,6 +105,7 @@ soulbound:
pickup: false
craft: false
click: false
join: true # 'true' recommended
# Enable, disable, and customize the weapon effects here.
# Weapon effects depend on the item type & type set.
@ -265,9 +268,10 @@ item-revision:
# Here you can disable individual events for when
# Items should update when a higher revision ID is found
disable-on:
join: true
pickup: true
click: true
pickup: false
craft: true # 'true' recommended
click: false
join: false
# When I was a kid, I saw the Mona Lisa in my school art book...