예제 #1
0
파일: party.cpp 프로젝트: mrktj/tmwa
// パーティが追加された
int party_member_added(PartyId party_id, AccountId account_id, int flag)
{
    dumb_ptr<map_session_data> sd = map_id2sd(account_to_block(account_id)), sd2;
    PartyPair p = party_search(party_id);

    if (sd == nullptr)
    {
        if (flag == 0)
        {
            if (battle_config.error_log)
                PRINTF("party: member added error %d is not online\n"_fmt,
                        account_id);
            intif_party_leave(party_id, account_id);   // キャラ側に登録できなかったため脱退要求を出す
        }
        return 0;
    }
    sd2 = map_id2sd(account_to_block(sd->party_invite_account));
    sd->party_invite = PartyId();
    sd->party_invite_account = AccountId();

    if (!p)
    {
        PRINTF("party_member_added: party %d not found.\n"_fmt, party_id);
        intif_party_leave(party_id, account_id);
        return 0;
    }

    if (flag == 1)
    {                           // 失敗
        if (sd2 != nullptr)
            clif_party_inviteack(sd2, sd->status_key.name, 0);
        return 0;
    }

    // 成功
    sd->party_sended = 0;
    sd->status.party_id = party_id;

    if (sd2 != nullptr)
        clif_party_inviteack(sd2, sd->status_key.name, 2);

    // いちおう競合確認
    party_check_conflict(sd);

    party_send_xy_clear(p);

    return 0;
}
예제 #2
0
파일: party.cpp 프로젝트: mrktj/tmwa
/* Relay the result of a party creation request. */
void party_created(AccountId account_id, int fail, PartyId party_id, PartyName name)
{
    dumb_ptr<map_session_data> sd;
    sd = map_id2sd(account_to_block(account_id));

    nullpo_retv(sd);

    /* The party name is valid and not already taken. */
    if (!fail)
    {
        sd->status.party_id = party_id;

        PartyPair p = party_search(party_id);
        if (p)
        {
            PRINTF("party_created(): ID already exists!\n"_fmt);
            exit(1);
        }

        p.party_most = party_db.init(party_id);
        p.party_id = party_id;
        p->name = name;

        /* The party was created successfully. */
        clif_party_created(sd, 0);
    }

    else
        clif_party_created(sd, 1);
}
예제 #3
0
파일: party.cpp 프로젝트: mrktj/tmwa
/* Process response to party invitation. */
int party_reply_invite(dumb_ptr<map_session_data> sd, AccountId account_id, int flag)
{
    nullpo_retz(sd);

    /* There is no pending invitation. */
    if (!sd->party_invite || !sd->party_invite_account)
        return 0;

    /*
     * Only one invitation can be pending, so these have to be the same. Since
     * the client continues to send the wrong ID, and it's already managed on
     * this side of things, the sent ID is being ignored.
     */
    account_id = sd->party_invite_account;

    /* The invitation was accepted. */
    if (flag == 1)
        intif_party_addmember(sd->party_invite, sd->status_key.account_id);
    /* The invitation was rejected. */
    else
    {
        /* This is the player who sent the invitation. */
        dumb_ptr<map_session_data> tsd = nullptr;

        sd->party_invite = PartyId();
        sd->party_invite_account = AccountId();

        if ((tsd = map_id2sd(account_to_block(account_id))))
            clif_party_inviteack(tsd, sd->status_key.name, 1);
    }
    return 0;
}
예제 #4
0
파일: chrif.cpp 프로젝트: Rosalila/tswa
/*==========================================
 * マップ鯖間移動ack
 *------------------------------------------
 */
static
int chrif_changemapserverack(Session *, const Packet_Fixed<0x2b06>& fixed)
{
    dumb_ptr<map_session_data> sd = map_id2sd(account_to_block(fixed.account_id));

    if (sd == nullptr || sd->status_key.char_id != fixed.char_id)
        return -1;

    // I am fairly certain that this is not possible
    if (fixed.error == 1)
    {
        if (battle_config.error_log)
            PRINTF("map server change failed.\n"_fmt);
        pc_authfail(sd->status_key.account_id);
        return 0;
    }
    MapName mapname = fixed.map_name;
    uint16_t x = fixed.x;
    uint16_t y = fixed.y;
    IP4Address ip = fixed.map_ip;
    uint16_t port = fixed.map_port;
    clif_changemapserver(sd, mapname, x, y, ip, port);

    return 0;
}
예제 #5
0
파일: trade.cpp 프로젝트: mrktj/tmwa
/*==========================================
 * アイテム追加完了(ok押し)
 *------------------------------------------
 */
void trade_tradeok(dumb_ptr<map_session_data> sd)
{
    dumb_ptr<map_session_data> target_sd;
    int trade_i;

    nullpo_retv(sd);

    for (trade_i = 0; trade_i < TRADE_MAX; trade_i++)
    {
        IOff2 index = sd->deal_item_index[trade_i];
        if (!index.ok())
            continue;
        if (sd->deal_item_amount[trade_i] >
            sd->status.inventory[index.unshift()].amount
            || sd->deal_item_amount[trade_i] < 0)
        {
            trade_tradecancel(sd);
            return;
        }

    }

    if ((target_sd = map_id2sd(account_to_block(sd->trade_partner))) != nullptr)
    {
        sd->deal_locked = 1;
        clif_tradeitemok(sd, IOff2::from(0), 0, 0);
        clif_tradedeal_lock(sd, 0);
        clif_tradedeal_lock(target_sd, 1);
    }
}
예제 #6
0
파일: trade.cpp 프로젝트: mrktj/tmwa
/*==========================================
 * 取引要請
 *------------------------------------------
 */
