77 */
88package net .wurstclient .hacks ;
99
10- import net .wurstclient .hack .Hack ;
11- import net .wurstclient .WurstClient ;
10+ import java .io .File ;
11+ import java .nio .file .Path ;
12+ import net .minecraft .network .chat .Component ;
13+ import net .wurstclient .Category ;
14+ import net .wurstclient .WurstClient ;
15+ import net .wurstclient .hack .Hack ;
1216import net .wurstclient .lootsearch .LootChestManager ;
1317import net .wurstclient .lootsearch .LootSearchUtil ;
14-
15- import java . io . File ;
18+ import net . wurstclient . settings . FileSetting ;
19+ import net . wurstclient . settings . TextFieldSetting ;
1620
1721public final class LootSearchHack extends Hack
1822{
19- public LootSearchHack ()
20- {
21- super ("LootSearch" );
22- // No category -> Navigator-only
23- }
23+ private final FileSetting lootJsonPicker =
24+ new FileSetting ("Loot JSON" , "" , "lootprobe" , folder -> {
25+ try
26+ {
27+ java .nio .file .Files .createDirectories (folder );
28+ Path placeholder = folder .resolve ("lootprobe-placeholder.json" );
29+ if (!java .nio .file .Files .exists (placeholder ))
30+ java .nio .file .Files .writeString (placeholder , "{}\n " );
31+ }catch (java .io .IOException e )
32+ {
33+ throw new RuntimeException (e );
34+ }
35+ });
36+
37+ private final TextFieldSetting literalJsonPath = new TextFieldSetting (
38+ "JSON Path" ,
39+ "Literal path to a loot export JSON file. If set, this path is used instead of auto-detection." ,
40+ "" );
41+
42+ public LootSearchHack ()
43+ {
44+ super ("LootSearch" );
45+ setCategory (Category .ITEMS );
46+ addSetting (lootJsonPicker );
47+ addSetting (literalJsonPath );
48+ }
2449
2550 @ Override
2651 protected void onEnable ()
@@ -36,26 +61,15 @@ protected void onEnable()
3661 }catch (Throwable ignored )
3762 {}
3863
39- File dir = LootSearchUtil .getSeedmapperLootDir ();
40- if (dir == null || !dir .exists () || !dir .isDirectory ())
41- {
42- if (WurstClient .MC != null && WurstClient .MC .player != null )
43- WurstClient .MC .player .displayClientMessage (
44- net .minecraft .network .chat .Component .literal (
45- "SeedMapper loot folder not found. Run SeedMapper and export loot first." ),
46- false );
47- setEnabled (false );
48- return ;
49- }
50-
51- File f = LootSearchUtil .findFileForServer (serverIp );
64+ File f = resolveLootFile (serverIp );
5265 if (f == null )
5366 {
67+ File dir = LootSearchUtil .getSeedmapperLootDir ();
5468 if (WurstClient .MC != null && WurstClient .MC .player != null )
5569 {
5670 WurstClient .MC .player
5771 .displayClientMessage (
58- net . minecraft . network . chat . Component .literal (
72+ Component .literal (
5973 "No loot export found for this server." ),
6074 false );
6175 sendLootSearchDebug (serverIp , dir );
@@ -75,19 +89,59 @@ protected void onEnable()
7589 setEnabled (false );
7690 }
7791
92+ private File resolveLootFile (String serverIp )
93+ {
94+ // Highest priority: literal path entered by user.
95+ File explicit = resolveLiteralJsonPath ();
96+ if (explicit != null )
97+ return explicit ;
98+
99+ // Then use selected file from wurst/lootprobe.
100+ File selected = LootSearchUtil
101+ .normalizeJsonFile (lootJsonPicker .getSelectedFile ().toFile ());
102+ if (selected != null && !selected .getName ()
103+ .equalsIgnoreCase ("lootprobe-placeholder.json" ))
104+ return selected ;
105+
106+ // Fallback to existing server-based SeedMapper detection.
107+ return LootSearchUtil .findFileForServer (serverIp );
108+ }
109+
110+ private File resolveLiteralJsonPath ()
111+ {
112+ String raw = literalJsonPath .getValue ();
113+ if (raw == null || raw .isBlank ())
114+ return null ;
115+
116+ File file = new File (raw .trim ());
117+ if (!file .isAbsolute () && WurstClient .MC != null
118+ && WurstClient .MC .gameDirectory != null )
119+ {
120+ file = new File (WurstClient .MC .gameDirectory , raw .trim ());
121+ }
122+
123+ File normalized = LootSearchUtil .normalizeJsonFile (file );
124+ if (normalized == null )
125+ {
126+ if (WurstClient .MC != null && WurstClient .MC .player != null )
127+ WurstClient .MC .player .displayClientMessage (Component .literal (
128+ "LootSearch: JSON Path does not point to an existing .json file." ),
129+ false );
130+ }
131+ return normalized ;
132+ }
133+
78134 private void sendLootSearchDebug (String serverIp , File dir )
79135 {
80136 if (WurstClient .MC == null || WurstClient .MC .player == null )
81137 return ;
82138
83139 String ip = serverIp == null ? "<null>" : serverIp ;
84140 String dirPath = dir == null ? "<null>" : dir .getAbsolutePath ();
85- WurstClient .MC .player
86- .displayClientMessage (net .minecraft .network .chat .Component
87- .literal ("LootSearch debug: serverIp=" + ip ), false );
88- WurstClient .MC .player
89- .displayClientMessage (net .minecraft .network .chat .Component
90- .literal ("LootSearch debug: lootDir=" + dirPath ), false );
141+ WurstClient .MC .player .displayClientMessage (
142+ Component .literal ("LootSearch debug: serverIp=" + ip ), false );
143+ WurstClient .MC .player .displayClientMessage (
144+ Component .literal ("LootSearch debug: lootDir=" + dirPath ), false );
91145
92146 if (dir == null || !dir .exists () || !dir .isDirectory ())
93147 return ;
@@ -96,10 +150,8 @@ private void sendLootSearchDebug(String serverIp, File dir)
96150 dir .listFiles ((d , name ) -> name .toLowerCase ().endsWith (".json" ));
97151 if (files == null || files .length == 0 )
98152 {
99- WurstClient .MC .player .displayClientMessage (
100- net .minecraft .network .chat .Component .literal (
101- "LootSearch debug: no .json files in lootDir" ),
102- false );
153+ WurstClient .MC .player .displayClientMessage (Component
154+ .literal ("LootSearch debug: no .json files in lootDir" ), false );
103155 return ;
104156 }
105157
@@ -113,8 +165,7 @@ private void sendLootSearchDebug(String serverIp, File dir)
113165 if (files .length > 10 )
114166 names .append (" ... (" ).append (files .length ).append (" total)" );
115167
116- WurstClient .MC .player
117- .displayClientMessage (net .minecraft .network .chat .Component
118- .literal ("LootSearch debug: files=" + names ), false );
168+ WurstClient .MC .player .displayClientMessage (
169+ Component .literal ("LootSearch debug: files=" + names ), false );
119170 }
120171}
0 commit comments