add ability to disable rare announcements per account; closes #576
This commit is contained in:
+26
-10
@@ -136,6 +136,7 @@ phosg::JSON BBLicense::json() const {
|
||||
Account::Account(const phosg::JSON& json)
|
||||
: account_id(0),
|
||||
flags(0),
|
||||
user_flags(0),
|
||||
ban_end_time(0),
|
||||
ep3_current_meseta(0),
|
||||
ep3_total_meseta_earned(0),
|
||||
@@ -222,6 +223,7 @@ Account::Account(const phosg::JSON& json)
|
||||
}
|
||||
|
||||
this->flags = json.get_int("Flags", 0);
|
||||
this->user_flags = json.get_int("UserFlags", 0);
|
||||
this->ban_end_time = json.get_int("BanEndTime", 0);
|
||||
this->last_player_name = json.get_string("LastPlayerName", "");
|
||||
this->auto_reply_message = json.get_string("AutoReplyMessage", "");
|
||||
@@ -278,6 +280,7 @@ phosg::JSON Account::json() const {
|
||||
{"XBLicenses", std::move(xb_json)},
|
||||
{"BBLicenses", std::move(bb_json)},
|
||||
{"Flags", this->flags},
|
||||
{"UserFlags", this->user_flags},
|
||||
{"BanEndTime", this->ban_end_time},
|
||||
{"LastPlayerName", this->last_player_name},
|
||||
{"AutoReplyMessage", this->auto_reply_message},
|
||||
@@ -300,34 +303,34 @@ void Account::print(FILE* stream) const {
|
||||
} else if (this->flags == static_cast<uint32_t>(Flag::MODERATOR)) {
|
||||
flags_str = "MODERATOR";
|
||||
} else {
|
||||
if (this->flags & static_cast<uint32_t>(Flag::KICK_USER)) {
|
||||
if (this->check_flag(Flag::KICK_USER)) {
|
||||
flags_str += "KICK_USER,";
|
||||
}
|
||||
if (this->flags & static_cast<uint32_t>(Flag::BAN_USER)) {
|
||||
if (this->check_flag(Flag::BAN_USER)) {
|
||||
flags_str += "BAN_USER,";
|
||||
}
|
||||
if (this->flags & static_cast<uint32_t>(Flag::SILENCE_USER)) {
|
||||
if (this->check_flag(Flag::SILENCE_USER)) {
|
||||
flags_str += "SILENCE_USER,";
|
||||
}
|
||||
if (this->flags & static_cast<uint32_t>(Flag::CHANGE_EVENT)) {
|
||||
if (this->check_flag(Flag::CHANGE_EVENT)) {
|
||||
flags_str += "CHANGE_EVENT,";
|
||||
}
|
||||
if (this->flags & static_cast<uint32_t>(Flag::ANNOUNCE)) {
|
||||
if (this->check_flag(Flag::ANNOUNCE)) {
|
||||
flags_str += "ANNOUNCE,";
|
||||
}
|
||||
if (this->flags & static_cast<uint32_t>(Flag::FREE_JOIN_GAMES)) {
|
||||
if (this->check_flag(Flag::FREE_JOIN_GAMES)) {
|
||||
flags_str += "FREE_JOIN_GAMES,";
|
||||
}
|
||||
if (this->flags & static_cast<uint32_t>(Flag::DEBUG)) {
|
||||
if (this->check_flag(Flag::DEBUG)) {
|
||||
flags_str += "DEBUG,";
|
||||
}
|
||||
if (this->flags & static_cast<uint32_t>(Flag::CHEAT_ANYWHERE)) {
|
||||
if (this->check_flag(Flag::CHEAT_ANYWHERE)) {
|
||||
flags_str += "CHEAT_ANYWHERE,";
|
||||
}
|
||||
if (this->flags & static_cast<uint32_t>(Flag::DISABLE_QUEST_REQUIREMENTS)) {
|
||||
if (this->check_flag(Flag::DISABLE_QUEST_REQUIREMENTS)) {
|
||||
flags_str += "ALWAYS_ENABLE_CHAT_COMMANDS,";
|
||||
}
|
||||
if (this->flags & static_cast<uint32_t>(Flag::IS_SHARED_ACCOUNT)) {
|
||||
if (this->check_flag(Flag::IS_SHARED_ACCOUNT)) {
|
||||
flags_str += "IS_SHARED_ACCOUNT,";
|
||||
}
|
||||
}
|
||||
@@ -339,6 +342,19 @@ void Account::print(FILE* stream) const {
|
||||
fprintf(stream, " Flags: %08" PRIX32 " (%s)\n", this->flags, flags_str.c_str());
|
||||
}
|
||||
|
||||
if (this->user_flags) {
|
||||
string user_flags_str = "";
|
||||
if (this->check_user_flag(UserFlag::DISABLE_DROP_NOTIFICATION_BROADCAST)) {
|
||||
user_flags_str += "DISABLE_DROP_NOTIFICATION_BROADCAST,";
|
||||
}
|
||||
if (user_flags_str.empty()) {
|
||||
user_flags_str = "none";
|
||||
} else if (phosg::ends_with(user_flags_str, ",")) {
|
||||
user_flags_str.pop_back();
|
||||
}
|
||||
fprintf(stream, " User flags: %08" PRIX32 " (%s)\n", this->user_flags, user_flags_str.c_str());
|
||||
}
|
||||
|
||||
if (this->ban_end_time) {
|
||||
string time_str = phosg::format_time(this->ban_end_time);
|
||||
fprintf(stream, " Banned until: %" PRIu64 " (%s)\n", this->ban_end_time, time_str.c_str());
|
||||
|
||||
@@ -76,11 +76,15 @@ struct Account {
|
||||
UNUSED_BITS = 0x70FFFF00,
|
||||
// clang-format on
|
||||
};
|
||||
enum class UserFlag : uint32_t {
|
||||
DISABLE_DROP_NOTIFICATION_BROADCAST = 0x00000001,
|
||||
};
|
||||
|
||||
// account_id is also the account's guild card number
|
||||
uint32_t account_id = 0;
|
||||
|
||||
uint32_t flags = 0;
|
||||
uint32_t user_flags = 0;
|
||||
uint64_t ban_end_time = 0; // 0 = not banned
|
||||
std::string last_player_name;
|
||||
std::string auto_reply_message;
|
||||
@@ -124,6 +128,19 @@ struct Account {
|
||||
this->flags = static_cast<uint32_t>(mask);
|
||||
}
|
||||
|
||||
[[nodiscard]] inline bool check_user_flag(UserFlag flag) const {
|
||||
return !!(this->user_flags & static_cast<uint32_t>(flag));
|
||||
}
|
||||
inline void set_user_flag(UserFlag flag) {
|
||||
this->user_flags |= static_cast<uint32_t>(flag);
|
||||
}
|
||||
inline void clear_user_flag(UserFlag flag) {
|
||||
this->user_flags &= (~static_cast<uint32_t>(flag));
|
||||
}
|
||||
inline void toggle_user_flag(UserFlag flag) {
|
||||
this->user_flags ^= static_cast<uint32_t>(flag);
|
||||
}
|
||||
|
||||
void print(FILE* stream) const;
|
||||
};
|
||||
|
||||
|
||||
@@ -2088,6 +2088,13 @@ static void proxy_command_switch_assist(shared_ptr<ProxyServer::LinkedSession> s
|
||||
ses->config.check_flag(Client::Flag::SWITCH_ASSIST_ENABLED) ? "enabled" : "disabled");
|
||||
}
|
||||
|
||||
static void server_command_toggle_rare_announce(shared_ptr<Client> c, const std::string&) {
|
||||
c->login->account->toggle_user_flag(Account::UserFlag::DISABLE_DROP_NOTIFICATION_BROADCAST);
|
||||
c->login->account->save();
|
||||
send_text_message_printf(c, "$C6Rare announcements\n%s for your\nitems",
|
||||
c->login->account->check_user_flag(Account::UserFlag::DISABLE_DROP_NOTIFICATION_BROADCAST) ? "disabled" : "enabled");
|
||||
}
|
||||
|
||||
static void server_command_dropmode(shared_ptr<Client> c, const std::string& args) {
|
||||
auto l = c->require_lobby();
|
||||
check_is_game(l, true);
|
||||
@@ -2580,6 +2587,7 @@ static const unordered_map<string, ChatCommandDefinition> chat_commands({
|
||||
{"$allevent", {server_command_lobby_event_all, nullptr}},
|
||||
{"$ann", {server_command_announce, nullptr}},
|
||||
{"$ann!", {server_command_announce_mail, nullptr}},
|
||||
{"$announcerares", {server_command_toggle_rare_announce, nullptr}},
|
||||
{"$arrow", {server_command_arrow, proxy_command_arrow}},
|
||||
{"$auction", {server_command_auction, proxy_command_auction}},
|
||||
{"$ax", {server_command_ax, nullptr}},
|
||||
|
||||
@@ -2071,7 +2071,8 @@ static void on_pick_up_item_generic(
|
||||
}
|
||||
}
|
||||
|
||||
if (fi->flags & 0x1000) {
|
||||
if (!c->login->account->check_user_flag(Account::UserFlag::DISABLE_DROP_NOTIFICATION_BROADCAST) &&
|
||||
(fi->flags & 0x1000)) {
|
||||
uint32_t pi = fi->data.primary_identifier();
|
||||
bool should_send_game_notif, should_send_global_notif;
|
||||
if (is_v1_or_v2(c->version()) && (c->version() != Version::GC_NTE)) {
|
||||
|
||||
+36
-1
@@ -362,11 +362,37 @@ uint32_t parse_account_flags(const string& flags_str) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint32_t parse_account_user_flags(const string& user_flags_str) {
|
||||
try {
|
||||
size_t end_pos = 0;
|
||||
uint32_t ret = stoul(user_flags_str, &end_pos, 16);
|
||||
if (end_pos == user_flags_str.size()) {
|
||||
return ret;
|
||||
}
|
||||
} catch (const exception&) {
|
||||
}
|
||||
|
||||
uint32_t ret = 0;
|
||||
auto tokens = phosg::split(user_flags_str, ',');
|
||||
for (const auto& token : tokens) {
|
||||
string token_upper = phosg::toupper(token);
|
||||
if (token_upper == "NONE") {
|
||||
// Nothing to do
|
||||
} else if (token_upper == "DISABLE_DROP_NOTIFICATION_BROADCAST") {
|
||||
ret |= static_cast<uint32_t>(Account::UserFlag::DISABLE_DROP_NOTIFICATION_BROADCAST);
|
||||
} else {
|
||||
throw runtime_error("invalid user flag name: " + token_upper);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
CommandDefinition c_add_account(
|
||||
"add-account", "add-account [PARAMETERS...]\n\
|
||||
Add an account to the server. <parameters> is some subset of:\n\
|
||||
id=ACCOUNT-ID: preferred account ID in hex (optional)\n\
|
||||
flags=FLAGS: behaviors and permissions for the account (see below)\n\
|
||||
user-flags=FLAGS: user-set behaviors for the account\n\
|
||||
ep3-current-meseta=MESETA: Episode 3 Meseta value\n\
|
||||
ep3-total-meseta=MESETA: Episode 3 total Meseta ever earned\n\
|
||||
temporary: marks the account as temporary; it is not saved to disk and\n\
|
||||
@@ -405,6 +431,8 @@ CommandDefinition c_add_account(
|
||||
account->is_temporary = true;
|
||||
} else if (phosg::starts_with(token, "flags=")) {
|
||||
account->flags = parse_account_flags(token.substr(6));
|
||||
} else if (phosg::starts_with(token, "user-flags=")) {
|
||||
account->user_flags = parse_account_user_flags(token.substr(11));
|
||||
} else {
|
||||
throw invalid_argument("invalid account field: " + token);
|
||||
}
|
||||
@@ -418,7 +446,8 @@ CommandDefinition c_update_account(
|
||||
Update an existing license. ACCOUNT-ID (8 hex digits) specifies which\n\
|
||||
account to update. The options are similar to the add-account command:\n\
|
||||
flags=FLAGS: sets behaviors and permissions for the account (same as\n\
|
||||
with add-account)\n\
|
||||
add-account)\n\
|
||||
user-flags=FLAGS: sets behaviors for the account (same as add-account)\n\
|
||||
ban-duration=DURATION: bans this account for the specified duration; the\n\
|
||||
duration should be of the form 3d, 2w, 1mo, or 1y\n\
|
||||
unban: clears any existing ban from this account\n\
|
||||
@@ -441,6 +470,7 @@ CommandDefinition c_update_account(
|
||||
int64_t new_ep3_current_meseta = -1;
|
||||
int64_t new_ep3_total_meseta = -1;
|
||||
int64_t new_flags = -1;
|
||||
int64_t new_user_flags = -1;
|
||||
uint8_t new_is_temporary = 0xFF;
|
||||
int64_t new_ban_duration = -1;
|
||||
for (const string& token : tokens) {
|
||||
@@ -454,6 +484,8 @@ CommandDefinition c_update_account(
|
||||
new_is_temporary = 0;
|
||||
} else if (phosg::starts_with(token, "flags=")) {
|
||||
new_flags = parse_account_flags(token.substr(6));
|
||||
} else if (phosg::starts_with(token, "user-flags=")) {
|
||||
new_user_flags = parse_account_user_flags(token.substr(11));
|
||||
} else if (token == "unban") {
|
||||
new_ban_duration = 0;
|
||||
} else if (phosg::starts_with(token, "ban-duration=")) {
|
||||
@@ -492,6 +524,9 @@ CommandDefinition c_update_account(
|
||||
if (new_flags >= 0) {
|
||||
account->flags = new_flags;
|
||||
}
|
||||
if (new_user_flags >= 0) {
|
||||
account->user_flags = new_user_flags;
|
||||
}
|
||||
if (new_is_temporary != 0xFF) {
|
||||
account->is_temporary = new_is_temporary;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user