void trade_tradeack(dumb_ptr<map_session_data> sd, int type)
{
    dumb_ptr<map_session_data> target_sd;
    nullpo_retv(sd);

    if ((target_sd = map_id2sd(account_to_block(sd->trade_partner))) != nullptr)
    {
        clif_tradestart(target_sd, type);
        clif_tradestart(sd, type);
        if (type == 4)
        {                       // Cancel
            sd->deal_locked = 0;
            sd->trade_partner = AccountId();
            target_sd->deal_locked = 0;
            target_sd->trade_partner = AccountId();
        }
        if (sd->npc_id)
            npc_event_dequeue(sd);
        if (target_sd->npc_id)
            npc_event_dequeue(target_sd);

        //close STORAGE window if it's open. It protects from spooffing packets [Lupus]
        if (sd->state.storage_open)
            storage_storageclose(sd);
    }
}
예제 #7
0
파일: chrif.cpp 프로젝트: Rosalila/tswa
/*==========================================
 * Disconnection of a player (account has been deleted in login-server) by [Yor]
 *------------------------------------------
 */
static
int chrif_accountdeletion(Session *, const Packet_Fixed<0x2b13>& fixed)
{
    dumb_ptr<map_session_data> sd;

    AccountId acc = fixed.account_id;
    if (battle_config.etc_log)
        PRINTF("chrif_accountdeletion %d.\n"_fmt, acc);
    sd = map_id2sd(account_to_block(acc));
    if (acc)
    {
        if (sd != nullptr)
        {
            sd->login_id1++;    // change identify, because if player come back in char within the 5 seconds, he can change its characters
            clif_displaymessage(sd->sess,
                                 "Your account has been deleted (disconnection)..."_s);
            clif_setwaitclose(sd->sess); // forced to disconnect for the change
        }
    }
    else
    {
        if (sd != nullptr)
            PRINTF("chrif_accountdeletion failed - player not online.\n"_fmt);
    }

    return 0;
}
예제 #8
0
파일: trade.cpp 프로젝트: mrktj/tmwa
/*==========================================
 * 取引キャンセル
 *------------------------------------------
 */
void trade_tradecancel(dumb_ptr<map_session_data> sd)
{
    dumb_ptr<map_session_data> target_sd;
    int trade_i;

    nullpo_retv(sd);

    if ((target_sd = map_id2sd(account_to_block(sd->trade_partner))) != nullptr)
    {
        for (trade_i = 0; trade_i < TRADE_MAX; trade_i++)
        {                       //give items back (only virtual)
            if (sd->deal_item_amount[trade_i] != 0)
            {
                assert (sd->deal_item_index[trade_i].ok());
                clif_additem(sd,
                        sd->deal_item_index[trade_i].unshift(),
                        sd->deal_item_amount[trade_i],
                        PickupFail::OKAY);
                sd->deal_item_index[trade_i] = IOff2::from(0);
                sd->deal_item_amount[trade_i] = 0;
            }
            if (target_sd->deal_item_amount[trade_i] != 0)
            {
                assert (target_sd->deal_item_index[trade_i].ok());
                clif_additem(target_sd,
                        target_sd->deal_item_index[trade_i].unshift(),
                        target_sd->deal_item_amount[trade_i],
                        PickupFail::OKAY);
                target_sd->deal_item_index[trade_i] = IOff2::from(0);
                target_sd->deal_item_amount[trade_i] = 0;
            }
        }
        if (sd->deal_zeny)
        {
            sd->deal_zeny = 0;
            clif_updatestatus(sd, SP::ZENY);
        }
        if (target_sd->deal_zeny)
        {
            clif_updatestatus(target_sd, SP::ZENY);
            target_sd->deal_zeny = 0;
        }
        sd->deal_locked = 0;
        sd->trade_partner = AccountId();
        target_sd->deal_locked = 0;
        target_sd->trade_partner = AccountId();
        clif_tradecancelled(sd);
        clif_tradecancelled(target_sd);
    }
}
예제 #9
0
파일: party.cpp 프로젝트: mrktj/tmwa
// パーティの設定変更通知
int party_optionchanged(PartyId party_id, AccountId account_id, int exp, int item,
                         int flag)
{
    PartyPair p;
    dumb_ptr<map_session_data> sd = map_id2sd(account_to_block(account_id));
    if (!(p = party_search(party_id)))
        return 0;

    if (!(flag & 0x01))
        p->exp = exp;
    if (!(flag & 0x10))
        p->item = item;
    clif_party_option(p, sd, flag);
    return 0;
}
예제 #10
0
파일: intif.cpp 프로젝트: themanaworld/tmwa
// アカウント変数通知
static
int intif_parse_AccountReg(Session *, const Packet_Head<0x3804>& head, const std::vector<Packet_Repeat<0x3804>>& repeat)
{
    dumb_ptr<map_session_data> sd = map_id2sd(account_to_block(head.account_id));
    if (sd == nullptr)
        return 1;

    size_t jlim = std::min(ACCOUNT_REG_NUM, repeat.size());
    for (size_t j = 0; j < jlim; j++)
    {
        sd->status.account_reg[j].str = repeat[j].name;
        sd->status.account_reg[j].value = repeat[j].value;
    }
    sd->status.account_reg_num = jlim;

    return 0;
}
예제 #11
0
파일: trade.cpp 프로젝트: mrktj/tmwa
// This is called when a char's zeny is changed
// This helps prevent money duplication and other problems
// [Jaxad0127]
void trade_verifyzeny(dumb_ptr<map_session_data> sd)
{
    dumb_ptr<map_session_data> target_sd;

    nullpo_retv(sd);

    if ((target_sd = map_id2sd(account_to_block(sd->trade_partner))) != nullptr)
    {
        if (sd->deal_zeny > sd->status.zeny)
        {
            if (sd->deal_locked < 1)
                trade_tradeadditem(sd, IOff2::from(0), sd->status.zeny);    // Fix money ammount
            else
                trade_tradecancel(sd); // Or cancel the trade if we can't fix it
        }
    }
}
예제 #12
0
파일: intif.cpp 프로젝트: themanaworld/tmwa
// パーティ追加要求
void intif_party_addmember(PartyId party_id, AccountId account_id)
{
    if (!char_session)
        return;

    dumb_ptr<map_session_data> sd;
    sd = map_id2sd(account_to_block(account_id));
    if (sd != nullptr)
    {
        Packet_Fixed<0x3022> fixed_22;
        fixed_22.party_id = party_id;
        fixed_22.account_id = account_id;
        fixed_22.char_name = sd->status_key.name;
        fixed_22.map_name = sd->bl_m->name_;
        fixed_22.level = sd->status.base_level;
        send_fpacket<0x3022, 52>(char_session, fixed_22);
    }
}
예제 #13
0
파일: chrif.cpp 프로젝트: Rosalila/tswa
/*==========================================
 * End of GM change(@GM) (modified by Yor)
 *------------------------------------------
 */
static
void chrif_changedgm(Session *, const Packet_Fixed<0x2b0b>& fixed)
{
    AccountId acc = fixed.account_id;
    GmLevel level = fixed.gm_level;

    dumb_ptr<map_session_data> sd = map_id2sd(account_to_block(acc));

    if (battle_config.etc_log)
        PRINTF("chrif_changedgm: account: %d, GM level 0 -> %d.\n"_fmt, acc,
                level);
    if (sd != nullptr)
    {
        if (level)
            clif_displaymessage(sd->sess, "GM modification success."_s);
        else
            clif_displaymessage(sd->sess, "Failure of GM modification."_s);
    }
}
예제 #14
0
파일: chrif.cpp 프로젝트: Rosalila/tswa
/*==========================================
 * 性別変化終了 (modified by Yor)
 *------------------------------------------
 */
static
void chrif_changedsex(Session *, const Packet_Fixed<0x2b0d>& fixed)
{
    dumb_ptr<map_session_data> sd;

    AccountId acc = fixed.account_id;
    SEX sex = fixed.sex;
    if (battle_config.etc_log)
        PRINTF("chrif_changedsex %d.\n"_fmt, acc);
    sd = map_id2sd(account_to_block(acc));
    if (acc)
    {
        if (sd != nullptr && sd->status.sex != sex)
        {
            if (sd->status.sex == SEX::MALE)
                sd->sex = sd->status.sex = SEX::FEMALE;
            else if (sd->status.sex == SEX::FEMALE)
                sd->sex = sd->status.sex = SEX::MALE;
            // to avoid any problem with equipment and invalid sex, equipment is unequiped.
            for (IOff0 i : IOff0::iter())
            {
                if (sd->status.inventory[i].nameid
                    && bool(sd->status.inventory[i].equip))
                    pc_unequipitem(sd, i, CalcStatus::NOW);
            }
            // save character
            chrif_save(sd);
            sd->login_id1++;    // change identify, because if player come back in char within the 5 seconds, he can change its characters
            // do same modify in login-server for the account, but no in char-server (it ask again login_id1 to login, and don't remember it)
            clif_displaymessage(sd->sess,
                                 "Your sex has been changed (need disconexion by the server)..."_s);
            clif_setwaitclose(sd->sess); // forced to disconnect for the change
        }
    }
    else
    {
        if (sd != nullptr)
        {
            PRINTF("chrif_changedsex failed.\n"_fmt);
        }
    }
}
예제 #15
0
파일: party.cpp 프로젝트: mrktj/tmwa
// パーティメンバの移動通知
void party_recv_movemap(PartyId party_id, AccountId account_id, MapName mapname,
        int online, int lv)
{
    PartyPair p;
    int i;
    if (!(p = party_search(party_id)))
        return;
    for (i = 0; i < MAX_PARTY; i++)
    {
        PartyMember *m = &p->member[i];
        if (m == nullptr)
        {
            PRINTF("party_recv_movemap nullpo?\n"_fmt);
            return;
        }
        if (m->account_id == account_id)
        {
            m->map = mapname;
            m->online = online;
            m->lv = lv;
            break;
        }
    }
    if (i == MAX_PARTY)
    {
        if (battle_config.error_log)
            PRINTF("party: not found member %d on %d[%s]"_fmt, account_id,
                    party_id, p->name);
        return;
    }

    for (i = 0; i < MAX_PARTY; i++)
    {                           // sd再設定
        dumb_ptr<map_session_data> sd = map_id2sd(account_to_block(p->member[i].account_id));
        p->member[i].sd = (sd != nullptr
                           && sd->status.party_id == p.party_id) ? sd.operator->() : nullptr;
    }

    party_send_xy_clear(p);    // 座標再通知要請

    clif_party_info(p, nullptr);
}
예제 #16
0
파일: intif.cpp 프로젝트: themanaworld/tmwa
// 倉庫データ受信
static
int intif_parse_LoadStorage(Session *, const Packet_Payload<0x3810>& payload)
{
    dumb_ptr<map_session_data> sd;

    sd = map_id2sd(account_to_block(payload.account_id));
    if (sd == nullptr)
    {
        if (battle_config.error_log)
            PRINTF("intif_parse_LoadStorage: user not found %d\n"_fmt,
                    payload.account_id);
        return 1;
    }
    P<Storage> stor = account2storage(payload.account_id);
    if (stor->storage_status == 1)
    {                           // Already open.. lets ignore this update
        if (battle_config.error_log)
            PRINTF("intif_parse_LoadStorage: storage received for a client already open (User %d:%d)\n"_fmt,
                    sd->status_key.account_id, sd->status_key.char_id);
        return 1;
    }
    if (stor->dirty)
    {                           // Already have storage, and it has been modified and not saved yet! Exploit! [Skotlex]
        if (battle_config.error_log)
            PRINTF("intif_parse_LoadStorage: received storage for an already modified non-saved storage! (User %d:%d)\n"_fmt,
                    sd->status_key.account_id, sd->status_key.char_id);
        return 1;
    }

    if (battle_config.save_log)
        PRINTF("intif_openstorage: %d\n"_fmt, payload.account_id);
    *stor = payload.storage;
    stor->dirty = 0;
    stor->storage_status = 1;
    sd->state.storage_open = 1;
    clif_storageitemlist(sd, stor);
    clif_storageequiplist(sd, stor);
    clif_updatestorageamount(sd, stor);

    return 0;
}
예제 #17
0
파일: party.cpp 프로젝트: mrktj/tmwa
// 情報所得
int party_recv_info(const PartyPair sp)
{
    int i;

    nullpo_retz(sp);

    PartyPair p = party_search(sp.party_id);
    if (!p)
    {
        p.party_most = party_db.init(sp.party_id);

        // 最初のロードなのでユーザーのチェックを行う
        *p.party_most = *sp.party_most;
        party_check_member(p);
    }
    else
        *p.party_most = *sp.party_most;

    for (i = 0; i < MAX_PARTY; i++)
    {                           // sdの設定
        dumb_ptr<map_session_data> sd = map_id2sd(account_to_block(p->member[i].account_id));
        p->member[i].sd = (sd != nullptr
                           && sd->status.party_id == p.party_id) ? sd.operator->() : nullptr;
    }

    clif_party_info(p, nullptr);

    for (i = 0; i < MAX_PARTY; i++)
    {                           // 設定情報の送信
//      dumb_ptr<map_session_data> sd = map_id2sd(p->member[i].account_id);
        dumb_ptr<map_session_data> sd = dumb_ptr<map_session_data>(p->member[i].sd);
        if (sd != nullptr && sd->party_sended == 0)
        {
            clif_party_option(p, sd, 0x100);
            sd->party_sended = 1;
        }
    }

    return 0;
}
예제 #18
0
파일: party.cpp 프로젝트: mrktj/tmwa
// パーティメンバが脱退した
int party_member_leaved(PartyId party_id, AccountId account_id, CharName name)
{
    dumb_ptr<map_session_data> sd = map_id2sd(account_to_block(account_id));
    PartyPair p = party_search(party_id);
    if (p)
    {
        int i;
        for (i = 0; i < MAX_PARTY; i++)
            if (p->member[i].account_id == account_id)
            {
                clif_party_leaved(p, sd, account_id, name, 0x00);
                p->member[i].account_id = AccountId();
                p->member[i].sd = nullptr;
            }
    }
    if (sd != nullptr && sd->status.party_id == party_id)
    {
        sd->status.party_id = PartyId();
        sd->party_sended = 0;
    }
    return 0;
}
예제 #19
0
파일: chrif.cpp 프로젝트: MadCamel/tmwa
/*==========================================
 * 性別変化終了 (modified by Yor)
 *------------------------------------------
 */
