eu.jangos.realm.network.packet.server.character.SMSG_CHAR_ENUM.java Source code

Java tutorial

Introduction

Here is the source code for eu.jangos.realm.network.packet.server.character.SMSG_CHAR_ENUM.java

Source

package eu.jangos.realm.network.packet.server.character;

import eu.jangos.realm.controller.characters.ItemInstanceService;
import eu.jangos.realm.controller.factory.ItemServiceFactory;
import eu.jangos.realm.controller.world.ItemService;
import eu.jangos.realm.enums.characters.GenderEnum;
import eu.jangos.realm.enums.characters.ProfessionsEnum;
import eu.jangos.realm.enums.characters.RaceEnum;
import eu.jangos.realm.model.characters.Characters;
import eu.jangos.realm.network.opcode.Opcodes;
import eu.jangos.realm.network.packet.AbstractRealmServerPacket;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufUtil;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.List;

/*
 * Copyright 2016 Warkdev.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/**
 * SMSG_CHAR_ENUM represents a message sent by the server a client is
 * authenticated for this realm.
 *
 * @author Warkdev
 * @version v0.1 BETA.
 */
public class SMSG_CHAR_ENUM extends AbstractRealmServerPacket {

    /**
     * List of characters.
     */
    private List<Characters> listChars;

    /**
     * Number of characters.
     */
    private int numChars;

    private static final int EQUIPMENT_SLOT_END = 19;

    public SMSG_CHAR_ENUM(Opcodes code) {
        super(code, 3);
        this.listChars = new ArrayList<>();
        this.numChars = 0;
    }

    /**
     * Add one character to the list of characters.
     *
     * @param character The character to be added.
     */
    public void addCharacter(Characters character) {
        if (this.listChars.add(character)) {
            this.size += getCharacterLength(character);
            this.numChars++;
        }
    }

    /**
     * Add characters to the actual list of characters.
     *
     * @param listChars The list of characters to be added.
     */
    public void addCharacters(List<Characters> listChars) {
        for (Characters c : listChars) {
            addCharacter(c);
        }
    }

    /**
     * Remove the character from the character list.
     *
     * @param character The character to be removed.
     */
    public void remCharacter(Characters character) {
        if (this.listChars.remove(character)) {
            this.size -= getCharacterLength(character);
            this.numChars--;
        }
    }

    private int getCharacterLength(Characters character) {
        return 159 + character.getName().length();
    }

    public String toString() {
        String toString = "[SMSG_CHAR_ENUM [ " + this.numChars + " character(s), size: " + this.size;

        for (Characters c : this.listChars) {
            toString += "[ id: " + c.getGuid() + ", name: " + c.getName() + ", race: "
                    + RaceEnum.convert(c.getRace()) + ", class: " + ProfessionsEnum.convert(c.getFkDbcClass())
                    + ", gender: " + GenderEnum.convert(c.getGender());
        }

        toString += " ]]";
        return toString;
    }

    /**
     * Build the field which represents the login flag.
     * @param c The character for which the flags need to be created.
     * @return An integer corresponding to the value of the character flag.
     */
    private byte convertLoginFlagsToByte(Characters c) {
        byte flags = 0; // NONE

        flags += (c.getChangename() ? 1 : 0); // RENAME
        flags += (c.getResetspell() ? 2 : 0); // RESET SPELLS
        flags += (c.getResettalents() ? 4 : 0); // RESET TALENTS
        //flags+=(c.isCharcustom()? 8 : 0); // CUSTOMIZE -- Not used
        //flags+=(c.isre() ? 16 : 0); // RESET PET TALENTS -- Not used
        flags += (c.getTotaltime() == 0 ? 32 : 0); // FIRST LOGIN        

        return flags;
    }

