Skip to content

Commit 22e0c1d

Browse files
Feature - Server Links (#261)
* Add base ServerLinkModule # Conflicts: # docs/developers/lightweight/protobuf/getting-started.mdx # gradle/libs.versions.toml * server links api (WIP) * add the json & proto examples * add markdown docs * update serverlink docs * update paths in notification module example * update server link overview img * update overview desc * update component usage docs * Update version tags to 1.2.5 * Update license year * Fix conflicts * Remove extra line --------- Co-authored-by: TrentinTheKid <25537885+TrentinTheKid@users.noreply.github.com>
1 parent d806e8d commit 22e0c1d

38 files changed

Lines changed: 1369 additions & 90 deletions

File tree

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
* This file is part of Apollo, licensed under the MIT License.
3+
*
4+
* Copyright (c) 2026 Moonsworth
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+
package com.lunarclient.apollo.common.icon;
25+
26+
import lombok.Builder;
27+
import lombok.Getter;
28+
29+
/**
30+
* Represents a resource location icon.
31+
*
32+
* @since 1.2.5
33+
*/
34+
@Getter
35+
@Builder
36+
public final class ResourceLocationIcon extends Icon {
37+
38+
/**
39+
* Returns the icon {@link String} resource location.
40+
*
41+
* <p>Represents a path to an icon that will appear for the player.</p>
42+
*
43+
* @return the icon resource location
44+
* @since 1.2.5
45+
*/
46+
String resourceLocation;
47+
48+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/*
2+
* This file is part of Apollo, licensed under the MIT License.
3+
*
4+
* Copyright (c) 2026 Moonsworth
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+
package com.lunarclient.apollo.module.serverlink;
25+
26+
import lombok.Builder;
27+
import lombok.Getter;
28+
import net.kyori.adventure.text.Component;
29+
30+
/**
31+
* Represents a link entry displayed in the Server Links menu.
32+
*
33+
* @since 1.2.5
34+
*/
35+
@Getter
36+
@Builder
37+
public final class ServerLink {
38+
39+
/**
40+
* Returns the server link {@link String} id.
41+
*
42+
* @return the server link id
43+
* @since 1.2.5
44+
*/
45+
String id;
46+
47+
/**
48+
* Returns the server link {@link Component} display name.
49+
*
50+
* @return the server link display name
51+
* @since 1.2.5
52+
*/
53+
Component displayName;
54+
55+
/**
56+
* Returns the server link {@link String} url.
57+
*
58+
* @return the server link url
59+
* @since 1.2.5
60+
*/
61+
String url;
62+
63+
}
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
/*
2+
* This file is part of Apollo, licensed under the MIT License.
3+
*
4+
* Copyright (c) 2026 Moonsworth
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+
package com.lunarclient.apollo.module.serverlink;
25+
26+
import com.lunarclient.apollo.common.icon.ResourceLocationIcon;
27+
import com.lunarclient.apollo.module.ApolloModule;
28+
import com.lunarclient.apollo.module.ModuleDefinition;
29+
import com.lunarclient.apollo.recipients.Recipients;
30+
import java.util.List;
31+
import org.jetbrains.annotations.ApiStatus;
32+
33+
/**
34+
* Represents the server links module.
35+
*
36+
* <p>This module provides support for the Server Links feature introduced in
37+
* Minecraft 1.21.0, with compatibility extending down to version 1.7.</p>
38+
*
39+
* @since 1.2.5
40+
*/
41+
@ApiStatus.NonExtendable
42+
@ModuleDefinition(id = "server_link", name = "Server Link")
43+
public abstract class ServerLinkModule extends ApolloModule {
44+
45+
/**
46+
* Overrides the server link menu title image for the {@link Recipients}.
47+
*
48+
* <p>The provided {@link ResourceLocationIcon} will be displayed in place of the default
49+
* menu title.</p>
50+
*
51+
* <p>The resource location must reference a valid client-side asset using the standard
52+
* namespace format:</p>
53+
*
54+
* <pre>
55+
* minecraft:textures/item/apple.png
56+
* lunar:logo/logo-100x100.png
57+
* </pre>
58+
*
59+
* <p>For optimal results, a square image (e.g. 128x128) is recommended.</p>
60+
*
61+
* @param recipients the recipients that are receiving the packet
62+
* @param icon the resource location icon
63+
* @since 1.2.5
64+
*/
65+
public abstract void overrideServerLinkResource(Recipients recipients, ResourceLocationIcon icon);
66+
67+
/**
68+
* Resets the server link menu title image for the {@link Recipients}.
69+
*
70+
* <p>Reverts back to displaying the default menu title.</p>
71+
*
72+
* @param recipients the recipients that are receiving the packet
73+
* @since 1.2.5
74+
*/
75+
public abstract void resetServerLinkResource(Recipients recipients);
76+
77+
/**
78+
* Adds or updates the {@link ServerLink} for the {@link Recipients}.
79+
*
80+
* @param recipients the recipients that are receiving the packet
81+
* @param serverLink the server link
82+
* @since 1.2.5
83+
*/
84+
public abstract void addServerLink(Recipients recipients, ServerLink serverLink);
85+
86+
/**
87+
* Adds or updates the {@link ServerLink}s for the {@link Recipients}.
88+
*
89+
* @param recipients the recipients that are receiving the packet
90+
* @param serverLinks the server links
91+
* @since 1.2.5
92+
*/
93+
public abstract void addServerLink(Recipients recipients, List<ServerLink> serverLinks);
94+
95+
/**
96+
* Removes the {@link ServerLink} from the {@link Recipients}.
97+
*
98+
* @param recipients the recipients that are receiving the packet
99+
* @param serverLinkId the server link id
100+
* @since 1.2.5
101+
*/
102+
public abstract void removeServerLink(Recipients recipients, String serverLinkId);
103+
104+
/**
105+
* Removes the {@link ServerLink} from the {@link Recipients}.
106+
*
107+
* @param recipients the recipients that are receiving the packet
108+
* @param serverLink the server link
109+
* @since 1.2.5
110+
*/
111+
public abstract void removeServerLink(Recipients recipients, ServerLink serverLink);
112+
113+
/**
114+
* Removes the {@link ServerLink}s from the {@link Recipients}.
115+
*
116+
* @param recipients the recipients that are receiving the packet
117+
* @param serverLinkIds the server link ids
118+
* @since 1.2.5
119+
*/
120+
public abstract void removeServerLink(Recipients recipients, List<String> serverLinkIds);
121+
122+
/**
123+
* Resets all {@link ServerLink}s for the {@link Recipients}.
124+
*
125+
* @param recipients the recipients that are receiving the packet
126+
* @since 1.2.5
127+
*/
128+
public abstract void resetServerLinks(Recipients recipients);
129+
130+
}
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
/*
2+
* This file is part of Apollo, licensed under the MIT License.
3+
*
4+
* Copyright (c) 2026 Moonsworth
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+
package com.lunarclient.apollo.module.serverlink;
25+
26+
import com.lunarclient.apollo.common.ApolloComponent;
27+
import com.lunarclient.apollo.common.icon.ResourceLocationIcon;
28+
import com.lunarclient.apollo.network.NetworkTypes;
29+
import com.lunarclient.apollo.player.AbstractApolloPlayer;
30+
import com.lunarclient.apollo.recipients.Recipients;
31+
import com.lunarclient.apollo.serverlink.v1.AddServerLinkMessage;
32+
import com.lunarclient.apollo.serverlink.v1.OverrideServerLinkResourceMessage;
33+
import com.lunarclient.apollo.serverlink.v1.RemoveServerLinkMessage;
34+
import com.lunarclient.apollo.serverlink.v1.ResetServerLinkResourceMessage;
35+
import com.lunarclient.apollo.serverlink.v1.ResetServerLinksMessage;
36+
import java.util.Collections;
37+
import java.util.List;
38+
import java.util.stream.Collectors;
39+
import lombok.NonNull;
40+
41+
/**
42+
* Provides the server link module.
43+
*
44+
* @since 1.2.5
45+
*/
46+
public final class ServerLinkModuleImpl extends ServerLinkModule {
47+
48+
@Override
49+
public void overrideServerLinkResource(@NonNull Recipients recipients, @NonNull ResourceLocationIcon icon) {
50+
OverrideServerLinkResourceMessage message = OverrideServerLinkResourceMessage.newBuilder()
51+
.setIcon(NetworkTypes.toProtobuf(icon))
52+
.build();
53+
54+
recipients.forEach(player -> ((AbstractApolloPlayer) player).sendPacket(message));
55+
}
56+
57+
@Override
58+
public void resetServerLinkResource(@NonNull Recipients recipients) {
59+
ResetServerLinkResourceMessage message = ResetServerLinkResourceMessage.getDefaultInstance();
60+
recipients.forEach(player -> ((AbstractApolloPlayer) player).sendPacket(message));
61+
}
62+
63+
@Override
64+
public void addServerLink(@NonNull Recipients recipients, @NonNull ServerLink serverLink) {
65+
this.addServerLink(recipients, Collections.singletonList(serverLink));
66+
}
67+
68+
@Override
69+
public void addServerLink(@NonNull Recipients recipients, @NonNull List<ServerLink> serverLinks) {
70+
List<com.lunarclient.apollo.serverlink.v1.ServerLink> serverLinksProto = serverLinks.stream()
71+
.map(this::toProtobuf)
72+
.collect(Collectors.toList());
73+
74+
AddServerLinkMessage message = AddServerLinkMessage.newBuilder()
75+
.addAllServerLinks(serverLinksProto)
76+
.build();
77+
78+
recipients.forEach(player -> ((AbstractApolloPlayer) player).sendPacket(message));
79+
}
80+
81+
@Override
82+
public void removeServerLink(@NonNull Recipients recipients, @NonNull String serverLinkId) {
83+
this.removeServerLink(recipients, Collections.singletonList(serverLinkId));
84+
}
85+
86+
@Override
87+
public void removeServerLink(@NonNull Recipients recipients, @NonNull ServerLink serverLink) {
88+
this.removeServerLink(recipients, Collections.singletonList(serverLink.getId()));
89+
}
90+
91+
@Override
92+
public void removeServerLink(@NonNull Recipients recipients, @NonNull List<String> serverLinkIds) {
93+
RemoveServerLinkMessage message = RemoveServerLinkMessage.newBuilder()
94+
.addAllServerLinkIds(serverLinkIds)
95+
.build();
96+
97+
recipients.forEach(player -> ((AbstractApolloPlayer) player).sendPacket(message));
98+
}
99+
100+
@Override
101+
public void resetServerLinks(@NonNull Recipients recipients) {
102+
ResetServerLinksMessage message = ResetServerLinksMessage.getDefaultInstance();
103+
recipients.forEach(player -> ((AbstractApolloPlayer) player).sendPacket(message));
104+
}
105+
106+
private com.lunarclient.apollo.serverlink.v1.ServerLink toProtobuf(ServerLink serverLink) {
107+
return com.lunarclient.apollo.serverlink.v1.ServerLink.newBuilder()
108+
.setId(serverLink.getId())
109+
.setDisplayNameAdventureJsonLines(ApolloComponent.toJson(serverLink.getDisplayName()))
110+
.setUrl(serverLink.getUrl())
111+
.build();
112+
}
113+
114+
}

0 commit comments

Comments
 (0)