diff options
| -rw-r--r-- | .github/ISSUE_TEMPLATE/bug_report.md | 31 | ||||
| -rw-r--r-- | .github/ISSUE_TEMPLATE/feature_request.md | 20 | ||||
| -rw-r--r-- | .travis.yml | 1 | ||||
| -rw-r--r-- | Attorney_Online.pro | 4 | ||||
| -rw-r--r-- | include/aoapplication.h | 5 | ||||
| -rw-r--r-- | include/aoblipplayer.h | 3 | ||||
| -rw-r--r-- | include/aopacket.h | 7 | ||||
| -rw-r--r-- | include/aosfxplayer.h | 3 | ||||
| -rw-r--r-- | include/courtroom.h | 19 | ||||
| -rw-r--r-- | include/encryption_functions.h | 15 | ||||
| -rw-r--r-- | include/hex_functions.h | 16 | ||||
| -rw-r--r-- | include/lobby.h | 1 | ||||
| -rwxr-xr-x | scripts/configure_ubuntu.sh | 3 | ||||
| -rw-r--r-- | src/aoblipplayer.cpp | 4 | ||||
| -rw-r--r-- | src/aocaseannouncerdialog.cpp | 2 | ||||
| -rw-r--r-- | src/aoimage.cpp | 15 | ||||
| -rw-r--r-- | src/aomusicplayer.cpp | 22 | ||||
| -rw-r--r-- | src/aooptionsdialog.cpp | 2 | ||||
| -rw-r--r-- | src/aopacket.cpp | 72 | ||||
| -rw-r--r-- | src/aosfxplayer.cpp | 27 | ||||
| -rw-r--r-- | src/charselect.cpp | 8 | ||||
| -rw-r--r-- | src/courtroom.cpp | 263 | ||||
| -rw-r--r-- | src/encryption_functions.cpp | 58 | ||||
| -rw-r--r-- | src/hex_functions.cpp | 17 | ||||
| -rw-r--r-- | src/lobby.cpp | 10 | ||||
| -rw-r--r-- | src/main.cpp | 2 | ||||
| -rw-r--r-- | src/packet_distribution.cpp | 188 | ||||
| -rw-r--r-- | src/path_functions.cpp | 53 |
28 files changed, 368 insertions, 503 deletions
diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..0e1e98c --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,31 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: '' +assignees: '' + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**To reproduce** +Steps to reproduce the behavior: +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Version:** + - OS: (e.g. Windows 10) + - Version or branch: (e.g. 2.8.5, master, ui-files, etc.) + +**Additional context** +Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..bbcbbe7 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,20 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: '' +labels: '' +assignees: '' + +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. diff --git a/.travis.yml b/.travis.yml index 48bc2b5..802ace9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,6 @@ language: cpp os: osx +osx_image: xcode12 addons: homebrew: update: true diff --git a/Attorney_Online.pro b/Attorney_Online.pro index d2c2062..1a5f214 100644 --- a/Attorney_Online.pro +++ b/Attorney_Online.pro @@ -14,6 +14,10 @@ SOURCES += $$files($$PWD/src/*.cpp) HEADERS += $$files($$PWD/include/*.h) LIBS += -L$$PWD/lib +QMAKE_LFLAGS += -Wl,-rpath,"'\$$ORIGIN/lib'" + +# Uncomment for verbose network logging +# DEFINES += DEBUG_NETWORK # Uncomment to enable Discord Rich Presence # DEFINES += DISCORD diff --git a/include/aoapplication.h b/include/aoapplication.h index 60d945e..790b445 100644 --- a/include/aoapplication.h +++ b/include/aoapplication.h @@ -63,14 +63,10 @@ public: /////////////////server metadata////////////////// - unsigned int s_decryptor = 5; - bool encryption_needed = true; - bool yellow_text_enabled = false; bool prezoom_enabled = false; bool flipping_enabled = false; bool custom_objection_enabled = false; - bool improved_loading_enabled = false; bool desk_mod_enabled = false; bool evidence_enabled = false; bool cccc_ic_support_enabled = false; @@ -80,6 +76,7 @@ public: bool looping_sfx_support_enabled = false; bool additive_enabled = false; bool effects_enabled = false; + bool y_offset_enabled = false; ///////////////loading info/////////////////// diff --git a/include/aoblipplayer.h b/include/aoblipplayer.h index 4d3b5f1..a11e29d 100644 --- a/include/aoblipplayer.h +++ b/include/aoblipplayer.h @@ -22,12 +22,9 @@ public: int m_cycle = 0; private: - const int max_blip_ms = 60; - QWidget *m_parent; AOApplication *ao_app; qreal m_volume; - QElapsedTimer delay; void set_volume_internal(qreal p_volume); diff --git a/include/aopacket.h b/include/aopacket.h index 4097be8..6d1deba 100644 --- a/include/aopacket.h +++ b/include/aopacket.h @@ -8,21 +8,16 @@ class AOPacket { public: AOPacket(QString p_packet_string); - AOPacket(QString header, QStringList &p_contents); - ~AOPacket(); + AOPacket(QString header, QStringList &p_contents) : m_header(header), m_contents(p_contents){} QString get_header() { return m_header; } QStringList &get_contents() { return m_contents; } QString to_string(); - void encrypt_header(unsigned int p_key); - void decrypt_header(unsigned int p_key); - void net_encode(); void net_decode(); private: - bool encrypted = false; QString m_header; QStringList m_contents; diff --git a/include/aosfxplayer.h b/include/aosfxplayer.h index 0a5fffa..7597636 100644 --- a/include/aosfxplayer.h +++ b/include/aosfxplayer.h @@ -16,8 +16,7 @@ public: void clear(); void loop_clear(); - void play(QString p_sfx, QString p_char = "", QString shout = "", - int channel = -1); + void play(QString p_sfx, QString p_char = "", QString shout = ""); void stop(int channel = -1); void set_volume(qreal p_volume); void set_looping(bool toggle, int channel = -1); diff --git a/include/courtroom.h b/include/courtroom.h index 5b5ff6c..eb33fd8 100644 --- a/include/courtroom.h +++ b/include/courtroom.h @@ -58,6 +58,7 @@ #include <QTextCharFormat> //#include <QRandomGenerator> +#include <algorithm> #include <stack> class AOApplication; @@ -225,7 +226,7 @@ public: // selected // or the user isn't already scrolled to the top void append_ic_text(QString p_text, QString p_name = "", QString action = "", - int color = 0); + int color = 0, QDateTime timestamp = QDateTime::currentDateTime()); // prints who played the song to IC chat and plays said song(if found on local // filesystem) takes in a list where the first element is the song name and @@ -275,14 +276,17 @@ private: bool message_is_centered = false; int current_display_speed = 3; - int message_display_speed[7] = {0, 10, 25, 40, 50, 70, 90}; + int message_display_speed[7] = {5, 10, 25, 40, 50, 70, 90}; // The character ID of the character this user wants to appear alongside with. int other_charid = -1; - // The offset this user has given if they want to appear alongside someone. + // The horizontal offset this user has given if they want to appear alongside someone. int char_offset = 0; + // The vertical offset this user has given. + int char_vert_offset = 0; + // 0 = in front, 1 = behind int pair_order = 0; @@ -311,7 +315,7 @@ private: int real_tick_pos = 0; // used to determine how often blips sound int blip_ticker = 0; - int blip_rate = 1; + int blip_rate = 2; int rainbow_counter = 0; bool rainbow_appended = false; bool blank_blip = false; @@ -424,8 +428,12 @@ private: // List of all currently available pos QStringList pos_dropdown_list; + // is the message we're about to send supposed to present evidence? bool is_presenting_evidence = false; + // have we already presented evidence for this message? + bool evidence_presented = false; + QString effect = ""; // Music effect flags we want to send to server when we play music @@ -520,6 +528,7 @@ private: AOButton *ui_pair_button; QListWidget *ui_pair_list; QSpinBox *ui_pair_offset_spinbox; + QSpinBox *ui_pair_vert_offset_spinbox; QComboBox *ui_pair_order_dropdown; @@ -701,6 +710,7 @@ private slots: void music_random(); void music_list_expand_all(); void music_list_collapse_all(); + void music_stop(); void on_area_list_double_clicked(QTreeWidgetItem *p_item, int column); void select_emote(int p_id); @@ -774,6 +784,7 @@ private slots: void on_log_limit_changed(int value); void on_pair_offset_changed(int value); + void on_pair_vert_offset_changed(int value); void on_ooc_toggle_clicked(); diff --git a/include/encryption_functions.h b/include/encryption_functions.h deleted file mode 100644 index b70e8e6..0000000 --- a/include/encryption_functions.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef ENCRYPTION_FUNCTIONS_H -#define ENCRYPTION_FUNCTIONS_H - -#include <QString> - -#include <QVector> -#include <cstddef> -#include <iomanip> -#include <sstream> -#include <stdlib.h> - -QString fanta_encrypt(QString p_input, unsigned int key); -QString fanta_decrypt(QString p_input, unsigned int key); - -#endif // ENCRYPTION_FUNCTIONS_H diff --git a/include/hex_functions.h b/include/hex_functions.h deleted file mode 100644 index d178ba1..0000000 --- a/include/hex_functions.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef HEX_OPERATIONS_H -#define HEX_OPERATIONS_H - -#include <algorithm> -#include <bitset> -#include <cstdint> -#include <iomanip> -#include <iostream> -#include <sstream> -#include <string> - -namespace omni { -std::string int_to_hex(unsigned int input); -} - -#endif // HEX_OPERATIONS_H diff --git a/include/lobby.h b/include/lobby.h index 42f5297..4278534 100644 --- a/include/lobby.h +++ b/include/lobby.h @@ -46,6 +46,7 @@ public: void set_loading_value(int p_value); bool public_servers_selected = true; + bool doubleclicked = false; ~Lobby(); diff --git a/scripts/configure_ubuntu.sh b/scripts/configure_ubuntu.sh index 280dfdf..b010d36 100755 --- a/scripts/configure_ubuntu.sh +++ b/scripts/configure_ubuntu.sh @@ -20,10 +20,13 @@ cd tmp #get the bass prebuilt curl http://www.un4seen.com/files/bass24-linux.zip -o bass_linux.zip +curl http://www.un4seen.com/files/bassopus24-linux.zip -o bassopus_linux.zip unzip bass_linux.zip +unzip bassopus_linux.zip cp x64/libbass.so ../../lib +cp x64/libbassopus.so ../../lib #get the discord-rpc prebuilt curl -L https://github.com/discordapp/discord-rpc/releases/download/v3.4.0/discord-rpc-linux.zip -o discord_rpc_linux.zip diff --git a/src/aoblipplayer.cpp b/src/aoblipplayer.cpp index 5b4d625..6607d46 100644 --- a/src/aoblipplayer.cpp +++ b/src/aoblipplayer.cpp @@ -26,10 +26,6 @@ void AOBlipPlayer::set_blips(QString p_sfx) void AOBlipPlayer::blip_tick() { - if (delay.isValid() && delay.elapsed() < max_blip_ms) - return; - - delay.start(); int f_cycle = m_cycle++; if (m_cycle == 5) diff --git a/src/aocaseannouncerdialog.cpp b/src/aocaseannouncerdialog.cpp index d91433a..aea6405 100644 --- a/src/aocaseannouncerdialog.cpp +++ b/src/aocaseannouncerdialog.cpp @@ -3,7 +3,7 @@ AOCaseAnnouncerDialog::AOCaseAnnouncerDialog(QWidget *parent, AOApplication *p_ao_app, Courtroom *p_court) - : QDialog(parent) + : QDialog(parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint) { ao_app = p_ao_app; court = p_court; diff --git a/src/aoimage.cpp b/src/aoimage.cpp index 2663ba0..3977c97 100644 --- a/src/aoimage.cpp +++ b/src/aoimage.cpp @@ -2,6 +2,8 @@ #include "aoimage.h" +#include <QBitmap> + AOImage::AOImage(QWidget *parent, AOApplication *p_ao_app) : QLabel(parent) { m_parent = parent; @@ -29,9 +31,10 @@ bool AOImage::set_image(QString p_image) } QPixmap f_pixmap(final_image_path); - - this->setPixmap( - f_pixmap.scaled(this->width(), this->height(), Qt::IgnoreAspectRatio)); + f_pixmap = + f_pixmap.scaled(this->width(), this->height(), Qt::IgnoreAspectRatio); + this->setPixmap(f_pixmap); + this->setMask(f_pixmap.mask()); return true; } @@ -45,7 +48,9 @@ bool AOImage::set_chatbox(QString p_path) QPixmap f_pixmap(p_path); - this->setPixmap( - f_pixmap.scaled(this->width(), this->height(), Qt::IgnoreAspectRatio)); + f_pixmap = + f_pixmap.scaled(this->width(), this->height(), Qt::IgnoreAspectRatio); + this->setPixmap(f_pixmap); + this->setMask(f_pixmap.mask()); return true; } diff --git a/src/aomusicplayer.cpp b/src/aomusicplayer.cpp index 6c61b9a..585a7f4 100644 --- a/src/aomusicplayer.cpp +++ b/src/aomusicplayer.cpp @@ -23,14 +23,26 @@ void AOMusicPlayer::play(QString p_song, int channel, bool loop, unsigned int flags = BASS_STREAM_PRESCAN | BASS_STREAM_AUTOFREE | BASS_UNICODE | BASS_ASYNCFILE; - if (loop) + unsigned int streaming_flags = BASS_STREAM_AUTOFREE; + if (loop) { flags |= BASS_SAMPLE_LOOP; + streaming_flags |= BASS_SAMPLE_LOOP; + } DWORD newstream; - if (f_path.endsWith(".opus")) - newstream = BASS_OPUS_StreamCreateFile(FALSE, f_path.utf16(), 0, 0, flags); - else - newstream = BASS_StreamCreateFile(FALSE, f_path.utf16(), 0, 0, flags); + if (f_path.startsWith("http")) { + if (f_path.endsWith(".opus")) + newstream = BASS_OPUS_StreamCreateURL(f_path.toStdString().c_str(), 0, streaming_flags, nullptr, 0); + else + newstream = BASS_StreamCreateURL(f_path.toStdString().c_str(), 0, streaming_flags, nullptr, 0); + + } else { + if (f_path.endsWith(".opus")) + newstream = BASS_OPUS_StreamCreateFile(FALSE, f_path.utf16(), 0, 0, flags); + else + newstream = BASS_StreamCreateFile(FALSE, f_path.utf16(), 0, 0, flags); + } + if (ao_app->get_audio_output_device() != "default") BASS_ChannelSetDevice(m_stream_list[channel], BASS_GetDevice()); diff --git a/src/aooptionsdialog.cpp b/src/aooptionsdialog.cpp index 4d36f43..2641d8d 100644 --- a/src/aooptionsdialog.cpp +++ b/src/aooptionsdialog.cpp @@ -3,7 +3,7 @@ #include "bass.h" AOOptionsDialog::AOOptionsDialog(QWidget *parent, AOApplication *p_ao_app) - : QDialog(parent) + : QDialog(parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint) { ao_app = p_ao_app; diff --git a/src/aopacket.cpp b/src/aopacket.cpp index 6afd39e..bb6ac73 100644 --- a/src/aopacket.cpp +++ b/src/aopacket.cpp @@ -1,80 +1,30 @@ #include "aopacket.h" -#include "encryption_functions.h" - AOPacket::AOPacket(QString p_packet_string) { QStringList packet_contents = p_packet_string.split("#"); - m_header = packet_contents.at(0); - - for (int n_string = 1; n_string < packet_contents.size() - 1; ++n_string) { - m_contents.append(packet_contents.at(n_string)); - } -} - -AOPacket::AOPacket(QString p_header, QStringList &p_contents) -{ - m_header = p_header; - m_contents = p_contents; + m_header = packet_contents.first(); + m_contents = packet_contents.mid(1, packet_contents.size()-2); // trims % } -AOPacket::~AOPacket() {} - QString AOPacket::to_string() { - QString f_string = m_header; - - for (QString i_string : m_contents) { - f_string += ("#" + i_string); - } - - f_string += "#%"; - - if (encrypted) - return "#" + f_string; - else - return f_string; -} - -void AOPacket::encrypt_header(unsigned int p_key) -{ - m_header = fanta_encrypt(m_header, p_key); - - encrypted = true; -} - -void AOPacket::decrypt_header(unsigned int p_key) -{ - m_header = fanta_decrypt(m_header, p_key); - - encrypted = false; + return m_header + "#" + m_contents.join("#") + "#%"; } void AOPacket::net_encode() { - for (int n_element = 0; n_element < m_contents.size(); ++n_element) { - QString f_element = m_contents.at(n_element); - f_element.replace("#", "<num>") - .replace("%", "<percent>") - .replace("$", "<dollar>") - .replace("&", "<and>"); - - m_contents.removeAt(n_element); - m_contents.insert(n_element, f_element); - } + m_contents.replaceInStrings("#", "<num>") + .replaceInStrings("%", "<percent>") + .replaceInStrings("$", "<dollar>") + .replaceInStrings("&", "<and>"); } void AOPacket::net_decode() { - for (int n_element = 0; n_element < m_contents.size(); ++n_element) { - QString f_element = m_contents.at(n_element); - f_element.replace("<num>", "#") - .replace("<percent>", "%") - .replace("<dollar>", "$") - .replace("<and>", "&"); - - m_contents.removeAt(n_element); - m_contents.insert(n_element, f_element); - } + m_contents.replaceInStrings("<num>", "#") + .replaceInStrings("<percent>", "%") + .replaceInStrings("<dollar>", "$") + .replaceInStrings("<and>", "&"); } diff --git a/src/aosfxplayer.cpp b/src/aosfxplayer.cpp index 1a0e2d2..13de04f 100644 --- a/src/aosfxplayer.cpp +++ b/src/aosfxplayer.cpp @@ -24,17 +24,17 @@ void AOSfxPlayer::loop_clear() set_volume_internal(m_volume); } -void AOSfxPlayer::play(QString p_sfx, QString p_char, QString shout, - int channel) +void AOSfxPlayer::play(QString p_sfx, QString p_char, QString shout) { - if (channel == -1) { - if (BASS_ChannelIsActive(m_stream_list[channel]) == BASS_ACTIVE_PLAYING) - m_channel = (m_channel + 1) % m_channelmax; - channel = m_channel; + for (int i = 0; i < m_channelmax; ++i) { + if (BASS_ChannelIsActive(m_stream_list[i]) == BASS_ACTIVE_PLAYING) + m_channel = (i + 1) % m_channelmax; + else { + m_channel = i; + break; + } } - BASS_ChannelStop(m_stream_list[channel]); - QString misc_path = ""; QString char_path = ""; QString theme_path = ""; @@ -45,7 +45,8 @@ void AOSfxPlayer::play(QString p_sfx, QString p_char, QString shout, shout + "/" + p_sfx); theme_path = ao_app->get_sfx_suffix(ao_app->get_theme_path(p_sfx)); if (!file_exists(theme_path)) - theme_path = ao_app->get_sfx_suffix(ao_app->get_default_theme_path(p_sfx)); + theme_path = + ao_app->get_sfx_suffix(ao_app->get_default_theme_path(p_sfx)); } if (p_char != "") char_path = @@ -57,17 +58,17 @@ void AOSfxPlayer::play(QString p_sfx, QString p_char, QString shout, f_path = char_path; else if (file_exists(misc_path)) f_path = misc_path; - else if (shout != "" && file_exists(theme_path)) //only check here for shouts + else if (shout != "" && file_exists(theme_path)) // only check here for shouts f_path = theme_path; else f_path = sound_path; if (f_path.endsWith(".opus")) - m_stream_list[channel] = BASS_OPUS_StreamCreateFile( + m_stream_list[m_channel] = BASS_OPUS_StreamCreateFile( FALSE, f_path.utf16(), 0, 0, BASS_STREAM_AUTOFREE | BASS_UNICODE | BASS_ASYNCFILE); else - m_stream_list[channel] = BASS_StreamCreateFile( + m_stream_list[m_channel] = BASS_StreamCreateFile( FALSE, f_path.utf16(), 0, 0, BASS_STREAM_AUTOFREE | BASS_UNICODE | BASS_ASYNCFILE); @@ -81,7 +82,7 @@ void AOSfxPlayer::play(QString p_sfx, QString p_char, QString shout, } BASS_ChannelPlay(m_stream_list[m_channel], false); - BASS_ChannelSetSync(m_stream_list[channel], BASS_SYNC_DEV_FAIL, 0, + BASS_ChannelSetSync(m_stream_list[m_channel], BASS_SYNC_DEV_FAIL, 0, ao_app->BASSreset, 0); } diff --git a/src/charselect.cpp b/src/charselect.cpp index 7356089..1091a7a 100644 --- a/src/charselect.cpp +++ b/src/charselect.cpp @@ -7,6 +7,8 @@ void Courtroom::construct_char_select() { + this->setWindowFlags( (this->windowFlags() | Qt::CustomizeWindowHint) & ~Qt::WindowMaximizeButtonHint); + ui_char_select_background = new AOImage(this, ao_app); ui_char_buttons = new QWidget(ui_char_select_background); @@ -72,10 +74,10 @@ void Courtroom::set_char_select() if (f_charselect.width < 0 || f_charselect.height < 0) { qDebug() << "W: did not find char_select width or height in " "courtroom_design.ini!"; - this->resize(714, 668); + this->setFixedSize(714, 668); } else - this->resize(f_charselect.width, f_charselect.height); + this->setFixedSize(f_charselect.width, f_charselect.height); ui_char_select_background->resize(f_charselect.width, f_charselect.height); ui_char_select_background->set_image("charselect_background"); @@ -146,8 +148,6 @@ void Courtroom::char_clicked(int n_char) else update_character(n_char); - enter_courtroom(); - if (n_char != -1) ui_ic_chat_name->setPlaceholderText(char_list.at(n_char).name); } diff --git a/src/courtroom.cpp b/src/courtroom.cpp index e8d3262..ba13e21 100644 --- a/src/courtroom.cpp +++ b/src/courtroom.cpp @@ -3,6 +3,9 @@ Courtroom::Courtroom(AOApplication *p_ao_app) : QMainWindow() { ao_app = p_ao_app; + + this->setWindowFlags( (this->windowFlags() | Qt::CustomizeWindowHint) & ~Qt::WindowMaximizeButtonHint); + ao_app->initBASS(); qsrand(static_cast<uint>(QDateTime::currentMSecsSinceEpoch() / 1000)); @@ -242,7 +245,10 @@ Courtroom::Courtroom(AOApplication *p_ao_app) : QMainWindow() ui_pair_list = new QListWidget(this); ui_pair_offset_spinbox = new QSpinBox(this); ui_pair_offset_spinbox->setRange(-100, 100); - ui_pair_offset_spinbox->setSuffix(tr("% offset")); + ui_pair_offset_spinbox->setSuffix(tr("% x offset")); + ui_pair_vert_offset_spinbox = new QSpinBox(this); + ui_pair_vert_offset_spinbox->setRange(-100, 100); + ui_pair_vert_offset_spinbox->setSuffix(tr("% y offset")); ui_pair_order_dropdown = new QComboBox(this); ui_pair_order_dropdown->addItem(tr("To front")); @@ -386,6 +392,8 @@ Courtroom::Courtroom(AOApplication *p_ao_app) : QMainWindow() SLOT(on_pair_list_clicked(QModelIndex))); connect(ui_pair_offset_spinbox, SIGNAL(valueChanged(int)), this, SLOT(on_pair_offset_changed(int))); + connect(ui_pair_vert_offset_spinbox, SIGNAL(valueChanged(int)), this, + SLOT(on_pair_vert_offset_changed(int))); connect(ui_pair_order_dropdown, SIGNAL(currentIndexChanged(int)), this, SLOT(on_pair_order_dropdown_changed(int))); @@ -446,13 +454,13 @@ void Courtroom::set_widgets() if (f_courtroom.width < 0 || f_courtroom.height < 0) { qDebug() << "W: did not find courtroom width or height in " << filename; - this->resize(714, 668); + this->setFixedSize(714, 668); } else { m_courtroom_width = f_courtroom.width; m_courtroom_height = f_courtroom.height; - this->resize(f_courtroom.width, f_courtroom.height); + this->setFixedSize(f_courtroom.width, f_courtroom.height); } set_fonts(); @@ -586,12 +594,18 @@ void Courtroom::set_widgets() set_size_and_pos(ui_pair_offset_spinbox, "pair_offset_spinbox"); ui_pair_offset_spinbox->hide(); ui_pair_offset_spinbox->setToolTip( - tr("Change the percentage offset of your character's position from the " + tr("Change the horizontal percentage offset of your character's position from the " + "center of the screen.")); + + set_size_and_pos(ui_pair_vert_offset_spinbox, "pair_vert_offset_spinbox"); + ui_pair_vert_offset_spinbox->hide(); + ui_pair_vert_offset_spinbox->setToolTip( + tr("Change the vertical percentage offset of your character's position from the " "center of the screen.")); ui_pair_order_dropdown->hide(); set_size_and_pos(ui_pair_order_dropdown, "pair_order_dropdown"); - ui_pair_offset_spinbox->setToolTip( + ui_pair_order_dropdown->setToolTip( tr("Change the order of appearance for your character.")); set_size_and_pos(ui_pair_button, "pair_button"); @@ -706,8 +720,7 @@ void Courtroom::set_widgets() ui_sfx_remove->setText("X"); ui_sfx_remove->set_image("evidencex"); ui_sfx_remove->setToolTip( - tr("Remove the currently selected iniswap from the list and return to " - "the original character folder.")); + tr("Remove the currently selected sound effect.")); ui_sfx_remove->hide(); set_iniswap_dropdown(); @@ -1320,6 +1333,9 @@ void Courtroom::update_character(int p_cid) ui_char_select_background->hide(); ui_ic_chat_message->setEnabled(m_cid != -1); ui_ic_chat_message->setFocus(); + // have to call these to make sure sfx and blips don't get accidentally muted forever when we change characters + sfx_player->set_volume(ui_sfx_slider->value()); + blip_player->set_volume(ui_blip_slider->value()); } void Courtroom::enter_courtroom() @@ -1533,9 +1549,8 @@ void Courtroom::on_chat_return_pressed() return; ui_ic_chat_message->blockSignals(true); - QTimer::singleShot(600, this, [=] { - ui_ic_chat_message->blockSignals(false); - }); + QTimer::singleShot(600, this, + [=] { ui_ic_chat_message->blockSignals(false); }); // MS# // deskmod# // pre-emote# @@ -1597,13 +1612,11 @@ void Courtroom::on_chat_return_pressed() int f_emote_mod = ao_app->get_emote_mod(current_char, current_emote); // needed or else legacy won't understand what we're saying - if (objection_state > 0) { - if (ui_pre->isChecked()) { - if (f_emote_mod == 4 || f_emote_mod == 5) - f_emote_mod = 6; - else - f_emote_mod = 2; - } + if (objection_state > 0 && ui_pre->isChecked()) { + if (f_emote_mod == 4 || f_emote_mod == 5) + f_emote_mod = 6; + else + f_emote_mod = 2; } else if (ui_pre->isChecked() && !ui_pre_non_interrupt->isChecked()) { if (f_emote_mod == 0) @@ -1695,7 +1708,10 @@ void Courtroom::on_chat_return_pressed() packet_contents.append("-1"); } // Send the offset as it's gonna be used regardless - packet_contents.append(QString::number(char_offset)); + if(ao_app->y_offset_enabled) + packet_contents.append(QString::number(char_offset) + "&" + QString::number(char_vert_offset)); + else + packet_contents.append(QString::number(char_offset)); // Finally, we send over if we want our pres to not interrupt. if (ui_pre_non_interrupt->isChecked() && ui_pre->isChecked()) { @@ -1763,6 +1779,7 @@ void Courtroom::reset_ic() ui_vp_chat_arrow->stop(); text_state = 0; anim_state = 0; + evidence_presented = false; ui_vp_objection->stop(); chat_tick_timer->stop(); ui_vp_evidence_display->reset(); @@ -1796,6 +1813,7 @@ void Courtroom::handle_chatmessage(QStringList *p_contents) if (p_contents->size() < MS_MINIMUM) return; + int prev_char_id = m_chatmessage[CHAR_ID].toInt(); for (int n_string = 0; n_string < MS_MAXIMUM; ++n_string) { // Note that we have added stuff that vanilla clients and servers simply // won't send. So now, we have to check if the thing we want even exists @@ -1864,8 +1882,8 @@ void Courtroom::handle_chatmessage(QStringList *p_contents) m_chatmessage[MESSAGE] = ""; // Turn it into true blankpost } - if (!m_chatmessage[MESSAGE].isEmpty() || ic_chatlog_history.isEmpty() || - ic_chatlog_history.last().get_message() != "") { + if (prev_char_id != f_char_id || !m_chatmessage[MESSAGE].isEmpty() || + ic_chatlog_history.isEmpty() || ic_chatlog_history.last().get_message() != "") { log_ic_text(f_charname, f_displayname, m_chatmessage[MESSAGE], "", m_chatmessage[TEXT_COLOR].toInt()); append_ic_text(m_chatmessage[MESSAGE], f_displayname, "", @@ -2085,10 +2103,19 @@ void Courtroom::handle_chatmessage_2() if (got_other_charid > -1) { // If there is, show them! ui_vp_sideplayer_char->show(); - - int other_offset = m_chatmessage[OTHER_OFFSET].toInt(); + QStringList other_offsets = m_chatmessage[OTHER_OFFSET].split("&"); + int other_offset; + int other_offset_v; + if (other_offsets.length() <= 1) { + other_offset = m_chatmessage[OTHER_OFFSET].toInt(); + other_offset_v = 0; + } + else { + other_offset = other_offsets[0].toInt(); + other_offset_v = other_offsets[1].toInt(); + } ui_vp_sideplayer_char->move(ui_viewport->width() * other_offset / 100, - 0); + ui_viewport->height() * other_offset_v / 100); QStringList args = m_chatmessage[OTHER_CHARID].split("^"); if (args.size() > @@ -2127,12 +2154,14 @@ void Courtroom::handle_chatmessage_2() } // Set ourselves according to SELF_OFFSET - bool ok; - int self_offset = m_chatmessage[SELF_OFFSET].toInt(&ok); - if (ok) - ui_vp_player_char->move(ui_viewport->width() * self_offset / 100, 0); - else - ui_vp_player_char->move(0, 0); + QStringList self_offsets = m_chatmessage[SELF_OFFSET].split("&"); + int self_offset = self_offsets[0].toInt(); + int self_offset_v; + if (self_offsets.length() <= 1) + self_offset_v = 0; + else + self_offset_v = self_offsets[1].toInt(); + ui_vp_player_char->move(ui_viewport->width() * self_offset / 100, ui_viewport->height() * self_offset_v / 100); switch (emote_mod) { case 1: @@ -2255,7 +2284,8 @@ void Courtroom::handle_chatmessage_3() .isEmpty()) // Pure whitespace showname, get outta here. f_showname = m_chatmessage[CHAR_NAME]; - if (f_evi_id > 0 && f_evi_id <= local_evidence_list.size()) { + if (f_evi_id > 0 && f_evi_id <= local_evidence_list.size() && + !evidence_presented) { // shifted by 1 because 0 is no evidence per legacy standards QString f_image = local_evidence_list.at(f_evi_id - 1).image; QString f_evi_name = local_evidence_list.at(f_evi_id - 1).name; @@ -2269,6 +2299,8 @@ void Courtroom::handle_chatmessage_3() tr("has presented evidence"), m_chatmessage[TEXT_COLOR].toInt()); append_ic_text(f_evi_name, f_showname, tr("has presented evidence")); + evidence_presented = true; // we're done presenting evidence, and we + // don't want to do it twice } int emote_mod = m_chatmessage[EMOTE_MOD].toInt(); @@ -2587,7 +2619,7 @@ void Courtroom::log_ic_text(QString p_name, QString p_showname, } void Courtroom::append_ic_text(QString p_text, QString p_name, QString p_action, - int color) + int color, QDateTime timestamp) { QTextCharFormat bold; QTextCharFormat normal; @@ -2613,15 +2645,23 @@ void Courtroom::append_ic_text(QString p_text, QString p_name, QString p_action, } // Timestamp if we're doing that meme - if (log_timestamp) - ui_ic_chatlog->textCursor().insertText( - "[" + QDateTime::currentDateTime().toString("h:mm:ss AP") + "] ", - normal); + if (log_timestamp) { + if (timestamp.isValid()) { + ui_ic_chatlog->textCursor().insertText( + "[" + timestamp.toString("h:mm:ss AP") + "] ", normal); + } else { + qDebug() << "could not insert invalid timestamp"; + } + } // Format the name of the actor ui_ic_chatlog->textCursor().insertText(p_name, bold); + // Special case for stopping the music + if (p_action == tr("has stopped the music")) { + ui_ic_chatlog->textCursor().insertText(" " + p_action + ".", normal); + } // If action not blank: - if (p_action != "") { + else if (p_action != "") { // Format the action in normal ui_ic_chatlog->textCursor().insertText(" " + p_action, normal); if (log_newline) @@ -2960,17 +3000,40 @@ void Courtroom::chat_tick() ui_vp_message->ensureCursorVisible(); - // Blip player and real tick pos ticker - if (!formatting_char && (f_character != ' ' || blank_blip)) { - if (blip_ticker % blip_rate == 0) { + // We blip every "blip rate" letters. + // Here's an example with blank_blip being false and blip_rate being 2: + // I am you + // ! ! ! ! + // where ! is the blip sound + int b_rate = blip_rate; + // Earrape prevention without using timers, this method is more consistent. + if (msg_delay != 0 && msg_delay <= 25) { + // The default blip speed is 40ms, and if current msg_delay is 25ms, + // the formula will result in the blip rate of: + // 40/25 = 1.6 = 2 + // And if it's faster than that: + // 40/10 = 4 + b_rate = qMax(b_rate, qRound(static_cast<float>(message_display_speed[3])/msg_delay)); + } + if (blip_ticker % b_rate == 0) { + // ignoring white space unless blank_blip is enabled. + if (!formatting_char && (f_character != ' ' || blank_blip)) { blip_player->blip_tick(); + ++blip_ticker; } + } + else + { + // Don't fully ignore whitespace still, keep ticking until + // we reached the need to play a blip sound - we also just + // need to wait for a letter to play it on. ++blip_ticker; } - // Punctuation delayer - if (punctuation_chars.contains(f_character)) { - msg_delay *= punctuation_modifier; + // Punctuation delayer, only kicks in on speed ticks less than }} + if (current_display_speed > 1 && punctuation_chars.contains(f_character)) { + // Making the user have to wait any longer than 150ms per letter is downright unreasonable + msg_delay = qMin(150, msg_delay * punctuation_modifier); } // If this color is talking @@ -3157,14 +3220,19 @@ void Courtroom::handle_song(QStringList *p_contents) { effect_flags = p_contents->at(5).toInt(); } - music_player->play(f_song, channel, looping, effect_flags); - if (channel == 0) - ui_music_name->setText(f_song_clear); + if (f_song == "~stop.mp3") + ui_music_name->setText(tr("None")); + else if (channel == 0) { + if (file_exists(ao_app->get_sfx_suffix(ao_app->get_music_path(f_song)))) + ui_music_name->setText(f_song_clear); + else + ui_music_name->setText(tr("[MISSING] %1").arg(f_song_clear)); + } } else { QString str_char = char_list.at(n_char).name; - QString str_show = char_list.at(n_char).name; + QString str_show = ao_app->get_showname(str_char); if (p_contents->length() > 2) { if (p_contents->at(2) != "") { @@ -3186,13 +3254,25 @@ void Courtroom::handle_song(QStringList *p_contents) } if (!mute_map.value(n_char)) { - log_ic_text(str_char, str_show, f_song, tr("has played a song"), - m_chatmessage[TEXT_COLOR].toInt()); - append_ic_text(f_song_clear, str_show, tr("has played a song")); - + if (f_song == "~stop.mp3") { + log_ic_text(str_char, str_show, "", tr("has stopped the music"), + m_chatmessage[TEXT_COLOR].toInt()); + append_ic_text("", str_show, tr("has stopped the music")); + } + else { + log_ic_text(str_char, str_show, f_song, tr("has played a song"), + m_chatmessage[TEXT_COLOR].toInt()); + append_ic_text(f_song_clear, str_show, tr("has played a song")); + } music_player->play(f_song, channel, looping, effect_flags); - if (channel == 0) - ui_music_name->setText(f_song_clear); + if (f_song == "~stop.mp3") + ui_music_name->setText(tr("None")); + else if (channel == 0) { + if (file_exists(ao_app->get_sfx_suffix(ao_app->get_music_path(f_song)))) + ui_music_name->setText(f_song_clear); + else + ui_music_name->setText(tr("[MISSING] %1").arg(f_song_clear)); + } } } } @@ -3350,9 +3430,8 @@ void Courtroom::on_ooc_return_pressed() if (ok) { if (off >= -100 && off <= 100) { char_offset = off; - QString msg = tr("You have set your offset to "); - msg.append(QString::number(off)); - msg.append("%."); + QString msg = tr("You have set your offset to %1%%.") + .arg(QString::number(off)); append_server_chatmessage("CLIENT", msg, "1"); } else { @@ -3366,6 +3445,30 @@ void Courtroom::on_ooc_return_pressed() } return; } + else if (ooc_message.startsWith("/voffset")) { + ui_ooc_chat_message->clear(); + ooc_message.remove(0, 8); + + bool ok; + int off = ooc_message.toInt(&ok); + if (ok) { + if (off >= -100 && off <= 100) { + char_vert_offset = off; + QString msg = tr("You have set your vertical offset to %1%%.") + .arg(QString::number(off)); + append_server_chatmessage("CLIENT", msg, "1"); + } + else { + append_server_chatmessage( + "CLIENT", tr("Your vertical offset must be between -100% and 100%!"), "1"); + } + } + else { + append_server_chatmessage("CLIENT", + tr("That vertical offset does not look like one."), "1"); + } + return; + } else if (ooc_message.startsWith("/switch_am")) { append_server_chatmessage( "CLIENT", tr("You switched your music and area list."), "1"); @@ -3474,9 +3577,10 @@ void Courtroom::on_ooc_return_pressed() if (!caseauth.isEmpty()) append_server_chatmessage(tr("CLIENT"), tr("Case made by %1.").arg(caseauth), "1"); - if (!casedoc.isEmpty()) - ao_app->send_server_packet(new AOPacket("CT#" + ui_ooc_chat_name->text() + - "#/doc " + casedoc + "#%")); + if (!casedoc.isEmpty()) { + QStringList f_contents = {ui_ooc_chat_name->text(), "/doc " + casedoc}; + ao_app->send_server_packet(new AOPacket("CT", f_contents)); + } if (!casestatus.isEmpty()) ao_app->send_server_packet(new AOPacket("CT#" + ui_ooc_chat_name->text() + "#/status " + casestatus + "#%")); @@ -3489,7 +3593,15 @@ void Courtroom::on_ooc_return_pressed() new AOPacket("DE#" + QString::number(i) + "#%")); } - foreach (QString evi, casefile.childGroups()) { + // sort the case_evidence numerically + QStringList case_evidence = casefile.childGroups(); + std::sort(case_evidence.begin(), case_evidence.end(), + [] (const QString &a, const QString &b) { + return a.toInt() < b.toInt(); + }); + + // load evidence + foreach (QString evi, case_evidence) { if (evi == "General") continue; @@ -3907,7 +4019,7 @@ void Courtroom::set_effects_dropdown() return; } - effectslist.prepend("None"); + effectslist.prepend(tr("None")); ui_effects_dropdown->show(); ui_effects_dropdown->addItems(effectslist); @@ -4085,10 +4197,10 @@ void Courtroom::on_music_list_double_clicked(QTreeWidgetItem *p_item, { if (is_muted) return; - + if (p_item->parent() == nullptr) // i.e. we've clicked a category + return; column = 1; // Column 1 is always the metadata (which we want) QString p_song = p_item->text(column); - QStringList packet_contents; packet_contents.append(p_song); packet_contents.append(QString::number(m_cid)); @@ -4103,7 +4215,7 @@ void Courtroom::on_music_list_double_clicked(QTreeWidgetItem *p_item, void Courtroom::on_music_list_context_menu_requested(const QPoint &pos) { QMenu *menu = new QMenu(); - + menu->addAction(QString(tr("Stop Current Song")), this, SLOT(music_stop())); menu->addAction(QString(tr("Play Random Song")), this, SLOT(music_random())); menu->addSeparator(); menu->addAction(QString(tr("Expand All Categories")), this, @@ -4181,6 +4293,22 @@ void Courtroom::music_list_collapse_all() ui_music_list->setCurrentItem(current); } +void Courtroom::music_stop() +{ // send a fake music packet with a nonexistent song + if (is_muted) // this requires a special exception for "~stop.mp3" in + return; // tsuserver3, as it will otherwise reject songs not on + QStringList packet_contents; // its music list + packet_contents.append( + "~stop.mp3"); // this is our fake song, playing it triggers special code + packet_contents.append(QString::number(m_cid)); + if ((!ui_ic_chat_name->text().isEmpty() && ao_app->cccc_ic_support_enabled) || + ao_app->effects_enabled) + packet_contents.append(ui_ic_chat_name->text()); + if (ao_app->effects_enabled) + packet_contents.append(QString::number(music_flags)); + ao_app->send_server_packet(new AOPacket("MC", packet_contents), false); +} + void Courtroom::on_area_list_double_clicked(QTreeWidgetItem *p_item, int column) { column = 0; // The metadata @@ -4322,6 +4450,7 @@ void Courtroom::on_mute_clicked() ui_mute_list->show(); ui_pair_list->hide(); ui_pair_offset_spinbox->hide(); + ui_pair_vert_offset_spinbox->hide(); ui_pair_order_dropdown->hide(); ui_pair_button->set_image("pair_button"); ui_mute->set_image("mute_pressed"); @@ -4337,6 +4466,8 @@ void Courtroom::on_pair_clicked() if (ui_pair_list->isHidden()) { ui_pair_list->show(); ui_pair_offset_spinbox->show(); + if(ao_app->y_offset_enabled) + ui_pair_vert_offset_spinbox->show(); ui_pair_order_dropdown->show(); ui_mute_list->hide(); ui_mute->set_image("mute"); @@ -4345,6 +4476,7 @@ void Courtroom::on_pair_clicked() else { ui_pair_list->hide(); ui_pair_offset_spinbox->hide(); + ui_pair_vert_offset_spinbox->hide(); ui_pair_order_dropdown->hide(); ui_pair_button->set_image("pair_button"); } @@ -4501,6 +4633,8 @@ void Courtroom::on_log_limit_changed(int value) { log_maximum_blocks = value; } void Courtroom::on_pair_offset_changed(int value) { char_offset = value; } +void Courtroom::on_pair_vert_offset_changed(int value) { char_vert_offset = value; } + void Courtroom::on_witness_testimony_clicked() { if (is_muted) @@ -4659,7 +4793,8 @@ void Courtroom::regenerate_ic_chatlog() append_ic_text(item.get_message(), ui_showname_enable->isChecked() ? item.get_showname() : item.get_name(), - item.get_action(), item.get_chat_color()); + item.get_action(), item.get_chat_color(), + item.get_datetime().toLocalTime()); } } diff --git a/src/encryption_functions.cpp b/src/encryption_functions.cpp deleted file mode 100644 index 6669fe1..0000000 --- a/src/encryption_functions.cpp +++ /dev/null @@ -1,58 +0,0 @@ -#include "encryption_functions.h" - -#include "hex_functions.h" - -QString fanta_encrypt(QString temp_input, unsigned int p_key) -{ - // using standard stdlib types is actually easier here because of implicit - // char<->int conversion which in turn makes encryption arithmetic easier - - unsigned int key = p_key; - unsigned int C1 = 53761; - unsigned int C2 = 32618; - - QVector<uint_fast8_t> temp_result; - std::string input = temp_input.toUtf8().constData(); - - for (unsigned int pos = 0; pos < input.size(); ++pos) { - uint_fast8_t output = input.at(pos) ^ (key >> 8) % 256; - temp_result.append(output); - key = (temp_result.at(pos) + key) * C1 + C2; - } - - std::string result = ""; - - for (uint_fast8_t i_int : temp_result) { - result += omni::int_to_hex(i_int); - } - - QString final_result = QString::fromStdString(result); - - return final_result; -} - -QString fanta_decrypt(QString temp_input, unsigned int key) -{ - std::string input = temp_input.toUtf8().constData(); - - QVector<unsigned int> unhexed_vector; - - for (unsigned int i = 0; i < input.length(); i += 2) { - std::string byte = input.substr(i, 2); - unsigned int hex_int = strtoul(byte.c_str(), nullptr, 16); - unhexed_vector.append(hex_int); - } - - unsigned int C1 = 53761; - unsigned int C2 = 32618; - - std::string result = ""; - - for (int pos = 0; pos < unhexed_vector.size(); ++pos) { - unsigned char output = unhexed_vector.at(pos) ^ (key >> 8) % 256; - result += output; - key = (unhexed_vector.at(pos) + key) * C1 + C2; - } - - return QString::fromStdString(result); -} diff --git a/src/hex_functions.cpp b/src/hex_functions.cpp deleted file mode 100644 index 1e35718..0000000 --- a/src/hex_functions.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include "hex_functions.h" - -namespace omni { -std::string int_to_hex(unsigned int input) -{ - if (input > 255) - return "FF"; - - std::stringstream stream; - stream << std::setfill('0') << std::setw(sizeof(char) * 2) << std::hex - << input; - std::string result(stream.str()); - std::transform(result.begin(), result.end(), result.begin(), ::toupper); - - return result; -} -} // namespace omni diff --git a/src/lobby.cpp b/src/lobby.cpp index 093b0f7..afbf221 100644 --- a/src/lobby.cpp +++ b/src/lobby.cpp @@ -13,6 +13,7 @@ Lobby::Lobby(AOApplication *p_ao_app) : QMainWindow() this->setWindowTitle(tr("Attorney Online 2")); this->setWindowIcon(QIcon(":/logo.png")); + this->setWindowFlags( (this->windowFlags() | Qt::CustomizeWindowHint) & ~Qt::WindowMaximizeButtonHint); ui_background = new AOImage(this, ao_app); ui_public_servers = new AOButton(this, ao_app); @@ -97,10 +98,10 @@ void Lobby::set_widgets() "Did you download all resources correctly from tiny.cc/getao, " "including the large 'base' folder?")); - this->resize(517, 666); + this->setFixedSize(517, 666); } else { - this->resize(f_lobby.width, f_lobby.height); + this->setFixedSize(f_lobby.width, f_lobby.height); } set_size_and_pos(ui_background, "lobby"); @@ -355,7 +356,7 @@ void Lobby::on_connect_released() void Lobby::on_about_clicked() { - const bool hasApng = QImageReader::supportedImageFormats().contains("APNG"); + const bool hasApng = QImageReader::supportedImageFormats().contains("apng"); QString msg = tr("<h2>Attorney Online %1</h2>" @@ -441,8 +442,9 @@ void Lobby::on_server_list_clicked(QTreeWidgetItem *p_item, int column) // doubleclicked on an item in the serverlist so we'll connect right away void Lobby::on_server_list_doubleclicked(QTreeWidgetItem *p_item, int column) { + doubleclicked = true; on_server_list_clicked(p_item, column); - on_connect_released(); + //on_connect_released(); } void Lobby::on_server_search_edited(QString p_text) diff --git a/src/main.cpp b/src/main.cpp index 364377b..ce8b1dd 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -21,6 +21,8 @@ int main(int argc, char *argv[]) AOApplication main_app(argc, argv); + AOApplication::addLibraryPath(AOApplication::applicationDirPath() + "/lib"); + QSettings *configini = main_app.configini; QPluginLoader apngPlugin("qapng"); diff --git a/src/packet_distribution.cpp b/src/packet_distribution.cpp index ee56cdb..4e2d5ed 100644 --- a/src/packet_distribution.cpp +++ b/src/packet_distribution.cpp @@ -2,7 +2,6 @@ #include "courtroom.h" #include "debug_functions.h" -#include "encryption_functions.h" #include "hardware_functions.h" #include "lobby.h" #include "networkmanager.h" @@ -120,16 +119,11 @@ void AOApplication::server_packet_received(AOPacket *p_packet) if (f_contents.size() == 0) goto end; - // you may ask where 322 comes from. that would be a good question. - s_decryptor = fanta_decrypt(f_contents.at(0), 322).toUInt(); - // default(legacy) values - encryption_needed = true; yellow_text_enabled = false; prezoom_enabled = false; flipping_enabled = false; custom_objection_enabled = false; - improved_loading_enabled = false; desk_mod_enabled = false; evidence_enabled = false; cccc_ic_support_enabled = false; @@ -139,10 +133,7 @@ void AOApplication::server_packet_received(AOPacket *p_packet) looping_sfx_support_enabled = false; additive_enabled = false; effects_enabled = false; - - // workaround for tsuserver4 - if (f_contents.at(0) == "NOENCRYPT") - encryption_needed = false; + y_offset_enabled = false; QString f_hdid; f_hdid = get_hdid(); @@ -176,12 +167,10 @@ void AOApplication::server_packet_received(AOPacket *p_packet) } } else if (header == "FL") { - // encryption_needed = true; yellow_text_enabled = false; prezoom_enabled = false; flipping_enabled = false; custom_objection_enabled = false; - improved_loading_enabled = false; desk_mod_enabled = false; evidence_enabled = false; cccc_ic_support_enabled = false; @@ -199,10 +188,6 @@ void AOApplication::server_packet_received(AOPacket *p_packet) flipping_enabled = true; if (f_packet.contains("customobjections", Qt::CaseInsensitive)) custom_objection_enabled = true; - if (f_packet.contains("fastloading", Qt::CaseInsensitive)) - improved_loading_enabled = true; - if (f_packet.contains("noencryption", Qt::CaseInsensitive)) - encryption_needed = false; if (f_packet.contains("deskmod", Qt::CaseInsensitive)) desk_mod_enabled = true; if (f_packet.contains("evidence", Qt::CaseInsensitive)) @@ -221,6 +206,8 @@ void AOApplication::server_packet_received(AOPacket *p_packet) additive_enabled = true; if (f_packet.contains("effects", Qt::CaseInsensitive)) effects_enabled = true; + if (f_packet.contains("y_offset", Qt::CaseInsensitive)) + y_offset_enabled = true; } else if (header == "PN") { if (f_contents.size() < 2) @@ -228,6 +215,11 @@ void AOApplication::server_packet_received(AOPacket *p_packet) w_lobby->set_player_count(f_contents.at(0).toInt(), f_contents.at(1).toInt()); + + if (w_lobby->doubleclicked) { + send_server_packet(new AOPacket("askchaa#%")); + w_lobby->doubleclicked = false; + } } else if (header == "SI") { if (f_contents.size() != 3) @@ -283,11 +275,7 @@ void AOApplication::server_packet_received(AOPacket *p_packet) AOPacket *f_packet; - if (improved_loading_enabled) - f_packet = new AOPacket("RC#%"); - else - f_packet = new AOPacket("askchar2#%"); - + f_packet = new AOPacket("RC#%"); send_server_packet(f_packet); // Remove any characters not accepted in folder names for the server_name @@ -308,152 +296,6 @@ void AOApplication::server_packet_received(AOPacket *p_packet) discord->state_server(server_name.toStdString(), hash.result().toBase64().toStdString()); } - else if (header == "CI") { - if (!courtroom_constructed) - goto end; - - for (int n_element = 0; n_element < f_contents.size(); n_element += 2) { - if (f_contents.at(n_element).toInt() != loaded_chars) - break; - - // this means we are on the last element and checking n + 1 element will - // be game over so - if (n_element == f_contents.size() - 1) - break; - - QStringList sub_elements = f_contents.at(n_element + 1).split("&"); - if (sub_elements.size() < 2) - break; - - char_type f_char; - f_char.name = sub_elements.at(0); - f_char.description = sub_elements.at(1); - f_char.evidence_string = sub_elements.at(3); - // temporary. the CharsCheck packet sets this properly - f_char.taken = false; - - ++loaded_chars; - - w_lobby->set_loading_text(tr("Loading chars:\n%1/%2") - .arg(QString::number(loaded_chars)) - .arg(QString::number(char_list_size))); - - w_courtroom->append_char(f_char); - - int total_loading_size = - char_list_size * 2 + evidence_list_size + music_list_size; - int loading_value = int( - ((loaded_chars + generated_chars + loaded_music + loaded_evidence) / - static_cast<double>(total_loading_size)) * - 100); - w_lobby->set_loading_value(loading_value); - } - - if (improved_loading_enabled) - send_server_packet(new AOPacket("RE#%")); - else { - QString next_packet_number = - QString::number(((loaded_chars - 1) / 10) + 1); - send_server_packet(new AOPacket("AN#" + next_packet_number + "#%")); - } - } - else if (header == "EI") { - if (!courtroom_constructed) - goto end; - - // +1 because evidence starts at 1 rather than 0 for whatever reason - // enjoy fanta - if (f_contents.at(0).toInt() != loaded_evidence + 1) - goto end; - - if (f_contents.size() < 2) - goto end; - - QStringList sub_elements = f_contents.at(1).split("&"); - if (sub_elements.size() < 4) - goto end; - - evi_type f_evi; - f_evi.name = sub_elements.at(0); - f_evi.description = sub_elements.at(1); - // no idea what the number at position 2 is. probably an identifier? - f_evi.image = sub_elements.at(3); - - ++loaded_evidence; - - w_lobby->set_loading_text(tr("Loading evidence:\n%1/%2") - .arg(QString::number(loaded_evidence)) - .arg(QString::number(evidence_list_size))); - - w_courtroom->append_evidence(f_evi); - - int total_loading_size = - char_list_size * 2 + evidence_list_size + music_list_size; - int loading_value = - int(((loaded_chars + generated_chars + loaded_music + loaded_evidence) / - static_cast<double>(total_loading_size)) * - 100); - w_lobby->set_loading_value(loading_value); - - QString next_packet_number = QString::number(loaded_evidence); - send_server_packet(new AOPacket("AE#" + next_packet_number + "#%")); - } - else if (header == "EM") { - if (!courtroom_constructed) - goto end; - - bool musics_time = false; - int areas = 0; - - for (int n_element = 0; n_element < f_contents.size(); n_element += 2) { - if (f_contents.at(n_element).toInt() != loaded_music) - break; - - if (n_element == f_contents.size() - 1) - break; - - QString f_music = f_contents.at(n_element + 1); - - ++loaded_music; - - w_lobby->set_loading_text(tr("Loading music:\n%1/%2") - .arg(QString::number(loaded_music)) - .arg(QString::number(music_list_size))); - - if (musics_time) { - w_courtroom->append_music(f_music); - } - else { - if (f_music.endsWith(".wav") || f_music.endsWith(".mp3") || - f_music.endsWith(".mp4") || f_music.endsWith(".ogg") || - f_music.endsWith(".opus")) { - musics_time = true; - areas--; - w_courtroom->fix_last_area(); - w_courtroom->append_music(f_music); - } - else { - w_courtroom->append_area(f_music); - areas++; - } - } - - for (int area_n = 0; area_n < areas; area_n++) { - w_courtroom->arup_append(0, "Unknown", "Unknown", "Unknown"); - } - - int total_loading_size = - char_list_size * 2 + evidence_list_size + music_list_size; - int loading_value = int( - ((loaded_chars + generated_chars + loaded_music + loaded_evidence) / - static_cast<double>(total_loading_size)) * - 100); - w_lobby->set_loading_value(loading_value); - } - - QString next_packet_number = QString::number(((loaded_music - 1) / 10) + 1); - send_server_packet(new AOPacket("AM#" + next_packet_number + "#%")); - } else if (header == "CharsCheck") { if (!courtroom_constructed) goto end; @@ -621,6 +463,8 @@ void AOApplication::server_packet_received(AOPacket *p_packet) if (f_contents.size() < 3) goto end; + w_courtroom->enter_courtroom(); + if (courtroom_constructed) w_courtroom->update_character(f_contents.at(2).toInt()); } @@ -755,19 +599,9 @@ void AOApplication::send_server_packet(AOPacket *p_packet, bool encoded) QString f_packet = p_packet->to_string(); - if (encryption_needed) { -#ifdef DEBUG_NETWORK - qDebug() << "S(e):" << f_packet; -#endif - - p_packet->encrypt_header(s_decryptor); - f_packet = p_packet->to_string(); - } - else { #ifdef DEBUG_NETWORK qDebug() << "S:" << f_packet; #endif - } net_manager->ship_server_packet(f_packet); diff --git a/src/path_functions.cpp b/src/path_functions.cpp index 10c8ae5..c6c73a8 100644 --- a/src/path_functions.cpp +++ b/src/path_functions.cpp @@ -44,61 +44,40 @@ QString AOApplication::get_data_path() { return get_base_path() + "data/"; } QString AOApplication::get_default_theme_path(QString p_file) { QString path = get_base_path() + "themes/default/" + p_file; -#ifndef CASE_SENSITIVE_FILESYSTEM - return path; -#else return get_case_sensitive_path(path); -#endif } QString AOApplication::get_custom_theme_path(QString p_theme, QString p_file) { QString path = get_base_path() + "themes/" + p_theme + "/" + p_file; -#ifndef CASE_SENSITIVE_FILESYSTEM - return path; -#else return get_case_sensitive_path(path); -#endif } QString AOApplication::get_theme_path(QString p_file) { QString path = get_base_path() + "themes/" + current_theme + "/" + p_file; -#ifndef CASE_SENSITIVE_FILESYSTEM - return path; -#else return get_case_sensitive_path(path); -#endif } QString AOApplication::get_character_path(QString p_char, QString p_file) { QString path = get_base_path() + "characters/" + p_char + "/" + p_file; -#ifndef CASE_SENSITIVE_FILESYSTEM - return path; -#else return get_case_sensitive_path(path); -#endif } QString AOApplication::get_sounds_path(QString p_file) { QString path = get_base_path() + "sounds/general/" + p_file; -#ifndef CASE_SENSITIVE_FILESYSTEM - return path; -#else return get_case_sensitive_path(path); -#endif } QString AOApplication::get_music_path(QString p_song) { + if (p_song.startsWith("http")) { + return p_song; // url + } QString path = get_base_path() + "sounds/music/" + p_song; -#ifndef CASE_SENSITIVE_FILESYSTEM - return path; -#else return get_case_sensitive_path(path); -#endif } QString AOApplication::get_background_path(QString p_file) @@ -106,11 +85,7 @@ QString AOApplication::get_background_path(QString p_file) QString path = get_base_path() + "background/" + w_courtroom->get_current_background() + "/" + p_file; if (courtroom_constructed) { -#ifndef CASE_SENSITIVE_FILESYSTEM - return path; -#else return get_case_sensitive_path(path); -#endif } return get_default_background_path(p_file); } @@ -118,33 +93,30 @@ QString AOApplication::get_background_path(QString p_file) QString AOApplication::get_default_background_path(QString p_file) { QString path = get_base_path() + "background/default/" + p_file; -#ifndef CASE_SENSITIVE_FILESYSTEM - return path; -#else return get_case_sensitive_path(path); -#endif } QString AOApplication::get_evidence_path(QString p_file) { QString path = get_base_path() + "evidence/" + p_file; -#ifndef CASE_SENSITIVE_FILESYSTEM - return path; -#else return get_case_sensitive_path(path); -#endif } QString AOApplication::get_case_sensitive_path(QString p_file) { + QFileInfo file(p_file); + QString file_basename = file.fileName(); + + // no path traversal above base folder + if (!(file.absolutePath().startsWith(get_base_path()))) + return get_base_path() + file_basename; + + #ifdef CASE_SENSITIVE_FILESYSTEM // first, check to see if it's actually there (also serves as base case for // recursion) if (exists(p_file)) return p_file; - QFileInfo file(p_file); - - QString file_basename = file.fileName(); QString file_parent_dir = get_case_sensitive_path(file.absolutePath()); // second, does it exist in the new parent dir? @@ -163,4 +135,7 @@ QString AOApplication::get_case_sensitive_path(QString p_file) // if nothing is found, let the caller handle the missing file return file_parent_dir + "/" + file_basename; +#else + return p_file; +#endif } |
