11// RandomDrop License | Copyright theo546 - github.com/theo546
22package com .theo546 .randomdrop ;
33
4+ import java .io .File ;
5+ import java .io .IOException ;
6+ import java .nio .charset .StandardCharsets ;
7+ import java .security .MessageDigest ;
8+ import java .security .NoSuchAlgorithmException ;
49import java .util .ArrayList ;
510import java .util .Arrays ;
611import java .util .Collections ;
1318import org .bukkit .Material ;
1419import org .bukkit .Location ;
1520import org .bukkit .World ;
21+ import org .bukkit .configuration .file .YamlConfiguration ;
1622import org .bukkit .enchantments .Enchantment ;
1723import org .bukkit .entity .Item ;
1824import org .bukkit .inventory .ItemStack ;
@@ -29,8 +35,28 @@ public class Main extends JavaPlugin {
2935 public static boolean KEEP_ITEM_CUSTOMNAME_ON_RANDOMIZE ;
3036 public static boolean CLAIM_CRAFTED_ITEMS ;
3137 public static boolean RANDOMIZE_CRAFT ;
38+ public static boolean PERSIST_LOOT_TABLE ;
3239 public static Map <Material , Material > LOOT_TABLE ;
3340
41+ private File getLootTableFile () {
42+ String hash = sha256 (String .valueOf (SEED )).substring (0 , 16 );
43+ return new File (getDataFolder (), "loot_table_" + hash + ".yml" );
44+ }
45+
46+ private static String sha256 (String input ) {
47+ try {
48+ MessageDigest digest = MessageDigest .getInstance ("SHA-256" );
49+ byte [] encoded = digest .digest (input .getBytes (StandardCharsets .UTF_8 ));
50+ StringBuilder sb = new StringBuilder ();
51+ for (byte b : encoded ) {
52+ sb .append (String .format ("%02x" , b ));
53+ }
54+ return sb .toString ();
55+ } catch (NoSuchAlgorithmException e ) {
56+ throw new RuntimeException (e );
57+ }
58+ }
59+
3460 @ Override
3561 public void onEnable () {
3662 getConfig ().addDefault ("RANDOMIZE_DURABILITY" , false );
@@ -41,6 +67,7 @@ public void onEnable() {
4167 getConfig ().addDefault ("KEEP_ITEM_CUSTOMNAME_ON_RANDOMIZE" , false );
4268 getConfig ().addDefault ("CLAIM_CRAFTED_ITEMS" , true );
4369 getConfig ().addDefault ("RANDOMIZE_CRAFT" , true );
70+ getConfig ().addDefault ("PERSIST_LOOT_TABLE" , true );
4471 getConfig ().options ().copyDefaults (true );
4572 saveConfig ();
4673
@@ -52,13 +79,19 @@ public void onEnable() {
5279 KEEP_ITEM_CUSTOMNAME_ON_RANDOMIZE = getConfig ().getBoolean ("KEEP_ITEM_CUSTOMNAME_ON_RANDOMIZE" );
5380 CLAIM_CRAFTED_ITEMS = getConfig ().getBoolean ("CLAIM_CRAFTED_ITEMS" );
5481 RANDOMIZE_CRAFT = getConfig ().getBoolean ("RANDOMIZE_CRAFT" );
82+ PERSIST_LOOT_TABLE = getConfig ().getBoolean ("PERSIST_LOOT_TABLE" );
5583
5684 initLootTable ();
5785 getServer ().getPluginManager ().registerEvents (new Listener (), this );
5886 }
5987
6088 private void initLootTable () {
6189 LOOT_TABLE = new HashMap <>();
90+ File file = getLootTableFile ();
91+ if (PERSIST_LOOT_TABLE && !getDataFolder ().exists ()) {
92+ getDataFolder ().mkdirs ();
93+ }
94+
6295 World world = Bukkit .getWorlds ().get (0 );
6396 Location spawn = world .getSpawnLocation ().clone ();
6497 spawn .setY (255 );
@@ -75,10 +108,44 @@ private void initLootTable() {
75108 }
76109 }
77110
111+ YamlConfiguration yaml = new YamlConfiguration ();
112+ if (PERSIST_LOOT_TABLE && file .exists ()) {
113+ try {
114+ yaml .load (file );
115+ for (String key : yaml .getKeys (false )) {
116+ Material k = Material .getMaterial (key );
117+ Material v = Material .getMaterial (yaml .getString (key ));
118+ if (k != null && v != null ) {
119+ LOOT_TABLE .put (k , v );
120+ }
121+ }
122+ } catch (Exception e ) {
123+ getLogger ().warning ("Failed to load loot table: " + e .getMessage ());
124+ }
125+ }
126+
78127 List <Material > shuffled = new ArrayList <>(valid );
79128 Collections .shuffle (shuffled , new Random (SEED ));
80- for (int i = 0 ; i < valid .size (); i ++) {
81- LOOT_TABLE .put (valid .get (i ), shuffled .get (i ));
129+ shuffled .removeAll (LOOT_TABLE .values ());
130+
131+ boolean updated = false ;
132+ for (Material m : valid ) {
133+ if (!LOOT_TABLE .containsKey (m )) {
134+ if (shuffled .isEmpty ()) break ;
135+ LOOT_TABLE .put (m , shuffled .remove (0 ));
136+ updated = true ;
137+ }
138+ }
139+
140+ if (PERSIST_LOOT_TABLE && (updated || !file .exists ())) {
141+ for (Map .Entry <Material , Material > entry : LOOT_TABLE .entrySet ()) {
142+ yaml .set (entry .getKey ().name (), entry .getValue ().name ());
143+ }
144+ try {
145+ yaml .save (file );
146+ } catch (IOException e ) {
147+ getLogger ().warning ("Failed to save loot table: " + e .getMessage ());
148+ }
82149 }
83150 }
84151
0 commit comments