166 Zeilen
6.9 KiB
Java
166 Zeilen
6.9 KiB
Java
/*
|
|
* This file is a part of the SteamWar software.
|
|
*
|
|
* Copyright (C) 2021 SteamWar.de-Serverteam
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Affero General Public License
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
package de.steamwar.listener;
|
|
|
|
import de.steamwar.ConfigSystem;
|
|
import de.steamwar.utils.BungeeTabListPlusFixer;
|
|
import io.netty.buffer.ByteBuf;
|
|
import net.md_5.bungee.BungeeCord;
|
|
import net.md_5.bungee.api.chat.TextComponent;
|
|
import net.md_5.bungee.api.event.PostLoginEvent;
|
|
import net.md_5.bungee.api.event.PreLoginEvent;
|
|
import net.md_5.bungee.api.plugin.Listener;
|
|
import net.md_5.bungee.connection.InitialHandler;
|
|
import net.md_5.bungee.connection.LoginResult;
|
|
import net.md_5.bungee.event.EventHandler;
|
|
import net.md_5.bungee.netty.ChannelWrapper;
|
|
import net.md_5.bungee.protocol.Protocol;
|
|
import net.md_5.bungee.protocol.ProtocolConstants;
|
|
import net.md_5.bungee.protocol.packet.Handshake;
|
|
|
|
import java.lang.reflect.Array;
|
|
import java.lang.reflect.Field;
|
|
import java.lang.reflect.Method;
|
|
import java.net.InetSocketAddress;
|
|
import java.util.Arrays;
|
|
import java.util.Set;
|
|
import java.util.UUID;
|
|
import java.util.function.Supplier;
|
|
|
|
public class SteamwarConnectionListener implements Listener {
|
|
|
|
private Field chField;
|
|
|
|
private Field loginProfile;
|
|
|
|
private static class SteamwarHandshake extends Handshake {
|
|
public void read(ByteBuf buf) {
|
|
setProtocolVersion(readVarInt(buf));
|
|
setHost(readString(buf));
|
|
setPort(buf.readUnsignedShort());
|
|
setRequestedProtocol(readVarInt(buf));
|
|
}
|
|
}
|
|
|
|
{
|
|
try {
|
|
Method mapMethod = Protocol.class.getDeclaredMethod("map", int.class, int.class);
|
|
mapMethod.setAccessible(true);
|
|
Object protocolMapping = mapMethod.invoke(null, ProtocolConstants.MINECRAFT_1_8, 0x00);
|
|
Class<?> directionDataClazz = Class.forName("net.md_5.bungee.protocol.Protocol$DirectionData");
|
|
Class<?> protocolMappingClazz = Class.forName("net.md_5.bungee.protocol.Protocol$ProtocolMapping");
|
|
Field field = Protocol.class.getDeclaredField("TO_SERVER");
|
|
field.setAccessible(true);
|
|
Object o = field.get(Protocol.HANDSHAKE);
|
|
Method method = Arrays.stream(directionDataClazz.getDeclaredMethods())
|
|
.filter(m -> m.getName().equals("registerPacket"))
|
|
.filter(m -> m.getParameterCount() == 3)
|
|
.filter(m -> m.getParameterTypes()[0] == Class.class)
|
|
.filter(m -> m.getParameterTypes()[1] == Supplier.class)
|
|
.filter(m -> m.getParameterTypes()[2].isArray())
|
|
.findFirst()
|
|
.orElseThrow(() -> new RuntimeException("Could not find registerPacket method"));
|
|
method.setAccessible(true);
|
|
Object protocolMappingArray = Array.newInstance(protocolMappingClazz, 1);
|
|
Array.set(protocolMappingArray, 0, protocolMapping);
|
|
method.invoke(o, Handshake.class, new Supplier<Handshake>() {
|
|
@Override
|
|
public Handshake get() {
|
|
return new SteamwarHandshake();
|
|
}
|
|
}, protocolMappingArray);
|
|
|
|
chField = InitialHandler.class.getDeclaredField("ch");
|
|
chField.setAccessible(true);
|
|
|
|
loginProfile = InitialHandler.class.getDeclaredField("loginProfile");
|
|
loginProfile.setAccessible(true);
|
|
} catch (Exception e) {
|
|
e.printStackTrace();
|
|
}
|
|
}
|
|
|
|
@EventHandler
|
|
public void preLoginEvent(PreLoginEvent preLoginEvent) {
|
|
if (!ConfigSystem.isEnabled()) return;
|
|
|
|
String address = preLoginEvent.getConnection().getSocketAddress().toString();
|
|
if (address.startsWith("/78.31.71.136:")) {
|
|
InitialHandler initialHandler = (InitialHandler) preLoginEvent.getConnection();
|
|
String extraData = initialHandler.getExtraDataInHandshake();
|
|
String[] split = extraData.split("\0");
|
|
|
|
StringBuilder uuidStringBuilder = new StringBuilder(split[2]);
|
|
uuidStringBuilder.insert(8, '-');
|
|
uuidStringBuilder.insert(13, '-');
|
|
uuidStringBuilder.insert(18, '-');
|
|
uuidStringBuilder.insert(23, '-');
|
|
|
|
if (ConfigSystem.isWhitelistEnabled()) {
|
|
Set<String> whitelist = ConfigSystem.getWhitelist();
|
|
if (!whitelist.contains(uuidStringBuilder.toString()) && !whitelist.contains(preLoginEvent.getConnection().getName())) {
|
|
preLoginEvent.setCancelled(true);
|
|
preLoginEvent.setCancelReason(new TextComponent());
|
|
return;
|
|
}
|
|
}
|
|
|
|
try {
|
|
ChannelWrapper channelWrapper = ((ChannelWrapper) chField.get(initialHandler));
|
|
channelWrapper.setRemoteAddress(new InetSocketAddress(split[1], ((InetSocketAddress) channelWrapper.getRemoteAddress()).getPort()));
|
|
} catch (IllegalAccessException e) {
|
|
e.printStackTrace();
|
|
return;
|
|
}
|
|
|
|
// 0: host, 1: address, 2: uuid, (3): mojangProfile (properties, so skin data)
|
|
preLoginEvent.getConnection().setOnlineMode(false);
|
|
|
|
initialHandler.setUniqueId(UUID.fromString(uuidStringBuilder.toString()));
|
|
|
|
if (split.length > 3) {
|
|
LoginResult loginResult = BungeeCord.getInstance().gson.fromJson("{\"properties\":" + split[3] + ", \"id\":\"\", \"name\":\"\"}", LoginResult.class);
|
|
try {
|
|
loginProfile.set(initialHandler, loginResult);
|
|
} catch (IllegalArgumentException | IllegalAccessException e) {
|
|
// Ignore
|
|
}
|
|
}
|
|
} else if (ConfigSystem.isOnlySteamWarJoin()) {
|
|
preLoginEvent.setCancelled(true);
|
|
preLoginEvent.setCancelReason(ConfigSystem.getNotFromSteamWarMessage());
|
|
}
|
|
}
|
|
|
|
@EventHandler
|
|
public void postLoginEvent(PostLoginEvent postLoginEvent) {
|
|
if (!ConfigSystem.isEnabled()) return;
|
|
|
|
String address = postLoginEvent.getPlayer().getPendingConnection().getSocketAddress().toString();
|
|
if (!address.startsWith("/127.127.127.127:")) {
|
|
return;
|
|
}
|
|
|
|
if (BungeeCord.getInstance().getPluginManager().getPlugin("BungeeTabListPlus") != null) {
|
|
BungeeTabListPlusFixer.remove(postLoginEvent.getPlayer());
|
|
}
|
|
}
|
|
}
|