    /**
     * Build the field which represents the character flags.
     *
     * @param c The character for which the flags needs to be created.
     * @return An integer corresponding to the value of the character flag.
     */
    private int convertPlayersFlagsToInt(Characters c) {
        int flags = 0;

        // flags+= 1; //UNKNOWN FLAG
        // flags+= (0*2) // UNKNOWN FLAG
        // flags+= (0*4) // UNKNOWN
        // flags+= (0*8) // UNKNOWN
        // flags+= (0*16) // UNKNOWN
        // flags+= (0*32) // UNKNOWN
        // flags+= (0*64) // UNKNOWN
        // flags+= (0*128) // UNKNOWN
        // flags+= (0*256) // UNKNOWN
        // flags+= (0*512) // UNKNOWN        
        flags += (c.getHidehelm() ? 1024 : 0); // HIDE_HELM
        flags += (c.getHidecloak() ? 2048 : 0); // HIDE_CLOAK
        // flags+= (0*4096) // UNKNOWN
        flags += (c.getGhost() ? 8192 : 0); // GHOST
        flags += (c.getChangename() ? 16384 : 0); // RENAME
        // flags+= (0*32768) // UNKNOWN
        // flags+= (0*65536) // UNKNOWN
        // flags+= (0*131072) // UNKNOWN
        // flags+= (0*262144) // UNKNOWN
        // flags+= (0*524288) // UNKNOWN
        // flags+= (0*1048576) // UNKNOWN
        // flags+= (0*2097152) // UNKNOWN
        // flags+= (0*4194304) // UNKNOWN
        // flags+= (0*8388608) // UNKNOWN        
        // flags+= (0*16777216) // LOCKED_BY_BILLING        
        // flags+= (0*33554432) // DECLINED     
        // flags+= (0*67108864) // UNKNOWN
        // flags+= (0*134217728) // UNKNOWN
        // flags+= (0*268435456) // UNKNOWN
        // flags+= (0*536870912) // UNKNOWN
        // flags+= (0*1073741824) // UNKNOWN
        // flags+= (0*2147483648) // UNKNOWN        

        return flags;
    }

    @Override
    public void encode(ByteBuf buf) throws Exception {
        // Packet structure:
        // 2b - 2b - 1b
        // Size (Little Endian) - Opcode (Big Endian) - number of characters 
        // If any character:
        // 8b - ?b - 1b - 1b - 1b - 1b - 1b - 1b - 1b - 1b - 1b - 4b - 4b - 4b - 4b - 4b - 4b - 1b - 4b - 4b - 4b 
        // GUID (Little Endian) - Name - Race - Class - Gender - Skin - Face - HairStyle - HairColor - FacialHair - level - zone - map - x - y - z - guild
        // char flags - first login - Pet id - Pet level - Pet Family
        // Then equipment: (19 pieces)
        // 4b - 1b
        // Item Display ID - Item Inventory Type
        // Then the bag
        // 4b - 1b
        // First bag display ID
        // First bag inventory type

        // TODO: 
        // - Guild membership
        // - Pet ID
        // - Pet Level
        // - Pet Family

        ItemService itemService = ItemServiceFactory.getInstance();
        ItemInstanceService iiService = new ItemInstanceService();

        buf.writeShort(this.size);
        buf.writeShort(this.code.getValue());
        buf.writeByte(this.numChars);

        for (Characters c : this.listChars) {
            buf = buf.order(ByteOrder.LITTLE_ENDIAN);
            buf.writeLong(c.getGuid());
            //buf = buf.order(ByteOrder.BIG_ENDIAN);
            ByteBufUtil.writeAscii(buf, c.getName());
            buf.writeByte((byte) 0); // End of string
            buf.writeByte(c.getRace());
            buf.writeByte(c.getFkDbcClass());
            buf.writeByte(c.getGender());
            buf.writeByte(c.getSkin());
            buf.writeByte(c.getFace());
            buf.writeByte(c.getHairstyle());
            buf.writeByte(c.getHaircolor());
            buf.writeByte(c.getFacialhair());
            buf.writeByte((byte) c.getLevel());
            buf.writeInt(c.getFkDbcZone());
            buf.writeInt(c.getFkDbcMap());
            buf.writeFloat((float) c.getPositionX()); // X
            buf.writeFloat((float) c.getPositionY()); // Y
            buf.writeFloat((float) c.getPositionZ()); // Z
            buf.writeInt(0); // Guild ID
            buf.writeInt(convertPlayersFlagsToInt(c)); // Char Flags            
            buf.writeByte(convertLoginFlagsToByte(c)); // First login
            buf.writeInt(0); // Pet ID
            buf.writeInt(0); // Pet Level
            buf.writeInt(0); // Pet family

            int count = 0;

            // We get the list of data for the equipment.
            for (Object data : iiService.getEquipmentCharEnum(c)) {
                Object[] itemInstance = (Object[]) data;
                int displayID = 0;
                byte inventoryType = 0;

                // We fill-in the data for the unoccupied slots.
                for (int i = count; i < Integer.parseInt(itemInstance[0].toString()); i++) {
                    buf.writeInt(displayID);
                    buf.writeByte(inventoryType);
                    count++;
                }

                // We add the occupied slot.
                Object[] item = itemService.getItemByIDCharEnum(Integer.parseInt(itemInstance[1].toString()));

                displayID = Integer.parseInt(item[0].toString());
                inventoryType = Byte.parseByte(item[1].toString());

                buf.writeInt(displayID);
                buf.writeByte(inventoryType);

                count++;
            }

            // We fill in the data for the end of the equipment slot.
            for (int i = count; i <= EQUIPMENT_SLOT_END; i++) {
                buf.writeInt(0);
                buf.writeByte(0);
            }

        }

    }
}