Ejemplo n.º 1
0
void ItemHandler::handleMessage(MessageIn &msg)
{
    switch (msg.getId())
    {
        case GPMSG_ITEM_APPEAR:
        case GPMSG_ITEMS:
        {
            while (msg.getUnreadLength())
            {
                int itemId = msg.readInt16();
                int x = msg.readInt16();
                int y = msg.readInt16();
                int id = (x << 16) | y; // dummy id

                if (itemId)
                {
                    actorSpriteManager->createItem(id, itemId, Vector(x, y));
                }
                else if (FloorItem *item = actorSpriteManager->findItem(id))
                {
                    actorSpriteManager->destroy(item);
                }
            }
        } break;
    }
}
Ejemplo n.º 2
0
void InventoryHandler::handleMessage(MessageIn &msg)
{
    switch (msg.getId())
    {
        case GPMSG_INVENTORY_FULL:
            player_node->clearInventory();
            // no break!

        case GPMSG_INVENTORY:
            while (msg.getUnreadLength())
            {
                int slot = msg.readInt8();
                if (slot == 255)
                {
                    player_node->setMoney(msg.readInt32());
                    continue;
                }

                int id = msg.readInt16();
                if (slot < EQUIPMENT_SIZE)
                {
                    player_node->mEquipment->setEquipment(slot, id);
                }
                else if (slot >= 32 && slot < 32 + INVENTORY_SIZE)
                {
                    int amount = id ? msg.readInt8() : 0;
                    player_node->setInvItem(slot - 32, id, amount);
                }
            };
            break;
    }
}
Ejemplo n.º 3
0
void ItemHandler::handleMessage(MessageIn &msg)
{
    Uint32 id;
    Uint16 x, y;
    int itemId;

    switch (msg.getId())
    {
        case SMSG_ITEM_VISIBLE:
        case SMSG_ITEM_DROPPED:
            id = msg.readInt32();
            itemId = msg.readInt16();
            msg.readInt8();  // identify flag
            x = msg.readInt16();
            y = msg.readInt16();
            msg.skip(4);     // amount,subX,subY / subX,subY,amount

            floorItemManager->create(id, itemId, x, y, engine->getCurrentMap());
            break;

        case SMSG_ITEM_REMOVE:
            FloorItem *item;
            item = floorItemManager->findById(msg.readInt32());
            if (item)
                floorItemManager->destroy(item);
            break;
    }
}
Ejemplo n.º 4
0
void ItemHandler::handleMessage(MessageIn &msg)
{
    switch (msg.getId())
    {
    case GPMSG_ITEM_APPEAR:
    case GPMSG_ITEMS:
    {
        while (msg.getUnreadLength())
        {
            int itemId = msg.readInt16();
            int x = msg.readInt16();
            int y = msg.readInt16();
            int id = (x << 16) | y; // dummy id

            if (itemId)
            {
                floorItemManager->create(id, itemId, x / 32, y / 32, engine->getCurrentMap());
            }
            else if (FloorItem *item = floorItemManager->findById(id))
            {
                floorItemManager->destroy(item);
            }
        }
    }
    break;
    }
}
Ejemplo n.º 5
0
void ItemHandler::handleMessage(MessageIn &msg)
{
    switch (msg.getId())
    {
        case SMSG_ITEM_VISIBLE:
        case SMSG_ITEM_DROPPED:
            {
                int id = msg.readInt32();
                int itemId = msg.readInt16();
                msg.readInt8();  // identify flag
                int x = msg.readInt16();
                int y = msg.readInt16();
                msg.skip(4);     // amount,subX,subY / subX,subY,amount

                Game *game = Game::instance();
                if (!game)
                    break;

                if (Map *map = game->getCurrentMap())
                    actorSpriteManager->createItem(id, itemId,
                                                   map->getTileCenter(x, y));
            }
            break;

        case SMSG_ITEM_REMOVE:
            if (FloorItem *item = actorSpriteManager->findItem(msg.readInt32()))
                actorSpriteManager->destroyActor(item);
            break;
    }
}
Ejemplo n.º 6
0
void GameHandler::handleNpc(GameClient &client, MessageIn &message)
{
    int id = message.readInt16();
    Actor *actor = findActorNear(client.character, id);
    if (!actor || actor->getType() != OBJECT_NPC)
    {
        sendNpcError(client, id, "Not close enough to NPC\n");
        return;
    }

    Being *npc = static_cast<Being*>(actor);

    switch (message.getId())
    {
        case PGMSG_NPC_SELECT:
            Npc::integerReceived(client.character, message.readInt8());
            break;
        case PGMSG_NPC_NUMBER:
            Npc::integerReceived(client.character, message.readInt32());
            break;
        case PGMSG_NPC_STRING:
            Npc::stringReceived(client.character, message.readString());
            break;
        case PGMSG_NPC_TALK:
            Npc::start(npc, client.character);
            break;
        case PGMSG_NPC_TALK_NEXT:
        default:
            Npc::resume(client.character);
            break;
    }
}
Ejemplo n.º 7
0
void Network::dispatchMessages()
{
    while (messageReady())
    {
        MessageIn msg = getNextMessage();

        MessageHandlerIterator iter = mMessageHandlers.find(msg.getId());

        if (msg.getLength() == 0)
            logger->error("Zero length packet received. Exiting.");

        if (iter != mMessageHandlers.end())
        {
            iter->second->handleMessage(msg);
        }
        else
        {
            logger->log("Unhandled packet: %x", msg.getId());
        }

        skip(msg.getLength());
    }
}
Ejemplo n.º 8
0
void GameHandler::handleTrade(GameClient &client, MessageIn &message)
{
    auto *characterComponent =
            client.character->getComponent<CharacterComponent>();

    int databaseId = characterComponent->getDatabaseID();

    std::stringstream str;
    Trade *t = characterComponent->getTrading();
    if (!t)
        return;

    switch (message.getId())
    {
        case PGMSG_TRADE_CANCEL:
            t->cancel();
            break;
        case PGMSG_TRADE_CONFIRM:
            t->confirm(client.character);
            break;
        case PGMSG_TRADE_AGREED:
            t->agree(client.character);
            // log transaction
            accountHandler->sendTransaction(databaseId,
                                            TRANS_TRADE_END,
                                            "User finished trading");
            break;
        case PGMSG_TRADE_SET_MONEY:
        {
            int money = message.readInt32();
            t->setMoney(client.character, money);
            // log transaction
            str << "User added " << money << " money to trade.";
            accountHandler->sendTransaction(databaseId,
                                            TRANS_TRADE_MONEY, str.str());
        } break;
        case PGMSG_TRADE_ADD_ITEM:
        {
            int slot = message.readInt8();
            t->addItem(client.character, slot, message.readInt8());
            // log transaction
            str << "User add item from slot " << slot;
            accountHandler->sendTransaction(databaseId,
                                            TRANS_TRADE_ITEM, str.str());
        } break;
    }
}
Ejemplo n.º 9
0
void ChatHandler::handleMessage(MessageIn &msg)
{
    switch (msg.getId())
    {
        case GPMSG_SAY:
            handleGameChatMessage(msg);
            break;

        case CPMSG_ENTER_CHANNEL_RESPONSE:
            handleEnterChannelResponse(msg);
            break;

        case CPMSG_LIST_CHANNELS_RESPONSE:
            handleListChannelsResponse(msg);
            break;

        case CPMSG_PRIVMSG:
            handlePrivateMessage(msg);
            break;

        case CPMSG_ANNOUNCEMENT:
            handleAnnouncement(msg);
            break;

        case CPMSG_PUBMSG:
            handleChatMessage(msg);
            break;

        case CPMSG_QUIT_CHANNEL_RESPONSE:
            handleQuitChannelResponse(msg);
            break;

        case CPMSG_LIST_CHANNELUSERS_RESPONSE:
            handleListChannelUsersResponse(msg);
            break;

        case CPMSG_CHANNEL_EVENT:
            handleChannelEvent(msg);
            break;

        case CPMSG_WHO_RESPONSE:
            handleWhoResponse(msg);
            break;
    }
}
Ejemplo n.º 10
0
void EffectHandler::handleMessage(MessageIn &msg)
{
    switch (msg.getId())
    {
    case GPMSG_CREATE_EFFECT_POS:
        handleCreateEffectPos(msg);
        break;
    case GPMSG_CREATE_EFFECT_BEING:
        handleCreateEffectBeing(msg);
        break;
    case GPMSG_CREATE_TEXT_PARTICLE:
        handleCreateTextParticle(msg);
        break;
    case GPMSG_SHAKE:
        handleShake(msg);
        break;
    default:
        break;
    }
}
Ejemplo n.º 11
0
void BuySellHandler::handleMessage(MessageIn &msg)
{
    Being *being = beingManager->findBeing(msg.readInt16());
    if (!being || being->getType() != Being::NPC)
    {
        return;
    }

    current_npc = being->getId();

    switch (msg.getId())
    {
        case GPMSG_NPC_BUY:
            buyDialog->reset();
            buyDialog->setMoney(player_node->getMoney());
            buyDialog->setVisible(true);

            while (msg.getUnreadLength())
            {
                int itemId = msg.readInt16();
                int amount = msg.readInt16();
                int value = msg.readInt16();
                buyDialog->addItem(itemId, amount, value);
            }
            break;

        case GPMSG_NPC_SELL:
            sellDialog->setMoney(player_node->getMoney());
            sellDialog->reset();
            sellDialog->setVisible(true);

            while (msg.getUnreadLength())
            {
                int itemId = msg.readInt16();
                int amount = msg.readInt16();
                int value = msg.readInt16();
                sellDialog->addItem(new Item(itemId, amount, false), value);
            }
            break;
    }
}
Ejemplo n.º 12
0
void ServerHandler::processMessage(NetComputer *comp, MessageIn &msg)
{
    GameServer *server = static_cast<GameServer *>(comp);

    switch (msg.getId())
    {
        case GAMSG_REGISTER:
        {
            LOG_DEBUG("GAMSG_REGISTER");
            // TODO: check the credentials of the game server
            server->address = msg.readString();
            server->port = msg.readInt16();
            const std::string password = msg.readString();

            // checks the version of the remote item database with our local copy
            unsigned int dbversion = msg.readInt32();
            LOG_INFO("Game server uses itemsdatabase with version " << dbversion);

            LOG_DEBUG("AGMSG_REGISTER_RESPONSE");
            MessageOut outMsg(AGMSG_REGISTER_RESPONSE);
            if (dbversion == storage->getItemDatabaseVersion())
            {
                LOG_DEBUG("Item databases between account server and "
                    "gameserver are in sync");
                outMsg.writeInt16(DATA_VERSION_OK);
            }
            else
            {
                LOG_DEBUG("Item database of game server has a wrong version");
                outMsg.writeInt16(DATA_VERSION_OUTDATED);
            }
            if (password == Configuration::getValue("net_password", "changeMe"))
            {
                outMsg.writeInt16(PASSWORD_OK);

                // transmit global world state variables
                std::map<std::string, std::string> variables;
                variables = storage->getAllWorldStateVars(Storage::WorldMap);
                for (std::map<std::string, std::string>::iterator i = variables.begin();
                     i != variables.end();
                     i++)
                {
                    outMsg.writeString(i->first);
                    outMsg.writeString(i->second);
                }

                comp->send(outMsg);
            }
            else
            {
                LOG_INFO("The password given by " << server->address << ':' << server->port << " was bad.");
                outMsg.writeInt16(PASSWORD_BAD);
                comp->disconnect(outMsg);
                break;
            }

            LOG_INFO("Game server " << server->address << ':' << server->port
                     << " wants to register " << (msg.getUnreadLength() / 2)
                     << " maps.");

            while (msg.getUnreadLength())
            {
                int id = msg.readInt16();
                LOG_INFO("Registering map " << id << '.');
                if (GameServer *s = getGameServerFromMap(id))
                {
                    LOG_ERROR("Server Handler: map is already registered by "
                              << s->address << ':' << s->port << '.');
                }
                else
                {
                    MessageOut outMsg(AGMSG_ACTIVE_MAP);

                    // Map variables
                    outMsg.writeInt16(id);
                    std::map<std::string, std::string> variables;
                    variables = storage->getAllWorldStateVars(id);

                     // Map vars number
                    outMsg.writeInt16(variables.size());

                    for (std::map<std::string, std::string>::iterator i = variables.begin();
                         i != variables.end();
                         i++)
                    {
                        outMsg.writeString(i->first);
                        outMsg.writeString(i->second);
                    }

                    // Persistent Floor Items
                    std::list<FloorItem> items;
                    items = storage->getFloorItemsFromMap(id);

                    outMsg.writeInt16(items.size()); //number of floor items

                    // Send each map item: item_id, amount, pos_x, pos_y
                    for (std::list<FloorItem>::iterator i = items.begin();
                         i != items.end(); ++i)
                    {
                        outMsg.writeInt32(i->getItemId());
                        outMsg.writeInt16(i->getItemAmount());
                        outMsg.writeInt16(i->getPosX());
                        outMsg.writeInt16(i->getPosY());
                    }

                    comp->send(outMsg);
                    MapStatistics &m = server->maps[id];
                    m.nbEntities = 0;
                    m.nbMonsters = 0;
                }
            }
        } break;

        case GAMSG_PLAYER_DATA:
        {
            LOG_DEBUG("GAMSG_PLAYER_DATA");
            int id = msg.readInt32();
            if (Character *ptr = storage->getCharacter(id, NULL))
            {
                deserializeCharacterData(*ptr, msg);
                if (!storage->updateCharacter(ptr))
                {
                    LOG_ERROR("Failed to update character "
                              << id << '.');
                }
                delete ptr;
            }
            else
            {
                LOG_ERROR("Received data for non-existing character "
                          << id << '.');
            }
        } break;

        case GAMSG_PLAYER_SYNC:
        {
            LOG_DEBUG("GAMSG_PLAYER_SYNC");
            GameServerHandler::syncDatabase(msg);
        } break;

        case GAMSG_REDIRECT:
        {
            LOG_DEBUG("GAMSG_REDIRECT");
            int id = msg.readInt32();
            std::string magic_token(utils::getMagicToken());
            if (Character *ptr = storage->getCharacter(id, NULL))
            {
                int mapId = ptr->getMapId();
                if (GameServer *s = getGameServerFromMap(mapId))
                {
                    registerGameClient(s, magic_token, ptr);
                    MessageOut result(AGMSG_REDIRECT_RESPONSE);
                    result.writeInt32(id);
                    result.writeString(magic_token, MAGIC_TOKEN_LENGTH);
                    result.writeString(s->address);
                    result.writeInt16(s->port);
                    comp->send(result);
                }
                else
                {
                    LOG_ERROR("Server Change: No game server for map " <<
                              mapId << '.');
                }
                delete ptr;
            }
            else
            {
                LOG_ERROR("Received data for non-existing character "
                          << id << '.');
            }
        } break;

        case GAMSG_PLAYER_RECONNECT:
        {
            LOG_DEBUG("GAMSG_PLAYER_RECONNECT");
            int id = msg.readInt32();
            std::string magic_token = msg.readString(MAGIC_TOKEN_LENGTH);

            if (Character *ptr = storage->getCharacter(id, NULL))
            {
                int accountID = ptr->getAccountID();
                AccountClientHandler::prepareReconnect(magic_token, accountID);
                delete ptr;
            }
            else
            {
                LOG_ERROR("Received data for non-existing character "
                          << id << '.');
            }
        } break;

        case GAMSG_GET_VAR_CHR:
        {
            int id = msg.readInt32();
            std::string name = msg.readString();
            std::string value = storage->getQuestVar(id, name);
            MessageOut result(AGMSG_GET_VAR_CHR_RESPONSE);
            result.writeInt32(id);
            result.writeString(name);
            result.writeString(value);
            comp->send(result);
        } break;

        case GAMSG_SET_VAR_CHR:
        {
            int id = msg.readInt32();
            std::string name = msg.readString();
            std::string value = msg.readString();
            storage->setQuestVar(id, name, value);
        } break;

        case GAMSG_SET_VAR_WORLD:
        {
            std::string name = msg.readString();
            std::string value = msg.readString();
            // save the new value to the database
            storage->setWorldStateVar(name, value, Storage::WorldMap);
            // relay the new value to all gameservers
            for (ServerHandler::NetComputers::iterator i = clients.begin();
                i != clients.end();
                i++)
            {
                MessageOut varUpdateMessage(AGMSG_SET_VAR_WORLD);
                varUpdateMessage.writeString(name);
                varUpdateMessage.writeString(value);
                (*i)->send(varUpdateMessage);
            }
        } break;

        case GAMSG_SET_VAR_MAP:
        {
            int mapid = msg.readInt32();
            std::string name = msg.readString();
            std::string value = msg.readString();
            storage->setWorldStateVar(name, value, mapid);
        } break;

        case GAMSG_BAN_PLAYER:
        {
            int id = msg.readInt32();
            int duration = msg.readInt32();
            storage->banCharacter(id, duration);
        } break;

        case GAMSG_CHANGE_PLAYER_LEVEL:
        {
            int id = msg.readInt32();
            int level = msg.readInt16();
            storage->setPlayerLevel(id, level);
        } break;

        case GAMSG_CHANGE_ACCOUNT_LEVEL:
        {
            int id = msg.readInt32();
            int level = msg.readInt16();

            // get the character so we can get the account id
            Character *c = storage->getCharacter(id, NULL);
            if (c)
            {
                storage->setAccountLevel(c->getAccountID(), level);
            }
        } break;

        case GAMSG_STATISTICS:
        {
            while (msg.getUnreadLength())
            {
                int mapId = msg.readInt16();
                ServerStatistics::iterator i = server->maps.find(mapId);
                if (i == server->maps.end())
                {
                    LOG_ERROR("Server " << server->address << ':'
                              << server->port << " should not be sending stati"
                              "stics for map " << mapId << '.');
                    // Skip remaining data.
                    break;
                }
                MapStatistics &m = i->second;
                m.nbEntities = msg.readInt16();
                m.nbMonsters = msg.readInt16();
                int nb = msg.readInt16();
                m.players.resize(nb);
                for (int j = 0; j < nb; ++j)
                {
                    m.players[j] = msg.readInt32();
                }
            }
        } break;

        case GCMSG_REQUEST_POST:
        {
            // Retrieve the post for user
            LOG_DEBUG("GCMSG_REQUEST_POST");
            MessageOut result(CGMSG_POST_RESPONSE);

            // get the character id
            int characterId = msg.readInt32();

            // send the character id of sender
            result.writeInt32(characterId);

            // get the character based on the id
            Character *ptr = storage->getCharacter(characterId, NULL);
            if (!ptr)
            {
                // Invalid character
                LOG_ERROR("Error finding character id for post");
                break;
            }

            // get the post for that character
            Post *post = postalManager->getPost(ptr);

            // send the post if valid
            if (post)
            {
                for (unsigned int i = 0; i < post->getNumberOfLetters(); ++i)
                {
                    // get each letter, send the sender's name,
                    // the contents and any attachments
                    Letter *letter = post->getLetter(i);
                    result.writeString(letter->getSender()->getName());
                    result.writeString(letter->getContents());
                    std::vector<InventoryItem> items = letter->getAttachments();
                    for (unsigned int j = 0; j < items.size(); ++j)
                    {
                        result.writeInt16(items[j].itemId);
                        result.writeInt16(items[j].amount);
                    }
                }

                // clean up
                postalManager->clearPost(ptr);
            }

            comp->send(result);
        } break;

        case GCMSG_STORE_POST:
        {
            // Store the letter for the user
            LOG_DEBUG("GCMSG_STORE_POST");
            MessageOut result(CGMSG_STORE_POST_RESPONSE);

            // get the sender and receiver
            int senderId = msg.readInt32();
            std::string receiverName = msg.readString();

            // for sending it back
            result.writeInt32(senderId);

            // get their characters
            Character *sender = storage->getCharacter(senderId, NULL);
            Character *receiver = storage->getCharacter(receiverName);
            if (!sender || !receiver)
            {
                // Invalid character
                LOG_ERROR("Error finding character id for post");
                result.writeInt8(ERRMSG_INVALID_ARGUMENT);
                break;
            }

            // get the letter contents
            std::string contents = msg.readString();

            std::vector< std::pair<int, int> > items;
            while (msg.getUnreadLength())
            {
                items.push_back(std::pair<int, int>(msg.readInt16(), msg.readInt16()));
            }

            // save the letter
            LOG_DEBUG("Creating letter");
            Letter *letter = new Letter(0, sender, receiver);
            letter->addText(contents);
            for (unsigned int i = 0; i < items.size(); ++i)
            {
                InventoryItem item;
                item.itemId = items[i].first;
                item.amount = items[i].second;
                letter->addAttachment(item);
            }
            postalManager->addLetter(letter);

            result.writeInt8(ERRMSG_OK);
            comp->send(result);
        } break;

        case GAMSG_TRANSACTION:
        {
            LOG_DEBUG("TRANSACTION");
            int id = msg.readInt32();
            int action = msg.readInt32();
            std::string message = msg.readString();

            Transaction trans;
            trans.mCharacterId = id;
            trans.mAction = action;
            trans.mMessage = message;
            storage->addTransaction(trans);
        } break;

        case GCMSG_PARTY_INVITE:
            chatHandler->handlePartyInvite(msg);
            break;

        case GAMSG_CREATE_ITEM_ON_MAP:
        {
            int mapId = msg.readInt32();
            int itemId = msg.readInt32();
            int amount = msg.readInt16();
            int posX = msg.readInt16();
            int posY = msg.readInt16();

            LOG_DEBUG("Gameserver create item " << itemId
                << " on map " << mapId);

            storage->addFloorItem(mapId, itemId, amount, posX, posY);
        } break;

        case GAMSG_REMOVE_ITEM_ON_MAP:
        {
            int mapId = msg.readInt32();
            int itemId = msg.readInt32();
            int amount = msg.readInt16();
            int posX = msg.readInt16();
            int posY = msg.readInt16();

            LOG_DEBUG("Gameserver removed item " << itemId
                << " from map " << mapId);

            storage->removeFloorItem(mapId, itemId, amount, posX, posY);
        } break;

        case GAMSG_ANNOUNCE:
        {
            const std::string message = msg.readString();
            const int senderId = msg.readInt16();
            const std::string senderName = msg.readString();
            chatHandler->handleAnnounce(message, senderId, senderName);
        } break;

        default:
            LOG_WARN("ServerHandler::processMessage, Invalid message type: "
                     << msg.getId());
            MessageOut result(XXMSG_INVALID);
            comp->send(result);
            break;
    }
}
Ejemplo n.º 13
0
void CharServerHandler::handleMessage(MessageIn &msg)
{
    int slot;
    LocalPlayer *tempPlayer;

    switch (msg.getId())
    {
        case APMSG_CHAR_CREATE_RESPONSE:
            handleCharCreateResponse(msg);
            break;

        case APMSG_CHAR_DELETE_RESPONSE:
        {
            int errMsg = msg.readInt8();
            // Character deletion successful
            if (errMsg == ERRMSG_OK)
            {
                delete mCharInfo->getEntry();
                mCharInfo->setEntry(0);
                mCharInfo->unlock();
                new OkDialog("Info", "Player deleted");
            }
            // Character deletion failed
            else
            {
                std::string message = "";
                switch (errMsg)
                {
                    case ERRMSG_NO_LOGIN:
                        message = "Not logged in";
                        break;
                    case ERRMSG_INVALID_ARGUMENT:
                        message = "Selection out of range";
                        break;
                    default:
                        message = "Unknown error";
                }
                mCharInfo->unlock();
                new OkDialog("Error", message);
            }
        }
            break;

        case APMSG_CHAR_INFO:
            tempPlayer = readPlayerData(msg, slot);
            mCharInfo->unlock();
            mCharInfo->select(slot);
            mCharInfo->setEntry(tempPlayer);

            // Close the character create dialog
            if (mCharCreateDialog)
            {
                mCharCreateDialog->scheduleDelete();
                mCharCreateDialog = 0;
            }
            break;

        case APMSG_CHAR_SELECT_RESPONSE:
            handleCharSelectResponse(msg);
            break;
    }
}
Ejemplo n.º 14
0
void PlayerHandler::handleMessage(MessageIn &msg)
{
    switch (msg.getId())
    {
    case SMSG_WALK_RESPONSE:
        /*
         * This client assumes that all walk messages succeed,
         * and that the server will send a correction notice
         * otherwise.
         */
        break;

    case SMSG_PLAYER_WARP:
    {
        std::string mapPath = msg.readString(16);
        bool nearby;
        Uint16 x = msg.readInt16();
        Uint16 y = msg.readInt16();

        logger->log("Warping to %s (%d, %d)", mapPath.c_str(), x, y);

        /*
         * We must clear the local player's target *before* the call
         * to changeMap, as it deletes all beings.
         */
        player_node->stopAttack();

        nearby = (engine->getCurrentMapName() == mapPath);

        // Switch the actual map, deleting the previous one if necessary
        mapPath = mapPath.substr(0, mapPath.rfind("."));
        engine->changeMap(mapPath);

        float scrollOffsetX = 0.0f;
        float scrollOffsetY = 0.0f;

        /* Scroll if neccessary */
        if (!nearby
                || (abs(x - player_node->getTileX()) > MAP_TELEPORT_SCROLL_DISTANCE)
                || (abs(y - player_node->getTileY()) > MAP_TELEPORT_SCROLL_DISTANCE))
        {
            scrollOffsetX = (x - player_node->getTileX()) * 32;
            scrollOffsetY = (y - player_node->getTileY()) * 32;
        }

        player_node->setAction(Being::STAND);
        player_node->mFrame = 0;
        player_node->setTileCoords(x, y);

        logger->log("Adjust scrolling by %d:%d", (int) scrollOffsetX,
                    (int) scrollOffsetY);

        viewport->scrollBy(scrollOffsetX, scrollOffsetY);
    }
    break;

    case SMSG_PLAYER_STAT_UPDATE_1:
    {
        int type = msg.readInt16();
        int value = msg.readInt32();

        switch (type)
        {
        case 0x0000:
            player_node->setWalkSpeed(value);
            break;
        case 0x0004:
            break; // manner
        case 0x0005:
            player_node->setHp(value);
            break;
        case 0x0006:
            player_node->setMaxHp(value);
            break;
        case 0x0007:
            player_node->setMP(value);
            break;
        case 0x0008:
            player_node->setMaxMP(value);
            break;
        case 0x0009:
            player_node->setCharacterPoints(value);
            break;
        case 0x000b:
            player_node->setLevel(value);
            break;
        case 0x000c:
            player_node->setSkillPoints(value);
            break;
        case 0x0018:
            if (value >= player_node->getMaxWeight() / 2 &&
                    player_node->getTotalWeight() <
                    player_node->getMaxWeight() / 2)
            {
                weightNotice = new OkDialog(_("Message"),
                                            _("You are carrying more than "
                                              "half your weight. You are "
                                              "unable to regain health."));
                weightNotice->addActionListener(
                    &weightListener);
            }
            player_node->setTotalWeight(value);
            break;
        case 0x0019:
            player_node->setMaxWeight(value);
            break;

        case 0x0029:
            player_node->setAttributeEffective(ATK, value
                                               + ATTR_BONUS(ATK));
            player_node->setAttributeBase(ATK, value);
            break;
        case 0x002a:
            value += player_node->getAttributeBase(ATK);
            player_node->setAttributeEffective(ATK, value);
            break;

        case 0x002b:
            player_node->setAttributeEffective(MATK, value
                                               + ATTR_BONUS(MATK));
            player_node->setAttributeBase(MATK, value);
            statusWindow->update(StatusWindow::MP);
            break;
        case 0x002c:
            value += player_node->getAttributeBase(MATK);
            player_node->setAttributeEffective(MATK, value);
            statusWindow->update(StatusWindow::MP);
            break;
        case 0x002d:
            player_node->setAttributeEffective(DEF, value
                                               + ATTR_BONUS(DEF));
            player_node->setAttributeBase(DEF, value);
            break;
        case 0x002e:
            value += player_node->getAttributeBase(DEF);
            player_node->setAttributeEffective(DEF, value);
            break;

        case 0x002f:
            player_node->setAttributeEffective(MDEF, value
                                               + ATTR_BONUS(MDEF));
            player_node->setAttributeBase(MDEF, value);
            break;
        case 0x0030:
            value += player_node->getAttributeBase(MDEF);
            player_node->setAttributeEffective(MDEF, value);
            break;

        case 0x0031:
            player_node->setAttributeBase(HIT, value);
            player_node->setAttributeEffective(HIT, value);
            break;

        case 0x0032:
            player_node->setAttributeEffective(FLEE, value
                                               + ATTR_BONUS(FLEE));
            player_node->setAttributeBase(FLEE, value);
            break;
        case 0x0033:
            value += player_node->getAttributeBase(FLEE);
            player_node->setAttributeEffective(FLEE, value);
            break;

        case 0x0034:
            player_node->setAttributeBase(CRIT, value);
            player_node->setAttributeEffective(CRIT, value);
            break;

        case 0x0035:
            player_node->mAttackSpeed = value;
            break;
        case 0x0037:
            player_node->setAttributeBase(JOB, value);
            player_node->setAttributeEffective(JOB, value);
            break;
        case 500:
            player_node->setGMLevel(value);
            break;
        }

        if (player_node->getHp() == 0 && !deathNotice)
        {
            deathNotice = new OkDialog(_("Message"),
                                       randomDeathMessage());
            deathNotice->addActionListener(&deathListener);
            player_node->setAction(Being::DEAD);
        }
    }
    break;

    case SMSG_PLAYER_STAT_UPDATE_2:
        switch (msg.readInt16()) {
        case 0x0001:
            player_node->setExp(msg.readInt32());
            break;
        case 0x0002:
            player_node->setExperience(JOB, msg.readInt32(),
                                       player_node->getExperience(JOB).second);
            break;
        case 0x0014: {
            int curGp = player_node->getMoney();
            player_node->setMoney(msg.readInt32());
            if (player_node->getMoney() > curGp)
                localChatTab->chatLog(strprintf(_("You picked up "
                                                  "%s."),
                                                Units::formatCurrency(player_node->getMoney()
                                                        - curGp).c_str()), BY_SERVER);
        }
        break;
        case 0x0016:
            player_node->setExpNeeded(msg.readInt32());
            break;
        case 0x0017:
            player_node->setExperience(JOB,
                                       player_node->getExperience(JOB).first,
                                       msg.readInt32());
            break;
        }
        break;

    case SMSG_PLAYER_STAT_UPDATE_3: // Update a base attribute
    {
        int type = msg.readInt32();
        int base = msg.readInt32();
        int bonus = msg.readInt32();

        player_node->setAttributeBase(type, base);
        player_node->setAttributeEffective(type, base + bonus);
    }
    break;

    case SMSG_PLAYER_STAT_UPDATE_4: // Attribute increase ack
    {
        int type = msg.readInt16();
        int fail = msg.readInt8();
        int value = msg.readInt8();

        if (fail != 1)
            break;

        int bonus = ATTR_BONUS(type);

        player_node->setAttributeBase(type, value);
        player_node->setAttributeEffective(type, value + bonus);
    }
    break;

    // Updates stats and status points
    case SMSG_PLAYER_STAT_UPDATE_5:
        player_node->setCharacterPoints(msg.readInt16());

        {
            int val = msg.readInt8();
            player_node->setAttributeEffective(STR, val + ATTR_BONUS(STR));
            player_node->setAttributeBase(STR, val);
            statusWindow->setPointsNeeded(STR, msg.readInt8());

            val = msg.readInt8();
            player_node->setAttributeEffective(AGI, val + ATTR_BONUS(AGI));
            player_node->setAttributeBase(AGI, val);
            statusWindow->setPointsNeeded(AGI, msg.readInt8());

            val = msg.readInt8();
            player_node->setAttributeEffective(VIT, val + ATTR_BONUS(VIT));
            player_node->setAttributeBase(VIT, val);
            statusWindow->setPointsNeeded(VIT, msg.readInt8());

            val = msg.readInt8();
            player_node->setAttributeEffective(INTT, val + ATTR_BONUS(INTT));
            player_node->setAttributeBase(INTT, val);
            statusWindow->setPointsNeeded(INTT, msg.readInt8());

            val = msg.readInt8();
            player_node->setAttributeEffective(DEX, val + ATTR_BONUS(DEX));
            player_node->setAttributeBase(DEX, val);
            statusWindow->setPointsNeeded(DEX, msg.readInt8());

            val = msg.readInt8();
            player_node->setAttributeEffective(LUK, val + ATTR_BONUS(LUK));
            player_node->setAttributeBase(LUK, val);
            statusWindow->setPointsNeeded(LUK, msg.readInt8());

            val = msg.readInt16(); // ATK
            player_node->setAttributeBase(ATK, val);
            val += msg.readInt16();  // ATK bonus
            player_node->setAttributeEffective(ATK, val);

            val = msg.readInt16(); // MATK
            player_node->setAttributeBase(MATK, val);
            val += msg.readInt16();  // MATK bonus
            player_node->setAttributeEffective(MATK, val);
            statusWindow->update(StatusWindow::MP);

            val = msg.readInt16(); // DEF
            player_node->setAttributeBase(DEF, val);
            val += msg.readInt16();  // DEF bonus
            player_node->setAttributeEffective(DEF, val);

            val = msg.readInt16(); // MDEF
            player_node->setAttributeBase(MDEF, val);
            val += msg.readInt16();  // MDEF bonus
            player_node->setAttributeEffective(MDEF, val);

            val = msg.readInt16(); // HIT
            player_node->setAttributeBase(ATK, val);
            player_node->setAttributeEffective(ATK, val);

            val = msg.readInt16(); // FLEE
            player_node->setAttributeBase(FLEE, val);
            val += msg.readInt16();  // FLEE bonus
            player_node->setAttributeEffective(FLEE, val);

            val = msg.readInt16();
            player_node->setAttributeBase(CRIT, val);
            player_node->setAttributeEffective(CRIT, val);
        }

        msg.readInt16();  // manner
        break;

    case SMSG_PLAYER_STAT_UPDATE_6:
        switch (msg.readInt16()) {
        case 0x0020:
            statusWindow->setPointsNeeded(STR, msg.readInt8());
            break;
        case 0x0021:
            statusWindow->setPointsNeeded(AGI, msg.readInt8());
            break;
        case 0x0022:
            statusWindow->setPointsNeeded(VIT, msg.readInt8());
            break;
        case 0x0023:
            statusWindow->setPointsNeeded(INTT, msg.readInt8());
            break;
        case 0x0024:
            statusWindow->setPointsNeeded(DEX, msg.readInt8());
            break;
        case 0x0025:
            statusWindow->setPointsNeeded(LUK, msg.readInt8());
            break;
        }
        break;

    case SMSG_PLAYER_ARROW_MESSAGE:
    {
        int type = msg.readInt16();

        switch (type) {
        case 0:
            localChatTab->chatLog(_("Equip arrows first."),
                                  BY_SERVER);
            break;
        default:
            logger->log("0x013b: Unhandled message %i", type);
            break;
        }
    }
    break;
    }
}
Ejemplo n.º 15
0
void AccountHandler::processMessage(NetComputer *comp, MessageIn &message)
{
    AccountClient &client = *static_cast< AccountClient * >(comp);

    switch (message.getId())
    {
        case PAMSG_LOGIN_RNDTRGR:
            LOG_DEBUG("Received msg ... PAMSG_LOGIN_RANDTRIGGER");
            handleLoginRandTriggerMessage(client, message);
            break;

        case PAMSG_LOGIN:
            LOG_DEBUG("Received msg ... PAMSG_LOGIN");
            handleLoginMessage(client, message);
            break;

        case PAMSG_LOGOUT:
            LOG_DEBUG("Received msg ... PAMSG_LOGOUT");
            handleLogoutMessage(client);
            break;

        case PAMSG_RECONNECT:
            LOG_DEBUG("Received msg ... PAMSG_RECONNECT");
            handleReconnectMessage(client, message);
            break;

        case PAMSG_REGISTER:
            LOG_DEBUG("Received msg ... PAMSG_REGISTER");
            handleRegisterMessage(client, message);
            break;

        case PAMSG_UNREGISTER:
            LOG_DEBUG("Received msg ... PAMSG_UNREGISTER");
            handleUnregisterMessage(client, message);
            break;

        case PAMSG_REQUEST_REGISTER_INFO :
            LOG_DEBUG("Received msg ... REQUEST_REGISTER_INFO");
            handleRequestRegisterInfoMessage(client, message);
            break;

        case PAMSG_EMAIL_CHANGE:
            LOG_DEBUG("Received msg ... PAMSG_EMAIL_CHANGE");
            handleEmailChangeMessage(client, message);
            break;

        case PAMSG_PASSWORD_CHANGE:
            LOG_DEBUG("Received msg ... PAMSG_PASSWORD_CHANGE");
            handlePasswordChangeMessage(client, message);
            break;

        case PAMSG_CHAR_CREATE:
            LOG_DEBUG("Received msg ... PAMSG_CHAR_CREATE");
            handleCharacterCreateMessage(client, message);
            break;

        case PAMSG_CHAR_SELECT:
            LOG_DEBUG("Received msg ... PAMSG_CHAR_SELECT");
            handleCharacterSelectMessage(client, message);
            break;

        case PAMSG_CHAR_DELETE:
            LOG_DEBUG("Received msg ... PAMSG_CHAR_DELETE");
            handleCharacterDeleteMessage(client, message);
            break;

        default:
            LOG_WARN("AccountHandler::processMessage, Invalid message type "
                     << message.getId());
            MessageOut result(XXMSG_INVALID);
            client.send(result);
            break;
    }
}
Ejemplo n.º 16
0
void BuySellHandler::handleMessage(MessageIn &msg)
{
    int n_items;
    switch (msg.getId())
    {
        case SMSG_NPC_BUY_SELL_CHOICE:
            buyDialog->setVisible(false);
            buyDialog->reset();
            sellDialog->setVisible(false);
            sellDialog->reset();
            current_npc = msg.readInt32();
            buySellDialog->setVisible(true);
            break;

        case SMSG_NPC_BUY:
            msg.readInt16();  // length
            n_items = (msg.getLength() - 4) / 11;
            buyDialog->reset();
            buyDialog->setMoney(player_node->getMoney());
            buyDialog->setVisible(true);

            for (int k = 0; k < n_items; k++)
            {
                int value = msg.readInt32();
                msg.readInt32();  // DCvalue
                msg.readInt8();  // type
                int itemId = msg.readInt16();
                buyDialog->addItem(itemId, 0, value);
            }
            break;

        case SMSG_NPC_SELL:
            msg.readInt16();  // length
            n_items = (msg.getLength() - 4) / 10;
            if (n_items > 0)
            {
                sellDialog->setMoney(player_node->getMoney());
                sellDialog->reset();
                sellDialog->setVisible(true);

                for (int k = 0; k < n_items; k++)
                {
                    int index = msg.readInt16() - INVENTORY_OFFSET;
                    int value = msg.readInt32();
                    msg.readInt32();  // OCvalue

                    Item *item = player_node->getInventory()->getItem(index);

                    if (item && !(item->isEquipped()))
                        sellDialog->addItem(item, value);
                }
            }
            else
            {
                localChatTab->chatLog(_("Nothing to sell."), BY_SERVER);
                current_npc = 0;
            }
            break;

        case SMSG_NPC_BUY_RESPONSE:
            if (msg.readInt8() == 0)
            {
                localChatTab->chatLog(_("Thanks for buying."), BY_SERVER);
            }
            else
            {
                // Reset player money since buy dialog already assumed purchase
                // would go fine
                buyDialog->setMoney(player_node->getMoney());
                localChatTab->chatLog(_("Unable to buy."), BY_SERVER);
            }
            break;

        case SMSG_NPC_SELL_RESPONSE:
            if (msg.readInt8() == 0)
                localChatTab->chatLog(_("Thanks for selling."), BY_SERVER);
            else
                localChatTab->chatLog(_("Unable to sell."), BY_SERVER);

            break;
    }
}
Ejemplo n.º 17
0
void SkillHandler::handleMessage(MessageIn &msg)
{
    int skillCount;

    switch (msg.getId())
    {
        case SMSG_PLAYER_SKILLS:
            msg.readInt16();  // length
            skillCount = (msg.getLength() - 4) / 37;
            skillDialog->cleanList();

            for (int k = 0; k < skillCount; k++)
            {
                int skillId = msg.readInt16();
                msg.readInt16();  // target type
                msg.readInt16();  // unknown
                int level = msg.readInt16();
                int sp = msg.readInt16();
                msg.readInt16();  // range
                std::string skillName = msg.readString(24);
                int up = msg.readInt8();

                if (level != 0 || up != 0)
                {
                    if (skillDialog->hasSkill(skillId)) {
                        skillDialog->setSkill(skillId, level, sp);
                    }
                    else {
                        skillDialog->addSkill(skillId, level, sp);
                    }
                }
            }
            skillDialog->update();
            break;

        case SMSG_SKILL_FAILED:
            // Action failed (ex. sit because you have not reached the
            // right level)
            short skill   = msg.readInt16();
            short bskill  = msg.readInt16();
            msg.readInt16(); // unknown
            char success = msg.readInt8();
            char reason  = msg.readInt8();
            if (success != SKILL_FAILED && bskill == BSKILL_EMOTE)
            {
                logger->log("Action: %d/%d", bskill, success);
            }

            std::string msg;
            if (success == SKILL_FAILED && skill == SKILL_BASIC)
            {
                switch (bskill)
                {
                    case BSKILL_TRADE:
                        msg = _("Trade failed!");
                        break;
                    case BSKILL_EMOTE:
                        msg = _("Emote failed!");
                        break;
                    case BSKILL_SIT:
                        msg = _("Sit failed!");
                        break;
                    case BSKILL_CREATECHAT:
                        msg = _("Chat creating failed!");
                        break;
                    case BSKILL_JOINPARTY:
                        msg = _("Could not join party!");
                        break;
                    case BSKILL_SHOUT:
                        msg = _("Cannot shout!");
                        break;
                }

                msg += " ";

                switch (reason)
                {
                    case RFAIL_SKILLDEP:
                        msg += _("You have not yet reached a high enough lvl!");
                        break;
                    case RFAIL_INSUFHP:
                        msg += _("Insufficient HP!");
                        break;
                    case RFAIL_INSUFSP:
                        msg += _("Insufficient SP!");
                        break;
                    case RFAIL_NOMEMO:
                        msg += _("You have no memos!");
                        break;
                    case RFAIL_SKILLDELAY:
                        msg += _("You cannot do that right now!");
                        break;
                    case RFAIL_ZENY:
                        msg += _("Seems you need more money... ;-)");
                        break;
                    case RFAIL_WEAPON:
                        msg += _("You cannot use this skill with that kind of weapon!");
                        break;
                    case RFAIL_REDGEM:
                        msg += _("You need another red gem!");
                        break;
                    case RFAIL_BLUEGEM:
                        msg += _("You need another blue gem!");
                        break;
                    case RFAIL_OVERWEIGHT:
                        msg += _("You're carrying to much to do this!");
                        break;
                    default:
                        msg += _("Huh? What's that?");
                        break;
                }
            }
            else
            {
                switch (skill)
                {
                    case SKILL_WARP :
                        msg = _("Warp failed...");
                        break;
                    case SKILL_STEAL :
                        msg = _("Could not steal anything...");
                        break;
                    case SKILL_ENVENOM :
                        msg = _("Poison had no effect...");
                        break;
                }
            }

            localChatTab->chatLog(msg);
            break;
    }
}
Ejemplo n.º 18
0
void EquipmentHandler::handleMessage(MessageIn &msg)
{
    int itemCount;
    int index, equipPoint, itemId;
    int type;
    Inventory *inventory = player_node->getInventory();

    switch (msg.getId())
    {
        case SMSG_PLAYER_EQUIPMENT:
            msg.readInt16(); // length
            itemCount = (msg.getLength() - 4) / 20;

            for (int loop = 0; loop < itemCount; loop++)
            {
                index = msg.readInt16() - INVENTORY_OFFSET;
                itemId = msg.readInt16();
                msg.readInt8();  // type
                msg.readInt8();  // identify flag
                msg.readInt16(); // equip type
                equipPoint = msg.readInt16();
                msg.readInt8();  // attribute
                msg.readInt8();  // refine
                msg.skip(8);     // card

                inventory->setItem(index, itemId, 1, true);

                setEquipment(equipPoint, index, true);
            }
            break;

        case SMSG_PLAYER_EQUIP:
            index = msg.readInt16() - INVENTORY_OFFSET;
            equipPoint = msg.readInt16();
            type = msg.readInt8();

            if (!type)
            {
                localChatTab->chatLog(_("Unable to equip."), BY_SERVER);
                break;
            }

            setEquipment(equipPoint, index, true);
            break;

        case SMSG_PLAYER_UNEQUIP:
            index = msg.readInt16() - INVENTORY_OFFSET;
            equipPoint = msg.readInt16();
            type = msg.readInt8();

            if (!type) {
                localChatTab->chatLog(_("Unable to unequip."), BY_SERVER);
                break;
            }

            setEquipment(equipPoint, index, false);
            break;

        case SMSG_PLAYER_ATTACK_RANGE:
            player_node->setAttackRange(msg.readInt16());
            break;

        case SMSG_PLAYER_ARROW_EQUIP:
            index = msg.readInt16();

            if (index <= 1)
                break;

            index -= INVENTORY_OFFSET;

            logger->log("Arrows equipped: %i", index);
            setEquipment(0x8000, index, true);
            break;
    }
}
Ejemplo n.º 19
0
void InventoryHandler::handleMessage(MessageIn &msg)
{
    int number;
    int index, amount, itemId, equipType, arrow;
    int identified, cards[4], itemType;
    Inventory *inventory = player_node->getInventory();
    Inventory *storage = player_node->getStorage();

    switch (msg.getId())
    {
        case SMSG_PLAYER_INVENTORY:
        case SMSG_PLAYER_STORAGE_ITEMS:
            if (msg.getId() == SMSG_PLAYER_INVENTORY)
            {
                // Clear inventory - this will be a complete refresh
                clearEquipment();
                inventory->clear();
            }
            else
            {
                /*
                 * This packet will always be followed by a
                 * SMSG_PLAYER_STORAGE_EQUIP packet.  The two packets
                 * together comprise a complete refresh of storage, so
                 * clear storage here
                 */
                storage->clear();
            }
            msg.readInt16();  // length
            number = (msg.getLength() - 4) / 18;

            for (int loop = 0; loop < number; loop++)
            {
                index = msg.readInt16();
                itemId = msg.readInt16();
                itemType = msg.readInt8();
                identified = msg.readInt8();
                amount = msg.readInt16();
                arrow = msg.readInt16();
                for (int i = 0; i < 4; i++)
                    cards[i] = msg.readInt16();

                index -= (msg.getId() == SMSG_PLAYER_INVENTORY) ?
                         INVENTORY_OFFSET : STORAGE_OFFSET;

                if (debugInventory)
                {
                    logger->log("Index: %d, ID: %d, Type: %d, Identified: %d, "
                                "Qty: %d, Cards: %d, %d, %d, %d",
                                index, itemId, itemType, identified, amount,
                                cards[0], cards[1], cards[2], cards[3]);
                }

                if (msg.getId() == SMSG_PLAYER_INVENTORY) {
                    inventory->setItem(index, itemId, amount, false);

                    // Trick because arrows are not considered equipment
                    if (arrow & 0x8000) {
                        if (Item *item = inventory->getItem(index))
                            item->setEquipment(true);
                    }
                } else {
                    storage->setItem(index, itemId, amount, false);
                }
            }
            break;

        case SMSG_PLAYER_STORAGE_EQUIP:
            msg.readInt16();  // length
            number = (msg.getLength() - 4) / 20;

            for (int loop = 0; loop < number; loop++) {
                index = msg.readInt16() - STORAGE_OFFSET;
                itemId = msg.readInt16();
                itemType = msg.readInt8();
                identified = msg.readInt8();
                amount = 1;
                msg.readInt16();    // Equip Point?
                msg.readInt16();    // Another Equip Point?
                msg.readInt8();   // Attribute (broken)
                msg.readInt8();   // Refine level
                for (int i = 0; i < 4; i++)
                    cards[i] = msg.readInt16();

                if (debugInventory)
                {
                    logger->log("Index: %d, ID: %d, Type: %d, Identified: %d, "
                                "Qty: %d, Cards: %d, %d, %d, %d",
                                index, itemId, itemType, identified, amount,
                                cards[0], cards[1], cards[2], cards[3]);
                }

                storage->setItem(index, itemId, amount, false);
            }
            break;

        case SMSG_PLAYER_INVENTORY_ADD:
            index = msg.readInt16() - INVENTORY_OFFSET;
            amount = msg.readInt16();
            itemId = msg.readInt16();
            identified = msg.readInt8();
            msg.readInt8();  // attribute
            msg.readInt8();  // refine
            for (int i = 0; i < 4; i++)
                cards[i] = msg.readInt16();
            equipType = msg.readInt16();
            itemType = msg.readInt8();

            {
                const ItemInfo &itemInfo = ItemDB::get(itemId);

                if (msg.readInt8() > 0)
                {
                    player_node->pickedUp(itemInfo, 0);
                }
                else
                {
                    player_node->pickedUp(itemInfo, amount);

                    Item *item = inventory->getItem(index);

                    if  (item && item->getId() == itemId)
                        amount += inventory->getItem(index)->getQuantity();

                    inventory->setItem(index, itemId, amount, equipType != 0);
                }
            } break;

        case SMSG_PLAYER_INVENTORY_REMOVE:
            index = msg.readInt16() - INVENTORY_OFFSET;
            amount = msg.readInt16();
            if (Item *item = inventory->getItem(index))
            {
                item->increaseQuantity(-amount);
                if (item->getQuantity() == 0)
                    inventory->removeItemAt(index);
            }
            break;

        case SMSG_PLAYER_INVENTORY_USE:
            index = msg.readInt16() - INVENTORY_OFFSET;
            msg.readInt16(); // item id
            msg.readInt32();  // id
            amount = msg.readInt16();
            msg.readInt8();  // type

            if (Item *item = inventory->getItem(index))
                item->setQuantity(amount);
            break;

        case SMSG_ITEM_USE_RESPONSE:
            index = msg.readInt16() - INVENTORY_OFFSET;
            amount = msg.readInt16();

            if (msg.readInt8() == 0) {
                localChatTab->chatLog(_("Failed to use item."), BY_SERVER);
            } else {
                if (Item *item = inventory->getItem(index))
                    item->setQuantity(amount);
            }
            break;

        case SMSG_PLAYER_STORAGE_STATUS:
            /*
             * This is the closest we get to an "Open Storage" packet from the
             * server. It always comes after the two SMSG_PLAYER_STORAGE_...
             * packets that update storage contents.
             */
            player_node->setInStorage(true);
            msg.readInt16(); // Storage capacity
            msg.readInt16(); // Used count
            break;

        case SMSG_PLAYER_STORAGE_ADD:
            /*
             * Move an item into storage
             */
            index = msg.readInt16() - STORAGE_OFFSET;
            amount = msg.readInt32();
            itemId = msg.readInt16();
            identified = msg.readInt8();
            msg.readInt8();  // attribute
            msg.readInt8();  // refine
            for (int i = 0; i < 4; i++)
                cards[i] = msg.readInt16();

            if (Item *item = storage->getItem(index))
            {
                item->setId(itemId);
                item->increaseQuantity(amount);
            }
            else
            {
                storage->setItem(index, itemId, amount, false);
            }
            break;

        case SMSG_PLAYER_STORAGE_REMOVE:
            /*
             * Move an item out of storage
             */
            index = msg.readInt16() - STORAGE_OFFSET;
            amount = msg.readInt16();
            if (Item *item = storage->getItem(index))
            {
                item->increaseQuantity(-amount);
                if (item->getQuantity() == 0)
                    storage->removeItemAt(index);
            }
            break;

        case SMSG_PLAYER_STORAGE_CLOSE:
            /*
             * Storage access has been closed
             */
            player_node->setInStorage(false);
            break;
    }
}
Ejemplo n.º 20
0
void ChatHandler::handleMessage(MessageIn &msg)
{
    Being *being;
    std::string chatMsg;
    std::string nick;
    int chatMsgLength;

    switch (msg.getId())
    {
        case SMSG_WHISPER_RESPONSE:
            switch (msg.readInt8())
            {
                case 0x00:
                    // comment out since we'll local echo in chat.cpp instead, then only report failures
                    //localChatTab->chatLog("Whisper sent", BY_SERVER);
                    break;
                case 0x01:
                    localChatTab->chatLog(_("Whisper could not be sent, user "
                                            "is offline."), BY_SERVER);
                    break;
                case 0x02:
                    localChatTab->chatLog(_("Whisper could not be sent, "
                                            "ignored by user."), BY_SERVER);
                    break;
            }
            break;

        // Received whisper
        case SMSG_WHISPER:
            chatMsgLength = msg.readInt16() - 28;
            nick = msg.readString(24);

            if (chatMsgLength <= 0)
                break;

            chatMsg = msg.readString(chatMsgLength);

            if (nick != "Server")
            {
                if (player_relations.hasPermission(nick, PlayerRelation::WHISPER))
                    chatWindow->whisper(nick, chatMsg);
            }
            else
            {
                localChatTab->chatLog(chatMsg, BY_SERVER);
            }

            break;

        // Received speech from being
        case SMSG_BEING_CHAT: {
            chatMsgLength = msg.readInt16() - 8;
            being = beingManager->findBeing(msg.readInt32());

            if (!being || chatMsgLength <= 0)
                break;

            chatMsg = msg.readString(chatMsgLength);

            std::string::size_type pos = chatMsg.find(" : ", 0);
            std::string sender_name = ((pos == std::string::npos)
                                       ? ""
                                       : chatMsg.substr(0, pos));

            // We use getIgnorePlayer instead of ignoringPlayer here because ignorePlayer' side
            // effects are triggered right below for Being::IGNORE_SPEECH_FLOAT.
            if (player_relations.checkPermissionSilently(sender_name, PlayerRelation::SPEECH_LOG))
                localChatTab->chatLog(chatMsg, BY_OTHER);

            chatMsg.erase(0, pos + 3);
            trim(chatMsg);

            if (player_relations.hasPermission(sender_name, PlayerRelation::SPEECH_FLOAT))
                being->setSpeech(chatMsg, SPEECH_TIME);
            break;
        }

        case SMSG_PLAYER_CHAT:
        case SMSG_GM_CHAT: {
            chatMsgLength = msg.readInt16() - 4;

            if (chatMsgLength <= 0)
                break;

            chatMsg = msg.readString(chatMsgLength);
            std::string::size_type pos = chatMsg.find(" : ", 0);

            if (msg.getId() == SMSG_PLAYER_CHAT)
            {
                if (localChatTab) localChatTab->chatLog(chatMsg, BY_PLAYER);

                if (pos != std::string::npos)
                    chatMsg.erase(0, pos + 3);

                trim(chatMsg);

                player_node->setSpeech(chatMsg, SPEECH_TIME);
            }
            else
            {
                localChatTab->chatLog(chatMsg, BY_GM);
            }
            break;
        }

        case SMSG_MVP:
            // Display MVP player
            msg.readInt32(); // id
            localChatTab->chatLog(_("MVP player."), BY_SERVER);
            break;
    }
}
Ejemplo n.º 21
0
void LoginHandler::handleMessage(MessageIn &msg)
{
    switch (msg.getId())
    {
        case APMSG_LOGIN_RESPONSE:
            handleLoginResponse(msg);
            break;
        case APMSG_REGISTER_RESPONSE:
            handleRegisterResponse(msg);
            break;
        case APMSG_RECONNECT_RESPONSE:
        {
            int errMsg = msg.readInt8();
            // Successful login
            if (errMsg == ERRMSG_OK)
            {
                state = STATE_CHAR_SELECT;
            }
            // Login failed
            else
            {
                switch (errMsg) {
                    case ERRMSG_INVALID_ARGUMENT:
                        errorMessage = _("Wrong magic_token");
                        break;
                    case ERRMSG_FAILURE:
                        errorMessage = _("Already logged in");
                        break;
                    case LOGIN_SERVER_FULL:
                        errorMessage = _("Server is full");
                        break;
                    default:
                        errorMessage = _("Unknown error");
                        break;
                }
                state = STATE_ERROR;
            }
        }
            break;

        case APMSG_PASSWORD_CHANGE_RESPONSE:
        {
            int errMsg = msg.readInt8();
            // Successful pass change
            if (errMsg == ERRMSG_OK)
            {
                state = STATE_CHANGEPASSWORD;
            }
            // pass change failed
            else
            {
                switch (errMsg) {
                    case ERRMSG_INVALID_ARGUMENT:
                        errorMessage = _("New password incorrect");
                        break;
                    case ERRMSG_FAILURE:
                        errorMessage = _("Old password incorrect");
                        break;
                    case ERRMSG_NO_LOGIN:
                        errorMessage = _("Account not connected. Please login first.");
                        break;
                    default:
                        errorMessage = _("Unknown error");
                        break;
                }
                state = STATE_ACCOUNTCHANGE_ERROR;
            }
        }
            break;

        case APMSG_EMAIL_CHANGE_RESPONSE:
        {
            int errMsg = msg.readInt8();
            // Successful pass change
            if (errMsg == ERRMSG_OK)
            {
                state = STATE_CHANGEEMAIL;
            }
            // pass change failed
            else
            {
                switch (errMsg) {
                    case ERRMSG_INVALID_ARGUMENT:
                        errorMessage = _("New email address incorrect");
                        break;
                    case ERRMSG_FAILURE:
                        errorMessage = _("Old email address incorrect");
                        break;
                    case ERRMSG_NO_LOGIN:
                        errorMessage = _("Account not connected. Please login first.");
                        break;
                    case ERRMSG_EMAIL_ALREADY_EXISTS:
                        errorMessage = _("The new Email Address already exists.");
                        break;
                    default:
                        errorMessage = _("Unknown error");
                        break;
                }
                state = STATE_ACCOUNTCHANGE_ERROR;
            }
        }
            break;

    }
}
Ejemplo n.º 22
0
void PlayerHandler::handleMessage(MessageIn &msg)
{
	switch (msg.getId())
	{
	case SMSG_WALK_RESPONSE:
		/*
		 * This client assumes that all walk messages succeed,
		 * and that the server will send a correction notice
		 * otherwise.
		 */
		break;

	case SMSG_PLAYER_WARP:
	{
		std::string mapPath = msg.readString(16);
		bool nearby;
		Uint16 x = msg.readInt16();
		Uint16 y = msg.readInt16();

		logger->log("Warping to %s (%d, %d)", mapPath.c_str(), x, y);

		/*
		 * We must clear the local player's target *before* the call
		 * to changeMap, as it deletes all beings.
		 */
		player_node->stopAttack();

		nearby = (engine->getCurrentMapName() == mapPath);

		// Switch the actual map, deleting the previous one if necessary
		mapPath = mapPath.substr(0, mapPath.rfind("."));
		engine->changeMap(mapPath);

		float scrollOffsetX = 0.0f;
		float scrollOffsetY = 0.0f;

		/* Scroll if neccessary */
		if (!nearby
				|| (abs(x - player_node->mX) > MAP_TELEPORT_SCROLL_DISTANCE)
				|| (abs(y - player_node->mY) > MAP_TELEPORT_SCROLL_DISTANCE))
		{
			scrollOffsetX = (x - player_node->mX) * 32;
			scrollOffsetY = (y - player_node->mY) * 32;
		}

		player_node->setAction(Being::STAND);
		player_node->mFrame = 0;
		player_node->mX = x;
		player_node->mY = y;

		logger->log("Adjust scrolling by %d:%d", (int) scrollOffsetX,
				(int) scrollOffsetY);

		viewport->scrollBy(scrollOffsetX, scrollOffsetY);
	}
		break;

	case SMSG_PLAYER_STAT_UPDATE_1:
	{
		int type = msg.readInt16();
		int value = msg.readInt32();

		switch (type)
		{
		//case 0x0000:
		//    player_node->setWalkSpeed(msg.readInt32());
		//    break;
		case 0x0005:
			player_node->setHp(value);
			break;
		case 0x0006:
			player_node->setMaxHp(value);
			break;
		case 0x0007:
			player_node->mMp = value;
			break;
		case 0x0008:
			player_node->mMaxMp = value;
			break;
		case 0x0009:
			player_node->mStatsPointsToAttribute = value;
			break;
		case 0x000b:
			player_node->setLevel(value);
			break;
		case 0x000c:
			player_node->mSkillPoint = value;
			skillDialog->update();
			break;
		case 0x0018:
			if (value >= player_node->getMaxWeight() / 2
					&& player_node->getTotalWeight()
							< player_node->getMaxWeight() / 2)
			{
				weightNotice = new OkDialog(_("Message"),
						_("You are carrying more than "
								"half your weight. You are "
								"unable to regain health."));
				weightNotice->addActionListener(&weightListener);
			}
			player_node->setTotalWeight(value);
			break;
		case 0x0019:
			player_node->setMaxWeight(value);
			break;
		case 0x0029:
			player_node->ATK = value;
			break;
		case 0x002b:
			player_node->MATK = value;
			break;
		case 0x002d:
			player_node->DEF = value;
			break;
		case 0x002e:
			player_node->DEF_BONUS = value;
			break;
		case 0x002f:
			player_node->MDEF = value;
			break;
		case 0x0031:
			player_node->HIT = value;
			break;
		case 0x0032:
			player_node->FLEE = value;
			break;
		case 0x0035:
			player_node->mAttackSpeed = value;
			break;
		case 0x0037:
			player_node->mJobLevel = value;
			break;
		case 500:
			player_node->setGMLevel(value);
			break;
		}

		if (player_node->getHp() == 0 && !deathNotice)
		{
			if (true)
			{
				game.wasKilled = true;
				Net::getPlayerHandler()->respawn();
			}
			else
			{
				deathNotice = new OkDialog(_("Message"), randomDeathMessage());
				deathNotice->addActionListener(&deathListener);
				player_node->setAction(Being::DEAD);
			}
		}
	}
		break;

	case SMSG_PLAYER_STAT_UPDATE_2:
		switch (msg.readInt16())
		{
		case 0x0001:
			player_node->setXp(msg.readInt32());
			break;
		case 0x0002:
			player_node->mJobXp = msg.readInt32();
			break;
		case 0x0014:
		{
			int curGp = player_node->getMoney();
			player_node->setMoney(msg.readInt32());
			if (player_node->getMoney() > curGp)
				localChatTab->chatLog(
						_("You picked up ") + Units::formatCurrency(
								player_node->getMoney() - curGp), BY_SERVER);
		}
			break;
		case 0x0016:
			player_node->mXpForNextLevel = msg.readInt32();
			break;
		case 0x0017:
			player_node->mJobXpForNextLevel = msg.readInt32();
			break;
		}
		break;

	case SMSG_PLAYER_STAT_UPDATE_3:
	{
		int type = msg.readInt32();
		int base = msg.readInt32();
		int bonus = msg.readInt32();
		int total = base + bonus;

		switch (type)
		{
		case 0x000d:
			player_node->mAttr[LocalPlayer::STR] = total;
			break;
		case 0x000e:
			player_node->mAttr[LocalPlayer::AGI] = total;
			break;
		case 0x000f:
			player_node->mAttr[LocalPlayer::VIT] = total;
			break;
		case 0x0010:
			player_node->mAttr[LocalPlayer::INT] = total;
			break;
		case 0x0011:
			player_node->mAttr[LocalPlayer::DEX] = total;
			break;
		case 0x0012:
			player_node->mAttr[LocalPlayer::LUK] = total;
			break;
		}
	}
		break;

	case SMSG_PLAYER_STAT_UPDATE_4:
	{
		int type = msg.readInt16();
		int fail = msg.readInt8();
		int value = msg.readInt8();

		if (fail != 1)
			break;

		switch (type)
		{
		case 0x000d:
			player_node->mAttr[LocalPlayer::STR] = value;
			break;
		case 0x000e:
			player_node->mAttr[LocalPlayer::AGI] = value;
			break;
		case 0x000f:
			player_node->mAttr[LocalPlayer::VIT] = value;
			break;
		case 0x0010:
			player_node->mAttr[LocalPlayer::INT] = value;
			break;
		case 0x0011:
			player_node->mAttr[LocalPlayer::DEX] = value;
			break;
		case 0x0012:
			player_node->mAttr[LocalPlayer::LUK] = value;
			break;
		}
	}
		break;

		// Updates stats and status points
	case SMSG_PLAYER_STAT_UPDATE_5:
		player_node->mStatsPointsToAttribute = msg.readInt16();
		player_node->mAttr[LocalPlayer::STR] = msg.readInt8();
		player_node->mAttrUp[LocalPlayer::STR] = msg.readInt8();
		player_node->mAttr[LocalPlayer::AGI] = msg.readInt8();
		player_node->mAttrUp[LocalPlayer::AGI] = msg.readInt8();
		player_node->mAttr[LocalPlayer::VIT] = msg.readInt8();
		player_node->mAttrUp[LocalPlayer::VIT] = msg.readInt8();
		player_node->mAttr[LocalPlayer::INT] = msg.readInt8();
		player_node->mAttrUp[LocalPlayer::INT] = msg.readInt8();
		player_node->mAttr[LocalPlayer::DEX] = msg.readInt8();
		player_node->mAttrUp[LocalPlayer::DEX] = msg.readInt8();
		player_node->mAttr[LocalPlayer::LUK] = msg.readInt8();
		player_node->mAttrUp[LocalPlayer::LUK] = msg.readInt8();
		player_node->ATK = msg.readInt16(); // ATK
		player_node->ATK_BONUS = msg.readInt16(); // ATK bonus
		player_node->MATK = msg.readInt16(); // MATK max
		player_node->MATK_BONUS = msg.readInt16(); // MATK min
		player_node->DEF = msg.readInt16(); // DEF
		player_node->DEF_BONUS = msg.readInt16(); // DEF bonus
		player_node->MDEF = msg.readInt16(); // MDEF
		player_node->MDEF_BONUS = msg.readInt16(); // MDEF bonus
		player_node->HIT = msg.readInt16(); // HIT
		player_node->FLEE = msg.readInt16(); // FLEE
		player_node->FLEE_BONUS = msg.readInt16(); // FLEE bonus
		msg.readInt16(); // critical
		msg.readInt16(); // unknown
		break;

	case SMSG_PLAYER_STAT_UPDATE_6:
		switch (msg.readInt16())
		{
		case 0x0020:
			player_node->mAttrUp[LocalPlayer::STR] = msg.readInt8();
			break;
		case 0x0021:
			player_node->mAttrUp[LocalPlayer::AGI] = msg.readInt8();
			break;
		case 0x0022:
			player_node->mAttrUp[LocalPlayer::VIT] = msg.readInt8();
			break;
		case 0x0023:
			player_node->mAttrUp[LocalPlayer::INT] = msg.readInt8();
			break;
		case 0x0024:
			player_node->mAttrUp[LocalPlayer::DEX] = msg.readInt8();
			break;
		case 0x0025:
			player_node->mAttrUp[LocalPlayer::LUK] = msg.readInt8();
			break;
		}
		break;

	case SMSG_PLAYER_ARROW_MESSAGE:
	{
		int type = msg.readInt16();

		switch (type)
		{
		case 0:
			localChatTab->chatLog(_("Equip arrows first."), BY_SERVER);
			break;
		default:
			logger->log("0x013b: Unhandled message %i", type);
			break;
		}
	}
		break;
	}
}
Ejemplo n.º 23
0
void ChatHandler::processMessage(NetComputer *comp, MessageIn &message)
{
    ChatClient &computer = *static_cast< ChatClient * >(comp);
    MessageOut result;

    if (computer.characterName.empty())
    {
        if (message.getId() != PCMSG_CONNECT) return;

        std::string magic_token = message.readString(MAGIC_TOKEN_LENGTH);
        mTokenCollector.addPendingClient(magic_token, &computer);
        sendGuildRejoin(computer);
        return;
    }

    switch (message.getId())
    {
        case PCMSG_CHAT:
            handleChatMessage(computer, message);
            break;

        case PCMSG_ANNOUNCE:
            handleAnnounceMessage(computer, message);
            break;

        case PCMSG_PRIVMSG:
            handlePrivMsgMessage(computer, message);
            break;

        case PCMSG_WHO:
            handleWhoMessage(computer);
            break;

        case PCMSG_ENTER_CHANNEL:
            handleEnterChannelMessage(computer, message);
            break;

        case PCMSG_USER_MODE:
            handleModeChangeMessage(computer, message);
            break;

        case PCMSG_KICK_USER:
            handleKickUserMessage(computer, message);

        case PCMSG_QUIT_CHANNEL:
            handleQuitChannelMessage(computer, message);
            break;

        case PCMSG_LIST_CHANNELS:
            handleListChannelsMessage(computer, message);
            break;

        case PCMSG_LIST_CHANNELUSERS:
            handleListChannelUsersMessage(computer, message);
            break;

        case PCMSG_TOPIC_CHANGE:
            handleTopicChange(computer, message);
            break;

        case PCMSG_DISCONNECT:
            handleDisconnectMessage(computer, message);
            break;

        case PCMSG_GUILD_CREATE:
            handleGuildCreation(computer, message);
            break;

        case PCMSG_GUILD_INVITE:
            handleGuildInvitation(computer, message);
            break;

        case PCMSG_GUILD_ACCEPT:
            handleGuildAcceptInvite(computer, message);
            break;

        case PCMSG_GUILD_GET_MEMBERS:
            handleGuildRetrieveMembers(computer, message);
            break;

        case PCMSG_GUILD_PROMOTE_MEMBER:
            handleGuildMemberLevelChange(computer, message);
            break;

        case PCMSG_GUILD_KICK_MEMBER:
            handleGuildMemberKick(computer, message);

        case PCMSG_GUILD_QUIT:
            handleGuildQuit(computer, message);
            break;

        case PCMSG_PARTY_INVITE:
            handlePartyInvite(computer, message);
            break;

        case PCMSG_PARTY_ACCEPT_INVITE:
            handlePartyAcceptInvite(computer, message);
            break;

        case PCMSG_PARTY_QUIT:
            handlePartyQuit(computer);
            break;

        case PCMSG_PARTY_REJECT_INVITE:
            handlePartyRejection(computer, message);
            break;

        default:
            LOG_WARN("ChatHandler::processMessage, Invalid message type"
                     << message.getId());
            result.writeShort(XXMSG_INVALID);
            break;
    }

    if (result.getLength() > 0)
        computer.send(result);
}
Ejemplo n.º 24
0
void PlayerHandler::handleMessage(MessageIn &msg)
{
    switch (msg.getId())
    {
        case GPMSG_PLAYER_MAP_CHANGE:
            handleMapChangeMessage(msg);
            break;

        case GPMSG_PLAYER_SERVER_CHANGE:
        {   // TODO: Fix the servers to test this
            netToken = msg.readString(32);
            std::string address = msg.readString();
            int port = msg.readInt16();
            logger->log("Changing server to %s:%d", address.c_str(), port);

            gameServer.hostname = address;
            gameServer.port = port;

            gameServerConnection->disconnect();
            Client::setState(STATE_CHANGE_MAP);
            local_player->setMap(0);
        } break;

        case GPMSG_PLAYER_ATTRIBUTE_CHANGE:
        {
            while (msg.getUnreadLength())
            {
                int attrId = msg.readInt16();
                double base = msg.readInt32() / 256.0;
                double value = msg.readInt32() / 256.0;

                // Set the core player attribute the stat
                // depending on attribute link.
                int playerInfoId =
                                  Attributes::getPlayerInfoIdFromAttrId(attrId);
                if (playerInfoId > -1)
                {
                    PlayerInfo::setAttribute(playerInfoId, value);
                }
                else
                {
                    PlayerInfo::setStatBase(attrId, base);
                    PlayerInfo::setStatMod(attrId, value - base);
                }
            }
        } break;

        case GPMSG_PLAYER_EXP_CHANGE:
        {
            logger->log("EXP Update");
            while (msg.getUnreadLength())
            {
                int skill = msg.readInt16();
                int current = msg.readInt32();
                int next = msg.readInt32();
                int level = msg.readInt16();

                PlayerInfo::setStatExperience(skill, current, next);
                PlayerInfo::setStatBase(skill, level);
            }
        } break;

        case GPMSG_LEVELUP:
        {
            PlayerInfo::setAttribute(LEVEL, msg.readInt16());
            PlayerInfo::setAttribute(CHAR_POINTS, msg.readInt16());
            PlayerInfo::setAttribute(CORR_POINTS, msg.readInt16());
            Particle* effect = particleEngine->addEffect(
                                               paths.getStringValue("particles")
                                     + paths.getStringValue("levelUpEffectFile")
                                                         ,0, 0);
            local_player->controlParticle(effect);
        } break;


        case GPMSG_LEVEL_PROGRESS:
        {
            PlayerInfo::setAttribute(EXP, msg.readInt8());
        } break;


        case GPMSG_RAISE_ATTRIBUTE_RESPONSE:
        {
            int errCode = msg.readInt8();
            int attrNum = msg.readInt16();
            switch (errCode)
            {
                case ATTRIBMOD_OK:
                {
                    // feel(acknowledgment);
                } break;
                case ATTRIBMOD_INVALID_ATTRIBUTE:
                {
                    logger->log("Warning: Server denied increase of attribute %d (unknown attribute) ", attrNum);
                } break;
                case ATTRIBMOD_NO_POINTS_LEFT:
                {
                    // when the server says "you got no points" it
                    // has to be correct. The server is always right!
                    // undo attribute change and set points to 0
                    logger->log("Warning: Server denied increase of attribute %d (no points left) ", attrNum);
                    int attrValue = PlayerInfo::getStatBase(attrNum) - 1;
                    PlayerInfo::setAttribute(CHAR_POINTS, 0);
                    PlayerInfo::setStatBase(attrNum, attrValue);
                } break;
                case ATTRIBMOD_DENIED:
                {
                    // undo attribute change
                    logger->log("Warning: Server denied increase of attribute %d (reason unknown) ", attrNum);
                    int points = PlayerInfo::getAttribute(CHAR_POINTS) - 1;
                    PlayerInfo::setAttribute(CHAR_POINTS, points);

                    int attrValue = PlayerInfo::getStatBase(attrNum) - 1;
                    PlayerInfo::setStatBase(attrNum, attrValue);
                } break;
            }
        } break;

        case GPMSG_LOWER_ATTRIBUTE_RESPONSE:
        {
            int errCode = msg.readInt8();
            int attrNum = msg.readInt16();
            switch (errCode)
            {
                case ATTRIBMOD_OK:
                {
                    // feel(acknowledgment);
                } break;
                case ATTRIBMOD_INVALID_ATTRIBUTE:
                {
                    logger->log("Warning: Server denied reduction of attribute %d (unknown attribute) ", attrNum);
                } break;
                case ATTRIBMOD_NO_POINTS_LEFT:
                {
                    // when the server says "you got no points" it
                    // has to be correct. The server is always right!
                    // undo attribute change and set points to 0
                    logger->log("Warning: Server denied reduction of attribute %d (no points left) ", attrNum);
                    int attrValue = PlayerInfo::getStatBase(attrNum) + 1;
                    // TODO are these right?
                    PlayerInfo::setAttribute(CHAR_POINTS, 0);
                    PlayerInfo::setAttribute(CORR_POINTS, 0);
                    PlayerInfo::setStatBase(attrNum, attrValue);
                } break;
                case ATTRIBMOD_DENIED:
                {
                    // undo attribute change
                    logger->log("Warning: Server denied reduction of attribute %d (reason unknown) ", attrNum);
                    int charaPoints = PlayerInfo::getAttribute(CHAR_POINTS) - 1;
                    PlayerInfo::setAttribute(CHAR_POINTS, charaPoints);

                    int correctPoints = PlayerInfo::getAttribute(CORR_POINTS) + 1;
                    PlayerInfo::setAttribute(CORR_POINTS, correctPoints);

                    int attrValue = PlayerInfo::getStatBase(attrNum) + 1;
                    PlayerInfo::setStatBase(attrNum, attrValue);
                } break;
            }

        } break;

        case GPMSG_SPECIAL_STATUS :
        {
            while (msg.getUnreadLength())
            {
                // { B specialID, L current, L max, L recharge }
                int id = msg.readInt8();
                int current = msg.readInt32();
                int max = msg.readInt32();
                int recharge = msg.readInt32();
                PlayerInfo::setSpecialStatus(id, current, max, recharge);
            }
        } break;
        /*
        case SMSG_PLAYER_ARROW_MESSAGE:
            {
                Sint16 type = msg.readInt16();

                switch (type)
                {
                    case 0:
                        localChatTab->chatLog(_("Equip arrows first."),
                                             BY_SERVER);
                        break;
                    default:
                        logger->log("0x013b: Unhandled message %i", type);
                        break;
                }
            }
            break;
        */
    }
}
Ejemplo n.º 25
0
void GuildHandler::handleMessage(MessageIn &msg)
{
    switch (msg.getId())
    {
        case CPMSG_GUILD_CREATE_RESPONSE:
        {
            logger->log("Received CPMSG_GUILD_CREATE_RESPONSE");
            if(msg.readInt8() == ERRMSG_OK)
            {
                // TODO - Acknowledge guild was created
                localChatTab->chatLog(_("Guild created."));
                joinedGuild(msg);
            }
            else
            {
                localChatTab->chatLog(_("Error creating guild."));
            }
        } break;

        case CPMSG_GUILD_INVITE_RESPONSE:
        {
            logger->log("Received CPMSG_GUILD_INVITE_RESPONSE");
            if(msg.readInt8() == ERRMSG_OK)
            {
                // TODO - Acknowledge invite was sent
                localChatTab->chatLog(_("Invite sent."));
            }
        } break;

        case CPMSG_GUILD_ACCEPT_RESPONSE:
        {
            logger->log("Received CPMSG_GUILD_ACCEPT_RESPONSE");
            if(msg.readInt8() == ERRMSG_OK)
            {
                // TODO - Acknowledge accepted into guild
                joinedGuild(msg);
            }
        } break;

        case CPMSG_GUILD_GET_MEMBERS_RESPONSE:
        {
            logger->log("Received CPMSG_GUILD_GET_MEMBERS_RESPONSE");
            if(msg.readInt8() == ERRMSG_OK)
            {
                std::string guildMember;
                bool online;
                std::string guildName;
                Guild *guild;

                short guildId = msg.readInt16();
                guild = player_node->getGuild(guildId);

                if (!guild)
                    return;

                guildName = guild->getName();

                while(msg.getUnreadLength())
                {
                    guildMember = msg.readString();
                    online = msg.readInt8();
                    if(guildMember != "")
                    {
                        guild->addMember(guildMember);
                        guildWindow->setOnline(guildName, guildMember, online);
                    }
                }

                guildWindow->updateTab();
            }
        } break;

        case CPMSG_GUILD_UPDATE_LIST:
        {
            logger->log("Received CPMSG_GUILD_UPDATE_LIST");
            short guildId = msg.readInt16();
            std::string guildMember = msg.readString();
            char eventId = msg.readInt8();

            Guild *guild = player_node->getGuild(guildId);
            if (guild)
            {
                switch(eventId)
                {
                    case GUILD_EVENT_NEW_PLAYER:
                        guild->addMember(guildMember);
                        guildWindow->setOnline(guild->getName(), guildMember,
                                               true);
                        break;

                    case GUILD_EVENT_LEAVING_PLAYER:
                        guild->removeMember(guildMember);
                        break;

                    case GUILD_EVENT_ONLINE_PLAYER:
                        guildWindow->setOnline(guild->getName(), guildMember,
                                               true);
                        break;

                    case GUILD_EVENT_OFFLINE_PLAYER:
                        guildWindow->setOnline(guild->getName(), guildMember,
                                               false);
                        break;

                    default:
                        logger->log("Invalid guild event");
                }
            }
            guildWindow->updateTab();


        } break;

        case CPMSG_GUILD_INVITED:
        {
            logger->log("Received CPMSG_GUILD_INVITED");
            std::string inviterName = msg.readString();
            std::string guildName = msg.readString();

            // Open a dialog asking if the player accepts joining the guild.
            guildWindow->openAcceptDialog(inviterName, guildName);
        } break;

        case CPMSG_GUILD_PROMOTE_MEMBER_RESPONSE:
        {
            logger->log("Received CPMSG_GUILD_PROMOTE_MEMBER_RESPONSE");

            if (msg.readInt8() == ERRMSG_OK)
            {
                // promotion succeeded
                localChatTab->chatLog(_("Member was promoted successfully."));
            }
            else
            {
                // promotion failed
                localChatTab->chatLog(_("Failed to promote member."));
            }
        }

        case CPMSG_GUILD_REJOIN:
        {
            logger->log("Received CPMSG_GUILD_REJOIN");

            joinedGuild(msg);
        } break;

        case CPMSG_GUILD_QUIT_RESPONSE:
        {
            logger->log("Received CPMSG_GUILD_QUIT_RESPONSE");

            if (msg.readInt8() == ERRMSG_OK)
            {
                // Must remove tab first, as it wont find the guild
                // name after its removed from the player
                int guildId = msg.readInt16();
                Guild *guild = player_node->getGuild(guildId);
                if (guild)
                {
                    Channel *channel = channelManager->findByName(guild->getName());
                    channelManager->removeChannel(channel);
                    guildWindow->removeTab(guildId);
                    player_node->removeGuild(guildId);
                }
            }
        } break;
    }
}
Ejemplo n.º 26
0
void GameHandler::processMessage(NetComputer *computer, MessageIn &message)
{
    GameClient &client = *static_cast<GameClient *>(computer);

    if (client.status == CLIENT_LOGIN)
    {
        if (message.getId() != PGMSG_CONNECT)
            return;

        std::string magic_token = message.readString(MAGIC_TOKEN_LENGTH);
        client.status = CLIENT_QUEUED; // Before the addPendingClient
        mTokenCollector.addPendingClient(magic_token, &client);
        return;
    }
    else if (client.status != CLIENT_CONNECTED)
    {
        return;
    }

    switch (message.getId())
    {
        case PGMSG_SAY:
            handleSay(client, message);
            break;

        case PGMSG_NPC_TALK:
        case PGMSG_NPC_TALK_NEXT:
        case PGMSG_NPC_SELECT:
        case PGMSG_NPC_NUMBER:
        case PGMSG_NPC_STRING:
            handleNpc(client, message);
            break;

        case PGMSG_PICKUP:
            handlePickup(client, message);
            break;

        case PGMSG_USE_ITEM:
            handleUseItem(client, message);
            break;

        case PGMSG_DROP:
            handleDrop(client, message);
            break;

        case PGMSG_WALK:
            handleWalk(client, message);
            break;

        case PGMSG_EQUIP:
            handleEquip(client, message);
            break;

        case PGMSG_UNEQUIP:
            handleUnequip(client, message);
            break;

        case PGMSG_MOVE_ITEM:
            handleMoveItem(client, message);
            break;

        case PGMSG_ATTACK:
            handleAttack(client, message);
            break;

        case PGMSG_USE_SPECIAL_ON_BEING:
            handleUseSpecialOnBeing(client, message);
            break;

        case PGMSG_USE_SPECIAL_ON_POINT:
            handleUseSpecialOnPoint(client, message);
            break;

        case PGMSG_ACTION_CHANGE:
            handleActionChange(client, message);
            break;

        case PGMSG_DIRECTION_CHANGE:
            handleDirectionChange(client, message);
            break;

        case PGMSG_DISCONNECT:
            handleDisconnect(client, message);
            break;

        case PGMSG_TRADE_REQUEST:
            handleTradeRequest(client, message);
            break;

        case PGMSG_TRADE_CANCEL:
        case PGMSG_TRADE_AGREED:
        case PGMSG_TRADE_CONFIRM:
        case PGMSG_TRADE_ADD_ITEM:
        case PGMSG_TRADE_SET_MONEY:
            handleTrade(client, message);
            break;

        case PGMSG_NPC_BUYSELL:
            handleNpcBuySell(client, message);
            break;

        case PGMSG_RAISE_ATTRIBUTE:
            handleRaiseAttribute(client, message);
            break;

        case PGMSG_LOWER_ATTRIBUTE:
            handleLowerAttribute(client, message);
            break;

        case PGMSG_RESPAWN:
            // plausibility check is done by character class
            client.character->respawn();
            break;

        case PGMSG_NPC_POST_SEND:
            handleNpcPostSend(client, message);
            break;

        case PGMSG_PARTY_INVITE:
            handlePartyInvite(client, message);
            break;

        case PGMSG_BEING_EMOTE:
            handleTriggerEmoticon(client, message);
            break;

        default:
            LOG_WARN("Invalid message type");
            client.send(MessageOut(XXMSG_INVALID));
            break;
    }
}
Ejemplo n.º 27
0
void ChatHandler::handleMessage(MessageIn &msg)
{
    Being *being;
    std::string chatMsg;
    std::string nick;
    int chatMsgLength;

    switch (msg.getId())
    {
        case SMSG_WHISPER_RESPONSE:
            if (mSentWhispers.empty())
                nick = "user";
            else
            {
                nick = mSentWhispers.front();
                mSentWhispers.pop();
            }

            switch (msg.readInt8())
            {
                case 0x00:
                    // Success (don't need to report)
                    break;
                case 0x01:
                    {
                        Event event(Event::WhisperError);
                        event.setString("nick", nick);
                        event.setString("error", strprintf(_("Whisper could "
                                  "not be sent, %s is offline."), nick.c_str()));
                        event.trigger(Event::ChatChannel);
                    }
                    break;
                case 0x02:
                    {
                        Event event(Event::WhisperError);
                        event.setString("nick", nick);
                        event.setString("error", strprintf(_("Whisper could "
                                 "not be sent, ignored by %s."), nick.c_str()));
                        event.Event::trigger(Event::ChatChannel);
                    }
                    break;
            }
            break;

        // Received whisper
        case SMSG_WHISPER:
            chatMsgLength = msg.readInt16() - 28;
            nick = msg.readString(24);

            if (chatMsgLength <= 0)
                break;

            chatMsg = msg.readString(chatMsgLength);

            // This is a sure sign of some special command, none of which are
            // supported at the moment.
            if (chatMsg.compare(0, 3, "\302\202!") == 0)
                return;

            if (nick != "Server")
            {
                // Ignore the shop commands since this client doesn't support
                // them at the moment.
                if (chatMsg.find("!selllist ") == 0 ||
                        chatMsg.find("!buylist ") == 0 ||
                        chatMsg.find("!buyitem ") == 0 ||
                        chatMsg.find("!sellitem ") == 0)
                    return;

                if (player_relations.hasPermission(nick, PlayerRelation::WHISPER))
                {
                    Event event(Event::Whisper);
                    event.setString("nick", nick);
                    event.setString("message", chatMsg);
                    event.trigger(Event::ChatChannel);
                }
            }
            else
            {
                SERVER_NOTICE(chatMsg)
            }

            break;

        // Received speech from being
        case SMSG_BEING_CHAT:
        {
            chatMsgLength = msg.readInt16() - 8;
            int beingId = msg.readInt32();
            being = actorSpriteManager->findBeing(beingId);

            if (!being || chatMsgLength <= 0)
                break;

            chatMsg = msg.readString(chatMsgLength);

            std::string::size_type pos = chatMsg.find(" : ", 0);
            std::string sender_name = ((pos == std::string::npos)
                                       ? "" : chatMsg.substr(0, pos));

            if (sender_name != being->getName()
                && being->getType() == Being::PLAYER)
            {
                if (!being->getName().empty())
                    sender_name = being->getName();
            }
            else
            {
                chatMsg.erase(0, pos + 3);
            }

            int perms;

            if (being->getType() == Being::PLAYER)
            {
                perms = player_relations.checkPermissionSilently(sender_name,
                    PlayerRelation::SPEECH_LOG | PlayerRelation::SPEECH_FLOAT);
            }
            else
            {
                perms = player_relations.getDefault()
                        & (PlayerRelation::SPEECH_LOG
                           | PlayerRelation::SPEECH_FLOAT);
            }

            trim(chatMsg);

            std::string reducedMessage = chatMsg;
            chatMsg = removeColors(sender_name) + " : " + reducedMessage;

            Event event(Event::Being);
            event.setString("message", chatMsg);
            event.setString("text", reducedMessage);
            event.setString("nick", sender_name);
            event.setInt("beingId", beingId);
            event.setInt("permissions", perms);
            event.trigger(Event::ChatChannel);

            break;
        }

        case SMSG_PLAYER_CHAT:
        case SMSG_GM_CHAT:
        {
            chatMsgLength = msg.readInt16() - 4;

            if (chatMsgLength <= 0)
                break;

            chatMsg = msg.readString(chatMsgLength);

            if (msg.getId() == SMSG_PLAYER_CHAT)
            {
                std::string::size_type pos = chatMsg.find(" : ", 0);
                std::string mes = chatMsg;

                if (pos != std::string::npos)
                    chatMsg.erase(0, pos + 3);

                trim(chatMsg);

                Event event(Event::Player);
                event.setString("message", mes);
                event.setString("text", chatMsg);
                event.setString("nick", local_player->getName());
                event.setInt("beingId", local_player->getId());
                event.setInt("permissions", player_relations.getDefault()
                             & (PlayerRelation::SPEECH_LOG
                                | PlayerRelation::SPEECH_FLOAT));
                event.trigger(Event::ChatChannel);
            }
            else
            {
                Event event(Event::Announcement);
                event.setString("message", chatMsg);
                event.trigger(Event::ChatChannel);
            }
            break;
        }

        case SMSG_MVP:
            // Display MVP player
            msg.readInt32(); // id
            SERVER_NOTICE(_("MVP player."))
            break;
    }
}
Ejemplo n.º 28
0
void GameHandler::processMessage(NetComputer *comp, MessageIn &message)
{
    GameClient &computer = *static_cast< GameClient * >(comp);
    MessageOut result;

    if (computer.status == CLIENT_LOGIN)
    {
        if (message.getId() != PGMSG_CONNECT)
            return;

        std::string magic_token = message.readString(MAGIC_TOKEN_LENGTH);
        computer.status = CLIENT_QUEUED; // Before the addPendingClient
        mTokenCollector.addPendingClient(magic_token, &computer);
        return;
    }
    else if (computer.status != CLIENT_CONNECTED)
    {
        return;
    }

    switch (message.getId())
    {
        case PGMSG_SAY:
        {
            std::string say = message.readString();
            if (say.empty()) break;

            if (say[0] == '@')
            {
                CommandHandler::handleCommand(computer.character, say);
                break;
            }
            GameState::sayAround(computer.character, say);
            std::string msg = computer.character->getName() + " said " + say;
            accountHandler->sendTransaction(computer.character->getDatabaseID(), TRANS_MSG_PUBLIC, msg);
        } break;

        case PGMSG_NPC_TALK:
        case PGMSG_NPC_TALK_NEXT:
        case PGMSG_NPC_SELECT:
        case PGMSG_NPC_NUMBER:
        case PGMSG_NPC_STRING:
        {
            int id = message.readShort();
            Actor *o = findActorNear(computer.character, id);
            if (!o || o->getType() != OBJECT_NPC)
            {
                sendError(comp, id, "Not close enough to NPC\n");
                break;
            }

            NPC *q = static_cast< NPC * >(o);
            if (message.getId() == PGMSG_NPC_SELECT)
            {
                q->select(computer.character, message.readByte());
            }
            else if (message.getId() == PGMSG_NPC_NUMBER)
            {
                q->integerReceived(computer.character, message.readLong());
            }
            else if (message.getId() == PGMSG_NPC_STRING)
            {
                q->stringReceived(computer.character, message.readString());
            }
            else
            {
                q->prompt(computer.character, message.getId() == PGMSG_NPC_TALK);
            }
        } break;

        case PGMSG_PICKUP:
        {
            int x = message.readShort();
            int y = message.readShort();
            Point ppos = computer.character->getPosition();

            // TODO: use a less arbitrary value.
            if (std::abs(x - ppos.x) + std::abs(y - ppos.y) < 48)
            {
                MapComposite *map = computer.character->getMap();
                Point ipos(x, y);
                for (FixedActorIterator i(map->getAroundPointIterator(ipos, 0)); i; ++i)
                {
                    Actor *o = *i;
                    Point opos = o->getPosition();
                    if (o->getType() == OBJECT_ITEM && opos.x == x && opos.y == y)
                    {
                        Item *item = static_cast< Item * >(o);
                        ItemClass *ic = item->getItemClass();
                        Inventory(computer.character)
                            .insert(ic->getDatabaseID(), item->getAmount());
                        GameState::remove(item);
                        // log transaction
                        std::stringstream str;
                        str << "User picked up item " << ic->getDatabaseID()
                            << " at " << opos.x << "x" << opos.y;
                        accountHandler->sendTransaction(computer.character->getDatabaseID(),
                            TRANS_ITEM_PICKUP, str.str());
                        break;
                    }
                }
            }
        } break;

        case PGMSG_USE_ITEM:
        {
            int slot = message.readByte();
            Inventory inv(computer.character);
            if (ItemClass *ic = ItemManager::getItem(inv.getItem(slot)))
            {
                if (ic->use(computer.character))
                {
                    inv.removeFromSlot(slot, 1);
                    // log transaction
                    std::stringstream str;
                    str << "User used item " << ic->getDatabaseID()
                        << " from slot " << slot;
                    accountHandler->sendTransaction(computer.character->getDatabaseID(),
                        TRANS_ITEM_USED, str.str());
                }
            }
        } break;

        case PGMSG_DROP:
        {
            int slot = message.readByte();
            int amount = message.readByte();
            Inventory inv(computer.character);
            if (ItemClass *ic = ItemManager::getItem(inv.getItem(slot)))
            {
                int nb = inv.removeFromSlot(slot, amount);
                Item *item = new Item(ic, amount - nb);
                item->setMap(computer.character->getMap());
                item->setPosition(computer.character->getPosition());
                if (!GameState::insert(item))
                {
                    // The map is full. Put back into inventory.
                    inv.insert(ic->getDatabaseID(), amount - nb);
                    delete item;
                    break;
                }
                // log transaction
                Point pt = computer.character->getPosition();
                std::stringstream str;
                str << "User dropped item " << ic->getDatabaseID()
                    << " at " << pt.x << "x" << pt.y;
                accountHandler->sendTransaction(computer.character->getDatabaseID(),
                    TRANS_ITEM_DROP, str.str());
            }
        } break;

        case PGMSG_WALK:
        {
            handleWalk(&computer, message);
        } break;

        case PGMSG_EQUIP:
        {
            int slot = message.readByte();
            Inventory(computer.character).equip(slot);
        } break;

        case PGMSG_UNEQUIP:
        {
            int slot = message.readByte();
            if (slot >= 0 && slot < EQUIP_PROJECTILE_SLOT)
            {
                Inventory(computer.character).unequip(slot);
            }
        } break;

        case PGMSG_MOVE_ITEM:
        {
            int slot1 = message.readByte();
            int slot2 = message.readByte();
            int amount = message.readByte();
            Inventory(computer.character).move(slot1, slot2, amount);
            // log transaction
            std::stringstream str;
            str << "User moved item "
                << " from slot " << slot1 << " to slot " << slot2;
            accountHandler->sendTransaction(computer.character->getDatabaseID(),
                TRANS_ITEM_MOVE, str.str());
        } break;

        case PGMSG_ATTACK:
        {
            int id = message.readShort();
            LOG_DEBUG("Character " << computer.character->getPublicID()
                      << " attacked being " << id);

            Actor *o = findActorNear(computer.character, id);
            if (o && o->getType() != OBJECT_NPC)
            {
                Being *being = static_cast<Being*>(o);
                computer.character->setTarget(being);
                computer.character->setAction(Being::ATTACK);
            }
        } break;

        case PGMSG_USE_SPECIAL:
        {
            int specialID = message.readByte();
            LOG_DEBUG("Character " << computer.character->getPublicID()
                      << " tries to use his special attack "<<specialID);
            computer.character->useSpecial(specialID);
        }

        case PGMSG_ACTION_CHANGE:
        {
            Being::Action action = (Being::Action)message.readByte();
            Being::Action current = (Being::Action)computer.character->getAction();
            bool logActionChange = true;

            switch (action)
            {
                case Being::STAND:
                {
                    if (current == Being::SIT)
                    {
                        computer.character->setAction(Being::STAND);
                        logActionChange = false;
                    }
                } break;
                case Being::SIT:
                {
                    if (current == Being::STAND)
                    {
                        computer.character->setAction(Being::SIT);
                        logActionChange = false;
                    }
                } break;
                default:
                    break;
            }

            // Log the action change only when this is relevant.
            if (logActionChange)
            {
                // log transaction
                std::stringstream str;
                str << "User changed action from " << current
                    << " to " << action;
                accountHandler->sendTransaction(
                    computer.character->getDatabaseID(),
                    TRANS_ACTION_CHANGE, str.str());
            }

        } break;

        case PGMSG_DIRECTION_CHANGE:
        {
            computer.character->setDirection(message.readByte());
        } break;

        case PGMSG_DISCONNECT:
        {
            bool reconnectAccount = (bool) message.readByte();

            result.writeShort(GPMSG_DISCONNECT_RESPONSE);
            result.writeByte(ERRMSG_OK); // It is, when control reaches here

            if (reconnectAccount)
            {
                std::string magic_token(utils::getMagicToken());
                result.writeString(magic_token, MAGIC_TOKEN_LENGTH);
                // No accountserver data, the client should remember that
                accountHandler->playerReconnectAccount(
                                   computer.character->getDatabaseID(),
                                   magic_token);
            }
            // TODO: implement a delayed remove
            GameState::remove(computer.character);

            accountHandler->sendCharacterData(computer.character);

            // Done with the character
            computer.character->disconnected();
            delete computer.character;
            computer.character = NULL;
            computer.status = CLIENT_LOGIN;
        } break;

        case PGMSG_TRADE_REQUEST:
        {
            int id = message.readShort();

            if (Trade *t = computer.character->getTrading())
            {
                if (t->request(computer.character, id)) break;
            }

            Character *q = findCharacterNear(computer.character, id);
            if (!q || q->isBusy())
            {
                result.writeShort(GPMSG_TRADE_CANCEL);
                break;
            }

            new Trade(computer.character, q);

            // log transaction
            std::string str;
            str = "User requested trade with " + q->getName();
            accountHandler->sendTransaction(computer.character->getDatabaseID(),
                TRANS_TRADE_REQUEST, str);
        } break;

        case PGMSG_TRADE_CANCEL:
        case PGMSG_TRADE_AGREED:
        case PGMSG_TRADE_CONFIRM:
        case PGMSG_TRADE_ADD_ITEM:
        case PGMSG_TRADE_SET_MONEY:
        {
            std::stringstream str;
            Trade *t = computer.character->getTrading();
            if (!t) break;

            switch (message.getId())
            {
                case PGMSG_TRADE_CANCEL:
                    t->cancel();
                    break;
                case PGMSG_TRADE_CONFIRM:
                    t->confirm(computer.character);
                    break;
                case PGMSG_TRADE_AGREED:
                    t->agree(computer.character);
                    // log transaction
                    accountHandler->sendTransaction(computer.character->getDatabaseID(),
                        TRANS_TRADE_END, "User finished trading");
                    break;
                case PGMSG_TRADE_SET_MONEY:
                {
                    int money = message.readLong();
                    t->setMoney(computer.character, money);
                    // log transaction
                    str << "User added " << money << " money to trade.";
                    accountHandler->sendTransaction(computer.character->getDatabaseID(),
                        TRANS_TRADE_MONEY, str.str());
                } break;
                case PGMSG_TRADE_ADD_ITEM:
                {
                    int slot = message.readByte();
                    t->addItem(computer.character, slot, message.readByte());
                    // log transaction
                    str << "User add item from slot " << slot;
                    accountHandler->sendTransaction(computer.character->getDatabaseID(),
                        TRANS_TRADE_ITEM, str.str());
                } break;
            }
        } break;

        case PGMSG_NPC_BUYSELL:
        {
            BuySell *t = computer.character->getBuySell();
            if (!t) break;
            int id = message.readShort();
            int amount = message.readShort();
            t->perform(id, amount);
        } break;

        case PGMSG_RAISE_ATTRIBUTE:
        {
            int attribute = message.readByte();
            AttribmodResponseCode retCode;
            retCode = computer.character->useCharacterPoint(attribute);
            result.writeShort(GPMSG_RAISE_ATTRIBUTE_RESPONSE);
            result.writeByte(retCode);
            result.writeByte(attribute);

            if (retCode == ATTRIBMOD_OK )
            {
                accountHandler->updateCharacterPoints(
                    computer.character->getDatabaseID(),
                    computer.character->getCharacterPoints(),
                    computer.character->getCorrectionPoints(),
                    attribute,
                    computer.character->getAttribute(attribute));

                // log transaction
                std::stringstream str;
                str << "User increased attribute " << attribute;
                accountHandler->sendTransaction(computer.character->getDatabaseID(),
                    TRANS_ATTR_INCREASE, str.str());
            }
        } break;

        case PGMSG_LOWER_ATTRIBUTE:
        {
            int attribute = message.readByte();
            AttribmodResponseCode retCode;
            retCode = computer.character->useCorrectionPoint(attribute);
            result.writeShort(GPMSG_LOWER_ATTRIBUTE_RESPONSE);
            result.writeByte(retCode);
            result.writeByte(attribute);

            if (retCode == ATTRIBMOD_OK )
            {
                accountHandler->updateCharacterPoints(
                    computer.character->getDatabaseID(),
                    computer.character->getCharacterPoints(),
                    computer.character->getCorrectionPoints(),
                    attribute,
                    computer.character->getAttribute(attribute));

                // log transaction
                std::stringstream str;
                str << "User decreased attribute " << attribute;
                accountHandler->sendTransaction(computer.character->getDatabaseID(),
                    TRANS_ATTR_DECREASE, str.str());
            }
        } break;

        case PGMSG_RESPAWN:
        {
            computer.character->respawn(); // plausibility check is done by character class
        } break;

        case PGMSG_NPC_POST_SEND:
        {
            handleSendPost(&computer, message);
        } break;

        default:
            LOG_WARN("Invalid message type");
            result.writeShort(XXMSG_INVALID);
            break;
    }

    if (result.getLength() > 0)
        computer.send(result);
}
Ejemplo n.º 29
0
void AccountConnection::processMessage(MessageIn &msg)
{
    LOG_DEBUG("Received message " << msg << " from account server");

    switch (msg.getId())
    {
        case AGMSG_REGISTER_RESPONSE:
        {
            if (msg.readInt16() != DATA_VERSION_OK)
            {
                LOG_ERROR("Item database is outdated! Please update to "
                          "prevent inconsistencies");
                stop();  // Disconnect gracefully from account server.
                // Stop gameserver to prevent inconsistencies.
                exit(EXIT_DB_EXCEPTION);
            }
            else
            {
                LOG_DEBUG("Local item database is "
                          "in sync with account server.");
            }
            if (msg.readInt16() != PASSWORD_OK)
            {
                LOG_ERROR("This game server sent a invalid password");
                stop();
                exit(EXIT_BAD_CONFIG_PARAMETER);
            }

            // read world state variables
            while (msg.getUnreadLength())
            {
                std::string key = msg.readString();
                std::string value = msg.readString();
                if (!key.empty() && !value.empty())
                {
                    GameState::setVariableFromDbserver(key, value);
                }
            }

        } break;

        case AGMSG_PLAYER_ENTER:
        {
            std::string token = msg.readString(MAGIC_TOKEN_LENGTH);
            Character *ptr = new Character(msg);
            gameHandler->addPendingCharacter(token, ptr);
        } break;

        case AGMSG_ACTIVE_MAP:
        {
            int mapId = msg.readInt16();
            if (MapManager::activateMap(mapId))
            {
                // Set map variables
                MapComposite *m = MapManager::getMap(mapId);
                int mapVarsNumber = msg.readInt16();
                for(int i = 0; i < mapVarsNumber; ++i)
                {
                    std::string key = msg.readString();
                    std::string value = msg.readString();
                    if (!key.empty() && !value.empty())
                        m->setVariableFromDbserver(key, value);
                }

                // Recreate potential persistent floor items
                LOG_DEBUG("Recreate persistant items on map " << mapId);
                int floorItemsNumber = msg.readInt16();

                for (int i = 0; i < floorItemsNumber; ++i)
                {
                    int itemId = msg.readInt32();
                    int amount = msg.readInt16();
                    int posX = msg.readInt16();
                    int posY = msg.readInt16();

                    if (ItemClass *ic = itemManager->getItem(itemId))
                    {
                        Item *item = new Item(ic, amount);
                        item->setMap(m);
                        Point dst(posX, posY);
                        item->setPosition(dst);

                        if (!GameState::insertOrDelete(item))
                        {
                            // The map is full.
                            LOG_WARN("Couldn't add floor item(s) " << itemId
                                << " into map " << mapId);
                            return;
                        }
                    }
                }
            }
        } break;

        case AGMSG_SET_VAR_WORLD:
        {
            std::string key = msg.readString();
            std::string value = msg.readString();
            GameState::setVariableFromDbserver(key, value);
            LOG_DEBUG("Global variable \"" << key << "\" has changed to \""
                      << value << "\"");
        } break;

        case AGMSG_REDIRECT_RESPONSE:
        {
            int id = msg.readInt32();
            std::string token = msg.readString(MAGIC_TOKEN_LENGTH);
            std::string address = msg.readString();
            int port = msg.readInt16();
            gameHandler->completeServerChange(id, token, address, port);
        } break;

        case AGMSG_GET_VAR_CHR_RESPONSE:
        {
            int id = msg.readInt32();
            std::string name = msg.readString();
            std::string value = msg.readString();
            recoveredQuestVar(id, name, value);
        } break;

        case CGMSG_CHANGED_PARTY:
        {
            // Character DB id
            int charid = msg.readInt32();
            // Party id, 0 for none
            int partyid = msg.readInt32();
            gameHandler->updateCharacter(charid, partyid);
        } break;

        case CGMSG_POST_RESPONSE:
        {
            // get the character
            Character *character = postMan->getCharacter(msg.readInt32());

            // check character is still valid
            if (!character)
            {
                break;
            }

            std::string sender = msg.readString();
            std::string letter = msg.readString();

            postMan->gotPost(character, sender, letter);

        } break;

        case CGMSG_STORE_POST_RESPONSE:
        {
            // get character
            Character *character = postMan->getCharacter(msg.readInt32());

            // check character is valid
            if (!character)
            {
                break;
            }

            // TODO: Get NPC to tell character if the sending of post
            // was successful or not

        } break;

        default:
            LOG_WARN("Invalid message type");
            break;
    }
}