diff --git a/pom.xml b/pom.xml
index 5f2b3a89..e1b4d5c9 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
4.0.0
me.zombie_striker
QualityArmory
- 2.1.2
+ 3.0.0-SNAPSHOT
QualityArmory
diff --git a/src/main/java/me/zombie_striker/customitemmanager/ArmoryBaseObject.java b/src/main/java/me/zombie_striker/customitemmanager/ArmoryBaseObject.java
deleted file mode 100644
index 1a2477bf..00000000
--- a/src/main/java/me/zombie_striker/customitemmanager/ArmoryBaseObject.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package me.zombie_striker.customitemmanager;
-
-import java.util.List;
-
-import me.zombie_striker.customitemmanager.MaterialStorage;
-import me.zombie_striker.qg.guns.utils.WeaponSounds;
-import org.bukkit.entity.Player;
-import org.bukkit.event.player.PlayerInteractEvent;
-import org.bukkit.inventory.ItemStack;
-
-public interface ArmoryBaseObject {
-
- ItemStack getItemStack();
-
- boolean is18Support();
-
- void set18Supported(boolean b);
-
- boolean onRMB(Player shooter, ItemStack usedItem);
-
- boolean onShift(Player shooter, ItemStack usedItem, boolean toggle);
-
- boolean onLMB(Player shooter, ItemStack usedItem);
-
- boolean onSwapTo(Player shooter, ItemStack usedItem);
-
- boolean onSwapAway(Player shooter, ItemStack usedItem);
-
-}
diff --git a/src/main/java/me/zombie_striker/customitemmanager/CustomBaseObject.java b/src/main/java/me/zombie_striker/customitemmanager/CustomBaseObject.java
index 3b478336..3555c9fb 100644
--- a/src/main/java/me/zombie_striker/customitemmanager/CustomBaseObject.java
+++ b/src/main/java/me/zombie_striker/customitemmanager/CustomBaseObject.java
@@ -1,157 +1,443 @@
package me.zombie_striker.customitemmanager;
+import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
-public class CustomBaseObject {
-
- private final UUID uuid = UUID.randomUUID();
- private String name;
- private MaterialStorage base;
- private List lore;
- private String displayname;
- private boolean customAnimations;
-
- private String soundOnEquip;
- private float soundOnEquipVolume = 1.0f;
- private String soundOnHit;
- private float soundOnHitVolume = 1.0f;
-
- private double price;
- private boolean enableShop = true;
- private boolean enableCrafting = true;
-
- Object[] ing = null;
- int craftingReturn = 1;
-
- public int maxItemStack = 1;
-
- public CustomBaseObject(String name, MaterialStorage storage, String displayname, List lore, boolean hasAimAnimations) {
- this.name = name;
- this.base = storage;
- this.displayname = displayname;
- this.lore = lore;
- this.customAnimations = hasAimAnimations;
- }
-
- public String getName() {
- return name;
- }
-
- public MaterialStorage getItemData() {
- return base;
- }
-
- public List getCustomLore() {
- if(lore==null) return new ArrayList<>();
- return new ArrayList<>(lore);
- }
-
- public void setCustomLore(List lore) {
- this.lore = lore;
- }
-
- public String getDisplayName() {
- return displayname;
- }
-
- public void setDisplayname(String displayname) {this.displayname = displayname;
- }
-
- public void enableBetterAimingAnimations(boolean b) {
- this.customAnimations = b;
- }
-
- boolean hasBetterAimingAnimations() {
- return this.customAnimations;
- }
-
- public String getSoundOnEquip() {
- return soundOnEquip;
- }
-
- public float getSoundOnEquipVolume() {
- return soundOnEquipVolume;
- }
-
- public String getSoundOnHit() {
- return soundOnHit;
- }
-
- public float getSoundOnHitVolume() {
- return soundOnHitVolume;
- }
-
- public void setSoundOnHit(String sound) {
- this.soundOnHit = sound;
- }
-
- public void setSoundOnEquip(String sound) {
- this.soundOnEquip = sound;
- }
-
- public void setSoundOnEquipVolume(float volume) {
- this.soundOnEquipVolume = volume;
- }
-
- public void setSoundOnHitVolume(float volume) {
- this.soundOnHitVolume = volume;
- }
-
- public double getPrice() {
- return price;
- }
-
- public void setPrice(double price) {
- this.price = price;
- }
-
- public boolean isEnableShop() {
- return enableShop;
- }
-
- public boolean isEnableCrafting() {
- return enableCrafting;
- }
-
- public void setEnableShop(boolean enableShop) {
- this.enableShop = enableShop;
- }
-
- public void setEnableCrafting(boolean enableCrafting) {
- this.enableCrafting = enableCrafting;
- }
-
- public void setIngredients(ItemStack[] ing) {
- this.ing = ing;
- }
- public void setIngredientsRaw(Object[] ing) {
- this.ing = ing;
- }
- @Deprecated
- public ItemStack[] getIngredients(){
- return (ItemStack[]) ing;
- }
- public Object[] getIngredientsRaw(){
- return ing;
- }
- public int getCraftingReturn(){
- return craftingReturn;
- }
- public void setCraftingReturn(int amount){
- this.craftingReturn = amount;
- }
- public int getMaxItemStack(){
- return maxItemStack;
- }
- public void setMaxItemStack(int amount){
- maxItemStack = amount;
- }
-
- public UUID getUuid() {
- return uuid;
- }
+/**
+ * Abstract base class for custom items/objects in the CustomItemManager system.
+ * Provides core functionality for custom items including identification,
+ * display properties,
+ * sounds, shop/crafting settings, and interaction handlers.
+ */
+public abstract class CustomBaseObject {
+
+ private final UUID uuid = UUID.randomUUID();
+ private String name;
+ private MaterialStorage base;
+ private List lore;
+ private String displayname;
+ private boolean customAnimations;
+
+ private String soundOnEquip;
+ private float soundOnEquipVolume = 1.0f;
+ private String soundOnHit;
+ private float soundOnHitVolume = 1.0f;
+
+ private double price;
+ private boolean enableShop = true;
+ private boolean enableCrafting = true;
+
+ Object[] ing = null;
+ int craftingReturn = 1;
+
+ public int maxItemStack = 1;
+
+ /**
+ * Constructs a new CustomBaseObject with the specified properties.
+ *
+ * @param name The internal name/ID of the custom object
+ * @param storage The material storage data
+ * @param displayname The display name shown in-game
+ * @param lore The item's lore text
+ * @param hasAimAnimations Whether this item uses custom aim animations
+ */
+ public CustomBaseObject(String name, MaterialStorage storage, String displayname, List lore,
+ boolean hasAimAnimations) {
+ this.name = name;
+ this.base = storage;
+ this.displayname = displayname;
+ this.lore = lore;
+ this.customAnimations = hasAimAnimations;
+ }
+
+ /**
+ * Gets the internal name/ID of this custom object.
+ *
+ * @return The name of this custom object
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Gets the material storage data for this item.
+ *
+ * @return The MaterialStorage object containing item data
+ */
+ public MaterialStorage getItemData() {
+ return base;
+ }
+
+ /**
+ * Gets a copy of this item's lore text.
+ *
+ * @return A new ArrayList containing the lore text
+ */
+ public List getCustomLore() {
+ if (lore == null)
+ return new ArrayList<>();
+ return new ArrayList<>(lore);
+ }
+
+ /**
+ * Sets the lore text for this item.
+ *
+ * @param lore The new lore text
+ */
+ public void setCustomLore(List lore) {
+ this.lore = lore;
+ }
+
+ /**
+ * Gets the display name shown in-game.
+ *
+ * @return The item's display name
+ */
+ public String getDisplayName() {
+ return displayname;
+ }
+
+ /**
+ * Sets the display name shown in-game.
+ *
+ * @param displayName The new display name
+ */
+ public void setDisplayname(String displayName) {
+ this.displayname = displayName;
+ }
+
+ /**
+ * Enables or disables custom aiming animations.
+ *
+ * @param enable True to enable, false to disable
+ */
+ public void enableBetterAimingAnimations(boolean enable) {
+ this.customAnimations = enable;
+ }
+
+ /**
+ * Checks if custom aiming animations are enabled.
+ *
+ * @return True if enabled, false if disabled
+ */
+ boolean hasBetterAimingAnimations() {
+ return this.customAnimations;
+ }
+
+ /**
+ * Gets the sound played when equipping this item.
+ *
+ * @return The equip sound string
+ */
+ public String getSoundOnEquip() {
+ return soundOnEquip;
+ }
+
+ /**
+ * Gets the volume of the sound played when equipping this item.
+ *
+ * @return The volume of the equip sound
+ */
+ public float getSoundOnEquipVolume() {
+ return soundOnEquipVolume;
+ }
+
+ /**
+ * When true, {@link #onSwapTo} is responsible for playing the equip sound so listeners should not play it again.
+ */
+ public boolean handlesEquipSound() {
+ return false;
+ }
+
+ /**
+ * Gets the sound played when hitting with this item.
+ *
+ * @return The hit sound string
+ */
+ public String getSoundOnHit() {
+ return soundOnHit;
+ }
+
+ /**
+ * Gets the volume of the sound played when hitting with this item.
+ *
+ * @return The volume of the hit sound
+ */
+ public float getSoundOnHitVolume() {
+ return soundOnHitVolume;
+ }
+
+ /**
+ * Sets the sound played when equipping this item.
+ *
+ * @param sound The sound string to play
+ */
+ public void setSoundOnEquip(String sound) {
+ this.soundOnEquip = sound;
+ }
+
+ /**
+ * Sets the volume of the sound played when equipping this item.
+ *
+ * @param volume The volume of the sound
+ */
+ public void setSoundOnEquipVolume(float volume) {
+ this.soundOnEquipVolume = volume;
+ }
+
+ /**
+ * Sets the sound played when hitting with this item.
+ *
+ * @param sound The sound string to play
+ */
+ public void setSoundOnHit(String sound) {
+ this.soundOnHit = sound;
+ }
+
+ /**
+ * Sets the volume of the sound played when hitting with this item.
+ *
+ * @param volume The volume of the sound
+ */
+ public void setSoundOnHitVolume(float volume) {
+ this.soundOnHitVolume = volume;
+ }
+
+ /**
+ * Gets the shop price of this item.
+ *
+ * @return The item's price
+ */
+ public double getPrice() {
+ return price;
+ }
+
+ /**
+ * Sets the shop price of this item.
+ *
+ * @param price The new price
+ */
+ public void setPrice(double price) {
+ this.price = price;
+ }
+
+ /**
+ * Checks if this item can be purchased in the shop.
+ *
+ * @return True if purchasable, false if not
+ */
+ public boolean isEnableShop() {
+ return enableShop;
+ }
+
+ /**
+ * Checks if this item can be crafted.
+ *
+ * @return True if craftable, false if not
+ */
+ public boolean isEnableCrafting() {
+ return enableCrafting;
+ }
+
+ /**
+ * Sets whether this item can be purchased in the shop.
+ *
+ * @param enableShop True to enable shop purchases, false to disable
+ */
+ public void setEnableShop(boolean enableShop) {
+ this.enableShop = enableShop;
+ }
+
+ /**
+ * Sets whether this item can be crafted.
+ *
+ * @param enableCrafting True to enable crafting, false to disable
+ */
+ public void setEnableCrafting(boolean enableCrafting) {
+ this.enableCrafting = enableCrafting;
+ }
+
+ /**
+ * Sets the crafting ingredients for this item.
+ *
+ * @param ing Array of ItemStacks used as ingredients
+ */
+ public void setIngredients(ItemStack[] ing) {
+ if (ing == null) {
+ this.ing = null;
+ return;
+ }
+ Object[] copy = new Object[ing.length];
+ for (int i = 0; i < ing.length; i++) {
+ copy[i] = ing[i] == null ? null : ing[i].clone();
+ }
+ this.ing = copy;
+ }
+
+ /**
+ * Sets the raw crafting ingredients for this item.
+ *
+ * @param ing Array of Objects used as ingredients
+ * @see CustomBaseObject#getIngredientsRaw()
+ */
+ public void setIngredientsRaw(Object[] ing) {
+ this.ing = ing == null ? null : ing.clone();
+ }
+
+ /**
+ * Gets the crafting ingredients.
+ *
+ * @return Array of ItemStacks used as ingredients
+ * @deprecated Use {@link #getIngredientsRaw()} instead.
+ */
+ @Deprecated
+ public ItemStack[] getIngredients() {
+ if (ing == null)
+ return new ItemStack[0];
+
+ ItemStack[] stacks = new ItemStack[ing.length];
+
+ for (int i = 0; i < ing.length; i++) {
+ if (ing[i] instanceof ItemStack) {
+ stacks[i] = (ItemStack) ing[i];
+ } else {
+ stacks[i] = null;
+ }
+ }
+
+ return stacks;
+ }
+
+ /**
+ * Gets the raw crafting ingredients.
+ *
+ * @return Array of Object ingredients. This can be either an {@link ItemStack} or a {@link String} for custom items.
+ */
+ public Object[] getIngredientsRaw() {
+ return ing == null ? null : ing.clone();
+ }
+
+ /**
+ * Gets the number of items returned from crafting.
+ *
+ * @return The crafting return amount
+ */
+ public int getCraftingReturn() {
+ return craftingReturn;
+ }
+
+ /**
+ * Sets the number of items returned from crafting.
+ *
+ * @param amount The new crafting return amount
+ */
+ public void setCraftingReturn(int amount) {
+ this.craftingReturn = amount;
+ }
+
+ /**
+ * Gets the maximum stack size for this item.
+ *
+ * @return The maximum stack size
+ */
+ public int getMaxItemStack() {
+ return maxItemStack;
+ }
+
+ /**
+ * Sets the maximum stack size for this item.
+ *
+ * @param amount The new maximum stack size
+ */
+ public void setMaxItemStack(int amount) {
+ maxItemStack = amount;
+ }
+
+ /**
+ * Returns the UUID of this custom object.
+ *
+ * @return the UUID of this object.
+ */
+ public UUID getUuid() {
+ return uuid;
+ }
+
+ /**
+ * Returns the {@link ItemStack} associated with this custom object.
+ *
+ * @return the {@code ItemStack} representing this object.
+ */
+ public abstract ItemStack getItemStack();
+
+ /**
+ * Checks whether this object supports Minecraft 1.8 mechanics or compatibility.
+ *
+ * @return {@code true} if 1.8 support is enabled; {@code false} otherwise.
+ */
+ public abstract boolean is18Support();
+
+ /**
+ * Sets whether this object supports Minecraft 1.8 mechanics or compatibility.
+ *
+ * @param b {@code true} to enable 1.8 support; {@code false} to disable it.
+ */
+ public abstract void set18Supported(boolean b);
+
+ /**
+ * Called when the player right-clicks (RMB).
+ *
+ * @param shooter the player using the item.
+ * @param usedItem the {@link ItemStack} being used.
+ * @return {@code true} if the action was successfully handled; {@code false}
+ * otherwise.
+ */
+ public abstract boolean onRMB(Player shooter, ItemStack usedItem);
+
+ /**
+ * Called when the player toggles shift.
+ *
+ * @param shooter the player using the item.
+ * @param usedItem the {@link ItemStack} being used.
+ * @param toggle a boolean that can be used to enable or disable a toggleable
+ * action/state.
+ * @return {@code true} if the action was successfully handled; {@code false}
+ * otherwise.
+ */
+ public abstract boolean onShift(Player shooter, ItemStack usedItem, boolean toggle);
+
+ /**
+ * Called when the player left-clicks (LMB).
+ *
+ * @param shooter the player using the item.
+ * @param usedItem the {@link ItemStack} being used.
+ * @return {@code true} if the action was successfully handled; {@code false}
+ * otherwise.
+ */
+ public abstract boolean onLMB(Player shooter, ItemStack usedItem);
+
+ /**
+ * Called when the player swaps to this item (e.g., changes to this item in
+ * hand).
+ *
+ * @param shooter the player equipping the item.
+ * @param usedItem the {@link ItemStack} being equipped.
+ * @return {@code true} if the action was successfully handled; {@code false}
+ * otherwise.
+ */
+ public abstract boolean onSwapTo(Player shooter, ItemStack usedItem);
+
+ /**
+ * Called when the player swaps away from this item (e.g., changes to a
+ * different item).
+ *
+ * @param shooter the player unequipping the item.
+ * @param usedItem the {@link ItemStack} being unequipped.
+ * @return {@code true} if the action was successfully handled; {@code false}
+ * otherwise.
+ */
+ public abstract boolean onSwapAway(Player shooter, ItemStack usedItem);
}
diff --git a/src/main/java/me/zombie_striker/customitemmanager/OLD_ItemFact.java b/src/main/java/me/zombie_striker/customitemmanager/OLD_ItemFact.java
index d2dff8d3..610e3b42 100644
--- a/src/main/java/me/zombie_striker/customitemmanager/OLD_ItemFact.java
+++ b/src/main/java/me/zombie_striker/customitemmanager/OLD_ItemFact.java
@@ -6,7 +6,6 @@
import me.zombie_striker.qg.guns.Gun;
import me.zombie_striker.qg.handlers.IronsightsHandler;
import org.bukkit.ChatColor;
-import org.bukkit.entity.Item;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
@@ -94,13 +93,13 @@ public static ItemStack getIronSights() {
im = ironsights.getItemMeta();
}
im.setDisplayName(IronsightsHandler.ironsightsDisplay);
- if (QAMain.ITEM_enableUnbreakable) {
+ if (QAMain.getConfiguration().items.ITEM_enableUnbreakable) {
try {
im.setUnbreakable(true);
} catch (Error | Exception e3423) { }
}
try {
- if (QAMain.ITEM_enableUnbreakable) {
+ if (QAMain.getConfiguration().items.ITEM_enableUnbreakable) {
im.addItemFlags(org.bukkit.inventory.ItemFlag.HIDE_UNBREAKABLE);
}
im.addItemFlags(org.bukkit.inventory.ItemFlag.HIDE_ATTRIBUTES);
diff --git a/src/main/java/me/zombie_striker/customitemmanager/qa/versions/V1_13/CustomGunItem.java b/src/main/java/me/zombie_striker/customitemmanager/qa/versions/V1_13/CustomGunItem.java
index 5f01a5c5..b3aafeb2 100644
--- a/src/main/java/me/zombie_striker/customitemmanager/qa/versions/V1_13/CustomGunItem.java
+++ b/src/main/java/me/zombie_striker/customitemmanager/qa/versions/V1_13/CustomGunItem.java
@@ -1,6 +1,9 @@
package me.zombie_striker.customitemmanager.qa.versions.V1_13;
-import me.zombie_striker.customitemmanager.*;
+import me.zombie_striker.customitemmanager.CustomBaseObject;
+import me.zombie_striker.customitemmanager.CustomItemManager;
+import me.zombie_striker.customitemmanager.MaterialStorage;
+import me.zombie_striker.customitemmanager.OLD_ItemFact;
import me.zombie_striker.customitemmanager.pack.StaticPackProvider;
import me.zombie_striker.customitemmanager.qa.AbstractCustomGunItem;
import me.zombie_striker.qg.QAMain;
@@ -8,13 +11,13 @@
import me.zombie_striker.qg.armor.ArmorObject;
import me.zombie_striker.qg.config.GunYMLCreator;
import me.zombie_striker.qg.guns.Gun;
+import me.zombie_striker.qg.guns.chargers.ChargingManager;
import me.zombie_striker.qg.guns.projectiles.ProjectileManager;
+import me.zombie_striker.qg.guns.reloaders.ReloadingManager;
import me.zombie_striker.qg.guns.utils.WeaponSounds;
import me.zombie_striker.qg.guns.utils.WeaponType;
import me.zombie_striker.qg.handlers.IronsightsHandler;
import me.zombie_striker.qg.handlers.MultiVersionLookup;
-import me.zombie_striker.qg.guns.chargers.ChargingManager;
-import me.zombie_striker.qg.guns.reloaders.ReloadingManager;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Material;
@@ -65,14 +68,15 @@ public ItemStack getItem(MaterialStorage ms) {
OLD_ItemFact.addVariantData(im,lore,base);
im.setLore(lore);
- if (QAMain.ITEM_enableUnbreakable) {
+ boolean enableUnbreakable = QAMain.getConfiguration().items.ITEM_enableUnbreakable;
+ if (enableUnbreakable) {
try {
im.setUnbreakable(true);
} catch (Error | Exception e34) {
}
}
try {
- if (QAMain.ITEM_enableUnbreakable) {
+ if (enableUnbreakable) {
im.addItemFlags(org.bukkit.inventory.ItemFlag.HIDE_UNBREAKABLE);
}
im.addItemFlags(org.bukkit.inventory.ItemFlag.HIDE_ATTRIBUTES);
diff --git a/src/main/java/me/zombie_striker/customitemmanager/qa/versions/V1_14/CustomGunItem.java b/src/main/java/me/zombie_striker/customitemmanager/qa/versions/V1_14/CustomGunItem.java
index a14cf0d7..aa291b7a 100644
--- a/src/main/java/me/zombie_striker/customitemmanager/qa/versions/V1_14/CustomGunItem.java
+++ b/src/main/java/me/zombie_striker/customitemmanager/qa/versions/V1_14/CustomGunItem.java
@@ -4,7 +4,10 @@
import com.cryptomorin.xseries.profiles.builder.XSkull;
import com.cryptomorin.xseries.profiles.objects.ProfileInputType;
import com.cryptomorin.xseries.profiles.objects.Profileable;
-import me.zombie_striker.customitemmanager.*;
+import me.zombie_striker.customitemmanager.CustomBaseObject;
+import me.zombie_striker.customitemmanager.CustomItemManager;
+import me.zombie_striker.customitemmanager.MaterialStorage;
+import me.zombie_striker.customitemmanager.OLD_ItemFact;
import me.zombie_striker.customitemmanager.pack.MultiVersionPackProvider;
import me.zombie_striker.customitemmanager.qa.AbstractCustomGunItem;
import me.zombie_striker.qg.QAMain;
@@ -13,13 +16,13 @@
import me.zombie_striker.qg.armor.ArmorObject;
import me.zombie_striker.qg.config.GunYMLCreator;
import me.zombie_striker.qg.guns.Gun;
+import me.zombie_striker.qg.guns.chargers.ChargingManager;
import me.zombie_striker.qg.guns.projectiles.ProjectileManager;
+import me.zombie_striker.qg.guns.reloaders.ReloadingManager;
import me.zombie_striker.qg.guns.utils.WeaponSounds;
import me.zombie_striker.qg.guns.utils.WeaponType;
import me.zombie_striker.qg.handlers.IronsightsHandler;
import me.zombie_striker.qg.handlers.MultiVersionLookup;
-import me.zombie_striker.qg.guns.chargers.ChargingManager;
-import me.zombie_striker.qg.guns.reloaders.ReloadingManager;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Material;
@@ -105,14 +108,15 @@ public ItemStack getItem(MaterialStorage ms) {
im.addAttributeModifier(XAttribute.ATTACK_SPEED.get(), modifier);
}
- if (QAMain.ITEM_enableUnbreakable) {
+ boolean enableUnbreakable = QAMain.getConfiguration().items.ITEM_enableUnbreakable;
+ if (enableUnbreakable) {
try {
im.setUnbreakable(true);
} catch (Error | Exception e34) {
}
}
try {
- if (QAMain.ITEM_enableUnbreakable) {
+ if (enableUnbreakable) {
im.addItemFlags(org.bukkit.inventory.ItemFlag.HIDE_UNBREAKABLE);
}
im.addItemFlags(org.bukkit.inventory.ItemFlag.HIDE_ATTRIBUTES);
diff --git a/src/main/java/me/zombie_striker/customitemmanager/qa/versions/V1_8/CustomGunItem.java b/src/main/java/me/zombie_striker/customitemmanager/qa/versions/V1_8/CustomGunItem.java
index bf326d42..abe1ad9b 100644
--- a/src/main/java/me/zombie_striker/customitemmanager/qa/versions/V1_8/CustomGunItem.java
+++ b/src/main/java/me/zombie_striker/customitemmanager/qa/versions/V1_8/CustomGunItem.java
@@ -65,7 +65,7 @@ public ItemStack getItem(MaterialStorage ms) {
OLD_ItemFact.addVariantData(im,lore,base);
im.setLore(lore);
- if (QAMain.ITEM_enableUnbreakable) {
+ if (QAMain.getConfiguration().items.ITEM_enableUnbreakable) {
try {
im.setUnbreakable(true);
} catch (Error | Exception e34) {
@@ -77,7 +77,7 @@ public ItemStack getItem(MaterialStorage ms) {
}
}
try {
- if (QAMain.ITEM_enableUnbreakable) {
+ if (QAMain.getConfiguration().items.ITEM_enableUnbreakable) {
im.addItemFlags(org.bukkit.inventory.ItemFlag.HIDE_UNBREAKABLE);
}
im.addItemFlags(org.bukkit.inventory.ItemFlag.HIDE_ATTRIBUTES);
diff --git a/src/main/java/me/zombie_striker/qg/QAMain.java b/src/main/java/me/zombie_striker/qg/QAMain.java
index e5ce5950..e9247b65 100644
--- a/src/main/java/me/zombie_striker/qg/QAMain.java
+++ b/src/main/java/me/zombie_striker/qg/QAMain.java
@@ -20,10 +20,7 @@
import me.zombie_striker.qg.armor.ArmorObject;
import me.zombie_striker.qg.attachments.AttachmentBase;
import me.zombie_striker.qg.boundingbox.BoundingBoxManager;
-import me.zombie_striker.qg.config.CommentYamlConfiguration;
-import me.zombie_striker.qg.config.GunYMLCreator;
-import me.zombie_striker.qg.config.GunYMLLoader;
-import me.zombie_striker.qg.config.MessagesYML;
+import me.zombie_striker.qg.config.*;
import me.zombie_striker.qg.gui.MenuManager;
import me.zombie_striker.qg.guns.Gun;
import me.zombie_striker.qg.guns.chargers.*;
@@ -33,7 +30,6 @@
import me.zombie_striker.qg.guns.reloaders.SingleBulletReloader;
import me.zombie_striker.qg.guns.reloaders.SlideReloader;
import me.zombie_striker.qg.guns.utils.GunRefillerRunnable;
-import me.zombie_striker.qg.guns.utils.WeaponSounds;
import me.zombie_striker.qg.handlers.*;
import me.zombie_striker.qg.hooks.MimicHookHandler;
import me.zombie_striker.qg.hooks.PlaceholderAPIHook;
@@ -43,8 +39,7 @@
import me.zombie_striker.qg.hooks.anticheat.VulcanHook;
import me.zombie_striker.qg.hooks.protection.ProtectionHandler;
import me.zombie_striker.qg.listener.QAListener;
-import me.zombie_striker.qg.miscitems.ThrowableItems;
-import me.zombie_striker.qg.miscitems.ThrowableItems.ThrowableHolder;
+import me.zombie_striker.qg.miscitems.ThrowableItemRegistry;
import me.zombie_striker.qg.npcs.Gunner;
import me.zombie_striker.qg.npcs.GunnerTrait;
import me.zombie_striker.qg.npcs_sentinel.SentinelQAHandler;
@@ -77,13 +72,11 @@ public class QAMain extends JavaPlugin {
private static String changelog = null;
- public static final int ViaVersionIdfor_1_8 = 106;
public static HashMap gunRegister = new LinkedHashMap<>();
public static HashMap ammoRegister = new LinkedHashMap<>();
public static HashMap miscRegister = new LinkedHashMap<>();
public static HashMap armorRegister = new LinkedHashMap<>();
-
public static HashMap craftingEntityNames = new HashMap<>();
public static HashMap lastWeaponSwitch = new HashMap<>();
@@ -98,82 +91,9 @@ public class QAMain extends JavaPlugin {
public static List namesToBypass = new ArrayList<>();
public static List interactableBlocks = new ArrayList<>();
public static List destructableBlocks = new ArrayList();
- public static int regenDestructableBlocksAfter = -1;
- public static boolean enableInteractChests = false;
- public static boolean DEBUG = false;
public static Object bulletTrail;
-
- public static boolean shouldSend = true;
- public static boolean sendOnJoin = false;
- public static boolean sendTitleOnJoin = false;
- public static boolean resourcepackInvincibility = false;
- public static double secondsTilSend = 0.0;
-
- public static boolean orderShopByPrice = false;
- public static boolean ignoreUnbreaking = false;
- public static boolean ignoreSkipping = false;
- public static boolean verboseLoadingLogging = false;
- public static boolean enableDurability = false;
- public static boolean enableArmorIgnore = false;
- public static boolean showCrashMessage = true;
- public static boolean enableRecoil = true;
- public static double bulletStep = 0.10;
- public static double gravity = 0.05;
- public static double swayModifier_Ironsights = 0.8;
- public static double swayModifier_Sneak = 0.7;
- public static double swayModifier_Walk = 1.5;
- public static double swayModifier_Run = 1.3;
- public static boolean blockbullet_leaves = false;
- public static boolean blockbullet_halfslabs = false;
- public static boolean blockbullet_door = false;
- public static boolean blockbullet_water = false;
- public static boolean blockbullet_glass = false;
- public static boolean overrideAnvil = false;
- public static boolean enableIronSightsON_RIGHT_CLICK = false;
- public static boolean SwapSneakToSingleFire = false;
- public static boolean enableBulletTrails = true;
- public static boolean reloadOnQ = true;
- public static boolean reloadOnF = true;
- public static boolean reloadOnFOnly = true;
- public static boolean unloadOnQ = false;
- public static boolean disableHotBarMessageOnShoot = false;
- public static boolean disableHotBarMessageOnReload = false;
- public static boolean disableHotBarMessageOnOutOfAmmo = false;
- public static boolean enableExplosionDamage = false;
- public static boolean enableExplosionDamageDrop = false;
- public static boolean requirePermsToShoot = false;
- public static boolean requirePermsToCraft = false;
- public static boolean requirePermsToBuy = false;
public static boolean enableEconomy = false;
- public static boolean allowGunReload = true;
- public static boolean enableBleeding = false;
- public static double bulletWound_initialbloodamount = 1500;
- public static double bulletWound_BloodIncreasePerSecond = 0.01;
- public static double bulletWound_MedkitBloodlossHealRate = 0.05;
- public static String headshot_sound = WeaponSounds.XP_ORG_PICKUP.getSoundName();
- public static String hit_sound = WeaponSounds.XP_ORG_PICKUP.getSoundName();
- public static List headshotBlacklist = new ArrayList<>();
- public static boolean HeadshotOneHit = true;
- public static boolean headshotPling = true;
- public static boolean enableHitSound = false;
public static boolean showOutOfAmmoOnItem = false;
- public static boolean showOutOfAmmoOnTitle = false;
- public static boolean showReloadOnTitle = false;
- public static boolean addGlowEffects = false;
- public static boolean enableReloadWhenOutOfAmmo = false;
- public static boolean overrideURL = false;
- public static boolean kickIfDeniedRequest = false;
- public static boolean showAmmoInXPBar = false;
- public static boolean perWeaponPermission = false;
- public static boolean perWeaponCraftPermission = false;
- public static boolean perWeaponBuyPermission = false;
- public static boolean useMoveForRecoil = true;
- public static double weaponSwitchDelay = 0;
- public static boolean allowGunHitEntities = true;
- public static boolean preventHiddenPlayers = true;
- public static boolean anticheatFix = false;
- public static boolean preventGunsInHoppers = true;
- public static int hitDistance = 5;
public static String S_NOPERM = "&c You do not have permission to do that.";
@@ -225,12 +145,6 @@ public class QAMain extends JavaPlugin {
public static String S_RESOURCEPACK_OPTIN = "By issuing this command, you have been removed from the whitelist. You will now recieve the resourcepack prompt";
public static String S_GRENADE_PULLPIN = " Pull the pin first...";
public static String S_GRENADE_PALREADYPULLPIN = "You already pulled the pin!";
- public static boolean enableCrafting = true;
- public static boolean enableShop = true;
- public static double smokeSpacing = 0.5;
- public static boolean enablePrimaryWeaponHandler = false;
- public static int primaryWeaponLimit = 2;
- public static int secondaryWeaponLimit = 2;
public static String prefix = "&8[&2QualityArmory&8]&r";
public static String S_missingIngredients = "You do not have all the materials needed to craft this.";
public static String S_noMoney = "You do not have enough money to buy this.";
@@ -242,29 +156,11 @@ public class QAMain extends JavaPlugin {
public static MessagesYML m;
public static CommentYamlConfiguration resourcepackwhitelist;
- public static String language = "en";
public static boolean hasParties = false;
- public static boolean friendlyFire = false;
public static boolean hasProtocolLib = false;
public static boolean hasViaVersion = false;
public static boolean hasViaRewind = false;
- public static boolean AUTOUPDATE = true;
- public static boolean SWAP_TO_LMB_SHOOT = true;
- public static boolean SHOW_BULLETS_LORE = false;
- public static boolean ENABLE_LORE_INFO = true;
- public static boolean ENABLE_LORE_HELP = true;
- public static boolean AutoDetectResourcepackVersion = true;
- public static boolean ITEM_enableUnbreakable = true;// TODO :stuufff
- public static boolean MANUALLYSELECT18 = false;
- public static boolean MANUALLYSELECT113 = false;
- public static boolean MANUALLYSELECT14 = false;
- public static boolean unknownTranslationKeyFixer = false;
- public static boolean enableCreationOfFiles = true;
- public static boolean changeDeathMessages = true;
public static List coloredGunScoreboard = new ArrayList();
- public static boolean blockBreakTexture = false;
- public static boolean autoarm = false;
- public static boolean restoreOffHand = false;
public static List currentlyScoping = new ArrayList<>();
private static QAMain main;
@@ -272,12 +168,17 @@ public class QAMain extends JavaPlugin {
private FileConfiguration config;
private File configFile;
private boolean saveTheConfig = false;
+ private MainConfig mainConfig;
private static MenuManager menuManager;
public static QAMain getInstance() {
return main;
}
+ public static MainConfig getConfiguration() {
+ return getInstance().mainConfig;
+ }
+
public static boolean isVersionHigherThan(int mainVersion, int secondVersion) {
return XReflection.supports(secondVersion);
}
@@ -315,7 +216,7 @@ public static void toggleNightvision(Player player, Gun g, boolean add) {
}
public static void DEBUG(String message) {
- if (DEBUG)
+ if (getConfiguration().debug.enabled)
Bukkit.broadcast(prefix + ChatColor.GREEN + " [DEBUG] " + ChatColor.RESET + message, "qualityarmory.debugmessages");
}
@@ -498,14 +399,12 @@ public static String findCraftEntityName(String itemName, String defaultName) {
@Override
public void onDisable() {
- for (Entry misc : miscRegister.entrySet()) {
- if (misc instanceof ThrowableItems) {
- for (Entry e : ThrowableItems.throwItems.entrySet()) {
- if (e.getKey() instanceof Item)
- e.getKey().remove();
- }
- }
+ List throwableEntities = new ArrayList<>(ThrowableItemRegistry.keySet());
+ for (Entity entity : throwableEntities) {
+ if (entity instanceof Item)
+ entity.remove();
}
+ ThrowableItemRegistry.clear();
for (Scoreboard s : coloredGunScoreboard)
for (Team t : s.getTeams())
@@ -522,6 +421,7 @@ public void onDisable() {
}
}
+ @Deprecated
public Object a(String path, Object def) {
if (getConfig().contains(path)) {
return getConfig().get(path);
@@ -537,6 +437,8 @@ public void onEnable() {
if (!this.getDataFolder().exists()) {
this.getDataFolder().mkdirs();
}
+ this.mainConfig = new MainConfig();
+ this.mainConfig.loadDefaults();
if (!NBT.preloadApi()) {
getLogger().severe("NBT-API wasn't initialized properly, disabling the plugin");
@@ -619,7 +521,7 @@ public void run() {
}
try {
- if (AUTOUPDATE)
+ if (getConfiguration().features.AUTOUPDATE)
GithubUpdater.autoUpdate(this, "Lorenzo0111", "QualityArmory", "QualityArmory.jar");
} catch (Exception e) {
}
@@ -628,7 +530,7 @@ public void run() {
metrics.addCustomChart(new Metrics.SimplePie("GunCount", () -> gunRegister.size() + ""));
metrics.addCustomChart(
- new Metrics.SimplePie("uses_default_resourcepack", () -> overrideURL + ""));
+ new Metrics.SimplePie("uses_default_resourcepack", () -> getConfiguration().resourcepack.overrideDefault + ""));
metrics.addCustomChart(
new Metrics.SimplePie("has_an_expansion_pack", () -> (expansionPacks.size() > 0) + ""));
if (!CustomItemManager.isUsingCustomData()) {
@@ -641,10 +543,10 @@ public void run() {
// if (p.getItemInHand().containsEnchantment(Enchantment.MENDING)) {
if (p.getItemInHand() != null && p.getItemInHand().hasItemMeta())
if (QualityArmory.isCustomItem(p.getItemInHand())) {
- if (ITEM_enableUnbreakable && (!p.getItemInHand().getItemMeta().isUnbreakable()
- && !ignoreUnbreaking)) {
+ if (getConfiguration().items.ITEM_enableUnbreakable && (!p.getItemInHand().getItemMeta().isUnbreakable()
+ && !getConfiguration().features.ignoreUnbreaking)) {
ItemStack temp = p.getItemInHand();
- int j = QualityArmory.findSafeSpot(temp, false, overrideURL);
+ int j = QualityArmory.findSafeSpot(temp, false, getConfiguration().resourcepack.overrideDefault);
temp.setDurability((short) Math.max(0, j - 1));
temp = Gun.removeCalculatedExtra(temp);
p.setItemInHand(temp);
@@ -658,10 +560,10 @@ public void run() {
if (p.getInventory().getItemInOffHand() != null
&& p.getInventory().getItemInOffHand().hasItemMeta())
if (QualityArmory.isCustomItem(p.getInventory().getItemInOffHand())) {
- if (ITEM_enableUnbreakable && (!p.getInventory().getItemInOffHand().getItemMeta()
- .isUnbreakable() && !ignoreUnbreaking)) {
+ if (getConfiguration().items.ITEM_enableUnbreakable && (!p.getInventory().getItemInOffHand().getItemMeta()
+ .isUnbreakable() && !getConfiguration().features.ignoreUnbreaking)) {
ItemStack temp = p.getInventory().getItemInOffHand();
- int j = QualityArmory.findSafeSpot(temp, false, overrideURL);
+ int j = QualityArmory.findSafeSpot(temp, false, getConfiguration().resourcepack.overrideDefault);
temp.setDurability((short) Math.max(0, j - 1));
temp = Gun.removeCalculatedExtra(temp);
p.getInventory().setItemInOffHand(temp);
@@ -681,8 +583,7 @@ public void run() {
@SuppressWarnings({"unchecked", "deprecation"})
public void reloadVals() {
- reloadConfig();
- DEBUG = (boolean) a("ENABLE-DEBUG", false);
+ this.mainConfig.reload();
new BoltactionCharger();
new BreakactionCharger();
@@ -713,13 +614,12 @@ public void reloadVals() {
// attachmentRegister.clear();
//Chris: Support more language file lang/message_xx.yml
- language = (String) a("language", "en");
File langFolder = new File(getDataFolder(), "lang");
if (langFolder.exists() && !langFolder.isDirectory()) {
langFolder.delete();
}
langFolder.mkdir();
- m = new MessagesYML(language, new File(langFolder, "message_" + language + ".yml"));
+ m = new MessagesYML(getConfiguration().general.language, new File(langFolder, "message_" + getConfiguration().general.language + ".yml"));
prefix = LocalUtils.colorize((String) m.a("Prefix", prefix));
S_ANVIL = LocalUtils.colorize((String) m.a("NoPermAnvilMessage", S_ANVIL));
S_NOPERM = LocalUtils.colorize((String) m.a("NoPerm", S_NOPERM));
@@ -826,165 +726,8 @@ public void reloadVals() {
}
- friendlyFire = (boolean) a("FriendlyFireEnabled", false);
-
- kickIfDeniedRequest = (boolean) a("KickPlayerIfDeniedResourcepack", false);
- shouldSend = (boolean) a("useDefaultResourcepack", true);
-
- enableDurability = (boolean) a("EnableWeaponDurability", false);
-
- bulletStep = (double) a("BulletDetection.step", 0.10);
-
- blockbullet_door = (boolean) a("BlockBullets.door", false);
- blockbullet_halfslabs = (boolean) a("BlockBullets.halfslabs", false);
- blockbullet_leaves = (boolean) a("BlockBullets.leaves", false);
- blockbullet_water = (boolean) a("BlockBullets.water", false);
- blockbullet_glass = (boolean) a("BlockBullets.glass", false);
-
- enableInteractChests = (boolean) a("enableInteract.Chests", false);
-
- overrideAnvil = (boolean) a("overrideAnvil", false);
-
- showCrashMessage = (boolean) a("showPossibleCrashHelpMessage", showCrashMessage);
-
- anticheatFix = (boolean) a("anticheatFix", anticheatFix);
-
- verboseLoadingLogging = (boolean) a("verboseItemLogging", verboseLoadingLogging);
-
- requirePermsToShoot = (boolean) a("enable_permssionsToShoot", requirePermsToShoot);
- requirePermsToCraft = (boolean) a("enable_permissionsToCraft", requirePermsToCraft);
- requirePermsToBuy = (boolean) a("enable_permissionsToBuy", requirePermsToBuy);
-
- sendOnJoin = (boolean) a("sendOnJoin", true);
- sendTitleOnJoin = (boolean) a("sendTitleOnJoin", false);
- resourcepackInvincibility = (boolean) a("resourcepackInvincibility", resourcepackInvincibility);
- secondsTilSend = Double.valueOf(a("SecondsTillRPIsSent", 5.0) + "");
-
- enableBulletTrails = (boolean) a("enableBulletTrails", true);
- smokeSpacing = Double.valueOf(a("BulletTrailsSpacing", 0.5) + "");
-
- enableArmorIgnore = (boolean) a("enableIgnoreArmorProtection", enableArmorIgnore);
- ignoreUnbreaking = (boolean) a("enableIgnoreUnbreakingChecks", ignoreUnbreaking);
- ignoreSkipping = (boolean) a("enableIgnoreSkipForBasegameItems", ignoreSkipping);
-
- ITEM_enableUnbreakable = (boolean) a("Items.enable_Unbreaking", ITEM_enableUnbreakable);
-
- // enableVisibleAmounts = (boolean) a("enableVisibleBulletCounts", false);
- reloadOnQ = (boolean) a("enableReloadingOnDrop", false);
- reloadOnF = (boolean) a("enableReloadingWhenSwapToOffhand", true);
- reloadOnFOnly = (boolean) a("enableReloadOnlyWhenSwapToOffhand", false);
- unloadOnQ = (boolean) a("enableUnloadingOnDrop", false);
-
- allowGunHitEntities = (boolean) a("allowGunHitEntities", true);
- preventHiddenPlayers = (boolean) a("preventHiddenPlayers", true);
- hitDistance = (int) a("hitDistance", hitDistance);
-
- preventGunsInHoppers = (boolean) a("preventGunsInHoppers", true);
-
- // showOutOfAmmoOnItem = (boolean) a("showOutOfAmmoOnItem", false);
- showOutOfAmmoOnTitle = (boolean) a("showOutOfAmmoOnTitle", false);
- showReloadOnTitle = (boolean) a("showReloadingTitle", false);
-
- showAmmoInXPBar = (boolean) a("showAmmoInXPBar", false);
- perWeaponPermission = (boolean) a("perWeaponPermission", false);
- perWeaponCraftPermission = (boolean) a("perWeaponCraftPermission", perWeaponCraftPermission);
- perWeaponBuyPermission = (boolean) a("perWeaponBuyPermission", perWeaponBuyPermission);
-
- useMoveForRecoil = (boolean) a("useMoveForRecoil", useMoveForRecoil);
-
- weaponSwitchDelay = (double) a("weaponSwitchDelay", 0.0);
-
- enableExplosionDamage = (boolean) a("enableExplosionDamage", false);
- enableExplosionDamageDrop = (boolean) a("enableExplosionDamageDrop", false);
-
- enablePrimaryWeaponHandler = (boolean) a("enablePrimaryWeaponLimiter", false);
- primaryWeaponLimit = (int) a("weaponlimiter_primaries", primaryWeaponLimit);
- secondaryWeaponLimit = (int) a("weaponlimiter_secondaries", secondaryWeaponLimit);
-
- enableCrafting = (boolean) a("enableCrafting", true);
- enableShop = (boolean) a("enableShop", true);
-
- AUTOUPDATE = (boolean) a("AUTO-UPDATE", true);
- SWAP_TO_LMB_SHOOT = !(boolean) a("Swap-Reload-and-Shooting-Controls", false);
-
- orderShopByPrice = (boolean) a("Order-Shop-By-Price", orderShopByPrice);
-
- SHOW_BULLETS_LORE = (boolean) a("enable_lore_gun-bullets", false);
- ENABLE_LORE_INFO = (boolean) a("enable_lore_gun-info_messages", true);
- ENABLE_LORE_HELP = (boolean) a("enable_lore_control-help_messages", true);
-
- HeadshotOneHit = (boolean) a("Enable_Headshot_Instantkill", HeadshotOneHit);
- headshotPling = (boolean) a("Enable_Headshot_Notification_Sound", headshotPling);
- headshot_sound = (String) a("Headshot_Notification_Sound", headshot_sound);
-
- headshotBlacklist.clear();
-
- List blacklist = (List) a("Headshot_Blacklist", new ArrayList());
- for (String s : blacklist) {
- try {
- headshotBlacklist.add(EntityType.valueOf(s));
- } catch (Error | Exception e4) {
- }
- }
-
- hit_sound = (String) a("Hit_Notification_Sound", hit_sound);
- enableHitSound = (boolean) a("Enable_Hit_Sound", enableHitSound);
-
- autoarm = (boolean) a("Enable_AutoArm_Grenades", autoarm);
-
- // ignoreArmorStands = (boolean) a("ignoreArmorStands", false);
-
- gravity = (double) a("gravityConstantForDropoffCalculations", gravity);
-
- allowGunReload = (boolean) a("allowGunReload", allowGunReload);
- AutoDetectResourcepackVersion = (boolean) a("Auto-Detect-Resourcepack", AutoDetectResourcepackVersion);
- MANUALLYSELECT18 = (boolean) a("ManuallyOverrideTo_1_8_systems",
- Bukkit.getPluginManager().isPluginEnabled("WetSponge") ? true : MANUALLYSELECT18);
- MANUALLYSELECT113 = (boolean) a("ManuallyOverrideTo_1_13_systems", MANUALLYSELECT113);
- MANUALLYSELECT14 = (boolean) a("ManuallyOverrideTo_1_14_systems", MANUALLYSELECT14);
-
- unknownTranslationKeyFixer = (boolean) a("unknownTranslationKeyFixer", false);
-
- enableCreationOfFiles = (boolean) a("Enable_Creation_Of_Default_Files", true);
-
- addGlowEffects = (boolean) a("EnableGlowEffects", false);
-
- blockBreakTexture = (boolean) a("Break-Block-Texture-If-Shot", true);
-
- enableRecoil = (boolean) a("enableRecoil", true);
-
- bulletWound_initialbloodamount = (double) a("experimental.BulletWounds.InitialBloodLevel",
- bulletWound_initialbloodamount);
- bulletWound_BloodIncreasePerSecond = (double) a("experimental.BulletWounds.BloodIncreasePerSecond",
- bulletWound_BloodIncreasePerSecond);
- bulletWound_MedkitBloodlossHealRate = (double) a("experimental.BulletWounds.Medkit_Heal_Bloodloss_Rate",
- bulletWound_MedkitBloodlossHealRate);
- enableBleeding = (boolean) a("experimental.BulletWounds.enableBleeding", enableBleeding);
-
- disableHotBarMessageOnOutOfAmmo = (boolean) a("disableHotbarMessages.OutOfAmmo", false);
- disableHotBarMessageOnShoot = (boolean) a("disableHotbarMessages.Shoot", false);
- disableHotBarMessageOnReload = (boolean) a("disableHotbarMessages.Reload", false);
-
- enableReloadWhenOutOfAmmo = (boolean) a("automaticallyReloadGunWhenOutOfAmmo", false);
-
- swayModifier_Run = (double) a("generalModifiers.sway.Run", swayModifier_Run);
- swayModifier_Walk = (double) a("generalModifiers.sway.Walk", swayModifier_Walk);
- swayModifier_Ironsights = (double) a("generalModifiers.sway.Ironsights", swayModifier_Ironsights);
- swayModifier_Sneak = (double) a("generalModifiers.sway.Sneak", swayModifier_Sneak);
-
- changeDeathMessages = (boolean) a("deathmessages.enable", changeDeathMessages);
-
- restoreOffHand = (boolean) a("restoreOffHand", restoreOffHand);
-
- List avoidTypes = (List) a("impenetrableEntityTypes",
- Collections.singletonList(EntityType.ARROW.name()));
- if (getConfig().getBoolean("ignoreArmorStands"))
- QAMain.avoidTypes.add(EntityType.ARMOR_STAND);
- for (String s : avoidTypes) {
- try {
- QAMain.avoidTypes.add(EntityType.valueOf(s));
- } catch (Error | Exception e4) {
- }
+ if (Bukkit.getPluginManager().isPluginEnabled("WetSponge")) {
+ getConfiguration().general.versionOverride = "1.8";
}
try {
@@ -992,20 +735,13 @@ public void reloadVals() {
} catch (Exception | Error e) {
}
- overrideURL = (boolean) a("DefaultResourcepackOverride", false);
-
- enableIronSightsON_RIGHT_CLICK = (boolean) a("IronSightsOnRightClick", false);
if (getConfig().contains("SwapSneakToSingleFile")) {
- SwapSneakToSingleFire = (boolean) a("SwapSneakToSingleFire", a("SwapSneakToSingleFile", false));
+ getConfiguration().weapons.SwapSneakToSingleFire = getConfig().getBoolean("SwapSneakToSingleFile", getConfiguration().weapons.SwapSneakToSingleFire);
getConfig().set("SwapSneakToSingleFile", null);
+ getConfig().set("weapons.ironsights.swap-sneak-to-single-fire", getConfiguration().weapons.SwapSneakToSingleFire);
saveTheConfig = true;
}
- SwapSneakToSingleFire = (boolean) a("SwapSneakToSingleFire", SwapSneakToSingleFire);
-
- List destarray = (List) a("DestructableMaterials",
- Collections.singletonList("MATERIAL_NAME_HERE"));
- destructableBlocks.addAll(GunYMLLoader.getMaterials(destarray));
- regenDestructableBlocksAfter = (int) a("RegenDestructableBlocksAfter", regenDestructableBlocksAfter);
+ destructableBlocks.addAll(GunYMLLoader.getMaterials(this.mainConfig.world.destructableMaterials));
for (Material m : Material.values())
if (m.isBlock())
@@ -1013,14 +749,14 @@ public void reloadVals() {
|| m.name().contains("LEVER"))
interactableBlocks.add(m);
// Chris: default has 1.14 ItemType
- if ((MANUALLYSELECT18 || !isVersionHigherThan(1, 9)) && !MANUALLYSELECT113 && !MANUALLYSELECT14) {
+ if ((getConfiguration().general.versionOverride.equalsIgnoreCase("1.8") || !isVersionHigherThan(1, 9)) && !getConfiguration().general.versionOverride.equalsIgnoreCase("1.13") && !getConfiguration().general.versionOverride.equalsIgnoreCase("1.14")) {
//1.8
CustomItemManager.registerItemType(getDataFolder(), "gun", new me.zombie_striker.customitemmanager.qa.versions.V1_8.CustomGunItem());
- } else if ((!isVersionHigherThan(1, 14) || MANUALLYSELECT113) && !MANUALLYSELECT18 && !MANUALLYSELECT14) {
+ } else if ((!isVersionHigherThan(1, 14) || getConfiguration().general.versionOverride.equalsIgnoreCase("1.13")) && !getConfiguration().general.versionOverride.equalsIgnoreCase("1.8") && !getConfiguration().general.versionOverride.equalsIgnoreCase("1.14")) {
//1.9 to 1.13
CustomItemManager.registerItemType(getDataFolder(), "gun", new CustomGunItem());
//Make sure vehicles are safe
- if (!overrideURL) {
+ if (!getConfiguration().resourcepack.overrideDefault) {
expansionPacks.add(MaterialStorage.getMS(Material.DIAMOND_AXE, 80, 0));
expansionPacks.add(MaterialStorage.getMS(Material.DIAMOND_AXE, 81, 0));
expansionPacks.add(MaterialStorage.getMS(Material.DIAMOND_AXE, 82, 0));
@@ -1043,18 +779,18 @@ public void reloadVals() {
expansionPacks.add(MaterialStorage.getMS(Material.DIAMOND_AXE, 115, 0));
expansionPacks.add(MaterialStorage.getMS(Material.DIAMOND_AXE, 116, 0));
}
- } else if (true || MANUALLYSELECT14) {
+ } else if (true || getConfiguration().general.versionOverride.equalsIgnoreCase("1.14")) {
//1.14. Use crossbows
- CustomItemManager.registerItemType(getDataFolder(), "gun", new me.zombie_striker.customitemmanager.qa.versions.V1_14.CustomGunItem().setOverrideAttackSpeed((boolean) a("overrideAttackSpeed", true)));
+ CustomItemManager.registerItemType(getDataFolder(), "gun", new me.zombie_striker.customitemmanager.qa.versions.V1_14.CustomGunItem().setOverrideAttackSpeed(this.mainConfig.items.overrideAttackSpeed));
}
// Chris: if switch on, create default items.
- if (enableCreationOfFiles) {
+ if (getConfiguration().features.enableCreationOfFiles) {
CustomItemManager.getItemType("gun").initItems(getDataFolder());
}
((AbstractCustomGunItem) CustomItemManager.getItemType("gun")).initIronsights(getDataFolder());
- if (overrideURL) {
+ if (getConfiguration().resourcepack.overrideDefault) {
if (!getConfig().contains("DefaultResourcepack")) {
getConfig().set("DefaultResourcepack", CustomItemManager.getResourcepackProvider().serialize());
saveTheConfig = true;
@@ -1095,14 +831,14 @@ public void reloadVals() {
GunYMLLoader.loadGuns(this);
GunYMLLoader.loadAttachments(this);
GunYMLLoader.loadArmor(this);
- if (QAMain.enableBleeding)
+ if (QAMain.getConfiguration().combat.enableBleeding)
BulletWoundHandler.startTimer();
if (tfh != null) {
tfh = new TreeFellerHandler();
Bukkit.getPluginManager().registerEvents(tfh, this);
}
- if (addGlowEffects) {
+ if (getConfiguration().features.addGlowEffects) {
coloredGunScoreboard = new ArrayList<>();
coloredGunScoreboard.add(registerGlowTeams(Bukkit.getScoreboardManager().getMainScoreboard()));
}
@@ -1187,10 +923,10 @@ public List onTabComplete(CommandSender sender, Command command, String
s.add("version");
if (b("dumpItem", args[0]))
s.add("dumpItem");
- if (enableShop)
+ if (getConfiguration().menu.enableShop)
if (b("shop", args[0]))
s.add("shop");
- if (enableCrafting)
+ if (getConfiguration().menu.enableCrafting)
if (b("craft", args[0]))
s.add("craft");
// if (b("getOpenGunSlot", args[0]))
@@ -1275,8 +1011,8 @@ public boolean onCommand(CommandSender sender, Command command, String label, St
}
if (args[0].equalsIgnoreCase("debug")) {
if (sender.hasPermission("qualityarmory.debug")) {
- DEBUG = !DEBUG;
- sender.sendMessage(prefix + "Console debugging set to " + DEBUG);
+ getConfiguration().debug.enabled = !getConfiguration().debug.enabled;
+ sender.sendMessage(prefix + "Console debugging set to " + getConfiguration().debug.enabled);
} else {
sender.sendMessage(prefix + ChatColor.RED + S_NOPERM);
return true;
@@ -1576,7 +1312,7 @@ else if (sender instanceof Player)
sender.sendMessage(prefix + " Overriding resourcepack requirement.");
return true;
}
- if (shouldSend && !resourcepackReq.contains(player.getUniqueId())) {
+ if (getConfiguration().resourcepack.enabled && !resourcepackReq.contains(player.getUniqueId())) {
QualityArmory.sendResourcepack(((Player) sender), true);
return true;
}
@@ -1584,7 +1320,7 @@ else if (sender instanceof Player)
sendHelp(player);
return true;
}
- if (enableCrafting)
+ if (getConfiguration().menu.enableCrafting)
if (args[0].equalsIgnoreCase("craft")) {
if (!sender.hasPermission("qualityarmory.craft")) {
sender.sendMessage(prefix + ChatColor.RED + S_NOPERM);
@@ -1599,11 +1335,11 @@ else if (sender instanceof Player)
}
if (g instanceof Gun) {
- if (requirePermsToCraft && !player.hasPermission("qualityarmory.craftgun")) {
+ if (getConfiguration().permissions.requirePermsToCraft && !player.hasPermission("qualityarmory.craftgun")) {
player.sendMessage(prefix + ChatColor.RED + S_NOPERM);
return true;
}
- if (perWeaponCraftPermission && !player.hasPermission("qualityarmory.craftgun." + g.getName())) {
+ if (getConfiguration().permissions.perWeaponCraftPermission && !player.hasPermission("qualityarmory.craftgun." + g.getName())) {
player.sendMessage(prefix + ChatColor.RED + S_NOPERM);
return true;
}
@@ -1627,7 +1363,7 @@ else if (sender instanceof Player)
return true;
}
- if (enableShop)
+ if (getConfiguration().menu.enableShop)
if (args[0].equalsIgnoreCase("shop")) {
if (args.length == 2 && sender.hasPermission("qualityarmory.shop.other")) {
Player target = Bukkit.getPlayer(args[1]);
@@ -1689,6 +1425,12 @@ public boolean isDuplicateGun(ItemStack is1, Player player) {
return false;
}
+ public void handleException(Exception e) {
+ if (this.mainConfig == null || this.mainConfig.debug.logExceptions)
+ this.getLogger().log(Level.SEVERE, "An exception occurred in QualityArmory", e);
+ else this.getLogger().severe("An exception occurred in QualityArmory. Enable 'log-exceptions' for more information: " + e.getMessage());
+ }
+
@Override
public void reloadConfig() {
if (configFile == null) {
diff --git a/src/main/java/me/zombie_striker/qg/ammo/Ammo.java b/src/main/java/me/zombie_striker/qg/ammo/Ammo.java
index a5b2e687..4544863b 100644
--- a/src/main/java/me/zombie_striker/qg/ammo/Ammo.java
+++ b/src/main/java/me/zombie_striker/qg/ammo/Ammo.java
@@ -1,7 +1,6 @@
package me.zombie_striker.qg.ammo;
import com.cryptomorin.xseries.XMaterial;
-import me.zombie_striker.customitemmanager.ArmoryBaseObject;
import me.zombie_striker.customitemmanager.CustomBaseObject;
import me.zombie_striker.customitemmanager.CustomItemManager;
import me.zombie_striker.customitemmanager.MaterialStorage;
@@ -15,7 +14,7 @@
import java.util.List;
-public class Ammo extends CustomBaseObject implements ArmoryBaseObject{
+public class Ammo extends CustomBaseObject {
boolean indiDrop;
diff --git a/src/main/java/me/zombie_striker/qg/api/QualityArmory.java b/src/main/java/me/zombie_striker/qg/api/QualityArmory.java
index 2ab6034d..2e7559fe 100644
--- a/src/main/java/me/zombie_striker/qg/api/QualityArmory.java
+++ b/src/main/java/me/zombie_striker/qg/api/QualityArmory.java
@@ -1,14 +1,22 @@
package me.zombie_striker.qg.api;
-import java.io.File;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map.Entry;
-
-import me.zombie_striker.customitemmanager.*;
+import me.zombie_striker.customitemmanager.CustomBaseObject;
+import me.zombie_striker.customitemmanager.CustomItemManager;
+import me.zombie_striker.customitemmanager.MaterialStorage;
+import me.zombie_striker.customitemmanager.OLD_ItemFact;
+import me.zombie_striker.qg.QAMain;
+import me.zombie_striker.qg.ammo.Ammo;
+import me.zombie_striker.qg.armor.ArmorObject;
+import me.zombie_striker.qg.attachments.AttachmentBase;
+import me.zombie_striker.qg.config.GunYML;
+import me.zombie_striker.qg.config.GunYMLCreator;
+import me.zombie_striker.qg.config.GunYMLLoader;
+import me.zombie_striker.qg.guns.Gun;
+import me.zombie_striker.qg.guns.utils.WeaponSounds;
+import me.zombie_striker.qg.guns.utils.WeaponType;
import me.zombie_striker.qg.handlers.HotbarMessager;
import me.zombie_striker.qg.handlers.IronsightsHandler;
+import me.zombie_striker.qg.hooks.ViaVersionHook;
import me.zombie_striker.qg.hooks.protection.ProtectionHandler;
import me.zombie_striker.qg.miscitems.AmmoBag;
import me.zombie_striker.qg.utils.LocalUtils;
@@ -21,20 +29,15 @@
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.scheduler.BukkitRunnable;
-
-import me.zombie_striker.qg.*;
-import me.zombie_striker.qg.ammo.Ammo;
-import me.zombie_striker.qg.armor.ArmorObject;
-import me.zombie_striker.qg.attachments.AttachmentBase;
-import me.zombie_striker.qg.config.GunYML;
-import me.zombie_striker.qg.config.GunYMLCreator;
-import me.zombie_striker.qg.config.GunYMLLoader;
-import me.zombie_striker.qg.guns.Gun;
-import me.zombie_striker.qg.guns.utils.WeaponSounds;
-import me.zombie_striker.qg.guns.utils.WeaponType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map.Entry;
+
public class QualityArmory {
public static GunYML createAndLoadNewGun(String name, String displayname, Material material, int id,
@@ -111,7 +114,7 @@ public void run() {
player.sendMessage(LocalUtils.colorize(ChatColor.RED + QAMain.S_NORES2));
}
}
- if (QAMain.showCrashMessage)
+ if (QAMain.getConfiguration().ui.showCrashMessage)
player.sendMessage(LocalUtils.colorize(QAMain.prefix + QAMain.S_RESOURCEPACK_HELP));
new BukkitRunnable() {
@@ -119,20 +122,20 @@ public void run() {
public void run() {
try {
try {
- QAMain.DEBUG("Sending resourcepack : " + (QAMain.AutoDetectResourcepackVersion) + " || "
- + QAMain.MANUALLYSELECT18 + " || " + QAMain.isVersionHigherThan(1, 9) + " || ");
+ QAMain.DEBUG("Sending resourcepack : " + (QAMain.getConfiguration().resourcepack.autoDetectVersion) + " || "
+ + QAMain.getConfiguration().general.versionOverride.equalsIgnoreCase("1.8") + " || " + QAMain.isVersionHigherThan(1, 9) + " || ");
try {
if (QAMain.hasViaVersion) {
QAMain.DEBUG(
"Has Viaversion: " + com.viaversion.viaversion.api.Via.getAPI()
- .getPlayerVersion(player) + " 1.8=" + QAMain.ViaVersionIdfor_1_8);
+ .getPlayerVersion(player) + " 1.8=" + ViaVersionHook.VIAVERSION_1_8);
}
} catch (Error | Exception re4) {
}
if (QAMain.isVersionHigherThan(1, 19))
- player.setResourcePack(CustomItemManager.getResourcepack(player), null, QAMain.kickIfDeniedRequest);
+ player.setResourcePack(CustomItemManager.getResourcepack(player), null, QAMain.getConfiguration().resourcepack.kickIfDenied);
else player.setResourcePack(CustomItemManager.getResourcepack(player));
} catch (Error | Exception e4) {
@@ -153,7 +156,7 @@ public void run() {
}
}.runTaskLater(QAMain.getInstance(), 20 * (warning ? 1 : 5));
}
- }.runTaskLater(QAMain.getInstance(), (long) (20 * QAMain.secondsTilSend));
+ }.runTaskLater(QAMain.getInstance(), (long) (20 * QAMain.getConfiguration().resourcepack.secondsTilSend));
}
public static boolean allowGunsInRegion(Location loc) {
@@ -464,9 +467,9 @@ public static void sendHotbarGunAmmoCount(final Player p, final CustomBaseObject
int ammoamount = getAmmoInInventory(p, g.getAmmoType());
- if (QAMain.showOutOfAmmoOnTitle && ammoamount <= 0 && Gun.getAmount(p) < 1) {
+ if (QAMain.getConfiguration().ui.showOutOfAmmoOnTitle && ammoamount <= 0 && Gun.getAmount(p) < 1) {
p.sendTitle(" ", QAMain.S_OUT_OF_AMMO, 0, 20, 1);
- } else if (QAMain.showReloadOnTitle && reloading) {
+ } else if (QAMain.getConfiguration().ui.showReloadOnTitle && reloading) {
for (int i = 1; i < g.getReloadTime() * 20; i += 2) {
final int id = i;
new BukkitRunnable() {
@@ -486,14 +489,14 @@ public void run() {
try {
String message = QAMain.S_HOTBAR_FORMAT;
- if (QAMain.disableHotBarMessageOnOutOfAmmo && QAMain.disableHotBarMessageOnReload
- && QAMain.disableHotBarMessageOnShoot)
+ if (QAMain.getConfiguration().ui.disableHotBarMessageOnOutOfAmmo && QAMain.getConfiguration().ui.disableHotBarMessageOnReload
+ && QAMain.getConfiguration().ui.disableHotBarMessageOnShoot)
return;
- if (reloading && QAMain.disableHotBarMessageOnReload)
+ if (reloading && QAMain.getConfiguration().ui.disableHotBarMessageOnReload)
return;
- if (ammoamount <= 0 && QAMain.disableHotBarMessageOnOutOfAmmo)
+ if (ammoamount <= 0 && QAMain.getConfiguration().ui.disableHotBarMessageOnOutOfAmmo)
return;
- if (!reloading && ammoamount > 0 && QAMain.disableHotBarMessageOnShoot)
+ if (!reloading && ammoamount > 0 && QAMain.getConfiguration().ui.disableHotBarMessageOnShoot)
return;
if (message.contains("%name%"))
@@ -510,7 +513,7 @@ public void run() {
if (message.contains("%total%"))
message = message.replace("%total%", "" + ammoamount);
- if (QAMain.unknownTranslationKeyFixer) {
+ if (QAMain.getConfiguration().features.unknownTranslationKeyFixer) {
message = ChatColor.stripColor(message);
} else {
message = LocalUtils.colorize(message);
@@ -631,7 +634,7 @@ public static boolean isOverLimitForPrimaryWeapons(Gun g, Player p) {
count++;
}
}
- return count >= (g.isPrimaryWeapon() ? QAMain.primaryWeaponLimit : QAMain.secondaryWeaponLimit);
+ return count >= (g.isPrimaryWeapon() ? QAMain.getConfiguration().limiter.primaryWeaponLimit : QAMain.getConfiguration().limiter.secondaryWeaponLimit);
}
public static ItemStack getCustomItemAsItemStack(String name) {
diff --git a/src/main/java/me/zombie_striker/qg/armor/ArmorObject.java b/src/main/java/me/zombie_striker/qg/armor/ArmorObject.java
index 4f32809c..0f7e163c 100644
--- a/src/main/java/me/zombie_striker/qg/armor/ArmorObject.java
+++ b/src/main/java/me/zombie_striker/qg/armor/ArmorObject.java
@@ -1,7 +1,6 @@
package me.zombie_striker.qg.armor;
import com.cryptomorin.xseries.XAttribute;
-import me.zombie_striker.customitemmanager.ArmoryBaseObject;
import me.zombie_striker.customitemmanager.CustomBaseObject;
import me.zombie_striker.customitemmanager.CustomItemManager;
import me.zombie_striker.customitemmanager.MaterialStorage;
@@ -14,7 +13,7 @@
import java.util.List;
-public class ArmorObject extends CustomBaseObject implements ArmoryBaseObject {
+public class ArmorObject extends CustomBaseObject {
private int protection = 0;
private double heightMin = 1;
@@ -97,10 +96,9 @@ public boolean onShift(Player shooter, ItemStack usedItem, boolean toggle) {
@Override
public boolean onLMB(Player e, ItemStack usedItem) {
- // TODO Auto-generated method stub
return false;
-
}
+
@Override
public ItemStack getItemStack() {
ItemStack item = CustomItemManager.getItemType("gun").getItem(this.getItemData().getMat(),this.getItemData().getData(),this.getItemData().getVariant());
diff --git a/src/main/java/me/zombie_striker/qg/config/GunYMLLoader.java b/src/main/java/me/zombie_striker/qg/config/GunYMLLoader.java
index e996f0e3..0d3218d5 100644
--- a/src/main/java/me/zombie_striker/qg/config/GunYMLLoader.java
+++ b/src/main/java/me/zombie_striker/qg/config/GunYMLLoader.java
@@ -42,7 +42,7 @@ public static void loadAmmo(QAMain main) {
: Material.DIAMOND_AXE;
int variant = f2.contains("variant") ? f2.getInt("variant") : 0;
final String name = f2.getString("name");
- if(QAMain.verboseLoadingLogging)
+ if(QAMain.getConfiguration().features.verboseLoadingLogging)
main.getLogger().info("-Loading AmmoType: " + name);
String extraData = null;
@@ -105,7 +105,7 @@ public static void loadAmmo(QAMain main) {
e.printStackTrace();
}
}
- if(!QAMain.verboseLoadingLogging)
+ if(!QAMain.getConfiguration().features.verboseLoadingLogging)
main.getLogger().info("-Loaded "+items+" Ammo types.");
@@ -122,7 +122,7 @@ public static void loadArmor(QAMain main) {
FileConfiguration f2 = YamlConfiguration.loadConfiguration(f);
if ((!f2.contains("invalid")) || !f2.getBoolean("invalid")) {
final String name = f2.getString("name");
- if(QAMain.verboseLoadingLogging)
+ if(QAMain.getConfiguration().features.verboseLoadingLogging)
main.getLogger().info("-Loading Armor: " + name);
Material m = f2.contains("material") ? Material.matchMaterial(f2.getString("material"))
@@ -163,7 +163,7 @@ public static void loadArmor(QAMain main) {
e.printStackTrace();
}
}
- if(!QAMain.verboseLoadingLogging)
+ if(!QAMain.getConfiguration().features.verboseLoadingLogging)
main.getLogger().info("-Loaded "+items+" Armor types.");
}
}
@@ -177,7 +177,7 @@ public static void loadMisc(QAMain main) {
FileConfiguration f2 = YamlConfiguration.loadConfiguration(f);
if ((!f2.contains("invalid")) || !f2.getBoolean("invalid")) {
final String name = f2.getString("name");
- if (QAMain.verboseLoadingLogging)
+ if (QAMain.getConfiguration().features.verboseLoadingLogging)
main.getLogger().info("-Loading Misc: " + name);
Material m = f2.contains("material") ? Material.matchMaterial(f2.getString("material"))
@@ -278,7 +278,7 @@ public static void loadMisc(QAMain main) {
e.printStackTrace();
}
}
- if(!QAMain.verboseLoadingLogging)
+ if(!QAMain.getConfiguration().features.verboseLoadingLogging)
main.getLogger().info("-Loaded "+items+" Misc.");
}
}
@@ -288,7 +288,7 @@ public static void loadGuns(QAMain main, File f) {
FileConfiguration f2 = YamlConfiguration.loadConfiguration(f);
if ((!f2.contains("invalid")) || !f2.getBoolean("invalid")) {
final String name = f2.getString("name");
- if(QAMain.verboseLoadingLogging)
+ if(QAMain.getConfiguration().features.verboseLoadingLogging)
main.getLogger().info("-Loading Gun: " + name);
Material m = f2.contains("material") ? Material.matchMaterial(f2.getString("material"))
@@ -503,7 +503,7 @@ public static void loadGuns(QAMain main) {
loadGuns(main, f);
items++;
}
- if(!QAMain.verboseLoadingLogging)
+ if(!QAMain.getConfiguration().features.verboseLoadingLogging)
main.getLogger().info("-Loaded "+items+" Gun types.");
}
}
@@ -517,7 +517,8 @@ public static void loadAttachments(QAMain main) {
FileConfiguration f2 = YamlConfiguration.loadConfiguration(f);
if ((!f2.contains("invalid")) || !f2.getBoolean("invalid")) {
final String name = f2.getString("name");
- main.getLogger().info("-Loading Attachment: " + name);
+ if (QAMain.getConfiguration().features.verboseLoadingLogging)
+ main.getLogger().info("-Loading Attachment: " + name);
final String displayname = f2.contains("displayname")
? LocalUtils.colorize( f2.getString("displayname"))
: (ChatColor.GOLD + name);
@@ -569,7 +570,7 @@ public static void loadAttachments(QAMain main) {
e.printStackTrace();
}
}
- if(!QAMain.verboseLoadingLogging)
+ if(!QAMain.getConfiguration().features.verboseLoadingLogging)
main.getLogger().info("-Loaded "+items+" Attachment types.");
}
}
diff --git a/src/main/java/me/zombie_striker/qg/config/MainConfig.java b/src/main/java/me/zombie_striker/qg/config/MainConfig.java
new file mode 100644
index 00000000..27490f57
--- /dev/null
+++ b/src/main/java/me/zombie_striker/qg/config/MainConfig.java
@@ -0,0 +1,298 @@
+package me.zombie_striker.qg.config;
+
+import me.zombie_striker.qg.QAMain;
+import me.zombie_striker.qg.config.system.BaseConfiguration;
+import me.zombie_striker.qg.config.system.Config;
+import org.bukkit.entity.EntityType;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+public class MainConfig extends BaseConfiguration {
+ public Debug debug = new Debug();
+ public General general = new General();
+ public Compat compat = new Compat();
+ public Resourcepack resourcepack = new Resourcepack();
+ public Weapons weapons = new Weapons();
+ public Interactions interactions = new Interactions();
+ public UI ui = new UI();
+ public Features features = new Features();
+ public Permissions permissions = new Permissions();
+ public Menu menu = new Menu();
+ public Limiter limiter = new Limiter();
+ public Items items = new Items();
+ public Combat combat = new Combat();
+ public World world = new World();
+
+ public static class Debug {
+ @Config(value = "debug.enabled", oldPath = "ENABLE-DEBUG")
+ public boolean enabled = false;
+
+ @Config(value = "debug.log-exceptions", oldPath = "log-exceptions")
+ public boolean logExceptions = true;
+ }
+
+ public static class General {
+ @Config(value = "general.language", oldPath = "language")
+ public String language = "en";
+
+ @Config(value = "general.version-override")
+ public String versionOverride = "none";
+ }
+
+ public static class Compat {
+ @Config(value = "compat.friendly-fire", oldPath = "FriendlyFireEnabled")
+ public boolean friendlyFire = false;
+ }
+
+ public static class Resourcepack {
+ @Config(value = "resourcepack.enabled", oldPath = "useDefaultResourcepack")
+ public boolean enabled = true;
+
+ @Config(value = "resourcepack.send-on-join.enabled", oldPath = "sendOnJoin")
+ public boolean sendOnJoin = true;
+
+ @Config(value = "resourcepack.send-on-join.title", oldPath = "sendTitleOnJoin")
+ public boolean sendTitleOnJoin = false;
+
+ @Config(value = "resourcepack.send-on-join.delay", oldPath = "SecondsTillRPIsSent")
+ public double secondsTilSend = 0.0;
+
+ @Config(value = "resourcepack.kick-if-denied", oldPath = "KickPlayerIfDeniedResourcepack")
+ public boolean kickIfDenied = false;
+
+ @Config(value = "resourcepack.invincibility", oldPath = "resourcepackInvincibility")
+ public boolean invincibility = false;
+
+ @Config(value = "resourcepack.auto-detect-version", oldPath = "Auto-Detect-Resourcepack")
+ public boolean autoDetectVersion = true;
+
+ @Config(value = "resourcepack.override-default", oldPath = "DefaultResourcepackOverride")
+ public boolean overrideDefault = false;
+ }
+
+ public static class Weapons {
+ @Config(value = "weapons.durability", oldPath = "EnableWeaponDurability")
+ public boolean enableDurability = false;
+ @Config(value = "weapons.detection.bullet-step", oldPath = "BulletDetection.step")
+ public double bulletStep = 0.10;
+ @Config(value = "weapons.block-bullets.door", oldPath = "BlockBullets.door")
+ public boolean blockbullet_door = false;
+ @Config(value = "weapons.block-bullets.halfslabs", oldPath = "BlockBullets.halfslabs")
+ public boolean blockbullet_halfslabs = false;
+ @Config(value = "weapons.block-bullets.leaves", oldPath = "BlockBullets.leaves")
+ public boolean blockbullet_leaves = false;
+ @Config(value = "weapons.block-bullets.water", oldPath = "BlockBullets.water")
+ public boolean blockbullet_water = false;
+ @Config(value = "weapons.block-bullets.glass", oldPath = "BlockBullets.glass")
+ public boolean blockbullet_glass = false;
+ @Config(value = "weapons.detection.gravity", oldPath = "gravityConstantForDropoffCalculations")
+ public double gravity = 0.05;
+ @Config(value = "weapons.sway.run", oldPath = "generalModifiers.sway.Run")
+ public double swayModifier_Run = 2.0;
+ @Config(value = "weapons.sway.walk", oldPath = "generalModifiers.sway.Walk")
+ public double swayModifier_Walk = 1.5;
+ @Config(value = "weapons.sway.sneak", oldPath = "generalModifiers.sway.Sneak")
+ public double swayModifier_Sneak = 0.7;
+ @Config(value = "weapons.allow-gun-hit-entities", oldPath = "allowGunHitEntities")
+ public boolean allowGunHitEntities = true;
+ @Config(value = "weapons.hit-distance", oldPath = "hitDistance")
+ public int hitDistance = 5;
+ @Config(value = "weapons.allow-gun-reload", oldPath = "allowGunReload")
+ public boolean allowGunReload = true;
+ @Config(value = "weapons.enable-recoil", oldPath = "enableRecoil")
+ public boolean enableRecoil = true;
+ @Config(value = "weapons.recoil.use-player-move", oldPath = "useMoveForRecoil")
+ public boolean useMoveForRecoil = true;
+ @Config(value = "weapons.switch-delay-seconds", oldPath = "weaponSwitchDelay")
+ public double weaponSwitchDelay = 0.0;
+ @Config(value = "weapons.ironsights.right-click", oldPath = "IronSightsOnRightClick")
+ public boolean enableIronSightsON_RIGHT_CLICK = false;
+ @Config(value = "weapons.ironsights.swap-sneak-to-single-fire", oldPath = "SwapSneakToSingleFire")
+ public boolean SwapSneakToSingleFire = false;
+ @Config(value = "weapons.auto-reload-when-out-of-ammo", oldPath = "automaticallyReloadGunWhenOutOfAmmo")
+ public boolean enableReloadWhenOutOfAmmo = false;
+ @Config(value = "weapons.controls.reload-on-drop", oldPath = "enableReloadingOnDrop")
+ public boolean reloadOnQ = true;
+ @Config(value = "weapons.controls.reload-on-offhand-swap", oldPath = "enableReloadingWhenSwapToOffhand")
+ public boolean reloadOnF = true;
+ @Config(value = "weapons.controls.reload-only-on-offhand-swap", oldPath = "enableReloadOnlyWhenSwapToOffhand")
+ public boolean reloadOnFOnly = false;
+ @Config(value = "weapons.controls.unload-on-drop", oldPath = "enableUnloadingOnDrop")
+ public boolean unloadOnQ = false;
+ @Config(value = "weapons.headshot.instant-kill", oldPath = "Enable_Headshot_Instantkill")
+ public boolean HeadshotOneHit = false;
+ @Config(value = "weapons.headshot.play-notification-sound", oldPath = "Enable_Headshot_Notification_Sound")
+ public boolean headshotPling = false;
+ @Config(value = "weapons.headshot.notification-sound", oldPath = "Headshot_Notification_Sound")
+ public String headshot_sound = "entity.experience_orb.pickup";
+ @Config(value = "weapons.hit-sound.enabled", oldPath = "Enable_Hit_Sound")
+ public boolean enableHitSound = false;
+ @Config(value = "weapons.hit-sound.sound", oldPath = "Hit_Notification_Sound")
+ public String hit_sound = "ENTITY_EXPERIENCE_ORB_PICKUP";
+ @Config(value = "weapons.headshot.blacklist", oldPath = "Headshot_Blacklist")
+ public List headshotBlacklist = Collections.emptyList();
+ @Config(value = "weapons.impenetrable-entities", oldPath = "impenetrableEntityTypes")
+ public List impenetrableEntityTypes = new ArrayList<>(Arrays.asList(EntityType.ARROW.name()));
+ }
+
+ public static class Interactions {
+ @Config(value = "interactions.override-anvil", oldPath = "overrideAnvil")
+ public boolean overrideAnvil = false;
+ @Config(value = "interactions.enable-chest-interact", oldPath = "enableInteract.Chests")
+ public boolean enableInteractChests = false;
+ @Config(value = "interactions.prevent-hidden-players-hit", oldPath = "preventHiddenPlayers")
+ public boolean preventHiddenPlayers = true;
+ @Config(value = "interactions.prevent-guns-in-hoppers", oldPath = "preventGunsInHoppers")
+ public boolean preventGunsInHoppers = true;
+ }
+
+ public static class UI {
+ @Config(value = "ui.show-possible-crash-help-message", oldPath = "showPossibleCrashHelpMessage")
+ public boolean showCrashMessage = true;
+ @Config(value = "ui.show-ammo-in-xp-bar", oldPath = "showAmmoInXPBar")
+ public boolean showAmmoInXPBar = false;
+ @Config(value = "ui.show-out-of-ammo-title", oldPath = "showOutOfAmmoOnTitle")
+ public boolean showOutOfAmmoOnTitle = false;
+ @Config(value = "ui.show-reload-title", oldPath = "showReloadingTitle")
+ public boolean showReloadOnTitle = false;
+ @Config(value = "ui.disable-hotbar-messages.out-of-ammo", oldPath = "disableHotbarMessages.OutOfAmmo")
+ public boolean disableHotBarMessageOnOutOfAmmo = false;
+ @Config(value = "ui.disable-hotbar-messages.shoot", oldPath = "disableHotbarMessages.Shoot")
+ public boolean disableHotBarMessageOnShoot = false;
+ @Config(value = "ui.disable-hotbar-messages.reload", oldPath = "disableHotbarMessages.Reload")
+ public boolean disableHotBarMessageOnReload = false;
+ }
+
+ public static class Features {
+ @Config(value = "features.anticheat-fix", oldPath = "anticheatFix")
+ public boolean anticheatFix = false;
+ @Config(value = "features.enable-ignore-armor-protection", oldPath = "enableIgnoreArmorProtection")
+ public boolean enableArmorIgnore = false;
+ @Config(value = "features.enable-ignore-unbreaking-checks", oldPath = "enableIgnoreUnbreakingChecks")
+ public boolean ignoreUnbreaking = false;
+ @Config(value = "features.enable-ignore-skip-for-basegame-items", oldPath = "enableIgnoreSkipForBasegameItems")
+ public boolean ignoreSkipping = false;
+ @Config(value = "features.verbose-item-logging", oldPath = "verboseItemLogging")
+ public boolean verboseLoadingLogging = false;
+ @Config(value = "features.enable-explosion-damage", oldPath = "enableExplosionDamage")
+ public boolean enableExplosionDamage = false;
+ @Config(value = "features.enable-glow-effects", oldPath = "EnableGlowEffects")
+ public boolean addGlowEffects = false;
+ @Config(value = "features.unknown-translation-key-fixer", oldPath = "unknownTranslationKeyFixer")
+ public boolean unknownTranslationKeyFixer = false;
+ @Config(value = "features.break-block-texture-if-shot", oldPath = "Break-Block-Texture-If-Shot")
+ public boolean blockBreakTexture = true;
+ @Config(value = "features.enable-auto-arm-grenades", oldPath = "Enable_AutoArm_Grenades")
+ public boolean autoarm = false;
+ @Config(value = "features.restore-offhand", oldPath = "restoreOffHand")
+ public boolean restoreOffHand = false;
+ @Config(value = "features.enable-bullet-trails", oldPath = "enableBulletTrails")
+ public boolean enableBulletTrails = true;
+ @Config(value = "features.bullet-trails-spacing", oldPath = "BulletTrailsSpacing")
+ public double smokeSpacing = 0.5;
+ @Config(value = "features.enable-creation-of-default-files", oldPath = "Enable_Creation_Of_Default_Files")
+ public boolean enableCreationOfFiles = true;
+ @Config(value = "features.auto-update", oldPath = "AUTO-UPDATE")
+ public boolean AUTOUPDATE = true;
+ @Config(value = "features.swap-reload-and-shooting-controls", oldPath = "Swap-Reload-and-Shooting-Controls")
+ public boolean SwapReloadAndShootingControls = false;
+ @Config(value = "features.enable-lore-gun-bullets", oldPath = "enable_lore_gun-bullets")
+ public boolean SHOW_BULLETS_LORE = false;
+ @Config(value = "features.enable-lore-gun-info-messages", oldPath = "enable_lore_gun-info_messages")
+ public boolean ENABLE_LORE_INFO = true;
+ @Config(value = "features.enable-lore-control-help-messages", oldPath = "enable_lore_control-help_messages")
+ public boolean ENABLE_LORE_HELP = true;
+ }
+
+ public static class Permissions {
+ @Config(value = "permissions.require-shoot", oldPath = "enable_permssionsToShoot")
+ public boolean requirePermsToShoot = false;
+ @Config(value = "permissions.require-craft", oldPath = "enable_permissionsToCraft")
+ public boolean requirePermsToCraft = false;
+ @Config(value = "permissions.require-buy", oldPath = "enable_permissionsToBuy")
+ public boolean requirePermsToBuy = false;
+ @Config(value = "permissions.per-weapon.shoot", oldPath = "perWeaponPermission")
+ public boolean perWeaponPermission = false;
+ @Config(value = "permissions.per-weapon.craft", oldPath = "perWeaponCraftPermission")
+ public boolean perWeaponCraftPermission = false;
+ @Config(value = "permissions.per-weapon.buy", oldPath = "perWeaponBuyPermission")
+ public boolean perWeaponBuyPermission = false;
+ }
+
+ public static class Menu {
+ @Config(value = "menu.enable-crafting", oldPath = "enableCrafting")
+ public boolean enableCrafting = true;
+ @Config(value = "menu.enable-shop", oldPath = "enableShop")
+ public boolean enableShop = true;
+ @Config(value = "menu.order-shop-by-price", oldPath = "Order-Shop-By-Price")
+ public boolean orderShopByPrice = false;
+ }
+
+ public static class Limiter {
+ @Config(value = "limiter.primary.enabled", oldPath = "enablePrimaryWeaponLimiter")
+ public boolean enablePrimaryWeaponHandler = false;
+ @Config(value = "limiter.primary.max", oldPath = "weaponlimiter_primaries")
+ public int primaryWeaponLimit = 2;
+ @Config(value = "limiter.secondary.max", oldPath = "weaponlimiter_secondaries")
+ public int secondaryWeaponLimit = 2;
+ }
+
+ public static class Items {
+ @Config(value = "items.enable-unbreaking", oldPath = "Items.enable_Unbreaking")
+ public boolean ITEM_enableUnbreakable = true;
+ @Config(value = "items.override-attack-speed", oldPath = "overrideAttackSpeed")
+ public boolean overrideAttackSpeed = true;
+ }
+
+ public static class Combat {
+ @Config(value = "combat.bleeding.enabled", oldPath = "experimental.BulletWounds.enableBleeding")
+ public boolean enableBleeding = false;
+ @Config(value = "combat.bleeding.initial-blood-level", oldPath = "experimental.BulletWounds.InitialBloodLevel")
+ public double bulletWound_initialbloodamount = 1500;
+ @Config(value = "combat.bleeding.blood-increase-per-second", oldPath = "experimental.BulletWounds.BloodIncreasePerSecond")
+ public double bulletWound_BloodIncreasePerSecond = 0.01;
+ @Config(value = "combat.bleeding.medkit-heal-bloodloss-rate", oldPath = "experimental.BulletWounds.Medkit_Heal_Bloodloss_Rate")
+ public double bulletWound_MedkitBloodlossHealRate = 0.05;
+ @Config(value = "combat.death-messages.enabled", oldPath = "deathmessages.enable")
+ public boolean changeDeathMessages = true;
+ }
+
+ public static class World {
+ @Config(value = "world.destructable-materials", oldPath = "DestructableMaterials")
+ public List destructableMaterials = Collections.singletonList("MATERIAL_NAME_HERE");
+ @Config(value = "world.regen-destructable-blocks-after", oldPath = "RegenDestructableBlocksAfter")
+ public int regenDestructableBlocksAfter = -1;
+ }
+
+ public MainConfig() {
+ super(new File(QAMain.getInstance().getDataFolder(), "config.yml"));
+ }
+
+
+ @Override
+ public int getVersion() {
+ return 3;
+ }
+
+ @Override
+ public void customMigrate() {
+ if (this.config.contains("ignoreArmorStands") && this.config.getBoolean("ignoreArmorStands")) {
+ if (!weapons.impenetrableEntityTypes.contains(EntityType.ARMOR_STAND.name())) {
+ weapons.impenetrableEntityTypes.add(EntityType.ARMOR_STAND.name());
+ }
+ }
+
+ if (this.config.contains("ManuallyOverrideTo_1_8_systems") && this.config.getBoolean("ManuallyOverrideTo_1_8_systems"))
+ general.versionOverride = "1.8";
+
+ if (this.config.contains("ManuallyOverrideTo_1_13_systems") && this.config.getBoolean("ManuallyOverrideTo_1_13_systems"))
+ general.versionOverride = "1.13";
+
+ if (this.config.contains("ManuallyOverrideTo_1_14_systems") && this.config.getBoolean("ManuallyOverrideTo_1_14_systems"))
+ general.versionOverride = "1.14";
+ }
+}
diff --git a/src/main/java/me/zombie_striker/qg/config/system/BaseConfiguration.java b/src/main/java/me/zombie_striker/qg/config/system/BaseConfiguration.java
new file mode 100644
index 00000000..4534441a
--- /dev/null
+++ b/src/main/java/me/zombie_striker/qg/config/system/BaseConfiguration.java
@@ -0,0 +1,316 @@
+package me.zombie_striker.qg.config.system;
+
+import me.zombie_striker.qg.QAMain;
+import me.zombie_striker.qg.config.system.serializers.ConfigSerializer;
+import me.zombie_striker.qg.config.system.serializers.EntityTypeSerializer;
+import org.bukkit.configuration.file.FileConfiguration;
+import org.bukkit.configuration.file.YamlConfiguration;
+
+import java.io.File;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.*;
+
+/**
+ * This class handles the configuration file loading, saving, and migration.
+ * It uses reflection to load the fields annotated with @Config and set their values from the configuration file.
+ *
+ * @see Config
+ */
+public abstract class BaseConfiguration {
+ public static final List> SERIALIZERS = new ArrayList<>();
+ private final QAMain plugin = QAMain.getInstance();
+ private final File file;
+ protected FileConfiguration config;
+
+ static {
+ SERIALIZERS.add(new EntityTypeSerializer());
+ }
+
+ protected BaseConfiguration(File file) {
+ this.file = file;
+ this.loadFile();
+ }
+
+ /**
+ * Loads the configuration file into memory.
+ */
+ protected void loadFile() {
+ this.config = YamlConfiguration.loadConfiguration(this.file);
+ }
+
+ /**
+ * Loads the default values into the configuration file if it doesn't exist.
+ */
+ @SuppressWarnings("ResultOfMethodCallIgnored")
+ public void loadDefaults() {
+ if (!this.file.exists()) {
+ try {
+ this.file.getParentFile().mkdirs();
+ this.file.createNewFile();
+ } catch (Exception e) {
+ plugin.handleException(e);
+ }
+ }
+
+ if (this.config.get("version") == null) {
+ this.config.set("version", 0);
+ }
+
+ this.migrate();
+
+ for (ConfigFieldBinding binding : this.collectConfigFields()) {
+ String path = binding.config.value();
+ Object value = this.config.get(path);
+ if (value != null) continue;
+
+ try {
+ binding.field.setAccessible(true);
+ this.config.set(path, binding.field.get(binding.owner));
+ } catch (IllegalAccessException e) {
+ plugin.handleException(e);
+ }
+ }
+
+ this.save();
+ }
+
+ /**
+ * Reloads the configuration file and updates the fields annotated with @Config.
+ */
+ public void reload() {
+ this.loadFile();
+
+ for (ConfigFieldBinding binding : this.collectConfigFields()) {
+ String path = binding.config.value();
+ Object value;
+
+ if (List.class.isAssignableFrom(binding.field.getType())) {
+ if (!this.config.contains(path))
+ continue;
+ value = this.getValueList(path, this.resolveListElementType(binding.field));
+ } else {
+ value = this.getValue(path, binding.field.getType());
+ }
+
+ if (value == null) continue;
+
+ try {
+ binding.field.setAccessible(true);
+ binding.field.set(binding.owner, value);
+ } catch (IllegalAccessException e) {
+ plugin.handleException(e);
+ }
+ }
+ }
+
+ /**
+ * Gets the value of a field from the configuration file.
+ *
+ * @param path The path of the field in the configuration file.
+ * @param type The class type of the field.
+ * @return The value of the field, or null if it doesn't exist.
+ */
+ @SuppressWarnings("unchecked")
+ public T getValue(String path, Class type) {
+ Object raw = this.config.get(path);
+ if (raw == null) return null;
+ return this.convertRawValue(raw, type);
+ }
+
+ /**
+ * Gets the value of a field from the configuration file.
+ *
+ * @param path The path of the field in the configuration file.
+ * @param type The class type of the field.
+ * @return The value of the field, or null if it doesn't exist.
+ */
+ public List getValueList(String path, Class type) {
+ List> values = this.config.getList(path);
+ List result = new ArrayList<>();
+ if (values == null) return result;
+
+ for (Object value : values) {
+ T obj = this.convertRawValue(value, type);
+ if (obj != null) result.add(obj);
+ }
+
+ return result;
+ }
+
+ /**
+ * Saves the configuration file to disk.
+ */
+ public void save() {
+ try {
+ this.config.save(this.file);
+ } catch (Exception e) {
+ plugin.handleException(e);
+ }
+ }
+
+ /**
+ * Migrates the configuration file from an old version to the current version.
+ * This method checks for fields annotated with @Config that have an oldPath specified.
+ * It copies the value from the old path to the new path and removes the old path.
+ * If the version in the configuration file is already up to date, it does nothing.
+ */
+ public void migrate() {
+ if (this.getVersion() == 0) return;
+ if (this.config.getInt("version") == this.getVersion()) return;
+
+ this.customMigrate();
+
+ for (ConfigFieldBinding binding : this.collectConfigFields()) {
+ if (binding.config.oldPath().isEmpty()) continue;
+
+ String oldPath = binding.config.oldPath();
+ Object value = this.convertRawValue(this.config.get(oldPath), binding.field.getType());
+ if (value == null) continue;
+
+ this.config.set(binding.config.value(), value);
+ this.config.set(oldPath, null);
+ }
+
+ this.config.set("version", this.getVersion());
+ this.save();
+ }
+
+
+ /**
+ * @return The version of the configuration file.
+ */
+ public abstract int getVersion();
+
+
+ /**
+ * This method is called before the default migration process.
+ * You can override this method to perform any custom migration logic.
+ */
+ public void customMigrate() {
+ }
+
+ @SuppressWarnings("unchecked")
+ private T convertRawValue(Object raw, Class type) {
+ if (raw == null) return null;
+ if (type == null) return null;
+
+ try {
+ if (type.isPrimitive()) {
+ if (type.equals(boolean.class)) return (T) Boolean.valueOf(Boolean.parseBoolean(String.valueOf(raw)));
+ if (type.equals(int.class)) return (T) Integer.valueOf(Integer.parseInt(String.valueOf(raw)));
+ if (type.equals(double.class)) return (T) Double.valueOf(Double.parseDouble(String.valueOf(raw)));
+ if (type.equals(long.class)) return (T) Long.valueOf(Long.parseLong(String.valueOf(raw)));
+ return null;
+ }
+
+ if (type.isInstance(raw)) return (T) raw;
+ if (type.equals(String.class)) return (T) String.valueOf(raw);
+ if (type.equals(Boolean.class)) return (T) Boolean.valueOf(Boolean.parseBoolean(String.valueOf(raw)));
+ if (type.equals(Integer.class)) return (T) Integer.valueOf(Integer.parseInt(String.valueOf(raw)));
+ if (type.equals(Double.class)) return (T) Double.valueOf(Double.parseDouble(String.valueOf(raw)));
+ if (type.equals(Long.class)) return (T) Long.valueOf(Long.parseLong(String.valueOf(raw)));
+ if (Map.class.isAssignableFrom(type) && raw instanceof Map) return (T) raw;
+
+ for (ConfigSerializer> serializer : SERIALIZERS) {
+ if (serializer.getType().equals(type)) {
+ return (T) serializer.deserialize(String.valueOf(raw));
+ }
+ }
+ } catch (RuntimeException e) {
+ plugin.getLogger().warning("Config value could not be converted to " + type.getName() + ": " + raw + " — " + e.getMessage());
+ }
+
+ return null;
+ }
+
+ @SuppressWarnings("unchecked")
+ private Class resolveListElementType(Field field) {
+ Type genericType = field.getGenericType();
+ if (!(genericType instanceof ParameterizedType)) return (Class) Object.class;
+
+ Type[] typeArguments = ((ParameterizedType) genericType).getActualTypeArguments();
+ if (typeArguments.length == 0) return (Class) Object.class;
+
+ Type firstType = typeArguments[0];
+ if (firstType instanceof Class) return (Class) firstType;
+ if (firstType instanceof ParameterizedType) {
+ Type rawType = ((ParameterizedType) firstType).getRawType();
+ if (rawType instanceof Class) return (Class) rawType;
+ }
+
+ return (Class) Object.class;
+ }
+
+ private List collectConfigFields() {
+ List fields = new ArrayList<>();
+ this.collectConfigFields(this, fields, Collections.newSetFromMap(new IdentityHashMap