Skip to content

Commit adad904

Browse files
committed
Updated EnchantmentHandler & ChestSearch
1 parent 5610164 commit adad904

11 files changed

Lines changed: 857 additions & 77 deletions

File tree

src/main/java/net/wurstclient/FriendsList.java

Lines changed: 93 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,20 +11,30 @@
1111
import java.nio.file.NoSuchFileException;
1212
import java.nio.file.Path;
1313
import java.util.ArrayList;
14+
import java.util.HashSet;
15+
import java.util.Locale;
1416
import java.util.TreeSet;
1517

18+
import net.minecraft.ChatFormatting;
19+
import net.minecraft.client.Minecraft;
20+
import net.minecraft.client.multiplayer.PlayerInfo;
21+
import net.minecraft.network.chat.Component;
22+
import net.minecraft.network.chat.MutableComponent;
1623
import com.google.gson.JsonArray;
1724
import net.minecraft.world.entity.Entity;
1825
import net.minecraft.world.entity.player.Player;
1926
import net.wurstclient.commands.FriendsCmd;
27+
import net.wurstclient.events.UpdateListener;
2028
import net.wurstclient.settings.CheckboxSetting;
2129
import net.wurstclient.util.json.JsonException;
2230
import net.wurstclient.util.json.JsonUtils;
2331

24-
public class FriendsList
32+
public class FriendsList implements UpdateListener
2533
{
2634
private final TreeSet<String> friends = new TreeSet<>();
2735
private Path path;
36+
private String lastServerKey = "";
37+
private final HashSet<String> onlineFriends = new HashSet<>();
2838

2939
public FriendsList(Path path)
3040
{
@@ -77,6 +87,61 @@ public boolean isFriend(Entity entity)
7787
return entity != null && contains(entity.getName().getString());
7888
}
7989

90+
@Override
91+
public void onUpdate()
92+
{
93+
Minecraft mc = WurstClient.MC;
94+
if(mc == null)
95+
return;
96+
97+
FriendsCmd friendsCmd = WurstClient.INSTANCE.getCmds().friendsCmd;
98+
if(friendsCmd == null || !friendsCmd.getFriendJoinAlerts().isChecked())
99+
{
100+
lastServerKey = "";
101+
onlineFriends.clear();
102+
return;
103+
}
104+
105+
String serverKey = resolveServerKey(mc);
106+
if(serverKey.isEmpty() || mc.getConnection() == null
107+
|| mc.player == null)
108+
{
109+
lastServerKey = "";
110+
onlineFriends.clear();
111+
return;
112+
}
113+
114+
boolean serverChanged = !serverKey.equals(lastServerKey);
115+
HashSet<String> nowOnlineFriends = new HashSet<>();
116+
for(PlayerInfo info : mc.getConnection().getOnlinePlayers())
117+
{
118+
if(info == null || info.getProfile() == null)
119+
continue;
120+
121+
String name = info.getProfile().name();
122+
if(name == null || name.isBlank() || !contains(name)
123+
|| name.equals(mc.player.getName().getString()))
124+
continue;
125+
126+
nowOnlineFriends.add(name);
127+
}
128+
129+
if(serverChanged)
130+
{
131+
for(String name : nowOnlineFriends)
132+
sendFriendAlert(name + " is already on this server.");
133+
}else
134+
{
135+
for(String name : nowOnlineFriends)
136+
if(!onlineFriends.contains(name))
137+
sendFriendAlert(name + " joined this server.");
138+
}
139+
140+
onlineFriends.clear();
141+
onlineFriends.addAll(nowOnlineFriends);
142+
lastServerKey = serverKey;
143+
}
144+
80145
public ArrayList<String> toList()
81146
{
82147
return new ArrayList<>(friends);
@@ -121,4 +186,31 @@ private JsonArray createJson()
121186
friends.forEach(json::add);
122187
return json;
123188
}
189+
190+
private static String resolveServerKey(Minecraft mc)
191+
{
192+
try
193+
{
194+
if(mc.getCurrentServer() == null
195+
|| mc.getCurrentServer().ip == null)
196+
return "";
197+
return mc.getCurrentServer().ip.trim().toLowerCase(Locale.ROOT);
198+
}catch(Throwable ignored)
199+
{
200+
return "";
201+
}
202+
}
203+
204+
private static void sendFriendAlert(String message)
205+
{
206+
Minecraft mc = WurstClient.MC;
207+
if(mc == null || mc.gui == null)
208+
return;
209+
210+
MutableComponent prefix =
211+
Component.literal("[Friends] ").withStyle(ChatFormatting.BLUE);
212+
MutableComponent body =
213+
Component.literal(message).withStyle(ChatFormatting.WHITE);
214+
mc.gui.getChat().addClientSystemMessage(prefix.append(body));
215+
}
124216
}

src/main/java/net/wurstclient/WurstClient.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,7 @@ public void initialize()
175175
Path friendsFile = wurstFolder.resolve("friends.json");
176176
friends = new FriendsList(friendsFile);
177177
friends.load();
178+
eventManager.add(UpdateListener.class, friends);
178179

