Skip to content

Commit 40516ca

Browse files
authored
Add Addon Packets (#1)
* add AddonDisablePacket & InstalledAddon Packets * register missing addon packets * properly implement the addon packets * improve usability of InstalledAddonsResponse, add LabyModInstalledAddonsUpdateEvent * oops * add installed addon model
1 parent 9174438 commit 40516ca

File tree

19 files changed

+1160
-3
lines changed

19 files changed

+1160
-3
lines changed

api/src/main/java/net/labymod/serverapi/api/Protocol.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -325,13 +325,19 @@ private void handlePacket(ProtocolPacket protocolPacket, UUID sender, Packet pac
325325
this.awaitingResponses.remove(responsePacket);
326326
}
327327
} catch (Exception e) {
328-
e.printStackTrace();
328+
this.protocolService.logger().warn(
329+
"Failed to handle packet response " + packet.getClass().getSimpleName(), e);
329330
}
330331
}
331332
}
332333

333334
for (PacketHandler handler : protocolPacket.handlers) {
334-
handler.handle(sender, packet);
335+
try {
336+
handler.handle(sender, packet);
337+
} catch (Exception e) {
338+
this.protocolService.logger().warn(
339+
"Failed to handle packet " + packet.getClass().getSimpleName(), e);
340+
}
335341
}
336342

337343
this.protocolService.afterPacketHandled(this, packet, sender);

core/src/main/java/net/labymod/serverapi/core/AbstractLabyModPlayer.java

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
import net.labymod.serverapi.core.packet.clientbound.game.feature.PlayingGameModePacket;
4949
import net.labymod.serverapi.core.packet.clientbound.game.feature.marker.AddMarkerPacket;
5050
import net.labymod.serverapi.core.packet.clientbound.game.feature.marker.MarkerPacket;
51+
import net.labymod.serverapi.core.packet.clientbound.game.moderation.AddonDisablePacket;
5152
import net.labymod.serverapi.core.packet.clientbound.game.moderation.AddonRecommendationPacket;
5253
import net.labymod.serverapi.core.packet.clientbound.game.moderation.PermissionPacket;
5354
import net.labymod.serverapi.core.packet.clientbound.game.supplement.InputPromptPacket;
@@ -74,6 +75,7 @@ public abstract class AbstractLabyModPlayer<P extends AbstractLabyModPlayer<?>>
7475
private final AbstractLabyModProtocolService protocolService;
7576
private final List<LabyModIntegrationPlayer> integrationPlayers = new ArrayList<>();
7677
private final Map<String, EconomyDisplay> economies = new HashMap<>(2);
78+
private final List<String> disabledAddons = new ArrayList<>();
7779

7880
private Subtitle subtitle;
7981
private TabListFlag flag;
@@ -204,6 +206,51 @@ public void updateSubtitle(Consumer<Subtitle> consumer) {
204206
}
205207
}
206208