static
void chrif_changedsex(Session *, const Packet_Fixed<0x2b0d>& fixed)
{
    dumb_ptr<map_session_data> sd;

    AccountId acc = fixed.account_id;
    SEX sex = fixed.sex;
    if (battle_config.etc_log)
        PRINTF("chrif_changedsex %d.\n"_fmt, acc);
    sd = map_id2sd(account_to_block(acc));
    if (acc)
    {
        if (sd != nullptr && sd->status.sex != sex)
        {
            sd->sex = sd->status.sex = sex;
            // to avoid any problem with equipment and invalid sex, equipment is unequiped.
            for (IOff0 i : IOff0::iter())
            {
                if (sd->status.inventory[i].nameid
                    && bool(sd->status.inventory[i].equip))
                    pc_unequipitem(sd, i, CalcStatus::LATER);
            }
            pc_calcstatus(sd, 0);
            // save character
            chrif_save(sd);
            sd->login_id1++;    // change identify, because if player come back in char within the 5 seconds, he can change its characters
            // do same modify in login-server for the account, but no in char-server (it ask again login_id1 to login, and don't remember it)
            clif_fixpcpos(sd); // use clif_set0078_main_1d8 to send new sex to the client
        }
    }
    else
    {
        if (sd != nullptr)
        {
            PRINTF("chrif_changedsex failed.\n"_fmt);
        }
    }
}
예제 #20
0
파일: trade.cpp 프로젝트: mrktj/tmwa
/*==========================================
 * 取引許諾(trade押し)
 *------------------------------------------
 */
void trade_tradecommit(dumb_ptr<map_session_data> sd)
{
    dumb_ptr<map_session_data> target_sd;
    int trade_i;

    nullpo_retv(sd);

    if ((target_sd = map_id2sd(account_to_block(sd->trade_partner))) != nullptr)
    {
        MAP_LOG_PC(sd, " TRADECOMMIT WITH %d GIVE %d GET %d"_fmt,
                target_sd->status_key.char_id, sd->deal_zeny,
                target_sd->deal_zeny);
        if ((sd->deal_locked >= 1) && (target_sd->deal_locked >= 1))
        {                       // both have pressed 'ok'
            if (sd->deal_locked < 2)
            {
                sd->deal_locked = 2;
            }                   // set locked to 2
            if (target_sd->deal_locked == 2)
            {                   // the other one pressed 'trade' too
                if (sd->deal_zeny > sd->status.zeny)
                {
                    sd->deal_zeny = 0;
                    trade_tradecancel(sd);
                    MAP_LOG_PC(sd, " TRADECANCEL"_fmt);
                    return;
                }
                if (target_sd->deal_zeny > target_sd->status.zeny)
                {
                    target_sd->deal_zeny = 0;
                    trade_tradecancel(sd);
                    MAP_LOG_PC(sd, " TRADECANCEL"_fmt);
                    return;
                }
                sd->trade_partner = AccountId();
                target_sd->trade_partner = AccountId();
                for (trade_i = 0; trade_i < TRADE_MAX; trade_i++)
                {
                    if (sd->deal_item_amount[trade_i] != 0)
                    {
                        assert (sd->deal_item_index[trade_i].ok());
                        IOff0 n = sd->deal_item_index[trade_i].unshift();
                        PickupFail flag = pc_additem(target_sd,
                                &sd->status.inventory[n],
                                sd->deal_item_amount[trade_i]);
                        if (flag == PickupFail::OKAY)
                            pc_delitem(sd, n, sd->deal_item_amount[trade_i],
                                        1);
                        else
                            clif_additem(sd, n,
                                    sd->deal_item_amount[trade_i],
                                    PickupFail::OKAY);
                        sd->deal_item_index[trade_i] = IOff2::from(0);
                        sd->deal_item_amount[trade_i] = 0;
                    }
                    if (target_sd->deal_item_amount[trade_i] != 0)
                    {
                        assert (target_sd->deal_item_index[trade_i].ok());
                        IOff0 n = target_sd->deal_item_index[trade_i].unshift();
                        PickupFail flag = pc_additem(sd,
                                &target_sd->status.inventory[n],
                                target_sd->deal_item_amount[trade_i]);
                        if (flag == PickupFail::OKAY)
                            pc_delitem(target_sd, n,
                                        target_sd->deal_item_amount[trade_i],
                                        1);
                        else
                            clif_additem(target_sd, n,
                                    target_sd->deal_item_amount[trade_i],
                                    PickupFail::OKAY);
                        target_sd->deal_item_index[trade_i] = IOff2::from(0);
                        target_sd->deal_item_amount[trade_i] = 0;
                    }
                }
                if (sd->deal_zeny)
                {
                    int deal = sd->deal_zeny;
                    sd->deal_zeny = 0;
                    sd->status.zeny -= deal;
                    clif_updatestatus(sd, SP::ZENY);
                    target_sd->status.zeny += deal;
                    clif_updatestatus(target_sd, SP::ZENY);
                }
                if (target_sd->deal_zeny)
                {
                    int deal = target_sd->deal_zeny;
                    target_sd->deal_zeny = 0;
                    target_sd->status.zeny -= deal;
                    clif_updatestatus(target_sd, SP::ZENY);
                    sd->status.zeny += deal;
                    clif_updatestatus(sd, SP::ZENY);
                }
                sd->deal_locked = 0;
                target_sd->deal_locked = 0;
                clif_tradecompleted(sd, 0);
                clif_tradecompleted(target_sd, 0);
                MAP_LOG_PC(sd, " TRADEOK"_fmt);
            }
        }
    }
}
예제 #21
0
파일: chrif.cpp 프로젝트: Rosalila/tswa
/*==========================================
 *
 *------------------------------------------
 */
