/* 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; }
// パーティが追加された 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; }
// 情報所得失敗(そのIDのキャラを全部未所属にする) int party_recv_noinfo(PartyId party_id) { for (io::FD i : iter_fds()) { Session *s = get_session(i); if (!s) continue; map_session_data *sd = static_cast<map_session_data *>(s->session_data.get()); if (sd && sd->state.auth) { if (sd->status.party_id == party_id) sd->status.party_id = PartyId(); } } return 0; }
// 所属キャラの確認 static int party_check_member(PartyPair p) { nullpo_retz(p); for (io::FD i : iter_fds()) { Session *s = get_session(i); if (!s) continue; map_session_data *sd = static_cast<map_session_data *>(s->session_data.get()); if (sd && sd->state.auth) { if (sd->status.party_id == p.party_id) { int j, f = 1; for (j = 0; j < MAX_PARTY; j++) { // パーティにデータがあるか確認 if (p->member[j].account_id == sd->status_key.account_id) { if (p->member[j].name == sd->status_key.name) f = 0; // データがある else { // I can prove it was already zeroed // p->member[j].sd = nullptr; // 同垢別キャラだった } } } if (f) { sd->status.party_id = PartyId(); if (battle_config.error_log) PRINTF("party: check_member %d[%s] is not member\n"_fmt, sd->status_key.account_id, sd->status_key.name); } } } } return 0; }
// パーティ解散通知 int party_broken(PartyId party_id) { PartyPair p; int i; if (!(p = party_search(party_id))) return 0; for (i = 0; i < MAX_PARTY; i++) { if (p->member[i].sd != nullptr) { clif_party_leaved(p, dumb_ptr<map_session_data>(p->member[i].sd), p->member[i].account_id, p->member[i].name, 0x10); p->member[i].sd->status.party_id = PartyId(); p->member[i].sd->party_sended = 0; } } party_db.erase(party_id); return 0; }
// パーティメンバが脱退した 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; }
// パーティデータのロード void inter_party_init(void) { io::ReadFile in(party_txt); if (!in.is_open()) return; // TODO: convert to use char_id AString line; int c = 0; while (in.getline(line)) { PartyId i; if (extract(line, record<'\t'>(&i, "%newid%"_s)) && party_newid < i) { party_newid = i; continue; } PartyMost pm; PartyPair pp{PartyId(), borrow(pm)}; if (extract(line, &pp) && pp.party_id) { if (party_newid < next(pp.party_id)) party_newid = next(pp.party_id); party_check_deleted_init(pp); party_db.insert(pp.party_id, pm); // note: this is still referring to the noncanonical copy of // the PartyMost pointer. This is okay, though. party_check_empty(pp); } else { PRINTF("int_party: broken data [%s] line %d\n"_fmt, party_txt, c + 1); } c++; } }