Ir para conteúdo
  • Cadastre-se

Ackerzin

Membro
  • Total de itens

    689
  • Registro em

  • Última visita

  • Dias Ganhos

    7

Posts postados por Ackerzin

  1. o !autoloot remove, não está removendo o item, aparece a mensagem dizendo que foi removido, mas quando você fala !autoloot list, o item continua la, e continua pegando ele, não da nenhum erro na distro.
    o item só é removido quando utilizo o comando !autoloot clear.
     

    14:09 AutoLoot-> Adicionados: Akatsuki Backpack. Erros: Nenhum.
    14:09 AutoLoot-> Removidos: Akatsuki Backpack. Erros: Nenhum.

     

  2. 9 minutos atrás, KR33 disse:

    Ele removeu a dll sprextractor, esse só acha a dat, os cara tava chorando no post dele, dai ele removeu pq aki so sai as dat dos cliente mas vlw.

    Não entendi oque você falou, mas a dll e o programa esta ali no post que te mandei, pra extrair os arquivos de dentro do .cab, basta voce jogar o cliente encima do Cabextractor.exe

  3. Olá, achei esse codigo em outro forum, ele foi desenvolvido para abrir o mapa do old cliente, mas ele foi feito para 1.2+, gostaria de saber se alguem poderia passar ele para 0.4.

    Spoiler
    
    <talkaction words="/minimap" separator=" " script="minimap_scan.lua" />
    
    
    
    
    local distanceBetweenPositionsX = 8
    local distanceBetweenPositionsY = 8
    local addEventDelay = 100
    local teleportsPerEvent = 3
    local maxEventExecutionTime = 1000
    
    local function teleportToClosestPosition(player, x, y, z)
       -- direct to position
       local tile = Tile(x, y, z)
    
       if not tile or not tile:getGround() or tile:hasFlag(TILESTATE_TELEPORT) or not player:teleportTo(tile:getPosition()) then
          for distance = 1, 3 do
             -- try to find some close tile
             for changeX = -distance, distance, distance do
                for changeY = -distance, distance, distance do
                   tile = Tile(x + changeX, y + changeY, z)
                   if tile and tile:getGround() and not tile:hasFlag(TILESTATE_TELEPORT) and player:teleportTo(tile:getPosition()) then
                      return true
                   end
                end
             end
          end
    
          return false
       end
    
       return true
    end
    
    local function sendScanProgress(player, minX, maxX, minY, maxY, x, y, z, lastProgress)
       local progress = math.floor(((y - minY + (((x - minX) / (maxX - minX)) * distanceBetweenPositionsY)) / (maxY - minY)) * 100)
       if progress ~= lastProgress then
          player:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, 'Scan progress: ~' .. progress .. '%')
       end
    
       return progress
    end
    
    local function minimapScan(cid, minX, maxX, minY, maxY, x, y, z, lastProgress)
       local player = Player(cid)
    
       if not player then
          --print('Minimap scan stopped - player logged out', cid, minX, maxX, minY, maxY, x, y, z)
          return
       end
    
       local scanStartTime = os.mtime()
       local teleportsDone = 0
       while true do
          if scanStartTime + maxEventExecutionTime < os.mtime() then
             lastProgress = sendScanProgress(player, minX, maxX, minY, maxY, x, y, z, lastProgress)
             addEvent(minimapScan, addEventDelay, cid, minX, maxX, minY, maxY, x, y, z, lastProgress)
             break
          end
    
          x = x + distanceBetweenPositionsX
          if x > maxX then
             x = minX
             y = y + distanceBetweenPositionsY
             if y > maxY then
                player:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, 'Scan finished: ' .. os.time())
                --print('Minimap scan complete', player:getName(), minX, maxX, minY, maxY, x, y, z)
                break
             end
          end
    
          if teleportToClosestPosition(player, x, y, z) then
             teleportsDone = teleportsDone + 1
             lastProgress = sendScanProgress(player, minX, maxX, minY, maxY, x, y, z, lastProgress)
    
             --print('Minimap scan teleport', player:getName(), minX, maxX, minY, maxY, x, y, z, progress, teleportsDone)
             if teleportsDone == teleportsPerEvent then
                addEvent(minimapScan, addEventDelay, cid, minX, maxX, minY, maxY, x, y, z, progress)
                break
             end
          end
       end
    end
    
    local function minimapStart(player, minX, maxX, minY, maxY, x, y, z)
       player:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, 'Scan started: ' .. os.time())
       --print('Minimap scan start', player:getName(), minX, maxX, minY, maxY, x, y, z)
       minimapScan(player:getId(), minX, maxX, minY, maxY, minX - 5, minY, z)
    end
    
    function onSay(player, words, param)
       if player:getGroup():getId() <= 4 then
          player:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, 'Only GOD can scan map. Too low Player group.')
          return false
       end
    
       if player:getAccountType() < ACCOUNT_TYPE_GAMEMASTER then
          player:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, 'Only GOD can scan map.Too low Account type.')
          return false
       end
    
       local positions = param:split(',')
       if #positions ~= 5 then
          player:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, 'Command requires 5 parameters: /minimap minX, maxX, minY, maxY, z')
          return false
       end
    
       for key, position in pairs(positions) do
          local value = tonumber(position)
    
          if not value then
             player:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, 'Invalid parameter ' .. key .. ': ' .. position)
             return false
          end
    
          positions[key] = value
       end
    
       minimapStart(player, positions[1], positions[2], positions[3], positions[4], positions[1] - distanceBetweenPositionsX, positions[3], positions[5])
       return false
    end

     


    crédito Gesior.pl

  4. 19 horas atrás, Cat disse:

     

     

    Para ativar transparência nessas versões precisa usar DLL.

    https://github.com/SaiyansKing/Tibia-Extended-Client-Library

    Nos entendemos a parte da dll, o problema é que não da para abrir ou salvar as sprites com aquele arquivo que você mandou, Tibia.otfi

    e se abrir sem esse arquivo e depois tentar salvar com a transparencia ativa, ele buga, nao salva.
    resumindo não conseguimos abrir o object builder com a opção transparencia ativa, e nem conseguimos salvar com a transparencia ativa.

  5. @Cat
    Então Nolis, estou tentando usar no 8.6, adicionei o Tibia.otfi  na pasta do cliente, e quando tento abrir da esses erros.

    Opções ativas, Estendido, Transparencia, Animaçoes melhoradas.
    Erro.
     

    Spoiler

    1.thumb.png.9a56352de89d112e89b582a60a35dbd0.png



    Opções ativas, Estendido, Transparencia.
    Erro.

    Spoiler

    2.thumb.png.ac0f264007ffe77863d4282617881667.png


    E quando abro apenas com Estendido, ele abre normalmente.
    e tambem consigo salvar ele normalmente, mas se eu ativar a opção "Transparencia" da esse erro.
     

    Spoiler

    3.thumb.png.0d27b6835af81deb65cbf551a43aae35.png



     

  6. 16 horas atrás, You Know Nothing disse:

    Olá pessoal!

     

    Estou montando um evento, e eu cheguei numa parte que não estou conseguindo realizar.

     

    A ideia é que, por exemplo tem uma alavanca, quando um player usar ela pela primeira vez, começará uma contagem de tempo, que será usada no final do evento para ver quem esteve com essa storage por mais tempo e assim vencer.

     

    Então se esse player 1 usou a alavanca começou a contagem de tempo dele, caso vier um player 2 e usar a mesma alavanca a contagem de tempo do player 1 vai pausar e vai se iniciar a contagem do player 2 , e assim seja quantos players vierem usar a alavanca.

    Caso o player 1 conseguir usar a alavanca novamente, a contagem dele que antes tinha sido pausada, vai voltar e continuar com o tempo que ele já tinha antes do player 2 pegar dele.

     

    E se possível no final eu poder apresentar qual foi o top 5 players com mais tempo dessa storage.

    Seria para um servidor 8.6, em otxserver.

     

    Obrigado a todos que leram até aquiiii e se puder me dar uma força com isso, que Deus te abençoa.

     

    Att,

     

     

    9 horas atrás, Vodkart disse:

    #Resolvido via Discord TK!

     

    Foi modificado action/lib e criado talkactions + função que retorna em tempo real o tempo, exemplo da alavanca + rank em tempo real em uso (para teste)

     

    unknown.png

     

     

    e depois final do evento (teste)

     

    unknown.png

     



    Vocês podem postar isso para nos, meros mortais? <3

  7. 20 minutos atrás, xWhiteWolf disse:

    Alguem me explica pq o Vodkart tem 7 awards e eu só tenho 5 sendo mostradas (sendo que tenho 6) @Cat


    Vodkart:                                   xWhiteWolf
    image.png.73ddeac83abae5eb30aad00ba7fe03a6.pngimage.png.9de6979562266e55ff319116a5b220d8.png

    image.png


    Porque Deus quis assim, e se reclamar, vou lhe dar ban

  8. Em 01/11/2020 em 23:22, joaopedrodepaiva disse:

    Salve rapaziada, bom dia. Estou com um problema ao tentar adicionar um código que deixa a vida e mana por porcentagem.

    Estou usando ESSA TFS 0.4.

    Topico do codigo Vida e Mana em porcentagem.

     

    Erros que acontecem ao tentar compilar:

      Mostrar conteúdo oculto

    ||=== TheForgottenServer, default ===|
    C:\Users\Joaop\Desktop\CRIACAO\Baiak High Exp\source\source\protocolgame.cpp||In member function 'void ProtocolGame::AddPlayerStats(NetworkMessage_ptr)':|
    C:\Users\Joaop\Desktop\CRIACAO\Baiak High Exp\source\source\protocolgame.cpp|2932|error: 'class NetworkMessage' has no member named 'AddByte'|
    C:\Users\Joaop\Desktop\CRIACAO\Baiak High Exp\source\source\protocolgame.cpp|2935|error: 'class NetworkMessage' has no member named 'AddU16'|
    C:\Users\Joaop\Desktop\CRIACAO\Baiak High Exp\source\source\protocolgame.cpp|2936|error: 'class NetworkMessage' has no member named 'AddU16'|
    C:\Users\Joaop\Desktop\CRIACAO\Baiak High Exp\source\source\protocolgame.cpp|2940|error: 'class NetworkMessage' has no member named 'AddU16'|
    C:\Users\Joaop\Desktop\CRIACAO\Baiak High Exp\source\source\protocolgame.cpp|2941|error: 'class NetworkMessage' has no member named 'AddU16'|
    C:\Users\Joaop\Desktop\CRIACAO\Baiak High Exp\source\source\protocolgame.cpp|2943|error: 'class NetworkMessage' has no member named 'AddU32'|
    C:\Users\Joaop\Desktop\CRIACAO\Baiak High Exp\source\source\protocolgame.cpp|2946|error: 'class NetworkMessage' has no member named 'AddU32'|
    C:\Users\Joaop\Desktop\CRIACAO\Baiak High Exp\source\source\protocolgame.cpp|2948|error: 'class NetworkMessage' has no member named 'AddU32'|
    C:\Users\Joaop\Desktop\CRIACAO\Baiak High Exp\source\source\protocolgame.cpp|2950|error: 'class NetworkMessage' has no member named 'AddU16'|
    C:\Users\Joaop\Desktop\CRIACAO\Baiak High Exp\source\source\protocolgame.cpp|2951|error: 'class NetworkMessage' has no member named 'AddByte'|
    C:\Users\Joaop\Desktop\CRIACAO\Baiak High Exp\source\source\protocolgame.cpp|2954|error: 'class NetworkMessage' has no member named 'AddU16'|
    C:\Users\Joaop\Desktop\CRIACAO\Baiak High Exp\source\source\protocolgame.cpp|2955|error: 'class NetworkMessage' has no member named 'AddU16'|
    C:\Users\Joaop\Desktop\CRIACAO\Baiak High Exp\source\source\protocolgame.cpp|2959|error: 'class NetworkMessage' has no member named 'AddU16'|
    C:\Users\Joaop\Desktop\CRIACAO\Baiak High Exp\source\source\protocolgame.cpp|2960|error: 'class NetworkMessage' has no member named 'AddU16'|
    C:\Users\Joaop\Desktop\CRIACAO\Baiak High Exp\source\source\protocolgame.cpp|2962|error: 'class NetworkMessage' has no member named 'AddByte'|
    C:\Users\Joaop\Desktop\CRIACAO\Baiak High Exp\source\source\protocolgame.cpp|2963|error: 'class NetworkMessage' has no member named 'AddByte'|
    C:\Users\Joaop\Desktop\CRIACAO\Baiak High Exp\source\source\protocolgame.cpp|2964|error: 'class NetworkMessage' has no member named 'AddByte'|
    C:\Users\Joaop\Desktop\CRIACAO\Baiak High Exp\source\source\protocolgame.cpp|2965|error: 'class NetworkMessage' has no member named 'AddU16'|
    ||=== Build finished: 18 errors, 0 warnings ===|
     

     

    Meu protocolgame.cpp:

     

      Mostrar conteúdo oculto

    ////////////////////////////////////////////////////////////////////////
    // OpenTibia - an opensource roleplaying game
    ////////////////////////////////////////////////////////////////////////
    // 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/>.
    ////////////////////////////////////////////////////////////////////////
    #include "otpch.h"
    #include <boost/function.hpp>
    #include <iostream>

    #include "protocolgame.h"
    #include "textlogger.h"

    #include "waitlist.h"
    #include "player.h"

    #include "connection.h"
    #include "networkmessage.h"
    #include "outputmessage.h"

    #include "iologindata.h"
    #include "ioban.h"

    #include "items.h"
    #include "tile.h"
    #include "house.h"

    #include "actions.h"
    #include "creatureevent.h"
    #include "quests.h"

    #include "chat.h"
    #include "configmanager.h"
    #include "game.h"

    extern Game g_game;
    extern ConfigManager g_config;
    extern Actions actions;
    extern CreatureEvents* g_creatureEvents;
    extern Chat g_chat;

    template<class FunctionType>
    void ProtocolGame::addGameTaskInternal(uint32_t delay, const FunctionType& func)
    {
        if(delay > 0)
            Dispatcher::getInstance().addTask(createTask(delay, func));
        else
            Dispatcher::getInstance().addTask(createTask(func));
    }

    #ifdef __ENABLE_SERVER_DIAGNOSTIC__
    uint32_t ProtocolGame::protocolGameCount = 0;
    #endif

    void ProtocolGame::setPlayer(Player* p)
    {
        player = p;
    }

    void ProtocolGame::releaseProtocol()
    {
        if(player && player->client == this)
            player->client = NULL;

        Protocol::releaseProtocol();
    }

    void ProtocolGame::deleteProtocolTask()
    {
        if(player)
        {
            g_game.freeThing(player);
            player = NULL;
        }

        Protocol::deleteProtocolTask();
    }

    bool ProtocolGame::login(const std::string& name, uint32_t id, const std::string&,
        OperatingSystem_t operatingSystem, uint16_t version, bool gamemaster, bool castAccount)
    {
        //dispatcher thread
        PlayerVector players = g_game.getPlayersByName(name);
        Player* _player = NULL;
        if(!players.empty())
            _player = players[random_range(0, (players.size() - 1))];

        if((!_player || name == "Account Manager" || g_config.getNumber(ConfigManager::ALLOW_CLONES) > (int32_t)players.size()) && !castAccount)
        {
            isCast = false; //CAST
            player = new Player(name, this);
            player->addRef();

            player->setID();
            if(!IOLoginData::getInstance()->loadPlayer(player, name, true))
            {
                disconnectClient(0x14, "Your character could not be loaded.");
                return false;
            }

            Ban ban;
            ban.value = player->getID();
            ban.param = PLAYERBAN_BANISHMENT;

            ban.type = BAN_PLAYER;
            if(IOBan::getInstance()->getData(ban) && !player->hasFlag(PlayerFlag_CannotBeBanned))
            {
                bool deletion = ban.expires < 0;
                std::string name_ = "Automático ";
                if(!ban.adminId)
                    name_ += (deletion ? "deletion" : "banishment");
                else
                    IOLoginData::getInstance()->getNameByGuid(ban.adminId, name_, true);

                char buffer[500 + ban.comment.length()];
                sprintf(buffer, "Your character has been %s at:\n%s by: %s,\nfor the following reason:\n%s.\nThe action taken was:\n%s.\nThe comment given was:\n%s.\nYour %s%s.",
                    (deletion ? "deleted" : "banished"), formatDateEx(ban.added, "%d %b %Y").c_str(), name_.c_str(),
                    getReason(ban.reason).c_str(), getAction(ban.action, false).c_str(), ban.comment.c_str(),
                    (deletion ? "character won't be undeleted" : "banishment will be lifted at:\n"),
                    (deletion ? "" : formatDateEx(ban.expires).c_str()));

                disconnectClient(0x14, buffer);
                return false;
            }

            if(IOBan::getInstance()->isPlayerBanished(player->getGUID(), PLAYERBAN_LOCK) && id != 1)
            {
                if(g_config.getBool(ConfigManager::NAMELOCK_MANAGER))
                {
                    player->name = "Account Manager";
                    player->accountManager = MANAGER_NAMELOCK;

                    player->managerNumber = id;
                    player->managerString2 = name;
                }
                else
                {
                    disconnectClient(0x14, "Your character has been namelocked.");
                    return false;
                }
            }
            else if(player->getName() == "Account Manager")
            {
                if(!g_config.getBool(ConfigManager::ACCOUNT_MANAGER))
                {
                    disconnectClient(0x14, "Account Manager is disabled.");
                    return false;
                }

                if(id != 1)
                {
                    player->accountManager = MANAGER_ACCOUNT;
                    player->managerNumber = id;
                }
                else
                    player->accountManager = MANAGER_NEW;
            }

            if(gamemaster && !player->hasCustomFlag(PlayerCustomFlag_GamemasterPrivileges))
            {
                disconnectClient(0x14, "You are not a gamemaster! Turn off the gamemaster mode in your IP changer.");
                return false;
            }

            if(!player->hasFlag(PlayerFlag_CanAlwaysLogin))
            {
                if(g_game.getGameState() == GAMESTATE_CLOSING)
                {
                    disconnectClient(0x14, "Gameworld is just going down, please come back later.");
                    return false;
                }

                if(g_game.getGameState() == GAMESTATE_CLOSED)
                {
                    disconnectClient(0x14, "Gameworld is currently closed, please come back later.");
                    return false;
                }
            }

            if(g_config.getBool(ConfigManager::ONE_PLAYER_ON_ACCOUNT) && !player->isAccountManager() &&
                !IOLoginData::getInstance()->hasCustomFlag(id, PlayerCustomFlag_CanLoginMultipleCharacters))
            {
                bool found = false;
                PlayerVector tmp = g_game.getPlayersByAccount(id);
                for(PlayerVector::iterator it = tmp.begin(); it != tmp.end(); ++it)
                {
                    if((*it)->getName() != name)
                        continue;

                    found = true;
                    break;
                }

                if(tmp.size() > 0 && !found)
                {
                    disconnectClient(0x14, "You may only login with one character\nof your account at the same time.");
                    return false;
                }
            }

            if(!WaitingList::getInstance()->login(player))
            {
                if(OutputMessage_ptr output = OutputMessagePool::getInstance()->getOutputMessage(this, false))
                {
                    TRACK_MESSAGE(output);
                    std::stringstream ss;
                    ss << "Too many players online.\n" << "You are ";

                    int32_t slot = WaitingList::getInstance()->getSlot(player);
                    if(slot)
                    {
                        ss << "at ";
                        if(slot > 0)
                            ss << slot;
                        else
                            ss << "unknown";

                        ss << " place on the waiting list.";
                    }
                    else
                        ss << "awaiting connection...";

                    output->put<char>(0x16);
                    output->putString(ss.str());
                    output->put<char>(WaitingList::getTime(slot));
                    OutputMessagePool::getInstance()->send(output);
                }

                getConnection()->close();
                return false;
            }

            if(!IOLoginData::getInstance()->loadPlayer(player, name))
            {
                disconnectClient(0x14, "Your character could not be loaded.");
                return false;
            }

            player->setClientVersion(version);
            player->setOperatingSystem(operatingSystem);
            if(!g_game.placeCreature(player, player->getLoginPosition()) && !g_game.placeCreature(player, player->getMasterPosition(), false, true))
            {
                disconnectClient(0x14, "Temple position is wrong. Contact with the administration..");
                return false;
            }

            if(player->isUsingOtclient())
                player->registerCreatureEvent("ExtendedOpcode"); //OTC

            player->lastIP = player->getIP();
            player->lastLoad = OTSYS_TIME();
            player->lastLogin = std::max(time(NULL), player->lastLogin + 1);

            m_acceptPackets = true;
            return true;
        }

        if(gamemaster && !_player->hasCustomFlag(PlayerCustomFlag_GamemasterPrivileges))
        {
            disconnectClient(0x14, "You are not a gamemaster! Turn off the gamemaster mode in your IP changer.");
            return false;
        }

        if(_player->client)
        {
            if((m_eventConnect || !g_config.getBool(ConfigManager::REPLACE_KICK_ON_LOGIN)) && !castAccount) //CAST
            {
                //A task has already been scheduled just bail out (should not be overriden)
                disconnectClient(0x14, "You are already logged in.");
                return false;
            }

            if(!castAccount) {
                g_chat.removeUserFromAllChannels(_player);
                _player->disconnect();
                _player->isConnecting = true;
            }

            addRef();
            if(!castAccount)
                m_eventConnect = Scheduler::getInstance().addEvent(createSchedulerTask(
                    1000, boost::bind(&ProtocolGame::connect, this, _player->getID(), operatingSystem, version, castAccount)));
            else
                connect(_player->getID(), operatingSystem, version, castAccount);
            return true;
        }

        addRef();
        return connect(_player->getID(), operatingSystem, version, castAccount);
    }

    bool ProtocolGame::logout(bool displayEffect, bool forceLogout)
    {
        //dispatcher thread
        if(!player)
            return false;

        if(getIsCast() && !player->isAccountManager()) {
            PlayerCast pc = player->getCast();
            for(AutoList<ProtocolGame>::iterator it = Player::cSpectators.begin(); it != Player::cSpectators.end(); ++it) //CAST
                if(it->second == this)
                    if(Connection_ptr connection = it->second->getConnection()) {
                        PrivateChatChannel* channel = g_chat.getPrivateChannel(player);
                        if(channel) {
                            channel->talk("", SPEAK_CHANNEL_RA, (getViewerName() + " deixou o cast."));
                        }

                        connection->close();
                        player->removeCastViewer(it->first);
                    }
            return false;
        }

        if(!player->isRemoved())
        {
            if(!forceLogout)
            {
                if(!IOLoginData::getInstance()->hasCustomFlag(player->getAccount(), PlayerCustomFlag_CanLogoutAnytime))
                {
                    if(player->getTile()->hasFlag(TILESTATE_NOLOGOUT))
                    {
                        player->sendCancelMessage(RET_YOUCANNOTLOGOUTHERE);
                        return false;
                    }

                    //if(player->hasCondition(CONDITION_INFIGHT))
                    if(player->getZone() != ZONE_PROTECTION && player->hasCondition(CONDITION_INFIGHT))
                    {
                        player->sendCancelMessage(RET_YOUMAYNOTLOGOUTDURINGAFIGHT);
                        return false;
                    }

                    if(!g_creatureEvents->playerLogout(player, false)) //let the script handle the error message
                        return false;
                }
                else
                    g_creatureEvents->playerLogout(player, true);
            }
            else if(!g_creatureEvents->playerLogout(player, true))
                return false;

            if(displayEffect && !player->isGhost())
                g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF);
        }

        player->kickCastViewers(); //CAST

        if(Connection_ptr connection = getConnection())
            connection->close();

        if(player->isRemoved())
            return true;

        return g_game.removeCreature(player);
    }

    bool ProtocolGame::connect(uint32_t playerId, OperatingSystem_t operatingSystem, uint16_t version, bool castAccount)
    {
        if(!castAccount)
            unRef();

        m_eventConnect = 0;

        Player* _player = g_game.getPlayerByID(playerId);
        if(castAccount) {  //CAST
            PlayerCast pc = _player->getCast();
            for(std::list<CastBan>::iterator it = pc.bans.begin(); it != pc.bans.end(); ++it)
                if(it->ip == getIP()) {
                    disconnectClient(0x14, "You are banned from this cast.");
                    return false;
                }

            if(_player->getCastViewerCount() >= 50) {
                disconnectClient(0x14, "The cast reached the maximum viewer limit (50).");
                return false;
            }

            player = _player;
            player->addRef();
            m_acceptPackets = true;
            isCast = true;
            player->addCastViewer(this);
            sendAddCreature(_player, _player->getPosition(), _player->getTile()->getClientIndexOfThing(_player, _player));

            PrivateChatChannel* channel = g_chat.getPrivateChannel(_player);
            if(channel) {
                sendCreatePrivateChannel(channel->getId(), channel->getName());
                channel->talk("", SPEAK_CHANNEL_RA, (getViewerName() + " has joined the cast."));
                sendCreatureSay(player, SPEAK_PRIVATE, "Cast communication is turned on.");
            }
            else
                sendCreatureSay(player, SPEAK_PRIVATE, "Cast communication is turned off.");
            return true;
        }

        if(!_player || _player->isRemoved() || _player->client)
        {
            disconnectClient(0x14, "You are already logged in.");
            return false;
        }

        isCast = false;
        player = _player;
        player->addRef();
        player->client = this;
        player->isConnecting = false;

        player->sendCreatureAppear(player);
        player->setOperatingSystem(operatingSystem);
        player->setClientVersion(version);

        player->lastIP = player->getIP();
        player->lastLoad = OTSYS_TIME();
        player->lastLogin = std::max(time(NULL), player->lastLogin + 1);

        m_acceptPackets = true;
        return true;
    }

    void ProtocolGame::disconnect()
    {
        if(getConnection())
            getConnection()->close();
    }

    void ProtocolGame::disconnectClient(uint8_t error, const char* message)
    {
        if(OutputMessage_ptr output = OutputMessagePool::getInstance()->getOutputMessage(this, false))
        {
            TRACK_MESSAGE(output);
            output->put<char>(error);
            output->putString(message);
            OutputMessagePool::getInstance()->send(output);
        }

        disconnect();
    }

    void ProtocolGame::onConnect()
    {
        if(OutputMessage_ptr output = OutputMessagePool::getInstance()->getOutputMessage(this, false))
        {
            TRACK_MESSAGE(output);
            enableChecksum();

            output->put<char>(0x1F);
            output->put<uint16_t>(random_range(0, 0xFFFF));
            output->put<uint16_t>(0x00);
            output->put<char>(random_range(0, 0xFF));

            OutputMessagePool::getInstance()->send(output);
        }
    }

    void ProtocolGame::onRecvFirstMessage(NetworkMessage& msg)
    {
        parseFirstPacket(msg);
    }

    bool ProtocolGame::parseFirstPacket(NetworkMessage& msg)
    {
        if(g_game.getGameState() == GAMESTATE_SHUTDOWN)
        {
            getConnection()->close();
            return false;
        }

        OperatingSystem_t operatingSystem = (OperatingSystem_t)msg.get<uint16_t>();
        uint16_t version = msg.get<uint16_t>();
        if(!RSA_decrypt(msg))
        {
            getConnection()->close();
            return false;
        }

        uint32_t key[4] = {msg.get<uint32_t>(), msg.get<uint32_t>(), msg.get<uint32_t>(), msg.get<uint32_t>()};
        enableXTEAEncryption();
        setXTEAKey(key);
        // notifica o otclient que este servidor pode receber opcodes de protocolo de jogo estendido
       if(operatingSystem >= CLIENTOS_OTCLIENT_LINUX)
       sendExtendedOpcode(0x00, std::string());

        bool gamemaster = msg.get<char>();
        std::string name = msg.getString(), character = msg.getString(), password = msg.getString();

        msg.skip(6); //841- wtf?
        if(!g_config.getBool(ConfigManager::MANUAL_ADVANCED_CONFIG))
        {
            if(version < CLIENT_VERSION_MIN || version > CLIENT_VERSION_MAX)
            {
                disconnectClient(0x14, CLIENT_VERSION_STRING);
                return false;
            }
        else
            if(version < g_config.getNumber(ConfigManager::VERSION_MIN) || version > g_config.getNumber(ConfigManager::VERSION_MAX))
            {
                disconnectClient(0x14, g_config.getString(ConfigManager::VERSION_MSG).c_str());
                return false;
            }
        }

        bool castAccount = false;
        if(name.empty()) //CAST
        {
            if(g_config.getBool(ConfigManager::ENABLE_CAST))
                castAccount = true;
             else {
            if(!g_config.getBool(ConfigManager::ACCOUNT_MANAGER))
            {
                disconnectClient(0x14, "Invalid account name.");
                return false;
            }

            name = "1";
            password = "1";
            }
        }

        if(g_game.getGameState() < GAMESTATE_NORMAL)
        {
            disconnectClient(0x14, "Gameworld is just starting up, please wait.");
            return false;
        }

        if(g_game.getGameState() == GAMESTATE_MAINTAIN)
        {
            disconnectClient(0x14, "Gameworld is under maintenance, please re-connect in a while.");
            return false;
        }

        if(ConnectionManager::getInstance()->isDisabled(getIP(), protocolId))
        {
            disconnectClient(0x14, "Too many connections attempts from your IP address, please try again later.");
            return false;
        }

        if(IOBan::getInstance()->isIpBanished(getIP()))
        {
            disconnectClient(0x14, "Your IP is banished!");
            return false;
        }

        uint32_t id = 1;
        if(!IOLoginData::getInstance()->getAccountId(name, id) && !castAccount) //CAST
        {
            ConnectionManager::getInstance()->addAttempt(getIP(), protocolId, false);
            disconnectClient(0x14, "Invalid account name.");
            return false;
        }

        if (castAccount) { //CAST
            bool found = false;

            if(Player::castAutoList.empty()) {
                ConnectionManager::getInstance()->addAttempt(getIP(), protocolId, false);
                disconnectClient(0x14, "Cast not found.\nPlease refresh your login list.");
                return false;
            }

            for(AutoList<Player>::iterator it = Player::castAutoList.begin(); it != Player::castAutoList.end(); ++it)
            {
                if (it->second->getName() == character) {
                    found = true;
                    if(it->second->getCastingPassword() != "" && it->second->getCastingPassword() != password) {
                        ConnectionManager::getInstance()->addAttempt(getIP(), protocolId, false);
                        disconnectClient(0x14, "Wrong password to protected cast.");
                        return false;
                    }
                }
            }

            if(!found) {
                ConnectionManager::getInstance()->addAttempt(getIP(), protocolId, false);
                disconnectClient(0x14, "Cast not found.\nPlease refresh your login list.");
                return false;
            }
        }

        //std::string hash, salt;
        //if((!IOLoginData::getInstance()->getPassword(id, hash, salt, character) || !encryptTest(salt + password, hash)) && !castAccount) //CAST
        std::string hash;
        if((!IOLoginData::getInstance()->getPassword(id, hash, character) || !encryptTest(password, hash)) && !castAccount)
        {
            ConnectionManager::getInstance()->addAttempt(getIP(), protocolId, false);
            disconnectClient(0x14, "Invalid password.");
            return false;
        }

        Ban ban;
        ban.value = id;

        ban.type = BAN_ACCOUNT;
        if(IOBan::getInstance()->getData(ban) && !IOLoginData::getInstance()->hasFlag(id, PlayerFlag_CannotBeBanned))
        {
            bool deletion = ban.expires < 0;
            std::string name_ = "Automatic ";
            if(!ban.adminId)
                name_ += (deletion ? "deletion" : "banishment");
            else
                IOLoginData::getInstance()->getNameByGuid(ban.adminId, name_, true);

            char buffer[500 + ban.comment.length()];
            sprintf(buffer, "Your account has been %s at:\n%s by: %s,\nfor the following reason:\n%s.\nThe action taken was:\n%s.\nThe comment given was:\n%s.\nYour %s%s.",
                (deletion ? "deleted" : "banished"), formatDateEx(ban.added, "%d %b %Y").c_str(), name_.c_str(),
                getReason(ban.reason).c_str(), getAction(ban.action, false).c_str(), ban.comment.c_str(),
                (deletion ? "account won't be undeleted" : "banishment will be lifted at:\n"),
                (deletion ? "" : formatDateEx(ban.expires).c_str()));

            disconnectClient(0x14, buffer);
            return false;
        }

        ConnectionManager::getInstance()->addAttempt(getIP(), protocolId, true);
        Dispatcher::getInstance().addTask(createTask(boost::bind(
            &ProtocolGame::login, this, character, id, password, operatingSystem, version, gamemaster, castAccount)));
        return true;
    }

    void ProtocolGame::parsePacket(NetworkMessage &msg)
    {
        if(!player || !m_acceptPackets || g_game.getGameState() == GAMESTATE_SHUTDOWN || msg.size() <= 0)
            return;

        uint32_t now = time(NULL);
        if(m_packetTime != now)
        {
            m_packetTime = now;
            m_packetCount = 0;
        }

        ++m_packetCount;
        if(m_packetCount > (uint32_t)g_config.getNumber(ConfigManager::MAX_PACKETS_PER_SECOND))
            return;

        uint8_t recvbyte = msg.get<char>();
        //a dead player cannot performs actions
        if(player->isRemoved() && recvbyte != 0x14)
            return;

        if(isCast && !player->isAccountManager()) { //CAST
            switch(recvbyte)
            {
                case 0x14:
                    parseLogout(msg);
                    break;

                case 0x96:
                    parseSay(msg);
                    break;

                case 0x1E:
                    parseReceivePing(msg);
                    break;

                case 0x97: // request channels
                    parseGetChannels(msg);
                    break;

                case 0xAA:
                    parseCreatePrivateChannel(msg);
                    break;

                default:
                    sendCancelWalk();
                    break;
            }
        }
        else if(player->isAccountManager())
        {
            switch(recvbyte)
            {
                case 0x14:
                    parseLogout(msg);
                    break;

                case 0x96:
                    parseSay(msg);
                    break;

                default:
                    sendCancelWalk();
                    break;
            }
        }
        else
        {
            switch(recvbyte)
            {
                case 0x14: // logout
                    parseLogout(msg);
                    break;

                case 0x1E: // keep alive / ping response
                    parseReceivePing(msg);
                    break;

                case 0x32: // otclient extended opcode
                    parseExtendedOpcode(msg);
                    break;

                case 0x64: // move with steps
                    parseAutoWalk(msg);
                    break;

                case 0x65: // move north
                case 0x66: // move east
                case 0x67: // move south
                case 0x68: // move west
                    parseMove(msg, (Direction)(recvbyte - 0x65));
                    break;

                case 0x69: // stop-autowalk
                    addGameTask(&Game::playerStopAutoWalk, player->getID());
                    break;

                case 0x6A:
                    parseMove(msg, NORTHEAST);
                    break;

                case 0x6B:
                    parseMove(msg, SOUTHEAST);
                    break;

                case 0x6C:
                    parseMove(msg, SOUTHWEST);
                    break;

                case 0x6D:
                    parseMove(msg, NORTHWEST);
                    break;

                case 0x6F: // turn north
                case 0x70: // turn east
                case 0x71: // turn south
                case 0x72: // turn west
                    parseTurn(msg, (Direction)(recvbyte - 0x6F));
                    break;

                case 0x78: // throw item
                    parseThrow(msg);
                    break;

                case 0x79: // description in shop window
                    parseLookInShop(msg);
                    break;

                case 0x7A: // player bought from shop
                    parsePlayerPurchase(msg);
                    break;

                case 0x7B: // player sold to shop
                    parsePlayerSale(msg);
                    break;

                case 0x7C: // player closed shop window
                    parseCloseShop(msg);
                    break;

                case 0x7D: // Request trade
                    parseRequestTrade(msg);
                    break;

                case 0x7E: // Look at an item in trade
                    parseLookInTrade(msg);
                    break;

                case 0x7F: // Accept trade
                    parseAcceptTrade(msg);
                    break;

                case 0x80: // close/cancel trade
                    parseCloseTrade();
                    break;

                case 0x82: // use item
                    parseUseItem(msg);
                    break;

                case 0x83: // use item
                    parseUseItemEx(msg);
                    break;

                case 0x84: // battle window
                    parseBattleWindow(msg);
                    break;

                case 0x85: //rotate item
                    parseRotateItem(msg);
                    break;

                case 0x87: // close container
                    parseCloseContainer(msg);
                    break;

                case 0x88: //"up-arrow" - container
                    parseUpArrowContainer(msg);
                    break;

                case 0x89:
                    parseTextWindow(msg);
                    break;

                case 0x8A:
                    parseHouseWindow(msg);
                    break;

                case 0x8C: // throw item
                    parseLookAt(msg);
                    break;

                case 0x96: // say something
                    parseSay(msg);
                    break;

                case 0x97: // request channels
                    parseGetChannels(msg);
                    break;

                case 0x98: // open channel
                    parseOpenChannel(msg);
                    break;

                case 0x99: // close channel
                    parseCloseChannel(msg);
                    break;

                case 0x9A: // open priv
                    parseOpenPriv(msg);
                    break;

                case 0x9B: //process report
                    parseProcessRuleViolation(msg);
                    break;

                case 0x9C: //gm closes report
                    parseCloseRuleViolation(msg);
                    break;

                case 0x9D: //player cancels report
                    parseCancelRuleViolation(msg);
                    break;

                case 0x9E: // close NPC
                    parseCloseNpc(msg);
                    break;

                case 0xA0: // set attack and follow mode
                    parseFightModes(msg);
                    break;

                case 0xA1: // attack
                    parseAttack(msg);
                    break;

                case 0xA2: //follow
                    parseFollow(msg);
                    break;

                case 0xA3: // invite party
                    parseInviteToParty(msg);
                    break;

                case 0xA4: // join party
                    parseJoinParty(msg);
                    break;

                case 0xA5: // revoke party
                    parseRevokePartyInvite(msg);
                    break;

                case 0xA6: // pass leadership
                    parsePassPartyLeadership(msg);
                    break;

                case 0xA7: // leave party
                    parseLeaveParty(msg);
                    break;

                case 0xA8: // share exp
                    parseSharePartyExperience(msg);
                    break;

                case 0xAA:
                    parseCreatePrivateChannel(msg);
                    break;

                case 0xAB:
                    parseChannelInvite(msg);
                    break;

                case 0xAC:
                    parseChannelExclude(msg);
                    break;

                case 0xBE: // cancel move
                    parseCancelMove(msg);
                    break;

                case 0xC9: //client request to resend the tile
                    parseUpdateTile(msg);
                    break;

                case 0xCA: //client request to resend the container (happens when you store more than container maxsize)
                    parseUpdateContainer(msg);
                    break;

                case 0xD2: // request outfit
                    if((!player->hasCustomFlag(PlayerCustomFlag_GamemasterPrivileges) || !g_config.getBool(
                        ConfigManager::DISABLE_OUTFITS_PRIVILEGED)) && (g_config.getBool(ConfigManager::ALLOW_CHANGEOUTFIT)
                        || g_config.getBool(ConfigManager::ALLOW_CHANGECOLORS) || g_config.getBool(ConfigManager::ALLOW_CHANGEADDONS)))
                        parseRequestOutfit(msg);
                    break;

                case 0xD3: // set outfit
                    if((!player->hasCustomFlag(PlayerCustomFlag_GamemasterPrivileges) || !g_config.getBool(ConfigManager::DISABLE_OUTFITS_PRIVILEGED))
                        && (g_config.getBool(ConfigManager::ALLOW_CHANGECOLORS) || g_config.getBool(ConfigManager::ALLOW_CHANGEOUTFIT)))
                    parseSetOutfit(msg);
                    break;

                case 0xDC:
                    parseAddVip(msg);
                    break;

                case 0xDD:
                    parseRemoveVip(msg);
                    break;

                case 0xE6:
                    parseBugReport(msg);
                    break;

                case 0xE7:
                    parseViolationWindow(msg);
                    break;

                case 0xE8:
                    parseDebugAssert(msg);
                    break;

                case 0xF0:
                    parseQuests(msg);
                    break;

                case 0xF1:
                    parseQuestInfo(msg);
                    break;

                case 0xF2:
                    parseViolationReport(msg);
                    break;

                default:
                {
                    if(g_config.getBool(ConfigManager::BAN_UNKNOWN_BYTES))
                    {
                        int64_t banTime = -1;
                        ViolationAction_t action = ACTION_BANISHMENT;
                        Account tmp = IOLoginData::getInstance()->loadAccount(player->getAccount(), true);

                        tmp.warnings++;
                        if(tmp.warnings >= g_config.getNumber(ConfigManager::WARNINGS_TO_DELETION))
                            action = ACTION_DELETION;
                        else if(tmp.warnings >= g_config.getNumber(ConfigManager::WARNINGS_TO_FINALBAN))
                        {
                            banTime = time(NULL) + g_config.getNumber(ConfigManager::FINALBAN_LENGTH);
                            action = ACTION_BANFINAL;
                        }
                        else
                            banTime = time(NULL) + g_config.getNumber(ConfigManager::BAN_LENGTH);

                        if(IOBan::getInstance()->addAccountBanishment(tmp.number, banTime, 13, action,
                            "Sending unknown packets to the server.", 0, player->getGUID()))
                        {
                            IOLoginData::getInstance()->saveAccount(tmp);
                            player->sendTextMessage(MSG_INFO_DESCR, "You have been banished.");

                            g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_WRAPS_GREEN);
                            Scheduler::getInstance().addEvent(createSchedulerTask(1000, boost::bind(
                                &Game::kickPlayer, &g_game, player->getID(), false)));
                        }
                    }

                    std::stringstream hex;
                    hex << "0x" << std::hex << (int16_t)recvbyte << std::dec;
                    Logger::getInstance()->eFile(getFilePath(FILE_TYPE_LOG, "bots/" + player->getName() + ".log").c_str(),
                        "[" + formatDate() + "] Received byte " + hex.str(), false);
                    break;
                }
            }
        }
    }

    void ProtocolGame::GetTileDescription(const Tile* tile, NetworkMessage_ptr msg)
    {
        if(!tile)
            return;

        int32_t count = 0;
        if(tile->ground)
        {
            msg->putItem(tile->ground);
            count++;
        }

        const TileItemVector* items = tile->getItemList();
        const CreatureVector* creatures = tile->getCreatures();

        ItemVector::const_iterator it;
        if(items)
        {
            for(it = items->getBeginTopItem(); (it != items->getEndTopItem() && count < 10); ++it, ++count)
                msg->putItem(*it);
        }

        if(creatures)
        {
            for(CreatureVector::const_reverse_iterator cit = creatures->rbegin(); (cit != creatures->rend() && count < 10); ++cit)
            {
                if(!player->canSeeCreature(*cit))
                    continue;

                bool known;
                uint32_t removedKnown;
                checkCreatureAsKnown((*cit)->getID(), known, removedKnown);

                AddCreature(msg, (*cit), known, removedKnown);
                count++;
            }
        }

        if(items)
        {
            for(it = items->getBeginDownItem(); (it != items->getEndDownItem() && count < 10); ++it, ++count)
                msg->putItem(*it);
        }
    }

    void ProtocolGame::GetMapDescription(int32_t x, int32_t y, int32_t z,
        int32_t width, int32_t height, NetworkMessage_ptr msg)
    {
        int32_t skip = -1, startz, endz, zstep = 0;
        if(z > 7)
        {
            startz = z - 2;
            endz = std::min((int32_t)MAP_MAX_LAYERS - 1, z + 2);
            zstep = 1;
        }
        else
        {
            startz = 7;
            endz = 0;
            zstep = -1;
        }

        for(int32_t nz = startz; nz != endz + zstep; nz += zstep)
            GetFloorDescription(msg, x, y, nz, width, height, z - nz, skip);

        if(skip >= 0)
        {
            msg->put<char>(skip);
            msg->put<char>(0xFF);
            //cc += skip;
        }
    }

    void ProtocolGame::GetFloorDescription(NetworkMessage_ptr msg, int32_t x, int32_t y, int32_t z,
            int32_t width, int32_t height, int32_t offset, int32_t& skip)
    {
        Tile* tile = NULL;
        for(int32_t nx = 0; nx < width; nx++)
        {
            for(int32_t ny = 0; ny < height; ny++)
            {
                if((tile = g_game.getTile(Position(x + nx + offset, y + ny + offset, z))))
                {
                    if(skip >= 0)
                    {
                        msg->put<char>(skip);
                        msg->put<char>(0xFF);
                    }

                    skip = 0;
                    GetTileDescription(tile, msg);
                }
                else
                {
                    ++skip;
                    if(skip == 0xFF)
                    {
                        msg->put<char>(0xFF);
                        msg->put<char>(0xFF);
                        skip = -1;
                    }
                }
            }
        }
    }

    void ProtocolGame::checkCreatureAsKnown(uint32_t id, bool& known, uint32_t& removedKnown)
    {
        // loop through the known creature list and check if the given creature is in
        for(std::list<uint32_t>::iterator it = knownCreatureList.begin(); it != knownCreatureList.end(); ++it)
        {
            if((*it) != id)
                continue;

            // know... make the creature even more known...
            knownCreatureList.erase(it);
            knownCreatureList.push_back(id);

            known = true;
            return;
        }

        // ok, he is unknown...
        known = false;
        // ... but not in future
        knownCreatureList.push_back(id);
        // too many known creatures?
        if(knownCreatureList.size() > 250)
        {
            // lets try to remove one from the end of the list
            Creature* c = NULL;
            for(int32_t n = 0; n < 250; n++)
            {
                removedKnown = knownCreatureList.front();
                if(!(c = g_game.getCreatureByID(removedKnown)) || !canSee(c))
                    break;

                // this creature we can't remove, still in sight, so back to the end
                knownCreatureList.pop_front();
                knownCreatureList.push_back(removedKnown);
            }

            // hopefully we found someone to remove :S, we got only 250 tries
            // if not... lets kick some players with debug errors :)
            knownCreatureList.pop_front();
        }
        else // we can cache without problems :)
            removedKnown = 0;
    }

    bool ProtocolGame::canSee(const Creature* c) const
    {
        return !c->isRemoved() && player->canSeeCreature(c) && canSee(c->getPosition());
    }

    bool ProtocolGame::canSee(const Position& pos) const
    {
        return canSee(pos.x, pos.y, pos.z);
    }

    bool ProtocolGame::canSee(uint16_t x, uint16_t y, uint16_t z) const
    {
    #ifdef __DEBUG__
        if(z >= MAP_MAX_LAYERS)
            std::clog << "[Warning - ProtocolGame::canSee] Z-value is out of range!" << std::endl;
    #endif

        const Position& myPos = player->getPosition();
        if(myPos.z <= 7)
        {
            //we are on ground level or above (7 -> 0), view is from 7 -> 0
            if(z > 7)
                return false;
        }
        else if(myPos.z >= 8 && std::abs(myPos.z - z) > 2) //we are underground (8 -> 15), view is +/- 2 from the floor we stand on
            return false;

        //negative offset means that the action taken place is on a lower floor than ourself
        int32_t offsetz = myPos.z - z;
        return ((x >= myPos.x - 8 + offsetz) && (x <= myPos.x + 9 + offsetz) &&
            (y >= myPos.y - 6 + offsetz) && (y <= myPos.y + 7 + offsetz));
    }

    //********************** Parse methods *******************************//
    void ProtocolGame::parseLogout(NetworkMessage&)
    {
        Dispatcher::getInstance().addTask(createTask(boost::bind(&ProtocolGame::logout, this, true, false)));
    }

    void ProtocolGame::parseCreatePrivateChannel(NetworkMessage&)
    {
        addGameTask(&Game::playerCreatePrivateChannel, player->getID(), this); //CAST
    }

    void ProtocolGame::parseChannelInvite(NetworkMessage& msg)
    {
        const std::string name = msg.getString();
        addGameTask(&Game::playerChannelInvite, player->getID(), name);
    }

    void ProtocolGame::parseChannelExclude(NetworkMessage& msg)
    {
        const std::string name = msg.getString();
        addGameTask(&Game::playerChannelExclude, player->getID(), name);
    }

    void ProtocolGame::parseGetChannels(NetworkMessage&)
    {
        addGameTask(&Game::playerRequestChannels, player->getID(), this); //CAST
    }

    void ProtocolGame::parseOpenChannel(NetworkMessage& msg)
    {
        uint16_t channelId = msg.get<uint16_t>();
        addGameTask(&Game::playerOpenChannel, player->getID(), channelId);
    }

    void ProtocolGame::parseCloseChannel(NetworkMessage& msg)
    {
        uint16_t channelId = msg.get<uint16_t>();
        addGameTask(&Game::playerCloseChannel, player->getID(), channelId);
    }

    void ProtocolGame::parseOpenPriv(NetworkMessage& msg)
    {
        const std::string receiver = msg.getString();
        addGameTask(&Game::playerOpenPrivateChannel, player->getID(), receiver);
    }

    void ProtocolGame::parseProcessRuleViolation(NetworkMessage& msg)
    {
        const std::string reporter = msg.getString();
        addGameTask(&Game::playerProcessRuleViolation, player->getID(), reporter);
    }

    void ProtocolGame::parseCloseRuleViolation(NetworkMessage& msg)
    {
        const std::string reporter = msg.getString();
        addGameTask(&Game::playerCloseRuleViolation, player->getID(), reporter);
    }

    void ProtocolGame::parseCancelRuleViolation(NetworkMessage&)
    {
        addGameTask(&Game::playerCancelRuleViolation, player->getID());
    }

    void ProtocolGame::parseCloseNpc(NetworkMessage&)
    {
        addGameTask(&Game::playerCloseNpcChannel, player->getID());
    }

    void ProtocolGame::parseCancelMove(NetworkMessage&)
    {
        addGameTask(&Game::playerCancelAttackAndFollow, player->getID());
    }

    void ProtocolGame::parseReceivePing(NetworkMessage&)
    {
        addGameTask(&Game::playerReceivePing, player->getID());
    }

    void ProtocolGame::parseAutoWalk(NetworkMessage& msg)
    {
        // first we get all directions...
        std::list<Direction> path;
        size_t dirCount = msg.get<char>();
        for(size_t i = 0; i < dirCount; ++i)
        {
            uint8_t rawDir = msg.get<char>();
            Direction dir = SOUTH;
            switch(rawDir)
            {
                case 1:
                    dir = EAST;
                    break;
                case 2:
                    dir = NORTHEAST;
                    break;
                case 3:
                    dir = NORTH;
                    break;
                case 4:
                    dir = NORTHWEST;
                    break;
                case 5:
                    dir = WEST;
                    break;
                case 6:
                    dir = SOUTHWEST;
                    break;
                case 7:
                    dir = SOUTH;
                    break;
                case 8:
                    dir = SOUTHEAST;
                    break;
                default:
                    continue;
            }

            path.push_back(dir);
        }

        addGameTask(&Game::playerAutoWalk, player->getID(), path);
    }

    void ProtocolGame::parseMove(NetworkMessage&, Direction dir)
    {
        addGameTask(&Game::playerMove, player->getID(), dir);
    }

    void ProtocolGame::parseTurn(NetworkMessage&, Direction dir)
    {
        addGameTaskTimed(DISPATCHER_TASK_EXPIRATION, &Game::playerTurn, player->getID(), dir);
    }

    void ProtocolGame::parseRequestOutfit(NetworkMessage&)
    {
        addGameTask(&Game::playerRequestOutfit, player->getID());
    }

    void ProtocolGame::parseSetOutfit(NetworkMessage& msg)
    {
        Outfit_t newOutfit = player->defaultOutfit;
        if(g_config.getBool(ConfigManager::ALLOW_CHANGEOUTFIT))
            newOutfit.lookType = msg.get<uint16_t>();
        else
            msg.skip(2);

        if(g_config.getBool(ConfigManager::ALLOW_CHANGECOLORS))
        {
            newOutfit.lookHead = msg.get<char>();
            newOutfit.lookBody = msg.get<char>();
            newOutfit.lookLegs = msg.get<char>();
            newOutfit.lookFeet = msg.get<char>();
        }
        else
            msg.skip(4);

        if(g_config.getBool(ConfigManager::ALLOW_CHANGEADDONS))
            newOutfit.lookAddons = msg.get<char>();
        else
            msg.skip(1);

        addGameTask(&Game::playerChangeOutfit, player->getID(), newOutfit);
    }

    void ProtocolGame::parseUseItem(NetworkMessage& msg)
    {
        Position pos = msg.getPosition();
        uint16_t spriteId = msg.get<uint16_t>();
        int16_t stackpos = msg.get<char>();
        uint8_t index = msg.get<char>();
        bool isHotkey = (pos.x == 0xFFFF && !pos.y && !pos.z);
        addGameTaskTimed(DISPATCHER_TASK_EXPIRATION, &Game::playerUseItem, player->getID(), pos, stackpos, index, spriteId, isHotkey);
    }

    void ProtocolGame::parseUseItemEx(NetworkMessage& msg)
    {
        Position fromPos = msg.getPosition();
        uint16_t fromSpriteId = msg.get<uint16_t>();
        int16_t fromStackpos = msg.get<char>();
        Position toPos = msg.getPosition();
        uint16_t toSpriteId = msg.get<uint16_t>();
        int16_t toStackpos = msg.get<char>();
        bool isHotkey = (fromPos.x == 0xFFFF && !fromPos.y && !fromPos.z);
        addGameTaskTimed(DISPATCHER_TASK_EXPIRATION, &Game::playerUseItemEx, player->getID(),
            fromPos, fromStackpos, fromSpriteId, toPos, toStackpos, toSpriteId, isHotkey);
    }

    void ProtocolGame::parseBattleWindow(NetworkMessage& msg)
    {
        Position fromPos = msg.getPosition();
        uint16_t spriteId = msg.get<uint16_t>();
        int16_t fromStackpos = msg.get<char>();
        uint32_t creatureId = msg.get<uint32_t>();
        bool isHotkey = (fromPos.x == 0xFFFF && !fromPos.y && !fromPos.z);
        addGameTaskTimed(DISPATCHER_TASK_EXPIRATION, &Game::playerUseBattleWindow, player->getID(), fromPos, fromStackpos, creatureId, spriteId, isHotkey);
    }

    void ProtocolGame::parseCloseContainer(NetworkMessage& msg)
    {
        uint8_t cid = msg.get<char>();
        addGameTask(&Game::playerCloseContainer, player->getID(), cid);
    }

    void ProtocolGame::parseUpArrowContainer(NetworkMessage& msg)
    {
        uint8_t cid = msg.get<char>();
        addGameTask(&Game::playerMoveUpContainer, player->getID(), cid);
    }

    void ProtocolGame::parseUpdateTile(NetworkMessage& msg)
    {
        Position pos = msg.getPosition();
        //addGameTask(&Game::playerUpdateTile, player->getID(), pos);
    }

    void ProtocolGame::parseUpdateContainer(NetworkMessage& msg)
    {
        uint8_t cid = msg.get<char>();
        addGameTask(&Game::playerUpdateContainer, player->getID(), cid);
    }

    void ProtocolGame::parseThrow(NetworkMessage& msg)
    {
        Position fromPos = msg.getPosition();
        uint16_t spriteId = msg.get<uint16_t>();
        int16_t fromStackpos = msg.get<char>();
        Position toPos = msg.getPosition();
        uint8_t count = msg.get<char>();
        if(toPos != fromPos)
            addGameTaskTimed(DISPATCHER_TASK_EXPIRATION, &Game::playerMoveThing,
                player->getID(), fromPos, spriteId, fromStackpos, toPos, count);
    }

    void ProtocolGame::parseLookAt(NetworkMessage& msg)
    {
        Position pos = msg.getPosition();
        uint16_t spriteId = msg.get<uint16_t>();
        int16_t stackpos = msg.get<char>();
        addGameTaskTimed(DISPATCHER_TASK_EXPIRATION, &Game::playerLookAt, player->getID(), pos, spriteId, stackpos);
    }

    void ProtocolGame::parseSay(NetworkMessage& msg)
    {
        std::string receiver;
        uint16_t channelId = 0;

        SpeakClasses type = (SpeakClasses)msg.get<char>();
        switch(type)
        {
            case SPEAK_PRIVATE:
            case SPEAK_PRIVATE_RED:
            case SPEAK_RVR_ANSWER:
                receiver = msg.getString();
                break;

            case SPEAK_CHANNEL_Y:
            case SPEAK_CHANNEL_RN:
            case SPEAK_CHANNEL_RA:
                channelId = msg.get<uint16_t>();
                break;

            default:
                break;
        }

        const std::string text = msg.getString();
        if(text.length() > 255) //client limit
        {
            std::stringstream s;
            s << text.length();

            Logger::getInstance()->eFile("bots/" + player->getName() + ".log", "Attempt to send message with size " + s.str() + " - client is limited to 255 characters.", true);
            return;
        }

        addGameTaskTimed(DISPATCHER_TASK_EXPIRATION, &Game::playerSay, player->getID(), channelId, type, receiver, text, this); //CAST
    }

    void ProtocolGame::parseFightModes(NetworkMessage& msg)
    {
        uint8_t rawFightMode = msg.get<char>(); //1 - offensive, 2 - balanced, 3 - defensive
        uint8_t rawChaseMode = msg.get<char>(); //0 - stand while fightning, 1 - chase opponent
        uint8_t rawSecureMode = msg.get<char>(); //0 - can't attack unmarked, 1 - can attack unmarked

        chaseMode_t chaseMode = CHASEMODE_STANDSTILL;
        if(rawChaseMode == 1)
            chaseMode = CHASEMODE_FOLLOW;

        fightMode_t fightMode = FIGHTMODE_ATTACK;
        if(rawFightMode == 2)
            fightMode = FIGHTMODE_BALANCED;
        else if(rawFightMode == 3)
            fightMode = FIGHTMODE_DEFENSE;

        secureMode_t secureMode = SECUREMODE_OFF;
        if(rawSecureMode == 1)
            secureMode = SECUREMODE_ON;

        addGameTaskTimed(DISPATCHER_TASK_EXPIRATION, &Game::playerSetFightModes, player->getID(), fightMode, chaseMode, secureMode);
    }

    void ProtocolGame::parseAttack(NetworkMessage& msg)
    {
        uint32_t creatureId = msg.get<uint32_t>();
        msg.get<uint32_t>(); //?
        msg.get<uint32_t>(); //?

        addGameTask(&Game::playerSetAttackedCreature, player->getID(), creatureId);
    }

    void ProtocolGame::parseFollow(NetworkMessage& msg)
    {
        uint32_t creatureId = msg.get<uint32_t>();
        addGameTask(&Game::playerFollowCreature, player->getID(), creatureId);
    }

    void ProtocolGame::parseTextWindow(NetworkMessage& msg)
    {
        uint32_t windowTextId = msg.get<uint32_t>();
        const std::string newText = msg.getString();
        addGameTask(&Game::playerWriteItem, player->getID(), windowTextId, newText);
    }

    void ProtocolGame::parseHouseWindow(NetworkMessage &msg)
    {
        uint8_t doorId = msg.get<char>();
        uint32_t id = msg.get<uint32_t>();
        const std::string text = msg.getString();
        addGameTask(&Game::playerUpdateHouseWindow, player->getID(), doorId, id, text);
    }

    void ProtocolGame::parseLookInShop(NetworkMessage &msg)
    {
        uint16_t id = msg.get<uint16_t>();
        uint16_t count = msg.get<char>();
        addGameTaskTimed(DISPATCHER_TASK_EXPIRATION, &Game::playerLookInShop, player->getID(), id, count);
    }

    void ProtocolGame::parsePlayerPurchase(NetworkMessage &msg)
    {
        uint16_t id = msg.get<uint16_t>();
        uint16_t count = msg.get<char>();
        uint16_t amount = msg.get<char>();
        bool ignoreCap = msg.get<char>();
        bool inBackpacks = msg.get<char>();
        addGameTaskTimed(DISPATCHER_TASK_EXPIRATION, &Game::playerPurchaseItem, player->getID(), id, count, amount, ignoreCap, inBackpacks);
    }

    void ProtocolGame::parsePlayerSale(NetworkMessage &msg)
    {
        uint16_t id = msg.get<uint16_t>();
        uint16_t count = msg.get<char>();
        uint16_t amount = msg.get<char>();
        addGameTaskTimed(DISPATCHER_TASK_EXPIRATION, &Game::playerSellItem, player->getID(), id, count, amount);
    }

    void ProtocolGame::parseCloseShop(NetworkMessage&)
    {
        addGameTask(&Game::playerCloseShop, player->getID());
    }

    void ProtocolGame::parseRequestTrade(NetworkMessage& msg)
    {
        Position pos = msg.getPosition();
        uint16_t spriteId = msg.get<uint16_t>();
        int16_t stackpos = msg.get<char>();
        uint32_t playerId = msg.get<uint32_t>();
        addGameTask(&Game::playerRequestTrade, player->getID(), pos, stackpos, playerId, spriteId);
    }

    void ProtocolGame::parseAcceptTrade(NetworkMessage&)
    {
        addGameTask(&Game::playerAcceptTrade, player->getID());
    }

    void ProtocolGame::parseLookInTrade(NetworkMessage& msg)
    {
        bool counter = msg.get<char>();
        int32_t index = msg.get<char>();
        addGameTaskTimed(DISPATCHER_TASK_EXPIRATION, &Game::playerLookInTrade, player->getID(), counter, index);
    }

    void ProtocolGame::parseCloseTrade()
    {
        addGameTask(&Game::playerCloseTrade, player->getID());
    }

    void ProtocolGame::parseAddVip(NetworkMessage& msg)
    {
        const std::string name = msg.getString();
        if(name.size() > 32)
            return;

        addGameTask(&Game::playerRequestAddVip, player->getID(), name);
    }

    void ProtocolGame::parseRemoveVip(NetworkMessage& msg)
    {
        uint32_t guid = msg.get<uint32_t>();
        addGameTask(&Game::playerRequestRemoveVip, player->getID(), guid);
    }

    void ProtocolGame::parseRotateItem(NetworkMessage& msg)
    {
        Position pos = msg.getPosition();
        uint16_t spriteId = msg.get<uint16_t>();
        int16_t stackpos = msg.get<char>();
        addGameTaskTimed(DISPATCHER_TASK_EXPIRATION, &Game::playerRotateItem, player->getID(), pos, stackpos, spriteId);
    }

    void ProtocolGame::parseDebugAssert(NetworkMessage& msg)
    {
        if(m_debugAssertSent)
            return;

        std::stringstream s;
        s << "----- " << formatDate() << " - " << player->getName() << " (" << convertIPAddress(getIP())
            << ") -----" << std::endl << msg.getString() << std::endl << msg.getString()
            << std::endl << msg.getString() << std::endl << msg.getString()
            << std::endl << std::endl;

        m_debugAssertSent = true;
        Logger::getInstance()->iFile(LOGFILE_ASSERTIONS, s.str(), false);
    }

    void ProtocolGame::parseBugReport(NetworkMessage& msg)
    {
        std::string comment = msg.getString();
        addGameTask(&Game::playerReportBug, player->getID(), comment);
    }

    void ProtocolGame::parseInviteToParty(NetworkMessage& msg)
    {
        uint32_t targetId = msg.get<uint32_t>();
        addGameTask(&Game::playerInviteToParty, player->getID(), targetId);
    }

    void ProtocolGame::parseJoinParty(NetworkMessage& msg)
    {
        uint32_t targetId = msg.get<uint32_t>();
        addGameTask(&Game::playerJoinParty, player->getID(), targetId);
    }

    void ProtocolGame::parseRevokePartyInvite(NetworkMessage& msg)
    {
        uint32_t targetId = msg.get<uint32_t>();
        addGameTask(&Game::playerRevokePartyInvitation, player->getID(), targetId);
    }

    void ProtocolGame::parsePassPartyLeadership(NetworkMessage& msg)
    {
        uint32_t targetId = msg.get<uint32_t>();
        addGameTask(&Game::playerPassPartyLeadership, player->getID(), targetId);
    }

    void ProtocolGame::parseLeaveParty(NetworkMessage&)
    {
        addGameTask(&Game::playerLeaveParty, player->getID(), false);
    }

    void ProtocolGame::parseSharePartyExperience(NetworkMessage& msg)
    {
        bool activate = msg.get<char>();
        uint8_t unknown = msg.get<char>(); //TODO: find out what is this byte
        addGameTask(&Game::playerSharePartyExperience, player->getID(), activate, unknown);
    }

    void ProtocolGame::parseQuests(NetworkMessage&)
    {
        addGameTask(&Game::playerQuests, player->getID());
    }

    void ProtocolGame::parseQuestInfo(NetworkMessage& msg)
    {
        uint16_t questId = msg.get<uint16_t>();
        addGameTask(&Game::playerQuestInfo, player->getID(), questId);
    }

    void ProtocolGame::parseViolationWindow(NetworkMessage& msg)
    {
        std::string target = msg.getString();
        uint8_t reason = msg.get<char>();
        ViolationAction_t action = (ViolationAction_t)msg.get<char>();
        std::string comment = msg.getString();
        std::string statement = msg.getString();
        uint32_t statementId = (uint32_t)msg.get<uint16_t>();
        bool ipBanishment = msg.get<char>();
        addGameTask(&Game::playerViolationWindow, player->getID(), target,
            reason, action, comment, statement, statementId, ipBanishment);
    }

    void ProtocolGame::parseViolationReport(NetworkMessage& msg)
    {
        msg.skip(msg.size() - msg.position());
        // addGameTask(&Game::playerViolationReport, player->getID(), ...);
    }

    //********************** Send methods *******************************//
    void ProtocolGame::sendOpenPrivateChannel(const std::string& receiver)
    {
        NetworkMessage_ptr msg = getOutputBuffer();
        if(msg)
        {
            TRACK_MESSAGE(msg);
            msg->put<char>(0xAD);
            msg->putString(receiver);
        }
    }

    void ProtocolGame::sendCreatureOutfit(const Creature* creature, const Outfit_t& outfit)
    {
        if(!canSee(creature))
            return;

        NetworkMessage_ptr msg = getOutputBuffer();
        if(msg)
        {
            TRACK_MESSAGE(msg);
            msg->put<char>(0x8E);
            msg->put<uint32_t>(creature->getID());
            AddCreatureOutfit(msg, creature, outfit);
        }
    }

    void ProtocolGame::sendCreatureLight(const Creature* creature)
    {
        if(!canSee(creature))
            return;

        NetworkMessage_ptr msg = getOutputBuffer();
        if(msg)
        {
            TRACK_MESSAGE(msg);
            AddCreatureLight(msg, creature);
        }
    }

    void ProtocolGame::sendWorldLight(const LightInfo& lightInfo)
    {
        NetworkMessage_ptr msg = getOutputBuffer();
        if(msg)
        {
            TRACK_MESSAGE(msg);
            AddWorldLight(msg, lightInfo);
        }
    }

    void ProtocolGame::sendCreatureImpassable(const Creature* creature)
    {
        /* TODO: how this actually work...
        reloadCreature(creature); */

        if(!canSee(creature))
            return;

        NetworkMessage_ptr msg = getOutputBuffer();
        if(msg)
        {
            TRACK_MESSAGE(msg);
            msg->put<char>(0x92);
            msg->put<uint32_t>(creature->getID());
            msg->put<char>(!player->canWalkthrough(creature));
        }
    }

    void ProtocolGame::sendCreatureShield(const Creature* creature)
    {
        if(!canSee(creature))
            return;

        NetworkMessage_ptr msg = getOutputBuffer();
        if(msg)
        {
            TRACK_MESSAGE(msg);
            msg->put<char>(0x91);
            msg->put<uint32_t>(creature->getID());
            msg->put<char>(player->getPartyShield(creature));
        }
    }

    void ProtocolGame::sendCreatureSkull(const Creature* creature)
    {
        if(!canSee(creature))
            return;

        NetworkMessage_ptr msg = getOutputBuffer();
        if(msg)
        {
            TRACK_MESSAGE(msg);
            msg->put<char>(0x90);
            msg->put<uint32_t>(creature->getID());
            msg->put<char>(player->getSkullType(creature));
        }
    }

    void ProtocolGame::sendCreatureSquare(const Creature* creature, uint8_t color)
    {
        if(!canSee(creature))
            return;

        NetworkMessage_ptr msg = getOutputBuffer();
        if(msg)
        {
            TRACK_MESSAGE(msg);
            msg->put<char>(0x86);
            msg->put<uint32_t>(creature->getID());
            msg->put<char>(color);
        }
    }

    void ProtocolGame::sendTutorial(uint8_t tutorialId)
    {
        NetworkMessage_ptr msg = getOutputBuffer();
        if(msg)
        {
            TRACK_MESSAGE(msg);
            msg->put<char>(0xDC);
            msg->put<char>(tutorialId);
        }
    }

    void ProtocolGame::sendAddMarker(const Position& pos, MapMarks_t markType, const std::string& desc)
    {
        NetworkMessage_ptr msg = getOutputBuffer();
        if(msg)
        {
            TRACK_MESSAGE(msg);
            msg->put<char>(0xDD);
            msg->putPosition(pos);
            msg->put<char>(markType);
            msg->putString(desc);
        }
    }

    void ProtocolGame::sendReLoginWindow()
    {
        NetworkMessage_ptr msg = getOutputBuffer();
        if(msg)
        {
            TRACK_MESSAGE(msg);
            msg->put<char>(0x28);
        }
    }

    void ProtocolGame::sendStats()
    {
        NetworkMessage_ptr msg = getOutputBuffer();
        if(msg)
        {
            TRACK_MESSAGE(msg);
            AddPlayerStats(msg);
        }
    }

    void ProtocolGame::sendTextMessage(MessageClasses mClass, const std::string& message)
    {
        NetworkMessage_ptr msg = getOutputBuffer();
        if(msg)
        {
            TRACK_MESSAGE(msg);
            AddTextMessage(msg, mClass, message);
        }
    }

    void ProtocolGame::sendClosePrivate(uint16_t channelId)
    {
        NetworkMessage_ptr msg = getOutputBuffer();
        if(msg)
        {
            TRACK_MESSAGE(msg);
            if(channelId == CHANNEL_GUILD || channelId == CHANNEL_PARTY)
                g_chat.removeUserFromChannel(player, channelId);

            msg->put<char>(0xB3);
            msg->put<uint16_t>(channelId);
        }
    }

    void ProtocolGame::sendCreatePrivateChannel(uint16_t channelId, const std::string& channelName)
    {
        NetworkMessage_ptr msg = getOutputBuffer();
        if(msg)
        {
            TRACK_MESSAGE(msg);
            msg->put<char>(0xB2);
            msg->put<uint16_t>(channelId);
            msg->putString(channelName);
        }
    }

    void ProtocolGame::sendChannelsDialog() //CAST
    {
        NetworkMessage_ptr msg = getOutputBuffer();
        if(msg)
        {
            TRACK_MESSAGE(msg);
            msg->put<char>(0xAB);

            if(getIsCast()) {
                msg->put<char>(1);
                msg->put<uint16_t>(CHANNEL_PRIVATE);
                msg->putString("Cast Channel");
            } else {
                ChannelList list = g_chat.getChannelList(player);
                msg->put<char>(list.size());

                ChatChannel* channel = NULL;
                for(ChannelList::iterator it = list.begin(); it != list.end(); ++it)
                {
                    if(!(channel = (*it)))
                        continue;

                    msg->put<uint16_t>(channel->getId());
                    msg->putString(channel->getName());
                }
            }
        }
    }

    void ProtocolGame::sendChannel(uint16_t channelId, const std::string& channelName)
    {
        NetworkMessage_ptr msg = getOutputBuffer();
        if(msg)
        {
            TRACK_MESSAGE(msg);
            msg->put<char>(0xAC);
            msg->put<uint16_t>(channelId);
            msg->putString(channelName);
        }
    }

    void ProtocolGame::sendRuleViolationsChannel(uint16_t channelId)
    {
        NetworkMessage_ptr msg = getOutputBuffer();
        if(msg)
        {
            TRACK_MESSAGE(msg);
            msg->put<char>(0xAE);
            msg->put<uint16_t>(channelId);
            for(RuleViolationsMap::const_iterator it = g_game.getRuleViolations().begin(); it != g_game.getRuleViolations().end(); ++it)
            {
                RuleViolation& rvr = *it->second;
                if(rvr.isOpen && rvr.reporter)
                    AddCreatureSpeak(msg, rvr.reporter, SPEAK_RVR_CHANNEL, rvr.text, channelId, rvr.time);
            }
        }
    }

    void ProtocolGame::sendRemoveReport(const std::string& name)
    {
        NetworkMessage_ptr msg = getOutputBuffer();
        if(msg)
        {
            TRACK_MESSAGE(msg);
            msg->put<char>(0xAF);
            msg->putString(name);
        }
    }

    void ProtocolGame::sendRuleViolationCancel(const std::string& name)
    {
        NetworkMessage_ptr msg = getOutputBuffer();
        if(msg)
        {
            TRACK_MESSAGE(msg);
            msg->put<char>(0xB0);
            msg->putString(name);
        }
    }

    void ProtocolGame::sendLockRuleViolation()
    {
        NetworkMessage_ptr msg = getOutputBuffer();
        if(msg)
        {
            TRACK_MESSAGE(msg);
            msg->put<char>(0xB1);
        }
    }

    void ProtocolGame::sendIcons(int32_t icons)
    {
        NetworkMessage_ptr msg = getOutputBuffer();
        if(msg)
        {
            TRACK_MESSAGE(msg);
            msg->put<char>(0xA2);
            msg->put<uint16_t>(icons);
        }
    }

    void ProtocolGame::sendContainer(uint32_t cid, const Container* container, bool hasParent)
    {
        NetworkMessage_ptr msg = getOutputBuffer();
        if(msg)
        {
            TRACK_MESSAGE(msg);
            msg->put<char>(0x6E);
            msg->put<char>(cid);

            msg->putItemId(container);
            msg->putString(container->getName());
            msg->put<char>(container->capacity());

            msg->put<char>(hasParent ? 0x01 : 0x00);
            msg->put<char>(std::min(container->size(), (uint32_t)255));

            ItemList::const_iterator cit = container->getItems();
            for(uint32_t i = 0; cit != container->getEnd() && i < 255; ++cit, ++i)
                msg->putItem(*cit);
        }
    }

    void ProtocolGame::sendShop(const ShopInfoList& shop)
    {
        NetworkMessage_ptr msg = getOutputBuffer();
        if(msg)
        {
            TRACK_MESSAGE(msg);
            msg->put<char>(0x7A);
            msg->put<char>(std::min(shop.size(), (size_t)255));

            ShopInfoList::const_iterator it = shop.begin();
            for(uint32_t i = 0; it != shop.end() && i < 255; ++it, ++i)
                AddShopItem(msg, (*it));
        }
    }

    void ProtocolGame::sendCloseShop()
    {
        NetworkMessage_ptr msg = getOutputBuffer();
        if(msg)
        {
            TRACK_MESSAGE(msg);
            msg->put<char>(0x7C);
        }
    }

    void ProtocolGame::sendGoods(const ShopInfoList& shop)
    {
        NetworkMessage_ptr msg = getOutputBuffer();
        if(msg)
        {
            TRACK_MESSAGE(msg);
            msg->put<char>(0x7B);
            msg->put<uint32_t>((uint32_t)g_game.getMoney(player));

            std::map<uint32_t, uint32_t> goodsMap;
            if(shop.size() >= 5)
            {
                for(ShopInfoList::const_iterator sit = shop.begin(); sit != shop.end(); ++sit)
                {
                    if(sit->sellPrice < 0)
                        continue;

                    int8_t subType = -1;
                    if(sit->subType)
                    {
                        const ItemType& it = Item::items[sit->itemId];
                        if(it.hasSubType() && !it.stackable)
                            subType = sit->subType;
                    }

                    uint32_t count = player->__getItemTypeCount(sit->itemId, subType);
                    if(count > 0)
                        goodsMap[sit->itemId] = count;
                }
            }
            else
            {
                std::map<uint32_t, uint32_t> tmpMap;
                player->__getAllItemTypeCount(tmpMap);
                for(ShopInfoList::const_iterator sit = shop.begin(); sit != shop.end(); ++sit)
                {
                    if(sit->sellPrice < 0)
                        continue;

                    int8_t subType = -1;
                    const ItemType& it = Item::items[sit->itemId];
                    if(sit->subType && it.hasSubType() && !it.stackable)
                        subType = sit->subType;

                    if(subType != -1)
                    {
                        uint32_t count = subType;
                        if(!it.isFluidContainer() && !it.isSplash())
                            count = player->__getItemTypeCount(sit->itemId, subType);

                        if(count > 0)
                            goodsMap[sit->itemId] = count;
                        else
                            goodsMap[sit->itemId] = 0;
                    }
                    else
                        goodsMap[sit->itemId] = tmpMap[sit->itemId];
                }
            }

            msg->put<char>(std::min(goodsMap.size(), (size_t)255));
            std::map<uint32_t, uint32_t>::const_iterator it = goodsMap.begin();
            for(uint32_t i = 0; it != goodsMap.end() && i < 255; ++it, ++i)
            {
                msg->putItemId(it->first);
                msg->put<char>(std::min(it->second, (uint32_t)255));
            }
        }
    }

    void ProtocolGame::sendTradeItemRequest(const Player* player, const Item* item, bool ack)
    {
        NetworkMessage_ptr msg = getOutputBuffer();
        if(msg)
        {
            TRACK_MESSAGE(msg);
            if(ack)
                msg->put<char>(0x7D);
            else
                msg->put<char>(0x7E);

            msg->putString(player->getName());
            if(const Container* container = item->getContainer())
            {
                msg->put<char>(container->getItemHoldingCount() + 1);
                msg->putItem(item);
                for(ContainerIterator it = container->begin(); it != container->end(); ++it)
                    msg->putItem(*it);
            }
            else
            {
                msg->put<char>(1);
                msg->putItem(item);
            }
        }
    }

    void ProtocolGame::sendCloseTrade()
    {
        NetworkMessage_ptr msg = getOutputBuffer();
        if(msg)
        {
            TRACK_MESSAGE(msg);
            msg->put<char>(0x7F);
        }
    }

    void ProtocolGame::sendCloseContainer(uint32_t cid)
    {
        NetworkMessage_ptr msg = getOutputBuffer();
        if(msg)
        {
            TRACK_MESSAGE(msg);
            msg->put<char>(0x6F);
            msg->put<char>(cid);
        }
    }

    void ProtocolGame::sendCreatureTurn(const Creature* creature, int16_t stackpos)
    {
        if(stackpos >= 10 || !canSee(creature))
            return;

        NetworkMessage_ptr msg = getOutputBuffer();
        if(msg)
        {
            TRACK_MESSAGE(msg);
            msg->put<char>(0x6B);
            msg->putPosition(creature->getPosition());
            msg->put<char>(stackpos);
            msg->put<uint16_t>(0x63); /*99*/
            msg->put<uint32_t>(creature->getID());
            msg->put<char>(creature->getDirection());
        }
    }

    void ProtocolGame::sendCreatureSay(const Creature* creature, SpeakClasses type, const std::string& text, Position* pos/* = NULL*/)
    {
        if(isCast && !(creature->getPlayer() == player)) //CAST
            return;

        NetworkMessage_ptr msg = getOutputBuffer();
        if(msg)
        {
            TRACK_MESSAGE(msg);
            AddCreatureSpeak(msg, creature, type, text, 0, 0, pos, NULL); //CAST
        }
    }

    void ProtocolGame::sendToChannel(const Creature* creature, SpeakClasses type, const std::string& text, uint16_t channelId, uint32_t time /*= 0*/, ProtocolGame* pg)
    {
        ChatChannel* channel = NULL; //CAST
        if(creature != NULL && creature->getPlayer())
            channel = g_chat.getPrivateChannel((Player*)creature->getPlayer());

        if(pg != NULL && pg->getIsCast() && ((channel != NULL && channelId != channel->getId()) || !channel)) //CAST
            return;

        NetworkMessage_ptr msg = getOutputBuffer();
        if(msg)
        {
            TRACK_MESSAGE(msg);
            AddCreatureSpeak(msg, creature, type, text, channelId, time, NULL, pg); //CAST
        }
    }

    void ProtocolGame::sendCancel(const std::string& message)
    {
        NetworkMessage_ptr msg = getOutputBuffer();
        if(msg)
        {
            TRACK_MESSAGE(msg);
            AddTextMessage(msg, MSG_STATUS_SMALL, message);
        }
    }

    void ProtocolGame::sendCancelTarget()
    {
        NetworkMessage_ptr msg = getOutputBuffer();
        if(msg)
        {
            TRACK_MESSAGE(msg);
            msg->put<char>(0xA3);
            msg->put<uint32_t>(0); //? creatureId?
        }
    }

    void ProtocolGame::sendChangeSpeed(const Creature* creature, uint32_t speed)
    {
        if(!canSee(creature))
            return;

        NetworkMessage_ptr msg = getOutputBuffer();
        if(msg)
        {
            TRACK_MESSAGE(msg);
            msg->put<char>(0x8F);
            msg->put<uint32_t>(creature->getID());
            msg->put<uint16_t>(speed);
        }
    }

    void ProtocolGame::sendCancelWalk()
    {
        NetworkMessage_ptr msg = getOutputBuffer();
        if(msg)
        {
            TRACK_MESSAGE(msg);
            msg->put<char>(0xB5);
            msg->put<char>(player->getDirection());
        }
    }

    void ProtocolGame::sendSkills()
    {
        NetworkMessage_ptr msg = getOutputBuffer();
        if(msg)
        {
            TRACK_MESSAGE(msg);
            AddPlayerSkills(msg);
        }
    }

    void ProtocolGame::sendPing()
    {
        NetworkMessage_ptr msg = getOutputBuffer();
        if(msg)
        {
            TRACK_MESSAGE(msg);
            msg->put<char>(0x1E);
        }
    }

    void ProtocolGame::sendDistanceShoot(const Position& from, const Position& to, uint8_t type)
    {
        if(type > SHOOT_EFFECT_LAST || (!canSee(from) && !canSee(to)))
            return;

        NetworkMessage_ptr msg = getOutputBuffer();
        if(msg)
        {
            TRACK_MESSAGE(msg);
            AddDistanceShoot(msg, from, to, type);
        }
    }

    void ProtocolGame::sendMagicEffect(const Position& pos, uint8_t type)
    {
        if(type > MAGIC_EFFECT_LAST || !canSee(pos))
            return;

        NetworkMessage_ptr msg = getOutputBuffer();
        if(msg)
        {
            TRACK_MESSAGE(msg);
            AddMagicEffect(msg, pos, type);
        }
    }

    void ProtocolGame::sendAnimatedText(const Position& pos, uint8_t color, std::string text)
    {
        if(!canSee(pos))
            return;

        NetworkMessage_ptr msg = getOutputBuffer();
        if(msg)
        {
            TRACK_MESSAGE(msg);
            AddAnimatedText(msg, pos, color, text);
        }
    }

    void ProtocolGame::sendCreatureHealth(const Creature* creature)
    {
        if(!canSee(creature))
            return;

        NetworkMessage_ptr msg = getOutputBuffer();
        if(msg)
        {
            TRACK_MESSAGE(msg);
            AddCreatureHealth(msg, creature);
        }
    }

    void ProtocolGame::sendFYIBox(const std::string& message)
    {
        if(message.empty() || message.length() > 1018) //Prevent client debug when message is empty or length is > 1018 (not confirmed)
        {
            std::clog << "[Warning - ProtocolGame::sendFYIBox] Trying to send an empty or too huge message." << std::endl;
            return;
        }

        NetworkMessage_ptr msg = getOutputBuffer();
        if(msg)
        {
            TRACK_MESSAGE(msg);
            msg->put<char>(0x15);
            msg->putString(message);
        }
    }

    //tile
    void ProtocolGame::sendAddTileItem(const Tile*, const Position& pos, uint32_t stackpos, const Item* item)
    {
        if(!canSee(pos))
            return;

        NetworkMessage_ptr msg = getOutputBuffer();
        if(msg)
        {
            TRACK_MESSAGE(msg);
            AddTileItem(msg, pos, stackpos, item);
        }
    }

    void ProtocolGame::sendUpdateTileItem(const Tile*, const Position& pos, uint32_t stackpos, const Item* item)
    {
        if(!canSee(pos))
            return;

        NetworkMessage_ptr msg = getOutputBuffer();
        if(msg)
        {
            TRACK_MESSAGE(msg);
            UpdateTileItem(msg, pos, stackpos, item);
        }
    }

    void ProtocolGame::sendRemoveTileItem(const Tile*, const Position& pos, uint32_t stackpos)
    {
        if(!canSee(pos))
            return;

        NetworkMessage_ptr msg = getOutputBuffer();
        if(msg)
        {
            TRACK_MESSAGE(msg);
            RemoveTileItem(msg, pos, stackpos);
        }
    }

    void ProtocolGame::sendUpdateTile(const Tile* tile, const Position& pos)
    {
        if(!canSee(pos))
            return;

        NetworkMessage_ptr msg = getOutputBuffer();
        if(msg)
        {
            TRACK_MESSAGE(msg);
            msg->put<char>(0x69);
            msg->putPosition(pos);
            if(tile)
            {
                GetTileDescription(tile, msg);
                msg->put<char>(0x00);
                msg->put<char>(0xFF);
            }
            else
            {
                msg->put<char>(0x01);
                msg->put<char>(0xFF);
            }
        }
    }

    void ProtocolGame::sendAddCreature(const Creature* creature, const Position& pos, uint32_t stackpos)
    {
        if(!canSee(creature))
            return;

        NetworkMessage_ptr msg = getOutputBuffer();
        if(!msg)
            return;

        TRACK_MESSAGE(msg);
        if(creature != player)
        {
            AddTileCreature(msg, pos, stackpos, creature);
            return;
        }

        msg->put<char>(0x0A);
        msg->put<uint32_t>(player->getID());
        msg->put<uint16_t>(0x32);

        msg->put<char>(player->hasFlag(PlayerFlag_CanReportBugs));
        if(Group* group = player->getGroup())
        {
            int32_t reasons = group->getViolationReasons();
            if(reasons > 1)
            {
                msg->put<char>(0x0B);
                for(int32_t i = 0; i < 20; ++i)
                {
                    if(i < 4)
                        msg->put<char>(group->getNameViolationFlags());
                    else if(i < reasons)
                        msg->put<char>(group->getStatementViolationFlags());
                    else
                        msg->put<char>(0x00);
                }
            }
        }

        AddMapDescription(msg, pos);
        for(int32_t i = SLOT_FIRST; i < SLOT_LAST; ++i)
            AddInventoryItem(msg, (slots_t)i, player->getInventoryItem((slots_t)i));

        AddPlayerStats(msg);
        AddPlayerSkills(msg);

        LightInfo lightInfo;
        g_game.getWorldLightInfo(lightInfo);

        AddWorldLight(msg, lightInfo);
        AddCreatureLight(msg, creature);

        player->sendIcons();
        for(VIPSet::iterator it = player->VIPList.begin(); it != player->VIPList.end(); it++)
        {
            std::string vipName;
            if(IOLoginData::getInstance()->getNameByGuid((*it), vipName))
            {
                Player* tmpPlayer = g_game.getPlayerByName(vipName);
                sendVIP((*it), vipName, (tmpPlayer && player->canSeeCreature(tmpPlayer)));
            }
        }
    }

    void ProtocolGame::sendRemoveCreature(const Creature*, const Position& pos, uint32_t stackpos)
    {
        if(!canSee(pos))
            return;

        NetworkMessage_ptr msg = getOutputBuffer();
        if(msg)
        {
            TRACK_MESSAGE(msg);
            RemoveTileItem(msg, pos, stackpos);
        }
    }

    void ProtocolGame::sendMoveCreature(const Creature* creature, const Tile*, const Position& newPos,
        uint32_t newStackpos, const Tile*, const Position& oldPos, uint32_t oldStackpos, bool teleport)
    {
        if(creature == player)
        {
            NetworkMessage_ptr msg = getOutputBuffer();
            if(msg)
            {
                TRACK_MESSAGE(msg);
                if(teleport || oldStackpos >= 10)
                {
                    RemoveTileItem(msg, oldPos, oldStackpos);
                    AddMapDescription(msg, newPos);
                }
                else
                {
                    if(oldPos.z != 7 || newPos.z < ?
                    {
                        msg->put<char>(0x6D);
                        msg->putPosition(oldPos);
                        msg->put<char>(oldStackpos);
                        msg->putPosition(newPos);
                    }
                    else
                        RemoveTileItem(msg, oldPos, oldStackpos);

                    if(newPos.z > oldPos.z)
                        MoveDownCreature(msg, creature, newPos, oldPos, oldStackpos);
                    else if(newPos.z < oldPos.z)
                        MoveUpCreature(msg, creature, newPos, oldPos, oldStackpos);

                    if(oldPos.y > newPos.y) // north, for old x
                    {
                        msg->put<char>(0x65);
                        GetMapDescription(oldPos.x - 8, newPos.y - 6, newPos.z, 18, 1, msg);
                    }
                    else if(oldPos.y < newPos.y) // south, for old x
                    {
                        msg->put<char>(0x67);
                        GetMapDescription(oldPos.x - 8, newPos.y + 7, newPos.z, 18, 1, msg);
                    }

                    if(oldPos.x < newPos.x) // east, [with new y]
                    {
                        msg->put<char>(0x66);
                        GetMapDescription(newPos.x + 9, newPos.y - 6, newPos.z, 1, 14, msg);
                    }
                    else if(oldPos.x > newPos.x) // west, [with new y]
                    {
                        msg->put<char>(0x68);
                        GetMapDescription(newPos.x - 8, newPos.y - 6, newPos.z, 1, 14, msg);
                    }
                }
            }
        }
        else if(canSee(oldPos) && canSee(newPos))
        {
            if(!player->canSeeCreature(creature))
                return;

            NetworkMessage_ptr msg = getOutputBuffer();
            if(msg)
            {
                TRACK_MESSAGE(msg);
                if(!teleport && (oldPos.z != 7 || newPos.z < ? && oldStackpos < 10)
                {
                    msg->put<char>(0x6D);
                    msg->putPosition(oldPos);
                    msg->put<char>(oldStackpos);
                    msg->putPosition(newPos);
                }
                else
                {
                    RemoveTileItem(msg, oldPos, oldStackpos);
                    AddTileCreature(msg, newPos, newStackpos, creature);
                }
            }
        }
        else if(canSee(oldPos))
        {
            if(!player->canSeeCreature(creature))
                return;

            NetworkMessage_ptr msg = getOutputBuffer();
            if(msg)
            {
                TRACK_MESSAGE(msg);
                RemoveTileItem(msg, oldPos, oldStackpos);
            }
        }
        else if(canSee(newPos) && player->canSeeCreature(creature))
        {
            NetworkMessage_ptr msg = getOutputBuffer();
            if(msg)
            {
                TRACK_MESSAGE(msg);
                AddTileCreature(msg, newPos, newStackpos, creature);
            }
        }
    }

    //inventory
    void ProtocolGame::sendAddInventoryItem(slots_t slot, const Item* item)
    {
        NetworkMessage_ptr msg = getOutputBuffer();
        if(msg)
        {
            TRACK_MESSAGE(msg);
            AddInventoryItem(msg, slot, item);
        }
    }

    void ProtocolGame::sendUpdateInventoryItem(slots_t slot, const Item* item)
    {
        NetworkMessage_ptr msg = getOutputBuffer();
        if(msg)
        {
            TRACK_MESSAGE(msg);
            UpdateInventoryItem(msg, slot, item);
        }
    }

    void ProtocolGame::sendRemoveInventoryItem(slots_t slot)
    {
        NetworkMessage_ptr msg = getOutputBuffer();
        if(msg)
        {
            TRACK_MESSAGE(msg);
            RemoveInventoryItem(msg, slot);
        }
    }

    //containers
    void ProtocolGame::sendAddContainerItem(uint8_t cid, const Item* item)
    {
        NetworkMessage_ptr msg = getOutputBuffer();
        if(msg)
        {
            TRACK_MESSAGE(msg);
            AddContainerItem(msg, cid, item);
        }
    }

    void ProtocolGame::sendUpdateContainerItem(uint8_t cid, uint8_t slot, const Item* item)
    {
        NetworkMessage_ptr msg = getOutputBuffer();
        if(msg)
        {
            TRACK_MESSAGE(msg);
            UpdateContainerItem(msg, cid, slot, item);
        }
    }

    void ProtocolGame::sendRemoveContainerItem(uint8_t cid, uint8_t slot)
    {
        NetworkMessage_ptr msg = getOutputBuffer();
        if(msg)
        {
            TRACK_MESSAGE(msg);
            RemoveContainerItem(msg, cid, slot);
        }
    }

    void ProtocolGame::sendTextWindow(uint32_t windowTextId, Item* item, uint16_t maxLen, bool canWrite)
    {
        NetworkMessage_ptr msg = getOutputBuffer();
        if(msg)
        {
            TRACK_MESSAGE(msg);
            msg->put<char>(0x96);
            msg->put<uint32_t>(windowTextId);
            msg->putItemId(item);
            if(canWrite)
            {
                msg->put<uint16_t>(maxLen);
                msg->putString(item->getText());
            }
            else
            {
                msg->put<uint16_t>(item->getText().size());
                msg->putString(item->getText());
            }

            const std::string& writer = item->getWriter();
            if(writer.size())
                msg->putString(writer);
            else
                msg->putString("");

            time_t writtenDate = item->getDate();
            if(writtenDate > 0)
                msg->putString(formatDate(writtenDate));
            else
                msg->putString("");
        }
    }

    void ProtocolGame::sendTextWindow(uint32_t windowTextId, uint32_t itemId, const std::string& text)
    {
        NetworkMessage_ptr msg = getOutputBuffer();
        if(msg)
        {
            TRACK_MESSAGE(msg);
            msg->put<char>(0x96);
            msg->put<uint32_t>(windowTextId);
            msg->putItemId(itemId);

            msg->put<uint16_t>(text.size());
            msg->putString(text);

            msg->putString("");
            msg->putString("");
        }
    }

    void ProtocolGame::sendHouseWindow(uint32_t windowTextId, House*,
        uint32_t, const std::string& text)
    {
        NetworkMessage_ptr msg = getOutputBuffer();
        if(msg)
        {
            TRACK_MESSAGE(msg);
            msg->put<char>(0x97);
            msg->put<char>(0x00);
            msg->put<uint32_t>(windowTextId);
            msg->putString(text);
        }
    }

    void ProtocolGame::sendOutfitWindow()
    {
        NetworkMessage_ptr msg = getOutputBuffer();
        if(msg)
        {
            TRACK_MESSAGE(msg);
            msg->put<char>(0xC8);
            AddCreatureOutfit(msg, player, player->getDefaultOutfit(), true);

            std::list<Outfit> outfitList;
            for(OutfitMap::iterator it = player->outfits.begin(); it != player->outfits.end(); ++it)
            {
                if(player->canWearOutfit(it->first, it->second.addons))
                    outfitList.push_back(it->second);
            }

             if(outfitList.size())
            {
                msg->put<char>((size_t)std::min((size_t)OUTFITS_MAX_NUMBER, outfitList.size()));
                std::list<Outfit>::iterator it = outfitList.begin();
                for(int32_t i = 0; it != outfitList.end() && i < OUTFITS_MAX_NUMBER; ++it, ++i)
                {
                    msg->put<uint16_t>(it->lookType);
                    msg->putString(it->name);
                    if(player->hasCustomFlag(PlayerCustomFlag_CanWearAllAddons))
                        msg->put<char>(0x03);
                    else if(!g_config.getBool(ConfigManager::ADDONS_PREMIUM) || player->isPremium())
                        msg->put<char>(it->addons);
                    else
                        msg->put<char>(0x00);
                }
            }
            else
            {
                msg->put<char>(1);
                msg->put<uint16_t>(player->getDefaultOutfit().lookType);
                msg->putString("Your outfit");
                msg->put<char>(player->getDefaultOutfit().lookAddons);
            }

            player->hasRequestedOutfit(true);
        }
    }

    void ProtocolGame::sendQuests()
    {
        NetworkMessage_ptr msg = getOutputBuffer();
        if(msg)
        {
            TRACK_MESSAGE(msg);
            msg->put<char>(0xF0);

            msg->put<uint16_t>(Quests::getInstance()->getQuestCount(player));
            for(QuestList::const_iterator it = Quests::getInstance()->getFirstQuest(); it != Quests::getInstance()->getLastQuest(); ++it)
            {
                if(!(*it)->isStarted(player))
                    continue;

                msg->put<uint16_t>((*it)->getId());
                msg->putString((*it)->getName());
                msg->put<char>((*it)->isCompleted(player));
            }
        }
    }

    void ProtocolGame::sendQuestInfo(Quest* quest)
    {
        NetworkMessage_ptr msg = getOutputBuffer();
        if(msg)
        {
            TRACK_MESSAGE(msg);
            msg->put<char>(0xF1);
            msg->put<uint16_t>(quest->getId());

            msg->put<char>(quest->getMissionCount(player));
            for(MissionList::const_iterator it = quest->getFirstMission(); it != quest->getLastMission(); ++it)
            {
                if(!(*it)->isStarted(player))
                    continue;

                msg->putString((*it)->getName(player));
                msg->putString((*it)->getDescription(player));
            }
        }
    }

    void ProtocolGame::sendVIPLogIn(uint32_t guid)
    {
        NetworkMessage_ptr msg = getOutputBuffer();
        if(msg)
        {
            TRACK_MESSAGE(msg);
            msg->put<char>(0xD3);
            msg->put<uint32_t>(guid);
        }
    }

    void ProtocolGame::sendVIPLogOut(uint32_t guid)
    {
        NetworkMessage_ptr msg = getOutputBuffer();
        if(msg)
        {
            TRACK_MESSAGE(msg);
            msg->put<char>(0xD4);
            msg->put<uint32_t>(guid);
        }
    }

    void ProtocolGame::sendVIP(uint32_t guid, const std::string& name, bool isOnline)
    {
        NetworkMessage_ptr msg = getOutputBuffer();
        if(msg)
        {
            TRACK_MESSAGE(msg);
            msg->put<char>(0xD2);
            msg->put<uint32_t>(guid);
            msg->putString(name);
            msg->put<char>(isOnline ? 1 : 0);
        }
    }

    void ProtocolGame::reloadCreature(const Creature* creature)
    {
        if(!canSee(creature))
            return;

        // we are cheating the client in here!
        uint32_t stackpos = creature->getTile()->getClientIndexOfThing(player, creature);
        if(stackpos >= 10)
            return;

        NetworkMessage_ptr msg = getOutputBuffer();
        if(msg)
        {
            TRACK_MESSAGE(msg);
            std::list<uint32_t>::iterator it = std::find(knownCreatureList.begin(), knownCreatureList.end(), creature->getID());
            if(it != knownCreatureList.end())
            {
                RemoveTileItem(msg, creature->getPosition(), stackpos);
                msg->put<char>(0x6A);

                msg->putPosition(creature->getPosition());
                msg->put<char>(stackpos);
                AddCreature(msg, creature, false, creature->getID());
            }
            else
                AddTileCreature(msg, creature->getPosition(), stackpos, creature);
        }
    }

    void ProtocolGame::AddMapDescription(NetworkMessage_ptr msg, const Position& pos)
    {
        msg->put<char>(0x64);
        msg->putPosition(player->getPosition());
        GetMapDescription(pos.x - 8, pos.y - 6, pos.z, 18, 14, msg);
    }

    void ProtocolGame::AddTextMessage(NetworkMessage_ptr msg, MessageClasses mclass, const std::string& message)
    {
        msg->put<char>(0xB4);
        msg->put<char>(mclass);
        msg->putString(message);
    }

    void ProtocolGame::AddAnimatedText(NetworkMessage_ptr msg, const Position& pos,
        uint8_t color, const std::string& text)
    {
        msg->put<char>(0x84);
        msg->putPosition(pos);
        msg->put<char>(color);
        msg->putString(text);
    }

    void ProtocolGame::AddMagicEffect(NetworkMessage_ptr msg,const Position& pos, uint8_t type)
    {
        msg->put<char>(0x83);
        msg->putPosition(pos);
        msg->put<char>(type + 1);
    }

    void ProtocolGame::AddDistanceShoot(NetworkMessage_ptr msg, const Position& from, const Position& to,
        uint8_t type)
    {
        msg->put<char>(0x85);
        msg->putPosition(from);
        msg->putPosition(to);
        msg->put<char>(type + 1);
    }

    void ProtocolGame::AddCreature(NetworkMessage_ptr msg, const Creature* creature, bool known, uint32_t remove)
    {
        if(!known)
        {
            msg->put<uint16_t>(0x61);
            msg->put<uint32_t>(remove);
            msg->put<uint32_t>(creature->getID());
            msg->putString(creature->getHideName() ? "" : creature->getName());
        }
        else
        {
            msg->put<uint16_t>(0x62);
            msg->put<uint32_t>(creature->getID());
        }

        if(!creature->getHideHealth())
            msg->put<char>((int32_t)std::ceil(((float)creature->getHealth()) * 100 / std::max(creature->getMaxHealth(), (int32_t)1)));
        else
            msg->put<char>(0x00);

        msg->put<char>((uint8_t)creature->getDirection());
        AddCreatureOutfit(msg, creature, creature->getCurrentOutfit());

        LightInfo lightInfo;
        if(creature == player && player->hasCustomFlag(PlayerCustomFlag_HasFullLight))
        {
            lightInfo.level = 0xFF;
            lightInfo.color = 215;
        }
        else
            creature->getCreatureLight(lightInfo);

        msg->put<char>(lightInfo.level);
        msg->put<char>(lightInfo.color);

        msg->put<uint16_t>(creature->getStepSpeed());
        msg->put<char>(player->getSkullType(creature));
        msg->put<char>(player->getPartyShield(creature));
        if(!known)
            msg->put<char>(player->getGuildEmblem(creature));

        msg->put<char>(!player->canWalkthrough(creature));
    }

    void ProtocolGame::AddPlayerStats(NetworkMessage_ptr msg)
    {
        msg->AddByte(0xA0);
        if (player->getPlayerInfo(PLAYERINFO_MAXHEALTH) > 0)
        {
            msg->AddU16(uint16_t(player->getHealth() * 100 / player->getPlayerInfo(PLAYERINFO_MAXHEALTH)));
            msg->AddU16(100);
        }
        else
        {
            msg->AddU16(0);
            msg->AddU16(0);
        }
        msg->AddU32(uint32_t(player->getFreeCapacity() * 100));
        uint64_t experience = player->getExperience();
        if(experience > 0x7FFFFFFF) // client debugs after 2,147,483,647 exp
            msg->AddU32(0x7FFFFFFF);
        else
            msg->AddU32(experience);

        msg->AddU16(player->getPlayerInfo(PLAYERINFO_LEVEL));
        msg->AddByte(player->getPlayerInfo(PLAYERINFO_LEVELPERCENT));
        if (player->getPlayerInfo(PLAYERINFO_MAXMANA) > 0)
        {
            msg->AddU16(player->getPlayerInfo(PLAYERINFO_MANA) * 100 / player->getPlayerInfo(PLAYERINFO_MAXMANA));
            msg->AddU16(100);
        }
        else
        {
            msg->AddU16(0);
            msg->AddU16(0);
        }
        msg->AddByte(player->getPlayerInfo(PLAYERINFO_MAGICLEVEL));
        msg->AddByte(player->getPlayerInfo(PLAYERINFO_MAGICLEVELPERCENT));
        msg->AddByte(player->getPlayerInfo(PLAYERINFO_SOUL));
        msg->AddU16(player->getStaminaMinutes());
    }

    void ProtocolGame::AddPlayerSkills(NetworkMessage_ptr msg)
    {
        msg->put<char>(0xA1);
        msg->put<char>(player->getSkill(SKILL_FIST, SKILL_LEVEL));
        msg->put<char>(player->getSkill(SKILL_FIST, SKILL_PERCENT));
        msg->put<char>(player->getSkill(SKILL_CLUB, SKILL_LEVEL));
        msg->put<char>(player->getSkill(SKILL_CLUB, SKILL_PERCENT));
        msg->put<char>(player->getSkill(SKILL_SWORD, SKILL_LEVEL));
        msg->put<char>(player->getSkill(SKILL_SWORD, SKILL_PERCENT));
        msg->put<char>(player->getSkill(SKILL_AXE, SKILL_LEVEL));
        msg->put<char>(player->getSkill(SKILL_AXE, SKILL_PERCENT));
        msg->put<char>(player->getSkill(SKILL_DIST, SKILL_LEVEL));
        msg->put<char>(player->getSkill(SKILL_DIST, SKILL_PERCENT));
        msg->put<char>(player->getSkill(SKILL_SHIELD, SKILL_LEVEL));
        msg->put<char>(player->getSkill(SKILL_SHIELD, SKILL_PERCENT));
        msg->put<char>(player->getSkill(SKILL_FISH, SKILL_LEVEL));
        msg->put<char>(player->getSkill(SKILL_FISH, SKILL_PERCENT));
    }

    void ProtocolGame::AddCreatureSpeak(NetworkMessage_ptr msg, const Creature* creature, SpeakClasses type,
        std::string text, uint16_t channelId, uint32_t time/*= 0*/, Position* pos/* = NULL*/, ProtocolGame* pg) //CAST
    {
        msg->put<char>(0xAA);
        if(creature)
        {
            const Player* speaker = creature->getPlayer();
            if(speaker)
            {
                msg->put<uint32_t>(++g_chat.statement);
                g_chat.statementMap[g_chat.statement] = text;
            }
            else
                msg->put<uint32_t>(0x00);

            if(creature->getSpeakType() != SPEAK_CLASS_NONE)
                type = creature->getSpeakType();

            std::string pname;
            if(speaker && pg != NULL && pg->isCast) {//CAST
                pname = pg->viewerName;
            }
            else
                pname = creature->getName();

            switch(type)
            {
                case SPEAK_CHANNEL_RA:
                    msg->putString("");
                    break;
                case SPEAK_RVR_ANSWER:
                    msg->putString("Gamemaster");
                    break;
                default:
                    msg->putString(!creature->getHideName() ? pname: ""); //CAST
                    break;
            }

            if(speaker && type != SPEAK_RVR_ANSWER && !speaker->isAccountManager()
                && !speaker->hasCustomFlag(PlayerCustomFlag_HideLevel) && (pg == NULL || (pg != NULL && !pg->getIsCast()))) //CAST
                msg->put<uint16_t>(speaker->getPlayerInfo(PLAYERINFO_LEVEL));
            else
                msg->put<uint16_t>(0x00);

        }
        else
        {
            msg->put<uint32_t>(0x00);
            msg->putString("");
            msg->put<uint16_t>(0x00);
        }

        msg->put<char>(type);
        switch(type)
        {
            case SPEAK_SAY:
            case SPEAK_WHISPER:
            case SPEAK_YELL:
            case SPEAK_MONSTER_SAY:
            case SPEAK_MONSTER_YELL:
            case SPEAK_PRIVATE_NP:
            {
                if(pos)
                    msg->putPosition(*pos);
                else if(creature)
                    msg->putPosition(creature->getPosition());
                else
                    msg->putPosition(Position(0,0,7));

                break;
            }

            case SPEAK_CHANNEL_Y:
            case SPEAK_CHANNEL_RN:
            case SPEAK_CHANNEL_RA:
            case SPEAK_CHANNEL_O:
            case SPEAK_CHANNEL_W:
                msg->put<uint16_t>(channelId);
                break;

            case SPEAK_RVR_CHANNEL:
            {
                msg->put<uint32_t>(uint32_t(OTSYS_TIME() / 1000 & 0xFFFFFFFF) - time);
                break;
            }

            default:
                break;
        }

        msg->putString(text);
    }

    void ProtocolGame::AddCreatureHealth(NetworkMessage_ptr msg,const Creature* creature)
    {
        msg->put<char>(0x8C);
        msg->put<uint32_t>(creature->getID());
        if(!creature->getHideHealth())
            msg->put<char>((int32_t)std::ceil(((float)creature->getHealth()) * 100 / std::max(creature->getMaxHealth(), (int32_t)1)));
        else
            msg->put<char>(0x00);
    }

    void ProtocolGame::AddCreatureOutfit(NetworkMessage_ptr msg, const Creature* creature, const Outfit_t& outfit, bool outfitWindow/* = false*/)
    {
        if(outfitWindow || !creature->getPlayer() || (!creature->isInvisible() && (!creature->isGhost()
            || !g_config.getBool(ConfigManager::GHOST_INVISIBLE_EFFECT))))
        {
            msg->put<uint16_t>(outfit.lookType);
            if(outfit.lookType)
            {
                msg->put<char>(outfit.lookHead);
                msg->put<char>(outfit.lookBody);
                msg->put<char>(outfit.lookLegs);
                msg->put<char>(outfit.lookFeet);
                msg->put<char>(outfit.lookAddons);
            }
            else if(outfit.lookTypeEx)
                msg->putItemId(outfit.lookTypeEx);
            else
                msg->put<uint16_t>(outfit.lookTypeEx);
        }
        else
            msg->put<uint32_t>(0x00);
    }

    void ProtocolGame::AddWorldLight(NetworkMessage_ptr msg, const LightInfo& lightInfo)
    {
        msg->put<char>(0x82);
        msg->put<char>(player->hasCustomFlag(PlayerCustomFlag_HasFullLight) ? 0xFF : lightInfo.level);
        msg->put<char>(lightInfo.color);
    }

    void ProtocolGame::AddCreatureLight(NetworkMessage_ptr msg, const Creature* creature)
    {
        msg->put<char>(0x8D);
        msg->put<uint32_t>(creature->getID());

        LightInfo lightInfo;
        if(creature == player && player->hasCustomFlag(PlayerCustomFlag_HasFullLight))
        {
            lightInfo.level = 0xFF;
            lightInfo.color = 215;
        }
        else
            creature->getCreatureLight(lightInfo);

        msg->put<char>(lightInfo.level);
        msg->put<char>(lightInfo.color);
    }

    //tile
    void ProtocolGame::AddTileItem(NetworkMessage_ptr msg, const Position& pos, uint32_t stackpos, const Item* item)
    {
        if(stackpos >= 10)
            return;

        msg->put<char>(0x6A);
        msg->putPosition(pos);
        msg->put<char>(stackpos);
        msg->putItem(item);
    }

    void ProtocolGame::AddTileCreature(NetworkMessage_ptr msg, const Position& pos, uint32_t stackpos, const Creature* creature)
    {
        if(stackpos >= 10)
            return;

        msg->put<char>(0x6A);
        msg->putPosition(pos);
        msg->put<char>(stackpos);

        bool known;
        uint32_t removedKnown;
        checkCreatureAsKnown(creature->getID(), known, removedKnown);
        AddCreature(msg, creature, known, removedKnown);
    }

    void ProtocolGame::UpdateTileItem(NetworkMessage_ptr msg, const Position& pos, uint32_t stackpos, const Item* item)
    {
        if(stackpos >= 10)
            return;

        msg->put<char>(0x6B);
        msg->putPosition(pos);
        msg->put<char>(stackpos);
        msg->putItem(item);
    }

    void ProtocolGame::RemoveTileItem(NetworkMessage_ptr msg, const Position& pos, uint32_t stackpos)
    {
        if(stackpos >= 10)
            return;

        msg->put<char>(0x6C);
        msg->putPosition(pos);
        msg->put<char>(stackpos);
    }

    void ProtocolGame::MoveUpCreature(NetworkMessage_ptr msg, const Creature* creature,
        const Position& newPos, const Position& oldPos, uint32_t)
    {
        if(creature != player)
            return;

        msg->put<char>(0xBE); //floor change up
        if(newPos.z == 7) //going to surface
        {
            int32_t skip = -1;
            GetFloorDescription(msg, oldPos.x - 8, oldPos.y - 6, 5, 18, 14, 3, skip); //(floor 7 and 6 already set)
            GetFloorDescription(msg, oldPos.x - 8, oldPos.y - 6, 4, 18, 14, 4, skip);
            GetFloorDescription(msg, oldPos.x - 8, oldPos.y - 6, 3, 18, 14, 5, skip);
            GetFloorDescription(msg, oldPos.x - 8, oldPos.y - 6, 2, 18, 14, 6, skip);
            GetFloorDescription(msg, oldPos.x - 8, oldPos.y - 6, 1, 18, 14, 7, skip);
            GetFloorDescription(msg, oldPos.x - 8, oldPos.y - 6, 0, 18, 14, 8, skip);
            if(skip >= 0)
            {
                msg->put<char>(skip);
                msg->put<char>(0xFF);
            }
        }
        else if(newPos.z > 7) //underground, going one floor up (still underground)
        {
            int32_t skip = -1;
            GetFloorDescription(msg, oldPos.x - 8, oldPos.y - 6, oldPos.z - 3, 18, 14, 3, skip);
            if(skip >= 0)
            {
                msg->put<char>(skip);
                msg->put<char>(0xFF);
            }
        }

        //moving up a floor up makes us out of sync
        //west
        msg->put<char>(0x68);
        GetMapDescription(oldPos.x - 8, oldPos.y + 1 - 6, newPos.z, 1, 14, msg);

        //north
        msg->put<char>(0x65);
        GetMapDescription(oldPos.x - 8, oldPos.y - 6, newPos.z, 18, 1, msg);
    }

    void ProtocolGame::MoveDownCreature(NetworkMessage_ptr msg, const Creature* creature,
        const Position& newPos, const Position& oldPos, uint32_t)
    {
        if(creature != player)
            return;

        msg->put<char>(0xBF); //floor change down
        if(newPos.z == ? //going from surface to underground
        {
            int32_t skip = -1;
            GetFloorDescription(msg, oldPos.x - 8, oldPos.y - 6, newPos.z, 18, 14, -1, skip);
            GetFloorDescription(msg, oldPos.x - 8, oldPos.y - 6, newPos.z + 1, 18, 14, -2, skip);
            GetFloorDescription(msg, oldPos.x - 8, oldPos.y - 6, newPos.z + 2, 18, 14, -3, skip);
            if(skip >= 0)
            {
                msg->put<char>(skip);
                msg->put<char>(0xFF);
            }
        }
        else if(newPos.z > oldPos.z && newPos.z > 8 && newPos.z < 14) //going further down
        {
            int32_t skip = -1;
            GetFloorDescription(msg, oldPos.x - 8, oldPos.y - 6, newPos.z + 2, 18, 14, -3, skip);
            if(skip >= 0)
            {
                msg->put<char>(skip);
                msg->put<char>(0xFF);
            }
        }

        //moving down a floor makes us out of sync
        //east
        msg->put<char>(0x66);
        GetMapDescription(oldPos.x + 9, oldPos.y - 1 - 6, newPos.z, 1, 14, msg);

        //south
        msg->put<char>(0x67);
        GetMapDescription(oldPos.x - 8, oldPos.y + 7, newPos.z, 18, 1, msg);
    }

    //inventory
    void ProtocolGame::AddInventoryItem(NetworkMessage_ptr msg, slots_t slot, const Item* item)
    {
        if(item)
        {
            msg->put<char>(0x78);
            msg->put<char>(slot);
            msg->putItem(item);
        }
        else
            RemoveInventoryItem(msg, slot);
    }

    void ProtocolGame::RemoveInventoryItem(NetworkMessage_ptr msg, slots_t slot)
    {
        msg->put<char>(0x79);
        msg->put<char>(slot);
    }

    void ProtocolGame::UpdateInventoryItem(NetworkMessage_ptr msg, slots_t slot, const Item* item)
    {
        AddInventoryItem(msg, slot, item);
    }

    //containers
    void ProtocolGame::AddContainerItem(NetworkMessage_ptr msg, uint8_t cid, const Item* item)
    {
        msg->put<char>(0x70);
        msg->put<char>(cid);
        msg->putItem(item);
    }

    void ProtocolGame::UpdateContainerItem(NetworkMessage_ptr msg, uint8_t cid, uint8_t slot, const Item* item)
    {
        msg->put<char>(0x71);
        msg->put<char>(cid);
        msg->put<char>(slot);
        msg->putItem(item);
    }

    void ProtocolGame::RemoveContainerItem(NetworkMessage_ptr msg, uint8_t cid, uint8_t slot)
    {
        msg->put<char>(0x72);
        msg->put<char>(cid);
        msg->put<char>(slot);
    }

    void ProtocolGame::sendChannelMessage(std::string author, std::string text, SpeakClasses type, uint8_t channel)
    {
        NetworkMessage_ptr msg = getOutputBuffer();
        if(msg)
        {
            TRACK_MESSAGE(msg);
            msg->put<char>(0xAA);
            msg->put<uint32_t>(0x00);
            msg->putString(author);
            msg->put<uint16_t>(0x00);
            msg->put<char>(type);
            msg->put<uint16_t>(channel);
            msg->putString(text);
        }
    }

    void ProtocolGame::AddShopItem(NetworkMessage_ptr msg, const ShopInfo& item)
    {
        const ItemType& it = Item::items[item.itemId];
        msg->put<uint16_t>(it.clientId);
        if(it.isSplash() || it.isFluidContainer())
            msg->put<char>(fluidMap[item.subType % 8]);
        else if(it.stackable || it.charges)
            msg->put<char>(item.subType);
        else
            msg->put<char>(0x01);

        msg->putString(item.itemName);
        msg->put<uint32_t>(uint32_t(it.weight * 100));
        msg->put<uint32_t>(item.buyPrice);
        msg->put<uint32_t>(item.sellPrice);
    }
    void ProtocolGame::parseExtendedOpcode(NetworkMessage& msg)
    {
    uint8_t opcode = msg.get<char>();
    std::string buffer = msg.getString();

    // processar opcodes adicionais via evento de script lua
    addGameTask(&Game::parsePlayerExtendedOpcode, player->getID(), opcode, buffer);
    }

    void ProtocolGame::sendExtendedOpcode(uint8_t opcode, const std::string& buffer)
    {
    // opcodes estendidos só podem ser enviados para jogadores usando otclient(otc), o tíbia(old) da cipsoft não pode entendê-los

    NetworkMessage_ptr msg = getOutputBuffer();
    if(msg)
    {
    TRACK_MESSAGE(msg);
             msg->put<char>(0x32);
             msg->put<char>(opcode);
            msg->putString(buffer);
    }
    }
     

     

    Meu Networkmessage:

      Mostrar conteúdo oculto

    ////////////////////////////////////////////////////////////////////////
    // OpenTibia - an opensource roleplaying game
    ////////////////////////////////////////////////////////////////////////
    // 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/>.
    ////////////////////////////////////////////////////////////////////////

    #ifndef __NETWORKMESSAGE__
    #define __NETWORKMESSAGE__
    #include "otsystem.h"
    #include "const.h"

    enum SocketCode_t
    {
        SOCKET_CODE_OK,
        SOCKET_CODE_TIMEOUT,
        SOCKET_CODE_ERROR,
    };

    class Item;
    class Position;

    class NetworkMessage
    {
        public:
            NetworkMessage() {reset();}
            virtual ~NetworkMessage() {}

            // resets the internal buffer to an empty message
            void reset(uint16_t size = NETWORK_CRYPTOHEADER_SIZE)
            {
                m_size = 0;
                m_position = size;
            }

            // socket functions
            SocketCode_t read(SOCKET socket, bool ignoreLength, int32_t timeout = NETWORK_RETRY_TIMEOUT);
            SocketCode_t write(SOCKET socket, int32_t timeout = NETWORK_RETRY_TIMEOUT);

            // simple read functions for incoming message
            template<typename T>
            T get(bool peek = false)
            {
                T value = *(T*)(m_buffer + m_position);
                if(peek)
                    return value;

                m_position += sizeof(T);
                return value;
            }

            std::string getString(bool peek = false, uint16_t size = 0);
            std::string getRaw(bool peek = false) {return getString(peek, m_size - m_position);}

            // read for complex types
            Position getPosition();

            // skips count unknown/unused bytes in an incoming message
            void skip(int32_t count) {m_position += count;}

            // simple write functions for outgoing message
            template<typename T>
            void put(T value)
            {
                if(!hasSpace(sizeof(T)))
                    return;

                *(T*)(m_buffer + m_position) = value;
                m_position += sizeof(T);
                m_size += sizeof(T);
            }

            void putString(const std::string& value, bool addSize = true) {putString(value.c_str(), addSize);}
            void putString(const char* value, bool addSize = true);

            void putPadding(uint32_t amount);

            // write for complex types
            void putPosition(const Position& pos);
            void putItem(uint16_t id, uint8_t count);
            void putItem(const Item* item);
            void putItemId(const Item* item);
            void putItemId(uint16_t itemId);

            int32_t decodeHeader();

            // message propeties functions
              uint16_t size() const {return m_size;}
            void setSize(uint16_t size) {m_size = size;}

            uint16_t position() const {return m_position;}
            void setPosition(uint16_t position) {m_position = position;}

            char* buffer() {return (char*)&m_buffer[0];}
            char* bodyBuffer()
            {
                m_position = NETWORK_HEADER_SIZE;
                return (char*)&m_buffer[NETWORK_HEADER_SIZE];
            }
            
    #ifdef __TRACK_NETWORK__
            virtual void Track(std::string file, int32_t line, std::string func) {}
            virtual void clearTrack() {}

    #endif
        protected:
            // used to check available space while writing
            inline bool hasSpace(int32_t size) {return (size + m_position < NETWORK_MAX_SIZE - 16);}

            // message propeties
            uint16_t m_size;
            uint16_t m_position;

            // message data
            uint8_t m_buffer[NETWORK_MAX_SIZE];
    };

    typedef boost::shared_ptr<NetworkMessage> NetworkMessage_ptr;
    #endif
     

     

    Sei que o problema esta no NetworkMessage.h porem nao sei como resolver por saber pouco de C.

     

    A modificacao que fiz foi alterar a função AddPlayerStats pela a que esta no topico da vida e mana por porcentagem.

    Estou usando o CodeBlocks para compilar.

     

    Se alguem ouder me ajudar, agradeco demais! Vi que mais gente estava com esse problema tambem.

    Tenta seguir esse topico.

     

     

  9. 14 horas atrás, Mallruk disse:

    .Qual servidor ou website você utiliza como base?  Skelot

     

    Qual o motivo deste tópico? Suporte

     

    Está surgindo algum erro? Se sim coloque-o aqui. 

     

    Você tem o código disponível? Se tiver publique-o aqui: 

    
     

     

    Você tem alguma imagem que possa auxiliar no problema? Se sim, coloque-a aqui. 

     

    Screenshot_13.jpg



    onde você pegou essa base? poderia me enviar o link?

  10. Seria legal adicionar algum modo que nao sei ainda qual seria o "ideal", de os outros players do servidor remover o bijuu de dentro do jinchuuriki, vou dar algumas ideias "aleatorias para isso" Quando o player que possui o jinchuuriki tiver com 5% da vida, alguem player pode tentar quebrar o selo da maldição, assim tendo uma % bem baixa de consegui, e uma % de nao da certo e esse Player que tentou acabar morrendo, outra forma, poderia ser quando o player que possui jinchuuriki morrer uma para algum player, o player vai ganhando uma %, exemplo, 1% de chance da bijuu ser solta, morreu denovo, 2%, e assim até um limite de 20% dai sempre que esse jinchuuriki morrer tem 20% do bijuu sair do seu corpo.

  11. 25 minutos atrás, diarmaint disse:

    @Ackerzin
    Deixa eu tentar entender aqui,

    EDIT--

    tá dando pra usar 3x

    mas eu diminui a quantidade de skill ganho, então tá tudo beleza !

    
    if getPlayerStorageValue(cid, 19221) < 2 then ---se for menor que 2
    
    setPlayerStorageValue(cid, 19221, getPlayerStorageValue(cid, 19221)+1) vai adicionar +1, é isso ?
    
    

    sim isso mesmo, faz o seguinte, se quiser apenas 2 mesmo, poem isso no seu config.lua

     

    if getPlayerStorageValue(cid, 19221) == -1 then
    setPlayerStorageValue(cid, 19221, 1) 
    end

    e altera essa linha para 
     

    if getPlayerStorageValue(cid, 19221) < 3

     

     

    pra funcionar essa modificação, ou reinicia o servidor ou apos dar reload creatuerscripts, reloga seu char.

  12. 7 minutos atrás, diarmaint disse:

    @Ackerzin é ats de naruto :s

    @RicK Sanchez existe sim.

     

    diminui para 50 de skill galera, deu tudo certo!, 

    agora como posso modificar para poder usar essa alavanca apenas 2x?

     

    function onUse(cid, item, fromPosition, itemEx, toPosition)
    local position1 = {x=getPlayerPosition(cid).x+1, y=getPlayerPosition(cid).y+1, z=getPlayerPosition(cid).z}
    local Gain = 50
    
    if getPlayerStorageValue(cid, 19221) < 2 then
    doPlayerAddSkill(cid, 0, Gain)
    doPlayerAddSkill(cid, 1, Gain)
    doPlayerAddSkill(cid, 2, Gain)
    doPlayerAddSkill(cid, 3, Gain)
    doPlayerAddSkill(cid, 4, Gain)
    doPlayerAddSkill(cid, 5, Gain)
    doPlayerAddSkill(cid, 6, Gain)
    doPlayerAddMagLevel(cid, Gain)
    doPlayerSendTextMessage(cid, 22, "SKills+++")
    doSendMagicEffect(position1, 186)
    setPlayerStorageValue(cid, 19221, getPlayerStorageValue(cid, 19221)+1)
    else
    doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, "Não há nada para você aqui.")
    end
    return TRUE
    end 

     

  13. 7 minutos atrás, diarmaint disse:

    .Qual servidor ou website você utiliza como base? 

    0.4 8.60

    Qual o motivo deste tópico? 

    Estou tentando fazer uma alavanca que dê skills, ela funciona, mas assim que clico da dbug no cliente, quando entro novamente no personagem, as skills estão lá!

    não sei aonde está o problema.

    Está surgindo algum erro? Se sim coloque-o aqui. 

     

    Você tem o código disponível? Se tiver publique-o aqui: 

    
    function onUse(cid, item, fromPosition, itemEx, toPosition)
    local position1 = {x=getPlayerPosition(cid).x+1, y=getPlayerPosition(cid).y+1, z=getPlayerPosition(cid).z}
    
    local Gain = 90
    
    
    
    if getPlayerStorageValue(cid, 19221) < 1 then
    
    
    
    doPlayerAddSkill(cid, 0, Gain)
    doPlayerAddSkill(cid, 1, Gain)
    doPlayerAddSkill(cid, 2, Gain)
    doPlayerAddSkill(cid, 3, Gain)
    doPlayerAddSkill(cid, 4, Gain)
    doPlayerAddSkill(cid, 5, Gain)
    doPlayerAddSkill(cid, 6, Gain)
    doPlayerAddMagLevel(cid, Gain)
    
    
    doPlayerSendTextMessage(cid, 22, "SKills+++")
    doSendMagicEffect(position1, 186)
    
    setPlayerStorageValue(cid, 19221, 1)
    else
    doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, "Não há nada para você aqui.")
    end
    
    return TRUE
    end 

     

    Você tem alguma imagem que possa auxiliar no problema? Se sim, coloque-a aqui. 

     

    Tenta mudar a quantidade de skills que ganhar para um pouco menos, exemplo 1 ou 2, se eu nao me engano tem uma quantia que tal vocação pode ter de cada skill, imagina um Knight com 90 de ML? é isso sepa.

  14. 2 horas atrás, diarmaint disse:

    .Qual servidor ou website você utiliza como base? 

    0,4 8.60

    Qual o motivo deste tópico? 

    Estou com o seguinte erro no script que o @Yan Liima postou no xt,
    quando o player morre para aquele fogo da forcefield, ou aquele espeto no chão que aparece ao pisar, está ocorrendo esse erro.

    eu sei que o erro ocorre pois não é encontrado o monstro/player que causou a morte do jogador, visto que o channel avisa quando o player é morto par alguma dessas opções.

    como posso resolver isso ?

    Está surgindo algum erro? Se sim coloque-o aqui. 

     

    Você tem o código disponível? Se tiver publique-o aqui: 

    
     -- Coded by Zoom..
    local info, win, lose = "%s [Level: %s] foi mort%s pelo %s %s%s", "%s obteve %s frags seguidos após derrotar %s.", "%s acabou de impedir que %s fizesse uma sequência de %s frags seguidos."
    local frags, storage = {2, 5, 8, 10, 15, 20, 35, 45, 50}, 30045
    
    function onDeath(cid, corpse, deathList)
    if(not isPlayer(cid)) then
    return true
    end
    
    local target = deathList[1]
    doCreatureSetStorage(target, storage, getCreatureStorage(target, storage) + (getCreatureStorage(target, storage) == -1 and 2 or 1))
    
    for _, pid in ipairs(getPlayersOnline()) do
    doPlayerSendChannelMessage(pid, '', info:format(getCreatureName(cid), getPlayerLevel(cid), getPlayerSex(cid) == 1 and "o" or "a", isPlayer(target) and "player" or "monstro", getCreatureName(target), isPlayer(target) and " [Level: "..getPlayerLevel(target).."]." or "."), TALKTYPE_CHANNEL_O, 0xF)
    for _, frag in ipairs(frags) do
    if(getCreatureStorage(target, storage) == frag) then
    doPlayerSendChannelMessage(pid, '', win:format(getCreatureName(target), frag, getCreatureName(cid)), TALKTYPE_CHANNEL_W, 0xF)
    end
    
    if(getCreatureStorage(cid, storage) >= frag) then
    doPlayerSendChannelMessage(pid, '', lose:format(getCreatureName(target), getCreatureName(cid), getCreatureStorage(cid, storage)+1), TALKTYPE_CHANNEL_RN, 0xF)
    end
    end
    end
    
    doCreatureSetStorage(cid, storage, 0)
    return true
    end

     

    Você tem alguma imagem que possa auxiliar no problema? Se sim, coloque-a aqui. 

     

    Eu utilizo esse aqui, muito da hora.

     

    -- Coded by Zoom..
    local info = {
    	[1] = "%s [Level: %s] estilhaçou %s%s.",
    	[2] = "Se %s [Level: %s] continuar assim, %s%s vai morrer dentro da PZ.",
    	[3] = "%s [Level: %s] mandou um brutality em %s%s.",
    	[4] = "%s [Level: %s] fez a vida abandonar %s%s.",
    	[5] = "%s [Level: %s] forrou o chão com o sangue de %s%s.",
    	[6] = "%s [Level: %s] aniquilou %s%s.",
    	[7] = "%s [Level: %s] acabou de derrotar %s%s.",
    	[8] = "%s [Level: %s] está com o sangue de %s%s nas mãos.",
    	[9] = "%s [Level: %s] destruiu %s%s.",
    	[10] = "%s [Level: %s] da boas vindas a %s%s no circo de soled.",
    	[11] = "%s [Level: %s] fará %s%s ter pesadelos por um tempo.",
    	[12] = "%s [Level: %s] está sendo cruel com %s%s.",
    	[13] = "Que isso %s [Level: %s], melhor %s%s ir treinar um pouco.",
    	[14] = "%s [Level: %s] venceu a luta contra %s%s.",
    	[15] = "%s [Level: %s] trouxe dor e sofrimento para %s%s.",
    	[16] = "%s [Level: %s] assassinou %s%s.",
    	[17] = "%s [Level: %s] castigou %s%s.",
    	[18] = "%s [Level: %s] enfrentou e derrubou %s%s.",
        [19] = "%s [Level: %s] matou %s%s.",
    	[20] = "%s [Level: %s] casou %s%s com a morte.",
    	[21] = "%s [Level: %s] purificou %s%s."
    }
    
    local lose, win = "%s acabou de impedir que %s fizesse uma sequência de %s frags seguidos.", "%s obteve %s frags seguidos após derrotar %s."
    local frags, storage = {3, 5, 8, 10}, 30045
    
    function onDeath(cid, corpse, deathList)
    local target = deathList[1]
    
    if(not isPlayer(cid) or not isPlayer(target)) then
    	return true
    end
    
    	doCreatureSetStorage(target, storage, getCreatureStorage(target, storage) + (getCreatureStorage(target, storage) == -1 and 2 or 1))
    	for _, pid in ipairs(getPlayersOnline()) do
    		doPlayerSendChannelMessage(pid, '', info[math.random(21)]:format(getCreatureName(target), isPlayer(target) and getPlayerLevel(target), getCreatureName(cid), " [Level: "..getPlayerLevel(cid).."]"), TALKTYPE_CHANNEL_ORANGE, 0xF)
    		for _, frag in ipairs(frags) do			
    			if(getCreatureStorage(target, storage) == frag) then
    				doPlayerSendChannelMessage(pid, '', win:format(getCreatureName(target), frag, getCreatureName(cid)), TALKTYPE_CHANNEL_MANAGEMENT, 0xF)
    			end
    		end
    	end
    
    	doCreatureSetStorage(cid, storage, 0)
    	return true
    end

     

  15. 1 hora atrás, Cjaker disse:

    Heyo, venho disponibilizar umas ferramentas que utilizo pra conseguir obter meus arquivos protegidos dentro de um .exe.
    Serve mais pra caso você usou protetores como Enigma, Molebox e entre outros.
    Use os quatro softwares antes de dizer que não funcionou, caso realmente não conseguiu então os softwares não são compatíveis com a proteção que está utilizando.
    OBS: Estou disponibilizando para que você possa recuperar seus arquivos, não use com intenções maliciosas!

    > Os softwares não são meus e podem ser facilmente encontrados no Google <

    [Downloads]

    demoleition.exe 633 kB · 0 downloads
    demoleitionv.exe 632 kB · 0 downloads
    demoleitionVS.exe 664 kB · 0 downloads
    EnigmaVBUnpacker.exe 615 kB · 0 downloads


    [Scans]
    https://www.virustotal.com/gui/file/2c0b8ceaeb5e05590e397daed3d48d77d06f04583508e3819d79cb945b71a164/detection
    https://www.virustotal.com/gui/file/331f8e90ed61c5f64c32585a232885291eabb351b28fb3bd194f26d67fc5e181/detection
    https://www.virustotal.com/gui/file/d66188a6034b099a3884d06fc79d03b72c5274ff8dfce36ab012fdb26566a645/detection
    https://www.virustotal.com/gui/file/07aba08e7b9c410c4713ea30b386889d3cd15d88d8e3ca12f907f8a39ce0cee9/detection

    OBS: Estou disponibilizando para que você possa recuperar seus arquivos, não use com intenções maliciosas!

    OBRIGADO MESTRE, ESSA PARTE AQUI FOI SENSACIONAL <3

×
×
  • Criar Novo...

Informação Importante

Confirmação de Termo