From 37de947a3df3c90b27562515f5d3a1e05ad40de5 Mon Sep 17 00:00:00 2001 From: Crystalwarrior Date: Wed, 24 Mar 2021 23:05:09 +0300 Subject: [PATCH 01/20] Mark ui_selector, ui_passworded, ui_taken for evidence and character select as static-only due to massice performance overhead for no substantial benefit --- include/aoimage.h | 4 +++- src/aocharbutton.cpp | 6 +++--- src/aoevidencebutton.cpp | 4 ++-- src/aoimage.cpp | 5 +++-- src/charselect.cpp | 2 +- 5 files changed, 12 insertions(+), 9 deletions(-) diff --git a/include/aoimage.h b/include/aoimage.h index 70ff1fc..b75eee1 100644 --- a/include/aoimage.h +++ b/include/aoimage.h @@ -11,7 +11,7 @@ class AOImage : public QLabel { public: - AOImage(QWidget *parent, AOApplication *p_ao_app); + AOImage(QWidget *parent, AOApplication *p_ao_app, bool make_static = false); ~AOImage(); QWidget *m_parent; @@ -20,6 +20,8 @@ public: QString path; + bool is_static = false; + bool set_image(QString p_image, QString p_misc = ""); void set_size_and_pos(QString identifier); }; diff --git a/src/aocharbutton.cpp b/src/aocharbutton.cpp index 3b384f3..5b48e50 100644 --- a/src/aocharbutton.cpp +++ b/src/aocharbutton.cpp @@ -15,19 +15,19 @@ AOCharButton::AOCharButton(QWidget *parent, AOApplication *p_ao_app, int x_pos, this->resize(60, 60); this->move(x_pos, y_pos); - ui_taken = new AOImage(this, ao_app); + ui_taken = new AOImage(this, ao_app, true); ui_taken->resize(60, 60); ui_taken->set_image("char_taken"); ui_taken->setAttribute(Qt::WA_TransparentForMouseEvents); ui_taken->hide(); - ui_passworded = new AOImage(this, ao_app); + ui_passworded = new AOImage(this, ao_app, true); ui_passworded->resize(60, 60); ui_passworded->set_image("char_passworded"); ui_passworded->setAttribute(Qt::WA_TransparentForMouseEvents); ui_passworded->hide(); - ui_selector = new AOImage(parent, ao_app); + ui_selector = new AOImage(parent, ao_app, true); ui_selector->resize(62, 62); ui_selector->move(x_pos - 1, y_pos - 1); ui_selector->set_image("char_selector"); diff --git a/src/aoevidencebutton.cpp b/src/aoevidencebutton.cpp index aea903a..fee7327 100644 --- a/src/aoevidencebutton.cpp +++ b/src/aoevidencebutton.cpp @@ -9,14 +9,14 @@ AOEvidenceButton::AOEvidenceButton(QWidget *p_parent, AOApplication *p_ao_app, ao_app = p_ao_app; m_parent = p_parent; - ui_selected = new AOImage(this, ao_app); + ui_selected = new AOImage(this, ao_app, true); ui_selected->resize(p_w, p_h); // ui_selected->move(p_x, p_y); ui_selected->set_image("evidence_selected"); ui_selected->setAttribute(Qt::WA_TransparentForMouseEvents); ui_selected->hide(); - ui_selector = new AOImage(this, ao_app); + ui_selector = new AOImage(this, ao_app, true); ui_selector->resize(p_w, p_h); // ui_selector->move(p_x - 1, p_y - 1); ui_selector->set_image("evidence_selector"); diff --git a/src/aoimage.cpp b/src/aoimage.cpp index e1bd8b8..142189c 100644 --- a/src/aoimage.cpp +++ b/src/aoimage.cpp @@ -4,11 +4,12 @@ #include -AOImage::AOImage(QWidget *parent, AOApplication *p_ao_app) : QLabel(parent) +AOImage::AOImage(QWidget *parent, AOApplication *p_ao_app, bool make_static) : QLabel(parent) { m_parent = parent; ao_app = p_ao_app; movie = new QMovie(); + is_static = make_static; connect(movie, &QMovie::frameChanged, [=]{ QPixmap f_pixmap = movie->currentPixmap(); f_pixmap = @@ -23,7 +24,7 @@ AOImage::~AOImage() {} bool AOImage::set_image(QString p_path, QString p_misc) { // Check if the user wants animated themes - if (ao_app->get_animated_theme()) + if (!is_static && ao_app->get_animated_theme()) // We want an animated image p_path = ao_app->get_image(p_path, ao_app->current_theme, ao_app->get_subtheme(), ao_app->default_theme, p_misc); else diff --git a/src/charselect.cpp b/src/charselect.cpp index 510d8c0..d45e875 100644 --- a/src/charselect.cpp +++ b/src/charselect.cpp @@ -21,7 +21,7 @@ void Courtroom::construct_char_select() ui_char_buttons = new QWidget(ui_char_select_background); - ui_selector = new AOImage(ui_char_select_background, ao_app); + ui_selector = new AOImage(ui_char_select_background, ao_app, true); ui_selector->setAttribute(Qt::WA_TransparentForMouseEvents); ui_selector->resize(62, 62); From 48093c3f2b7068f3dd20baa101614a52b855bc04 Mon Sep 17 00:00:00 2001 From: Crystalwarrior Date: Wed, 24 Mar 2021 23:05:46 +0300 Subject: [PATCH 02/20] Remove useless code for extra ui_selector that is not used --- include/courtroom.h | 1 - src/charselect.cpp | 4 ---- src/courtroom.cpp | 3 --- 3 files changed, 8 deletions(-) diff --git a/include/courtroom.h b/include/courtroom.h index 9e0ae58..7e31b73 100644 --- a/include/courtroom.h +++ b/include/courtroom.h @@ -755,7 +755,6 @@ private: QVector ui_char_button_list; QVector ui_char_button_list_filtered; - AOImage *ui_selector; AOButton *ui_back_to_lobby; diff --git a/src/charselect.cpp b/src/charselect.cpp index d45e875..0a2659e 100644 --- a/src/charselect.cpp +++ b/src/charselect.cpp @@ -21,10 +21,6 @@ void Courtroom::construct_char_select() ui_char_buttons = new QWidget(ui_char_select_background); - ui_selector = new AOImage(ui_char_select_background, ao_app, true); - ui_selector->setAttribute(Qt::WA_TransparentForMouseEvents); - ui_selector->resize(62, 62); - ui_back_to_lobby = new AOButton(ui_char_select_background, ao_app); ui_char_password = new QLineEdit(ui_char_select_background); diff --git a/src/courtroom.cpp b/src/courtroom.cpp index 2d63487..507acc1 100644 --- a/src/courtroom.cpp +++ b/src/courtroom.cpp @@ -972,9 +972,6 @@ void Courtroom::set_widgets() set_size_and_pos(ui_sfx_slider, "sfx_slider"); set_size_and_pos(ui_blip_slider, "blip_slider"); - ui_selector->set_image("char_selector"); - ui_selector->hide(); - set_size_and_pos(ui_back_to_lobby, "back_to_lobby"); ui_back_to_lobby->setText(tr("Back to Lobby")); ui_back_to_lobby->setToolTip(tr("Return back to the server list.")); From 132bf9b9d93071b7f4b3bc04d3d29ef50cb1162b Mon Sep 17 00:00:00 2001 From: Crystalwarrior Date: Wed, 7 Apr 2021 02:09:41 +0300 Subject: [PATCH 03/20] Don't generate QMovie() at all if we're told we're a static AOImage --- src/aoimage.cpp | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/src/aoimage.cpp b/src/aoimage.cpp index 142189c..6f1b84f 100644 --- a/src/aoimage.cpp +++ b/src/aoimage.cpp @@ -8,15 +8,18 @@ AOImage::AOImage(QWidget *parent, AOApplication *p_ao_app, bool make_static) : Q { m_parent = parent; ao_app = p_ao_app; - movie = new QMovie(); is_static = make_static; - connect(movie, &QMovie::frameChanged, [=]{ - QPixmap f_pixmap = movie->currentPixmap(); - f_pixmap = - f_pixmap.scaled(this->size(), Qt::IgnoreAspectRatio); - this->setPixmap(f_pixmap); - this->setMask(f_pixmap.mask()); - }); + if (!is_static) // Only create the QMovie if we're non-static + { + movie = new QMovie(); + connect(movie, &QMovie::frameChanged, [=]{ + QPixmap f_pixmap = movie->currentPixmap(); + f_pixmap = + f_pixmap.scaled(this->size(), Qt::IgnoreAspectRatio); + this->setPixmap(f_pixmap); + this->setMask(f_pixmap.mask()); + }); + } } AOImage::~AOImage() {} @@ -36,12 +39,14 @@ bool AOImage::set_image(QString p_path, QString p_misc) return false; } path = p_path; - movie->stop(); - movie->setFileName(path); - if (ao_app->get_animated_theme() && movie->frameCount() > 1) { - movie->start(); + if (!is_static) { + movie->stop(); + movie->setFileName(path); + if (ao_app->get_animated_theme() && movie->frameCount() > 1) { + movie->start(); + } } - else { + if (is_static || !ao_app->get_animated_theme() || movie->frameCount() <= 1) { QPixmap f_pixmap(path); f_pixmap = From 97ea1a6ad419790279d1730bf33b740c66269f73 Mon Sep 17 00:00:00 2001 From: Crystalwarrior Date: Mon, 19 Apr 2021 23:11:17 +0300 Subject: [PATCH 04/20] Fix potential memory leak due to QMovie not being parented to anything --- src/aoimage.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/aoimage.cpp b/src/aoimage.cpp index 6f1b84f..656528e 100644 --- a/src/aoimage.cpp +++ b/src/aoimage.cpp @@ -11,7 +11,7 @@ AOImage::AOImage(QWidget *parent, AOApplication *p_ao_app, bool make_static) : Q is_static = make_static; if (!is_static) // Only create the QMovie if we're non-static { - movie = new QMovie(); + movie = new QMovie(this); connect(movie, &QMovie::frameChanged, [=]{ QPixmap f_pixmap = movie->currentPixmap(); f_pixmap = From 8f0913d30e5ed1cd6a9ee5f7f8b82d68f7630395 Mon Sep 17 00:00:00 2001 From: in1tiate <32779090+in1tiate@users.noreply.github.com> Date: Mon, 19 Apr 2021 15:18:39 -0500 Subject: [PATCH 05/20] euthanize morton (#522) --- src/courtroom.cpp | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/courtroom.cpp b/src/courtroom.cpp index 7ea39df..8ffd2b5 100644 --- a/src/courtroom.cpp +++ b/src/courtroom.cpp @@ -3891,14 +3891,8 @@ void Courtroom::case_called(QString msg, bool def, bool pro, bool jud, bool jur, { if (ui_casing->isChecked()) { ui_server_chatlog->append(msg); - if ((ao_app->get_casing_defence_enabled() && def) || - (ao_app->get_casing_prosecution_enabled() && pro) || - (ao_app->get_casing_judge_enabled() && jud) || - (ao_app->get_casing_juror_enabled() && jur) || - (ao_app->get_casing_steno_enabled() && steno)) { - modcall_player->play(ao_app->get_court_sfx("case_call")); - ao_app->alert(this); - } + modcall_player->play(ao_app->get_court_sfx("case_call")); + ao_app->alert(this); } } From 9a20143e222cab8ddce8d0f8e47421e4805b285e Mon Sep 17 00:00:00 2001 From: Crystalwarrior Date: Tue, 20 Apr 2021 00:24:14 +0300 Subject: [PATCH 06/20] Fix ~~, ~> and <> breaking tick pos --- src/courtroom.cpp | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/src/courtroom.cpp b/src/courtroom.cpp index 8ffd2b5..3950cb6 100644 --- a/src/courtroom.cpp +++ b/src/courtroom.cpp @@ -3361,21 +3361,8 @@ void Courtroom::chat_tick() // Alignment characters if (tick_pos < 2) { - if (f_rest.startsWith("~~")) { - tick_pos = f_rest.indexOf("~~"); - f_rest.remove(tick_pos, 2); + if (f_rest.startsWith("~~") || f_rest.startsWith("~>") || f_rest.startsWith("<>")) tick_pos += 2; - } - else if (f_rest.startsWith("~>")) { - tick_pos = f_rest.indexOf("~>"); - f_rest.remove(tick_pos, 2); - tick_pos += 2; - } - else if (f_rest.startsWith("<>")) { - tick_pos = f_rest.indexOf("<>"); - f_rest.remove(tick_pos, 2); - tick_pos += 2; - } } f_rest.remove(0, tick_pos); QTextBoundaryFinder tbf(QTextBoundaryFinder::Grapheme, f_rest); From e36ac916a96a285e20e0f31308e52b97a595f92a Mon Sep 17 00:00:00 2001 From: Crystalwarrior Date: Tue, 20 Apr 2021 02:36:15 +0300 Subject: [PATCH 07/20] Fix anim_state deciding whether you're allowed to send a message or not (the only thing that should decide that is if text is done processing or not) Fix objections forcing a missingno to appear when you object to someone mid-preanim, and their preanim ends before objection shout finishes. This also resolves a crapton of other bugs related to preanim_done() signal. Move evidence display from handle_ic_speaking to start_chat_ticking (makes more sense over here) Remove a misplaced set_static_duration for ui_vp_player_char (must've got here over a strange merge conflict or smth) Remove useless anim_state and text_state setters in reload_theme func, the func that calls the BG to display already handles everything needed for IC reset --- src/courtroom.cpp | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/courtroom.cpp b/src/courtroom.cpp index 8ffd2b5..9fe8441 100644 --- a/src/courtroom.cpp +++ b/src/courtroom.cpp @@ -1667,7 +1667,7 @@ void Courtroom::on_chat_return_pressed() if (is_muted) return; - if ((anim_state < 3 || text_state < 2) && objection_state == 0) + if (text_state < 2 && objection_state == 0) return; ui_ic_chat_message->blockSignals(true); @@ -2186,8 +2186,6 @@ bool Courtroom::handle_objection() objection_mod = m_chatmessage[OBJECTION_MOD].toInt(); } - - // if an objection is used if (objection_mod <= 4 && objection_mod >= 1) { ui_vp_objection->set_static_duration(shout_static_time); @@ -2523,7 +2521,6 @@ void Courtroom::initialize_chatbox() if (f_charid >= 0 && f_charid < char_list.size() && (m_chatmessage[SHOWNAME].isEmpty() || !ui_showname_enable->isChecked())) { QString real_name = char_list.at(f_charid).name; - ui_vp_player_char->set_static_duration(0); QString f_showname = ao_app->get_showname(real_name); ui_vp_showname->setText(f_showname); @@ -2671,8 +2668,6 @@ void Courtroom::display_evidence_image() void Courtroom::handle_ic_speaking() { - // Display the evidence - display_evidence_image(); QString side = m_chatmessage[SIDE]; int emote_mod = m_chatmessage[EMOTE_MOD].toInt(); // emote_mod 5 is zoom and emote_mod 6 is zoom w/ preanim. @@ -3182,6 +3177,9 @@ void Courtroom::play_preanim(bool immediate) void Courtroom::preanim_done() { + // Currently, someone's talking over us mid-preanim... + if (anim_state != 1 && anim_state != 4) + return; anim_state = 1; switch(m_chatmessage[DESK_MOD].toInt()) { case 4: @@ -3211,6 +3209,9 @@ void Courtroom::start_chat_ticking() if (text_state != 0) return; + // Display the evidence + display_evidence_image(); + if (m_chatmessage[EFFECTS] != "") { QStringList fx_list = m_chatmessage[EFFECTS].split("|"); QString fx = fx_list[0]; @@ -5254,8 +5255,6 @@ void Courtroom::on_reload_theme_clicked() enter_courtroom(); gen_char_rgb_list(ao_app->get_chat(current_char)); - anim_state = 4; - text_state = 3; objection_custom = ""; // to update status on the background From 1edb5d9ae199d7b4512b862e994e4f5b89decb7c Mon Sep 17 00:00:00 2001 From: Crystalwarrior Date: Tue, 20 Apr 2021 02:38:42 +0300 Subject: [PATCH 08/20] Add support for narrator chat (??!!) which does not affect the state of IC in any way, rather the only thing it affects is the IC chat box. INSANELY useful for GMs to play sound effects, talk over the situation, etc. without causing the IC viewport to reset. Stress-tested with preanims, non-interrupting preanims, idle chat, talking chat, evidence presenting --- src/courtroom.cpp | 125 ++++++++++++++++++++++++++-------------------- 1 file changed, 71 insertions(+), 54 deletions(-) diff --git a/src/courtroom.cpp b/src/courtroom.cpp index 9fe8441..2314c99 100644 --- a/src/courtroom.cpp +++ b/src/courtroom.cpp @@ -2231,6 +2231,7 @@ bool Courtroom::handle_objection() sfx_player->clear(); // Objection played! Cut all sfx. return true; } + if (m_chatmessage[EMOTE] != "") display_character(); return false; } @@ -2389,22 +2390,31 @@ void Courtroom::handle_ic_message() // Update the chatbox information initialize_chatbox(); - // Display our own character - display_character(); - - // Reset the pair character - ui_vp_sideplayer_char->stop(); - ui_vp_sideplayer_char->move(0, 0); - - // If the emote_mod is not zooming int emote_mod = m_chatmessage[EMOTE_MOD].toInt(); - if (emote_mod != 5 && emote_mod != 6) { - // Display the pair character - display_pair_character(m_chatmessage[OTHER_CHARID], m_chatmessage[OTHER_OFFSET]); - } + bool immediate = m_chatmessage[IMMEDIATE].toInt() == 1; + if (m_chatmessage[EMOTE] != "") { + // Display our own character + display_character(); - // Parse the emote_mod part of the chat message - handle_emote_mod(m_chatmessage[EMOTE_MOD].toInt(), m_chatmessage[IMMEDIATE].toInt() == 1); + // Reset the pair character + ui_vp_sideplayer_char->stop(); + ui_vp_sideplayer_char->move(0, 0); + + // If the emote_mod is not zooming + if (emote_mod != 5 && emote_mod != 6) { + // Display the pair character + display_pair_character(m_chatmessage[OTHER_CHARID], m_chatmessage[OTHER_OFFSET]); + } + + // Parse the emote_mod part of the chat message + handle_emote_mod(emote_mod, immediate); + } + else + { + start_chat_ticking(); + if (emote_mod == 1 || emote_mod == 2 || emote_mod == 6 || immediate) + play_sfx(); + } // if we have instant objections disabled, and queue is not empty, check if next message after this is an objection. if (!ao_app->is_instant_objection_enabled() && chatmessage_queue.size() > 0) @@ -3300,26 +3310,31 @@ void Courtroom::chat_tick() if (tick_pos >= f_message.size()) { text_state = 2; - if (anim_state < 3) { - QStringList c_paths = { - ao_app->get_image_suffix(ao_app->get_character_path(m_chatmessage[CHAR_NAME], "(c)" + m_chatmessage[EMOTE])), - ao_app->get_image_suffix(ao_app->get_character_path(m_chatmessage[CHAR_NAME], "(c)/" + m_chatmessage[EMOTE])) - }; - // if there is a (c) animation for this emote and we haven't played it already - if (file_exists(ui_vp_player_char->find_image(c_paths)) &&(!c_played)) { - anim_state = 5; - ui_vp_player_char->set_play_once(true); - filename = "(c)" + m_chatmessage[EMOTE]; - c_played = true; + // Check if we're a narrator msg + if (m_chatmessage[EMOTE] != "") { + if (anim_state < 3) { + QStringList c_paths = { + ao_app->get_image_suffix(ao_app->get_character_path(m_chatmessage[CHAR_NAME], "(c)" + m_chatmessage[EMOTE])), + ao_app->get_image_suffix(ao_app->get_character_path(m_chatmessage[CHAR_NAME], "(c)/" + m_chatmessage[EMOTE])) + }; + // if there is a (c) animation for this emote and we haven't played it already + if (file_exists(ui_vp_player_char->find_image(c_paths)) &&(!c_played)) { + anim_state = 5; + ui_vp_player_char->set_play_once(true); + filename = "(c)" + m_chatmessage[EMOTE]; + c_played = true; + } + else { + anim_state = 3; + ui_vp_player_char->set_play_once(false); + filename = "(a)" + m_chatmessage[EMOTE]; + } + ui_vp_player_char->load_image(filename, m_chatmessage[CHAR_NAME], 0, + false); } - else { - anim_state = 3; - ui_vp_player_char->set_play_once(false); - filename = "(a)" + m_chatmessage[EMOTE]; - } - ui_vp_player_char->load_image(filename, m_chatmessage[CHAR_NAME], 0, - false); } + else // We're a narrator msg + anim_state = 3; QString f_char; QString f_custom_theme; if (ao_app->is_customchat_enabled()) { @@ -3520,28 +3535,30 @@ void Courtroom::chat_tick() msg_delay = qMin(max_delay, msg_delay * punctuation_modifier); } - // If this color is talking - if (color_is_talking && anim_state != 2 && - anim_state < - 4) // Set it to talking as we're not on that already (though we have - // to avoid interrupting a non-interrupted preanim) - { - ui_vp_player_char->stop(); - ui_vp_player_char->set_play_once(false); - filename = "(b)" + m_chatmessage[EMOTE]; - ui_vp_player_char->load_image(filename, m_chatmessage[CHAR_NAME], 0, - false); - anim_state = 2; - } - else if (!color_is_talking && anim_state < 3 && - anim_state != 3) // Set it to idle as we're not on that already - { - ui_vp_player_char->stop(); - ui_vp_player_char->set_play_once(false); - filename = "(a)" + m_chatmessage[EMOTE]; - ui_vp_player_char->load_image(filename, m_chatmessage[CHAR_NAME], 0, - false); - anim_state = 3; + if (m_chatmessage[EMOTE] != "") { + // If this color is talking + if (color_is_talking && anim_state != 2 && + anim_state < + 4) // Set it to talking as we're not on that already (though we have + // to avoid interrupting a non-interrupted preanim) + { + ui_vp_player_char->stop(); + ui_vp_player_char->set_play_once(false); + filename = "(b)" + m_chatmessage[EMOTE]; + ui_vp_player_char->load_image(filename, m_chatmessage[CHAR_NAME], 0, + false); + anim_state = 2; + } + else if (!color_is_talking && anim_state < 3 && + anim_state != 3) // Set it to idle as we're not on that already + { + ui_vp_player_char->stop(); + ui_vp_player_char->set_play_once(false); + filename = "(a)" + m_chatmessage[EMOTE]; + ui_vp_player_char->load_image(filename, m_chatmessage[CHAR_NAME], 0, + false); + anim_state = 3; + } } // Continue ticking chat_tick_timer->start(msg_delay); From a1abe8abfa9aaf6ff0fbb7197555d1c97f6b5cdd Mon Sep 17 00:00:00 2001 From: Crystalwarrior Date: Tue, 20 Apr 2021 02:50:42 +0300 Subject: [PATCH 09/20] Fix blankposting when narrating not hiding the chatbox Fix using objections against talking players not causing them to stop talking (with this method, they will only finish their current animation cycle unitl freezing in place) --- src/courtroom.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/courtroom.cpp b/src/courtroom.cpp index 2314c99..a29788a 100644 --- a/src/courtroom.cpp +++ b/src/courtroom.cpp @@ -2229,6 +2229,7 @@ bool Courtroom::handle_objection() filename, m_chatmessage[CHAR_NAME], ao_app->get_chat(m_chatmessage[CHAR_NAME])); sfx_player->clear(); // Objection played! Cut all sfx. + ui_vp_player_char->set_play_once(true); return true; } if (m_chatmessage[EMOTE] != "") @@ -3253,6 +3254,10 @@ void Courtroom::start_chat_ticking() ui_vp_chatbox->show(); ui_vp_message->show(); } + else { + ui_vp_chatbox->hide(); + ui_vp_message->hide(); + } // If we're not already waiting on the next message, start the timer. We could be overriden if there's an objection planned. int delay = ao_app->stay_time(); if (delay > 0 && !text_queue_timer->isActive()) From e517a365d59a46f213e5f053404ecb1904f63ab6 Mon Sep 17 00:00:00 2001 From: in1tiate <32779090+in1tiate@users.noreply.github.com> Date: Mon, 19 Apr 2021 19:27:25 -0500 Subject: [PATCH 10/20] don't set a mask on elements affected by offsets (#524) --- include/aolayer.h | 1 + src/aolayer.cpp | 7 ++++--- src/courtroom.cpp | 2 ++ 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/include/aolayer.h b/include/aolayer.h index 1984b77..f42642c 100644 --- a/include/aolayer.h +++ b/include/aolayer.h @@ -52,6 +52,7 @@ public: bool force_continuous = false; Qt::TransformationMode transform_mode = Qt::FastTransformation; // transformation mode to use for this image bool stretch = false; // Should we stretch/squash this image to fill the screen? + bool masked = true; // Set a mask to the dimensions of the widget? // Set the movie's image to provided paths, preparing for playback. void start_playback(QString p_image); diff --git a/src/aolayer.cpp b/src/aolayer.cpp index 18213ce..e4db75a 100644 --- a/src/aolayer.cpp +++ b/src/aolayer.cpp @@ -98,9 +98,10 @@ void AOLayer::center_pixmap(QPixmap f_pixmap) { x + (f_w - f_pixmap.width()) / 2, y + (f_h - f_pixmap.height())); // Always center horizontally, always put // at the bottom vertically - this->setMask( - QRegion((f_pixmap.width() - f_w) / 2, (f_pixmap.height() - f_h) / 2, f_w, - f_h)); // make sure we don't escape the area we've been given + if (masked) + this->setMask( + QRegion((f_pixmap.width() - f_w) / 2, (f_pixmap.height() - f_h) / 2, f_w, + f_h)); // make sure we don't escape the area we've been given } void AOLayer::combo_resize(int w, int h) diff --git a/src/courtroom.cpp b/src/courtroom.cpp index 8ffd2b5..aafc16d 100644 --- a/src/courtroom.cpp +++ b/src/courtroom.cpp @@ -46,7 +46,9 @@ Courtroom::Courtroom(AOApplication *p_ao_app) : QMainWindow() ui_vp_background = new BackgroundLayer(ui_viewport, ao_app); ui_vp_speedlines = new SplashLayer(ui_viewport, ao_app); ui_vp_player_char = new CharLayer(ui_viewport, ao_app); + ui_vp_player_char->masked = false; ui_vp_sideplayer_char = new CharLayer(ui_viewport, ao_app); + ui_vp_sideplayer_char->masked = false; ui_vp_sideplayer_char->hide(); ui_vp_desk = new BackgroundLayer(ui_viewport, ao_app); From 81c0f9a569eaee58a28ca521b15ab397c03a4890 Mon Sep 17 00:00:00 2001 From: Crystalwarrior Date: Tue, 20 Apr 2021 08:13:56 +0300 Subject: [PATCH 11/20] Better logs with OOC logging, [IC] and [OOC] tags (#519) * Add OOC logging to the .log files, making them infinitely more precious to GMs especially of ambitious multi-area RPs Add [IC] and [OOC] tags to distinguish between the types of msg * minor wording change for .log top line to make it clearer that it's the server address and not the user address Co-authored-by: oldmud0 --- src/courtroom.cpp | 5 +++++ src/packet_distribution.cpp | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/courtroom.cpp b/src/courtroom.cpp index fd0e1ca..9a6fd08 100644 --- a/src/courtroom.cpp +++ b/src/courtroom.cpp @@ -1647,6 +1647,11 @@ void Courtroom::append_server_chatmessage(QString p_name, QString p_message, ui_server_chatlog->append_chatmessage(p_name, p_message, color); + + if (ao_app->get_auto_logging_enabled() && !ao_app->log_filename.isEmpty()) { + QString full = "[OOC][" + QDateTime::currentDateTime().toUTC().toString() + "] " + p_name + ": " + p_message; + ao_app->append_to_file(full, ao_app->log_filename, true); + } } void Courtroom::on_authentication_state_received(int p_state) diff --git a/src/packet_distribution.cpp b/src/packet_distribution.cpp index cf51002..dc76ec1 100644 --- a/src/packet_distribution.cpp +++ b/src/packet_distribution.cpp @@ -308,7 +308,7 @@ void AOApplication::server_packet_received(AOPacket *p_packet) this->log_filename = QDateTime::currentDateTime().toUTC().toString( "'logs/" + server_name.remove(QRegExp("[\\\\/:*?\"<>|\']")) + "/'yyyy-MM-dd hh-mm-ss t'.log'"); - this->write_to_file("Joined server " + server_name + " on address " + + this->write_to_file("Joined server " + server_name + " hosted on address " + server_address + " on " + QDateTime::currentDateTime().toUTC().toString(), log_filename, true); From 7b058d1401ddc1721304516f5cc7cdbdb15fee5d Mon Sep 17 00:00:00 2001 From: Crystalwarrior Date: Wed, 21 Apr 2021 02:14:49 +0300 Subject: [PATCH 12/20] Fix last line in the .demo file not being processed Fix timings for OOC being really busted if max_wait is -1 (dunno at which point this bug was introduced) --- src/demoserver.cpp | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/demoserver.cpp b/src/demoserver.cpp index 764cf22..09741fd 100644 --- a/src/demoserver.cpp +++ b/src/demoserver.cpp @@ -264,22 +264,26 @@ void DemoServer::playback() if (current_packet.startsWith("MS#")) elapsed_time = 0; - while (!current_packet.startsWith("wait") && !demo_data.isEmpty()) { + while (!current_packet.startsWith("wait#")) { client_sock->write(current_packet.toUtf8()); + if (demo_data.isEmpty()) + break; current_packet = demo_data.dequeue(); } if (!demo_data.isEmpty()) { AOPacket wait_packet = AOPacket(current_packet); int duration = wait_packet.get_contents().at(0).toInt(); - if (max_wait != -1 && duration + elapsed_time > max_wait) { - duration = qMax(0, max_wait - elapsed_time); - // Skip the difference on the timers - emit skip_timers(wait_packet.get_contents().at(0).toInt() - duration); - } - else if (timer->interval() != 0 && duration + elapsed_time > timer->interval()) { - duration = qMax(0, timer->interval() - elapsed_time); + if (max_wait != -1) { + if (duration + elapsed_time > max_wait) { + duration = qMax(0, max_wait - elapsed_time); + // Skip the difference on the timers emit skip_timers(wait_packet.get_contents().at(0).toInt() - duration); + } + else if (timer->interval() != 0 && duration + elapsed_time > timer->interval()) { + duration = qMax(0, timer->interval() - elapsed_time); + emit skip_timers(wait_packet.get_contents().at(0).toInt() - duration); + } } elapsed_time += duration; timer->start(duration); From fb4a5e0656cf1ad023b761139f30ecf3a584f56e Mon Sep 17 00:00:00 2001 From: Crystalwarrior Date: Wed, 21 Apr 2021 02:54:08 +0300 Subject: [PATCH 13/20] Fix log_chatmessage referring to the global m_chatmessage instead of the local variables that should be sent to it at the point of the func being called. (#530) --- include/courtroom.h | 2 +- src/courtroom.cpp | 17 +++++++---------- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/include/courtroom.h b/include/courtroom.h index 7e31b73..9da465a 100644 --- a/include/courtroom.h +++ b/include/courtroom.h @@ -235,7 +235,7 @@ public: DISPLAY_AND_IO }; // Log the message contents and information such as evidence presenting etc. into the log file, the IC log, or both. - void log_chatmessage(QString f_message, int f_char_id, QString f_showname = "", int f_color = 0, LogMode f_log_mode=IO_ONLY); + void log_chatmessage(QString f_message, int f_char_id, QString f_showname = "", QString f_char = "", QString f_objection_mod = "", int f_evi_id = 0, int f_color = 0, LogMode f_log_mode=IO_ONLY); // Log the message contents and information such as evidence presenting etc. into the IC logs void handle_callwords(); diff --git a/src/courtroom.cpp b/src/courtroom.cpp index 8a346a2..776c0c9 100644 --- a/src/courtroom.cpp +++ b/src/courtroom.cpp @@ -1984,7 +1984,7 @@ void Courtroom::chatmessage_enqueue(QStringList p_contents) if (SHOWNAME < p_contents.size()) showname = p_contents[SHOWNAME]; - log_chatmessage(p_contents[MESSAGE], f_char_id, showname, p_contents[TEXT_COLOR].toInt(), log_mode); + log_chatmessage(p_contents[MESSAGE], f_char_id, showname, p_contents[CHAR_NAME], p_contents[OBJECTION_MOD], p_contents[EVIDENCE_ID].toInt(), p_contents[TEXT_COLOR].toInt(), log_mode); // Send this boi into the queue chatmessage_queue.enqueue(p_contents); @@ -2018,7 +2018,7 @@ void Courtroom::skip_chatmessage_queue() while (!chatmessage_queue.isEmpty()) { QStringList p_contents = chatmessage_queue.dequeue(); - log_chatmessage(p_contents[MESSAGE], p_contents[CHAR_ID].toInt(), p_contents[SHOWNAME], p_contents[TEXT_COLOR].toInt(), DISPLAY_ONLY); + log_chatmessage(p_contents[MESSAGE], p_contents[CHAR_ID].toInt(), p_contents[SHOWNAME], p_contents[CHAR_NAME], p_contents[OBJECTION_MOD], p_contents[EVIDENCE_ID].toInt(), p_contents[TEXT_COLOR].toInt(), DISPLAY_ONLY); } } @@ -2041,7 +2041,7 @@ void Courtroom::unpack_chatmessage(QStringList p_contents) if (!ao_app->is_desyncrhonized_logs_enabled()) { // We have logs displaying as soon as we reach the message in our queue, which is a less confusing but also less accurate experience for the user. - log_chatmessage(m_chatmessage[MESSAGE], m_chatmessage[CHAR_ID].toInt(), m_chatmessage[SHOWNAME], m_chatmessage[TEXT_COLOR].toInt(), DISPLAY_ONLY); + log_chatmessage(m_chatmessage[MESSAGE], m_chatmessage[CHAR_ID].toInt(), m_chatmessage[SHOWNAME], m_chatmessage[CHAR_NAME], m_chatmessage[OBJECTION_MOD], m_chatmessage[EVIDENCE_ID].toInt(), m_chatmessage[TEXT_COLOR].toInt(), DISPLAY_ONLY); } // Process the callwords for this message @@ -2060,7 +2060,7 @@ void Courtroom::unpack_chatmessage(QStringList p_contents) handle_ic_message(); } -void Courtroom::log_chatmessage(QString f_message, int f_char_id, QString f_showname, int f_color, LogMode f_log_mode) +void Courtroom::log_chatmessage(QString f_message, int f_char_id, QString f_showname, QString f_char, QString f_objection_mod, int f_evi_id, int f_color, LogMode f_log_mode) { // Display name will use the showname QString f_displayname = f_showname; @@ -2081,16 +2081,15 @@ void Courtroom::log_chatmessage(QString f_message, int f_char_id, QString f_show // Check if a custom objection is in use int objection_mod = 0; QString custom_objection = ""; - if (m_chatmessage[OBJECTION_MOD].contains("4&")) { + if (f_objection_mod.contains("4&")) { objection_mod = 4; - custom_objection = m_chatmessage[OBJECTION_MOD].split( + custom_objection = f_objection_mod.split( "4&")[1]; // takes the name of custom objection. } else { - objection_mod = m_chatmessage[OBJECTION_MOD].toInt(); + objection_mod = f_objection_mod.toInt(); } - QString f_char = m_chatmessage[CHAR_NAME]; QString f_custom_theme = ao_app->get_chat(f_char); if (objection_mod <= 4 && objection_mod >= 1) { QString shout_message; @@ -2137,8 +2136,6 @@ void Courtroom::log_chatmessage(QString f_message, int f_char_id, QString f_show } } - // Obtain evidence ID we're trying to work with - int f_evi_id = m_chatmessage[EVIDENCE_ID].toInt(); // If the evidence ID is in the valid range if (f_evi_id > 0 && f_evi_id <= local_evidence_list.size()) { // Obtain the evidence name From d2c0c4fa0dfdef2534fcc0826f8c36bc4568a631 Mon Sep 17 00:00:00 2001 From: Crystalwarrior Date: Thu, 22 Apr 2021 19:02:07 +0300 Subject: [PATCH 14/20] Fix charlayer regression not allowing us to *directly* refer to an emote we want to use with a file path (base/misc/blank for example) Actually use the helper funcs for searching images instead of reimplementing the same thing --- src/aolayer.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/aolayer.cpp b/src/aolayer.cpp index e4db75a..ccf2d63 100644 --- a/src/aolayer.cpp +++ b/src/aolayer.cpp @@ -197,20 +197,20 @@ void CharLayer::load_image(QString p_filename, QString p_charname, << " continuous: " << continuous; #endif QStringList pathlist = { - ao_app->get_image_suffix(ao_app->get_character_path( - p_charname, prefix + current_emote)), // Default path - ao_app->get_image_suffix(ao_app->get_character_path( + current_emote, // The path by itself + ao_app->get_character_path( + p_charname, prefix + current_emote), // Default path + ao_app->get_character_path( p_charname, - prefix + "/" + current_emote)), // Path check if it's categorized + prefix + "/" + current_emote), // Path check if it's categorized // into a folder - ao_app->get_image_suffix(ao_app->get_character_path( + ao_app->get_character_path( p_charname, - current_emote)), // Just use the non-prefixed image, animated or not - ao_app->get_image_suffix( - ao_app->get_theme_path("placeholder")), // Theme placeholder path - ao_app->get_image_suffix(ao_app->get_theme_path( - "placeholder", ao_app->default_theme))}; // Default theme placeholder path - start_playback(find_image(pathlist)); + current_emote), // Just use the non-prefixed image, animated or not + ao_app->get_theme_path("placeholder"), // Theme placeholder path + ao_app->get_theme_path( + "placeholder", ao_app->default_theme)}; // Default theme placeholder path + start_playback(ao_app->get_image_path(pathlist)); } void SplashLayer::load_image(QString p_filename, QString p_charname, From d3e5cb933cd91d5393943ab3385bac0fc233cdc9 Mon Sep 17 00:00:00 2001 From: Crystalwarrior Date: Thu, 22 Apr 2021 19:09:44 +0300 Subject: [PATCH 15/20] Charlayer - only check for direct path after the previous checks fail but before missingno --- src/aolayer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/aolayer.cpp b/src/aolayer.cpp index ccf2d63..795274f 100644 --- a/src/aolayer.cpp +++ b/src/aolayer.cpp @@ -197,7 +197,6 @@ void CharLayer::load_image(QString p_filename, QString p_charname, << " continuous: " << continuous; #endif QStringList pathlist = { - current_emote, // The path by itself ao_app->get_character_path( p_charname, prefix + current_emote), // Default path ao_app->get_character_path( @@ -207,6 +206,7 @@ void CharLayer::load_image(QString p_filename, QString p_charname, ao_app->get_character_path( p_charname, current_emote), // Just use the non-prefixed image, animated or not + current_emote, // The path by itself after the above fail ao_app->get_theme_path("placeholder"), // Theme placeholder path ao_app->get_theme_path( "placeholder", ao_app->default_theme)}; // Default theme placeholder path From 2c259a6337c66eb5900d2c46534c75e9d77586c1 Mon Sep 17 00:00:00 2001 From: Crystalwarrior Date: Thu, 22 Apr 2021 19:11:39 +0300 Subject: [PATCH 16/20] Do the same as previous commit for the get_asset_paths func - only check for the direct file path before missingno --- src/path_functions.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/path_functions.cpp b/src/path_functions.cpp index 5107349..79851c1 100644 --- a/src/path_functions.cpp +++ b/src/path_functions.cpp @@ -105,7 +105,6 @@ QString AOApplication::get_evidence_path(QString p_file) QStringList AOApplication::get_asset_paths(QString p_element, QString p_theme, QString p_subtheme, QString p_default_theme, QString p_misc, QString p_character, QString p_placeholder) { QStringList pathlist; - pathlist += p_element; // The path by itself if (p_character != "") pathlist += get_character_path(p_character, p_element); // Character folder if (p_misc != "" && p_theme != "" && p_subtheme != "") @@ -120,6 +119,7 @@ QStringList AOApplication::get_asset_paths(QString p_element, QString p_theme, Q pathlist += get_theme_path(p_element, p_theme); // Theme path if (p_default_theme != "") pathlist += get_theme_path(p_element, p_default_theme); // Default theme path + pathlist += p_element; // The path by itself if (p_placeholder != "" && p_theme != "") pathlist += get_theme_path(p_placeholder, p_theme); // Placeholder path if (p_placeholder != "" && p_default_theme != "") From 9359ed7f54dd996d879e465c87d5b9631bc6d6bb Mon Sep 17 00:00:00 2001 From: in1tiate Date: Fri, 23 Apr 2021 00:30:50 -0500 Subject: [PATCH 17/20] make sure we save the shownames even when theyre disabled --- src/courtroom.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/courtroom.cpp b/src/courtroom.cpp index 776c0c9..8bbaaa9 100644 --- a/src/courtroom.cpp +++ b/src/courtroom.cpp @@ -2067,11 +2067,6 @@ void Courtroom::log_chatmessage(QString f_message, int f_char_id, QString f_show if (f_char_id != -1) { // Grab the char.ini showname f_showname = ao_app->get_showname(char_list.at(f_char_id).name); - // If custom serversided shownames are not enabled - if (!ui_showname_enable->isChecked()) { - // Set the display name to the char.ini showname - f_displayname = f_showname; - } } // If display name is just whitespace, use the char.ini showname. if (f_displayname.trimmed().isEmpty()) @@ -2171,6 +2166,8 @@ void Courtroom::log_chatmessage(QString f_message, int f_char_id, QString f_show append_ic_text(f_message, f_displayname, "",f_color); break; } + if (!ui_showname_enable->isChecked()) + regenerate_ic_chatlog(); } bool Courtroom::handle_objection() From 9fbe899c0e6ff464d91c2b2171eebb8fb879facb Mon Sep 17 00:00:00 2001 From: Crystalwarrior Date: Fri, 23 Apr 2021 09:55:04 +0300 Subject: [PATCH 18/20] Automatically fix desynced demo files with issues pre-#496 PR (#532) * Implement a demo auto-fixing solution. If the client detects a pre-2.9.1 demo file, it will prompt the user if they wish to correct it, since otherwise the demo will be desynched from reality. The aforementioned issue was fixed in https://github.com/AttorneyOnline/AO2-Client/pull/496 however 2.9.0 still has incorrect demo recording. Fix potential memory leak by not flushing and closing the demo file after opening it for reading. * backup broken demo file before fixing it * comments ahoy Co-authored-by: in1tiate --- include/demoserver.h | 1 + src/demoserver.cpp | 50 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/include/demoserver.h b/include/demoserver.h index 3dc645b..f41084e 100644 --- a/include/demoserver.h +++ b/include/demoserver.h @@ -10,6 +10,7 @@ #include #include #include +#include class DemoServer : public QObject { diff --git a/src/demoserver.cpp b/src/demoserver.cpp index 09741fd..d6927a5 100644 --- a/src/demoserver.cpp +++ b/src/demoserver.cpp @@ -252,6 +252,56 @@ void DemoServer::load_demo(QString filename) demo_data.enqueue(line); line = demo_stream.readLine(); } + demo_file.flush(); + demo_file.close(); + + // No-shenanigans 2.9.0 demo file with the dreaded demo desync bug detected https://github.com/AttorneyOnline/AO2-Client/pull/496 + // If we don't start with the SC packet this means user-edited weirdo shenanigans. Don't screw around with those. + if (demo_data.head().startsWith("SC#") && demo_data.last().startsWith("wait#")) { + qDebug() << "Loaded a broken pre-2.9.1 demo file, with the wait desync issue!"; + QMessageBox *msgBox = new QMessageBox; + msgBox->setAttribute(Qt::WA_DeleteOnClose); + msgBox->setTextFormat(Qt::RichText); + msgBox->setText("This appears to be a broken pre-2.9.1 demo file with the wait desync issue!
Do you want to correct this file? If you refuse, this demo will be desynchronized!"); + msgBox->setWindowTitle("Pre-2.9.1 demo detected!"); + msgBox->setStandardButtons(QMessageBox::NoButton); + QTimer::singleShot(2000, msgBox, std::bind(&QMessageBox::setStandardButtons,msgBox,QMessageBox::Yes|QMessageBox::No)); + int ret = msgBox->exec(); + QQueue p_demo_data; + switch (ret) { + case QMessageBox::Yes: + qDebug() << "Making a backup of the broken demo..."; + QFile::copy(filename, filename + ".backup"); + while (!demo_data.isEmpty()) { + QString current_packet = demo_data.dequeue(); + // TODO: faster way of doing this, maybe with QtConcurrent's MapReduce methods? + if (!current_packet.startsWith("SC#") && current_packet.startsWith("wait#")) { + p_demo_data.insert(qMax(1, p_demo_data.size()-1), current_packet); + continue; + } + p_demo_data.enqueue(current_packet); + } + if (demo_file.open(QIODevice::WriteOnly | QIODevice::Text | + QIODevice::Truncate)) { + QTextStream out(&demo_file); + out.setCodec("UTF-8"); + out << p_demo_data.dequeue(); + for (QString line : p_demo_data) { + out << "\n" << line; + } + demo_file.flush(); + demo_file.close(); + } + load_demo(filename); + break; + case QMessageBox::No: + // No was clicked + break; + default: + // should never be reached + break; + } + } } void DemoServer::playback() From 66f2369af2c4e15ef3eb605f2eefcbc10b576455 Mon Sep 17 00:00:00 2001 From: in1tiate <32779090+in1tiate@users.noreply.github.com> Date: Fri, 23 Apr 2021 02:18:56 -0500 Subject: [PATCH 19/20] Fix Cyrillic characters not being read correctly from QSettings inis (#535) * set ini codecs to utf8 * fix color config reading in Latin1 rather than Utf8 --- src/path_functions.cpp | 1 + src/text_file_functions.cpp | 7 +++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/path_functions.cpp b/src/path_functions.cpp index 79851c1..dbf1cc4 100644 --- a/src/path_functions.cpp +++ b/src/path_functions.cpp @@ -173,6 +173,7 @@ QString AOApplication::get_config_value(QString p_identifier, QString p_config, p = get_case_sensitive_path(p); if (file_exists(p)) { QSettings settings(p, QSettings::IniFormat); + settings.setIniCodec("UTF-8"); QVariant value = settings.value(p_identifier); if (value.type() == QVariant::StringList) { // qDebug() << "got" << p << "is a string list, returning" << value.toStringList().join(","); diff --git a/src/text_file_functions.cpp b/src/text_file_functions.cpp index a671d61..af4c232 100644 --- a/src/text_file_functions.cpp +++ b/src/text_file_functions.cpp @@ -277,6 +277,7 @@ QString AOApplication::read_design_ini(QString p_identifier, QString p_design_path) { QSettings settings(p_design_path, QSettings::IniFormat); + settings.setIniCodec("UTF-8"); QVariant value = settings.value(p_identifier); if (value.type() == QVariant::StringList) { return value.toStringList().join(","); @@ -435,7 +436,7 @@ QString AOApplication::get_chat_markup(QString p_identifier, QString p_chat) // New Chadly method QString value = get_config_value(p_identifier, "chat_config.ini", current_theme, get_subtheme(), default_theme, p_chat); if (!value.isEmpty()) - return value.toLatin1(); + return value.toUtf8(); // Backwards ass compatibility QStringList backwards_paths{get_theme_path("misc/" + p_chat + "/config.ini"), @@ -446,7 +447,7 @@ QString AOApplication::get_chat_markup(QString p_identifier, QString p_chat) for (const QString &p : backwards_paths) { QString value = read_design_ini(p_identifier, p); if (!value.isEmpty()) { - return value.toLatin1(); + return value.toUtf8(); } } @@ -521,6 +522,7 @@ QString AOApplication::read_char_ini(QString p_char, QString p_search_line, QSettings settings(get_character_path(p_char, "char.ini"), QSettings::IniFormat); settings.beginGroup(target_tag); + settings.setIniCodec("UTF-8"); QString value = settings.value(p_search_line).value(); settings.endGroup(); return value; @@ -541,6 +543,7 @@ QStringList AOApplication::read_ini_tags(QString p_path, QString target_tag) { QStringList r_values; QSettings settings(p_path, QSettings::IniFormat); + settings.setIniCodec("UTF-8"); if (!target_tag.isEmpty()) settings.beginGroup(target_tag); QStringList keys = settings.allKeys(); From 5fca08537b6f2c6c581156c4dc07bc9ba61b17ef Mon Sep 17 00:00:00 2001 From: oldmud0 Date: Fri, 23 Apr 2021 07:53:59 -0500 Subject: [PATCH 20/20] Update themes submodule (#539) --- base/themes | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/base/themes b/base/themes index c9acb90..7c036c0 160000 --- a/base/themes +++ b/base/themes @@ -1 +1 @@ -Subproject commit c9acb90137361ea8c29bc4cf2bf530d14b52b23a +Subproject commit 7c036c09ddfadc2680a2c5dbfa188dc98142a427