mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-12 17:07:55 -04:00
wip modding api: PluginChannelHandler
This commit is contained in:
parent
967e612257
commit
3630aecf5f
@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Codename Minosoft
|
||||
* Copyright (C) 2020 Moritz Zwerger
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.protocol.modding.channels;
|
||||
|
||||
import de.bixilon.minosoft.protocol.protocol.InByteBuffer;
|
||||
|
||||
public interface ChannelHandler {
|
||||
|
||||
void handle(PluginChannelHandler handler, InByteBuffer buffer);
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Codename Minosoft
|
||||
* Copyright (C) 2020 Moritz Zwerger
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.protocol.modding.channels;
|
||||
|
||||
public enum DefaultPluginChannels {
|
||||
MC_BRAND("MC|Brand");
|
||||
|
||||
|
||||
final String name;
|
||||
|
||||
DefaultPluginChannels(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public static DefaultPluginChannels byName(String name) {
|
||||
for (DefaultPluginChannels d : values()) {
|
||||
if (d.getName().equals(name)) {
|
||||
return d;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
}
|
@ -0,0 +1,112 @@
|
||||
/*
|
||||
* Codename Minosoft
|
||||
* Copyright (C) 2020 Moritz Zwerger
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.protocol.modding.channels;
|
||||
|
||||
import de.bixilon.minosoft.logging.Log;
|
||||
import de.bixilon.minosoft.protocol.network.Connection;
|
||||
import de.bixilon.minosoft.protocol.packets.serverbound.play.PacketPluginMessageSending;
|
||||
import de.bixilon.minosoft.protocol.protocol.InByteBuffer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class PluginChannelHandler {
|
||||
final Map<String, List<ChannelHandler>> channels;
|
||||
final List<String> registeredClientChannels;
|
||||
final List<String> registeredServerChannels;
|
||||
final Connection connection;
|
||||
|
||||
public PluginChannelHandler(Connection connection) {
|
||||
channels = new HashMap<>();
|
||||
registeredClientChannels = new ArrayList<>();
|
||||
registeredServerChannels = new ArrayList<>();
|
||||
this.connection = connection;
|
||||
}
|
||||
|
||||
public void registerClientHandler(String name, ChannelHandler handler) {
|
||||
if (channels.get(name) == null) {
|
||||
// no channel with that name was registered yet
|
||||
List<ChannelHandler> handlerList = new ArrayList<>();
|
||||
handlerList.add(handler);
|
||||
channels.put(name, handlerList);
|
||||
return;
|
||||
}
|
||||
// was registered, appending to list
|
||||
|
||||
channels.get(name).add(handler);
|
||||
}
|
||||
|
||||
public void unregisterClientHandler(String name, ChannelHandler handler) {
|
||||
if (channels.get(name) == null) {
|
||||
// not registered
|
||||
return;
|
||||
}
|
||||
channels.get(name).remove(handler);
|
||||
}
|
||||
|
||||
public void handle(String name, byte[] data) {
|
||||
if (name.equals("REGISTER")) {
|
||||
// register this channel
|
||||
String toRegisterName = new String(data);
|
||||
registeredClientChannels.add(toRegisterName);
|
||||
Log.debug(String.format("Server registered plugin channel \"%s\"", toRegisterName));
|
||||
return;
|
||||
}
|
||||
if (name.equals("UNREGISTER")) {
|
||||
// register this channel
|
||||
String toUnregisterName = new String(data);
|
||||
registeredClientChannels.remove(toUnregisterName);
|
||||
Log.debug(String.format("Server unregistered plugin channel \"%s\"", toUnregisterName));
|
||||
return;
|
||||
}
|
||||
// check if channel was registered or if it is a default channel
|
||||
if (!registeredClientChannels.contains(name) && DefaultPluginChannels.byName(name) == null) {
|
||||
Log.debug(String.format("Server tried to send data into unregistered plugin channel (name=\"%s\", messageLength=%d)", name, data.length));
|
||||
return;
|
||||
}
|
||||
if (channels.get(name) == null) {
|
||||
Log.debug(String.format("Can not handle plugin message in channel \"%s\" (messageLength=%d)", name, data.length));
|
||||
return;
|
||||
}
|
||||
|
||||
for (ChannelHandler handler : channels.get(name)) {
|
||||
handler.handle(this, new InByteBuffer(data));
|
||||
}
|
||||
}
|
||||
|
||||
public void sendRawData(String channel, byte[] data) {
|
||||
connection.sendPacket(new PacketPluginMessageSending(channel, data));
|
||||
}
|
||||
|
||||
public void registerServerChannel(String name) {
|
||||
if (DefaultPluginChannels.byName(name) != null) {
|
||||
// channel is a default channel, can not register
|
||||
throw new IllegalArgumentException(String.format("Can not register default Minecraft plugin channel (name=%s)", name));
|
||||
}
|
||||
sendRawData("REGISTER", name.getBytes());
|
||||
registeredServerChannels.add(name);
|
||||
}
|
||||
|
||||
public void unregisterServerChannel(String name) {
|
||||
if (DefaultPluginChannels.byName(name) != null) {
|
||||
// channel is a default channel, can not unregister
|
||||
throw new IllegalArgumentException(String.format("Can not unregister default Minecraft plugin channel (name=%s)", name));
|
||||
}
|
||||
sendRawData("UNREGISTER", name.getBytes());
|
||||
registeredServerChannels.remove(name);
|
||||
}
|
||||
|
||||
}
|
@ -13,8 +13,12 @@
|
||||
|
||||
package de.bixilon.minosoft.protocol.network;
|
||||
|
||||
import de.bixilon.minosoft.Minosoft;
|
||||
import de.bixilon.minosoft.config.GameConfiguration;
|
||||
import de.bixilon.minosoft.game.datatypes.Player;
|
||||
import de.bixilon.minosoft.logging.Log;
|
||||
import de.bixilon.minosoft.protocol.modding.channels.DefaultPluginChannels;
|
||||
import de.bixilon.minosoft.protocol.modding.channels.PluginChannelHandler;
|
||||
import de.bixilon.minosoft.protocol.packets.ClientboundPacket;
|
||||
import de.bixilon.minosoft.protocol.packets.ServerboundPacket;
|
||||
import de.bixilon.minosoft.protocol.packets.serverbound.handshaking.PacketHandshake;
|
||||
@ -33,11 +37,11 @@ public class Connection {
|
||||
private final int port;
|
||||
private final Network network;
|
||||
private final PacketHandler handler;
|
||||
private final PluginChannelHandler pluginChannelHandler;
|
||||
private final ArrayList<ClientboundPacket> handlingQueue;
|
||||
Thread handleThread;
|
||||
private Player player;
|
||||
private ConnectionState state = ConnectionState.DISCONNECTED;
|
||||
Thread handleThread;
|
||||
|
||||
private boolean onlyPing;
|
||||
|
||||
public Connection(String host, int port) {
|
||||
@ -46,6 +50,8 @@ public class Connection {
|
||||
network = new Network(this);
|
||||
handlingQueue = new ArrayList<>();
|
||||
handler = new PacketHandler(this);
|
||||
pluginChannelHandler = new PluginChannelHandler(this);
|
||||
registerDefaultChannels();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -130,6 +136,10 @@ public class Connection {
|
||||
return player;
|
||||
}
|
||||
|
||||
public void setPlayer(Player player) {
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
public void sendPacket(ServerboundPacket p) {
|
||||
network.sendPacket(p);
|
||||
}
|
||||
@ -157,11 +167,20 @@ public class Connection {
|
||||
handleThread.start();
|
||||
}
|
||||
|
||||
public void setPlayer(Player player) {
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
public void sendChatMessage(String message) {
|
||||
sendPacket(new PacketChatMessage(message));
|
||||
}
|
||||
|
||||
public PluginChannelHandler getPluginChannelHandler() {
|
||||
return pluginChannelHandler;
|
||||
}
|
||||
|
||||
public void registerDefaultChannels() {
|
||||
// MC|Brand
|
||||
getPluginChannelHandler().registerClientHandler(DefaultPluginChannels.MC_BRAND.getName(), (handler, buffer) -> {
|
||||
Log.info(String.format("Server is running %s on version %s", new String(buffer.readBytes(buffer.getBytesLeft())), getVersion().getName()));
|
||||
|
||||
getPluginChannelHandler().sendRawData(DefaultPluginChannels.MC_BRAND.getName(), (Minosoft.getConfig().getBoolean(GameConfiguration.NETWORK_FAKE_CLIENT_BRAND) ? "vanilla" : "Minosoft").getBytes());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -13,8 +13,6 @@
|
||||
|
||||
package de.bixilon.minosoft.protocol.protocol;
|
||||
|
||||
import de.bixilon.minosoft.Minosoft;
|
||||
import de.bixilon.minosoft.config.GameConfiguration;
|
||||
import de.bixilon.minosoft.game.datatypes.GameMode;
|
||||
import de.bixilon.minosoft.game.datatypes.blocks.Blocks;
|
||||
import de.bixilon.minosoft.game.datatypes.entities.meta.HumanMetaData;
|
||||
@ -30,7 +28,6 @@ import de.bixilon.minosoft.protocol.packets.clientbound.status.PacketStatusRespo
|
||||
import de.bixilon.minosoft.protocol.packets.serverbound.login.PacketEncryptionResponse;
|
||||
import de.bixilon.minosoft.protocol.packets.serverbound.play.PacketKeepAliveResponse;
|
||||
import de.bixilon.minosoft.protocol.packets.serverbound.play.PacketPlayerPositionAndRotationSending;
|
||||
import de.bixilon.minosoft.protocol.packets.serverbound.play.PacketPluginMessageSending;
|
||||
|
||||
import javax.crypto.SecretKey;
|
||||
import java.math.BigInteger;
|
||||
@ -103,13 +100,7 @@ public class PacketHandler {
|
||||
}
|
||||
|
||||
public void handle(PacketPluginMessageReceiving pkg) {
|
||||
if (pkg.getChannel().equals("MC|Brand")) {
|
||||
// server brand received
|
||||
Log.info(String.format("Server is running %s on version %s", new String(pkg.getData()), connection.getVersion().getName()));
|
||||
|
||||
// send back own brand
|
||||
connection.sendPacket(new PacketPluginMessageSending("MC|Brand", (Minosoft.getConfig().getBoolean(GameConfiguration.NETWORK_FAKE_CLIENT_BRAND) ? "vanilla" : "Minosoft")));
|
||||
}
|
||||
connection.getPluginChannelHandler().handle(pkg.getChannel(), pkg.getData());
|
||||
}
|
||||
|
||||
public void handle(PacketSpawnLocation pkg) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user