179180
translator = new WurstTranslator();
180181

Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
/*
2+
* Copyright (c) 2014-2026 Wurst-Imperium and contributors.
3+
*
4+
* This source code is subject to the terms of the GNU General Public
5+
* License, version 3. If a copy of the GPL was not distributed with this
6+
* file, You can obtain one at: https://www.gnu.org/licenses/gpl-3.0.txt
7+
*/
8+
package net.wurstclient.chestsearch;
9+
10+
import net.minecraft.core.BlockPos;
11+
12+
public final class SlotHighlighter
13+
{
14+
public static final SlotHighlighter INSTANCE = new SlotHighlighter();
15+
16+
private int enchantmentHandlerSlot = -1;
17+
private int chestSearchSlot = -1;
18+
private String chestSearchDimension = "";
19+
private BlockPos chestSearchPos;
20+
private boolean stickyUntilHovered;
21+
22+
private String pendingDimension = "";
23+
private BlockPos pendingPos;
24+
private int pendingSlot = -1;
25+
26+
private SlotHighlighter()
27+
{}
28+
29+
public synchronized void setPending(String dimension, BlockPos pos,
30+
int slot)
31+
{
32+
if(pos == null || slot < 0)
33+
{
34+
clearPending();
35+
return;
36+
}
37+
pendingDimension = normalize(dimension);
38+
pendingPos = pos.immutable();
39+
pendingSlot = slot;
40+
}
41+
42+
public synchronized void clearPending()
43+
{
44+
pendingDimension = "";
45+
pendingPos = null;
46+
pendingSlot = -1;
47+
}
48+
49+
public synchronized int tryActivate(String dimension, BlockPos pos)
50+
{
51+
String dim = normalize(dimension);
52+
if(pendingPos == null || pendingSlot < 0 || pos == null)
53+
return -1;
54+
if(!dim.equals(pendingDimension) || !pos.equals(pendingPos))
55+
return -1;
56+
chestSearchSlot = pendingSlot;
57+
chestSearchDimension = dim;
58+
chestSearchPos = pos.immutable();
59+
return chestSearchSlot;
60+
}
61+
62+
public synchronized int tryActivateForDimension(String dimension)
63+
{
64+
String dim = normalize(dimension);
65+
if(pendingPos == null || pendingSlot < 0)
66+
return -1;
67+
if(!dim.equals(pendingDimension))
68+
return -1;
69+
chestSearchSlot = pendingSlot;
70+
chestSearchDimension = dim;
71+
chestSearchPos = pendingPos.immutable();
72+
return chestSearchSlot;
73+
}
74+
75+
public synchronized int getActiveSlot()
76+
{
77+
return chestSearchSlot >= 0 ? chestSearchSlot : enchantmentHandlerSlot;
78+
}
79+
80+
public synchronized int getEnchantmentHandlerSlot()
81+
{
82+
return enchantmentHandlerSlot;
83+
}
84+
85+
public synchronized int getChestSearchSlot()
86+
{
87+
return chestSearchSlot;
88+
}
89+
90+
public synchronized String getChestSearchDimension()
91+
{
92+
return chestSearchDimension;
93+
}
94+
95+
public synchronized BlockPos getChestSearchPos()
96+
{
97+
return chestSearchPos;
98+
}
99+
100+
public synchronized void setActiveSlot(int slot)
101+
{
102+
if(slot < 0)
103+
{
104+
clearEnchantmentHandlerActive();
105+
return;
106+
}
107+
enchantmentHandlerSlot = slot;
108+
stickyUntilHovered = false;
109+
}
110+
111+
public synchronized void setStickySlot(int slot)
112+
{
113+
if(slot < 0)
114+
{
115+
clearEnchantmentHandlerActive();
116+
return;
117+
}
118+
enchantmentHandlerSlot = slot;
119+
stickyUntilHovered = true;
120+
}
121+
122+
public synchronized boolean isStickyActive()
123+
{
124+
return enchantmentHandlerSlot >= 0 && stickyUntilHovered;
125+
}
126+
127+
public synchronized boolean isEnchantmentHandlerActive()
128+
{
129+
return enchantmentHandlerSlot >= 0;
130+
}
131+
132+
public synchronized boolean isChestSearchActive()
133+
{
134+
return chestSearchSlot >= 0;
135+
}
136+
137+
public synchronized void clearEnchantmentHandlerActive()
138+
{
139+
enchantmentHandlerSlot = -1;
140+
stickyUntilHovered = false;
141+
}
142+
143+
public synchronized void clearChestSearchActive()
144+
{
145+
chestSearchSlot = -1;
146+
chestSearchDimension = "";
147+
chestSearchPos = null;
148+
}
149+
150+
public synchronized void forgetChestSearchSelection()
151+
{
152+
clearPending();
153+
clearChestSearchActive();
154+
}
155+
156+
public synchronized void clearActive()
157+
{
158+
clearEnchantmentHandlerActive();
159+
clearChestSearchActive();
160+
}
161+
162+
public synchronized void clearAll()
163+
{
164+
clearPending();
165+
clearActive();
166+
}
167+
168+
private static String normalize(String dimension)
169+
{
170+
if(dimension == null)
171+
return "";
172+
String dim = dimension.trim().toLowerCase(java.util.Locale.ROOT);
173+
int colon = dim.indexOf(':');
174+
if(colon >= 0 && colon < dim.length() - 1)
175+
return dim.substring(colon + 1);
176+
return dim;
177+
}
178+
179+
}

0 commit comments

Comments
 (0)