me.bigteddy98.mcproxy.protocol.NetworkManager.java Source code

Java tutorial

Introduction

Here is the source code for me.bigteddy98.mcproxy.protocol.NetworkManager.java

Source

/* 
 * MCProxy
 * Copyright (C) 2014 Sander Gielisse
 *
 *     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 <http://www.gnu.org/licenses/>.
 */
package me.bigteddy98.mcproxy.protocol;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelPipeline;

import java.util.ArrayList;
import java.util.List;
import java.util.zip.Deflater;
import java.util.zip.Inflater;

import me.bigteddy98.mcproxy.Main;
import me.bigteddy98.mcproxy.ProxyLogger;
import me.bigteddy98.mcproxy.api.GameMode;
import me.bigteddy98.mcproxy.api.InventoryType;
import me.bigteddy98.mcproxy.api.Player;
import me.bigteddy98.mcproxy.api.PotionEffect;
import me.bigteddy98.mcproxy.api.Weather;
import me.bigteddy98.mcproxy.api.entity.Achievement;
import me.bigteddy98.mcproxy.entity.Location;
import me.bigteddy98.mcproxy.inventory.ItemStack;
import me.bigteddy98.mcproxy.protocol.codex.CompressionCodex;
import me.bigteddy98.mcproxy.protocol.codex.DecompressionCodex;
import me.bigteddy98.mcproxy.protocol.handlers.ClientSideHandler;
import me.bigteddy98.mcproxy.protocol.packet.Packet;
import me.bigteddy98.mcproxy.protocol.packet.PacketDataWrapper;
import me.bigteddy98.mcproxy.protocol.packet.PacketReceiveEvent;

public class NetworkManager implements Player {

    public final ClientSideHandler clientSideHandler;
    public volatile ConnectionState currentState = ConnectionState.HANDSHAKE;
    public volatile int protocolId;

    public Deflater deflater = new Deflater();
    public Inflater inflater = new Inflater();
    public int compressionThreshold = -1;
    public boolean clientsideCompressionEnabled = false;
    public boolean serversideCompressionEnabled = false;

    public ChannelPipeline serversidePipeline;
    public ChannelPipeline clientsidePipeline;

    public String playerName;
    public String uuid;

    public NetworkManager(ClientSideHandler clientToProxyHandler) {
        this.clientSideHandler = clientToProxyHandler;
    }

    public synchronized List<Packet> handleServerBoundPackets(ByteBuf originalBuffer, ByteBuf bufferClone)
            throws InstantiationException, IllegalAccessException {
        List<Packet> list = new ArrayList<>();
        if (bufferClone.readableBytes() == 0) {
            return list;
        }
        PacketDataWrapper wrapper = new PacketDataWrapper(bufferClone);
        while (bufferClone.readableBytes() > 0) {
            bufferClone.markReaderIndex();
            int readBytes = bufferClone.readableBytes();
            int length = 0;
            {
                int bytes = 0;
                byte in;
                while (true) {
                    if (readBytes < 1) {
                        bufferClone.resetReaderIndex();
                        return list;
                    }
                    in = bufferClone.readByte();
                    length |= (in & 0x7F) << (bytes++ * 7);
                    if (bytes > 5) {
                        throw new RuntimeException("VarInt too big");
                    }
                    if ((in & 0x80) != 0x80) {
                        break;
                    }
                }
            }
            if (bufferClone.readableBytes() < length) {
                bufferClone.resetReaderIndex();
                return list;
            }
            int id = wrapper.readVarInt();
            Class<? extends Packet> clazz = PacketRegistry.getServerBoundPacket(id, this.currentState);
            if (clazz == null) {
                return list;
            }
            Packet packet = clazz.newInstance();
            packet.read(wrapper);
            packet.onReceive(this, new PacketReceiveEvent());
            list.add(packet);
            ProxyLogger.debug("Handled " + packet.toString());
            bufferClone.discardSomeReadBytes();
        }
        return list;
    }

    public synchronized List<Packet> handleClientBoundPackets(ByteBuf originalBuffer, ByteBuf bufferClone)
            throws InstantiationException, IllegalAccessException {
        List<Packet> list = new ArrayList<>();
        if (bufferClone.readableBytes() == 0) {
            return list;
        }
        PacketDataWrapper wrapper = new PacketDataWrapper(bufferClone);
        while (bufferClone.readableBytes() > 0) {
            bufferClone.markReaderIndex();
            int readBytes = bufferClone.readableBytes();
            int length = 0;
            {
                int bytes = 0;
                byte in;
                while (true) {
                    if (readBytes < 1) {
                        bufferClone.resetReaderIndex();
                        return list;
                    }
                    in = bufferClone.readByte();
                    length |= (in & 0x7F) << (bytes++ * 7);
                    if (bytes > 5) {
                        throw new RuntimeException("VarInt too big");
                    }
                    if ((in & 0x80) != 0x80) {
                        break;
                    }
                }
            }
            if (bufferClone.readableBytes() < length) {
                bufferClone.resetReaderIndex();
                return list;
            }
            int id = wrapper.readVarInt();
            Class<? extends Packet> clazz = PacketRegistry.getClientBoundPacket(id, this.currentState);
            if (clazz == null) {
                return list;
            }
            Packet packet = clazz.newInstance();
            packet.read(wrapper);
            packet.onReceive(this, new PacketReceiveEvent());
            list.add(packet);
            ProxyLogger.debug("Handled " + packet.toString());
            bufferClone.discardSomeReadBytes();
        }
        return list;
    }

    public void disconnect() {
        this.clientsidePipeline.close();
        this.serversidePipeline.close();
        Main.getInstance().getDataManager().disconnectPlayer(this);
    }

