10
10
import de .hysky .skyblocker .utils .NEURepoManager ;
11
11
import de .hysky .skyblocker .utils .scheduler .MessageScheduler ;
12
12
import io .github .moulberry .repo .data .NEUItem ;
13
+ import io .github .moulberry .repo .util .NEUId ;
13
14
import it .unimi .dsi .fastutil .Pair ;
14
15
import net .fabricmc .fabric .api .client .command .v2 .ClientCommandRegistrationCallback ;
15
16
import net .fabricmc .fabric .api .client .command .v2 .FabricClientCommandSource ;
24
25
import org .slf4j .Logger ;
25
26
import org .slf4j .LoggerFactory ;
26
27
27
- import java .util .Arrays ;
28
- import java .util .HashMap ;
29
- import java .util .HashSet ;
30
- import java .util .Map ;
28
+ import java .util .*;
31
29
import java .util .regex .Matcher ;
32
30
import java .util .regex .Pattern ;
33
31
import java .util .stream .Collectors ;
@@ -40,8 +38,7 @@ public class SearchOverManager {
40
38
private static final Logger LOGGER = LoggerFactory .getLogger ("Skyblocker Search Overlay" );
41
39
42
40
private static final Pattern BAZAAR_ENCHANTMENT_PATTERN = Pattern .compile ("ENCHANTMENT_(\\ D*)_(\\ d+)" );
43
- private static final Pattern AUCTION_PET_AND_RUNE_PATTERN = Pattern .compile ("([A-Z0-9_]+);(\\ d+)" );
44
-
41
+ private static final String PET_NAME_START = "[Lvl {LVL}] " ;
45
42
/**
46
43
* converts index (in array) +1 to a roman numeral
47
44
*/
@@ -52,14 +49,18 @@ public class SearchOverManager {
52
49
53
50
private static @ Nullable SignBlockEntity sign = null ;
54
51
private static boolean signFront = true ;
55
- private static boolean isAuction ;
52
+ protected static boolean isAuction ;
56
53
private static boolean isCommand ;
57
54
58
55
protected static String search = "" ;
56
+ protected static Boolean maxPetLevel = false ;
57
+ protected static int dungeonStars = 0 ;
59
58
60
59
// Use non-final variables and swap them to prevent concurrent modification
61
60
private static HashSet <String > bazaarItems ;
62
61
private static HashSet <String > auctionItems ;
62
+ private static HashSet <String > auctionPets ;
63
+ private static HashSet <String > starableItems ;
63
64
private static HashMap <String , String > namesToId ;
64
65
65
66
public static String [] suggestionsArray = {};
@@ -91,6 +92,8 @@ private static int startCommand(boolean isAuction) {
91
92
private static void loadItems () {
92
93
HashSet <String > bazaarItems = new HashSet <>();
93
94
HashSet <String > auctionItems = new HashSet <>();
95
+ HashSet <String > auctionPets = new HashSet <>();
96
+ HashSet <String > starableItems = new HashSet <>();
94
97
HashMap <String , String > namesToId = new HashMap <>();
95
98
96
99
//get bazaar items
@@ -139,28 +142,28 @@ private static void loadItems() {
139
142
140
143
//get auction items
141
144
try {
145
+ Set <@ NEUId String > essenceCosts = NEURepoManager .NEU_REPO .getConstants ().getEssenceCost ().getCosts ().keySet ();
142
146
if (TooltipInfoType .THREE_DAY_AVERAGE .getData () == null ) {
143
147
TooltipInfoType .THREE_DAY_AVERAGE .run ();
144
148
}
145
149
for (Map .Entry <String , JsonElement > entry : TooltipInfoType .THREE_DAY_AVERAGE .getData ().entrySet ()) {
146
150
String id = entry .getKey ();
147
-
148
- Matcher matcher = AUCTION_PET_AND_RUNE_PATTERN .matcher (id );
149
- if (matcher .find ()) {//is a pet or rune convert id to name
150
- String name = matcher .group (1 ).replace ("_" , " " );
151
- name = capitalizeFully (name );
152
- auctionItems .add (name );
153
- namesToId .put (name , id );
154
- continue ;
155
- }
156
- //something else look up in NEU repo.
151
+ //look up in NEU repo.
157
152
id = id .split ("[+-]" )[0 ];
158
153
NEUItem neuItem = NEURepoManager .NEU_REPO .getItems ().getItemBySkyblockId (id );
159
154
if (neuItem != null ) {
160
155
String name = Formatting .strip (neuItem .getDisplayName ());
156
+ //add names that are pets to the list of pets to work with the lvl 100 button
157
+ if (name != null && name .startsWith (PET_NAME_START )) {
158
+ name = name .replace (PET_NAME_START , "" );
159
+ auctionPets .add (name .toLowerCase ());
160
+ }
161
+ //if it has essence cost add to starable items
162
+ if (name != null && essenceCosts .contains (neuItem .getSkyblockItemId ())) {
163
+ starableItems .add (name .toLowerCase ());
164
+ }
161
165
auctionItems .add (name );
162
166
namesToId .put (name , id );
163
- continue ;
164
167
}
165
168
}
166
169
} catch (Exception e ) {
@@ -169,11 +172,14 @@ private static void loadItems() {
169
172
170
173
SearchOverManager .bazaarItems = bazaarItems ;
171
174
SearchOverManager .auctionItems = auctionItems ;
175
+ SearchOverManager .auctionPets = auctionPets ;
176
+ SearchOverManager .starableItems = starableItems ;
172
177
SearchOverManager .namesToId = namesToId ;
173
178
}
174
179
175
180
/**
176
181
* Capitalizes the first letter off every word in a string
182
+ *
177
183
* @param str string to capitalize
178
184
*/
179
185
private static String capitalizeFully (String str ) {
@@ -188,8 +194,9 @@ private static String capitalizeFully(String str) {
188
194
189
195
/**
190
196
* Receives data when a search is started and resets values
191
- * @param sign the sign that is being edited
192
- * @param front if it's the front of the sign
197
+ *
198
+ * @param sign the sign that is being edited
199
+ * @param front if it's the front of the sign
193
200
* @param isAuction if the sign is loaded from the auction house menu or bazaar
194
201
*/
195
202
public static void updateSign (@ NotNull SignBlockEntity sign , boolean front , boolean isAuction ) {
@@ -214,18 +221,38 @@ public static void updateSign(@NotNull SignBlockEntity sign, boolean front, bool
214
221
215
222
/**
216
223
* Updates the search value and the suggestions based on that value.
224
+ *
217
225
* @param newValue new search value
218
226
*/
219
227
protected static void updateSearch (String newValue ) {
220
228
search = newValue ;
221
229
//update the suggestion values
222
230
int totalSuggestions = SkyblockerConfigManager .get ().uiAndVisuals .searchOverlay .maxSuggestions ;
223
231
if (newValue .isBlank () || totalSuggestions == 0 ) return ; //do not search for empty value
224
- suggestionsArray = (isAuction ? auctionItems : bazaarItems ).stream ().filter (item -> item .toLowerCase ().contains (search .toLowerCase ())).limit (totalSuggestions ).toArray (String []::new );
232
+ suggestionsArray = (isAuction ? auctionItems : bazaarItems ).stream ().sorted (Comparator .comparing (SearchOverManager ::shouldFrontLoad , Comparator .reverseOrder ())).filter (item -> item .toLowerCase ().contains (search .toLowerCase ())).limit (totalSuggestions ).toArray (String []::new );
233
+ }
234
+
235
+ /**
236
+ * determines if a value should be moved to the front of the search
237
+ *
238
+ * @param name name of the suggested item
239
+ * @return if the value should be at the front of the search queue
240
+ */
241
+ private static boolean shouldFrontLoad (String name ) {
242
+ if (!isAuction ) {
243
+ return false ;
244
+ }
245
+ //do nothing to non pets
246
+ if (!auctionPets .contains (name .toLowerCase ())) {
247
+ return false ;
248
+ }
249
+ //only front load pets when there is enough of the pet typed, so it does not spoil searching for other items
250
+ return (double ) search .length () / name .length () > 0.5 ;
225
251
}
226
252
227
253
/**
228
254
* Gets the suggestion in the suggestion array at the index
255
+ *
229
256
* @param index index of suggestion
230
257
*/
231
258
protected static String getSuggestion (int index ) {
@@ -242,6 +269,7 @@ protected static String getSuggestionId(int index) {
242
269
243
270
/**
244
271
* Gets the item name in the history array at the index
272
+ *
245
273
* @param index index of suggestion
246
274
*/
247
275
protected static String getHistory (int index ) {
@@ -286,20 +314,64 @@ private static void saveHistory() {
286
314
}
287
315
288
316
/**
289
- *Saves the current value of ({@link SearchOverManager#search}) then pushes it to a command or sign depending on how the gui was opened
317
+ * Saves the current value of ({@link SearchOverManager#search}) then pushes it to a command or sign depending on how the gui was opened
290
318
*/
291
319
protected static void pushSearch () {
292
320
//save to history
293
321
if (!search .isEmpty ()) {
294
322
saveHistory ();
295
323
}
324
+ //add pet level or dungeon starts if in ah
325
+ if (isAuction ) {
326
+ addExtras ();
327
+ }
328
+ //push
296
329
if (isCommand ) {
297
330
pushCommand ();
298
331
} else {
299
332
pushSign ();
300
333
}
301
334
}
302
335
336
+ /**
337
+ * Adds pet level 100 or necessary dungeon starts if needed
338
+ */
339
+ private static void addExtras () {
340
+ // pet level
341
+ if (maxPetLevel ) {
342
+ if (auctionPets .contains (search .toLowerCase ())) {
343
+ if (search .equalsIgnoreCase ("golden dragon" )) {
344
+ search = "[Lvl 200] " + search ;
345
+ } else {
346
+ search = "[Lvl 100] " + search ;
347
+ }
348
+ }
349
+ } else {
350
+ // still filter for only pets
351
+ if (auctionPets .contains (search .toLowerCase ())) {
352
+ // add bracket so only get pets
353
+ search = "] " + search ;
354
+ }
355
+ }
356
+
357
+ // dungeon stars
358
+ // check if it's a dungeon item and if so add correct stars
359
+ if (dungeonStars > 0 && starableItems .contains (search .toLowerCase ())) {
360
+ StringBuilder starString = new StringBuilder (" " );
361
+ //add stars up to 5
362
+ starString .append ("✪" .repeat (Math .max (0 , Math .min (dungeonStars , 5 ))));
363
+ //add number for other stars
364
+ switch (dungeonStars ) {
365
+ case 6 -> starString .append ("➊" );
366
+ case 7 -> starString .append ("➋" );
367
+ case 8 -> starString .append ("➌" );
368
+ case 9 -> starString .append ("➍" );
369
+ case 10 -> starString .append ("➎" );
370
+ }
371
+ search += starString .toString ();
372
+ }
373
+ }
374
+
303
375
/**
304
376
* runs the command to search for the value in ({@link SearchOverManager#search})
305
377
*/
0 commit comments