forked from BLOCKFANTASY/LOOHP-Limbo
format ClientConnection.java
This commit is contained in:
parent
4353859951
commit
ea7d33a0e3
|
|
@ -1,29 +1,5 @@
|
||||||
package com.loohp.limbo.network;
|
package com.loohp.limbo.network;
|
||||||
|
|
||||||
import java.io.DataInputStream;
|
|
||||||
import java.io.DataOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.InetAddress;
|
|
||||||
import java.net.Socket;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.Random;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.Timer;
|
|
||||||
import java.util.TimerTask;
|
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import com.loohp.limbo.network.protocol.packets.PacketIn;
|
|
||||||
import org.json.simple.JSONArray;
|
|
||||||
import org.json.simple.JSONObject;
|
|
||||||
import org.json.simple.parser.JSONParser;
|
|
||||||
|
|
||||||
import com.loohp.limbo.Limbo;
|
import com.loohp.limbo.Limbo;
|
||||||
import com.loohp.limbo.events.player.PlayerJoinEvent;
|
import com.loohp.limbo.events.player.PlayerJoinEvent;
|
||||||
import com.loohp.limbo.events.player.PlayerLoginEvent;
|
import com.loohp.limbo.events.player.PlayerLoginEvent;
|
||||||
|
|
@ -34,8 +10,8 @@ import com.loohp.limbo.events.player.PlayerSelectedSlotChangeEvent;
|
||||||
import com.loohp.limbo.events.status.StatusPingEvent;
|
import com.loohp.limbo.events.status.StatusPingEvent;
|
||||||
import com.loohp.limbo.file.ServerProperties;
|
import com.loohp.limbo.file.ServerProperties;
|
||||||
import com.loohp.limbo.location.Location;
|
import com.loohp.limbo.location.Location;
|
||||||
import com.loohp.limbo.network.protocol.packets.Packet;
|
|
||||||
import com.loohp.limbo.network.protocol.packets.PacketHandshakingIn;
|
import com.loohp.limbo.network.protocol.packets.PacketHandshakingIn;
|
||||||
|
import com.loohp.limbo.network.protocol.packets.PacketIn;
|
||||||
import com.loohp.limbo.network.protocol.packets.PacketLoginInLoginStart;
|
import com.loohp.limbo.network.protocol.packets.PacketLoginInLoginStart;
|
||||||
import com.loohp.limbo.network.protocol.packets.PacketLoginInPluginMessaging;
|
import com.loohp.limbo.network.protocol.packets.PacketLoginInPluginMessaging;
|
||||||
import com.loohp.limbo.network.protocol.packets.PacketLoginOutDisconnect;
|
import com.loohp.limbo.network.protocol.packets.PacketLoginOutDisconnect;
|
||||||
|
|
@ -86,514 +62,538 @@ import com.loohp.limbo.utils.MojangAPIUtils;
|
||||||
import com.loohp.limbo.utils.MojangAPIUtils.SkinResponse;
|
import com.loohp.limbo.utils.MojangAPIUtils.SkinResponse;
|
||||||
import com.loohp.limbo.world.BlockPosition;
|
import com.loohp.limbo.world.BlockPosition;
|
||||||
import com.loohp.limbo.world.World;
|
import com.loohp.limbo.world.World;
|
||||||
|
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.md_5.bungee.api.ChatColor;
|
import net.md_5.bungee.api.ChatColor;
|
||||||
import net.md_5.bungee.api.chat.BaseComponent;
|
import net.md_5.bungee.api.chat.BaseComponent;
|
||||||
import net.md_5.bungee.api.chat.TextComponent;
|
import net.md_5.bungee.api.chat.TextComponent;
|
||||||
import net.md_5.bungee.api.chat.TranslatableComponent;
|
import net.md_5.bungee.api.chat.TranslatableComponent;
|
||||||
|
import org.json.simple.JSONArray;
|
||||||
|
import org.json.simple.JSONObject;
|
||||||
|
import org.json.simple.parser.JSONParser;
|
||||||
|
|
||||||
|
import java.io.DataInputStream;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.net.Socket;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.Random;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.Timer;
|
||||||
|
import java.util.TimerTask;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class ClientConnection extends Thread {
|
public class ClientConnection extends Thread {
|
||||||
|
|
||||||
public static enum ClientState {
|
private final Random random = new Random();
|
||||||
LEGACY,
|
|
||||||
HANDSHAKE,
|
|
||||||
STATUS,
|
|
||||||
LOGIN,
|
|
||||||
PLAY,
|
|
||||||
DISCONNECTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
private final Random random = new Random();
|
|
||||||
|
|
||||||
private final Socket client_socket;
|
private final Socket client_socket;
|
||||||
|
protected Channel channel;
|
||||||
private boolean running;
|
private boolean running;
|
||||||
private ClientState state;
|
private ClientState state;
|
||||||
|
|
||||||
private Player player;
|
private Player player;
|
||||||
private TimerTask keepAliveTask;
|
private TimerTask keepAliveTask;
|
||||||
private AtomicLong lastPacketTimestamp;
|
private AtomicLong lastPacketTimestamp;
|
||||||
private AtomicLong lastKeepAlivePayLoad;
|
private AtomicLong lastKeepAlivePayLoad;
|
||||||
|
private InetAddress inetAddress;
|
||||||
protected Channel channel;
|
private boolean ready;
|
||||||
|
|
||||||
private InetAddress inetAddress;
|
|
||||||
|
|
||||||
private boolean ready;
|
|
||||||
|
|
||||||
public ClientConnection(Socket client_socket) {
|
public ClientConnection(Socket client_socket) {
|
||||||
this.client_socket = client_socket;
|
this.client_socket = client_socket;
|
||||||
this.inetAddress = client_socket.getInetAddress();
|
this.inetAddress = client_socket.getInetAddress();
|
||||||
this.lastPacketTimestamp = new AtomicLong(-1);
|
this.lastPacketTimestamp = new AtomicLong(-1);
|
||||||
this.lastKeepAlivePayLoad = new AtomicLong(-1);
|
this.lastKeepAlivePayLoad = new AtomicLong(-1);
|
||||||
this.channel = new Channel(this, null, null);
|
this.channel = new Channel(this, null, null);
|
||||||
this.running = false;
|
this.running = false;
|
||||||
this.ready = false;
|
this.ready = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public InetAddress getInetAddress() {
|
public InetAddress getInetAddress() {
|
||||||
return inetAddress;
|
return inetAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getLastKeepAlivePayLoad() {
|
public long getLastKeepAlivePayLoad() {
|
||||||
return lastKeepAlivePayLoad.get();
|
return lastKeepAlivePayLoad.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setLastKeepAlivePayLoad(long payLoad) {
|
public void setLastKeepAlivePayLoad(long payLoad) {
|
||||||
this.lastKeepAlivePayLoad.set(payLoad);
|
this.lastKeepAlivePayLoad.set(payLoad);
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getLastPacketTimestamp() {
|
public long getLastPacketTimestamp() {
|
||||||
return lastPacketTimestamp.get();
|
return lastPacketTimestamp.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setLastPacketTimestamp(long payLoad) {
|
public void setLastPacketTimestamp(long payLoad) {
|
||||||
this.lastPacketTimestamp.set(payLoad);
|
this.lastPacketTimestamp.set(payLoad);
|
||||||
}
|
}
|
||||||
|
|
||||||
public TimerTask getKeepAliveTask() {
|
public TimerTask getKeepAliveTask() {
|
||||||
return this.keepAliveTask;
|
return this.keepAliveTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Player getPlayer() {
|
public Player getPlayer() {
|
||||||
return player;
|
return player;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ClientState getClientState() {
|
public ClientState getClientState() {
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Socket getSocket() {
|
public Socket getSocket() {
|
||||||
return client_socket;
|
return client_socket;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Channel getChannel() {
|
public Channel getChannel() {
|
||||||
return channel;
|
return channel;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isRunning() {
|
public boolean isRunning() {
|
||||||
return running;
|
return running;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isReady() {
|
public boolean isReady() {
|
||||||
return ready;
|
return ready;
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void sendPacket(PacketOut packet) throws IOException {
|
public synchronized void sendPacket(PacketOut packet) throws IOException {
|
||||||
if (channel.writePacket(packet)) {
|
if (channel.writePacket(packet)) {
|
||||||
setLastPacketTimestamp(System.currentTimeMillis());
|
setLastPacketTimestamp(System.currentTimeMillis());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void disconnect(BaseComponent[] reason) {
|
public void disconnect(BaseComponent[] reason) {
|
||||||
disconnect(BungeecordAdventureConversionUtils.toComponent(reason));
|
disconnect(BungeecordAdventureConversionUtils.toComponent(reason));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void disconnect(Component reason) {
|
public void disconnect(Component reason) {
|
||||||
try {
|
try {
|
||||||
PacketPlayOutDisconnect packet = new PacketPlayOutDisconnect(reason);
|
PacketPlayOutDisconnect packet = new PacketPlayOutDisconnect(reason);
|
||||||
sendPacket(packet);
|
sendPacket(packet);
|
||||||
} catch (IOException ignored) {}
|
} catch (IOException ignored) {
|
||||||
try {
|
}
|
||||||
client_socket.close();
|
try {
|
||||||
} catch (IOException ignored) {}
|
client_socket.close();
|
||||||
}
|
} catch (IOException ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void disconnectDuringLogin(BaseComponent[] reason) {
|
private void disconnectDuringLogin(BaseComponent[] reason) {
|
||||||
disconnectDuringLogin(BungeecordAdventureConversionUtils.toComponent(reason));
|
disconnectDuringLogin(BungeecordAdventureConversionUtils.toComponent(reason));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void disconnectDuringLogin(Component reason) {
|
private void disconnectDuringLogin(Component reason) {
|
||||||
try {
|
try {
|
||||||
PacketLoginOutDisconnect packet = new PacketLoginOutDisconnect(reason);
|
PacketLoginOutDisconnect packet = new PacketLoginOutDisconnect(reason);
|
||||||
sendPacket(packet);
|
sendPacket(packet);
|
||||||
} catch (IOException ignored) {}
|
} catch (IOException ignored) {
|
||||||
try {
|
}
|
||||||
client_socket.close();
|
try {
|
||||||
} catch (IOException ignored) {}
|
client_socket.close();
|
||||||
}
|
} catch (IOException ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
running = true;
|
running = true;
|
||||||
state = ClientState.HANDSHAKE;
|
state = ClientState.HANDSHAKE;
|
||||||
try {
|
try {
|
||||||
client_socket.setKeepAlive(true);
|
client_socket.setKeepAlive(true);
|
||||||
channel.input = new DataInputStream(client_socket.getInputStream());
|
channel.input = new DataInputStream(client_socket.getInputStream());
|
||||||
channel.output = new DataOutputStream(client_socket.getOutputStream());
|
channel.output = new DataOutputStream(client_socket.getOutputStream());
|
||||||
int handShakeSize = DataTypeIO.readVarInt(channel.input);
|
int handShakeSize = DataTypeIO.readVarInt(channel.input);
|
||||||
|
|
||||||
//legacy ping
|
//legacy ping
|
||||||
if (handShakeSize == 0xFE) {
|
if (handShakeSize == 0xFE) {
|
||||||
state = ClientState.LEGACY;
|
state = ClientState.LEGACY;
|
||||||
channel.output.writeByte(255);
|
channel.output.writeByte(255);
|
||||||
String str = inetAddress.getHostName() + ":" + client_socket.getPort();
|
String str = inetAddress.getHostName() + ":" + client_socket.getPort();
|
||||||
Limbo.getInstance().getConsole().sendMessage("[/" + str + "] <-> Legacy Status has pinged");
|
Limbo.getInstance().getConsole().sendMessage("[/" + str + "] <-> Legacy Status has pinged");
|
||||||
ServerProperties p = Limbo.getInstance().getServerProperties();
|
ServerProperties p = Limbo.getInstance().getServerProperties();
|
||||||
StatusPingEvent event = Limbo.getInstance().getEventsManager().callEvent(new StatusPingEvent(this, p.getVersionString(), p.getProtocol(), p.getMotd(), p.getMaxPlayers(), Limbo.getInstance().getPlayers().size(), p.getFavicon().orElse(null)));
|
StatusPingEvent event = Limbo.getInstance().getEventsManager().callEvent(new StatusPingEvent(this, p.getVersionString(), p.getProtocol(), p.getMotd(), p.getMaxPlayers(), Limbo.getInstance().getPlayers().size(), p.getFavicon().orElse(null)));
|
||||||
String response = Limbo.getInstance().buildLegacyPingResponse(event.getVersion(), event.getMotd(), event.getMaxPlayers(), event.getPlayersOnline());
|
String response = Limbo.getInstance().buildLegacyPingResponse(event.getVersion(), event.getMotd(), event.getMaxPlayers(), event.getPlayersOnline());
|
||||||
byte[] bytes = response.getBytes(StandardCharsets.UTF_16BE);
|
byte[] bytes = response.getBytes(StandardCharsets.UTF_16BE);
|
||||||
channel.output.writeShort(response.length());
|
channel.output.writeShort(response.length());
|
||||||
channel.output.write(bytes);
|
channel.output.write(bytes);
|
||||||
|
|
||||||
channel.close();
|
channel.close();
|
||||||
client_socket.close();
|
client_socket.close();
|
||||||
state = ClientState.DISCONNECTED;
|
state = ClientState.DISCONNECTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
PacketHandshakingIn handshake = (PacketHandshakingIn) channel.readPacket(handShakeSize);
|
PacketHandshakingIn handshake = (PacketHandshakingIn) channel.readPacket(handShakeSize);
|
||||||
|
|
||||||
boolean isBungeecord = Limbo.getInstance().getServerProperties().isBungeecord();
|
boolean isBungeecord = Limbo.getInstance().getServerProperties().isBungeecord();
|
||||||
boolean isBungeeGuard = Limbo.getInstance().getServerProperties().isBungeeGuard();
|
boolean isBungeeGuard = Limbo.getInstance().getServerProperties().isBungeeGuard();
|
||||||
boolean isVelocityModern = Limbo.getInstance().getServerProperties().isVelocityModern();
|
boolean isVelocityModern = Limbo.getInstance().getServerProperties().isVelocityModern();
|
||||||
String bungeeForwarding = handshake.getServerAddress();
|
String bungeeForwarding = handshake.getServerAddress();
|
||||||
UUID bungeeUUID = null;
|
UUID bungeeUUID = null;
|
||||||
SkinResponse forwardedSkin = null;
|
SkinResponse forwardedSkin = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
switch (handshake.getHandshakeType()) {
|
switch (handshake.getHandshakeType()) {
|
||||||
case STATUS:
|
case STATUS:
|
||||||
state = ClientState.STATUS;
|
state = ClientState.STATUS;
|
||||||
while (client_socket.isConnected()) {
|
while (client_socket.isConnected()) {
|
||||||
PacketIn packetIn = channel.readPacket();
|
PacketIn packetIn = channel.readPacket();
|
||||||
if (packetIn instanceof PacketStatusInRequest) {
|
if (packetIn instanceof PacketStatusInRequest) {
|
||||||
String str = inetAddress.getHostName() + ":" + client_socket.getPort();
|
String str = inetAddress.getHostName() + ":" + client_socket.getPort();
|
||||||
if (Limbo.getInstance().getServerProperties().handshakeVerboseEnabled()) {
|
if (Limbo.getInstance().getServerProperties().handshakeVerboseEnabled()) {
|
||||||
Limbo.getInstance().getConsole().sendMessage("[/" + str + "] <-> Handshake Status has pinged");
|
Limbo.getInstance().getConsole().sendMessage("[/" + str + "] <-> Handshake Status has pinged");
|
||||||
}
|
}
|
||||||
ServerProperties p = Limbo.getInstance().getServerProperties();
|
ServerProperties p = Limbo.getInstance().getServerProperties();
|
||||||
StatusPingEvent event = Limbo.getInstance().getEventsManager().callEvent(new StatusPingEvent(this, p.getVersionString(), p.getProtocol(), p.getMotd(), p.getMaxPlayers(), Limbo.getInstance().getPlayers().size(), p.getFavicon().orElse(null)));
|
StatusPingEvent event = Limbo.getInstance().getEventsManager().callEvent(new StatusPingEvent(this, p.getVersionString(), p.getProtocol(), p.getMotd(), p.getMaxPlayers(), Limbo.getInstance().getPlayers().size(), p.getFavicon().orElse(null)));
|
||||||
PacketStatusOutResponse response = new PacketStatusOutResponse(Limbo.getInstance().buildServerListResponseJson(event.getVersion(), event.getProtocol(), event.getMotd(), event.getMaxPlayers(), event.getPlayersOnline(), event.getFavicon()));
|
PacketStatusOutResponse response = new PacketStatusOutResponse(Limbo.getInstance().buildServerListResponseJson(event.getVersion(), event.getProtocol(), event.getMotd(), event.getMaxPlayers(), event.getPlayersOnline(), event.getFavicon()));
|
||||||
sendPacket(response);
|
sendPacket(response);
|
||||||
} else if (packetIn instanceof PacketStatusInPing) {
|
} else if (packetIn instanceof PacketStatusInPing) {
|
||||||
PacketStatusInPing ping = (PacketStatusInPing) packetIn;
|
PacketStatusInPing ping = (PacketStatusInPing) packetIn;
|
||||||
PacketStatusOutPong pong = new PacketStatusOutPong(ping.getPayload());
|
PacketStatusOutPong pong = new PacketStatusOutPong(ping.getPayload());
|
||||||
sendPacket(pong);
|
sendPacket(pong);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case LOGIN:
|
case LOGIN:
|
||||||
state = ClientState.LOGIN;
|
state = ClientState.LOGIN;
|
||||||
|
|
||||||
if (isBungeecord || isBungeeGuard) {
|
if (isBungeecord || isBungeeGuard) {
|
||||||
try {
|
try {
|
||||||
String[] data = bungeeForwarding.split("\\x00");
|
String[] data = bungeeForwarding.split("\\x00");
|
||||||
//String host = data[0];
|
//String host = data[0];
|
||||||
String ip = data[1];
|
String ip = data[1];
|
||||||
|
|
||||||
bungeeUUID = UUID.fromString(data[2].replaceFirst("([0-9a-fA-F]{8})([0-9a-fA-F]{4})([0-9a-fA-F]{4})([0-9a-fA-F]{4})([0-9a-fA-F]+)", "$1-$2-$3-$4-$5"));
|
bungeeUUID = UUID.fromString(data[2].replaceFirst("([0-9a-fA-F]{8})([0-9a-fA-F]{4})([0-9a-fA-F]{4})([0-9a-fA-F]{4})([0-9a-fA-F]+)", "$1-$2-$3-$4-$5"));
|
||||||
inetAddress = InetAddress.getByName(ip);
|
inetAddress = InetAddress.getByName(ip);
|
||||||
|
|
||||||
boolean bungeeGuardFound = false;
|
boolean bungeeGuardFound = false;
|
||||||
if (data.length > 3) {
|
if (data.length > 3) {
|
||||||
JSONArray skinJson = (JSONArray) new JSONParser().parse(data[3]);
|
JSONArray skinJson = (JSONArray) new JSONParser().parse(data[3]);
|
||||||
|
|
||||||
for (Object obj : skinJson) {
|
for (Object obj : skinJson) {
|
||||||
JSONObject property = (JSONObject) obj;
|
JSONObject property = (JSONObject) obj;
|
||||||
if (property.get("name").toString().equals("textures")) {
|
if (property.get("name").toString().equals("textures")) {
|
||||||
String skin = property.get("value").toString();
|
String skin = property.get("value").toString();
|
||||||
String signature = property.get("signature").toString();
|
String signature = property.get("signature").toString();
|
||||||
forwardedSkin = new SkinResponse(skin, signature);
|
forwardedSkin = new SkinResponse(skin, signature);
|
||||||
} else if (isBungeeGuard && property.get("name").toString().equals("bungeeguard-token")) {
|
} else if (isBungeeGuard && property.get("name").toString().equals("bungeeguard-token")) {
|
||||||
String token = property.get("value").toString();
|
String token = property.get("value").toString();
|
||||||
bungeeGuardFound = Limbo.getInstance().getServerProperties().getForwardingSecrets().contains(token);
|
bungeeGuardFound = Limbo.getInstance().getServerProperties().getForwardingSecrets().contains(token);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isBungeeGuard && !bungeeGuardFound) {
|
if (isBungeeGuard && !bungeeGuardFound) {
|
||||||
disconnectDuringLogin(TextComponent.fromLegacyText("Invalid information forwarding"));
|
disconnectDuringLogin(TextComponent.fromLegacyText("Invalid information forwarding"));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Limbo.getInstance().getConsole().sendMessage("If you wish to use bungeecord's IP forwarding, please enable that in your bungeecord config.yml as well!");
|
Limbo.getInstance().getConsole().sendMessage("If you wish to use bungeecord's IP forwarding, please enable that in your bungeecord config.yml as well!");
|
||||||
disconnectDuringLogin(new BaseComponent[] {new TextComponent(ChatColor.RED + "Please connect from the proxy!")});
|
disconnectDuringLogin(new BaseComponent[] {new TextComponent(ChatColor.RED + "Please connect from the proxy!")});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int messageId = this.random.nextInt();
|
int messageId = this.random.nextInt();
|
||||||
while (client_socket.isConnected()) {
|
while (client_socket.isConnected()) {
|
||||||
PacketIn packetIn = channel.readPacket();
|
PacketIn packetIn = channel.readPacket();
|
||||||
if (packetIn instanceof PacketLoginInLoginStart) {
|
if (packetIn instanceof PacketLoginInLoginStart) {
|
||||||
PacketLoginInLoginStart start = (PacketLoginInLoginStart) packetIn;
|
PacketLoginInLoginStart start = (PacketLoginInLoginStart) packetIn;
|
||||||
String username = start.getUsername();
|
String username = start.getUsername();
|
||||||
|
|
||||||
if (Limbo.getInstance().getServerProperties().isVelocityModern()) {
|
if (Limbo.getInstance().getServerProperties().isVelocityModern()) {
|
||||||
PacketLoginOutPluginMessaging loginPluginRequest = new PacketLoginOutPluginMessaging(messageId, ForwardingUtils.VELOCITY_FORWARDING_CHANNEL);
|
PacketLoginOutPluginMessaging loginPluginRequest = new PacketLoginOutPluginMessaging(messageId, ForwardingUtils.VELOCITY_FORWARDING_CHANNEL);
|
||||||
sendPacket(loginPluginRequest);
|
sendPacket(loginPluginRequest);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
UUID uuid = isBungeecord || isBungeeGuard ? bungeeUUID : UUID.nameUUIDFromBytes(("OfflinePlayer:" + username).getBytes(StandardCharsets.UTF_8));
|
UUID uuid = isBungeecord || isBungeeGuard ? bungeeUUID : UUID.nameUUIDFromBytes(("OfflinePlayer:" + username).getBytes(StandardCharsets.UTF_8));
|
||||||
|
|
||||||
PacketLoginOutLoginSuccess success = new PacketLoginOutLoginSuccess(uuid, username);
|
PacketLoginOutLoginSuccess success = new PacketLoginOutLoginSuccess(uuid, username);
|
||||||
sendPacket(success);
|
sendPacket(success);
|
||||||
|
|
||||||
state = ClientState.PLAY;
|
state = ClientState.PLAY;
|
||||||
|
|
||||||
player = new Player(this, username, uuid, Limbo.getInstance().getNextEntityId(), Limbo.getInstance().getServerProperties().getWorldSpawn(), new PlayerInteractManager());
|
player = new Player(this, username, uuid, Limbo.getInstance().getNextEntityId(), Limbo.getInstance().getServerProperties().getWorldSpawn(), new PlayerInteractManager());
|
||||||
player.setSkinLayers((byte) (0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40));
|
player.setSkinLayers((byte) (0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40));
|
||||||
Limbo.getInstance().addPlayer(player);
|
Limbo.getInstance().addPlayer(player);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
} else if (packetIn instanceof PacketLoginInPluginMessaging) {
|
} else if (packetIn instanceof PacketLoginInPluginMessaging) {
|
||||||
PacketLoginInPluginMessaging response = (PacketLoginInPluginMessaging) packetIn;
|
PacketLoginInPluginMessaging response = (PacketLoginInPluginMessaging) packetIn;
|
||||||
if (response.getMessageId() != messageId) {
|
if (response.getMessageId() != messageId) {
|
||||||
disconnectDuringLogin(TextComponent.fromLegacyText("Internal error, messageId did not match"));
|
disconnectDuringLogin(TextComponent.fromLegacyText("Internal error, messageId did not match"));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!response.getData().isPresent()) {
|
if (!response.getData().isPresent()) {
|
||||||
disconnectDuringLogin(TextComponent.fromLegacyText("Unknown login plugin response packet!"));
|
disconnectDuringLogin(TextComponent.fromLegacyText("Unknown login plugin response packet!"));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
byte[] responseData = response.getData().get();
|
byte[] responseData = response.getData().get();
|
||||||
if (!ForwardingUtils.validateVelocityModernResponse(responseData)) {
|
if (!ForwardingUtils.validateVelocityModernResponse(responseData)) {
|
||||||
disconnectDuringLogin(TextComponent.fromLegacyText("Invalid playerinfo forwarding!"));
|
disconnectDuringLogin(TextComponent.fromLegacyText("Invalid playerinfo forwarding!"));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ForwardingUtils.VelocityModernForwardingData data = ForwardingUtils.getVelocityDataFrom(responseData);
|
ForwardingUtils.VelocityModernForwardingData data = ForwardingUtils.getVelocityDataFrom(responseData);
|
||||||
inetAddress = InetAddress.getByName(data.getIpAddress());
|
inetAddress = InetAddress.getByName(data.getIpAddress());
|
||||||
forwardedSkin = data.getSkinResponse();
|
forwardedSkin = data.getSkinResponse();
|
||||||
|
|
||||||
PacketLoginOutLoginSuccess success = new PacketLoginOutLoginSuccess(data.getUuid(), data.getUsername());
|
PacketLoginOutLoginSuccess success = new PacketLoginOutLoginSuccess(data.getUuid(), data.getUsername());
|
||||||
sendPacket(success);
|
sendPacket(success);
|
||||||
|
|
||||||
state = ClientState.PLAY;
|
state = ClientState.PLAY;
|
||||||
|
|
||||||
player = new Player(this, data.getUsername(), data.getUuid(), Limbo.getInstance().getNextEntityId(), Limbo.getInstance().getServerProperties().getWorldSpawn(), new PlayerInteractManager());
|
player = new Player(this, data.getUsername(), data.getUuid(), Limbo.getInstance().getNextEntityId(), Limbo.getInstance().getServerProperties().getWorldSpawn(), new PlayerInteractManager());
|
||||||
player.setSkinLayers((byte) (0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40));
|
player.setSkinLayers((byte) (0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20 | 0x40));
|
||||||
Limbo.getInstance().addPlayer(player);
|
Limbo.getInstance().addPlayer(player);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PlayerLoginEvent event = Limbo.getInstance().getEventsManager().callEvent(new PlayerLoginEvent(this, false));
|
PlayerLoginEvent event = Limbo.getInstance().getEventsManager().callEvent(new PlayerLoginEvent(this, false));
|
||||||
if (event.isCancelled()) {
|
if (event.isCancelled()) {
|
||||||
disconnectDuringLogin(event.getCancelReason());
|
disconnectDuringLogin(event.getCancelReason());
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
channel.close();
|
channel.close();
|
||||||
client_socket.close();
|
client_socket.close();
|
||||||
state = ClientState.DISCONNECTED;
|
state = ClientState.DISCONNECTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state == ClientState.PLAY) {
|
if (state == ClientState.PLAY) {
|
||||||
|
|
||||||
TimeUnit.MILLISECONDS.sleep(500);
|
TimeUnit.MILLISECONDS.sleep(500);
|
||||||
|
|
||||||
ServerProperties properties = Limbo.getInstance().getServerProperties();
|
ServerProperties properties = Limbo.getInstance().getServerProperties();
|
||||||
Location worldSpawn = properties.getWorldSpawn();
|
Location worldSpawn = properties.getWorldSpawn();
|
||||||
|
|
||||||
PlayerJoinEvent joinEvent = Limbo.getInstance().getEventsManager().callEvent(new PlayerJoinEvent(player, worldSpawn));
|
PlayerJoinEvent joinEvent = Limbo.getInstance().getEventsManager().callEvent(new PlayerJoinEvent(player, worldSpawn));
|
||||||
worldSpawn = joinEvent.getSpawnLocation();
|
worldSpawn = joinEvent.getSpawnLocation();
|
||||||
World world = worldSpawn.getWorld();
|
World world = worldSpawn.getWorld();
|
||||||
|
|
||||||
PacketPlayOutLogin join = new PacketPlayOutLogin(player.getEntityId(), false, properties.getDefaultGamemode(), Limbo.getInstance().getWorlds(), Limbo.getInstance().getDimensionRegistry().getCodec(), world, 0, (byte) properties.getMaxPlayers(), 8, 8, properties.isReducedDebugInfo(), true, false, true);
|
PacketPlayOutLogin join = new PacketPlayOutLogin(player.getEntityId(), false, properties.getDefaultGamemode(), Limbo.getInstance().getWorlds(), Limbo.getInstance().getDimensionRegistry().getCodec(), world, 0, (byte) properties.getMaxPlayers(), 8, 8, properties.isReducedDebugInfo(), true, false, true);
|
||||||
sendPacket(join);
|
sendPacket(join);
|
||||||
Limbo.getInstance().getUnsafe().setPlayerGameModeSilently(player, properties.getDefaultGamemode());
|
Limbo.getInstance().getUnsafe().setPlayerGameModeSilently(player, properties.getDefaultGamemode());
|
||||||
|
|
||||||
SkinResponse skinresponce = (isVelocityModern || isBungeeGuard || isBungeecord) && forwardedSkin != null ? forwardedSkin : MojangAPIUtils.getSkinFromMojangServer(player.getName());
|
SkinResponse skinresponce = (isVelocityModern || isBungeeGuard || isBungeecord) && forwardedSkin != null ? forwardedSkin : MojangAPIUtils.getSkinFromMojangServer(player.getName());
|
||||||
PlayerSkinProperty skin = skinresponce != null ? new PlayerSkinProperty(skinresponce.getSkin(), skinresponce.getSignature()) : null;
|
PlayerSkinProperty skin = skinresponce != null ? new PlayerSkinProperty(skinresponce.getSkin(), skinresponce.getSignature()) : null;
|
||||||
PacketPlayOutPlayerInfo info = new PacketPlayOutPlayerInfo(PlayerInfoAction.ADD_PLAYER, player.getUniqueId(), new PlayerInfoData.PlayerInfoDataAddPlayer(player.getName(), Optional.ofNullable(skin), properties.getDefaultGamemode(), 0, false, Optional.empty()));
|
PacketPlayOutPlayerInfo info = new PacketPlayOutPlayerInfo(PlayerInfoAction.ADD_PLAYER, player.getUniqueId(), new PlayerInfoData.PlayerInfoDataAddPlayer(player.getName(), Optional.ofNullable(skin), properties.getDefaultGamemode(), 0, false, Optional.empty()));
|
||||||
sendPacket(info);
|
sendPacket(info);
|
||||||
|
|
||||||
Set<PlayerAbilityFlags> flags = new HashSet<>();
|
Set<PlayerAbilityFlags> flags = new HashSet<>();
|
||||||
if (properties.isAllowFlight()) {
|
if (properties.isAllowFlight()) {
|
||||||
flags.add(PlayerAbilityFlags.FLY);
|
flags.add(PlayerAbilityFlags.FLY);
|
||||||
}
|
}
|
||||||
if (player.getGamemode().equals(GameMode.CREATIVE)) {
|
if (player.getGamemode().equals(GameMode.CREATIVE)) {
|
||||||
flags.add(PlayerAbilityFlags.CREATIVE);
|
flags.add(PlayerAbilityFlags.CREATIVE);
|
||||||
}
|
}
|
||||||
PacketPlayOutPlayerAbilities abilities = new PacketPlayOutPlayerAbilities(0.05F, 0.1F, flags.toArray(new PlayerAbilityFlags[flags.size()]));
|
PacketPlayOutPlayerAbilities abilities = new PacketPlayOutPlayerAbilities(0.05F, 0.1F, flags.toArray(new PlayerAbilityFlags[flags.size()]));
|
||||||
sendPacket(abilities);
|
sendPacket(abilities);
|
||||||
|
|
||||||
String str = inetAddress.getHostName() + ":" + client_socket.getPort() + "|" + player.getName() + "(" + player.getUniqueId() + ")";
|
String str = inetAddress.getHostName() + ":" + client_socket.getPort() + "|" + player.getName() + "(" + player.getUniqueId() + ")";
|
||||||
Limbo.getInstance().getConsole().sendMessage("[/" + str + "] <-> Player had connected to the Limbo server!");
|
Limbo.getInstance().getConsole().sendMessage("[/" + str + "] <-> Player had connected to the Limbo server!");
|
||||||
|
|
||||||
PacketPlayOutDeclareCommands declare = DeclareCommands.getDeclareCommandsPacket(player);
|
PacketPlayOutDeclareCommands declare = DeclareCommands.getDeclareCommandsPacket(player);
|
||||||
if (declare != null) {
|
if (declare != null) {
|
||||||
sendPacket(declare);
|
sendPacket(declare);
|
||||||
}
|
}
|
||||||
|
|
||||||
player.playerInteractManager.update();
|
player.playerInteractManager.update();
|
||||||
|
|
||||||
PacketPlayOutSpawnPosition spawnPos = new PacketPlayOutSpawnPosition(BlockPosition.from(worldSpawn), worldSpawn.getPitch());
|
PacketPlayOutSpawnPosition spawnPos = new PacketPlayOutSpawnPosition(BlockPosition.from(worldSpawn), worldSpawn.getPitch());
|
||||||
sendPacket(spawnPos);
|
sendPacket(spawnPos);
|
||||||
|
|
||||||
PacketPlayOutPositionAndLook positionLook = new PacketPlayOutPositionAndLook(worldSpawn.getX(), worldSpawn.getY(), worldSpawn.getZ(), worldSpawn.getYaw(), worldSpawn.getPitch(), 1, false);
|
PacketPlayOutPositionAndLook positionLook = new PacketPlayOutPositionAndLook(worldSpawn.getX(), worldSpawn.getY(), worldSpawn.getZ(), worldSpawn.getYaw(), worldSpawn.getPitch(), 1, false);
|
||||||
Limbo.getInstance().getUnsafe().setPlayerLocationSilently(player, new Location(world, worldSpawn.getX(), worldSpawn.getY(), worldSpawn.getZ(), worldSpawn.getYaw(), worldSpawn.getPitch()));
|
Limbo.getInstance().getUnsafe().setPlayerLocationSilently(player, new Location(world, worldSpawn.getX(), worldSpawn.getY(), worldSpawn.getZ(), worldSpawn.getYaw(), worldSpawn.getPitch()));
|
||||||
sendPacket(positionLook);
|
sendPacket(positionLook);
|
||||||
|
|
||||||
player.getDataWatcher().update();
|
player.getDataWatcher().update();
|
||||||
PacketPlayOutEntityMetadata show = new PacketPlayOutEntityMetadata(player, false, Player.class.getDeclaredField("skinLayers"));
|
PacketPlayOutEntityMetadata show = new PacketPlayOutEntityMetadata(player, false, Player.class.getDeclaredField("skinLayers"));
|
||||||
sendPacket(show);
|
sendPacket(show);
|
||||||
|
|
||||||
if (properties.isAllowFlight()) {
|
if (properties.isAllowFlight()) {
|
||||||
PacketPlayOutGameState state = new PacketPlayOutGameState(3, player.getGamemode().getId());
|
PacketPlayOutGameState state = new PacketPlayOutGameState(3, player.getGamemode().getId());
|
||||||
sendPacket(state);
|
sendPacket(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
// RESOURCEPACK CODE CONRIBUTED BY GAMERDUCK123
|
// RESOURCEPACK CODE CONRIBUTED BY GAMERDUCK123
|
||||||
if (!properties.getResourcePackLink().equalsIgnoreCase("")) {
|
if (!properties.getResourcePackLink().equalsIgnoreCase("")) {
|
||||||
if (!properties.getResourcePackSHA1().equalsIgnoreCase("")) {
|
if (!properties.getResourcePackSHA1().equalsIgnoreCase("")) {
|
||||||
//SEND RESOURCEPACK
|
//SEND RESOURCEPACK
|
||||||
player.setResourcePack(properties.getResourcePackLink(), properties.getResourcePackSHA1(), properties.getResourcePackRequired(), properties.getResourcePackPrompt());
|
player.setResourcePack(properties.getResourcePackLink(), properties.getResourcePackSHA1(), properties.getResourcePackRequired(), properties.getResourcePackPrompt());
|
||||||
} else {
|
} else {
|
||||||
//NO SHA
|
//NO SHA
|
||||||
Limbo.getInstance().getConsole().sendMessage("ResourcePacks require SHA1s");
|
Limbo.getInstance().getConsole().sendMessage("ResourcePacks require SHA1s");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
//RESOURCEPACK NOT ENABLED
|
//RESOURCEPACK NOT ENABLED
|
||||||
}
|
}
|
||||||
|
|
||||||
// PLAYER LIST HEADER AND FOOTER CODE CONRIBUTED BY GAMERDUCK123
|
// PLAYER LIST HEADER AND FOOTER CODE CONRIBUTED BY GAMERDUCK123
|
||||||
player.sendPlayerListHeaderAndFooter(properties.getTabHeader(), properties.getTabFooter());
|
player.sendPlayerListHeaderAndFooter(properties.getTabHeader(), properties.getTabFooter());
|
||||||
|
|
||||||
ready = true;
|
ready = true;
|
||||||
|
|
||||||
keepAliveTask = new TimerTask() {
|
keepAliveTask = new TimerTask() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
if (ready) {
|
if (ready) {
|
||||||
long now = System.currentTimeMillis();
|
long now = System.currentTimeMillis();
|
||||||
if (now - getLastPacketTimestamp() > 15000) {
|
if (now - getLastPacketTimestamp() > 15000) {
|
||||||
PacketPlayOutKeepAlive keepAlivePacket = new PacketPlayOutKeepAlive(now);
|
PacketPlayOutKeepAlive keepAlivePacket = new PacketPlayOutKeepAlive(now);
|
||||||
try {
|
try {
|
||||||
sendPacket(keepAlivePacket);
|
sendPacket(keepAlivePacket);
|
||||||
setLastKeepAlivePayLoad(now);
|
setLastKeepAlivePayLoad(now);
|
||||||
} catch (Exception e) {}
|
} catch (Exception e) {
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
this.cancel();
|
} else {
|
||||||
}
|
this.cancel();
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
new Timer().schedule(keepAliveTask, 5000, 10000);
|
};
|
||||||
|
new Timer().schedule(keepAliveTask, 5000, 10000);
|
||||||
|
|
||||||
while (client_socket.isConnected()) {
|
while (client_socket.isConnected()) {
|
||||||
try {
|
try {
|
||||||
CheckedBiConsumer<PlayerMoveEvent, Location, IOException> processMoveEvent = (event, originalTo) -> {
|
CheckedBiConsumer<PlayerMoveEvent, Location, IOException> processMoveEvent = (event, originalTo) -> {
|
||||||
if (event.isCancelled()) {
|
if (event.isCancelled()) {
|
||||||
Location returnTo = event.getFrom();
|
Location returnTo = event.getFrom();
|
||||||
PacketPlayOutPositionAndLook cancel = new PacketPlayOutPositionAndLook(returnTo.getX(), returnTo.getY(), returnTo.getZ(), returnTo.getYaw(), returnTo.getPitch(), 1, false);
|
PacketPlayOutPositionAndLook cancel = new PacketPlayOutPositionAndLook(returnTo.getX(), returnTo.getY(), returnTo.getZ(), returnTo.getYaw(), returnTo.getPitch(), 1, false);
|
||||||
sendPacket(cancel);
|
sendPacket(cancel);
|
||||||
} else {
|
} else {
|
||||||
Location to = event.getTo();
|
Location to = event.getTo();
|
||||||
Limbo.getInstance().getUnsafe().setPlayerLocationSilently(player, to);
|
Limbo.getInstance().getUnsafe().setPlayerLocationSilently(player, to);
|
||||||
// If an event handler used setTo, let's make sure we tell the player about it.
|
// If an event handler used setTo, let's make sure we tell the player about it.
|
||||||
if (!originalTo.equals(to)) {
|
if (!originalTo.equals(to)) {
|
||||||
PacketPlayOutPositionAndLook pos = new PacketPlayOutPositionAndLook(to.getX(), to.getY(), to.getZ(), to.getYaw(), to.getPitch(), 1, false);
|
PacketPlayOutPositionAndLook pos = new PacketPlayOutPositionAndLook(to.getX(), to.getY(), to.getZ(), to.getYaw(), to.getPitch(), 1, false);
|
||||||
sendPacket(pos);
|
sendPacket(pos);
|
||||||
}
|
}
|
||||||
PacketPlayOutUpdateViewPosition response = new PacketPlayOutUpdateViewPosition((int) player.getLocation().getX() >> 4, (int) player.getLocation().getZ() >> 4);
|
PacketPlayOutUpdateViewPosition response = new PacketPlayOutUpdateViewPosition((int) player.getLocation().getX() >> 4, (int) player.getLocation().getZ() >> 4);
|
||||||
sendPacket(response);
|
sendPacket(response);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
PacketIn packetIn = channel.readPacket();
|
PacketIn packetIn = channel.readPacket();
|
||||||
if (packetIn instanceof PacketPlayInPositionAndLook) {
|
if (packetIn instanceof PacketPlayInPositionAndLook) {
|
||||||
PacketPlayInPositionAndLook pos = (PacketPlayInPositionAndLook) packetIn;
|
PacketPlayInPositionAndLook pos = (PacketPlayInPositionAndLook) packetIn;
|
||||||
Location from = player.getLocation();
|
Location from = player.getLocation();
|
||||||
Location to = new Location(player.getWorld(), pos.getX(), pos.getY(), pos.getZ(), pos.getYaw(), pos.getPitch());
|
Location to = new Location(player.getWorld(), pos.getX(), pos.getY(), pos.getZ(), pos.getYaw(), pos.getPitch());
|
||||||
|
|
||||||
if (!from.equals(to)) {
|
if (!from.equals(to)) {
|
||||||
PlayerMoveEvent event = Limbo.getInstance().getEventsManager().callEvent(new PlayerMoveEvent(player, from, to));
|
PlayerMoveEvent event = Limbo.getInstance().getEventsManager().callEvent(new PlayerMoveEvent(player, from, to));
|
||||||
processMoveEvent.consume(event, to);
|
processMoveEvent.consume(event, to);
|
||||||
}
|
}
|
||||||
} else if (packetIn instanceof PacketPlayInPosition) {
|
} else if (packetIn instanceof PacketPlayInPosition) {
|
||||||
PacketPlayInPosition pos = (PacketPlayInPosition) packetIn;
|
PacketPlayInPosition pos = (PacketPlayInPosition) packetIn;
|
||||||
Location from = player.getLocation();
|
Location from = player.getLocation();
|
||||||
Location to = new Location(player.getWorld(), pos.getX(), pos.getY(), pos.getZ(), player.getLocation().getYaw(), player.getLocation().getPitch());
|
Location to = new Location(player.getWorld(), pos.getX(), pos.getY(), pos.getZ(), player.getLocation().getYaw(), player.getLocation().getPitch());
|
||||||
|
|
||||||
if (!from.equals(to)) {
|
if (!from.equals(to)) {
|
||||||
PlayerMoveEvent event = Limbo.getInstance().getEventsManager().callEvent(new PlayerMoveEvent(player, from, to));
|
PlayerMoveEvent event = Limbo.getInstance().getEventsManager().callEvent(new PlayerMoveEvent(player, from, to));
|
||||||
processMoveEvent.consume(event, to);
|
processMoveEvent.consume(event, to);
|
||||||
}
|
}
|
||||||
} else if (packetIn instanceof PacketPlayInRotation) {
|
} else if (packetIn instanceof PacketPlayInRotation) {
|
||||||
PacketPlayInRotation pos = (PacketPlayInRotation) packetIn;
|
PacketPlayInRotation pos = (PacketPlayInRotation) packetIn;
|
||||||
Location from = player.getLocation();
|
Location from = player.getLocation();
|
||||||
Location to = new Location(player.getWorld(), player.getLocation().getX(), player.getLocation().getY(), player.getLocation().getZ(), pos.getYaw(), pos.getPitch());
|
Location to = new Location(player.getWorld(), player.getLocation().getX(), player.getLocation().getY(), player.getLocation().getZ(), pos.getYaw(), pos.getPitch());
|
||||||
|
|
||||||
if (!from.equals(to)) {
|
if (!from.equals(to)) {
|
||||||
PlayerMoveEvent event = Limbo.getInstance().getEventsManager().callEvent(new PlayerMoveEvent(player, from, to));
|
PlayerMoveEvent event = Limbo.getInstance().getEventsManager().callEvent(new PlayerMoveEvent(player, from, to));
|
||||||
processMoveEvent.consume(event, to);
|
processMoveEvent.consume(event, to);
|
||||||
}
|
}
|
||||||
} else if (packetIn instanceof PacketPlayInKeepAlive) {
|
} else if (packetIn instanceof PacketPlayInKeepAlive) {
|
||||||
PacketPlayInKeepAlive alive = (PacketPlayInKeepAlive) packetIn;
|
PacketPlayInKeepAlive alive = (PacketPlayInKeepAlive) packetIn;
|
||||||
if (alive.getPayload() != getLastKeepAlivePayLoad()) {
|
if (alive.getPayload() != getLastKeepAlivePayLoad()) {
|
||||||
Limbo.getInstance().getConsole().sendMessage("Incorrect Payload received in KeepAlive packet for player " + player.getName());
|
Limbo.getInstance().getConsole().sendMessage("Incorrect Payload received in KeepAlive packet for player " + player.getName());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else if (packetIn instanceof PacketPlayInTabComplete) {
|
} else if (packetIn instanceof PacketPlayInTabComplete) {
|
||||||
PacketPlayInTabComplete request = (PacketPlayInTabComplete) packetIn;
|
PacketPlayInTabComplete request = (PacketPlayInTabComplete) packetIn;
|
||||||
String[] command = CustomStringUtils.splitStringToArgs(request.getText().substring(1));
|
String[] command = CustomStringUtils.splitStringToArgs(request.getText().substring(1));
|
||||||
|
|
||||||
List<TabCompleteMatches> matches = new ArrayList<TabCompleteMatches>(Limbo.getInstance().getPluginManager().getTabOptions(player, command).stream().map(each -> new TabCompleteMatches(each)).collect(Collectors.toList()));
|
List<TabCompleteMatches> matches = new ArrayList<TabCompleteMatches>(Limbo.getInstance().getPluginManager().getTabOptions(player, command).stream().map(each -> new TabCompleteMatches(each)).collect(Collectors.toList()));
|
||||||
|
|
||||||
int start = CustomStringUtils.getIndexOfArg(request.getText(), command.length - 1) + 1;
|
int start = CustomStringUtils.getIndexOfArg(request.getText(), command.length - 1) + 1;
|
||||||
int length = command[command.length - 1].length();
|
int length = command[command.length - 1].length();
|
||||||
|
|
||||||
PacketPlayOutTabComplete response = new PacketPlayOutTabComplete(request.getId(), start, length, matches.toArray(new TabCompleteMatches[matches.size()]));
|
PacketPlayOutTabComplete response = new PacketPlayOutTabComplete(request.getId(), start, length, matches.toArray(new TabCompleteMatches[matches.size()]));
|
||||||
sendPacket(response);
|
sendPacket(response);
|
||||||
} else if (packetIn instanceof PacketPlayInChat) {
|
} else if (packetIn instanceof PacketPlayInChat) {
|
||||||
PacketPlayInChat chat = (PacketPlayInChat) packetIn;
|
PacketPlayInChat chat = (PacketPlayInChat) packetIn;
|
||||||
if (chat.getMessage().startsWith("/")) {
|
if (chat.getMessage().startsWith("/")) {
|
||||||
Limbo.getInstance().dispatchCommand(player, chat.getMessage());
|
Limbo.getInstance().dispatchCommand(player, chat.getMessage());
|
||||||
} else {
|
} else {
|
||||||
player.chat(chat.getMessage(), true);
|
player.chat(chat.getMessage(), true);
|
||||||
}
|
}
|
||||||
} else if (packetIn instanceof PacketPlayInHeldItemChange) {
|
} else if (packetIn instanceof PacketPlayInHeldItemChange) {
|
||||||
PacketPlayInHeldItemChange change = (PacketPlayInHeldItemChange) packetIn;
|
PacketPlayInHeldItemChange change = (PacketPlayInHeldItemChange) packetIn;
|
||||||
PlayerSelectedSlotChangeEvent event = Limbo.getInstance().getEventsManager().callEvent(new PlayerSelectedSlotChangeEvent(player, (byte) change.getSlot()));
|
PlayerSelectedSlotChangeEvent event = Limbo.getInstance().getEventsManager().callEvent(new PlayerSelectedSlotChangeEvent(player, (byte) change.getSlot()));
|
||||||
if (event.isCancelled()) {
|
if (event.isCancelled()) {
|
||||||
PacketPlayOutHeldItemChange cancelPacket = new PacketPlayOutHeldItemChange(player.getSelectedSlot());
|
PacketPlayOutHeldItemChange cancelPacket = new PacketPlayOutHeldItemChange(player.getSelectedSlot());
|
||||||
sendPacket(cancelPacket);
|
sendPacket(cancelPacket);
|
||||||
} else if (change.getSlot() != event.getSlot()) {
|
} else if (change.getSlot() != event.getSlot()) {
|
||||||
PacketPlayOutHeldItemChange changePacket = new PacketPlayOutHeldItemChange(event.getSlot());
|
PacketPlayOutHeldItemChange changePacket = new PacketPlayOutHeldItemChange(event.getSlot());
|
||||||
sendPacket(changePacket);
|
sendPacket(changePacket);
|
||||||
Limbo.getInstance().getUnsafe().setSelectedSlotSilently(player, event.getSlot());
|
Limbo.getInstance().getUnsafe().setSelectedSlotSilently(player, event.getSlot());
|
||||||
} else {
|
} else {
|
||||||
Limbo.getInstance().getUnsafe().setSelectedSlotSilently(player, event.getSlot());
|
Limbo.getInstance().getUnsafe().setSelectedSlotSilently(player, event.getSlot());
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (packetIn instanceof PacketPlayInResourcePackStatus) {
|
} else if (packetIn instanceof PacketPlayInResourcePackStatus) {
|
||||||
PacketPlayInResourcePackStatus rpcheck = (PacketPlayInResourcePackStatus) packetIn;
|
PacketPlayInResourcePackStatus rpcheck = (PacketPlayInResourcePackStatus) packetIn;
|
||||||
// Pass on result to the events
|
// Pass on result to the events
|
||||||
Limbo.getInstance().getEventsManager().callEvent(new PlayerResourcePackStatusEvent(player, rpcheck.getLoadedValue()));
|
Limbo.getInstance().getEventsManager().callEvent(new PlayerResourcePackStatusEvent(player, rpcheck.getLoadedValue()));
|
||||||
if (rpcheck.getLoadedValue().equals(EnumResourcePackStatus.DECLINED) && properties.getResourcePackRequired()) {
|
if (rpcheck.getLoadedValue().equals(EnumResourcePackStatus.DECLINED) && properties.getResourcePackRequired()) {
|
||||||
player.disconnect(new TranslatableComponent("multiplayer.requiredTexturePrompt.disconnect"));
|
player.disconnect(new TranslatableComponent("multiplayer.requiredTexturePrompt.disconnect"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Limbo.getInstance().getEventsManager().callEvent(new PlayerQuitEvent(player));
|
Limbo.getInstance().getEventsManager().callEvent(new PlayerQuitEvent(player));
|
||||||
|
|
||||||
str = inetAddress.getHostName() + ":" + client_socket.getPort() + "|" + player.getName();
|
str = inetAddress.getHostName() + ":" + client_socket.getPort() + "|" + player.getName();
|
||||||
Limbo.getInstance().getConsole().sendMessage("[/" + str + "] <-> Player had disconnected!");
|
Limbo.getInstance().getConsole().sendMessage("[/" + str + "] <-> Player had disconnected!");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (Exception ignored) {}
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
channel.close();
|
channel.close();
|
||||||
client_socket.close();
|
client_socket.close();
|
||||||
} catch (Exception ignored) {}
|
} catch (Exception ignored) {
|
||||||
state = ClientState.DISCONNECTED;
|
}
|
||||||
|
state = ClientState.DISCONNECTED;
|
||||||
|
|
||||||
if (player != null) {
|
if (player != null) {
|
||||||
Limbo.getInstance().removePlayer(player);
|
Limbo.getInstance().removePlayer(player);
|
||||||
}
|
}
|
||||||
Limbo.getInstance().getServerConnection().getClients().remove(this);
|
Limbo.getInstance().getServerConnection().getClients().remove(this);
|
||||||
running = false;
|
running = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static enum ClientState {
|
||||||
|
LEGACY,
|
||||||
|
HANDSHAKE,
|
||||||
|
STATUS,
|
||||||
|
LOGIN,
|
||||||
|
PLAY,
|
||||||
|
DISCONNECTED;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue