void ItemHandler::processItemDropped(Net::MessageIn &msg) const
{
    const int id = msg.readInt32();
    const int itemId = msg.readInt16();
    const unsigned char identify = msg.readInt8();  // identify flag
    const int x = msg.readInt16();
    const int y = msg.readInt16();
    const int subX = msg.readInt8();
    const int subY = msg.readInt8();
    const int amount = msg.readInt16();

    if (actorManager)
    {
        actorManager->createItem(id, itemId,
            x, y, amount, identify, subX, subY);
    }
}
示例#2
0
void PartyRecv::processPartySettings(Net::MessageIn &msg)
{
    if (!partyTab)
    {
        if (!chatWindow)
            return;

        Ea::PartyRecv::createTab();
    }

    msg.readInt32("party exp");
    const PartyShareT exp = static_cast<PartyShareT>(
        msg.readInt8("share exp"));
    const PartyShareT item = static_cast<PartyShareT>(
        msg.readInt8("share item"));
    Ea::PartyRecv::processPartySettingsContinue(msg, exp, item);
}
示例#3
0
void PartyHandler::processPartyLeave(Net::MessageIn &msg)
{
    int id = msg.readInt32();
    std::string nick = msg.readString(24);
    msg.readInt8();     // fail
    if (!player_node)
        return;

    if (id == player_node->getId())
    {
        if (Ea::taParty)
        {
            Ea::taParty->removeFromMembers();
            Ea::taParty->clearMembers();
        }
        SERVER_NOTICE(_("You have left the party."))
        delete Ea::partyTab;
        Ea::partyTab = nullptr;

        if (socialWindow && Ea::taParty)
            socialWindow->removeTab(Ea::taParty);
        player_node->setPartyName("");
    }
    else
    {
        if (Ea::partyTab)
        {
            Ea::partyTab->chatLog(strprintf(
                _("%s has left your party."),
                nick.c_str()), BY_SERVER);
        }
        if (actorSpriteManager)
        {
            Being *b = actorSpriteManager->findBeing(id);
            if (b && b->getType() == Being::PLAYER)
            {
                b->setParty(nullptr);
                b->setPartyName("");
            }
        }
        if (Ea::taParty)
            Ea::taParty->removeMember(id);
    }
}
示例#4
0
void PlayerHandler::processPlayerGetExp(Net::MessageIn &msg)
{
    if (!localPlayer)
        return;
    const BeingId id = msg.readBeingId("player id");
    const int exp = msg.readInt32("exp amount");
    const int stat = msg.readInt16("exp type");
    const bool fromQuest = msg.readInt16("is from quest");
    if (!fromQuest && id == localPlayer->getId())
    {
        if (stat == 1)
            localPlayer->addXpMessage(exp);
        else if (stat == 2)
            localPlayer->addJobMessage(exp);
        else
            UNIMPLIMENTEDPACKET;
    }
    // need show particle depend on isQuest flag, for now ignored
}
示例#5
0
void PartyHandler::processPartyInvited(Net::MessageIn &msg)
{
    int id = msg.readInt32();
    std::string partyName = msg.readString(24);
    std::string nick("");
    Being *being;

    if (actorSpriteManager)
    {
        if ((being = actorSpriteManager->findBeing(id)))
        {
            if (being && being->getType() == Being::PLAYER)
                nick = being->getName();
        }
    }

    if (socialWindow)
        socialWindow->showPartyInvite(partyName, nick);
}
示例#6
0
void FamilyRecv::processAskForChildReply(Net::MessageIn &msg)
{
    const int type = msg.readInt32("type");
    switch (type)
    {
        case 0:
            NotifyManager::notify(NotifyTypes::ADOPT_CHILD_ERROR_HAVE_BABY);
            break;
        case 1:
            NotifyManager::notify(NotifyTypes::ADOPT_CHILD_ERROR_LEVEL);
            break;
        case 2:
            NotifyManager::notify(NotifyTypes::ADOPT_CHILD_ERROR_BABY_MARRIED);
            break;
        default:
            UNIMPLEMENTEDPACKETFIELD(type);
            break;
    }
}
示例#7
0
void BuyingStoreRecv::processBuyingStoreCreateFailed(Net::MessageIn &msg)
{
    const int16_t result = msg.readInt16("result");
    const int weight = msg.readInt32("weight");
    switch (result)
    {
        case 1:
        default:
            NotifyManager::notify(NotifyTypes::BUYING_STORE_CREATE_FAILED);
            break;
        case 2:
            NotifyManager::notify(
                NotifyTypes::BUYING_STORE_CREATE_FAILED_WEIGHT,
                weight);
            break;
        case 8:
            NotifyManager::notify(NotifyTypes::BUYING_STORE_CREATE_EMPTY);
            break;
    }
}
示例#8
0
void GuildRecv::processGuildPosNameList(Net::MessageIn &msg)
{
    if (taGuild == nullptr)
    {
        logger->log1("!taGuild");
        return;
    }

    const int length = msg.readInt16("len");
    if (length < 4)
        return;
    const int count = (length - 4) / 28;

    for (int i = 0; i < count; i++)
    {
        const int id = msg.readInt32("position id");
        const std::string name = msg.readString(24, "position name");
        taGuild->addPos(id, name);
    }
}
示例#9
0
void BuyingStoreRecv::processBuyingStoreDeleteItem(Net::MessageIn &msg)
{
    Inventory *const inventory = localPlayer
        ? PlayerInfo::getInventory() : nullptr;

    const int index = msg.readInt16("index") - INVENTORY_OFFSET;
    const int amount = msg.readInt16("amount");
    msg.readInt32("price");

    if (inventory)
    {
        if (Item *const item = inventory->getItem(index))
        {
            item->increaseQuantity(-amount);
            if (item->getQuantity() == 0)
                inventory->removeItemAt(index);
            ArrowsListener::distributeEvent();
        }
    }
}
void GuildHandler::processGuildPosNameList(Net::MessageIn &msg) const
{
    if (!taGuild)
    {
        logger->log1("!taGuild");
        return;
    }

    const int length = msg.readInt16();
    if (length < 4)
        return;
    const int count = (length - 4) / 28;

    for (int i = 0; i < count; i++)
    {
        const int id = msg.readInt32();               // ID
        const std::string name = msg.readString(24);  // Position name
        taGuild->addPos(id, name);
    }
}
示例#11
0
void AchievementRecv::processAchievementUpdate(Net::MessageIn &msg)
{
    UNIMPLEMENTEDPACKET;
    msg.readInt32("total points");
    msg.readInt16("rank level");
    msg.readInt32("rank points");
    msg.readInt32("rank points need");

    msg.readInt32("ach id");
    msg.readUInt8("completed");
    for (int d = 0; d < 10; d ++)
        msg.readInt32("objective");
    msg.readInt32("completed at");
    msg.readUInt8("reward");
}
示例#12
0
void AchievementRecv::processAchievementList(Net::MessageIn &msg)
{
    UNIMPLEMENTEDPACKET;
    const int count = (msg.readInt16("len") - 22) / 50;
    msg.readInt32("total achievements");
    msg.readInt32("total points");
    msg.readInt16("rank level");
    msg.readInt32("rank points");
    msg.readInt32("rank points need");
    for (int f = 0; f < count; f ++)
    {
        msg.readInt32("ach id");
        msg.readUInt8("completed");
        for (int d = 0; d < 10; d ++)
            msg.readInt32("objective");
        msg.readInt32("completed at");
        msg.readUInt8("reward");
    }
}
示例#13
0
void PartyRecv::processPartyMemberInfo(Net::MessageIn &msg)
{
    const BeingId id = msg.readBeingId("account id");
    if (msg.getVersion() >= 20171207)
        msg.readBeingId("char id");
    const bool leader = msg.readInt32("leader") == 0U;
    int level = 0;
    if (msg.getVersionMain() >= 20170524 ||
        msg.getVersionRe() >= 20170502 ||
        packets_zero == true)
    {
        msg.readInt16("class");
        level = msg.readInt16("level");
    }
    const int x = msg.readInt16("x");
    const int y = msg.readInt16("y");
    const bool online = msg.readInt8("online") == 0U;
    msg.readString(24, "party name");
    const std::string nick = msg.readString(24, "player name");
    const std::string map = msg.readString(16, "map name");
    msg.readInt8("pickup item share (&1)");
    msg.readInt8("get item share (&2)");

    if (Ea::taParty == nullptr)
        return;

    PartyMember *const member = Ea::taParty->addMember(id, nick);
    if (member != nullptr)
    {
        if ((partyTab != nullptr) && member->getOnline() != online)
            partyTab->showOnline(nick, fromBool(online, Online));
        member->setLeader(leader);
        member->setOnline(online);
        member->setMap(map);
        member->setX(x);
        member->setY(y);
        if (level != 0)
            member->setLevel(level);
    }
}
示例#14
0
void GameRecv::processMapLogin(Net::MessageIn &msg)
{
    unsigned char direction;
    uint16_t x;
    uint16_t y;
    msg.readInt32("tick");
    msg.readCoordinates(x, y, direction, "position");
    msg.readInt16("unknown?");
    logger->log("Protocol: Player start position: (%d, %d),"
                " Direction: %d", x, y, direction);

    mLastHost &= 0xffffff;

    Network *const network = Network::mInstance;
    if (network != nullptr)
        network->pauseDispatch();

    // Switch now or we'll have problems
    client->setState(State::GAME);
    if (localPlayer != nullptr)
        localPlayer->setTileCoords(x, y);
}
示例#15
0
void PartyHandler::processPartyUpdateHp(Net::MessageIn &msg)
{
    int id = msg.readInt32();
    int hp = msg.readInt16();
    int maxhp = msg.readInt16();
    PartyMember *m = nullptr;
    if (Ea::taParty)
        m = Ea::taParty->getMember(id);
    if (m)
    {
        m->setHp(hp);
        m->setMaxHp(maxhp);
    }

    // The server only sends this when the member is in range, so
    // lets make sure they get the party hilight.
    if (actorSpriteManager && Ea::taParty)
    {
        if (Being *b = actorSpriteManager->findBeing(id))
            b->setParty(Ea::taParty);
    }
}  
示例#16
0
void PartyRecv::processPartySettings(Net::MessageIn &msg)
{
    if (partyTab == nullptr)
    {
        if (chatWindow == nullptr)
            return;

        Ea::PartyRecv::createTab();
    }

    const PartyShareT exp = static_cast<PartyShareT>(
        msg.readInt32("party exp"));
    Ea::PartyRecv::processPartyExpSettingsContinue(msg, exp);
    if (msg.getVersion() >= 20090603)
    {
        const PartyShareT item = static_cast<PartyShareT>(
            msg.readInt8("pickup item share (&1)"));
        Ea::PartyRecv::processPartyItemSettingsContinue(msg, item);
        const PartyShareT autoItem = static_cast<PartyShareT>(
            msg.readInt8("get auto item share (&2)"));
        processPartyAutoItemSettingsContinue(msg, autoItem);
    }
}
示例#17
0
void PartyHandler::processPartyMessage(Net::MessageIn &msg)
{
    int msgLength = msg.readInt16() - 8;
    if (msgLength <= 0)
        return;

    int id = msg.readInt32();
    std::string chatMsg = msg.readString(msgLength);

    if (Ea::taParty && Ea::partyTab)
    {
        PartyMember *member = Ea::taParty->getMember(id);
        if (member)
        {
            Ea::partyTab->chatLog(member->getName(), chatMsg);
        }
        else
        {
            Ea::partyTab->chatLog(strprintf(
                _("An unknown member tried to say: %s"),
                chatMsg.c_str()), BY_SERVER);
        }
    }
}
示例#18
0
void GuildRecv::processGuildBasicInfo(Net::MessageIn &msg)
{
    const int guildId = msg.readInt32("guild id");
    const int level = msg.readInt32("guild level");
    const int members = msg.readInt32("connect member");
    const int maxMembers = msg.readInt32("max member");
    const int avgLevel = msg.readInt32("average level");
    const int exp = msg.readInt32("exp");
    const int nextExp = msg.readInt32("next exp");
    msg.skip(12, "unused");
    const int emblem = msg.readInt32("emblem id");
    std::string name = msg.readString(24, "guild name");
    std::string castle;
    std::string master;
    if (msg.getVersion() >= 20160622)
    {
        castle = msg.readString(16, "castles");
        msg.readInt32("money, unused");
        msg.readBeingId("leader char id");
    }
    else
    {
        master = msg.readString(24, "master name");
        castle = msg.readString(16, "castles");
        msg.readInt32("money, unused");
    }

    if (guildTab != nullptr &&
        showBasicInfo)
    {
        showBasicInfo = false;
        // TRANSLATORS: guild info message
        guildTab->chatLog(strprintf(_("Guild name: %s"),
            name.c_str()),
            ChatMsgType::BY_SERVER,
            IgnoreRecord_false,
            TryRemoveColors_true);
        if (!master.empty())
        {
            // TRANSLATORS: guild info message
            guildTab->chatLog(strprintf(_("Guild master: %s"),
                master.c_str()),
                ChatMsgType::BY_SERVER,
                IgnoreRecord_false,
                TryRemoveColors_true);
        }
        // TRANSLATORS: guild info message
        guildTab->chatLog(strprintf(_("Guild level: %d"), level),
            ChatMsgType::BY_SERVER,
            IgnoreRecord_false,
            TryRemoveColors_true);
        // TRANSLATORS: guild info message
        guildTab->chatLog(strprintf(_("Online members: %d"), members),
            ChatMsgType::BY_SERVER,
            IgnoreRecord_false,
            TryRemoveColors_true);
        // TRANSLATORS: guild info message
        guildTab->chatLog(strprintf(_("Max members: %d"), maxMembers),
            ChatMsgType::BY_SERVER,
            IgnoreRecord_false,
            TryRemoveColors_true);
        // TRANSLATORS: guild info message
        guildTab->chatLog(strprintf(_("Average level: %d"), avgLevel),
            ChatMsgType::BY_SERVER,
            IgnoreRecord_false,
            TryRemoveColors_true);
        // TRANSLATORS: guild info message
        guildTab->chatLog(strprintf(_("Guild exp: %d"), exp),
            ChatMsgType::BY_SERVER,
            IgnoreRecord_false,
            TryRemoveColors_true);
        // TRANSLATORS: guild info message
        guildTab->chatLog(strprintf(_("Guild next exp: %d"), nextExp),
            ChatMsgType::BY_SERVER,
            IgnoreRecord_false,
            TryRemoveColors_true);
        // TRANSLATORS: guild info message
        guildTab->chatLog(strprintf(_("Guild castle: %s"), castle.c_str()),
            ChatMsgType::BY_SERVER,
            IgnoreRecord_false,
            TryRemoveColors_true);
    }

    Guild *const g = Guild::getGuild(CAST_S16(guildId));
    if (g == nullptr)
        return;
    g->setName(name);
    g->setEmblemId(emblem);
}
示例#19
0
void PlayerHandler::handleMessage(Net::MessageIn &msg)
{
    if (!player_node)
        return;

    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);
                int x = msg.readInt16();
                int 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();

                Game *game = Game::instance();

                const std::string &currentMapName = game->getCurrentMapName();
                bool sameMap = (currentMapName == mapPath);

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

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

                /* Scroll if necessary */
                Map *map = game->getCurrentMap();
                int tileX = player_node->getTileX();
                int tileY = player_node->getTileY();
                if (!sameMap
                    || (abs(x - tileX) > MAP_TELEPORT_SCROLL_DISTANCE)
                    || (abs(y - tileY) > MAP_TELEPORT_SCROLL_DISTANCE))
                {
                    scrollOffsetX = (x - tileX) * map->getTileWidth();
                    scrollOffsetY = (y - tileY) * map->getTileHeight();
                }

                player_node->setAction(Being::STAND);
                Vector pos = map->getTileCenter(x, y);
                player_node->setPosition(pos);
                // Stop movement
                player_node->setDestination(pos.x, pos.y);

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

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

        case SMSG_PLAYER_STAT_UPDATE_1:
            {
                if (!player_node)
                    break;
                int type = msg.readInt16();
                int value = msg.readInt32();

                switch (type)
                {
                    case 0x0000:
                      player_node->setMoveSpeed(Vector(value / 10,
                                                       value / 10, 0));
                    break;
                    case 0x0004: break; // manner
                    case 0x0005: PlayerInfo::setAttribute(HP, value); break;
                    case 0x0006: PlayerInfo::setAttribute(MAX_HP, value); break;
                    case 0x0007: PlayerInfo::setAttribute(MP, value); break;
                    case 0x0008: PlayerInfo::setAttribute(MAX_MP, value); break;
                    case 0x0009: PlayerInfo::setAttribute(CHAR_POINTS, value); break;
                    case 0x000b: PlayerInfo::setAttribute(LEVEL, value); break;
                    case 0x000c: PlayerInfo::setAttribute(SKILL_POINTS, value); break;
                    case 0x0018:
                                 if (value >= PlayerInfo::getAttribute(MAX_WEIGHT) / 2 &&
                                         PlayerInfo::getAttribute(TOTAL_WEIGHT) <
                                         PlayerInfo::getAttribute(MAX_WEIGHT) / 2)
                                 {
                                     weightNotice = new OkDialog(_("Message"),
                                             _("You are carrying more than "
                                               "half your weight. You are "
                                               "unable to regain health."));
                                     weightNotice->addActionListener(
                                             &weightListener);
                                 }
                                 PlayerInfo::setAttribute(TOTAL_WEIGHT, value);
                                 break;
                    case 0x0019: PlayerInfo::setAttribute(MAX_WEIGHT, value); break;

                    case 0x0029: PlayerInfo::setStatBase(ATK, value); break;
                    case 0x002a: PlayerInfo::setStatMod(ATK, value); break;

                    case 0x002b: PlayerInfo::setStatBase(MATK, value); break;
                    case 0x002c: PlayerInfo::setStatMod(MATK, value); break;

                    case 0x002d: PlayerInfo::setStatBase(DEF, value); break;
                    case 0x002e: PlayerInfo::setStatMod(DEF, value); break;

                    case 0x002f: PlayerInfo::setStatBase(MDEF, value); break;
                    case 0x0030: PlayerInfo::setStatMod(MDEF, value); break;

                    case 0x0031: PlayerInfo::setStatBase(HIT, value); break;

                    case 0x0032: PlayerInfo::setStatBase(FLEE, value); break;
                    case 0x0033: PlayerInfo::setStatMod(FLEE, value); break;

                    case 0x0034: PlayerInfo::setStatBase(CRIT, value); break;

                    case 0x0035: player_node->setAttackSpeed(value); break;

                    case 0x0037: PlayerInfo::setStatBase(JOB, value); break;

                    case 500: player_node->setGMLevel(value); break;
                }

                if (PlayerInfo::getAttribute(HP) == 0 && !deathNotice)
                {
                    viewport->shakeScreen(100);
                    deathNotice = new OkDialog(_("Message"),
                                               randomDeathMessage(),
                                               false);
                    deathNotice->addActionListener(&deathListener);
                    player_node->setAction(Being::DEAD);
                }
            }

            if (statusWindow)
                statusWindow->updateAttrs();

            break;

        case SMSG_PLAYER_STAT_UPDATE_2:
            switch (msg.readInt16())
            {
                case 0x0001:
                    PlayerInfo::setAttribute(EXP, msg.readInt32());
                    break;
                case 0x0002:
                    PlayerInfo::setStatExperience(JOB, msg.readInt32(),
                                                  PlayerInfo::getStatExperience(JOB).second);
                    break;

                case 0x0014:
                    {
                        int oldMoney = PlayerInfo::getAttribute(MONEY);
                        int newMoney = msg.readInt32();
                        std::string money = Units::formatCurrency(
                                            newMoney - oldMoney);
                        PlayerInfo::setAttribute(MONEY, newMoney);
                        if (newMoney > oldMoney)
                        {
                            if (config.getBoolValue("showpickupchat"))
                                SERVER_NOTICE(strprintf(_("You picked up %s."),
                                            Units::formatCurrency(newMoney -
                                            oldMoney).c_str()))
                            if (config.getBoolValue("showpickupparticle"))
                                player_node->addMessageToQueue(money,
                                                      UserPalette::PICKUP_INFO);
                        }
                    }
                    break;
                case 0x0016:
                    PlayerInfo::setAttribute(EXP_NEEDED, msg.readInt32());
                    break;
                case 0x0017:
                    PlayerInfo::setStatExperience(JOB,
                                                  PlayerInfo::getStatExperience(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();

                PlayerInfo::setStatBase(type, base, false);
                PlayerInfo::setStatMod(type, bonus);
            }
            break;

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

                if (ok != 1)
                {
                    SERVER_NOTICE(_("Cannot raise skill!"))
                }

                PlayerInfo::setStatBase(type, value);
            }
            break;

        // Updates stats and status points
        case SMSG_PLAYER_STAT_UPDATE_5:
            PlayerInfo::setAttribute(CHAR_POINTS, msg.readInt16());

            {
                int val = msg.readInt8();
                PlayerInfo::setStatBase(STR, val);
                if (val >= 99)
                {
                    statusWindow->setPointsNeeded(STR, 0);
                    msg.readInt8();
                }
                else
                {
                    statusWindow->setPointsNeeded(STR, msg.readInt8());
                }

                val = msg.readInt8();
                PlayerInfo::setStatBase(AGI, val);
                if (val >= 99)
                {
                    statusWindow->setPointsNeeded(AGI, 0);
                    msg.readInt8();
                }
                else
                {
                    statusWindow->setPointsNeeded(AGI, msg.readInt8());
                }

                val = msg.readInt8();
                PlayerInfo::setStatBase(VIT, val);
                if (val >= 99)
                {
                    statusWindow->setPointsNeeded(VIT, 0);
                    msg.readInt8();
                }
                else
                {
                    statusWindow->setPointsNeeded(VIT, msg.readInt8());
                }

                val = msg.readInt8();
                PlayerInfo::setStatBase(INT, val);
                if (val >= 99)
                {
                    statusWindow->setPointsNeeded(INT, 0);
                    msg.readInt8();
                }
                else
                {
                    statusWindow->setPointsNeeded(INT, msg.readInt8());
                }

                val = msg.readInt8();
                PlayerInfo::setStatBase(DEX, val);
                if (val >= 99)
                {
                    statusWindow->setPointsNeeded(DEX, 0);
                    msg.readInt8();
                }
                else
                {
                    statusWindow->setPointsNeeded(DEX, msg.readInt8());
                }

                val = msg.readInt8();
                PlayerInfo::setStatBase(LUK, val);
                if (val >= 99)
                {
                    statusWindow->setPointsNeeded(LUK, 0);
                    msg.readInt8();
                }
                else
                {
                    statusWindow->setPointsNeeded(LUK, msg.readInt8());
                }

                PlayerInfo::setStatBase(ATK, msg.readInt16(), false);
                PlayerInfo::setStatMod(ATK, msg.readInt16());

                PlayerInfo::setStatBase(MATK, msg.readInt16(), false);
                PlayerInfo::setStatMod(MATK, msg.readInt16());


                PlayerInfo::setStatBase(DEF, msg.readInt16(), false);
                PlayerInfo::setStatMod(DEF, msg.readInt16());

                PlayerInfo::setStatBase(MDEF, msg.readInt16(), false);
                PlayerInfo::setStatMod(MDEF, msg.readInt16());

                PlayerInfo::setStatBase(HIT, msg.readInt16());

                PlayerInfo::setStatBase(FLEE, msg.readInt16(), false);
                PlayerInfo::setStatMod(FLEE, msg.readInt16());

                PlayerInfo::setStatBase(CRIT, msg.readInt16());
            }

            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(INT, 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:
                        {
                            SERVER_NOTICE(_("Equip arrows first."))
                        }
                        break;
                    default:
                        logger->log("0x013b: Unhandled message %i", type);
                        break;
                }
            }
            break;
    }
}
示例#20
0
void GuildRecv::processGuildMemberList(Net::MessageIn &msg)
{
    if (actorManager == nullptr)
        return;

    const int length = msg.readInt16("len");
    if (length < 4)
        return;
    int guildSize = 0;
    if (msg.getVersion() >= 20161026)
    {
        guildSize = 34;
    }
    else
    {
        guildSize = 104;
    }

    const int count = (length - 4) / guildSize;
    if (taGuild == nullptr)
    {
        logger->log1("!taGuild");
        return;
    }

    taGuild->clearMembers();

    int onlineNum = 0;
    int totalNum = 0;
    for (int i = 0; i < count; i++)
    {
        const BeingId id = msg.readBeingId("account id");
        const int charId = msg.readInt32("char id");
        msg.readInt16("hair");
        msg.readInt16("hair color");
        const int gender = msg.readInt16("gender");
        const int race = msg.readInt16("class");
        const int level = msg.readInt16("level");
        const int exp = msg.readInt32("exp");
        const int online = msg.readInt32("online");
        const int pos = msg.readInt32("position");
        std::string name;
        if (msg.getVersion() < 20161026)
        {
            msg.skip(50, "unused");
            name = msg.readString(24, "name");
        }
        else
        {
            msg.readInt32("last login");  // for now unused
            name = actorManager->findCharById(charId);
            if (name.empty())
            {
                beingHandler->requestNameByCharId(charId);
            }
        }

        GuildMember *const m = taGuild->addMember(id, charId, name);
        if (m != nullptr)
        {
            m->setOnline(online != 0);
            m->setID(id);
            m->setCharId(charId);
            m->setGender(Being::intToGender(CAST_U8(gender)));
            m->setLevel(level);
            m->setExp(exp);
            m->setPos(pos);
            m->setRace(race);
            Being *const being = actorManager->findBeingByName(
                name, ActorType::Player);
            if (being != nullptr)
            {
                being->setGuildName(taGuild->getName());
                if (being->getLevel() != level)
                {
                    being->setLevel(level);
                    being->updateName();
                }
            }
            if (online != 0)
                onlineNum ++;
            totalNum ++;
        }
    }
    taGuild->sort();
    actorManager->updatePlayerGuild();
    actorManager->updatePlayerColors();
    if (socialWindow != nullptr)
        socialWindow->updateGuildCounter(onlineNum, totalNum);
}
void CharServerHandler::readPlayerData(Net::MessageIn &msg,
                                       Net::Character *const character,
                                       const bool) const
{
    if (!character)
        return;

    const Token &token =
        static_cast<LoginHandler*>(Net::getLoginHandler())->getToken();

    LocalPlayer *const tempPlayer = new LocalPlayer(msg.readInt32(), 0);
    tempPlayer->setGender(token.sex);

    PlayerInfoBackend &data = character->data;
    data.mAttributes[Attributes::EXP] = msg.readInt32();
    data.mAttributes[Attributes::MONEY] = msg.readInt32();
    Stat &jobStat = data.mStats[JOB];
    jobStat.exp = msg.readInt32();

    const int temp = msg.readInt32();
    jobStat.base = temp;
    jobStat.mod = temp;

    const int shoes = msg.readInt16();
    const int gloves = msg.readInt16();
    const int cape = msg.readInt16();
    const int misc1 = msg.readInt16();

    msg.readInt32();                       // option
    msg.readInt32();                       // karma
    msg.readInt32();                       // manner
    msg.readInt16();                       // character points left

    data.mAttributes[Attributes::HP] = msg.readInt16();
    data.mAttributes[Attributes::MAX_HP] = msg.readInt16();
    data.mAttributes[Attributes::MP] = msg.readInt16();
    data.mAttributes[Attributes::MAX_MP] = msg.readInt16();

    msg.readInt16();                             // speed
    tempPlayer->setSubtype(msg.readInt16(), 0);  // class (used for race)
    const int hairStyle = msg.readInt16();
    const uint16_t weapon = msg.readInt16();

    tempPlayer->setSprite(SPRITE_WEAPON, weapon, "", 1, true);

    data.mAttributes[Attributes::LEVEL] = msg.readInt16();

    msg.readInt16();  // skill point
    const int bottomClothes = msg.readInt16();
    const int shield = msg.readInt16();

    const int hat = msg.readInt16();  // head option top
    const int topClothes = msg.readInt16();

    tempPlayer->setSprite(SPRITE_HAIR, hairStyle * -1,
        ItemDB::get(-hairStyle).getDyeColorsString(msg.readInt16()));

    const int misc2 = msg.readInt16();
    tempPlayer->setName(msg.readString(24));

    character->dummy = tempPlayer;

    for (int i = 0; i < 6; i++)
        character->data.mStats[i + STR].base = msg.readUInt8();

    tempPlayer->setSprite(SPRITE_SHOE, shoes);
    tempPlayer->setSprite(SPRITE_GLOVES, gloves);
    tempPlayer->setSprite(SPRITE_CAPE, cape);
    tempPlayer->setSprite(SPRITE_MISC1, misc1);
    tempPlayer->setSprite(SPRITE_BOTTOMCLOTHES, bottomClothes);
    // to avoid show error (error.xml) need remove this sprite
    if (!config.getBoolValue("hideShield"))
        tempPlayer->setSprite(SPRITE_SHIELD, shield);

    tempPlayer->setSprite(SPRITE_HAT, hat);  // head option top
    tempPlayer->setSprite(SPRITE_TOPCLOTHES, topClothes);
    tempPlayer->setSprite(SPRITE_MISC2, misc2);
    character->slot = msg.readUInt8();  // character slot

    msg.readUInt8();  // unknown
}
示例#22
0
void TradeHandler::handleMessage(Net::MessageIn &msg)
{
    switch (msg.getId())
    {
        case GPMSG_TRADE_REQUEST:
        {
            Being *being = actorSpriteManager->findBeing(msg.readInt16());
            if (!being || !mAcceptTradeRequests)
            {
                respond(false);
                break;
            }
            mTrading = true;
            tradePartnerName = being->getName();
            tradePartnerID = being->getId();
            ConfirmDialog *dlg = new ConfirmDialog(_("Request for Trade"),
                    strprintf(_("%s wants to trade with you, do you accept?"),
                            tradePartnerName.c_str()));
            dlg->addActionListener(&listener);
        }   break;

        case GPMSG_TRADE_ADD_ITEM:
        {
            int type = msg.readInt16();
            int amount = msg.readInt8();
            tradeWindow->addItem(type, false, amount);
        }   break;

        case GPMSG_TRADE_SET_MONEY:
            tradeWindow->setMoney(msg.readInt32());
            break;

        case GPMSG_TRADE_START:
            tradeWindow->reset();
            tradeWindow->setCaption(strprintf(_("Trading with %s"),
                                              tradePartnerName.c_str()));
            tradeWindow->setVisible(true);
            break;

        case GPMSG_TRADE_BOTH_CONFIRM:
            tradeWindow->receivedOk(false);
            break;

        case GPMSG_TRADE_AGREED:
            tradeWindow->receivedOk(false);
            break;

        case GPMSG_TRADE_CANCEL:
            SERVER_NOTICE(_("Trade canceled."))
            tradeWindow->setVisible(false);
            tradeWindow->reset();
            mTrading = false;
            break;

        case GPMSG_TRADE_COMPLETE:
            SERVER_NOTICE(_("Trade completed."))
            tradeWindow->setVisible(false);
            tradeWindow->reset();
            mTrading = false;
            break;
    }
}
示例#23
0
void TradeHandler::handleMessage(Net::MessageIn &msg)
{
    switch (msg.getId())
    {
    case SMSG_TRADE_REQUEST:
    {
        // If a trade window or request window is already open, send a
        // trade cancel to any other trade request.
        //
        // Note that it would be nice if the server would prevent this
        // situation, and that the requesting player would get a
        // special message about the player being occupied.
        std::string tradePartnerNameTemp = msg.readString(24);

        if (player_relations.hasPermission(tradePartnerName,
                                           PlayerRelation::TRADE))
        {
            if (PlayerInfo::isTrading() || confirmDlg)
            {
                Net::getTradeHandler()->respond(false);
                break;
            }

            tradePartnerName = tradePartnerNameTemp;
            PlayerInfo::setTrading(true);
            confirmDlg = new ConfirmDialog(_("Request for Trade"),
                                           strprintf(_("%s wants to trade with you, do you "
                                                   "accept?"), tradePartnerName.c_str()));
            confirmDlg->addActionListener(&listener);
        }
        else
        {
            Net::getTradeHandler()->respond(false);
            break;
        }
    }
    break;

    case SMSG_TRADE_RESPONSE:
        switch (msg.readInt8())
        {
        case 0: // Too far away
            SERVER_NOTICE(_("Trading isn't possible. Trade "
                            "partner is too far away."))
            break;
        case 1: // Character doesn't exist
            SERVER_NOTICE(_("Trading isn't possible. Character "
                            "doesn't exist."))
            break;
        case 2: // Invite request check failed...
            SERVER_NOTICE(_("Trade cancelled due to an unknown "
                            "reason."))
            break;
        case 3: // Trade accepted
            tradeWindow->reset();
            tradeWindow->setCaption(strprintf(_("Trade: You and %s"),
                                              tradePartnerName.c_str()));
            tradeWindow->setVisible(true);
            break;
        case 4: // Trade cancelled
            if (player_relations.hasPermission(tradePartnerName,
                                               PlayerRelation::SPEECH_LOG))
                SERVER_NOTICE(strprintf(_("Trade with %s cancelled."),
                                        tradePartnerName.c_str()))
                // otherwise ignore silently

                tradeWindow->setVisible(false);
            PlayerInfo::setTrading(false);
            break;
        default: // Shouldn't happen as well, but to be sure
            SERVER_NOTICE(_("Unhandled trade cancel packet."))
            break;
        }
        break;

    case SMSG_TRADE_ITEM_ADD:
    {
        int amount = msg.readInt32();
        int type = msg.readInt16();
        msg.readInt8();  // identified flag
        msg.readInt8();  // attribute
        msg.readInt8();  // refine
        msg.skip(8);     // card (4 shorts)

        // TODO: handle also identified, etc
        if (type == 0)
            tradeWindow->setMoney(amount);
        else
            tradeWindow->addItem(type, false, amount);
    }
    break;

    case SMSG_TRADE_ITEM_ADD_RESPONSE:
        // Trade: New Item add response (was 0x00ea, now 01b1)
    {
        const int index = msg.readInt16() - INVENTORY_OFFSET;
        Item *item = PlayerInfo::getInventory()->getItem(index);
        if (!item)
        {
            tradeWindow->receivedOk(true);
            return;
        }
        int quantity = msg.readInt16();

        switch (msg.readInt8())
        {
        case 0:
            // Successfully added item
            if (item->isEquippable() && item->isEquipped())
            {
                item->doEvent(Event::DoUnequip);
            }
            tradeWindow->addItem(item->getId(), true, quantity);

            item->increaseQuantity(-quantity);
            break;
        case 1:
            // Add item failed - player overweighted
            SERVER_NOTICE(_("Failed adding item. Trade "
                            "partner is over weighted."))
            break;
        case 2:
            // Add item failed - player has no free slot
            SERVER_NOTICE(_("Failed adding item. Trade "
                            "partner has no free slot."))
            break;
        default:
            SERVER_NOTICE(_("Failed adding item for "
                            "unknown reason."))
            break;
        }
    }
    break;

    case SMSG_TRADE_OK:
        // 0 means ok from myself, 1 means ok from other;
        tradeWindow->receivedOk(msg.readInt8() == 0);
        break;

    case SMSG_TRADE_CANCEL:
        SERVER_NOTICE(_("Trade canceled."))
        tradeWindow->setVisible(false);
        tradeWindow->reset();
        PlayerInfo::setTrading(false);
        break;

    case SMSG_TRADE_COMPLETE:
        SERVER_NOTICE(_("Trade completed."))
        tradeWindow->setVisible(false);
        tradeWindow->reset();
        PlayerInfo::setTrading(false);
        break;
    }
}
示例#24
0
void LoginHandler::handleMessage(Net::MessageIn &msg)
{
    int code, worldCount;

    switch (msg.getId())
    {
        case SMSG_CHAR_PASSWORD_RESPONSE:
        {
            // 0: acc not found, 1: success, 2: password mismatch, 3: pass too short
            int errMsg = msg.readInt8();
            // Successful pass change
            if (errMsg == 1)
            {
                Client::setState(STATE_CHANGEPASSWORD_SUCCESS);
            }
            // pass change failed
            else
            {
                switch (errMsg)
                {
                    case 0:
                        errorMessage = _("Account was not found. Please re-login.");
                        break;
                    case 2:
                        errorMessage = _("Old password incorrect.");
                        break;
                    case 3:
                        errorMessage = _("New password too short.");
                        break;
                    default:
                        errorMessage = _("Unknown error.");
                        break;
                }
                Client::setState(STATE_ACCOUNTCHANGE_ERROR);
            }
        }
            break;

        case SMSG_UPDATE_HOST:
             int len;

             len = msg.readInt16() - 4;
             mUpdateHost = msg.readString(len);
             loginData.updateHost = mUpdateHost;

             logger->log("Received update host \"%s\" from login server.",
                     mUpdateHost.c_str());
             break;

        case SMSG_LOGIN_DATA:
            // Skip the length word
            msg.skip(2);

            clearWorlds();

            worldCount = (msg.getLength() - 47) / 32;

            mToken.session_ID1 = msg.readInt32();
            mToken.account_ID = msg.readInt32();
            mToken.session_ID2 = msg.readInt32();
            msg.skip(30);                           // unknown
            mToken.sex = msg.readInt8() ? GENDER_MALE : GENDER_FEMALE;

            for (int i = 0; i < worldCount; i++)
            {
                WorldInfo *world = new WorldInfo;

                world->address = msg.readInt32();
                world->port = msg.readInt16();
                world->name = msg.readString(20);
                world->online_users = msg.readInt32();
                world->updateHost = mUpdateHost;
                msg.skip(2);                        // unknown

                logger->log("Network: Server: %s (%s:%d)",
                        world->name.c_str(),
                        ipToString(world->address),
                        world->port);

                mWorlds.push_back(world);
            }
            Client::setState(STATE_WORLD_SELECT);
            break;

        case SMSG_LOGIN_ERROR:
            code = msg.readInt8();
            logger->log("Login::error code: %i", code);

            switch (code)
            {
                case 0:
                    errorMessage = _("Unregistered ID.");
                    break;
                case 1:
                    errorMessage = _("Wrong password.");
                    break;
                case 2:
                    errorMessage = _("Account expired.");
                    break;
                case 3:
                    errorMessage = _("Rejected from server.");
                    break;
                case 4:
                    errorMessage = _("You have been permanently banned from "
                                     "the game. Please contact the GM team.");
                    break;
                case 5:
                    errorMessage = _("Client too old.");
                    break;
                case 6:
                    errorMessage = strprintf(_("You have been temporarily "
                                               "banned from the game until "
                                               "%s.\nPlease contact the GM "
                                               "team via the forums."),
                                               msg.readString(20).c_str());
                    break;
                case 7:
                    errorMessage = _("Server overpopulated.");
                    break;
                case 9:
                    errorMessage = _("This user name is already taken.");
                    break;
                case 99:
                    errorMessage = _("Username permanently erased.");
                    break;
                default:
                    errorMessage = _("Unknown error.");
                    break;
            }
            Client::setState(STATE_ERROR);
            break;

        case SMSG_SERVER_VERSION_RESPONSE:
            {
                // TODO: verify these!

                msg.readInt8(); // -1
                msg.readInt8(); // T
                msg.readInt8(); // M
                msg.readInt8(); // W

                unsigned int options = msg.readInt32();

                mRegistrationEnabled = (options & 1);

                // Leave this last
                mVersionResponse = true;
            }
            break;
    }
}
示例#25
0
void CharServerHandler::handleMessage(Net::MessageIn &msg)
{
    switch (msg.getId())
    {
            case SMSG_CHAR_LOGIN:
            {
                msg.skip(2);  // Length word
                msg.skip(20); // Unused

                // Derive number of characters from message length
                const int count = (msg.getLength() - 24) / 106;

                for (int i = 0; i < count; ++i)
                {
                    Net::Character *character = new Net::Character;
                    readPlayerData(msg, character);
                    mCharacters.push_back(character);
                    logger->log("CharServer: Player: %s (%d)",
                                character->dummy->getName().c_str(), character->slot);
                }

                Client::setState(STATE_CHAR_SELECT);
            }
            break;

        case SMSG_CHAR_LOGIN_ERROR:
            switch (msg.readInt8())
            {
                case 0:
                    errorMessage = _("Access denied. Most likely, there are "
                                     "too many players on this server.");
                    break;
                case 1:
                    errorMessage = _("Cannot use this ID.");
                    break;
                default:
                    errorMessage = _("Unknown char-server failure.");
                    break;
            }
            Client::setState(STATE_ERROR);
            break;

        case SMSG_CHAR_CREATE_SUCCEEDED:
            {
                Net::Character *character = new Net::Character;
                readPlayerData(msg, character);
                mCharacters.push_back(character);

                updateCharSelectDialog();

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

        case SMSG_CHAR_CREATE_FAILED:
            new OkDialog(_("Error"), _("Failed to create character. Most "
                                       "likely the name is already taken."));
            if (mCharCreateDialog)
                mCharCreateDialog->unlock();
            break;

        case SMSG_CHAR_DELETE_SUCCEEDED:
            delete mSelectedCharacter;
            mCharacters.remove(mSelectedCharacter);
            mSelectedCharacter = 0;
            updateCharSelectDialog();
            unlockCharSelectDialog();
            new OkDialog(_("Info"), _("Character deleted."));
            break;

        case SMSG_CHAR_DELETE_FAILED:
            unlockCharSelectDialog();
            new OkDialog(_("Error"), _("Failed to delete character."));
            break;

        case SMSG_CHAR_MAP_INFO:
        {
            msg.skip(4); // CharID, must be the same as player_node->charID
            GameHandler *gh = static_cast<GameHandler*>(Net::getGameHandler());
            gh->setMap(msg.readString(16));
            mapServer.hostname = ipToString(msg.readInt32());
            mapServer.port = msg.readInt16();

            // Prevent the selected local player from being deleted
            player_node = mSelectedCharacter->dummy;
            PlayerInfo::setBackend(mSelectedCharacter->data);

            mSelectedCharacter->dummy = 0;

            delete_all(mCharacters);
            mCharacters.clear();
            updateCharSelectDialog();

            mNetwork->disconnect();
            Client::setState(STATE_CONNECT_GAME);
        }
        break;

        case SMSG_CHANGE_MAP_SERVER:
        {
            GameHandler *gh = static_cast<GameHandler*>(Net::getGameHandler());
            gh->setMap(msg.readString(16));
            int x = msg.readInt16();
            int y = msg.readInt16();
            mapServer.hostname = ipToString(msg.readInt32());
            mapServer.port = msg.readInt16();

            mNetwork->disconnect();
            Client::setState(STATE_CHANGE_MAP);
            player_node->setTileCoords(x, y);
            player_node->setMap(0);
        }
        break;
    }
}
示例#26
0
void LoginRecv::processLoginData(Net::MessageIn &msg)
{
    msg.readInt16("len");

    loginHandler->clearWorlds();

    int offset = 0;
    int serverLen = 0;
    if (msg.getVersion() >= 20170315)
    {
        offset = 47 + 17;
        serverLen = 32 + 128;
    }
    else
    {
        offset = 47;
        serverLen = 32;
    }

    const int worldCount = (msg.getLength() - offset) / serverLen;

    Ea::LoginRecv::mToken.session_ID1 = msg.readInt32("session id1");
    Ea::LoginRecv::mToken.account_ID = msg.readBeingId("accound id");
    Ea::LoginRecv::mToken.session_ID2 = msg.readInt32("session id2");
    msg.readInt32("old ip");
    loginData.lastLogin = msg.readString(24, "last login");
    msg.readInt16("unused");

    // reserve bits for future usage
    Ea::LoginRecv::mToken.sex = Being::intToGender(CAST_U8(
        msg.readUInt8("gender") & 3U));

    if (msg.getVersion() >= 20170315)
    {
        msg.readString(16, "twitter auth token");
        msg.readUInt8("twitter flag");
    }

    for (int i = 0; i < worldCount; i++)
    {
        WorldInfo *const world = new WorldInfo;

        world->address = msg.readInt32("ip address");
        world->port = msg.readInt16("port");
        world->name = msg.readString(20, "name");
        world->online_users = msg.readInt16("online number");
        config.setValue("updatehost", Ea::LoginRecv::mUpdateHost);
        world->updateHost = Ea::LoginRecv::mUpdateHost;
        msg.readInt16("maintenance");
        msg.readInt16("new");
        if (msg.getVersion() >= 20170315)
        {
            for (int f = 0; f < 32; f ++)
                msg.readInt32("unused2");
        }

        logger->log("Network: Server: %s (%s:%d)", world->name.c_str(),
            ipToString(world->address), world->port);

        Ea::LoginRecv::mWorlds.push_back(world);
    }
    client->setState(State::WORLD_SELECT);
}
示例#27
0
void PartyHandler::processPartyInfo(Net::MessageIn &msg)
{
    bool oldParty = false;
    std::set<std::string> names;
    if (!Ea::taParty)
    {
        logger->log1("error: party empty in SMSG_PARTY_INFO");
        Ea::taParty = Party::getParty(1);
    }
    if (Ea::taParty)
    {
        if (Ea::taParty->getNumberOfElements() > 1)
        {
            oldParty = true;

            Ea::taParty->getNamesSet(names);
        }
    }

    if (!player_node)
        logger->log1("error: player_node==0 in SMSG_PARTY_INFO");

    if (Ea::taParty)
        Ea::taParty->clearMembers();

    int length = msg.readInt16();
    if (Ea::taParty)
        Ea::taParty->setName(msg.readString(24));

    int count = (length - 28) / 46;
    if (player_node && Ea::taParty)
    {
        player_node->setParty(Ea::taParty);
        player_node->setPartyName(Ea::taParty->getName());
    }

    for (int i = 0; i < count; i++)
    {
        int id = msg.readInt32();
        std::string nick = msg.readString(24);
        std::string map = msg.readString(16);
        bool leader = msg.readInt8() == 0;
        bool online = msg.readInt8() == 0;

        if (Ea::taParty)
        {
            PartyMember *member = nullptr;
            if (oldParty)
            {
                //member = Ea::taParty->getMember(id);
                if (Ea::partyTab && names.find(nick) == names.end())
                {
                    Ea::partyTab->chatLog(strprintf(
                        _("%s has joined your party."),
                        nick.c_str()), BY_SERVER);
                }
            }
            member = Ea::taParty->addMember(id, nick);

            if (member)
            {
                member->setLeader(leader);
                member->setOnline(online);
                member->setMap(map);
            }
        }
    }

    if (Ea::taParty)
        Ea::taParty->sort();

    if (player_node && Ea::taParty)
    {
        player_node->setParty(Ea::taParty);
        player_node->setPartyName(Ea::taParty->getName());
    }
}
示例#28
0
void CashShopHandler::processCashShopPoints(Net::MessageIn &msg)
{
    UNIMPLIMENTEDPACKET;
    msg.readInt32("cash points");
    msg.readInt32("kafra points");
}
示例#29
0
void AchievementRecv::processAchievementGetReward(Net::MessageIn &msg)
{
    UNIMPLEMENTEDPACKET;
    msg.readUInt8("received");
    msg.readInt32("ach id");
}
示例#30
0
void GuildHandler::processGuildMemberList(Net::MessageIn &msg)
{
    const int length = msg.readInt16("len");
    if (length < 4)
        return;
    const int count = (length - 4) / 104;
    if (!taGuild)
    {
        logger->log1("!taGuild");
        return;
    }

    taGuild->clearMembers();

    int onlineNum = 0;
    int totalNum = 0;
    for (int i = 0; i < count; i++)
    {
        const BeingId id = msg.readBeingId("account id");
        const int charId = msg.readInt32("char id");
        msg.readInt16("hair");
        msg.readInt16("hair color");
        const int gender = msg.readInt16("gender");
        const int race = msg.readInt16("class");
        const int level = msg.readInt16("level");
        const int exp = msg.readInt32("exp");
        const int online = msg.readInt32("online");
        const int pos = msg.readInt32("position");
        msg.skip(50, "unused");
        std::string name = msg.readString(24, "name");

        GuildMember *const m = taGuild->addMember(id, charId, name);
        if (m)
        {
            m->setOnline(online);
            m->setID(id);
            m->setCharId(charId);
            m->setGender(Being::intToGender(static_cast<uint8_t>(gender)));
            m->setLevel(level);
            m->setExp(exp);
            m->setPos(pos);
            m->setRace(race);
            if (actorManager)
            {
                Being *const being = actorManager->findBeingByName(
                    name, ActorType::Player);
                if (being)
                {
                    being->setGuildName(taGuild->getName());
                    if (being->getLevel() != level)
                    {
                        being->setLevel(level);
                        being->updateName();
                    }
                }
            }
            if (online)
                onlineNum ++;
            totalNum ++;
        }
    }
    taGuild->sort();
    if (actorManager)
    {
        actorManager->updatePlayerGuild();
        actorManager->updatePlayerColors();
    }
    if (socialWindow)
        socialWindow->updateGuildCounter(onlineNum, totalNum);
}