209+
/**
210+
* Forcefully disables the provided addons.
211+
*
212+
* @param addonsToDisable the addons to disable
213+
*/
214+
public void disableAddons(List<String> addonsToDisable) {
215+
for (String addon : addonsToDisable) {
216+
if (!this.disabledAddons.contains(addon)) {
217+
this.disabledAddons.add(addon);
218+
}
219+
}
220+
221+
this.sendPacket(AddonDisablePacket.disable(addonsToDisable));
222+
}
223+
224+
/**
225+
* Reverts the forced disable state for the provided addons
226+
*
227+
* @param addonsToRevert the addons to revert
228+
*/
229+
public void revertDisabledAddons(List<String> addonsToRevert) {
230+
for (String addon : addonsToRevert) {
231+
this.disabledAddons.remove(addon);
232+
}
233+
234+
this.sendPacket(AddonDisablePacket.revert(addonsToRevert));
235+
}
236+
237+
/**
238+
* Reverts the forced disable state for all addons disabled via {@link #disableAddons(List)}
239+
*/
240+
public void revertDisabledAddons() {
241+
this.sendPacket(AddonDisablePacket.revert(this.disabledAddons));
242+
this.disabledAddons.clear();
243+
}
244+
245+
/**
246+
* Gets all forcefully disabled addons disabled via {@link #disableAddons(List)}
247+
*
248+
* @return the disabled addons
249+
*/
250+
public List<String> getDisabledAddons() {
251+
return this.disabledAddons;
252+
}
253+
207254
/**
208255
* Gives LabyMod the instruction to send placed markers by the player as
209256
* {@link net.labymod.serverapi.core.packet.serverbound.game.feature.marker.ClientAddMarkerPacket}

core/src/main/java/net/labymod/serverapi/core/LabyModProtocol.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,16 @@
3737
import net.labymod.serverapi.core.packet.clientbound.game.feature.PlayingGameModePacket;
3838
import net.labymod.serverapi.core.packet.clientbound.game.feature.marker.AddMarkerPacket;
3939
import net.labymod.serverapi.core.packet.clientbound.game.feature.marker.MarkerPacket;
40+
import net.labymod.serverapi.core.packet.clientbound.game.moderation.AddonDisablePacket;
4041
import net.labymod.serverapi.core.packet.clientbound.game.moderation.AddonRecommendationPacket;
42+
import net.labymod.serverapi.core.packet.clientbound.game.moderation.InstalledAddonsRequestPacket;
4143
import net.labymod.serverapi.core.packet.clientbound.game.moderation.PermissionPacket;
4244
import net.labymod.serverapi.core.packet.clientbound.game.supplement.InputPromptPacket;
4345
import net.labymod.serverapi.core.packet.clientbound.game.supplement.ServerSwitchPromptPacket;
4446
import net.labymod.serverapi.core.packet.serverbound.game.feature.marker.ClientAddMarkerPacket;
4547
import net.labymod.serverapi.core.packet.serverbound.game.moderation.AddonRecommendationResponsePacket;
48+
import net.labymod.serverapi.core.packet.serverbound.game.moderation.AddonStateChangedPacket;
49+
import net.labymod.serverapi.core.packet.serverbound.game.moderation.InstalledAddonsResponsePacket;
4650
import net.labymod.serverapi.core.packet.serverbound.game.supplement.InputPromptResponsePacket;
4751
import net.labymod.serverapi.core.packet.serverbound.game.supplement.ServerSwitchPromptResponsePacket;
4852
import net.labymod.serverapi.core.packet.serverbound.login.VersionLoginPacket;
@@ -75,7 +79,7 @@ private void registerPackets() {
7579
this.registerPacket(21, ServerSwitchPromptResponsePacket.class, Direction.SERVERBOUND);
7680
this.registerPacket(22, InputPromptPacket.class, Direction.CLIENTBOUND);
7781
this.registerPacket(23, InputPromptResponsePacket.class, Direction.SERVERBOUND);
78-
//this.registerPacket(24, AddonDisablePacket.class, Direction.CLIENTBOUND);
82+
this.registerPacket(24, AddonDisablePacket.class, Direction.CLIENTBOUND);
7983
this.registerPacket(25, AddonRecommendationPacket.class, Direction.CLIENTBOUND);
8084
this.registerPacket(26, AddonRecommendationResponsePacket.class, Direction.SERVERBOUND);
8185
this.registerPacket(27, MarkerPacket.class, Direction.CLIENTBOUND);
@@ -84,5 +88,8 @@ private void registerPackets() {
8488
//this.registerPacket(30, ChatFilterPacket.class, Direction.CLIENTBOUND);
8589
//this.registerPacket(31, ChatFilterRemovePacket.class, Direction.CLIENTBOUND);
8690
//this.registerPacket(32, ServerEventPacket.class, Direction.CLIENTBOUND);
91+
this.registerPacket(33, InstalledAddonsRequestPacket.class, Direction.CLIENTBOUND);
92+
this.registerPacket(34, InstalledAddonsResponsePacket.class, Direction.SERVERBOUND);
93+
this.registerPacket(35, AddonStateChangedPacket.class, Direction.SERVERBOUND);
8794
}
8895
}
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
/*
2+
* MIT License
3+
*
4+
* Copyright (c) 2024 LabyMedia GmbH
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in all
14+
* copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
* SOFTWARE.
23+
*/
24+
25+
package net.labymod.serverapi.core.model.moderation;
26+
27+
import java.util.Objects;
28+
29+
public class InstalledAddon {
30+
31+
private final String namespace;
32+
private final AddonVersion version;
33+
private final boolean local;
34+
private boolean enabled;
35+
36+
public InstalledAddon(String namespace, AddonVersion version, boolean enabled, boolean local) {
37+
this.namespace = namespace;
38+
this.version = version;
39+
this.enabled = enabled;
40+
this.local = local;
41+
}
42+
43+
/**
44+
* @return the namespace of the addon
45+
*/
46+
public String getNamespace() {
47+
return this.namespace;
48+
}
49+
50+
/**
51+
* @return the version of the addon
52+
*/
53+
public AddonVersion getVersion() {
54+
return this.version;
55+
}
56+
57+
/**
58+
* @return whether the addon was downloaded from the addon store or not
59+
*/
60+
public boolean isLocal() {
61+
return this.local;
62+
}
63+
64+
/**
65+
* @return whether the addon is enabled or not
66+
*/
67+
public boolean isEnabled() {
68+
return this.enabled;
69+
}
70+
71+
/**
72+
* Sets the enabled state of the addon
73+
*/
74+
public void setEnabled(boolean enabled) {
75+
this.enabled = enabled;
76+
}
77+
78+
@Override
79+
public String toString() {
80+
return "Addon{" +
81+
"namespace='" + this.namespace + '\'' +
82+
", version=" + this.version +
83+
", enabled=" + this.enabled +
84+
", local=" + this.local +
85+
'}';
86+
}
87+
88+
@Override
89+
public boolean equals(Object o) {
90+
if (this == o) {
91+
return true;
92+
}
93+
94+
if (!(o instanceof InstalledAddon)) {
95+
return false;
96+
}
97+
98+
InstalledAddon that = (InstalledAddon) o;
99+
return Objects.equals(this.namespace, that.namespace);
100+
}
101+
102+
@Override
103+
public int hashCode() {
104+
return Objects.hash(this.namespace);
105+
}
106+
107+
public static class AddonVersion {
108+
109+
private final int major;
110+
private final int minor;
111+
private final int patch;
112+
113+
public AddonVersion(int major, int minor, int patch) {
114+
this.major = major;
115+
this.minor = minor;
116+
this.patch = patch;
117+
}
118+
119+
public int getMajor() {
120+
return this.major;
121+
}
122+
123+
public int getMinor() {
124+
return this.minor;
125+
}
126+
127+
public int getPatch() {
128+
return this.patch;
129+
}
130+
131+
@Override
132+
public String toString() {
133+
return this.major + "." + this.minor + "." + this.patch;
134+
}
135+
}
136+
}
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
/*
2+
* MIT License
3+
*
4+
* Copyright (c) 2024 LabyMedia GmbH
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in all
14+
* copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
* SOFTWARE.
23+
*/
24+
25+
package net.labymod.serverapi.core.packet.clientbound.game.moderation;
26+
27+
import net.labymod.serverapi.api.packet.Packet;
28+
import net.labymod.serverapi.api.payload.io.PayloadReader;
29+
import net.labymod.serverapi.api.payload.io.PayloadWriter;
30+
import org.jetbrains.annotations.NotNull;
31+
32+
import java.util.Arrays;
33+
import java.util.Collections;
34+
import java.util.List;
35+
import java.util.Objects;
36+
37+
public class AddonDisablePacket implements Packet {
38+
39+
private List<String> addonsToDisable;
40+
private Action action;
41+
42+
protected AddonDisablePacket(@NotNull Action action, @NotNull List<String> addonsToDisable) {
43+
Objects.requireNonNull(addonsToDisable, "Addons to disable cannot be null");
44+
Objects.requireNonNull(action, "Action cannot be null");
45+
this.action = action;
46+
this.addonsToDisable = addonsToDisable;
47+
}
48+
49+
protected AddonDisablePacket(@NotNull Action action, @NotNull String... addonsToDisable) {
50+
this(action, Collections.unmodifiableList(Arrays.asList(addonsToDisable)));
51+
}
52+
53+
/**
54+
* Creates a packet that force disables the provided addons
55+
*
56+
* @param addonsToDisable the addons to disable
57+
* @return the created packet
58+
*/
59+
public static AddonDisablePacket disable(@NotNull List<String> addonsToDisable) {
60+
return new AddonDisablePacket(Action.DISABLE, addonsToDisable);
61+
}
62+
63+
/**
64+
* Creates a packet that reverts the forced disable state for the provided addons
65+
*
66+
* @param addonsToRevert the addons to revert
67+
* @return the created packet
68+
*/
69+
public static AddonDisablePacket revert(@NotNull List<String> addonsToRevert) {
70+
return new AddonDisablePacket(Action.REVERT, addonsToRevert);
71+
}
72+
73+
/**
74+
* Creates a packet that force disables the provided addons
75+
*
76+
* @param addonsToDisable the addons to disable
77+
* @return the created packet
78+
*/
79+
public static AddonDisablePacket disable(@NotNull String... addonsToDisable) {
80+
return new AddonDisablePacket(Action.DISABLE, addonsToDisable);
81+
}
82+
83+
/**
84+
* Creates a packet that reverts the forced disable state for the provided addons
85+
*
86+
* @param addonsToRevert the addons to revert
87+
* @return the created packet
88+
*/
89+
public static AddonDisablePacket revert(@NotNull String... addonsToRevert) {
90+
return new AddonDisablePacket(Action.REVERT, addonsToRevert);
91+
}
92+
93+
@Override
94+
public void read(@NotNull PayloadReader reader) {
95+
this.action = reader.readBoolean() ? Action.DISABLE : Action.REVERT;
96+
this.addonsToDisable = reader.readList(reader::readString);
97+
}
98+
99+
@Override
100+
public void write(@NotNull PayloadWriter writer) {
101+
writer.writeBoolean(this.action == Action.DISABLE);
102+
writer.writeCollection(this.addonsToDisable, writer::writeString);
103+
}
104+
105+
public @NotNull List<String> getAddonsToDisable() {
106+
return this.addonsToDisable;
107+
}
108+
109+
public @NotNull Action action() {
110+
return this.action;
111+
}
112+
113+
@Override
114+
public String toString() {
115+
return "AddonDisablePacket{" +
116+
"addonsToDisable=" + this.addonsToDisable +
117+
", action=" + this.action +
118+
'}';
119+
}
120+
121+
public enum Action {
122+
DISABLE,
123+
REVERT
124+
}
125+
}

0 commit comments

Comments
 (0)