From 37de947a3df3c90b27562515f5d3a1e05ad40de5 Mon Sep 17 00:00:00 2001 From: Crystalwarrior Date: Wed, 24 Mar 2021 23:05:09 +0300 Subject: Mark ui_selector, ui_passworded, ui_taken for evidence and character select as static-only due to massice performance overhead for no substantial benefit --- src/aocharbutton.cpp | 6 +++--- src/aoevidencebutton.cpp | 4 ++-- src/aoimage.cpp | 5 +++-- src/charselect.cpp | 2 +- 4 files changed, 9 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/aocharbutton.cpp b/src/aocharbutton.cpp index 3b384f35..5b48e50a 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 aea903ad..fee7327a 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 e1bd8b8c..142189c2 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 510d8c0a..d45e8759 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); -- cgit From 48093c3f2b7068f3dd20baa101614a52b855bc04 Mon Sep 17 00:00:00 2001 From: Crystalwarrior Date: Wed, 24 Mar 2021 23:05:46 +0300 Subject: Remove useless code for extra ui_selector that is not used --- src/charselect.cpp | 4 ---- src/courtroom.cpp | 3 --- 2 files changed, 7 deletions(-) (limited to 'src') diff --git a/src/charselect.cpp b/src/charselect.cpp index d45e8759..0a2659e8 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 2d634879..507acc13 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.")); -- cgit From 132bf9b9d93071b7f4b3bc04d3d29ef50cb1162b Mon Sep 17 00:00:00 2001 From: Crystalwarrior Date: Wed, 7 Apr 2021 02:09:41 +0300 Subject: 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(-) (limited to 'src') diff --git a/src/aoimage.cpp b/src/aoimage.cpp index 142189c2..6f1b84f6 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 = -- cgit From 97ea1a6ad419790279d1730bf33b740c66269f73 Mon Sep 17 00:00:00 2001 From: Crystalwarrior Date: Mon, 19 Apr 2021 23:11:17 +0300 Subject: Fix potential memory leak due to QMovie not being parented to anything --- src/aoimage.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/aoimage.cpp b/src/aoimage.cpp index 6f1b84f6..656528e3 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 = -- cgit 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: euthanize morton (#522) --- src/courtroom.cpp | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/courtroom.cpp b/src/courtroom.cpp index 7ea39df6..8ffd2b5c 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); } } -- cgit From 9a20143e222cab8ddce8d0f8e47421e4805b285e Mon Sep 17 00:00:00 2001 From: Crystalwarrior Date: Tue, 20 Apr 2021 00:24:14 +0300 Subject: Fix ~~, ~> and <> breaking tick pos --- src/courtroom.cpp | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) (limited to 'src') diff --git a/src/courtroom.cpp b/src/courtroom.cpp index 8ffd2b5c..3950cb6e 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); -- cgit From e36ac916a96a285e20e0f31308e52b97a595f92a Mon Sep 17 00:00:00 2001 From: Crystalwarrior Date: Tue, 20 Apr 2021 02:36:15 +0300 Subject: 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(-) (limited to 'src') diff --git a/src/courtroom.cpp b/src/courtroom.cpp index 8ffd2b5c..9fe84416 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 -- cgit From 1edb5d9ae199d7b4512b862e994e4f5b89decb7c Mon Sep 17 00:00:00 2001 From: Crystalwarrior Date: Tue, 20 Apr 2021 02:38:42 +0300 Subject: 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 | 123 +++++++++++++++++++++++++++++++----------------------- 1 file changed, 70 insertions(+), 53 deletions(-) (limited to 'src') diff --git a/src/courtroom.cpp b/src/courtroom.cpp index 9fe84416..2314c995 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(); + int emote_mod = m_chatmessage[EMOTE_MOD].toInt(); + bool immediate = m_chatmessage[IMMEDIATE].toInt() == 1; + if (m_chatmessage[EMOTE] != "") { + // Display our own character + display_character(); - // Reset the pair character - ui_vp_sideplayer_char->stop(); - ui_vp_sideplayer_char->move(0, 0); + // 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]); - } + // 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(m_chatmessage[EMOTE_MOD].toInt(), m_chatmessage[IMMEDIATE].toInt() == 1); + // 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; - } - else { - anim_state = 3; - ui_vp_player_char->set_play_once(false); - filename = "(a)" + m_chatmessage[EMOTE]; + // 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); } - 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); -- cgit From a1abe8abfa9aaf6ff0fbb7197555d1c97f6b5cdd Mon Sep 17 00:00:00 2001 From: Crystalwarrior Date: Tue, 20 Apr 2021 02:50:42 +0300 Subject: 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(+) (limited to 'src') diff --git a/src/courtroom.cpp b/src/courtroom.cpp index 2314c995..a29788a0 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()) -- cgit 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: don't set a mask on elements affected by offsets (#524) --- src/aolayer.cpp | 7 ++++--- src/courtroom.cpp | 2 ++ 2 files changed, 6 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/aolayer.cpp b/src/aolayer.cpp index 18213ce1..e4db75ad 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 8ffd2b5c..aafc16d0 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); -- cgit From 81c0f9a569eaee58a28ca521b15ab397c03a4890 Mon Sep 17 00:00:00 2001 From: Crystalwarrior Date: Tue, 20 Apr 2021 08:13:56 +0300 Subject: 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(-) (limited to 'src') diff --git a/src/courtroom.cpp b/src/courtroom.cpp index fd0e1ca1..9a6fd08d 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 cf510026..dc76ec1a 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); -- cgit From 7b058d1401ddc1721304516f5cc7cdbdb15fee5d Mon Sep 17 00:00:00 2001 From: Crystalwarrior Date: Wed, 21 Apr 2021 02:14:49 +0300 Subject: 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(-) (limited to 'src') diff --git a/src/demoserver.cpp b/src/demoserver.cpp index 764cf225..09741fd4 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); -- cgit From fb4a5e0656cf1ad023b761139f30ecf3a584f56e Mon Sep 17 00:00:00 2001 From: Crystalwarrior Date: Wed, 21 Apr 2021 02:54:08 +0300 Subject: 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) --- src/courtroom.cpp | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/courtroom.cpp b/src/courtroom.cpp index 8a346a2a..776c0c93 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 -- cgit From d2c0c4fa0dfdef2534fcc0826f8c36bc4568a631 Mon Sep 17 00:00:00 2001 From: Crystalwarrior Date: Thu, 22 Apr 2021 19:02:07 +0300 Subject: 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(-) (limited to 'src') diff --git a/src/aolayer.cpp b/src/aolayer.cpp index e4db75ad..ccf2d633 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, -- cgit From d3e5cb933cd91d5393943ab3385bac0fc233cdc9 Mon Sep 17 00:00:00 2001 From: Crystalwarrior Date: Thu, 22 Apr 2021 19:09:44 +0300 Subject: 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(-) (limited to 'src') diff --git a/src/aolayer.cpp b/src/aolayer.cpp index ccf2d633..795274f5 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 -- cgit From 2c259a6337c66eb5900d2c46534c75e9d77586c1 Mon Sep 17 00:00:00 2001 From: Crystalwarrior Date: Thu, 22 Apr 2021 19:11:39 +0300 Subject: 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(-) (limited to 'src') diff --git a/src/path_functions.cpp b/src/path_functions.cpp index 51073494..79851c11 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 != "") -- cgit From 9359ed7f54dd996d879e465c87d5b9631bc6d6bb Mon Sep 17 00:00:00 2001 From: in1tiate Date: Fri, 23 Apr 2021 00:30:50 -0500 Subject: make sure we save the shownames even when theyre disabled --- src/courtroom.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/courtroom.cpp b/src/courtroom.cpp index 776c0c93..8bbaaa93 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() -- cgit From 9fbe899c0e6ff464d91c2b2171eebb8fb879facb Mon Sep 17 00:00:00 2001 From: Crystalwarrior Date: Fri, 23 Apr 2021 09:55:04 +0300 Subject: 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 --- src/demoserver.cpp | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) (limited to 'src') diff --git a/src/demoserver.cpp b/src/demoserver.cpp index 09741fd4..d6927a5e 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() -- cgit 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: 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(-) (limited to 'src') diff --git a/src/path_functions.cpp b/src/path_functions.cpp index 79851c11..dbf1cc40 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 a671d618..af4c232c 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(); -- cgit