com.raphfrk.craftproxyclient.net.protocol.p172Play.P172PlayProtocol.java Source code

Java tutorial

Introduction

Here is the source code for com.raphfrk.craftproxyclient.net.protocol.p172Play.P172PlayProtocol.java

Source

/*
 * This file is part of CraftProxyClient.
 *
 * Copyright (c) 2013-2014, Raphfrk <http://raphfrk.com>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
 * of the Software, and to permit persons to whom the Software is furnished to do
 * so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package com.raphfrk.craftproxyclient.net.protocol.p172Play;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.charset.StandardCharsets;

import org.json.simple.JSONObject;

import com.raphfrk.craftproxyclient.net.protocol.Handshake;
import com.raphfrk.craftproxyclient.net.protocol.Packet;
import com.raphfrk.craftproxyclient.net.protocol.PacketChannel;
import com.raphfrk.craftproxyclient.net.protocol.Protocol;
import com.raphfrk.craftproxyclient.net.protocol.p17x.P17xHandshake;
import com.raphfrk.craftproxyclient.net.protocol.p17x.P17xKick;
import com.raphfrk.craftproxyclient.net.types.VarIntStringType;
import com.raphfrk.craftproxyclient.net.types.values.BulkData;
import com.raphfrk.craftproxycommon.compression.CompressionManager;
import com.raphfrk.craftproxycommon.message.MessageManager;
import com.raphfrk.craftproxycommon.message.SubMessage;

public class P172PlayProtocol extends Protocol {

    public P172PlayProtocol() {
        super(new P172PlayPacketRegistry());
    }

    public P17xHandshake getHandshake(Packet p) {
        return new P17xHandshake(p);
    }

    @Override
    public String getName() {
        return "1.72 (4)";
    }

    @Override
    public void sendKick(String message, PacketChannel client) throws IOException {
        client.writePacket(getKick(message));
    }

    @SuppressWarnings("unchecked")
    @Override
    public Packet getKick(String message) {
        JSONObject obj = new JSONObject();
        obj.put("text", message);
        return new P17xKick(0x40, obj.toJSONString());
    }

    @Override
    public Packet convertSubMessageToPacket(SubMessage message) throws IOException {
        int channelNameLength = VarIntStringType.stringToLength(MessageManager.getChannelName());
        byte[] data = MessageManager.encode(message.getSubCommand(), message.getData());
        return new Packet(0x17, new Object[] { 1 + channelNameLength + 2 + data.length, 0x17,
                MessageManager.getChannelName(), data });

    }

    @Override
    public void sendSubMessage(SubMessage s, PacketChannel client) throws IOException {
        throw new UnsupportedOperationException();
    }

    @Override
    public boolean isKickMessage(int id, boolean toServer) {
        return !toServer && id == 0x40;
    }

    @Override
    public Protocol handleLogin(Handshake handshake, PacketChannel client, PacketChannel server,
            InetSocketAddress serverAddr) throws IOException {
        throw new UnsupportedOperationException();
    }

    @Override
    public boolean isMessagePacket(int id, boolean toServer) {
        return !toServer && id == 0x3F;
    }

    @Override
    public String getMessageChannel(Packet p) {
        return (String) p.getField(2);
    }

    @Override
    public byte[] getMessageData(Packet p) {
        return (byte[]) p.getField(3);
    }

    @Override
    public SubMessage convertPacketToSubMessage(Packet p) throws IOException {
        String channel = (String) p.getField(2);
        if (!channel.equals(MessageManager.getChannelName())) {
            throw new IOException("Incorrect channel name " + channel);
        }
        byte[] data = (byte[]) p.getField(3);
        return MessageManager.decode(data);
    }

    @Override
    public Packet getRegisterPacket(String channel) {
        int registerLength = VarIntStringType.stringToLength("REGISTER");
        byte[] channelName = MessageManager.getChannelName().getBytes(StandardCharsets.UTF_8);
        return new Packet(0x17,
                new Object[] { 1 + registerLength + 2 + channelName.length, 0x17, "REGISTER", channelName });
    }

    @Override
    public boolean isDataPacket(int id) {
        return id == 0x21 || id == 0x26;
    }

    @Override
    public byte[] getDataArray(Packet p) {
        if (p.getId() == 0x21) {
            int primaryBitmask = ((Short) p.getField(5)) & 0xFFFF;
            int sections = Integer.bitCount(primaryBitmask);
            int maxSize = 256 + sections * 16384;

            byte[] data = (byte[]) p.getField(7);

            byte[] inflatedData = new byte[maxSize];
            int inflatedSize = CompressionManager.inflate(data, inflatedData);
            byte[] inflatedDataResized = new byte[inflatedSize];
            System.arraycopy(inflatedData, 0, inflatedDataResized, 0, inflatedSize);
            return inflatedDataResized;
        } else if (p.getId() == 0x26) {
            BulkData d = (BulkData) p.getField(2);
            int chunks = d.getChunks();
            int maxSize = chunks * 16384 * 16;
            byte[] inflatedData = new byte[maxSize];
            int inflatedSize = CompressionManager.inflate(d.getChunkData(), inflatedData);
            byte[] inflatedDataResized = new byte[inflatedSize];
            System.arraycopy(inflatedData, 0, inflatedDataResized, 0, inflatedSize);
            return inflatedDataResized;
        } else {
            return null;
        }
    }

    @Override
    public boolean setDataArray(Packet p, byte[] data) {
        if (p.getId() == 0x21) {
            byte[] deflatedData = new byte[data.length + 100];
            int size = CompressionManager.deflate(data, deflatedData);
            byte[] deflatedDataResized = new byte[size];
            System.arraycopy(deflatedData, 0, deflatedDataResized, 0, size);
            p.setField(7, deflatedDataResized);
            int length = 1 + 4 + 4 + 1 + 2 + 2 + 4 + deflatedDataResized.length;
            p.setField(0, length);
        } else if (p.getId() == 0x26) {
            byte[] deflatedData = new byte[data.length + 100];
            int size = CompressionManager.deflate(data, deflatedData);
            byte[] deflatedDataResized = new byte[size];
            System.arraycopy(deflatedData, 0, deflatedDataResized, 0, size);
            BulkData d = (BulkData) p.getField(2);
            d.setChunkData(deflatedDataResized);
            int length = 1 + 2 + 4 + 1 + deflatedDataResized.length + (4 + 4 + 2 + 2) * d.getChunks();
            p.setField(0, length);
        } else {
            return false;
        }
        return true;
    }

}