Skip to content

Commit

Permalink
feat: minestom server implementation (#5)
Browse files Browse the repository at this point in the history
* minestom initial commit

* fix: readme, init -> initialize, slf4j logger
  • Loading branch information
nateweisz authored Sep 5, 2024
1 parent e754307 commit 3088e29
Show file tree
Hide file tree
Showing 11 changed files with 593 additions and 1 deletion.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ The Server API is organized into several modules:
- `bungeecord` - The platform-specific integration for Servers running on BungeeCord.
- `common` - Contains shared classes and utilities used across different server implementations to ensure consistent
behavior and reduce code duplication.
- `minestom` - The platform-specific integration for Servers running on Minestom.
- `velocity` - The platform-specific integration for Servers running on Velocity.

## Integrations
Expand Down
21 changes: 21 additions & 0 deletions server/minestom/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
plugins {
id("java")
}

repositories {
mavenCentral()
}

dependencies {
compileOnly("net.minestom:minestom-snapshots:8f46913486")
}

java {
toolchain {
languageVersion.set(JavaLanguageVersion.of(21))
}
sourceCompatibility = JavaVersion.VERSION_21
targetCompatibility = JavaVersion.VERSION_21

}

Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* MIT License
*
* Copyright (c) 2024 LabyMedia GmbH
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

package net.labymod.serverapi.server.minestom;

import net.labymod.serverapi.core.AbstractLabyModPlayer;
import net.labymod.serverapi.core.AbstractLabyModProtocolService;
import net.labymod.serverapi.server.common.AbstractServerLabyModProtocolService;
import net.labymod.serverapi.server.common.model.player.AbstractServerLabyModPlayer;
import net.minestom.server.entity.Player;

import java.util.UUID;

public class LabyModPlayer extends AbstractServerLabyModPlayer<LabyModPlayer, Player> {
public LabyModPlayer(AbstractServerLabyModProtocolService<?> protocolService, UUID uniqueId, Player player, String labyModVersion) {
super(protocolService, uniqueId, player, labyModVersion);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
/*
* MIT License
*
* Copyright (c) 2024 LabyMedia GmbH
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

package net.labymod.serverapi.server.minestom;

import net.labymod.serverapi.api.Protocol;
import net.labymod.serverapi.api.logger.NoOpProtocolPlatformLogger;
import net.labymod.serverapi.api.logger.ProtocolPlatformLogger;
import net.labymod.serverapi.api.packet.Packet;
import net.labymod.serverapi.api.payload.PayloadChannelIdentifier;
import net.labymod.serverapi.api.payload.io.PayloadReader;
import net.labymod.serverapi.api.payload.io.PayloadWriter;
import net.labymod.serverapi.core.AbstractLabyModProtocolService;
import net.labymod.serverapi.core.packet.serverbound.login.VersionLoginPacket;
import net.labymod.serverapi.server.common.AbstractServerLabyModProtocolService;
import net.labymod.serverapi.server.common.JavaProtocolLogger;
import net.labymod.serverapi.server.common.model.player.AbstractServerLabyModPlayer;
import net.labymod.serverapi.server.minestom.event.LabyModInstalledAddonsUpdateEvent;
import net.labymod.serverapi.server.minestom.event.LabyModPacketReceivedEvent;
import net.labymod.serverapi.server.minestom.event.LabyModPacketSentEvent;
import net.labymod.serverapi.server.minestom.handler.DefaultVersionLoginPacketHandler;
import net.minestom.server.MinecraftServer;
import net.minestom.server.entity.Player;
import net.minestom.server.event.player.PlayerDisconnectEvent;
import net.minestom.server.event.player.PlayerPluginMessageEvent;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Objects;
import java.util.UUID;

public class LabyModProtocolService extends AbstractServerLabyModProtocolService<LabyModPlayer> {

private static LabyModProtocolService INSTANCE;
private final ProtocolPlatformLogger logger = new Slf4jPlatformLogger(LoggerFactory.getLogger(LabyModProtocolService.class));
private boolean initialized = false;

private LabyModProtocolService() {
}

public static LabyModProtocolService get() {
return INSTANCE;
}

public static void initialize() {
INSTANCE = new LabyModProtocolService();
INSTANCE.init();
}

private void init() {
if (initialized) {
throw new IllegalStateException("This protocol service is already initialized.");
}

labyModProtocol.registerHandler(
VersionLoginPacket.class,
new DefaultVersionLoginPacketHandler(this)
);

this.registry().addRegisterListener(
protocol -> {
MinecraftServer.getGlobalEventHandler().addListener(PlayerPluginMessageEvent.class, event -> onPluginMessage(event, protocol));
}
);
MinecraftServer.getGlobalEventHandler().addListener(PlayerDisconnectEvent.class, event -> {
handlePlayerQuit(event.getPlayer().getUuid());
});

initialized = true;
}

/**
* {@inheritDoc}
*/
@Override
@ApiStatus.Internal
public void handleInstalledAddonsUpdate(AbstractServerLabyModPlayer<?, ?> labyModPlayer) {
MinecraftServer.getGlobalEventHandler().call(new LabyModInstalledAddonsUpdateEvent(
this,
(LabyModPlayer) labyModPlayer
));
}

/**
* {@inheritDoc}
*/
@Override
public void send(@NotNull PayloadChannelIdentifier identifier, @NotNull UUID recipient, @NotNull PayloadWriter writer) {
Objects.requireNonNull(identifier, "Identifier cannot be null");
Objects.requireNonNull(recipient, "Recipient cannot be null");
Objects.requireNonNull(writer, "Writer cannot be null");

Player player = MinecraftServer.getConnectionManager().getOnlinePlayerByUuid(recipient);
if (player == null) {
return;
}

player.sendPluginMessage(identifier.toString(), writer.toByteArray());
}

@Override
public void afterPacketHandled(@NotNull Protocol protocol, @NotNull Packet packet, @NotNull UUID sender) {
MinecraftServer.getGlobalEventHandler().call(
new LabyModPacketReceivedEvent(
this,
protocol,
getPlayer(sender),
packet
)
);
}

@Override
public void afterPacketSent(@NotNull Protocol protocol, @NotNull Packet packet, @NotNull UUID recipient) {
MinecraftServer.getGlobalEventHandler().call(
new LabyModPacketSentEvent(
this,
protocol,
getPlayer(recipient),
packet
)
);
}

/**
* {@inheritDoc}
*/
@Override
public @NotNull ProtocolPlatformLogger logger() {
return logger;
}

/**
* {@inheritDoc}
*/
@Override
public boolean isInitialized() {
return true;
}

private void onPluginMessage(PlayerPluginMessageEvent event, Protocol protocol) {
if (!event.getIdentifier().equals(protocol.identifier().toString())) {
return;
}

try {
PayloadReader reader = new PayloadReader(event.getMessage());
protocol.handleIncomingPayload(event.getPlayer().getUuid(), reader);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package net.labymod.serverapi.server.minestom;

import net.labymod.serverapi.api.logger.ProtocolPlatformLogger;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;

public class Slf4jPlatformLogger implements ProtocolPlatformLogger {

private final Logger logger;

public Slf4jPlatformLogger(Logger logger) {
this.logger = logger;
}

@Override
public void info(@NotNull String s, Object... objects) {
this.logger.info(s, objects);
}

@Override
public void info(@NotNull String s, Throwable throwable) {
this.logger.info(s, throwable);
}

@Override
public void warn(@NotNull String s, Object... objects) {
this.logger.warn(s, objects);
}

@Override
public void warn(@NotNull String s, Throwable throwable) {
this.logger.warn(s, throwable);
}

@Override
public void error(@NotNull String s, Object... objects) {
this.logger.error(s, objects);
}

@Override
public void error(@NotNull String s, Throwable throwable) {
this.logger.error(s, throwable);
}

@Override
public void debug(@NotNull String message, Object... objects) {
this.logger.debug(message, objects);
}

@Override
public void debug(@NotNull String message, Throwable throwable) {
this.logger.debug(message, throwable);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* MIT License
*
* Copyright (c) 2024 LabyMedia GmbH
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

package net.labymod.serverapi.server.minestom.event;

import net.labymod.serverapi.server.common.model.addon.InstalledAddonsResponse;
import net.labymod.serverapi.server.minestom.LabyModPlayer;
import net.labymod.serverapi.server.minestom.LabyModProtocolService;
import net.minestom.server.entity.Player;
import net.minestom.server.event.trait.PlayerEvent;
import org.jetbrains.annotations.NotNull;

public record LabyModInstalledAddonsUpdateEvent(
LabyModProtocolService protocolService,
LabyModPlayer player
) implements PlayerEvent {

public @NotNull LabyModProtocolService protocolService() {
return this.protocolService;
}

public @NotNull LabyModPlayer labyModPlayer() {
return this.player;
}

public @NotNull InstalledAddonsResponse installedAddons() {
return this.player.installedAddons();
}

@Override
public @NotNull Player getPlayer() {
return player.getPlayer();
}
}
Loading

0 comments on commit 3088e29

Please sign in to comment.