static
void chrif_parse(Session *s)
{
    assert (s == char_session);

    RecvResult rv = RecvResult::Complete;
    uint16_t packet_id;
    while (rv == RecvResult::Complete && packet_peek_id(s, &packet_id))
    {
        switch (packet_id)
        {
            case 0x2af9:
            {
                Packet_Fixed<0x2af9> fixed;
                rv = recv_fpacket<0x2af9, 3>(s, fixed);
                if (rv != RecvResult::Complete)
                    break;

                chrif_connectack(s, fixed);
                break;
            }
            case 0x2afa:
            {
                Packet_Fixed<0x2afa> fixed;
                rv = recv_fpacket<0x2afa, 10>(s, fixed);
                if (rv != RecvResult::Complete)
                    break;

                ladmin_itemfrob(s, fixed);
                break;
            }
            case 0x2afb:
            {
                Packet_Fixed<0x2afb> fixed;
                rv = recv_fpacket<0x2afb, 27>(s, fixed);
                if (rv != RecvResult::Complete)
                    break;

                chrif_sendmapack(s, fixed);
                break;
            }
            case 0x2afd:
            {
                Packet_Payload<0x2afd> payload;
                rv = recv_ppacket<0x2afd>(s, payload);
                if (rv != RecvResult::Complete)
                    break;

                AccountId id = payload.account_id;
                int login_id2 = payload.login_id2;
                TimeT connect_until_time = payload.connect_until;
                short tmw_version = payload.packet_tmw_version;
                CharKey st_key = payload.char_key;
                CharData st_data = payload.char_data;
                pc_authok(id, login_id2,
                        connect_until_time, tmw_version,
                        &st_key, &st_data);
                break;
            }
            case 0x2afe:
            {
                Packet_Fixed<0x2afe> fixed;
                rv = recv_fpacket<0x2afe, 6>(s, fixed);
                if (rv != RecvResult::Complete)
                    break;

                pc_authfail(fixed.account_id);
                break;
            }
            case 0x2b00:
            {
                Packet_Fixed<0x2b00> fixed;
                rv = recv_fpacket<0x2b00, 6>(s, fixed);
                if (rv != RecvResult::Complete)
                    break;

                map_setusers(fixed.users);
                break;
            }
            case 0x2b03:
            {
                Packet_Fixed<0x2b03> fixed;
                rv = recv_fpacket<0x2b03, 7>(s, fixed);
                if (rv != RecvResult::Complete)
                    break;

                clif_charselectok(account_to_block(fixed.account_id));
                break;
            }
            case 0x2b04:
            {
                Packet_Head<0x2b04> head;
                std::vector<Packet_Repeat<0x2b04>> repeat;
                rv = recv_vpacket<0x2b04, 10, 16>(s, head, repeat);
                if (rv != RecvResult::Complete)
                    break;

                chrif_recvmap(s, head, repeat);
                break;
            }
            case 0x2b06:
            {
                Packet_Fixed<0x2b06> fixed;
                rv = recv_fpacket<0x2b06, 44>(s, fixed);
                if (rv != RecvResult::Complete)
                    break;

                chrif_changemapserverack(s, fixed);
                break;
            }
            case 0x2b0b:
            {
                Packet_Fixed<0x2b0b> fixed;
                rv = recv_fpacket<0x2b0b, 10>(s, fixed);
                if (rv != RecvResult::Complete)
                    break;

                chrif_changedgm(s, fixed);
                break;
            }
            case 0x2b0d:
            {
                Packet_Fixed<0x2b0d> fixed;
                rv = recv_fpacket<0x2b0d, 7>(s, fixed);
                if (rv != RecvResult::Complete)
                    break;

                chrif_changedsex(s, fixed);
                break;
            }
            case 0x2b0f:
            {
                Packet_Fixed<0x2b0f> fixed;
                rv = recv_fpacket<0x2b0f, 34>(s, fixed);
                if (rv != RecvResult::Complete)
                    break;

                chrif_char_ask_name_answer(s, fixed);
                break;
            }
            case 0x2b11:
            {
                Packet_Head<0x2b11> head;
                std::vector<Packet_Repeat<0x2b11>> repeat;
                rv = recv_vpacket<0x2b11, 8, 36>(s, head, repeat);
                if (rv != RecvResult::Complete)
                    break;

                chrif_accountreg2(s, head, repeat);
                break;
            }
            case 0x2b12:
            {
                Packet_Fixed<0x2b12> fixed;
                rv = recv_fpacket<0x2b12, 10>(s, fixed);
                if (rv != RecvResult::Complete)
                    break;

                chrif_divorce(fixed.char_id, fixed.partner_id);
                break;
            }
            case 0x2b13:
            {
                Packet_Fixed<0x2b13> fixed;
                rv = recv_fpacket<0x2b13, 6>(s, fixed);
                if (rv != RecvResult::Complete)
                    break;

                chrif_accountdeletion(s, fixed);
                break;
            }
            case 0x2b14:
            {
                Packet_Fixed<0x2b14> fixed;
                rv = recv_fpacket<0x2b14, 11>(s, fixed);
                if (rv != RecvResult::Complete)
                    break;

                chrif_accountban(s, fixed);
                break;
            }
            case 0x2b15:
            {
                std::vector<Packet_Repeat<0x2b15>> repeat;
                rv = recv_packet_repeatonly<0x2b15, 4, 5>(s, repeat);
                if (rv != RecvResult::Complete)
                    break;

                chrif_recvgmaccounts(s, repeat);
                break;
            }
            default:
            {
                RecvResult r = intif_parse(s, packet_id);

                if (r == RecvResult::Complete)
                    break;
                if (r == RecvResult::Incomplete)
                    return;

                if (battle_config.error_log)
                    PRINTF("chrif_parse : unknown packet %d %d\n"_fmt, s,
                            packet_id);
                s->set_eof();
                return;
            }
        }
    }
    if (rv == RecvResult::Error)
        s->set_eof();
}
예제 #22
0
파일: chrif.cpp 프로젝트: Rosalila/tswa
/*==========================================
 * Answer after a request about a character name to do some operations (by Yor)
 * Used to answer of chrif_char_ask_name.
 * type of operation:
 *   1: block
 *   2: ban
 *   3: unblock
 *   4: unban
 *   5: changesex
 * type of answer:
 *   0: login-server resquest done
 *   1: player not found
 *   2: gm level too low
 *   3: login-server offline
 *------------------------------------------
 */
