From 661ec87646fe57a0081d49e428267b0dfe3f0d65 Mon Sep 17 00:00:00 2001 From: Crystalwarrior Date: Sun, 15 Sep 2019 20:02:24 +0300 Subject: [PATCH] Implement networking for frame-specific effects data sending/parsing if the server supports it Reorganize charmovie.h a bit and make some functions private Add a new helper function "read_char_ini_tag" which returns a qstringlist of all key=value strings associated with the tag --- include/aoapplication.h | 3 + include/aocharmovie.h | 41 +++++++++----- src/aocharmovie.cpp | 109 +++++++++++++++++++++++++----------- src/courtroom.cpp | 65 ++++++++++----------- src/text_file_functions.cpp | 16 ++++++ 5 files changed, 153 insertions(+), 81 deletions(-) diff --git a/include/aoapplication.h b/include/aoapplication.h index 8885596..eb12b0c 100644 --- a/include/aoapplication.h +++ b/include/aoapplication.h @@ -232,6 +232,9 @@ public: //Returns the value of p_search_line within target_tag and terminator_tag QString read_char_ini(QString p_char, QString p_search_line, QString target_tag); + //Returns a QStringList of all key=value definitions on a given tag. + QStringList read_char_ini_tag(QString p_char, QString target_tag); + //Returns the side of the p_char character from that characters ini file QString get_char_side(QString p_char); diff --git a/include/aocharmovie.h b/include/aocharmovie.h index 5eaafaf..d066a39 100644 --- a/include/aocharmovie.h +++ b/include/aocharmovie.h @@ -17,12 +17,6 @@ class AOCharMovie : public QLabel public: AOCharMovie(QWidget *p_parent, AOApplication *p_ao_app); - //Set the movie's image to provided paths, preparing for playback. - void load_image(QString p_char, QString p_emote, QString emote_prefix); - - //Start playback of the movie (if animated). - void play(); - //Play a hat.gif - style preanimation void play_pre(QString p_char, QString p_emote, int duration); @@ -32,15 +26,6 @@ public: //Play an (a)normal.gif - style animation (not talking) void play_idle(QString p_char, QString p_emote); - //Play a frame-specific effect, if there's any defined for that specific frame. - void play_frame_effect(int frame); - - //Retreive a pixmap adjused for mirroring/aspect ratio shenanigans from a provided QImage - QPixmap get_pixmap(QImage image); - - //Set the movie's frame to provided pixmap - void set_frame(QPixmap f_pixmap); - //Stop the movie, clearing the image void stop(); @@ -59,6 +44,8 @@ public: //Return the frame delay adjusted for speed int get_frame_delay(int delay); + QStringList network_strings; + private: AOApplication *ao_app; @@ -75,6 +62,9 @@ private: QString last_path; QImageReader *m_reader = new QImageReader(); + QString m_char; + QString m_emote; + QElapsedTimer actual_time; const int time_mod = 60; @@ -90,6 +80,27 @@ private: bool m_flipped = false; bool play_once = true; + //Set the movie's image to provided paths, preparing for playback. + void load_image(QString p_char, QString p_emote, QString emote_prefix); + + //Start playback of the movie (if animated). + void play(); + + //Play a frame-specific effect, if there's any defined for that specific frame. + void play_frame_effect(int frame); + + //Retreive a pixmap adjused for mirroring/aspect ratio shenanigans from a provided QImage + QPixmap get_pixmap(QImage image); + + //Set the movie's frame to provided pixmap + void set_frame(QPixmap f_pixmap); + + //Initialize the frame-specific effects from the char.ini + void load_effects(); + + //Initialize the frame-specific effects from the provided network_strings, this is only initialized if network_strings has size more than 0. + void load_network_effects(); + signals: void done(); void shake(); diff --git a/src/aocharmovie.cpp b/src/aocharmovie.cpp index d67cf98..34c6c81 100644 --- a/src/aocharmovie.cpp +++ b/src/aocharmovie.cpp @@ -64,39 +64,13 @@ void AOCharMovie::load_image(QString p_char, QString p_emote, QString emote_pref movie_delays.append(f_delay); } - movie_effects.resize(max_frames); - for (int e_frame = 0; e_frame < max_frames; ++e_frame) - { -#ifdef DEBUG_CHARMOVIE - qDebug() << p_char << p_emote << e_frame; -#endif - QString effect = ao_app->get_screenshake_frame(p_char, emote_prefix + p_emote, e_frame); - if (effect != "") - { - movie_effects[e_frame].append("shake"); -#ifdef DEBUG_CHARMOVIE - qDebug() << e_frame << "shake"; -#endif - } + m_char = p_char; + m_emote = emote_prefix + p_emote; - effect = ao_app->get_flash_frame(p_char, emote_prefix + p_emote, e_frame); - if (effect != "") - { - movie_effects[e_frame].append("flash"); -#ifdef DEBUG_CHARMOVIE - qDebug() << e_frame << "flash"; -#endif - } - - effect = ao_app->get_sfx_frame(p_char, emote_prefix + p_emote, e_frame); - if (effect != "") - { - movie_effects[e_frame].append("sfx^"+effect); -#ifdef DEBUG_CHARMOVIE - qDebug() << e_frame << effect; -#endif - } - } + if (network_strings.size() > 0) //our FX overwritten by networked ones + this->load_network_effects(); + else //Use default ini FX + this->load_effects(); #ifdef DEBUG_CHARMOVIE qDebug() << max_frames << "Setting image to " << emote_path << "Time taken to process image:" << actual_time.elapsed(); @@ -104,6 +78,77 @@ void AOCharMovie::load_image(QString p_char, QString p_emote, QString emote_pref #endif } +void AOCharMovie::load_effects() +{ + movie_effects.clear(); + movie_effects.resize(max_frames); + for (int e_frame = 0; e_frame < max_frames; ++e_frame) + { + QString effect = ao_app->get_screenshake_frame(m_char, m_emote, e_frame); + if (effect != "") + { + movie_effects[e_frame].append("shake"); + } + + effect = ao_app->get_flash_frame(m_char, m_emote, e_frame); + if (effect != "") + { + movie_effects[e_frame].append("flash"); + } + + effect = ao_app->get_sfx_frame(m_char, m_emote, e_frame); + if (effect != "") + { + movie_effects[e_frame].append("sfx^"+effect); + } + } +} + +void AOCharMovie::load_network_effects() +{ + movie_effects.clear(); + movie_effects.resize(max_frames); + //Order is important!!! + QStringList effects_list = {"shake", "flash", "sfx^"}; + + //Determines which list is smaller - effects_list or network_strings - and uses it as basis for the loop. + //This way, incomplete network_strings would still be parsed, and excess/unaccounted for networked information is omitted. + int effects_size = qMin(effects_list.size(), network_strings.size()); + + for (int i = 0; i < effects_size; ++i) + { + QString netstring = network_strings.at(i); + QStringList emote_splits = netstring.split("^"); + foreach (QString emote, emote_splits) + { + QStringList parsed = emote.split("|"); + if (parsed.size() <= 0 || parsed.at(0) != m_emote) + continue; + foreach (QString frame_data, parsed) + { + QStringList frame_split = frame_data.split("="); + if (frame_split.size() <= 1) //We might still be hanging at the emote itself (entry 0). + continue; + int f_frame = frame_split.at(0).toInt(); + if (f_frame >= max_frames) + { + qDebug() << "Warning: out of bounds" << effects_list[i] << "frame" << f_frame << "out of" << max_frames << "for" << m_char << m_emote; + continue; + } + QString f_data = frame_split.at(1); + if (f_data != "") + { + QString effect = effects_list[i]; + if (effect == "sfx^") //Currently the only frame result that feeds us data, let's yank it in. + effect += f_data; + qDebug() << effect << f_data << "frame" << f_frame << "for" << m_char << m_emote; + movie_effects[f_frame].append(effect); + } + } + } + } +} + void AOCharMovie::play() { play_frame_effect(frame); diff --git a/src/courtroom.cpp b/src/courtroom.cpp index 2aa82b5..2e4fbb2 100644 --- a/src/courtroom.cpp +++ b/src/courtroom.cpp @@ -1267,41 +1267,31 @@ void Courtroom::on_chat_return_pressed() packet_contents.append(QString::number(screenshake_state)); qDebug() << "Are we screen shaking this one? " << screenshake_state; - QString frame_screenshake = ""; - QString frame_realization = ""; - QString frame_sfx = ""; + QString pre_emote = ao_app->get_pre_emote(current_char, current_emote); + QString emote = ao_app->get_emote(current_char, current_emote); + QStringList emotes_to_check = {pre_emote, "(b)" + emote, "(a)" + emote}; + QStringList effects_to_check = {"_FrameScreenshake", "_FrameRealization", "_FrameSFX"}; - QString preemote_sfx = ao_app->get_pre_emote(current_char, current_emote) + "^"; - QString preemote_shake = ao_app->get_pre_emote(current_char, current_emote) + "^"; - QString preemote_flash = ao_app->get_pre_emote(current_char, current_emote) + "^"; + foreach (QString f_effect, effects_to_check) + { + QString packet; + foreach (QString f_emote, emotes_to_check) + { + packet += f_emote; + QString sfx_frames = ao_app->read_char_ini_tag(current_char, f_emote.append(f_effect)).join("|"); + if (sfx_frames != "") + packet += "|" + sfx_frames; + packet += "^"; + } + qDebug() << f_effect << "packet" << packet; + packet_contents.append(packet); + } - QString talkemote_sfx = "(b)" + ao_app->get_emote(current_char, current_emote) + "^"; - QString talkemote_shake = "(b)" + ao_app->get_emote(current_char, current_emote) + "^"; - QString talkemote_flash = "(b)" + ao_app->get_emote(current_char, current_emote) + "^"; + //"roar|thing=thong^(b)roar^(a)roar^" - QString idleemote_sfx = "(a)" + ao_app->get_emote(current_char, current_emote) + "^"; - QString idleemote_shake = "(a)" + ao_app->get_emote(current_char, current_emote) + "^"; - QString idleemote_flash = "(a)" + ao_app->get_emote(current_char, current_emote) + "^"; - - frame_screenshake += preemote_shake; - frame_screenshake += talkemote_shake; - frame_screenshake += idleemote_shake; - - frame_realization += preemote_flash; - frame_realization += talkemote_flash; - frame_realization += idleemote_flash; - - frame_sfx += preemote_sfx; - frame_sfx += talkemote_sfx; - frame_sfx += idleemote_sfx; - qDebug() << "Final strings:"; - qDebug() << frame_screenshake; - qDebug() << frame_realization; - qDebug() << frame_sfx; - - packet_contents.append(frame_screenshake); - packet_contents.append(frame_realization); - packet_contents.append(frame_sfx); +// packet_contents.append(frame_screenshake); +// packet_contents.append(frame_realization); +// packet_contents.append(frame_sfx); } ao_app->send_server_packet(new AOPacket("MS", packet_contents)); } @@ -1447,6 +1437,15 @@ void Courtroom::handle_chatmessage_2() //Clear all looping sfx to prevent obnoxiousness sfx_player->loop_clear(); + if (!m_chatmessage[FRAME_SFX].isEmpty()) + { + //ORDER IS IMPORTANT!! + QStringList netstrings = {m_chatmessage[FRAME_SCREENSHAKE], m_chatmessage[FRAME_REALIZATION], m_chatmessage[FRAME_SFX]}; + ui_vp_player_char->network_strings = netstrings; + } + else + ui_vp_player_char->network_strings.clear(); + if (m_chatmessage[SHOWNAME].isEmpty() || !ui_showname_enable->isChecked()) { QString real_name = char_list.at(m_chatmessage[CHAR_ID].toInt()).name; @@ -1673,11 +1672,9 @@ void Courtroom::do_screenshake() ui_vp_chatbox }; - int i = 0; //I would prefer if this was its own "shake" function to be honest. foreach (QWidget* ui_element, affected_list) { - qDebug() << ++i; QPropertyAnimation *screenshake_animation = new QPropertyAnimation(ui_element, "pos", this); QPoint pos_default = QPoint(ui_element->x(), ui_element->y()); diff --git a/src/text_file_functions.cpp b/src/text_file_functions.cpp index 3d557c6..4c0885e 100644 --- a/src/text_file_functions.cpp +++ b/src/text_file_functions.cpp @@ -406,6 +406,22 @@ QString AOApplication::read_char_ini(QString p_char, QString p_search_line, QStr return value; } +//returns all the values of target_tag +QStringList AOApplication::read_char_ini_tag(QString p_char, QString target_tag) +{ + QStringList r_values; + QSettings settings(get_character_path(p_char, "char.ini"), QSettings::IniFormat); + settings.beginGroup(target_tag); + QStringList keys = settings.allKeys(); + foreach (QString key, keys) + { + QString value = settings.value(key).toString(); + r_values << key + "=" + value; + } + settings.endGroup(); + return r_values; +} + QString AOApplication::get_char_name(QString p_char) { QString f_result = read_char_ini(p_char, "name", "Options");