Inter server teleporting is there, albeit slightly borked
This commit is contained in:
parent
b53f66b6ac
commit
093f45463a
@ -14,7 +14,9 @@ import java.util.concurrent.Executors;
|
||||
import static net.md_5.bungee.Logger.$;
|
||||
import net.md_5.bungee.command.Command;
|
||||
import net.md_5.bungee.command.CommandEnd;
|
||||
import net.md_5.bungee.command.CommandList;
|
||||
import net.md_5.bungee.command.CommandSender;
|
||||
import net.md_5.bungee.command.CommandServer;
|
||||
import net.md_5.bungee.command.ConsoleCommandSender;
|
||||
|
||||
public class BungeeCord {
|
||||
@ -58,6 +60,8 @@ public class BungeeCord {
|
||||
|
||||
{
|
||||
commandMap.put("end", new CommandEnd());
|
||||
commandMap.put("glist", new CommandList());
|
||||
commandMap.put("server", new CommandServer());
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
|
@ -194,10 +194,11 @@ public class Configuration {
|
||||
|
||||
public InetSocketAddress getServer(String name) {
|
||||
String hostline = (name == null) ? defaultServerName : name;
|
||||
if (hostline != null) {
|
||||
return Util.getAddr(hostline);
|
||||
String server = servers.get(hostline);
|
||||
if (server != null) {
|
||||
return Util.getAddr(server);
|
||||
} else {
|
||||
throw new IllegalArgumentException("No server by name " + name);
|
||||
return Util.getAddr(servers.get(defaultServerName));
|
||||
}
|
||||
}
|
||||
|
||||
|
61
src/main/java/net/md_5/bungee/EntityMap.java
Normal file
61
src/main/java/net/md_5/bungee/EntityMap.java
Normal file
@ -0,0 +1,61 @@
|
||||
package net.md_5.bungee;
|
||||
|
||||
public class EntityMap {
|
||||
|
||||
public final static int[][] entityIds = new int[256][];
|
||||
|
||||
static {
|
||||
entityIds[0x05] = new int[]{1};
|
||||
entityIds[0x07] = new int[]{1, 5};
|
||||
entityIds[0x11] = new int[]{1};
|
||||
entityIds[0x12] = new int[]{1};
|
||||
entityIds[0x13] = new int[]{1};
|
||||
entityIds[0x14] = new int[]{1};
|
||||
entityIds[0x15] = new int[]{1};
|
||||
entityIds[0x16] = new int[]{1, 5};
|
||||
entityIds[0x17] = new int[]{1};
|
||||
entityIds[0x18] = new int[]{1};
|
||||
entityIds[0x19] = new int[]{1};
|
||||
entityIds[0x1C] = new int[]{1};
|
||||
entityIds[0x1E] = new int[]{1};
|
||||
entityIds[0x1F] = new int[]{1};
|
||||
entityIds[0x20] = new int[]{1};
|
||||
entityIds[0x21] = new int[]{1};
|
||||
entityIds[0x22] = new int[]{1};
|
||||
entityIds[0x26] = new int[]{1};
|
||||
entityIds[0x27] = new int[]{1, 5};
|
||||
entityIds[0x28] = new int[]{1};
|
||||
entityIds[0x47] = new int[]{1};
|
||||
}
|
||||
|
||||
public static void rewrite(byte[] packet, int oldId, int newId) {
|
||||
int packetId = Util.getId(packet);
|
||||
if (packetId == 0x1D) { // bulk entity
|
||||
for (int pos = 2; pos < packet.length; pos += 4) {
|
||||
if (oldId == readInt(packet, pos)) {
|
||||
setInt(packet, pos, newId);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
int[] idArray = entityIds[packetId];
|
||||
if (idArray != null) {
|
||||
for (int pos : idArray) {
|
||||
if (oldId == readInt(packet, pos)) {
|
||||
setInt(packet, pos, newId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void setInt(byte[] buf, int pos, int i) {
|
||||
buf[pos] = (byte) (i >> 24);
|
||||
buf[pos + 1] = (byte) (i >> 16);
|
||||
buf[pos + 2] = (byte) (i >> 8);
|
||||
buf[pos + 3] = (byte) i;
|
||||
}
|
||||
|
||||
private static int readInt(byte[] buf, int pos) {
|
||||
return (((buf[pos] & 0xFF) << 24) | ((buf[pos + 1] & 0xFF) << 16) | ((buf[pos + 2] & 0xFF) << 8) | buf[pos + 3] & 0xFF);
|
||||
}
|
||||
}
|
@ -6,18 +6,28 @@ import java.net.InetSocketAddress;
|
||||
import java.net.Socket;
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import net.md_5.bungee.command.CommandSender;
|
||||
import net.md_5.bungee.packet.DefinedPacket;
|
||||
import net.md_5.bungee.packet.Packet10HeldItem;
|
||||
import net.md_5.bungee.packet.Packet1Login;
|
||||
import net.md_5.bungee.packet.Packet2Handshake;
|
||||
import net.md_5.bungee.packet.Packet3Chat;
|
||||
import net.md_5.bungee.packet.Packet46GameState;
|
||||
import net.md_5.bungee.packet.Packet9Respawn;
|
||||
import net.md_5.bungee.packet.PacketFAPluginMessage;
|
||||
import net.md_5.bungee.packet.PacketInputStream;
|
||||
|
||||
public class UserConnection extends GenericConnection {
|
||||
public class UserConnection extends GenericConnection implements CommandSender {
|
||||
|
||||
public final Packet2Handshake handshake;
|
||||
public Queue<DefinedPacket> packetQueue = new ConcurrentLinkedQueue<>();
|
||||
private ServerConnection server;
|
||||
private UpstreamBridge upBridge;
|
||||
private DownstreamBridge downBridge;
|
||||
// reconnect stuff
|
||||
private Packet10HeldItem heldItem;
|
||||
private int clientEntityId;
|
||||
private int serverEntityId;
|
||||
|
||||
public UserConnection(Socket socket, PacketInputStream in, OutputStream out, Packet2Handshake handshake) {
|
||||
super(socket, in, out);
|
||||
@ -25,16 +35,37 @@ public class UserConnection extends GenericConnection {
|
||||
username = handshake.username;
|
||||
}
|
||||
|
||||
public void connect(String server) {
|
||||
InetSocketAddress addr = BungeeCord.instance.config.getServer(server);
|
||||
if (addr == null) {
|
||||
sendMessage(ChatColor.RED + "Specified server does not exist");
|
||||
return;
|
||||
}
|
||||
connect(addr);
|
||||
}
|
||||
|
||||
public void connect(InetSocketAddress serverAddr) {
|
||||
try {
|
||||
ServerConnection newServer = ServerConnection.connect(serverAddr, handshake, true);
|
||||
if (downBridge != null) {
|
||||
downBridge.interrupt();
|
||||
}
|
||||
if (server == null) {
|
||||
clientEntityId = newServer.loginPacket.entityId;
|
||||
out.write(newServer.loginPacket.getPacket());
|
||||
upBridge = new UpstreamBridge();
|
||||
upBridge.start();
|
||||
}
|
||||
if (downBridge != null) {
|
||||
downBridge.interrupt();
|
||||
} else {
|
||||
server.disconnect("Quitting");
|
||||
out.write(new Packet9Respawn((byte) 1, (byte) 0, (byte) 0, (short) 256, "DEFAULT").getPacket());
|
||||
out.write(new Packet9Respawn((byte) -1, (byte) 0, (byte) 0, (short) 256, "DEFAULT").getPacket());
|
||||
out.write(new Packet46GameState((byte) 2, (byte) 0).getPacket());
|
||||
Packet1Login login = newServer.loginPacket;
|
||||
serverEntityId = login.entityId;
|
||||
out.write(new Packet9Respawn(login.dimension, login.difficulty, login.gameMode, (short) 256, login.levelType).getPacket());
|
||||
if (heldItem != null) {
|
||||
newServer.out.write(heldItem.getPacket());
|
||||
}
|
||||
}
|
||||
downBridge = new DownstreamBridge();
|
||||
server = newServer;
|
||||
@ -70,6 +101,11 @@ public class UserConnection extends GenericConnection {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendMessage(String message) {
|
||||
packetQueue.add(new Packet3Chat(message));
|
||||
}
|
||||
|
||||
private class UpstreamBridge extends Thread {
|
||||
|
||||
public UpstreamBridge() {
|
||||
@ -81,7 +117,23 @@ public class UserConnection extends GenericConnection {
|
||||
while (!interrupted()) {
|
||||
try {
|
||||
byte[] packet = in.readPacket();
|
||||
server.out.write(packet);
|
||||
boolean sendPacket = true;
|
||||
|
||||
int id = Util.getId(packet);
|
||||
if (id == 0x03) {
|
||||
Packet3Chat chat = new Packet3Chat(packet);
|
||||
String message = chat.message;
|
||||
if (message.startsWith("/")) {
|
||||
sendPacket = !BungeeCord.instance.dispatchCommand(message.substring(1), UserConnection.this);
|
||||
}
|
||||
} else if (id == 0x10) {
|
||||
heldItem = new Packet10HeldItem(packet);
|
||||
}
|
||||
|
||||
EntityMap.rewrite(packet, clientEntityId, serverEntityId);
|
||||
if (sendPacket && !server.socket.isClosed()) {
|
||||
server.out.write(packet);
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
destory("Reached end of stream");
|
||||
} catch (Exception ex) {
|
||||
@ -102,10 +154,30 @@ public class UserConnection extends GenericConnection {
|
||||
while (!interrupted()) {
|
||||
try {
|
||||
byte[] packet = server.in.readPacket();
|
||||
out.write(packet);
|
||||
out.flush();
|
||||
boolean sendPacket = true;
|
||||
|
||||
int id = Util.getId(packet);
|
||||
if (id == 0xFA) {
|
||||
PacketFAPluginMessage message = new PacketFAPluginMessage(packet);
|
||||
if (message.tag.equals("RubberBand")) {
|
||||
String server = new String(message.data);
|
||||
connect(server);
|
||||
sendPacket = false;
|
||||
}
|
||||
}
|
||||
|
||||
while (!packetQueue.isEmpty()) {
|
||||
DefinedPacket p = packetQueue.poll();
|
||||
if (p != null) {
|
||||
out.write(p.getPacket());
|
||||
}
|
||||
}
|
||||
|
||||
EntityMap.rewrite(packet, serverEntityId, clientEntityId);
|
||||
if (sendPacket) {
|
||||
out.write(packet);
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
destory("Reached end of stream");
|
||||
} catch (Exception ex) {
|
||||
destory(Util.exception(ex));
|
||||
}
|
||||
|
24
src/main/java/net/md_5/bungee/command/CommandList.java
Normal file
24
src/main/java/net/md_5/bungee/command/CommandList.java
Normal file
@ -0,0 +1,24 @@
|
||||
package net.md_5.bungee.command;
|
||||
|
||||
import java.util.Collection;
|
||||
import net.md_5.bungee.BungeeCord;
|
||||
import net.md_5.bungee.ChatColor;
|
||||
import net.md_5.bungee.UserConnection;
|
||||
|
||||
public class CommandList extends Command {
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
StringBuilder users = new StringBuilder();
|
||||
Collection<UserConnection> connections = BungeeCord.instance.connections.values();
|
||||
|
||||
for (UserConnection con : connections) {
|
||||
users.append(con.username);
|
||||
users.append(ChatColor.RESET.toString());
|
||||
users.append(", ");
|
||||
}
|
||||
|
||||
users.setLength(users.length() - 2);
|
||||
sender.sendMessage(ChatColor.BLUE + "Currently online across all servers (" + connections.size() + "): " + ChatColor.RESET + users);
|
||||
}
|
||||
}
|
30
src/main/java/net/md_5/bungee/command/CommandServer.java
Normal file
30
src/main/java/net/md_5/bungee/command/CommandServer.java
Normal file
@ -0,0 +1,30 @@
|
||||
package net.md_5.bungee.command;
|
||||
|
||||
import java.util.Collection;
|
||||
import net.md_5.bungee.BungeeCord;
|
||||
import net.md_5.bungee.ChatColor;
|
||||
import net.md_5.bungee.UserConnection;
|
||||
|
||||
public class CommandServer extends Command {
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender, String[] args) {
|
||||
if (!(sender instanceof UserConnection)) {
|
||||
return;
|
||||
}
|
||||
UserConnection con = (UserConnection) sender;
|
||||
if (args.length <= 0) {
|
||||
Collection<String> servers = BungeeCord.instance.config.servers.keySet();
|
||||
StringBuilder serverList = new StringBuilder();
|
||||
for (String server : servers) {
|
||||
serverList.append(server);
|
||||
serverList.append(", ");
|
||||
}
|
||||
serverList.setLength(serverList.length() - 2);
|
||||
con.sendMessage(ChatColor.GOLD + "You may connect to the following servers at this time: " + serverList.toString());
|
||||
} else {
|
||||
String server = args[0];
|
||||
con.connect(server);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user