    public void enableServerSideCompression() {
        if (this.serversideCompressionEnabled) {
            return;
        }
        this.serversideCompressionEnabled = true;
        ProxyLogger.info("Serversided compression threshold is now set to " + this.compressionThreshold);
        this.serversidePipeline.addBefore("serverbound_proxy_codex", "decompression_codex",
                new DecompressionCodex(this));
        this.serversidePipeline.addBefore("serverbound_proxy_codex", "compression_codex",
                new CompressionCodex(this));
    }

    public void enableClientSideCompression() {
        if (this.clientsideCompressionEnabled) {
            return;
        }
        this.clientsideCompressionEnabled = true;
        ProxyLogger.info("Clientsided compression threshold is now set to " + this.compressionThreshold);
        this.clientsidePipeline.addBefore("clientbound_proxy_codex", "decompression_codex",
                new DecompressionCodex(this));
        this.clientsidePipeline.addBefore("clientbound_proxy_codex", "compression_codex",
                new CompressionCodex(this));
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((clientSideHandler == null) ? 0 : clientSideHandler.hashCode());
        result = prime * result + (clientsideCompressionEnabled ? 1231 : 1237);
        result = prime * result + ((clientsidePipeline == null) ? 0 : clientsidePipeline.hashCode());
        result = prime * result + compressionThreshold;
        result = prime * result + ((currentState == null) ? 0 : currentState.hashCode());
        result = prime * result + (serversideCompressionEnabled ? 1231 : 1237);
        result = prime * result + ((serversidePipeline == null) ? 0 : serversidePipeline.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        NetworkManager other = (NetworkManager) obj;
        if (clientSideHandler == null) {
            if (other.clientSideHandler != null)
                return false;
        } else if (!clientSideHandler.equals(other.clientSideHandler))
            return false;
        if (clientsideCompressionEnabled != other.clientsideCompressionEnabled)
            return false;
        if (clientsidePipeline == null) {
            if (other.clientsidePipeline != null)
                return false;
        } else if (!clientsidePipeline.equals(other.clientsidePipeline))
            return false;
        if (compressionThreshold != other.compressionThreshold)
            return false;
        if (currentState != other.currentState)
            return false;
        if (serversideCompressionEnabled != other.serversideCompressionEnabled)
            return false;
        if (serversidePipeline == null) {
            if (other.serversidePipeline != null)
                return false;
        } else if (!serversidePipeline.equals(other.serversidePipeline))
            return false;
        return true;
    }

    @Override
    public String getName() {
        return this.playerName;
    }

    @Override
    public void awardAchievement(Achievement achievement) {
        Main.getInstance().executeCommand("achievement give " + achievement.getName() + " " + this.getName());
    }

    @Override
    public void sendMessage(String message) {
        Main.getInstance().executeCommand("tellraw " + this.getName() + " {text:\"" + message + "\"}");
    }

    @Override
    public void teleport(Location loc) {
        Main.getInstance()
                .executeCommand("tp " + this.getName() + " " + loc.getX() + " " + loc.getY() + " " + loc.getZ());
    }

    @Override
    public void clearInventory() {
        Main.getInstance().executeCommand("clear " + this.getName());
    }

    @Override
    public void addPotionEffect(PotionEffect effect, int seconds, int amplifier, boolean hideParticles) {
        Main.getInstance().executeCommand("effect " + this.getName() + " " + effect.getId() + " " + seconds + " "
                + amplifier + " " + hideParticles);
    }

    @Override
    public void removePotionEffects() {
        Main.getInstance().executeCommand("effect " + this.getName() + " clear");
    }

    @Override
    public void setGameMode(GameMode gameMode) {
        Main.getInstance().executeCommand("gamemode " + gameMode.getId() + " " + this.getName());
    }

    @Override
    public void giveItem(ItemStack stack) {
        Main.getInstance().executeCommand("give " + this.getName() + " " + stack.getBlockId() + " "
                + stack.getAmount() + " " + stack.getDamage());
    }

    @Override
    public void kick(String reason) {
        Main.getInstance().executeCommand("kick " + this.getName() + " " + reason);
    }

    @Override
    public void playSound(String soundname) {
        Main.getInstance().executeCommand("playsound " + soundname + " " + this.getName());
    }

    @Override
    public void playSound(String soundname, float x, float y, float z) {
        Main.getInstance()
                .executeCommand("playsound " + soundname + " " + this.getName() + " " + x + " " + y + " " + z);
    }

    @Override
    public void setInventoryItem(InventoryType type, int slotNumber, ItemStack stack) {
        Main.getInstance()
                .executeCommand("replaceitem entity " + this.getName() + " "
                        + type.getName().replace("%SLOTNUMBER%", slotNumber + "") + " " + stack.getBlockId() + " "
                        + stack.getAmount() + " " + stack.getDamage());
    }

    @Override
    public void displayTitle(String message) {
        Main.getInstance().executeCommand("title " + this.getName() + " title {text:\"" + message + "\"}");
    }

    @Override
    public void displaySubTitle(String message) {
        Main.getInstance().executeCommand("title " + this.getName() + " subtitle {text:\"" + message + "\"}");
    }

    @Override
    public void giveExpLevels(int amount) {
        Main.getInstance().executeCommand("xp " + amount + "L " + this.getName());
    }

    @Override
    public void giveExp(int amount) {
        Main.getInstance().executeCommand("xp " + amount + " " + this.getName());
    }

    @Override
    public void removeExp(int amount) {
        Main.getInstance().executeCommand("xp -" + amount + " " + this.getName());
    }

    @Override
    public void removeAllExp() {
        Main.getInstance().executeCommand("xp -2147483648L " + this.getName());
    }

    @Override
    public void removeExpLevels(int amount) {
        Main.getInstance().executeCommand("xp -" + amount + "L " + this.getName());
    }
}