static
int chrif_char_ask_name_answer(Session *, const Packet_Fixed<0x2b0f>& fixed)
{
    AccountId acc = fixed.account_id;       // who asked, or nobody
    CharName player_name = fixed.char_name;

    dumb_ptr<map_session_data> sd = map_id2sd(account_to_block(acc));
    if (acc && sd != nullptr)
    {
        AString output;
        if (fixed.error == 1)   // player not found
            output = STRPRINTF("The player '%s' doesn't exist."_fmt,
                    player_name);
        else
        {
            switch (fixed.operation)
            {
                case 1:        // block
                    switch (fixed.error)
                    {
                        case 0:    // login-server resquest done
                            output = STRPRINTF(
                                    "Login-server has been asked to block the player '%s'."_fmt,
                                    player_name);
                            break;
                            //case 1: // player not found
                        case 2:    // gm level too low
                            output = STRPRINTF(
                                    "Your GM level don't authorise you to block the player '%s'."_fmt,
                                    player_name);
                            break;
                        case 3:    // login-server offline
                            output = STRPRINTF(
                                    "Login-server is offline. Impossible to block the the player '%s'."_fmt,
                                    player_name);
                            break;
                    }
                    break;
                case 2:        // ban
                    switch (fixed.error)
                    {
                        case 0:    // login-server resquest done
                            output = STRPRINTF(
                                    "Login-server has been asked to ban the player '%s'."_fmt,
                                    player_name);
                            break;
                            //case 1: // player not found
                        case 2:    // gm level too low
                            output = STRPRINTF(
                                    "Your GM level don't authorise you to ban the player '%s'."_fmt,
                                    player_name);
                            break;
                        case 3:    // login-server offline
                            output = STRPRINTF(
                                    "Login-server is offline. Impossible to ban the the player '%s'."_fmt,
                                    player_name);
                            break;
                    }
                    break;
                case 3:        // unblock
                    switch (fixed.error)
                    {
                        case 0:    // login-server resquest done
                            output = STRPRINTF(
                                    "Login-server has been asked to unblock the player '%s'."_fmt,
                                    player_name);
                            break;
                            //case 1: // player not found
                        case 2:    // gm level too low
                            output = STRPRINTF(
                                    "Your GM level don't authorise you to unblock the player '%s'."_fmt,
                                    player_name);
                            break;
                        case 3:    // login-server offline
                            output = STRPRINTF(
                                    "Login-server is offline. Impossible to unblock the the player '%s'."_fmt,
                                    player_name);
                            break;
                    }
                    break;
                case 4:        // unban
                    switch (fixed.error)
                    {
                        case 0:    // login-server resquest done
                            output = STRPRINTF(
                                    "Login-server has been asked to unban the player '%s'."_fmt,
                                    player_name);
                            break;
                            //case 1: // player not found
                        case 2:    // gm level too low
                            output = STRPRINTF(
                                    "Your GM level don't authorise you to unban the player '%s'."_fmt,
                                    player_name);
                            break;
                        case 3:    // login-server offline
                            output = STRPRINTF(
                                    "Login-server is offline. Impossible to unban the the player '%s'."_fmt,
                                    player_name);
                            break;
                    }
                    break;
                case 5:        // changesex
                    switch (fixed.error)
                    {
                        case 0:    // login-server resquest done
                            output = STRPRINTF(
                                    "Login-server has been asked to change the sex of the player '%s'."_fmt,
                                    player_name);
                            break;
                            //case 1: // player not found
                        case 2:    // gm level too low
                            output = STRPRINTF(
                                    "Your GM level don't authorise you to change the sex of the player '%s'."_fmt,
                                    player_name);
                            break;
                        case 3:    // login-server offline
                            output = STRPRINTF(
                                    "Login-server is offline. Impossible to change the sex of the the player '%s'."_fmt,
                                    player_name);
                            break;
                    }
                    break;
            }
        }
        if (output)
            clif_displaymessage(sd->sess, output);
    }
    else
        PRINTF("chrif_char_ask_name_answer failed - player not online.\n"_fmt);

    return 0;
}
예제 #23
0
파일: party.cpp 프로젝트: mrktj/tmwa
/* Process party invitation from sd to account_id. */
int party_invite(dumb_ptr<map_session_data> sd, AccountId account_id)
{
    dumb_ptr<map_session_data> tsd = map_id2sd(account_to_block(account_id));
    PartyPair p = party_search(sd->status.party_id);
    int i;
    int full = 1; /* Indicates whether or not there's room for one more. */

    nullpo_retz(sd);

    if (!tsd || !p || !tsd->sess)
        return 0;

    if (!battle_config.invite_request_check)
    {
        /* Disallow the invitation under these conditions. */
        if (tsd->trade_partner || tsd->npc_id
            || tsd->npc_shopid || pc_checkskill(tsd, SkillID::NV_PARTY) < 1)
        {
            clif_party_inviteack(sd, tsd->status_key.name, 1);
            return 0;
        }
    }

    /* The target player is already in a party, or has a pending invitation. */
    if (tsd->status.party_id || tsd->party_invite)
    {
        clif_party_inviteack(sd, tsd->status_key.name, 0);
        return 0;
    }

    for (i = 0; i < MAX_PARTY; i++)
    {
        /*
         * A character from the target account is already in the same party.
         * The response isn't strictly accurate, as they're separate
         * characters, but we're making do with what was already in place and
         * leaving this (mostly) alone for now.
         */
        if (p->member[i].account_id == account_id)
        {
            clif_party_inviteack(sd, tsd->status_key.name, 1);
            return 0;
        }

        if (!p->member[i].account_id)
            full = 0;
    }

    /* There isn't enough room for a new member. */
    if (full)
    {
        clif_party_inviteack(sd, tsd->status_key.name, 3);
        return 0;
    }

    /* Otherwise, relay the invitation to the target player. */
    tsd->party_invite = sd->status.party_id;
    tsd->party_invite_account = sd->status_key.account_id;

    clif_party_invite(sd, tsd);
    return 0;
}
예제 #24
0
파일: trade.cpp 프로젝트: mrktj/tmwa
/*==========================================
 * アイテム追加
 *------------------------------------------
 */
