Use autoincremented IDs for local backgrounds.

This commit is contained in:
levlam 2021-06-10 03:57:34 +03:00
parent a04a481fd4
commit aba5b1ab7c
5 changed files with 74 additions and 59 deletions

View File

@ -268,6 +268,7 @@ void BackgroundManager::Background::store(StorerT &storer) const {
STORE_FLAG(is_default);
STORE_FLAG(is_dark);
STORE_FLAG(has_file_id);
STORE_FLAG(has_new_local_id);
END_STORE_FLAGS();
td::store(id, storer);
td::store(access_hash, storer);
@ -286,6 +287,7 @@ void BackgroundManager::Background::parse(ParserT &parser) {
PARSE_FLAG(is_default);
PARSE_FLAG(is_dark);
PARSE_FLAG(has_file_id);
PARSE_FLAG(has_new_local_id);
END_PARSE_FLAGS();
td::parse(id, parser);
td::parse(access_hash, parser);
@ -317,23 +319,52 @@ class BackgroundManager::BackgroundLogEvent {
};
void BackgroundManager::start_up() {
max_local_background_id_ = BackgroundId(to_integer<int64>(G()->td_db()->get_binlog_pmc()->get("max_bg_id")));
// first parse all log events and fix max_local_background_id_ value
bool has_selected_background[2] = {false, false};
BackgroundLogEvent selected_background_log_event[2];
for (int i = 0; i < 2; i++) {
bool for_dark_theme = i != 0;
auto log_event_string = G()->td_db()->get_binlog_pmc()->get(get_background_database_key(for_dark_theme));
if (!log_event_string.empty()) {
BackgroundLogEvent log_event;
log_event_parse(log_event, log_event_string).ensure();
CHECK(log_event.background_.id.is_valid());
if (log_event.background_.file_id.is_valid() != log_event.background_.type.has_file()) {
LOG(ERROR) << "Failed to load " << log_event.background_.id << " of " << log_event.background_.type;
G()->td_db()->get_binlog_pmc()->erase(get_background_database_key(for_dark_theme));
continue;
has_selected_background[i] = true;
log_event_parse(selected_background_log_event[i], log_event_string).ensure();
const Background &background = selected_background_log_event[i].background_;
if (background.has_new_local_id && background.id.is_local() && !background.type.has_file() &&
background.id.get() > max_local_background_id_.get()) {
set_max_local_background_id(background.id);
}
set_background_id_[for_dark_theme] = log_event.background_.id;
set_background_type_[for_dark_theme] = log_event.set_type_;
}
}
add_background(log_event.background_);
// then add backgrounds fixing their ID
for (int i = 0; i < 2; i++) {
bool for_dark_theme = i != 0;
if (has_selected_background[i]) {
Background &background = selected_background_log_event[i].background_;
bool need_resave = false;
if (!background.has_new_local_id && !background.type.has_file()) {
background.has_new_local_id = true;
background.id = get_next_local_background_id();
need_resave = true;
}
CHECK(background.id.is_valid());
if (background.file_id.is_valid() != background.type.has_file()) {
LOG(ERROR) << "Failed to load " << background.id << " of " << background.type;
need_resave = true;
} else {
set_background_id_[for_dark_theme] = background.id;
set_background_type_[for_dark_theme] = selected_background_log_event[i].set_type_;
add_background(background);
}
if (need_resave) {
save_background_id(for_dark_theme);
}
}
send_update_selected_background(for_dark_theme);
@ -506,15 +537,25 @@ Result<FileId> BackgroundManager::prepare_input_file(const tl_object_ptr<td_api:
return std::move(file_id);
}
void BackgroundManager::set_max_local_background_id(BackgroundId background_id) {
CHECK(background_id.is_local());
CHECK(background_id.get() > max_local_background_id_.get());
max_local_background_id_ = background_id;
G()->td_db()->get_binlog_pmc()->set("max_bg_id", to_string(max_local_background_id_.get()));
}
BackgroundId BackgroundManager::get_next_local_background_id() {
set_max_local_background_id(BackgroundId(max_local_background_id_.get() + 1));
return max_local_background_id_;
}
BackgroundId BackgroundManager::add_fill_background(const BackgroundFill &fill) {
return add_fill_background(fill, false, fill.is_dark());
}
BackgroundId BackgroundManager::add_fill_background(const BackgroundFill &fill, bool is_default, bool is_dark) {
BackgroundId background_id(fill.get_id());
Background background;
background.id = background_id;
background.id = get_next_local_background_id();
background.is_creator = true;
background.is_default = is_default;
background.is_dark = is_dark;
@ -522,7 +563,7 @@ BackgroundId BackgroundManager::add_fill_background(const BackgroundFill &fill,
background.name = background.type.get_link();
add_background(background);
return background_id;
return background.id;
}
BackgroundId BackgroundManager::set_background(const td_api::InputBackground *input_background,
@ -933,7 +974,7 @@ BackgroundId BackgroundManager::on_get_background(BackgroundId expected_backgrou
}
auto background_id = BackgroundId(wallpaper->id_);
if (!background_id.is_valid() || BackgroundFill::is_valid_id(wallpaper->id_)) {
if (!background_id.is_valid() || background_id.is_local()) {
LOG(ERROR) << "Receive " << to_string(wallpaper);
return BackgroundId();
}
@ -952,17 +993,13 @@ BackgroundId BackgroundManager::on_get_background(BackgroundId expected_backgrou
auto wallpaper = move_tl_object_as<telegram_api::wallPaper>(wallpaper_ptr);
auto background_id = BackgroundId(wallpaper->id_);
if (!background_id.is_valid()) {
if (!background_id.is_valid() || background_id.is_local() || is_background_name_local(wallpaper->slug_)) {
LOG(ERROR) << "Receive " << to_string(wallpaper);
return BackgroundId();
}
if (expected_background_id.is_valid() && background_id != expected_background_id) {
LOG(ERROR) << "Expected " << expected_background_id << ", but receive " << to_string(wallpaper);
}
if (is_background_name_local(wallpaper->slug_) || BackgroundFill::is_valid_id(wallpaper->id_)) {
LOG(ERROR) << "Receive " << to_string(wallpaper);
return BackgroundId();
}
int32 document_id = wallpaper->document_->get_id();
if (document_id == telegram_api::documentEmpty::ID) {

View File

@ -75,6 +75,7 @@ class BackgroundManager : public Actor {
bool is_creator = false;
bool is_default = false;
bool is_dark = false;
bool has_new_local_id = true;
BackgroundType type;
FileSourceId file_source_id;
@ -105,6 +106,10 @@ class BackgroundManager : public Actor {
void send_update_selected_background(bool for_dark_theme) const;
void set_max_local_background_id(BackgroundId background_id);
BackgroundId get_next_local_background_id();
BackgroundId add_fill_background(const BackgroundFill &fill);
BackgroundId add_fill_background(const BackgroundFill &fill, bool is_default, bool is_dark);
@ -172,6 +177,8 @@ class BackgroundManager : public Actor {
};
std::unordered_map<FileId, UploadedFileInfo, FileIdHash> being_uploaded_files_;
BackgroundId max_local_background_id_;
Td *td_;
ActorShared<> parent_;
};

View File

@ -207,32 +207,6 @@ static bool is_valid_intensity(int32 intensity) {
return -100 <= intensity && intensity <= 100;
}
int64 BackgroundFill::get_id() const {
CHECK(is_valid_color(top_color_));
CHECK(is_valid_color(bottom_color_));
switch (get_type()) {
case Type::Solid:
return static_cast<int64>(top_color_) + 1;
case Type::Gradient:
CHECK(is_valid_rotation_angle(rotation_angle_));
return (rotation_angle_ / 45) * 0x1000001000001 + (static_cast<int64>(top_color_) << 24) + bottom_color_ +
(1 << 24) + 1;
case Type::FreeformGradient: {
CHECK(is_valid_color(third_color_));
CHECK(fourth_color_ == -1 || is_valid_color(fourth_color_));
const uint64 mul = 123456789;
uint64 result = static_cast<uint64>(top_color_);
result = result * mul + static_cast<uint64>(bottom_color_);
result = result * mul + static_cast<uint64>(third_color_);
result = result * mul + static_cast<uint64>(fourth_color_);
return static_cast<int64>(result % 0x8000008000008);
}
default:
UNREACHABLE();
return 0;
}
}
bool BackgroundFill::is_dark() const {
switch (get_type()) {
case Type::Solid:
@ -248,10 +222,6 @@ bool BackgroundFill::is_dark() const {
}
}
bool BackgroundFill::is_valid_id(int64 id) {
return 0 < id && id < 0x8000008000008;
}
bool operator==(const BackgroundFill &lhs, const BackgroundFill &rhs) {
return lhs.top_color_ == rhs.top_color_ && lhs.bottom_color_ == rhs.bottom_color_ &&
lhs.rotation_angle_ == rhs.rotation_angle_ && lhs.third_color_ == rhs.third_color_ &&

View File

@ -59,11 +59,7 @@ class BackgroundFill {
public:
static Result<BackgroundFill> get_background_fill(Slice name);
int64 get_id() const;
bool is_dark() const;
static bool is_valid_id(int64 id);
};
bool operator==(const BackgroundFill &lhs, const BackgroundFill &rhs);

View File

@ -2251,8 +2251,9 @@ class CliClient final : public Actor {
td_api::make_object<td_api::inputBackgroundLocal>(as_input_file(args)),
get_gradient_pattern_background(0xABCDEF, 0xFE, 51, false), op == "sbggpd"));
} else if (op == "sbgs" || op == "sbgsd") {
send_request(td_api::make_object<td_api::setBackground>(nullptr, get_solid_background(to_integer<int32>(args)),
op == "sbgsd"));
int32 color;
get_args(args, color);
send_request(td_api::make_object<td_api::setBackground>(nullptr, get_solid_background(color), op == "sbgsd"));
} else if (op == "sbgg" || op == "sbggd") {
int32 top_color;
int32 bottom_color;
@ -2268,12 +2269,16 @@ class CliClient final : public Actor {
send_request(td_api::make_object<td_api::setBackground>(
td_api::make_object<td_api::inputBackgroundRemote>(background_id), nullptr, op == "sbgfidd"));
} else if (op == "sbgwid" || op == "sbgwidd") {
int64 background_id;
get_args(args, background_id);
send_request(td_api::make_object<td_api::setBackground>(
td_api::make_object<td_api::inputBackgroundRemote>(to_integer<int64>(args)),
td_api::make_object<td_api::inputBackgroundRemote>(background_id),
td_api::make_object<td_api::backgroundTypeWallpaper>(true, true), op == "sbgwidd"));
} else if (op == "sbgpid" || op == "sbgpidd") {
int64 background_id;
get_args(args, background_id);
send_request(td_api::make_object<td_api::setBackground>(
td_api::make_object<td_api::inputBackgroundRemote>(to_integer<int64>(args)),
td_api::make_object<td_api::inputBackgroundRemote>(background_id),
get_solid_pattern_background(0xabcdef, 49, true), op == "sbgpidd"));
} else if (op == "rbg") {
send_request(td_api::make_object<td_api::removeBackground>(to_integer<int64>(args)));