Beispiel #1
0
int StateGame::OnGMCommand_LoadMonster (IPacket &packet)
{
    uint32_t ID = packet.Read<uint32_t>();

    uint8_t quantity = packet.Read<uint8_t>();

    uint8_t type = packet.Read<uint8_t>();

    if (!packet.EndOfStream())
        return MSG_ERROR_SIZE;

    if (!quantity)
        quantity = 1;

    boost::shared_ptr<Player> player = static_cast<srv::Connection*>(m_connection)->GetPlayer();

    if (!player)
        return MSG_ERROR;

    if(m_server->GetWorld()->IsInsideTown(player->get_position()))
        return MSG_SUCCESS;

    boost::shared_ptr<NPC> mob;
    std::vector<boost::shared_ptr<NPC> > list;

    World *world = m_server->GetWorld();

    for (uint16_t i = 0; i < quantity; ++i)
    {
        mob = world->GetCharacterFactory()->Create(ID);

        if (!mob)
        {
            syslog(LOG_INFO,"Failed to create NPC with ID = %i",ID);
            return MSG_SUCCESS;
        }

        mob->set_position(player->get_position());

        list.push_back(mob);
    }

    world->InsertNPC(list,player->get_position());

    return MSG_SUCCESS;
}
int StateLobby::OnCreateCharacter (IPacket &packet)
{
    /**
     *
     *  BASIC ITEMS ID'S
     *  (THE ID MIGHT CHANGE ON FUTURE UPDATES SO IT NEEDS TO BE CHECKED)
     *
     **/

    enum
    {
        /**
         *
         *  CHINESE BASIC ITEMS.
         *
         **/

        ITEM_CH_SWORD_01_A_DEF	= 3632,
        ITEM_CH_BLADE_01_A_DEF,
        ITEM_CH_SPEAR_01_A_DEF,
        ITEM_CH_TBLADE_01_A_DEF,
        ITEM_CH_BOW_01_A_DEF,

        ITEM_CH_M_HEAVY_01_BA_A_DEF,
        ITEM_CH_M_HEAVY_01_LA_A_DEF,
        ITEM_CH_M_HEAVY_01_FA_A_DEF,
        ITEM_CH_M_LIGHT_01_BA_A_DEF,
        ITEM_CH_M_LIGHT_01_LA_A_DEF,
        ITEM_CH_M_LIGHT_01_FA_A_DEF,
        ITEM_CH_M_CLOTHES_01_BA_A_DEF,
        ITEM_CH_M_CLOTHES_01_LA_A_DEF,
        ITEM_CH_M_CLOTHES_01_FA_A_DEF,
        ITEM_CH_W_HEAVY_01_BA_A_DEF,
        ITEM_CH_W_HEAVY_01_LA_A_DEF,
        ITEM_CH_W_HEAVY_01_FA_A_DEF,
        ITEM_CH_W_LIGHT_01_BA_A_DEF,
        ITEM_CH_W_LIGHT_01_LA_A_DEF,
        ITEM_CH_W_LIGHT_01_FA_A_DEF,
        ITEM_CH_W_CLOTHES_01_BA_A_DEF,
        ITEM_CH_W_CLOTHES_01_LA_A_DEF,
        ITEM_CH_W_CLOTHES_01_FA_A_DEF,
        ITEM_CH_SHIELD_01_A_DEF = 10488,

        ITEM_ETC_AMMO_ARROW_01_DEF = 3655,
        ITEM_ETC_AMMO_BOLT_01_DEF = 10487,

        /**
         *
         *  EUROPEAN BASIC ITEMS.
         *
         **/

        ITEM_EU_DAGGER_01_A_DEF = 10489,
        ITEM_EU_SWORD_01_A_DEF,
        ITEM_EU_TSWORD_01_A_DEF,
        ITEM_EU_AXE_01_A_DEF,
        ITEM_EU_CROSSBOW_01_A_DEF,
        ITEM_EU_DARKSTAFF_01_A_DEF,
        ITEM_EU_TSTAFF_01_A_DEF,
        ITEM_EU_HARP_01_A_DEF,
        ITEM_EU_STAFF_01_A_DEF,
        ITEM_EU_SHIELD_01_A_DEF,

        ITEM_EU_M_HEAVY_01_BA_A_DEF = 11219,
        ITEM_EU_M_HEAVY_01_LA_A_DEF,
        ITEM_EU_M_HEAVY_01_FA_A_DEF,
        ITEM_EU_M_LIGHT_01_BA_A_DEF,
        ITEM_EU_M_LIGHT_01_LA_A_DEF,
        ITEM_EU_M_LIGHT_01_FA_A_DEF,
        ITEM_EU_M_CLOTHES_01_BA_A_DEF,
        ITEM_EU_M_CLOTHES_01_LA_A_DEF,
        ITEM_EU_M_CLOTHES_01_FA_A_DEF,
        ITEM_EU_W_HEAVY_01_BA_A_DEF,
        ITEM_EU_W_HEAVY_01_LA_A_DEF,
        ITEM_EU_W_HEAVY_01_FA_A_DEF,
        ITEM_EU_W_LIGHT_01_BA_A_DEF,
        ITEM_EU_W_LIGHT_01_LA_A_DEF,
        ITEM_EU_W_LIGHT_01_FA_A_DEF,
        ITEM_EU_W_CLOTHES_01_BA_A_DEF,
        ITEM_EU_W_CLOTHES_01_LA_A_DEF,
        ITEM_EU_W_CLOTHES_01_FA_A_DEF
    };

    enum
    {
        POS_CHEST,
        POS_LEG,
        POS_FOOT,
        POS_WEAPON
    };

    if (!m_loaded || m_player_list.size() >= MAX_PLAYER_COUNT)
    {
        boost::shared_ptr<OPacket> pkt(new OPacket);
        
        if (!pkt)
            return MSG_ERROR_MEMORY;

        srv_pkt::Lobby(pkt,srv_pkt::LOBBY_ACTION_CREATE,srv_pkt::LOBBY_ERROR_MAX_CHARACTERS);
        m_connection->Send(pkt);
        return MSG_SUCCESS;
    }

    std::string name = packet.Read();

    uint32_t model = packet.Read<uint32_t>();

    uint8_t volume = packet.Read<uint8_t>();

    uint32_t items[4];

    for (int i = 0; i < 4; ++i)
        items[i] = packet.Read<uint32_t>();

    if (!packet.EndOfStream())
        return MSG_ERROR_SIZE;

    /// Validate data sent

    if (!IsNameValid(name))
        return MSG_SUCCESS;

    ///CHECK IF THE ARMOR IS OF THE SAME TYPE
    if (items[0]+1 != items[1] || items[1] +1 != items[2])
        return MSG_ERROR_ARG;

    World *world = m_server->GetWorld();

    ///CHECK THAT THE ITEMS CORRESPOND TO THE RACE,GENDER AND WEAPON
    if ( model >= 1907 && model <= 1932 )
    {
        ///CHINESE MODEL
        if (!world->IsChineseAllowed())
        {
            syslog(LOG_INFO,"This server dont allow creating ch characters.");
            return MSG_ERROR;
        }

        ///CHECK FOR VALID CHINESE WEAPONS
        switch(items[POS_WEAPON])
        {
        case ITEM_CH_SWORD_01_A_DEF:
        case ITEM_CH_BLADE_01_A_DEF:
        case ITEM_CH_SPEAR_01_A_DEF:
        case ITEM_CH_TBLADE_01_A_DEF:
        case ITEM_CH_BOW_01_A_DEF:
            break;
        default:
            return MSG_ERROR_ARG;
        }

        if (model >= 1907 && model <= 1919)
        {
            ///CHECK FOR MEN MODEL AND ITEMS
            if (items[0] > ITEM_CH_M_CLOTHES_01_FA_A_DEF)
                return MSG_ERROR_ARG;
        }
        else
        {
            ///CHECK FOR WOMEN MODEL AND ITEMS
            if (items[0] < ITEM_CH_W_HEAVY_01_BA_A_DEF)
                return MSG_ERROR_ARG;
        }
    }
    else if ( model >= 14477 && model <= 14502 )
    {
        if (!world->IsEuropeanAllowed())
        {
            syslog(LOG_INFO,"This server dont allow creating eu characters.");
            return MSG_ERROR;
        }

         ///CHECK FOR VALID CHINESE WEAPONS
        switch(items[POS_WEAPON])
        {
        case ITEM_EU_DAGGER_01_A_DEF:
        case ITEM_EU_SWORD_01_A_DEF:
        case ITEM_EU_TSWORD_01_A_DEF:
        case ITEM_EU_AXE_01_A_DEF:
        case ITEM_EU_CROSSBOW_01_A_DEF:
        case ITEM_EU_DARKSTAFF_01_A_DEF:
        case ITEM_EU_TSTAFF_01_A_DEF:
        case ITEM_EU_HARP_01_A_DEF:
        case ITEM_EU_STAFF_01_A_DEF:
            break;
        default:
            return MSG_ERROR_ARG;
        }

        if (model >= 14477 && model <= 14489)
        {
            ///CHECK FOR MEN MODEL AND ITEMS
            if (items[0] > ITEM_EU_M_CLOTHES_01_FA_A_DEF)
                return MSG_ERROR_ARG;
        }
        else
        {
            ///CHECK FOR WOMEN MODEL AND ITEMS
            if (items[0] < ITEM_EU_W_HEAVY_01_BA_A_DEF)
                return MSG_ERROR_ARG;
        }
    }
    else
        return MSG_ERROR_ARG;

    std::vector<Item> item_list;
    for (int i = 0; i < 4; ++i)
    {
        Item itm = world->GetItemFactory()->Create(items[i]);
        item_list.push_back(itm);
    }

    ///Look if the initial weapon requires a shield or bolt or arrows.
    uint32_t extraID = 0;

    switch(items[POS_WEAPON])
    {
    case ITEM_CH_SWORD_01_A_DEF:
    case ITEM_CH_BLADE_01_A_DEF:
        extraID = ITEM_CH_SHIELD_01_A_DEF;
        break;
    case ITEM_EU_SWORD_01_A_DEF:
    case ITEM_EU_DARKSTAFF_01_A_DEF:
    case ITEM_EU_STAFF_01_A_DEF:
        extraID = ITEM_EU_SHIELD_01_A_DEF;
        break;
    case ITEM_EU_CROSSBOW_01_A_DEF:
        extraID = ITEM_ETC_AMMO_BOLT_01_DEF;
        break;
    case ITEM_CH_BOW_01_A_DEF:
        extraID = ITEM_ETC_AMMO_ARROW_01_DEF;
        break;
    default:
        break;
    }

    if (extraID)
    {
        try
        {
            Item extra = world->GetItemFactory()->Create(extraID);

            if (extraID == ITEM_ETC_AMMO_ARROW_01_DEF || extraID == ITEM_ETC_AMMO_BOLT_01_DEF)
                extra.set_quantity(extra.get_max_stack());

            item_list.push_back(extra);
        }
        catch (const Exception::InvalidItemID &error)
        {
            syslog(LOG_INFO,"Failed to create item with ID = %i",extraID);
        }
    }

    std::for_each(item_list.begin(),item_list.end(),boost::bind(&set_default_position,_1));

    boost::shared_ptr<Player> player = world->GetCharacterFactory()->Create(model, volume, name, item_list);

    if (!player)
    {
        syslog(LOG_INFO,"Failed to create player with model %i",model);
        return MSG_ERROR;
    }

    m_player_list.push_back(player);

    DB::PLAYER::Create create;
    create(m_server->DBConnection(),static_cast<srv::Connection*>(m_connection)->AccountID(),player,name);

    boost::shared_ptr<OPacket> pkt(new OPacket);

    if (!pkt)
        return MSG_ERROR_MEMORY;

    srv_pkt::Lobby(pkt,srv_pkt::LOBBY_ACTION_CREATE);
    m_connection->Send(pkt);

    return MSG_SUCCESS;
}
void StateLobby::LoadCharacters ()
{
    World *world = m_server->GetWorld();

    DB::PLAYER::Select select;
    std::vector<PlayerProperty>  base_list = select(m_server->DBConnection(),
        static_cast<srv::Connection*>(m_connection)->AccountID());

    boost::shared_ptr<Player> new_player;
    for (size_t i = 0; i < base_list.size(); ++i)
    {
        base_list[i].GM = static_cast<srv::Connection*>(m_connection)->SecurityLevel();

        new_player = world->GetCharacterFactory()->Create(base_list[i]);

        if (!new_player)
        {
            syslog(LOG_INFO,"StateLobby::LoadCharacters - Failed to create character - Name %s.",
                base_list[i].Name.c_str());
            continue;
        }

        m_player_list.push_back(new_player);
     }

    Item new_item;
    for (size_t i = 0; i < m_player_list.size(); ++i)
    {
        DB::ITEM::Select iobj;
        std::vector<Item::extended_type> item_list = iobj(m_server->DBConnection(),m_player_list[i]->ID(),
                                                          STORAGE_INVENTORY);

        boost::shared_ptr<Storage> il = m_player_list[i]->get_storage(STORAGE_INVENTORY);

        for (std::vector<Item::extended_type>::const_iterator j= item_list.begin(); j != item_list.end(); ++j)
        {
            try
            {
                new_item = world->GetItemFactory()->Create(j->id,*j);
                il->InsertItem(new_item);
            }
            catch (Exception::InvalidItemID &error)
            {
                syslog(LOG_INFO,"Lobby::LoadCharacters() - Error while cloning item with ID = %i",j->id);
            }
        }

        item_list = iobj(m_server->DBConnection(),m_player_list[i]->ID(),STORAGE_AVATAR);

        boost::shared_ptr<Storage> al = m_player_list[i]->get_storage(STORAGE_AVATAR);

        for (std::vector<Item::extended_type>::const_iterator j= item_list.begin(); j != item_list.end(); ++j)
        {
            try
            {
                new_item = world->GetItemFactory()->Create(j->id,*j);
                al->InsertItem(new_item);
            }
            catch (Exception::InvalidItemID &error)
            {
                syslog(LOG_INFO,"Lobby::LoadCharacters() - Error while cloning item with ID = %i",j->id);
            }
        }

        m_player_list[i]->RecalculateStats();
    }
}