void trade_tradeadditem(dumb_ptr<map_session_data> sd, IOff2 index, int amount)
{
    dumb_ptr<map_session_data> target_sd;
    struct item_data *id;
    int trade_i;
    int trade_weight = 0;
    int free_ = 0;
    int c;

    nullpo_retv(sd);

    if (((target_sd = map_id2sd(account_to_block(sd->trade_partner))) != nullptr)
        && (sd->deal_locked < 1))
    {
        if (!index.ok())
        {
            if (index.index == 0 && amount > 0 && amount <= sd->status.zeny)
            {
                sd->deal_zeny = amount;
                clif_tradeadditem(sd, target_sd, index, amount);
            }
        }
        // note: amount is overridden below!
        else if (amount <= sd->status.inventory[index.unshift()].amount
                 && amount > 0)
        {
            // determine free slots of receiver
            for (IOff0 i : IOff0::iter())
            {
                if (!target_sd->status.inventory[i].nameid
                    && target_sd->inventory_data[i] == nullptr)
                    free_++;
            }
            for (trade_i = 0; trade_i < TRADE_MAX; trade_i++)
            {
                if (sd->deal_item_amount[trade_i] == 0)
                {
                    // calculate trade weight
                    trade_weight +=
                        sd->inventory_data[index.unshift()]->weight * amount;

                    // determine if item is a stackable already in receivers inventory, and up free count
                    for (IOff0 i : IOff0::iter())
                    {
                        if (target_sd->status.inventory[i].nameid ==
                            sd->status.inventory[index.unshift()].nameid
                            && target_sd->inventory_data[i] != nullptr)
                        {
                            id = target_sd->inventory_data[i];
                            if (id->type != ItemType::WEAPON
                                && id->type != ItemType::ARMOR
                                && id->type != ItemType::_7
                                && id->type != ItemType::_8)
                            {
                                free_++;
                                break;
                            }
                        }
                    }

                    if (target_sd->weight + trade_weight >
                        target_sd->max_weight)
                    {
                        clif_tradeitemok(sd, index, 0, 1); //fail to add item -- the player was over weighted.
                        amount = 0; // [MouseJstr]
                    }
                    else if (free_ <= 0)
                    {
                        clif_tradeitemok(sd, index, 0, 2); //fail to add item -- no free slots at receiver
                        amount = 0; // peavey
                    }
                    else
                    {
                        for (c = 0; c == trade_i - 1; c++)
                        {       // re-deal exploit protection [Valaris]
                            if (sd->deal_item_index[c] == index)
                            {
                                trade_tradecancel(sd);
                                return;
                            }
                        }
                        pc_unequipinvyitem(sd, index.unshift(), CalcStatus::NOW);
                        sd->deal_item_index[trade_i] = index;
                        sd->deal_item_amount[trade_i] += amount;
                        clif_tradeitemok(sd, index, amount, 0);    //success to add item
                        clif_tradeadditem(sd, target_sd, index, amount);
                    }
                    break;
                }
                else
                {
                    // calculate weight for stored deal
                    trade_weight +=
                        sd->inventory_data[sd->deal_item_index[trade_i].unshift()
                                           ]->weight *
                        sd->deal_item_amount[trade_i];
                    // count free stackables in stored deal
                    for (IOff0 i : IOff0::iter())
                    {
                        if (target_sd->status.inventory[i].nameid ==
                            sd->status.
                            inventory[sd->deal_item_index[trade_i].unshift()].nameid
                            && target_sd->inventory_data[i] != nullptr)
                        {
                            id = target_sd->inventory_data[i];
                            if (id->type != ItemType::WEAPON
                                && id->type != ItemType::ARMOR
                                && id->type != ItemType::_7
                                && id->type != ItemType::_8)
                            {
                                free_++;
                                break;
                            }
                        }
                    }
                }
                // used a slot, but might be cancelled out by stackable checks above
                free_--;
            }
        }
    }
}
예제 #25
0
파일: chrif.cpp 프로젝트: Rosalila/tswa
/*==========================================
 * Disconnection of a player (account has been banned of has a status, from login-server) by [Yor]
 *------------------------------------------
 */
static
int chrif_accountban(Session *, const Packet_Fixed<0x2b14>& fixed)
{
    dumb_ptr<map_session_data> sd;

    AccountId acc = fixed.account_id;
    if (battle_config.etc_log)
        PRINTF("chrif_accountban %d.\n"_fmt, acc);
    sd = map_id2sd(account_to_block(acc));
    if (acc)
    {
        if (sd != nullptr)
        {
            sd->login_id1++;    // change identify, because if player come back in char within the 5 seconds, he can change its characters
            if (fixed.ban_not_status == 0)
            {                   // 0: change of statut, 1: ban
                switch (static_cast<time_t>(fixed.status_or_ban_until))
                {               // status or final date of a banishment
                    case 1:    // 0 = Unregistered ID
                        clif_displaymessage(sd->sess,
                                             "Your account has 'Unregistered'."_s);
                        break;
                    case 2:    // 1 = Incorrect Password
                        clif_displaymessage(sd->sess,
                                             "Your account has an 'Incorrect Password'..."_s);
                        break;
                    case 3:    // 2 = This ID is expired
                        clif_displaymessage(sd->sess,
                                             "Your account has expired."_s);
                        break;
                    case 4:    // 3 = Rejected from Server
                        clif_displaymessage(sd->sess,
                                             "Your account has been rejected from server."_s);
                        break;
                    case 5:    // 4 = You have been blocked by the GM Team
                        clif_displaymessage(sd->sess,
                                             "Your account has been blocked by the GM Team."_s);
                        break;
                    case 6:    // 5 = Your Game's EXE file is not the latest version
                        clif_displaymessage(sd->sess,
                                             "Your Game's EXE file is not the latest version."_s);
                        break;
                    case 7:    // 6 = Your are Prohibited to log in until %s
                        clif_displaymessage(sd->sess,
                                             "Your account has been prohibited to log in."_s);
                        break;
                    case 8:    // 7 = Server is jammed due to over populated
                        clif_displaymessage(sd->sess,
                                             "Server is jammed due to over populated."_s);
                        break;
                    case 9:    // 8 = No MSG (actually, all states after 9 except 99 are No MSG, use only this)
                        clif_displaymessage(sd->sess,
                                             "Your account has not more authorised."_s);
                        break;
                    case 100:  // 99 = This ID has been totally erased
                        clif_displaymessage(sd->sess,
                                             "Your account has been totally erased."_s);
                        break;
                    default:
                        clif_displaymessage(sd->sess,
                                             "Your account has not more authorised."_s);
                        break;
                }
            }
            else if (fixed.ban_not_status == 1)
            {
                // 0: change of statut, 1: ban
                const TimeT timestamp = fixed.status_or_ban_until;    // status or final date of a banishment
                timestamp_seconds_buffer buffer;
                stamp_time(buffer, &timestamp);
                AString tmpstr = STRPRINTF("Your account has been banished until %s"_fmt, buffer);
                clif_displaymessage(sd->sess, tmpstr);
            }
            clif_setwaitclose(sd->sess); // forced to disconnect for the change
        }
    }
    else
    {
        if (sd != nullptr)
            PRINTF("chrif_accountban failed - player not online.\n"_fmt);
    }

    return 0;
}