CachedPlayerHeads/src/main/java/org/warp/cachedplayerheads/bungee/BungeeAPI.java
Andrea Cavalli 9d1f489996 First commit
2021-04-19 20:53:45 +02:00

118 lines
3.7 KiB
Java

package org.warp.cachedplayerheads.bungee;
import com.google.common.io.ByteArrayDataInput;
import com.google.common.io.ByteArrayDataOutput;
import com.google.common.io.ByteStreams;
import java.util.UUID;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import net.md_5.bungee.api.connection.Server;
import net.md_5.bungee.api.event.PluginMessageEvent;
import net.md_5.bungee.api.plugin.Listener;
import net.md_5.bungee.api.plugin.Plugin;
import net.md_5.bungee.event.EventHandler;
import net.skinsrestorer.api.SkinsRestorerAPI;
import org.warp.cachedplayerheads.SkinsRestorerAPIUtils;
public class BungeeAPI implements Listener {
private final Plugin playerheads;
private final SkinsRestorerAPI skinsRestorerAPI;
public BungeeAPI(SkinsRestorerAPI skinsRestorerAPI, Plugin playerheads) {
this.skinsRestorerAPI = skinsRestorerAPI;
this.playerheads = playerheads;
playerheads.getProxy().getPluginManager().registerListener(playerheads, this);
}
public void sendSkinData(Sender sender, UUID reqUUID, String skinData) {
ByteArrayDataOutput out = ByteStreams.newDataOutput();
out.writeUTF("PlayerTextureResponse");
out.writeLong(reqUUID.getMostSignificantBits());
out.writeLong(reqUUID.getLeastSignificantBits());
if (skinData == null) {
out.writeBoolean(false);
} else {
out.writeBoolean(true);
out.writeUTF(skinData);
}
// we send the data to the server
// using ServerInfo the packet is being queued if there are no players in the server
// using only the server to send data the packet will be lost if no players are in it
System.out.println("Replying skin request: " + reqUUID);
sender.sendData("cachedplayerheads:channel", out.toByteArray());
}
@EventHandler
public void on(PluginMessageEvent event) {
if (!event.getTag().equals("cachedplayerheads:channel")) {
return;
}
ByteArrayDataInput in = ByteStreams.newDataInput(event.getData());
String subChannel = in.readUTF();
long msb = in.readLong();
long lsb = in.readLong();
UUID reqUUID = new UUID(msb, lsb);
String playerName = in.readUTF();
System.out.println("Received skin request: " + reqUUID);
if (subChannel.equalsIgnoreCase("PlayerTextureRequest")) {
Sender sender;
// the receiver is a server when the proxy talks to a server
if (event.getReceiver() instanceof Server) {
Server receiver = (Server) event.getReceiver();
sender = new ServerSender(receiver);
}
// the receiver is a ProxiedPlayer when a server talks to the proxy
else if (event.getReceiver() instanceof ProxiedPlayer) {
ProxiedPlayer receiver = (ProxiedPlayer) event.getReceiver();
sender = new ProxiedPlayerSender(receiver);
} else {
System.err.println("Invalid receiver type: " + event.getReceiver());
sender = null;
}
if (sender != null) {
playerheads.getProxy().getScheduler().runAsync(playerheads, () -> {
String skinData = SkinsRestorerAPIUtils.getSkinData(skinsRestorerAPI, playerName);
sendSkinData(sender, reqUUID, skinData);
});
}
} else {
System.err.println("Invalid subchannel: " + subChannel);
}
}
private interface Sender {
void sendData(String channel, byte[] data);
}
private static class ServerSender implements Sender {
private final Server server;
public ServerSender(Server server) {
this.server = server;
}
@Override
public void sendData(String channel, byte[] data) {
server.sendData(channel, data);
}
}
private static class ProxiedPlayerSender implements Sender {
private final ProxiedPlayer proxiedPlayer;
public ProxiedPlayerSender(ProxiedPlayer proxiedPlayer) {
this.proxiedPlayer = proxiedPlayer;
}
@Override
public void sendData(String channel, byte[] data) {
proxiedPlayer.getServer().sendData(channel, data);
}
}
}