Skip to content

Commit 3088e29

Browse files
authored
feat: minestom server implementation (#5)
* minestom initial commit * fix: readme, init -> initialize, slf4j logger
1 parent e754307 commit 3088e29

11 files changed

+593
-1
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ The Server API is organized into several modules:
1919
- `bungeecord` - The platform-specific integration for Servers running on BungeeCord.
2020
- `common` - Contains shared classes and utilities used across different server implementations to ensure consistent
2121
behavior and reduce code duplication.
22+
- `minestom` - The platform-specific integration for Servers running on Minestom.
2223
- `velocity` - The platform-specific integration for Servers running on Velocity.
2324

2425
## Integrations

server/minestom/build.gradle.kts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
plugins {
2+
id("java")
3+
}
4+
5+
repositories {
6+
mavenCentral()
7+
}
8+
9+
dependencies {
10+
compileOnly("net.minestom:minestom-snapshots:8f46913486")
11+
}
12+
13+
java {
14+
toolchain {
15+
languageVersion.set(JavaLanguageVersion.of(21))
16+
}
17+
sourceCompatibility = JavaVersion.VERSION_21
18+
targetCompatibility = JavaVersion.VERSION_21
19+
20+
}
21+
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
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.server.minestom;
26+
27+
import net.labymod.serverapi.core.AbstractLabyModPlayer;
28+
import net.labymod.serverapi.core.AbstractLabyModProtocolService;
29+
import net.labymod.serverapi.server.common.AbstractServerLabyModProtocolService;
30+
import net.labymod.serverapi.server.common.model.player.AbstractServerLabyModPlayer;
31+
import net.minestom.server.entity.Player;
32+
33+
import java.util.UUID;
34+
35+
public class LabyModPlayer extends AbstractServerLabyModPlayer<LabyModPlayer, Player> {
36+
public LabyModPlayer(AbstractServerLabyModProtocolService<?> protocolService, UUID uniqueId, Player player, String labyModVersion) {
37+
super(protocolService, uniqueId, player, labyModVersion);
38+
}
39+
}
Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
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.server.minestom;
26+
27+
import net.labymod.serverapi.api.Protocol;
28+
import net.labymod.serverapi.api.logger.NoOpProtocolPlatformLogger;
29+
import net.labymod.serverapi.api.logger.ProtocolPlatformLogger;
30+
import net.labymod.serverapi.api.packet.Packet;
31+
import net.labymod.serverapi.api.payload.PayloadChannelIdentifier;
32+
import net.labymod.serverapi.api.payload.io.PayloadReader;
33+
import net.labymod.serverapi.api.payload.io.PayloadWriter;
34+
import net.labymod.serverapi.core.AbstractLabyModProtocolService;
35+
import net.labymod.serverapi.core.packet.serverbound.login.VersionLoginPacket;
36+
import net.labymod.serverapi.server.common.AbstractServerLabyModProtocolService;
37+
import net.labymod.serverapi.server.common.JavaProtocolLogger;
38+
import net.labymod.serverapi.server.common.model.player.AbstractServerLabyModPlayer;
39+
import net.labymod.serverapi.server.minestom.event.LabyModInstalledAddonsUpdateEvent;
40+
import net.labymod.serverapi.server.minestom.event.LabyModPacketReceivedEvent;
41+
import net.labymod.serverapi.server.minestom.event.LabyModPacketSentEvent;
42+
import net.labymod.serverapi.server.minestom.handler.DefaultVersionLoginPacketHandler;
43+
import net.minestom.server.MinecraftServer;
44+
import net.minestom.server.entity.Player;
45+
import net.minestom.server.event.player.PlayerDisconnectEvent;
46+
import net.minestom.server.event.player.PlayerPluginMessageEvent;
47+
import org.jetbrains.annotations.ApiStatus;
48+
import org.jetbrains.annotations.NotNull;
49+
import org.slf4j.Logger;
50+
import org.slf4j.LoggerFactory;
51+
52+
import java.util.Objects;
53+
import java.util.UUID;
54+
55+
public class LabyModProtocolService extends AbstractServerLabyModProtocolService<LabyModPlayer> {
56+
57+
private static LabyModProtocolService INSTANCE;
58+
private final ProtocolPlatformLogger logger = new Slf4jPlatformLogger(LoggerFactory.getLogger(LabyModProtocolService.class));
59+
private boolean initialized = false;
60+
61+
private LabyModProtocolService() {
62+
}
63+
64+
public static LabyModProtocolService get() {
65+
return INSTANCE;
66+
}
67+
68+
public static void initialize() {
69+
INSTANCE = new LabyModProtocolService();
70+
INSTANCE.init();
71+
}
72+
73+
private void init() {
74+
if (initialized) {
75+
throw new IllegalStateException("This protocol service is already initialized.");
76+
}
77+
78+
labyModProtocol.registerHandler(
79+
VersionLoginPacket.class,
80+
new DefaultVersionLoginPacketHandler(this)
81+
);
82+
83+
this.registry().addRegisterListener(
84+
protocol -> {
85+
MinecraftServer.getGlobalEventHandler().addListener(PlayerPluginMessageEvent.class, event -> onPluginMessage(event, protocol));
86+
}
87+
);
88+
MinecraftServer.getGlobalEventHandler().addListener(PlayerDisconnectEvent.class, event -> {
89+
handlePlayerQuit(event.getPlayer().getUuid());
90+
});
91+
92+
initialized = true;
93+
}
94+
95+
/**
96+
* {@inheritDoc}
97+
*/
98+
@Override
99+
@ApiStatus.Internal
100+
public void handleInstalledAddonsUpdate(AbstractServerLabyModPlayer<?, ?> labyModPlayer) {
101+
MinecraftServer.getGlobalEventHandler().call(new LabyModInstalledAddonsUpdateEvent(
102+
this,
103+
(LabyModPlayer) labyModPlayer
104+
));
105+
}
106+
107+
/**
108+
* {@inheritDoc}
109+
*/
110+
@Override
111+
public void send(@NotNull PayloadChannelIdentifier identifier, @NotNull UUID recipient, @NotNull PayloadWriter writer) {
112+
Objects.requireNonNull(identifier, "Identifier cannot be null");
113+
Objects.requireNonNull(recipient, "Recipient cannot be null");
114+
Objects.requireNonNull(writer, "Writer cannot be null");
115+
116+
Player player = MinecraftServer.getConnectionManager().getOnlinePlayerByUuid(recipient);
117+
if (player == null) {
118+
return;
119+
}
120+
121+
player.sendPluginMessage(identifier.toString(), writer.toByteArray());
122+
}
123+
124+
@Override
125+
public void afterPacketHandled(@NotNull Protocol protocol, @NotNull Packet packet, @NotNull UUID sender) {
126+
MinecraftServer.getGlobalEventHandler().call(
127+
new LabyModPacketReceivedEvent(
128+
this,
129+
protocol,
130+
getPlayer(sender),
131+
packet
132+
)
133+
);
134+
}
135+
136+
@Override
137+
public void afterPacketSent(@NotNull Protocol protocol, @NotNull Packet packet, @NotNull UUID recipient) {
138+
MinecraftServer.getGlobalEventHandler().call(
139+
new LabyModPacketSentEvent(
140+
this,
141+
protocol,
142+
getPlayer(recipient),
143+
packet
144+
)
145+
);
146+
}
147+
148+
/**
149+
* {@inheritDoc}
150+
*/
151+
@Override
152+
public @NotNull ProtocolPlatformLogger logger() {
153+
return logger;
154+
}
155+
156+
/**
157+
* {@inheritDoc}
158+
*/
159+
@Override
160+
public boolean isInitialized() {
161+
return true;
162+
}
163+
164+
private void onPluginMessage(PlayerPluginMessageEvent event, Protocol protocol) {
165+
if (!event.getIdentifier().equals(protocol.identifier().toString())) {
166+
return;
167+
}
168+
169+
try {
170+
PayloadReader reader = new PayloadReader(event.getMessage());
171+
protocol.handleIncomingPayload(event.getPlayer().getUuid(), reader);
172+
} catch (Exception e) {
173+
e.printStackTrace();
174+
}
175+
}
176+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package net.labymod.serverapi.server.minestom;
2+
3+
import net.labymod.serverapi.api.logger.ProtocolPlatformLogger;
4+
import org.jetbrains.annotations.NotNull;
5+
import org.slf4j.Logger;
6+
7+
public class Slf4jPlatformLogger implements ProtocolPlatformLogger {
8+
9+
private final Logger logger;
10+
11+
public Slf4jPlatformLogger(Logger logger) {
12+
this.logger = logger;
13+
}
14+
15+
@Override
16+
public void info(@NotNull String s, Object... objects) {
17+
this.logger.info(s, objects);
18+
}
19+
20+
@Override
21+
public void info(@NotNull String s, Throwable throwable) {
22+
this.logger.info(s, throwable);
23+
}
24+
25+
@Override
26+
public void warn(@NotNull String s, Object... objects) {
27+
this.logger.warn(s, objects);
28+
}
29+
30+
@Override
31+
public void warn(@NotNull String s, Throwable throwable) {
32+
this.logger.warn(s, throwable);
33+
}
34+
35+
@Override
36+
public void error(@NotNull String s, Object... objects) {
37+
this.logger.error(s, objects);
38+
}
39+
40+
@Override
41+
public void error(@NotNull String s, Throwable throwable) {
42+
this.logger.error(s, throwable);
43+
}
44+
45+
@Override
46+
public void debug(@NotNull String message, Object... objects) {
47+
this.logger.debug(message, objects);
48+
}
49+
50+
@Override
51+
public void debug(@NotNull String message, Throwable throwable) {
52+
this.logger.debug(message, throwable);
53+
}
54+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
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.server.minestom.event;
26+
27+
import net.labymod.serverapi.server.common.model.addon.InstalledAddonsResponse;
28+
import net.labymod.serverapi.server.minestom.LabyModPlayer;
29+
import net.labymod.serverapi.server.minestom.LabyModProtocolService;
30+
import net.minestom.server.entity.Player;
31+
import net.minestom.server.event.trait.PlayerEvent;
32+
import org.jetbrains.annotations.NotNull;
33+
34+
public record LabyModInstalledAddonsUpdateEvent(
35+
LabyModProtocolService protocolService,
36+
LabyModPlayer player
37+
) implements PlayerEvent {
38+
39+
public @NotNull LabyModProtocolService protocolService() {
40+
return this.protocolService;
41+
}
42+
43+
public @NotNull LabyModPlayer labyModPlayer() {
44+
return this.player;
45+
}
46+
47+
public @NotNull InstalledAddonsResponse installedAddons() {
48+
return this.player.installedAddons();
49+
}
50+
51+
@Override
52+
public @NotNull Player getPlayer() {
53+
return player.getPlayer();
54+
}
55+
}

0 commit comments

Comments
 (0)