From 00cfd2750d39795e4c205aee2a33b92b1da2524d Mon Sep 17 00:00:00 2001 From: David Skoland Date: Wed, 26 Dec 2018 16:43:08 +0100 Subject: moved headers into include and cpp files into src + logo into resource --- aoapplication.cpp | 187 --- aoapplication.h | 318 ---- aoblipplayer.cpp | 47 - aoblipplayer.h | 30 - aobutton.cpp | 26 - aobutton.h | 22 - aocaseannouncerdialog.cpp | 82 - aocaseannouncerdialog.h | 45 - aocharbutton.cpp | 97 -- aocharbutton.h | 44 - aocharmovie.cpp | 195 --- aocharmovie.h | 57 - aoemotebutton.cpp | 36 - aoemotebutton.h | 36 - aoevidencebutton.cpp | 119 -- aoevidencebutton.h | 50 - aoevidencedisplay.cpp | 96 -- aoevidencedisplay.h | 32 - aoimage.cpp | 47 - aoimage.h | 25 - aolineedit.cpp | 21 - aolineedit.h | 26 - aomovie.cpp | 90 - aomovie.h | 34 - aomusicplayer.cpp | 34 - aomusicplayer.h | 28 - aooptionsdialog.cpp | 517 ------ aooptionsdialog.h | 115 -- aopacket.cpp | 83 - aopacket.h | 32 - aoscene.cpp | 76 - aoscene.h | 27 - aosfxplayer.cpp | 51 - aosfxplayer.h | 28 - aotextarea.cpp | 60 - aotextarea.h | 24 - aotextedit.cpp | 21 - aotextedit.h | 23 - charselect.cpp | 268 --- chatlogpiece.cpp | 76 - chatlogpiece.h | 31 - courtroom.cpp | 3513 --------------------------------------- courtroom.h | 671 -------- datatypes.h | 119 -- debug_functions.cpp | 25 - debug_functions.h | 10 - discord-rpc.h | 85 - discord_rich_presence.cpp | 103 -- discord_rich_presence.h | 34 - emotes.cpp | 174 -- encryption_functions.cpp | 63 - encryption_functions.h | 15 - evidence.cpp | 345 ---- file_functions.cpp | 21 - file_functions.h | 12 - hardware_functions.cpp | 57 - hardware_functions.h | 10 - hex_functions.cpp | 18 - hex_functions.h | 17 - include/aoapplication.h | 318 ++++ include/aoblipplayer.h | 30 + include/aobutton.h | 22 + include/aocaseannouncerdialog.h | 45 + include/aocharbutton.h | 44 + include/aocharmovie.h | 57 + include/aoemotebutton.h | 36 + include/aoevidencebutton.h | 50 + include/aoevidencedisplay.h | 32 + include/aoimage.h | 25 + include/aolineedit.h | 26 + include/aomovie.h | 34 + include/aomusicplayer.h | 28 + include/aooptionsdialog.h | 115 ++ include/aopacket.h | 32 + include/aoscene.h | 27 + include/aosfxplayer.h | 28 + include/aotextarea.h | 24 + include/aotextedit.h | 23 + include/chatlogpiece.h | 31 + include/courtroom.h | 671 ++++++++ include/datatypes.h | 119 ++ include/debug_functions.h | 10 + include/discord-rpc.h | 85 + include/discord_rich_presence.h | 34 + include/encryption_functions.h | 15 + include/file_functions.h | 12 + include/hardware_functions.h | 10 + include/hex_functions.h | 17 + include/lobby.h | 95 ++ include/misc_functions.h | 9 + include/networkmanager.h | 86 + include/text_file_functions.h | 13 + lobby.cpp | 388 ----- lobby.h | 95 -- logo.ico | Bin 99678 -> 0 bytes logo.png | Bin 29302 -> 0 bytes main.cpp | 25 - misc_functions.cpp | 9 - misc_functions.h | 9 - networkmanager.cpp | 252 --- networkmanager.h | 86 - packet_distribution.cpp | 707 -------- path_functions.cpp | 162 -- resource/logo.ico | Bin 0 -> 99678 bytes resource/logo.png | Bin 0 -> 29302 bytes resources.qrc | 2 +- src/aoapplication.cpp | 187 +++ src/aoblipplayer.cpp | 47 + src/aobutton.cpp | 26 + src/aocaseannouncerdialog.cpp | 82 + src/aocharbutton.cpp | 97 ++ src/aocharmovie.cpp | 195 +++ src/aoemotebutton.cpp | 36 + src/aoevidencebutton.cpp | 119 ++ src/aoevidencedisplay.cpp | 96 ++ src/aoimage.cpp | 47 + src/aolineedit.cpp | 21 + src/aomovie.cpp | 90 + src/aomusicplayer.cpp | 34 + src/aooptionsdialog.cpp | 517 ++++++ src/aopacket.cpp | 83 + src/aoscene.cpp | 76 + src/aosfxplayer.cpp | 51 + src/aotextarea.cpp | 60 + src/aotextedit.cpp | 21 + src/charselect.cpp | 268 +++ src/chatlogpiece.cpp | 76 + src/courtroom.cpp | 3513 +++++++++++++++++++++++++++++++++++++++ src/debug_functions.cpp | 25 + src/discord_rich_presence.cpp | 103 ++ src/emotes.cpp | 174 ++ src/encryption_functions.cpp | 63 + src/evidence.cpp | 345 ++++ src/file_functions.cpp | 21 + src/hardware_functions.cpp | 57 + src/hex_functions.cpp | 18 + src/lobby.cpp | 388 +++++ src/main.cpp | 25 + src/misc_functions.cpp | 9 + src/networkmanager.cpp | 252 +++ src/packet_distribution.cpp | 707 ++++++++ src/path_functions.cpp | 162 ++ src/text_file_functions.cpp | 639 +++++++ text_file_functions.cpp | 639 ------- text_file_functions.h | 13 - 145 files changed, 10934 insertions(+), 10934 deletions(-) delete mode 100644 aoapplication.cpp delete mode 100644 aoapplication.h delete mode 100644 aoblipplayer.cpp delete mode 100644 aoblipplayer.h delete mode 100644 aobutton.cpp delete mode 100644 aobutton.h delete mode 100644 aocaseannouncerdialog.cpp delete mode 100644 aocaseannouncerdialog.h delete mode 100644 aocharbutton.cpp delete mode 100644 aocharbutton.h delete mode 100644 aocharmovie.cpp delete mode 100644 aocharmovie.h delete mode 100644 aoemotebutton.cpp delete mode 100644 aoemotebutton.h delete mode 100644 aoevidencebutton.cpp delete mode 100644 aoevidencebutton.h delete mode 100644 aoevidencedisplay.cpp delete mode 100644 aoevidencedisplay.h delete mode 100644 aoimage.cpp delete mode 100644 aoimage.h delete mode 100644 aolineedit.cpp delete mode 100644 aolineedit.h delete mode 100644 aomovie.cpp delete mode 100644 aomovie.h delete mode 100644 aomusicplayer.cpp delete mode 100644 aomusicplayer.h delete mode 100644 aooptionsdialog.cpp delete mode 100644 aooptionsdialog.h delete mode 100644 aopacket.cpp delete mode 100644 aopacket.h delete mode 100644 aoscene.cpp delete mode 100644 aoscene.h delete mode 100644 aosfxplayer.cpp delete mode 100644 aosfxplayer.h delete mode 100644 aotextarea.cpp delete mode 100644 aotextarea.h delete mode 100644 aotextedit.cpp delete mode 100644 aotextedit.h delete mode 100644 charselect.cpp delete mode 100644 chatlogpiece.cpp delete mode 100644 chatlogpiece.h delete mode 100644 courtroom.cpp delete mode 100644 courtroom.h delete mode 100644 datatypes.h delete mode 100644 debug_functions.cpp delete mode 100644 debug_functions.h delete mode 100644 discord-rpc.h delete mode 100644 discord_rich_presence.cpp delete mode 100644 discord_rich_presence.h delete mode 100644 emotes.cpp delete mode 100644 encryption_functions.cpp delete mode 100644 encryption_functions.h delete mode 100644 evidence.cpp delete mode 100644 file_functions.cpp delete mode 100644 file_functions.h delete mode 100644 hardware_functions.cpp delete mode 100644 hardware_functions.h delete mode 100644 hex_functions.cpp delete mode 100644 hex_functions.h create mode 100644 include/aoapplication.h create mode 100644 include/aoblipplayer.h create mode 100644 include/aobutton.h create mode 100644 include/aocaseannouncerdialog.h create mode 100644 include/aocharbutton.h create mode 100644 include/aocharmovie.h create mode 100644 include/aoemotebutton.h create mode 100644 include/aoevidencebutton.h create mode 100644 include/aoevidencedisplay.h create mode 100644 include/aoimage.h create mode 100644 include/aolineedit.h create mode 100644 include/aomovie.h create mode 100644 include/aomusicplayer.h create mode 100644 include/aooptionsdialog.h create mode 100644 include/aopacket.h create mode 100644 include/aoscene.h create mode 100644 include/aosfxplayer.h create mode 100644 include/aotextarea.h create mode 100644 include/aotextedit.h create mode 100644 include/chatlogpiece.h create mode 100644 include/courtroom.h create mode 100644 include/datatypes.h create mode 100644 include/debug_functions.h create mode 100644 include/discord-rpc.h create mode 100644 include/discord_rich_presence.h create mode 100644 include/encryption_functions.h create mode 100644 include/file_functions.h create mode 100644 include/hardware_functions.h create mode 100644 include/hex_functions.h create mode 100644 include/lobby.h create mode 100644 include/misc_functions.h create mode 100644 include/networkmanager.h create mode 100644 include/text_file_functions.h delete mode 100644 lobby.cpp delete mode 100644 lobby.h delete mode 100644 logo.ico delete mode 100644 logo.png delete mode 100644 main.cpp delete mode 100644 misc_functions.cpp delete mode 100644 misc_functions.h delete mode 100644 networkmanager.cpp delete mode 100644 networkmanager.h delete mode 100644 packet_distribution.cpp delete mode 100644 path_functions.cpp create mode 100644 resource/logo.ico create mode 100644 resource/logo.png create mode 100644 src/aoapplication.cpp create mode 100644 src/aoblipplayer.cpp create mode 100644 src/aobutton.cpp create mode 100644 src/aocaseannouncerdialog.cpp create mode 100644 src/aocharbutton.cpp create mode 100644 src/aocharmovie.cpp create mode 100644 src/aoemotebutton.cpp create mode 100644 src/aoevidencebutton.cpp create mode 100644 src/aoevidencedisplay.cpp create mode 100644 src/aoimage.cpp create mode 100644 src/aolineedit.cpp create mode 100644 src/aomovie.cpp create mode 100644 src/aomusicplayer.cpp create mode 100644 src/aooptionsdialog.cpp create mode 100644 src/aopacket.cpp create mode 100644 src/aoscene.cpp create mode 100644 src/aosfxplayer.cpp create mode 100644 src/aotextarea.cpp create mode 100644 src/aotextedit.cpp create mode 100644 src/charselect.cpp create mode 100644 src/chatlogpiece.cpp create mode 100644 src/courtroom.cpp create mode 100644 src/debug_functions.cpp create mode 100644 src/discord_rich_presence.cpp create mode 100644 src/emotes.cpp create mode 100644 src/encryption_functions.cpp create mode 100644 src/evidence.cpp create mode 100644 src/file_functions.cpp create mode 100644 src/hardware_functions.cpp create mode 100644 src/hex_functions.cpp create mode 100644 src/lobby.cpp create mode 100644 src/main.cpp create mode 100644 src/misc_functions.cpp create mode 100644 src/networkmanager.cpp create mode 100644 src/packet_distribution.cpp create mode 100644 src/path_functions.cpp create mode 100644 src/text_file_functions.cpp delete mode 100644 text_file_functions.cpp delete mode 100644 text_file_functions.h diff --git a/aoapplication.cpp b/aoapplication.cpp deleted file mode 100644 index d7c3e662..00000000 --- a/aoapplication.cpp +++ /dev/null @@ -1,187 +0,0 @@ -#include "aoapplication.h" - -#include "lobby.h" -#include "courtroom.h" -#include "networkmanager.h" -#include "debug_functions.h" - -#include "aooptionsdialog.h" -#include "aocaseannouncerdialog.h" - -AOApplication::AOApplication(int &argc, char **argv) : QApplication(argc, argv) -{ - // Create the QSettings class that points to the config.ini. - configini = new QSettings(get_base_path() + "config.ini", QSettings::IniFormat); - - net_manager = new NetworkManager(this); - discord = new AttorneyOnline::Discord(); - QObject::connect(net_manager, SIGNAL(ms_connect_finished(bool, bool)), - SLOT(ms_connect_finished(bool, bool))); -} - -AOApplication::~AOApplication() -{ - destruct_lobby(); - destruct_courtroom(); - delete discord; -} - -void AOApplication::construct_lobby() -{ - if (lobby_constructed) - { - qDebug() << "W: lobby was attempted constructed when it already exists"; - return; - } - - w_lobby = new Lobby(this); - lobby_constructed = true; - - QRect screenGeometry = QApplication::desktop()->screenGeometry(); - int x = (screenGeometry.width()-w_lobby->width()) / 2; - int y = (screenGeometry.height()-w_lobby->height()) / 2; - w_lobby->move(x, y); - - if (is_discord_enabled()) - discord->state_lobby(); - - w_lobby->show(); -} - -void AOApplication::destruct_lobby() -{ - if(!lobby_constructed) - { - qDebug() << "W: lobby was attempted destructed when it did not exist"; - return; - } - - delete w_lobby; - w_lobby = nullptr; - lobby_constructed = false; -} - -void AOApplication::construct_courtroom() -{ - if (courtroom_constructed) - { - qDebug() << "W: courtroom was attempted constructed when it already exists"; - return; - } - - w_courtroom = new Courtroom(this); - courtroom_constructed = true; - - QRect screenGeometry = QApplication::desktop()->screenGeometry(); - int x = (screenGeometry.width()-w_courtroom->width()) / 2; - int y = (screenGeometry.height()-w_courtroom->height()) / 2; - w_courtroom->move(x, y); -} - -void AOApplication::destruct_courtroom() -{ - if (!courtroom_constructed) - { - qDebug() << "W: courtroom was attempted destructed when it did not exist"; - return; - } - - delete w_courtroom; - w_courtroom = nullptr; - courtroom_constructed = false; -} - -QString AOApplication::get_version_string() -{ - return - QString::number(RELEASE) + "." + - QString::number(MAJOR_VERSION) + "." + - QString::number(MINOR_VERSION); -} - -void AOApplication::reload_theme() -{ - current_theme = read_theme(); -} - -void AOApplication::set_favorite_list() -{ - favorite_list = read_serverlist_txt(); -} - -QString AOApplication::get_current_char() -{ - if (courtroom_constructed) - return w_courtroom->get_current_char(); - else - return ""; -} - -void AOApplication::add_favorite_server(int p_server) -{ - if (p_server < 0 || p_server >= server_list.size()) - return; - - server_type fav_server = server_list.at(p_server); - - QString str_port = QString::number(fav_server.port); - - QString server_line = fav_server.ip + ":" + str_port + ":" + fav_server.name; - - write_to_serverlist_txt(server_line); -} - -void AOApplication::server_disconnected() -{ - if (courtroom_constructed) - { - call_notice("Disconnected from server."); - construct_lobby(); - destruct_courtroom(); - } -} - -void AOApplication::loading_cancelled() -{ - destruct_courtroom(); - - w_lobby->hide_loading_overlay(); -} - -void AOApplication::ms_connect_finished(bool connected, bool will_retry) -{ - if (connected) - { - AOPacket *f_packet = new AOPacket("ALL#%"); - send_ms_packet(f_packet); - } - else - { - if (will_retry) - { - if (lobby_constructed) - w_lobby->append_error("Error connecting to master server. Will try again in " - + QString::number(net_manager->ms_reconnect_delay_ms / 1000.f) + " seconds."); - } - else - { - call_error("There was an error connecting to the master server.\n" - "We deploy multiple master servers to mitigate any possible downtime, " - "but the client appears to have exhausted all possible methods of finding " - "and connecting to one.\n" - "Please check your Internet connection and firewall, and please try again."); - } - } -} - -void AOApplication::call_settings_menu() -{ - AOOptionsDialog settings(nullptr, this); - settings.exec(); -} - -void AOApplication::call_announce_menu(Courtroom *court) -{ - AOCaseAnnouncerDialog announcer(nullptr, this, court); - announcer.exec(); -} diff --git a/aoapplication.h b/aoapplication.h deleted file mode 100644 index f4207333..00000000 --- a/aoapplication.h +++ /dev/null @@ -1,318 +0,0 @@ -#ifndef AOAPPLICATION_H -#define AOAPPLICATION_H - -#include "aopacket.h" -#include "datatypes.h" -#include "discord_rich_presence.h" - -#include -#include -#include -#include - -#include -#include -#include - -#include - -#include -#include - -#include -#include -#include - -class NetworkManager; -class Lobby; -class Courtroom; - -class AOApplication : public QApplication -{ - Q_OBJECT - -public: - AOApplication(int &argc, char **argv); - ~AOApplication(); - - NetworkManager *net_manager; - Lobby *w_lobby; - Courtroom *w_courtroom; - AttorneyOnline::Discord *discord; - - bool lobby_constructed = false; - bool courtroom_constructed = false; - - void construct_lobby(); - void destruct_lobby(); - - void construct_courtroom(); - void destruct_courtroom(); - - void ms_packet_received(AOPacket *p_packet); - void server_packet_received(AOPacket *p_packet); - - void send_ms_packet(AOPacket *p_packet); - void send_server_packet(AOPacket *p_packet, bool encoded = true); - - void call_settings_menu(); - void call_announce_menu(Courtroom *court); - - /////////////////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; - bool arup_enabled = false; - bool casing_alerts_enabled = false; - bool modcall_reason_enabled = false; - - ///////////////loading info/////////////////// - - //player number, it's hardly used but might be needed for some old servers - int s_pv = 0; - - QString server_software = ""; - - int char_list_size = 0; - int loaded_chars = 0; - int generated_chars = 0; - int evidence_list_size = 0; - int loaded_evidence = 0; - int music_list_size = 0; - int loaded_music = 0; - - bool courtroom_loaded = false; - - //////////////////versioning/////////////// - - constexpr int get_release() const { return RELEASE; } - constexpr int get_major_version() const { return MAJOR_VERSION; } - constexpr int get_minor_version() const { return MINOR_VERSION; } - QString get_version_string(); - - /////////////////////////////////////////// - - void set_favorite_list(); - QVector& get_favorite_list() {return favorite_list;} - void add_favorite_server(int p_server); - - void set_server_list(); - QVector& get_server_list() {return server_list;} - - //reads the theme from config.ini and sets it accordingly - void reload_theme(); - - //Returns the character the player has currently selected - QString get_current_char(); - - //implementation in path_functions.cpp - QString get_base_path(); - QString get_data_path(); - QString get_theme_path(QString p_file); - QString get_default_theme_path(QString p_file); - QString get_custom_theme_path(QString p_theme, QString p_file); - QString get_character_path(QString p_char, QString p_file); - QString get_sounds_path(QString p_file); - QString get_music_path(QString p_song); - QString get_background_path(QString p_file); - QString get_default_background_path(QString p_file); - QString get_evidence_path(QString p_file); - QString get_case_sensitive_path(QString p_file); - - ////// Functions for reading and writing files ////// - // Implementations file_functions.cpp - - // Instead of reinventing the wheel, we'll use a QSettings class. - QSettings *configini; - - //Reads the theme from config.ini and loads it into the current_theme variable - QString read_theme(); - - //Returns the value of ooc_name in config.ini - QString get_ooc_name(); - - //Returns the blip rate from config.ini - int read_blip_rate(); - - //Returns true if blank blips is enabled in config.ini and false otherwise - bool get_blank_blip(); - - //Returns the value of default_music in config.ini - int get_default_music(); - - //Returns the value of default_sfx in config.ini - int get_default_sfx(); - - //Returns the value of default_blip in config.ini - int get_default_blip(); - - // Returns the value of whether Discord should be enabled on startup - // from the config.ini. - bool is_discord_enabled(); - - // Returns the value of the maximum amount of lines the IC chatlog - // may contain, from config.ini. - int get_max_log_size(); - - // Returns whether the log should go upwards (new behaviour) - // or downwards (vanilla behaviour). - bool get_log_goes_downwards(); - - // Returns the username the user may have set in config.ini. - QString get_default_username(); - - // Returns the audio device used for the client. - QString get_audio_output_device(); - - // Returns whether the user would like to have custom shownames on by default. - bool get_showname_enabled_by_default(); - - //Returns the list of words in callwords.ini - QStringList get_call_words(); - - //Appends the argument string to serverlist.txt - void write_to_serverlist_txt(QString p_line); - - //Returns the contents of serverlist.txt - QVector read_serverlist_txt(); - - //Returns the value of p_identifier in the design.ini file in p_design_path - QString read_design_ini(QString p_identifier, QString p_design_path); - - //Returns the coordinates of widget with p_identifier from p_file - QPoint get_button_spacing(QString p_identifier, QString p_file); - - //Returns the dimensions of widget with specified identifier from p_file - pos_size_type get_element_dimensions(QString p_identifier, QString p_file); - - //Returns the value of font_size with p_identifier from p_file - int get_font_size(QString p_identifier, QString p_file); - - //Returns the color with p_identifier from p_file - QColor get_color(QString p_identifier, QString p_file); - - // Returns the colour from the misc folder. - QColor get_chat_color(QString p_identifier, QString p_chat); - - //Returns the sfx with p_identifier from sounds.ini in the current theme path - QString get_sfx(QString p_identifier); - - //Figure out if we can opus this or if we should fall back to wav - QString get_sfx_suffix(QString sound_to_check); - - // Can we use APNG for this? If not, fall back to a gif. - QString get_image_suffix(QString path_to_check); - - //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 the side of the p_char character from that characters ini file - QString get_char_side(QString p_char); - - //Returns the showname from the ini of p_char - QString get_showname(QString p_char); - - //Returns the value of chat from the specific p_char's ini file - QString get_chat(QString p_char); - - //Returns the value of shouts from the specified p_char's ini file - QString get_char_shouts(QString p_char); - - //Returns the preanim duration of p_char's p_emote - int get_preanim_duration(QString p_char, QString p_emote); - - //Same as above, but only returns if it has a % in front(refer to Preanims section in the manual) - int get_ao2_preanim_duration(QString p_char, QString p_emote); - - //Not in use - int get_text_delay(QString p_char, QString p_emote); - - // Returns the custom realisation used by the character. - QString get_custom_realization(QString p_char); - - //Returns the name of p_char - QString get_char_name(QString p_char); - - //Returns the total amount of emotes of p_char - int get_emote_number(QString p_char); - - //Returns the emote comment of p_char's p_emote - QString get_emote_comment(QString p_char, int p_emote); - - //Returns the base name of p_char's p_emote - QString get_emote(QString p_char, int p_emote); - - //Returns the preanimation name of p_char's p_emote - QString get_pre_emote(QString p_char, int p_emote); - - //Returns the sfx of p_char's p_emote - QString get_sfx_name(QString p_char, int p_emote); - - //Not in use - int get_sfx_delay(QString p_char, int p_emote); - - //Returns the modifier for p_char's p_emote - int get_emote_mod(QString p_char, int p_emote); - - //Returns the desk modifier for p_char's p_emote - int get_desk_mod(QString p_char, int p_emote); - - //Returns p_char's gender - QString get_gender(QString p_char); - - // ====== - // These are all casing-related settings. - // ====== - - // Returns if the user has casing alerts enabled. - bool get_casing_enabled(); - - // Returns if the user wants to get alerts for the defence role. - bool get_casing_defence_enabled(); - - // Same for prosecution. - bool get_casing_prosecution_enabled(); - - // Same for judge. - bool get_casing_judge_enabled(); - - // Same for juror. - bool get_casing_juror_enabled(); - - // Same for steno. - bool get_casing_steno_enabled(); - - // Same for CM. - bool get_casing_cm_enabled(); - - // Get the message for the CM for casing alerts. - QString get_casing_can_host_cases(); - -private: - const int RELEASE = 2; - const int MAJOR_VERSION = 6; - const int MINOR_VERSION = 0; - - QString current_theme = "default"; - - QVector server_list; - QVector favorite_list; - -private slots: - void ms_connect_finished(bool connected, bool will_retry); - -public slots: - void server_disconnected(); - void loading_cancelled(); -}; - -#endif // AOAPPLICATION_H diff --git a/aoblipplayer.cpp b/aoblipplayer.cpp deleted file mode 100644 index 74757c50..00000000 --- a/aoblipplayer.cpp +++ /dev/null @@ -1,47 +0,0 @@ -#include "aoblipplayer.h" - -AOBlipPlayer::AOBlipPlayer(QWidget *parent, AOApplication *p_ao_app) -{ - m_parent = parent; - ao_app = p_ao_app; -} - -void AOBlipPlayer::set_blips(QString p_sfx) -{ - QString f_path = ao_app->get_sounds_path(p_sfx); - - for (int n_stream = 0 ; n_stream < 5 ; ++n_stream) - { - BASS_StreamFree(m_stream_list[n_stream]); - - m_stream_list[n_stream] = BASS_StreamCreateFile(FALSE, f_path.utf16(), 0, 0, BASS_UNICODE | BASS_ASYNCFILE); - } - - set_volume(m_volume); -} - -void AOBlipPlayer::blip_tick() -{ - int f_cycle = m_cycle++; - - if (m_cycle == 5) - m_cycle = 0; - - HSTREAM f_stream = m_stream_list[f_cycle]; - - if (ao_app->get_audio_output_device() != "default") - BASS_ChannelSetDevice(f_stream, BASS_GetDevice()); - BASS_ChannelPlay(f_stream, false); -} - -void AOBlipPlayer::set_volume(int p_value) -{ - m_volume = p_value; - - float volume = p_value / 100.0f; - - for (int n_stream = 0 ; n_stream < 5 ; ++n_stream) - { - BASS_ChannelSetAttribute(m_stream_list[n_stream], BASS_ATTRIB_VOL, volume); - } -} diff --git a/aoblipplayer.h b/aoblipplayer.h deleted file mode 100644 index aebba77d..00000000 --- a/aoblipplayer.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef AOBLIPPLAYER_H -#define AOBLIPPLAYER_H - -#include "bass.h" -#include "aoapplication.h" - -#include -#include -#include - -class AOBlipPlayer -{ -public: - AOBlipPlayer(QWidget *parent, AOApplication *p_ao_app); - - void set_blips(QString p_sfx); - void blip_tick(); - void set_volume(int p_volume); - - int m_cycle = 0; - -private: - QWidget *m_parent; - AOApplication *ao_app; - - int m_volume; - HSTREAM m_stream_list[5]; -}; - -#endif // AOBLIPPLAYER_H diff --git a/aobutton.cpp b/aobutton.cpp deleted file mode 100644 index 5be2e678..00000000 --- a/aobutton.cpp +++ /dev/null @@ -1,26 +0,0 @@ -#include "aobutton.h" - -#include "debug_functions.h" -#include "file_functions.h" - -AOButton::AOButton(QWidget *parent, AOApplication *p_ao_app) : QPushButton(parent) -{ - ao_app = p_ao_app; -} - -AOButton::~AOButton() -{ - -} - -void AOButton::set_image(QString p_image) -{ - QString image_path = ao_app->get_theme_path(p_image); - QString default_image_path = ao_app->get_default_theme_path(p_image); - - if (file_exists(image_path)) - this->setStyleSheet("border-image:url(\"" + image_path + "\")"); - else - this->setStyleSheet("border-image:url(\"" + default_image_path + "\")"); -} - diff --git a/aobutton.h b/aobutton.h deleted file mode 100644 index 4b7209ae..00000000 --- a/aobutton.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef AOBUTTON_H -#define AOBUTTON_H - -#include "aoapplication.h" - -#include -#include - -class AOButton : public QPushButton -{ - Q_OBJECT - -public: - AOButton(QWidget *parent, AOApplication *p_ao_app); - ~AOButton(); - - AOApplication *ao_app; - - void set_image(QString p_image); -}; - -#endif // AOBUTTON_H diff --git a/aocaseannouncerdialog.cpp b/aocaseannouncerdialog.cpp deleted file mode 100644 index 5b82b64f..00000000 --- a/aocaseannouncerdialog.cpp +++ /dev/null @@ -1,82 +0,0 @@ -#include "aocaseannouncerdialog.h" - -AOCaseAnnouncerDialog::AOCaseAnnouncerDialog(QWidget *parent, AOApplication *p_ao_app, Courtroom *p_court) - : QDialog(parent) -{ - ao_app = p_ao_app; - court = p_court; - - setWindowTitle(tr("Case Announcer")); - resize(405, 235); - - ui_announcer_buttons = new QDialogButtonBox(this); - - QSizePolicy sizepolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); - sizepolicy.setHorizontalStretch(0); - sizepolicy.setVerticalStretch(0); - sizepolicy.setHeightForWidth(ui_announcer_buttons->sizePolicy().hasHeightForWidth()); - ui_announcer_buttons->setSizePolicy(sizepolicy); - ui_announcer_buttons->setOrientation(Qt::Horizontal); - ui_announcer_buttons->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); - - QObject::connect(ui_announcer_buttons, SIGNAL(accepted()), this, SLOT(ok_pressed())); - QObject::connect(ui_announcer_buttons, SIGNAL(rejected()), this, SLOT(cancel_pressed())); - - setUpdatesEnabled(false); - - ui_vbox_layout = new QVBoxLayout(this); - - ui_form_layout = new QFormLayout(this); - ui_form_layout->setLabelAlignment(Qt::AlignLeading | Qt::AlignLeft | Qt::AlignVCenter); - ui_form_layout->setFormAlignment(Qt::AlignLeading | Qt::AlignLeft | Qt::AlignTop); - ui_form_layout->setContentsMargins(6, 6, 6, 6); - - ui_vbox_layout->addItem(ui_form_layout); - ui_vbox_layout->addWidget(ui_announcer_buttons); - - ui_case_title_label = new QLabel(this); - ui_case_title_label->setText(tr("Case title:")); - - ui_form_layout->setWidget(0, QFormLayout::LabelRole, ui_case_title_label); - - ui_case_title_textbox = new QLineEdit(this); - ui_case_title_textbox->setMaxLength(50); - - ui_form_layout->setWidget(0, QFormLayout::FieldRole, ui_case_title_textbox); - - ui_defense_needed = new QCheckBox(this); - ui_defense_needed->setText(tr("Defense needed")); - ui_prosecutor_needed = new QCheckBox(this); - ui_prosecutor_needed->setText(tr("Prosecution needed")); - ui_judge_needed = new QCheckBox(this); - ui_judge_needed->setText(tr("Judge needed")); - ui_juror_needed = new QCheckBox(this); - ui_juror_needed->setText(tr("Jurors needed")); - ui_steno_needed = new QCheckBox(this); - ui_steno_needed->setText(tr("Stenographer needed")); - - ui_form_layout->setWidget(1, QFormLayout::FieldRole, ui_defense_needed); - ui_form_layout->setWidget(2, QFormLayout::FieldRole, ui_prosecutor_needed); - ui_form_layout->setWidget(3, QFormLayout::FieldRole, ui_judge_needed); - ui_form_layout->setWidget(4, QFormLayout::FieldRole, ui_juror_needed); - ui_form_layout->setWidget(5, QFormLayout::FieldRole, ui_steno_needed); - - setUpdatesEnabled(true); -} - -void AOCaseAnnouncerDialog::ok_pressed() -{ - court->announce_case(ui_case_title_textbox->text(), - ui_defense_needed->isChecked(), - ui_prosecutor_needed->isChecked(), - ui_judge_needed->isChecked(), - ui_juror_needed->isChecked(), - ui_steno_needed->isChecked()); - - done(0); -} - -void AOCaseAnnouncerDialog::cancel_pressed() -{ - done(0); -} diff --git a/aocaseannouncerdialog.h b/aocaseannouncerdialog.h deleted file mode 100644 index a238c3f2..00000000 --- a/aocaseannouncerdialog.h +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef AOCASEANNOUNCERDIALOG_H -#define AOCASEANNOUNCERDIALOG_H - -#include "aoapplication.h" -#include "courtroom.h" - -#include -#include -#include -#include -#include -#include -#include - -class AOCaseAnnouncerDialog : public QDialog -{ - Q_OBJECT - -public: - explicit AOCaseAnnouncerDialog(QWidget *parent = nullptr, AOApplication *p_ao_app = nullptr, Courtroom *p_court = nullptr); - -private: - AOApplication *ao_app; - Courtroom *court; - - QDialogButtonBox *ui_announcer_buttons; - - QVBoxLayout *ui_vbox_layout; - QFormLayout *ui_form_layout; - - QLabel *ui_case_title_label; - QLineEdit *ui_case_title_textbox; - - QCheckBox *ui_defense_needed; - QCheckBox *ui_prosecutor_needed; - QCheckBox *ui_judge_needed; - QCheckBox *ui_juror_needed; - QCheckBox *ui_steno_needed; - -public slots: - void ok_pressed(); - void cancel_pressed(); -}; - -#endif // AOCASEANNOUNCERDIALOG_H diff --git a/aocharbutton.cpp b/aocharbutton.cpp deleted file mode 100644 index 76610270..00000000 --- a/aocharbutton.cpp +++ /dev/null @@ -1,97 +0,0 @@ -#include "aocharbutton.h" - -#include "file_functions.h" - -AOCharButton::AOCharButton(QWidget *parent, AOApplication *p_ao_app, int x_pos, int y_pos, bool is_taken) : QPushButton(parent) -{ - m_parent = parent; - - ao_app = p_ao_app; - - taken = is_taken; - - this->resize(60, 60); - this->move(x_pos, y_pos); - - ui_taken = new AOImage(this, ao_app); - ui_taken->resize(60, 60); - ui_taken->set_image("char_taken.png"); - ui_taken->setAttribute(Qt::WA_TransparentForMouseEvents); - ui_taken->hide(); - - ui_passworded = new AOImage(this, ao_app); - 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->resize(62, 62); - ui_selector->move(x_pos - 1, y_pos - 1); - ui_selector->set_image("char_selector.png"); - ui_selector->setAttribute(Qt::WA_TransparentForMouseEvents); - ui_selector->hide(); -} - -void AOCharButton::reset() -{ - ui_taken->hide(); - ui_passworded->hide(); - ui_selector->hide(); -} - -void AOCharButton::set_taken(bool is_taken) -{ - taken = is_taken; -} - -void AOCharButton::apply_taken_image() -{ - if (taken) - { - ui_taken->move(0,0); - ui_taken->show(); - } - else - { - ui_taken->hide(); - } -} - -void AOCharButton::set_passworded() -{ - ui_passworded->show(); -} - -void AOCharButton::set_image(QString p_character) -{ - QString image_path = ao_app->get_character_path(p_character, "char_icon.png"); - - this->setText(""); - - if (file_exists(image_path)) - this->setStyleSheet("border-image:url(\"" + image_path + "\")"); - else - { - this->setStyleSheet("border-image:url()"); - this->setText(p_character); - } -} - -void AOCharButton::enterEvent(QEvent * e) -{ - ui_selector->move(this->x() - 1, this->y() - 1); - ui_selector->raise(); - ui_selector->show(); - - setFlat(false); - QPushButton::enterEvent(e); -} - -void AOCharButton::leaveEvent(QEvent * e) -{ - ui_selector->hide(); - QPushButton::leaveEvent(e); -} - - diff --git a/aocharbutton.h b/aocharbutton.h deleted file mode 100644 index f372cdf8..00000000 --- a/aocharbutton.h +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef AOCHARBUTTON_H -#define AOCHARBUTTON_H - -#include "aoapplication.h" -#include "aoimage.h" - -#include -#include -#include -#include - -class AOCharButton : public QPushButton -{ - Q_OBJECT - -public: - AOCharButton(QWidget *parent, AOApplication *p_ao_app, int x_pos, int y_pos, bool is_taken); - - AOApplication *ao_app; - - void refresh(); - void reset(); - void set_taken(bool is_taken); - void set_passworded(); - - void apply_taken_image(); - - void set_image(QString p_character); - -private: - bool taken; - - QWidget *m_parent; - - AOImage *ui_taken; - AOImage *ui_passworded; - AOImage *ui_selector; - -protected: - void enterEvent(QEvent *e); - void leaveEvent(QEvent *e); -}; - -#endif // AOCHARBUTTON_H diff --git a/aocharmovie.cpp b/aocharmovie.cpp deleted file mode 100644 index 57487233..00000000 --- a/aocharmovie.cpp +++ /dev/null @@ -1,195 +0,0 @@ -#include "aocharmovie.h" - -#include "misc_functions.h" -#include "file_functions.h" -#include "aoapplication.h" - -AOCharMovie::AOCharMovie(QWidget *p_parent, AOApplication *p_ao_app) : QLabel(p_parent) -{ - ao_app = p_ao_app; - - m_movie = new QMovie(this); - - preanim_timer = new QTimer(this); - preanim_timer->setSingleShot(true); - - connect(m_movie, SIGNAL(frameChanged(int)), this, SLOT(frame_change(int))); - connect(preanim_timer, SIGNAL(timeout()), this, SLOT(timer_done())); -} - -void AOCharMovie::play(QString p_char, QString p_emote, QString emote_prefix) -{ - QString original_path = ao_app->get_character_path(p_char, emote_prefix + p_emote + ".gif"); - QString alt_path = ao_app->get_character_path(p_char, p_emote + ".png"); - QString apng_path = ao_app->get_character_path(p_char, emote_prefix + p_emote + ".apng"); - QString placeholder_path = ao_app->get_theme_path("placeholder.gif"); - QString placeholder_default_path = ao_app->get_default_theme_path("placeholder.gif"); - QString gif_path; - - if (file_exists(apng_path)) - gif_path = apng_path; - else if (file_exists(original_path)) - gif_path = original_path; - else if (file_exists(alt_path)) - gif_path = alt_path; - else if (file_exists(placeholder_path)) - gif_path = placeholder_path; - else - gif_path = placeholder_default_path; - - m_movie->stop(); - m_movie->setFileName(gif_path); - - QImageReader *reader = new QImageReader(gif_path); - - movie_frames.clear(); - QImage f_image = reader->read(); - while (!f_image.isNull()) - { - if (m_flipped) - movie_frames.append(f_image.mirrored(true, false)); - else - movie_frames.append(f_image); - f_image = reader->read(); - } - - delete reader; - - this->show(); - m_movie->start(); -} - -void AOCharMovie::play_pre(QString p_char, QString p_emote, int duration) -{ - QString gif_path = ao_app->get_character_path(p_char, p_emote); - - m_movie->stop(); - this->clear(); - m_movie->setFileName(gif_path); - m_movie->jumpToFrame(0); - - int full_duration = duration * time_mod; - int real_duration = 0; - - play_once = false; - - for (int n_frame = 0 ; n_frame < m_movie->frameCount() ; ++n_frame) - { - real_duration += m_movie->nextFrameDelay(); - m_movie->jumpToFrame(n_frame + 1); - } - -#ifdef DEBUG_GIF - qDebug() << "full_duration: " << full_duration; - qDebug() << "real_duration: " << real_duration; -#endif - - double percentage_modifier = 100.0; - - if (real_duration != 0 && duration != 0) - { - double modifier = full_duration / static_cast(real_duration); - percentage_modifier = 100 / modifier; - - if (percentage_modifier > 100.0) - percentage_modifier = 100.0; - } - -#ifdef DEBUG_GIF - qDebug() << "% mod: " << percentage_modifier; -#endif - - if (full_duration == 0 || full_duration >= real_duration) - { - play_once = true; - } - else - { - play_once = false; - preanim_timer->start(full_duration); - } - - - m_movie->setSpeed(static_cast(percentage_modifier)); - play(p_char, p_emote, ""); -} - -void AOCharMovie::play_talking(QString p_char, QString p_emote) -{ - QString gif_path = ao_app->get_character_path(p_char, "(b)" + p_emote); - - m_movie->stop(); - this->clear(); - m_movie->setFileName(gif_path); - - play_once = false; - m_movie->setSpeed(100); - play(p_char, p_emote, "(b)"); -} - -void AOCharMovie::play_idle(QString p_char, QString p_emote) -{ - QString gif_path = ao_app->get_character_path(p_char, "(a)" + p_emote); - - m_movie->stop(); - this->clear(); - m_movie->setFileName(gif_path); - - play_once = false; - m_movie->setSpeed(100); - play(p_char, p_emote, "(a)"); -} - -void AOCharMovie::stop() -{ - //for all intents and purposes, stopping is the same as hiding. at no point do we want a frozen gif to display - m_movie->stop(); - preanim_timer->stop(); - this->hide(); -} - -void AOCharMovie::combo_resize(int w, int h) -{ - QSize f_size(w, h); - this->resize(f_size); - m_movie->setScaledSize(f_size); -} - -void AOCharMovie::move(int ax, int ay) -{ - x = ax; - y = ay; - QLabel::move(x, y); -} - -void AOCharMovie::frame_change(int n_frame) -{ - - if (movie_frames.size() > n_frame) - { - QPixmap f_pixmap = QPixmap::fromImage(movie_frames.at(n_frame)); - auto aspect_ratio = Qt::KeepAspectRatio; - - if (f_pixmap.size().width() > f_pixmap.size().height()) - aspect_ratio = Qt::KeepAspectRatioByExpanding; - - if (f_pixmap.size().width() > this->size().width() || f_pixmap.size().height() > this->size().height()) - this->setPixmap(f_pixmap.scaled(this->width(), this->height(), aspect_ratio, Qt::SmoothTransformation)); - else - this->setPixmap(f_pixmap.scaled(this->width(), this->height(), aspect_ratio, Qt::FastTransformation)); - - QLabel::move(x + (this->width() - this->pixmap()->width())/2, y); - } - - if (m_movie->frameCount() - 1 == n_frame && play_once) - { - preanim_timer->start(m_movie->nextFrameDelay()); - m_movie->stop(); - } -} - -void AOCharMovie::timer_done() -{ - - done(); -} diff --git a/aocharmovie.h b/aocharmovie.h deleted file mode 100644 index 7ef7da3f..00000000 --- a/aocharmovie.h +++ /dev/null @@ -1,57 +0,0 @@ -#ifndef AOCHARMOVIE_H -#define AOCHARMOVIE_H - -#include -#include -#include -#include -#include - -class AOApplication; - -class AOCharMovie : public QLabel -{ - Q_OBJECT - -public: - AOCharMovie(QWidget *p_parent, AOApplication *p_ao_app); - - void play(QString p_char, QString p_emote, QString emote_prefix); - void play_pre(QString p_char, QString p_emote, int duration); - void play_talking(QString p_char, QString p_emote); - void play_idle(QString p_char, QString p_emote); - - void set_flipped(bool p_flipped) {m_flipped = p_flipped;} - - void stop(); - - void move(int ax, int ay); - - void combo_resize(int w, int h); - -private: - AOApplication *ao_app; - - QMovie *m_movie; - QVector movie_frames; - QTimer *preanim_timer; - - const int time_mod = 62; - - // These are the X and Y values before they are fixed based on the sprite's width. - int x = 0; - int y = 0; - - bool m_flipped = false; - - bool play_once = true; - -signals: - void done(); - -private slots: - void frame_change(int n_frame); - void timer_done(); -}; - -#endif // AOCHARMOVIE_H diff --git a/aoemotebutton.cpp b/aoemotebutton.cpp deleted file mode 100644 index 9c1d3889..00000000 --- a/aoemotebutton.cpp +++ /dev/null @@ -1,36 +0,0 @@ -#include "aoemotebutton.h" - -#include "file_functions.h" - -AOEmoteButton::AOEmoteButton(QWidget *p_parent, AOApplication *p_ao_app, int p_x, int p_y) : QPushButton(p_parent) -{ - parent = p_parent; - ao_app = p_ao_app; - - this->move(p_x, p_y); - this->resize(40, 40); - - connect(this, SIGNAL(clicked()), this, SLOT(on_clicked())); -} - -void AOEmoteButton::set_image(QString p_char, int p_emote, QString suffix) -{ - QString emotion_number = QString::number(p_emote + 1); - QString image_path = ao_app->get_character_path(p_char, "emotions/button" + emotion_number + suffix); - - if (file_exists(image_path)) - { - this->setText(""); - this->setStyleSheet("border-image:url(\"" + image_path + "\")"); - } - else - { - this->setText(ao_app->get_emote_comment(p_char, p_emote)); - this->setStyleSheet("border-image:url(\"\")"); - } -} - -void AOEmoteButton::on_clicked() -{ - emote_clicked(m_id); -} diff --git a/aoemotebutton.h b/aoemotebutton.h deleted file mode 100644 index c99a73b0..00000000 --- a/aoemotebutton.h +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef AOEMOTEBUTTON_H -#define AOEMOTEBUTTON_H - -#include "aoapplication.h" - -#include -#include - -class AOEmoteButton : public QPushButton -{ - Q_OBJECT - -public: - AOEmoteButton(QWidget *p_parent, AOApplication *p_ao_app, int p_x, int p_y); - - //void set_on(QString p_char, int p_emote); - //void set_off(QString p_char, int p_emote); - void set_image(QString p_char, int p_emote, QString suffix); - - void set_id(int p_id) {m_id = p_id;} - int get_id() {return m_id;} - -private: - QWidget *parent; - AOApplication *ao_app; - - int m_id = 0; - -signals: - void emote_clicked(int p_id); - -private slots: - void on_clicked(); -}; - -#endif // AOEMOTEBUTTON_H diff --git a/aoevidencebutton.cpp b/aoevidencebutton.cpp deleted file mode 100644 index 924aeb88..00000000 --- a/aoevidencebutton.cpp +++ /dev/null @@ -1,119 +0,0 @@ -#include "aoevidencebutton.h" - -#include "file_functions.h" - -AOEvidenceButton::AOEvidenceButton(QWidget *p_parent, AOApplication *p_ao_app, int p_x, int p_y) : QPushButton(p_parent) -{ - ao_app = p_ao_app; - m_parent = p_parent; - - ui_selected = new AOImage(p_parent, ao_app); - ui_selected->resize(70, 70); - ui_selected->move(p_x, p_y); - ui_selected->set_image("evidence_selected.png"); - ui_selected->setAttribute(Qt::WA_TransparentForMouseEvents); - ui_selected->hide(); - - ui_selector = new AOImage(p_parent, ao_app); - ui_selector->resize(71, 71); - ui_selector->move(p_x - 1, p_y - 1); - ui_selector->set_image("evidence_selector.png"); - ui_selector->setAttribute(Qt::WA_TransparentForMouseEvents); - ui_selector->hide(); - - this->move(p_x, p_y); - this->resize(70, 70); - this->setAcceptDrops(true); - - connect(this, SIGNAL(clicked()), this, SLOT(on_clicked())); -} - -void AOEvidenceButton::reset() -{ - this->hide(); - ui_selected->hide(); - ui_selector->hide(); -} - -void AOEvidenceButton::set_image(QString p_image) -{ - QString image_path = ao_app->get_evidence_path(p_image); - - if (file_exists(image_path)) - { - this->setText(""); - this->setStyleSheet("border-image:url(\"" + image_path + "\")"); - } - else - { - this->setText(p_image); - this->setStyleSheet(""); - } -} - -void AOEvidenceButton::set_theme_image(QString p_image) -{ - QString theme_image_path = ao_app->get_theme_path(p_image); - QString default_image_path = ao_app->get_default_theme_path(p_image); - - QString final_image_path; - - if (file_exists(theme_image_path)) - final_image_path = theme_image_path; - else - final_image_path = default_image_path; - - this->setText(""); - this->setStyleSheet("border-image:url(\"" + final_image_path + "\")"); -} - -void AOEvidenceButton::set_selected(bool p_selected) -{ - if (p_selected) - ui_selected->show(); - else - ui_selected->hide(); -} - -void AOEvidenceButton::on_clicked() -{ - evidence_clicked(m_id); -} - -void AOEvidenceButton::mouseDoubleClickEvent(QMouseEvent *e) -{ - QPushButton::mouseDoubleClickEvent(e); - evidence_double_clicked(m_id); -} - -void AOEvidenceButton::dragLeaveEvent(QMouseEvent *e) -{ - //QWidget::dragLeaveEvent(e); - - qDebug() << "drag leave event"; -} - -void AOEvidenceButton::dragEnterEvent(QMouseEvent *e) -{ - //QWidget::dragEnterEvent(e); - - qDebug() << "drag enter event"; -} - -void AOEvidenceButton::enterEvent(QEvent * e) -{ - ui_selector->show(); - - on_hover(m_id, true); - - setFlat(false); - QPushButton::enterEvent(e); -} - -void AOEvidenceButton::leaveEvent(QEvent * e) -{ - ui_selector->hide(); - - on_hover(m_id, false); - QPushButton::leaveEvent(e); -} diff --git a/aoevidencebutton.h b/aoevidencebutton.h deleted file mode 100644 index 27fb84b3..00000000 --- a/aoevidencebutton.h +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef AOEVIDENCEBUTTON_H -#define AOEVIDENCEBUTTON_H - -#include "aoapplication.h" -#include "aoimage.h" - -#include -#include -#include - -class AOEvidenceButton : public QPushButton -{ - Q_OBJECT - -public: - AOEvidenceButton(QWidget *p_parent, AOApplication *p_ao_app, int p_x, int p_y); - - void reset(); - void set_image(QString p_image); - void set_theme_image(QString p_image); - void set_id(int p_id) {m_id = p_id;} - - void set_selected(bool p_selected); - -private: - AOApplication *ao_app; - QWidget *m_parent; - - AOImage *ui_selected; - AOImage *ui_selector; - - int m_id = 0; - -protected: - void enterEvent(QEvent *e); - void leaveEvent(QEvent *e); - void mouseDoubleClickEvent(QMouseEvent *e); - void dragLeaveEvent(QMouseEvent *e); - void dragEnterEvent(QMouseEvent *e); - -signals: - void evidence_clicked(int p_id); - void evidence_double_clicked(int p_id); - void on_hover(int p_id, bool p_state); - -private slots: - void on_clicked(); -}; - -#endif // AOEVIDENCEBUTTON_H diff --git a/aoevidencedisplay.cpp b/aoevidencedisplay.cpp deleted file mode 100644 index 9ec105dd..00000000 --- a/aoevidencedisplay.cpp +++ /dev/null @@ -1,96 +0,0 @@ -#include "aoevidencedisplay.h" - -#include "file_functions.h" -#include "datatypes.h" -#include "misc_functions.h" - -AOEvidenceDisplay::AOEvidenceDisplay(QWidget *p_parent, AOApplication *p_ao_app) : QLabel(p_parent) -{ - ao_app = p_ao_app; - - evidence_movie = new QMovie(this); - evidence_icon = new QLabel(this); - sfx_player = new AOSfxPlayer(this, ao_app); - - connect(evidence_movie, SIGNAL(frameChanged(int)), this, SLOT(frame_change(int))); -} - -void AOEvidenceDisplay::show_evidence(QString p_evidence_image, bool is_left_side, int p_volume) -{ - this->reset(); - - sfx_player->set_volume(p_volume); - - QString f_evidence_path = ao_app->get_evidence_path(p_evidence_image); - - QPixmap f_pixmap(f_evidence_path); - - QString final_gif_path; - QString gif_name; - QString icon_identifier; - - if (is_left_side) - { - icon_identifier = "left_evidence_icon"; - gif_name = "evidence_appear_left.gif"; - } - else - { - icon_identifier = "right_evidence_icon"; - gif_name = "evidence_appear_right.gif"; - } - - pos_size_type icon_dimensions = ao_app->get_element_dimensions(icon_identifier, "courtroom_design.ini"); - - evidence_icon->move(icon_dimensions.x, icon_dimensions.y); - evidence_icon->resize(icon_dimensions.width, icon_dimensions.height); - - evidence_icon->setPixmap(f_pixmap.scaled(evidence_icon->width(), evidence_icon->height(), Qt::IgnoreAspectRatio)); - - QString f_default_gif_path = ao_app->get_default_theme_path(gif_name); - QString f_gif_path = ao_app->get_theme_path(gif_name); - - if (file_exists(f_gif_path)) - final_gif_path = f_gif_path; - else - final_gif_path = f_default_gif_path; - - evidence_movie->setFileName(final_gif_path); - - if(evidence_movie->frameCount() < 1) - return; - - this->setMovie(evidence_movie); - - evidence_movie->start(); - sfx_player->play(ao_app->get_sfx("evidence_present")); -} - -void AOEvidenceDisplay::frame_change(int p_frame) -{ - if (p_frame == (evidence_movie->frameCount() - 1)) - { - //we need this or else the last frame wont show - delay(evidence_movie->nextFrameDelay()); - - evidence_movie->stop(); - this->clear(); - - evidence_icon->show(); - } -} - -void AOEvidenceDisplay::reset() -{ - sfx_player->stop(); - evidence_movie->stop(); - evidence_icon->hide(); - this->clear(); -} - -QLabel* AOEvidenceDisplay::get_evidence_icon() -{ - return evidence_icon; -} - - diff --git a/aoevidencedisplay.h b/aoevidencedisplay.h deleted file mode 100644 index 13ca00d5..00000000 --- a/aoevidencedisplay.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef AOEVIDENCEDISPLAY_H -#define AOEVIDENCEDISPLAY_H - -#include "aoapplication.h" -#include "aosfxplayer.h" - -#include -#include -#include - -class AOEvidenceDisplay : public QLabel -{ - Q_OBJECT - -public: - AOEvidenceDisplay(QWidget *p_parent, AOApplication *p_ao_app); - - void show_evidence(QString p_evidence_image, bool is_left_side, int p_volume); - QLabel* get_evidence_icon(); - void reset(); - -private: - AOApplication *ao_app; - QMovie *evidence_movie; - QLabel *evidence_icon; - AOSfxPlayer *sfx_player; - -private slots: - void frame_change(int p_frame); -}; - -#endif // AOEVIDENCEDISPLAY_H diff --git a/aoimage.cpp b/aoimage.cpp deleted file mode 100644 index 7bb56bb6..00000000 --- a/aoimage.cpp +++ /dev/null @@ -1,47 +0,0 @@ -#include "file_functions.h" - -#include "aoimage.h" - -AOImage::AOImage(QWidget *parent, AOApplication *p_ao_app) : QLabel(parent) -{ - m_parent = parent; - ao_app = p_ao_app; -} - -AOImage::~AOImage() -{ - -} - -void AOImage::set_image(QString p_image) -{ - QString theme_image_path = ao_app->get_theme_path(p_image); - QString default_image_path = ao_app->get_default_theme_path(p_image); - - QString final_image_path; - - if (file_exists(theme_image_path)) - final_image_path = theme_image_path; - else - final_image_path = default_image_path; - - QPixmap f_pixmap(final_image_path); - - this->setPixmap(f_pixmap.scaled(this->width(), this->height(), Qt::IgnoreAspectRatio)); -} - -void AOImage::set_image_from_path(QString p_path) -{ - QString default_path = ao_app->get_default_theme_path("chatmed.png"); - - QString final_path; - - if (file_exists(p_path)) - final_path = p_path; - else - final_path = default_path; - - QPixmap f_pixmap(final_path); - - this->setPixmap(f_pixmap.scaled(this->width(), this->height(), Qt::IgnoreAspectRatio)); -} diff --git a/aoimage.h b/aoimage.h deleted file mode 100644 index 4713be0a..00000000 --- a/aoimage.h +++ /dev/null @@ -1,25 +0,0 @@ -//This class represents a static theme-dependent image - -#ifndef AOIMAGE_H -#define AOIMAGE_H - -#include "aoapplication.h" - -#include -#include - -class AOImage : public QLabel -{ -public: - AOImage(QWidget *parent, AOApplication *p_ao_app); - ~AOImage(); - - QWidget *m_parent; - AOApplication *ao_app; - - void set_image(QString p_image); - void set_image_from_path(QString p_path); - void set_size_and_pos(QString identifier); -}; - -#endif // AOIMAGE_H diff --git a/aolineedit.cpp b/aolineedit.cpp deleted file mode 100644 index f6026e14..00000000 --- a/aolineedit.cpp +++ /dev/null @@ -1,21 +0,0 @@ -#include "aolineedit.h" - -AOLineEdit::AOLineEdit(QWidget *parent) : QLineEdit(parent) -{ - this->setReadOnly(true); - this->setFrame(false); - - connect(this, SIGNAL(returnPressed()), this, SLOT(on_enter_pressed())); -} - -void AOLineEdit::mouseDoubleClickEvent(QMouseEvent *e) -{ - QLineEdit::mouseDoubleClickEvent(e); - - this->setReadOnly(false); -} - -void AOLineEdit::on_enter_pressed() -{ - this->setReadOnly(true); -} diff --git a/aolineedit.h b/aolineedit.h deleted file mode 100644 index ce17680d..00000000 --- a/aolineedit.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef AOLINEEDIT_H -#define AOLINEEDIT_H - -#include -#include - -class AOLineEdit : public QLineEdit -{ - Q_OBJECT - -public: - AOLineEdit(QWidget *parent); - -protected: - void mouseDoubleClickEvent(QMouseEvent *e); - -signals: - void double_clicked(); - -private slots: - void on_enter_pressed(); - - -}; - -#endif // AOLINEEDIT_H diff --git a/aomovie.cpp b/aomovie.cpp deleted file mode 100644 index edf5bdb0..00000000 --- a/aomovie.cpp +++ /dev/null @@ -1,90 +0,0 @@ -#include "aomovie.h" - -#include "file_functions.h" -#include "courtroom.h" -#include "misc_functions.h" - -AOMovie::AOMovie(QWidget *p_parent, AOApplication *p_ao_app) : QLabel(p_parent) -{ - ao_app = p_ao_app; - - m_movie = new QMovie(); - - this->setMovie(m_movie); - - connect(m_movie, SIGNAL(frameChanged(int)), this, SLOT(frame_change(int))); -} - -void AOMovie::set_play_once(bool p_play_once) -{ - play_once = p_play_once; -} - -void AOMovie::play(QString p_gif, QString p_char, QString p_custom_theme) -{ - m_movie->stop(); - - QString gif_path; - - QString custom_path; - if (p_gif == "custom") - custom_path = ao_app->get_image_suffix(ao_app->get_character_path(p_char, p_gif)); - else - custom_path = ao_app->get_image_suffix(ao_app->get_character_path(p_char, p_gif + "_bubble")); - - QString misc_path = ao_app->get_base_path() + "misc/" + p_custom_theme + "/" + p_gif + "_bubble.gif"; - QString custom_theme_path = ao_app->get_custom_theme_path(p_custom_theme, p_gif + ".gif"); - QString theme_path = ao_app->get_theme_path(p_gif + ".gif"); - QString default_theme_path = ao_app->get_default_theme_path(p_gif + ".gif"); - QString placeholder_path = ao_app->get_theme_path("placeholder.gif"); - QString default_placeholder_path = ao_app->get_default_theme_path("placeholder.gif"); - - if (file_exists(custom_path)) - gif_path = custom_path; - else if (file_exists(misc_path)) - gif_path = misc_path; - else if (file_exists(custom_theme_path)) - gif_path = custom_theme_path; - else if (file_exists(theme_path)) - gif_path = theme_path; - else if (file_exists(default_theme_path)) - gif_path = default_theme_path; - else if (file_exists(placeholder_path)) - gif_path = placeholder_path; - else if (file_exists(default_placeholder_path)) - gif_path = default_placeholder_path; - else - gif_path = ""; - - m_movie->setFileName(gif_path); - - this->show(); - m_movie->start(); -} - -void AOMovie::stop() -{ - m_movie->stop(); - this->hide(); -} - -void AOMovie::frame_change(int n_frame) -{ - if (n_frame == (m_movie->frameCount() - 1) && play_once) - { - //we need this or else the last frame wont show - delay(m_movie->nextFrameDelay()); - - this->stop(); - - //signal connected to courtroom object, let it figure out what to do - done(); - } -} - -void AOMovie::combo_resize(int w, int h) -{ - QSize f_size(w, h); - this->resize(f_size); - m_movie->setScaledSize(f_size); -} diff --git a/aomovie.h b/aomovie.h deleted file mode 100644 index 1f278bf8..00000000 --- a/aomovie.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef AOMOVIE_H -#define AOMOVIE_H - -#include -#include - -class Courtroom; -class AOApplication; - -class AOMovie : public QLabel -{ - Q_OBJECT - -public: - AOMovie(QWidget *p_parent, AOApplication *p_ao_app); - - void set_play_once(bool p_play_once); - void play(QString p_gif, QString p_char = "", QString p_custom_theme = ""); - void combo_resize(int w, int h); - void stop(); - -private: - QMovie *m_movie; - AOApplication *ao_app; - bool play_once = true; - -signals: - void done(); - -private slots: - void frame_change(int n_frame); -}; - -#endif // AOMOVIE_H diff --git a/aomusicplayer.cpp b/aomusicplayer.cpp deleted file mode 100644 index 997d82d8..00000000 --- a/aomusicplayer.cpp +++ /dev/null @@ -1,34 +0,0 @@ -#include "aomusicplayer.h" - -AOMusicPlayer::AOMusicPlayer(QWidget *parent, AOApplication *p_ao_app) -{ - m_parent = parent; - ao_app = p_ao_app; -} - -AOMusicPlayer::~AOMusicPlayer() -{ - BASS_ChannelStop(m_stream); -} - -void AOMusicPlayer::play(QString p_song) -{ - BASS_ChannelStop(m_stream); - - QString f_path = ao_app->get_music_path(p_song); - - m_stream = BASS_StreamCreateFile(FALSE, f_path.utf16(), 0, 0, BASS_STREAM_AUTOFREE | BASS_UNICODE | BASS_ASYNCFILE); - - this->set_volume(m_volume); - - if (ao_app->get_audio_output_device() != "default") - BASS_ChannelSetDevice(m_stream, BASS_GetDevice()); - BASS_ChannelPlay(m_stream, false); -} - -void AOMusicPlayer::set_volume(int p_value) -{ - m_volume = p_value; - float volume = m_volume / 100.0f; - BASS_ChannelSetAttribute(m_stream, BASS_ATTRIB_VOL, volume); -} diff --git a/aomusicplayer.h b/aomusicplayer.h deleted file mode 100644 index 560a7f90..00000000 --- a/aomusicplayer.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef AOMUSICPLAYER_H -#define AOMUSICPLAYER_H - -#include "bass.h" -#include "aoapplication.h" - -#include -#include -#include - -class AOMusicPlayer -{ -public: - AOMusicPlayer(QWidget *parent, AOApplication *p_ao_app); - ~AOMusicPlayer(); - - void play(QString p_song); - void set_volume(int p_value); - -private: - QWidget *m_parent; - AOApplication *ao_app; - - int m_volume = 0; - HSTREAM m_stream; -}; - -#endif // AOMUSICPLAYER_H diff --git a/aooptionsdialog.cpp b/aooptionsdialog.cpp deleted file mode 100644 index 2b8259f5..00000000 --- a/aooptionsdialog.cpp +++ /dev/null @@ -1,517 +0,0 @@ -#include "aooptionsdialog.h" -#include "aoapplication.h" -#include "bass.h" - -AOOptionsDialog::AOOptionsDialog(QWidget *parent, AOApplication *p_ao_app) : QDialog(parent) -{ - ao_app = p_ao_app; - - // Setting up the basics. - // setAttribute(Qt::WA_DeleteOnClose); - setWindowTitle(tr("Settings")); - resize(398, 320); - - ui_settings_buttons = new QDialogButtonBox(this); - - QSizePolicy sizePolicy1(QSizePolicy::Expanding, QSizePolicy::Fixed); - sizePolicy1.setHorizontalStretch(0); - sizePolicy1.setVerticalStretch(0); - sizePolicy1.setHeightForWidth(ui_settings_buttons->sizePolicy().hasHeightForWidth()); - ui_settings_buttons->setSizePolicy(sizePolicy1); - ui_settings_buttons->setOrientation(Qt::Horizontal); - ui_settings_buttons->setStandardButtons(QDialogButtonBox::Cancel | QDialogButtonBox::Save); - - QObject::connect(ui_settings_buttons, SIGNAL(accepted()), this, SLOT(save_pressed())); - QObject::connect(ui_settings_buttons, SIGNAL(rejected()), this, SLOT(discard_pressed())); - - // We'll stop updates so that the window won't flicker while it's being made. - setUpdatesEnabled(false); - - // First of all, we want a tabbed dialog, so let's add some layout. - ui_vertical_layout = new QVBoxLayout(this); - ui_settings_tabs = new QTabWidget(this); - - ui_vertical_layout->addWidget(ui_settings_tabs); - ui_vertical_layout->addWidget(ui_settings_buttons); - - // Let's add the tabs one by one. - // First, we'll start with 'Gameplay'. - ui_gameplay_tab = new QWidget(); - ui_settings_tabs->addTab(ui_gameplay_tab, tr("Gameplay")); - - ui_form_layout_widget = new QWidget(ui_gameplay_tab); - ui_form_layout_widget->setGeometry(QRect(10, 10, 361, 211)); - - ui_gameplay_form = new QFormLayout(ui_form_layout_widget); - ui_gameplay_form->setLabelAlignment(Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter); - ui_gameplay_form->setFormAlignment(Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop); - ui_gameplay_form->setContentsMargins(0, 0, 0, 0); - - ui_theme_label = new QLabel(ui_form_layout_widget); - ui_theme_label->setText(tr("Theme:")); - ui_theme_label->setToolTip(tr("Sets the theme used in-game. If the new theme changes " - "the lobby's look as well, you'll need to reload the " - "lobby for the changes to take effect, such as by joining " - "a server and leaving it.")); - ui_gameplay_form->setWidget(0, QFormLayout::LabelRole, ui_theme_label); - - ui_theme_combobox = new QComboBox(ui_form_layout_widget); - - // Fill the combobox with the names of the themes. - QDirIterator it(p_ao_app->get_base_path() + "themes", QDir::Dirs, QDirIterator::NoIteratorFlags); - while (it.hasNext()) - { - QString actualname = QDir(it.next()).dirName(); - if (actualname != "." && actualname != "..") - ui_theme_combobox->addItem(actualname); - if (actualname == p_ao_app->read_theme()) - ui_theme_combobox->setCurrentIndex(ui_theme_combobox->count()-1); - } - - ui_gameplay_form->setWidget(0, QFormLayout::FieldRole, ui_theme_combobox); - - ui_theme_log_divider = new QFrame(ui_form_layout_widget); - ui_theme_log_divider->setMidLineWidth(0); - ui_theme_log_divider->setFrameShape(QFrame::HLine); - ui_theme_log_divider->setFrameShadow(QFrame::Sunken); - - ui_gameplay_form->setWidget(1, QFormLayout::FieldRole, ui_theme_log_divider); - - ui_downwards_lbl = new QLabel(ui_form_layout_widget); - ui_downwards_lbl->setText(tr("Log goes downwards:")); - ui_downwards_lbl->setToolTip(tr("If ticked, new messages will appear at " - "the bottom (like the OOC chatlog). The traditional " - "(AO1) behaviour is equivalent to this being unticked.")); - - ui_gameplay_form->setWidget(2, QFormLayout::LabelRole, ui_downwards_lbl); - - ui_downwards_cb = new QCheckBox(ui_form_layout_widget); - ui_downwards_cb->setChecked(p_ao_app->get_log_goes_downwards()); - - ui_gameplay_form->setWidget(2, QFormLayout::FieldRole, ui_downwards_cb); - - ui_length_lbl = new QLabel(ui_form_layout_widget); - ui_length_lbl->setText(tr("Log length:")); - ui_length_lbl->setToolTip(tr("The amount of messages the IC chatlog will keep before " - "deleting older messages. A value of 0 or below counts as 'infinite'.")); - - ui_gameplay_form->setWidget(3, QFormLayout::LabelRole, ui_length_lbl); - - ui_length_spinbox = new QSpinBox(ui_form_layout_widget); - ui_length_spinbox->setMaximum(10000); - ui_length_spinbox->setValue(p_ao_app->get_max_log_size()); - - ui_gameplay_form->setWidget(3, QFormLayout::FieldRole, ui_length_spinbox); - - ui_log_names_divider = new QFrame(ui_form_layout_widget); - ui_log_names_divider->setFrameShape(QFrame::HLine); - ui_log_names_divider->setFrameShadow(QFrame::Sunken); - - ui_gameplay_form->setWidget(4, QFormLayout::FieldRole, ui_log_names_divider); - - ui_username_lbl = new QLabel(ui_form_layout_widget); - ui_username_lbl->setText(tr("Default username:")); - ui_username_lbl->setToolTip(tr("Your OOC name will be automatically set to this value " - "when you join a server.")); - - ui_gameplay_form->setWidget(5, QFormLayout::LabelRole, ui_username_lbl); - - ui_username_textbox = new QLineEdit(ui_form_layout_widget); - ui_username_textbox->setMaxLength(30); - ui_username_textbox->setText(p_ao_app->get_default_username()); - - ui_gameplay_form->setWidget(5, QFormLayout::FieldRole, ui_username_textbox); - - ui_showname_lbl = new QLabel(ui_form_layout_widget); - ui_showname_lbl->setText(tr("Custom shownames:")); - ui_showname_lbl->setToolTip(tr("Gives the default value for the in-game 'Custom shownames' " - "tickbox, which in turn determines whether the client should " - "display custom in-character names.")); - - ui_gameplay_form->setWidget(6, QFormLayout::LabelRole, ui_showname_lbl); - - ui_showname_cb = new QCheckBox(ui_form_layout_widget); - ui_showname_cb->setChecked(p_ao_app->get_showname_enabled_by_default()); - - ui_gameplay_form->setWidget(6, QFormLayout::FieldRole, ui_showname_cb); - - ui_net_divider = new QFrame(ui_form_layout_widget); - ui_net_divider->setFrameShape(QFrame::HLine); - ui_net_divider->setFrameShadow(QFrame::Sunken); - - ui_gameplay_form->setWidget(7, QFormLayout::FieldRole, ui_net_divider); - - ui_ms_lbl = new QLabel(ui_form_layout_widget); - ui_ms_lbl->setText(tr("Backup MS:")); - ui_ms_lbl->setToolTip(tr("If the built-in server lookups fail, the game will try the " - "address given here and use it as a backup master server address.")); - - ui_gameplay_form->setWidget(8, QFormLayout::LabelRole, ui_ms_lbl); - - QSettings* configini = ao_app->configini; - ui_ms_textbox = new QLineEdit(ui_form_layout_widget); - ui_ms_textbox->setText(configini->value("master", "").value()); - - ui_gameplay_form->setWidget(8, QFormLayout::FieldRole, ui_ms_textbox); - - ui_discord_lbl = new QLabel(ui_form_layout_widget); - ui_discord_lbl->setText(tr("Discord:")); - ui_discord_lbl->setToolTip(tr("Allows others on Discord to see what server you are in, " - "what character are you playing, and how long you have " - "been playing for.")); - - ui_gameplay_form->setWidget(9, QFormLayout::LabelRole, ui_discord_lbl); - - ui_discord_cb = new QCheckBox(ui_form_layout_widget); - ui_discord_cb->setChecked(ao_app->is_discord_enabled()); - - ui_gameplay_form->setWidget(9, QFormLayout::FieldRole, ui_discord_cb); - - // Here we start the callwords tab. - ui_callwords_tab = new QWidget(); - ui_settings_tabs->addTab(ui_callwords_tab, tr("Callwords")); - - ui_callwords_widget = new QWidget(ui_callwords_tab); - ui_callwords_widget->setGeometry(QRect(10, 10, 361, 211)); - - ui_callwords_layout = new QVBoxLayout(ui_callwords_widget); - ui_callwords_layout->setContentsMargins(0,0,0,0); - - ui_callwords_textbox = new QPlainTextEdit(ui_callwords_widget); - QSizePolicy sizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - sizePolicy.setHorizontalStretch(0); - sizePolicy.setVerticalStretch(0); - sizePolicy.setHeightForWidth(ui_callwords_textbox->sizePolicy().hasHeightForWidth()); - ui_callwords_textbox->setSizePolicy(sizePolicy); - - // Let's fill the callwords text edit with the already present callwords. - ui_callwords_textbox->document()->clear(); - foreach (QString callword, p_ao_app->get_call_words()) { - ui_callwords_textbox->appendPlainText(callword); - } - - ui_callwords_layout->addWidget(ui_callwords_textbox); - - ui_callwords_explain_lbl = new QLabel(ui_callwords_widget); - ui_callwords_explain_lbl->setWordWrap(true); - ui_callwords_explain_lbl->setText(tr("Enter as many callwords as you would like. These are case insensitive. Make sure to leave every callword in its own line!
Do not leave a line with a space at the end -- you will be alerted everytime someone uses a space in their messages.")); - - ui_callwords_layout->addWidget(ui_callwords_explain_lbl); - - // The audio tab. - ui_audio_tab = new QWidget(); - ui_settings_tabs->addTab(ui_audio_tab, tr("Audio")); - - ui_audio_widget = new QWidget(ui_audio_tab); - ui_audio_widget->setGeometry(QRect(10, 10, 361, 211)); - - ui_audio_layout = new QFormLayout(ui_audio_widget); - ui_audio_layout->setLabelAlignment(Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter); - ui_audio_layout->setFormAlignment(Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop); - ui_audio_layout->setContentsMargins(0, 0, 0, 0); - - ui_audio_device_lbl = new QLabel(ui_audio_widget); - ui_audio_device_lbl->setText(tr("Audio device:")); - ui_audio_device_lbl->setToolTip(tr("Sets the audio device for all sounds.")); - - ui_audio_layout->setWidget(0, QFormLayout::LabelRole, ui_audio_device_lbl); - - ui_audio_device_combobox = new QComboBox(ui_audio_widget); - - // Let's fill out the combobox with the available audio devices. - int a = 0; - BASS_DEVICEINFO info; - - if (needs_default_audiodev()) - { - ui_audio_device_combobox->addItem("default"); - } - - for (a = 0; BASS_GetDeviceInfo(a, &info); a++) - { - ui_audio_device_combobox->addItem(info.name); - if (p_ao_app->get_audio_output_device() == info.name) - ui_audio_device_combobox->setCurrentIndex(ui_audio_device_combobox->count()-1); - } - - ui_audio_layout->setWidget(0, QFormLayout::FieldRole, ui_audio_device_combobox); - - ui_audio_volume_divider = new QFrame(ui_audio_widget); - ui_audio_volume_divider->setFrameShape(QFrame::HLine); - ui_audio_volume_divider->setFrameShadow(QFrame::Sunken); - - ui_audio_layout->setWidget(1, QFormLayout::FieldRole, ui_audio_volume_divider); - - ui_music_volume_lbl = new QLabel(ui_audio_widget); - ui_music_volume_lbl->setText(tr("Music:")); - ui_music_volume_lbl->setToolTip(tr("Sets the music's default volume.")); - - ui_audio_layout->setWidget(2, QFormLayout::LabelRole, ui_music_volume_lbl); - - ui_music_volume_spinbox = new QSpinBox(ui_audio_widget); - ui_music_volume_spinbox->setValue(p_ao_app->get_default_music()); - ui_music_volume_spinbox->setMaximum(100); - ui_music_volume_spinbox->setSuffix("%"); - - ui_audio_layout->setWidget(2, QFormLayout::FieldRole, ui_music_volume_spinbox); - - ui_sfx_volume_lbl = new QLabel(ui_audio_widget); - ui_sfx_volume_lbl->setText(tr("SFX:")); - ui_sfx_volume_lbl->setToolTip(tr("Sets the SFX's default volume. " - "Interjections and actual sound effects count as 'SFX'.")); - - ui_audio_layout->setWidget(3, QFormLayout::LabelRole, ui_sfx_volume_lbl); - - ui_sfx_volume_spinbox = new QSpinBox(ui_audio_widget); - ui_sfx_volume_spinbox->setValue(p_ao_app->get_default_sfx()); - ui_sfx_volume_spinbox->setMaximum(100); - ui_sfx_volume_spinbox->setSuffix("%"); - - ui_audio_layout->setWidget(3, QFormLayout::FieldRole, ui_sfx_volume_spinbox); - - ui_blips_volume_lbl = new QLabel(ui_audio_widget); - ui_blips_volume_lbl->setText(tr("Blips:")); - ui_blips_volume_lbl->setToolTip(tr("Sets the volume of the blips, the talking sound effects.")); - - ui_audio_layout->setWidget(4, QFormLayout::LabelRole, ui_blips_volume_lbl); - - ui_blips_volume_spinbox = new QSpinBox(ui_audio_widget); - ui_blips_volume_spinbox->setValue(p_ao_app->get_default_blip()); - ui_blips_volume_spinbox->setMaximum(100); - ui_blips_volume_spinbox->setSuffix("%"); - - ui_audio_layout->setWidget(4, QFormLayout::FieldRole, ui_blips_volume_spinbox); - - ui_volume_blip_divider = new QFrame(ui_audio_widget); - ui_volume_blip_divider->setFrameShape(QFrame::HLine); - ui_volume_blip_divider->setFrameShadow(QFrame::Sunken); - - ui_audio_layout->setWidget(5, QFormLayout::FieldRole, ui_volume_blip_divider); - - ui_bliprate_lbl = new QLabel(ui_audio_widget); - ui_bliprate_lbl->setText(tr("Blip rate:")); - ui_bliprate_lbl->setToolTip(tr("Sets the delay between playing the blip sounds.")); - - ui_audio_layout->setWidget(6, QFormLayout::LabelRole, ui_bliprate_lbl); - - ui_bliprate_spinbox = new QSpinBox(ui_audio_widget); - ui_bliprate_spinbox->setValue(p_ao_app->read_blip_rate()); - ui_bliprate_spinbox->setMinimum(1); - - ui_audio_layout->setWidget(6, QFormLayout::FieldRole, ui_bliprate_spinbox); - - ui_blank_blips_lbl = new QLabel(ui_audio_widget); - ui_blank_blips_lbl->setText(tr("Blank blips:")); - ui_blank_blips_lbl->setToolTip(tr("If true, the game will play a blip sound even " - "when a space is 'being said'.")); - - ui_audio_layout->setWidget(7, QFormLayout::LabelRole, ui_blank_blips_lbl); - - ui_blank_blips_cb = new QCheckBox(ui_audio_widget); - ui_blank_blips_cb->setChecked(p_ao_app->get_blank_blip()); - - ui_audio_layout->setWidget(7, QFormLayout::FieldRole, ui_blank_blips_cb); - - // The casing tab! - ui_casing_tab = new QWidget(); - ui_settings_tabs->addTab(ui_casing_tab, tr("Casing")); - - ui_casing_widget = new QWidget(ui_casing_tab); - ui_casing_widget->setGeometry(QRect(10,10, 361, 211)); - - ui_casing_layout = new QFormLayout(ui_casing_widget); - ui_casing_layout->setLabelAlignment(Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter); - ui_casing_layout->setFormAlignment(Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop); - ui_casing_layout->setContentsMargins(0, 0, 0, 0); - - // -- SERVER SUPPORTS CASING - - ui_casing_supported_lbl = new QLabel(ui_casing_widget); - if (ao_app->casing_alerts_enabled) - ui_casing_supported_lbl->setText(tr("This server supports case alerts.")); - else - ui_casing_supported_lbl->setText(tr("This server does not support case alerts.")); - ui_casing_supported_lbl->setToolTip(tr("Pretty self-explanatory.")); - - ui_casing_layout->setWidget(0, QFormLayout::FieldRole, ui_casing_supported_lbl); - - // -- CASE ANNOUNCEMENTS - - ui_casing_enabled_lbl = new QLabel(ui_casing_widget); - ui_casing_enabled_lbl->setText(tr("Casing:")); - ui_casing_enabled_lbl->setToolTip(tr("If checked, you will get alerts about case " - "announcements.")); - - ui_casing_layout->setWidget(1, QFormLayout::LabelRole, ui_casing_enabled_lbl); - - ui_casing_enabled_cb = new QCheckBox(ui_casing_widget); - ui_casing_enabled_cb->setChecked(ao_app->get_casing_enabled()); - - ui_casing_layout->setWidget(1, QFormLayout::FieldRole, ui_casing_enabled_cb); - - // -- DEFENSE ANNOUNCEMENTS - - ui_casing_def_lbl = new QLabel(ui_casing_widget); - ui_casing_def_lbl->setText(tr("Defense:")); - ui_casing_def_lbl->setToolTip(tr("If checked, you will get alerts about case " - "announcements if a defense spot is open.")); - - ui_casing_layout->setWidget(2, QFormLayout::LabelRole, ui_casing_def_lbl); - - ui_casing_def_cb = new QCheckBox(ui_casing_widget); - ui_casing_def_cb->setChecked(ao_app->get_casing_defence_enabled()); - - ui_casing_layout->setWidget(2, QFormLayout::FieldRole, ui_casing_def_cb); - - // -- PROSECUTOR ANNOUNCEMENTS - - ui_casing_pro_lbl = new QLabel(ui_casing_widget); - ui_casing_pro_lbl->setText(tr("Prosecution:")); - ui_casing_pro_lbl->setToolTip(tr("If checked, you will get alerts about case " - "announcements if a prosecutor spot is open.")); - - ui_casing_layout->setWidget(3, QFormLayout::LabelRole, ui_casing_pro_lbl); - - ui_casing_pro_cb = new QCheckBox(ui_casing_widget); - ui_casing_pro_cb->setChecked(ao_app->get_casing_prosecution_enabled()); - - ui_casing_layout->setWidget(3, QFormLayout::FieldRole, ui_casing_pro_cb); - - // -- JUDGE ANNOUNCEMENTS - - ui_casing_jud_lbl = new QLabel(ui_casing_widget); - ui_casing_jud_lbl->setText(tr("Judge:")); - ui_casing_jud_lbl->setToolTip(tr("If checked, you will get alerts about case " - "announcements if the judge spot is open.")); - - ui_casing_layout->setWidget(4, QFormLayout::LabelRole, ui_casing_jud_lbl); - - ui_casing_jud_cb = new QCheckBox(ui_casing_widget); - ui_casing_jud_cb->setChecked(ao_app->get_casing_judge_enabled()); - - ui_casing_layout->setWidget(4, QFormLayout::FieldRole, ui_casing_jud_cb); - - // -- JUROR ANNOUNCEMENTS - - ui_casing_jur_lbl = new QLabel(ui_casing_widget); - ui_casing_jur_lbl->setText(tr("Juror:")); - ui_casing_jur_lbl->setToolTip(tr("If checked, you will get alerts about case " - "announcements if a juror spot is open.")); - - ui_casing_layout->setWidget(5, QFormLayout::LabelRole, ui_casing_jur_lbl); - - ui_casing_jur_cb = new QCheckBox(ui_casing_widget); - ui_casing_jur_cb->setChecked(ao_app->get_casing_juror_enabled()); - - ui_casing_layout->setWidget(5, QFormLayout::FieldRole, ui_casing_jur_cb); - - // -- STENO ANNOUNCEMENTS - - ui_casing_steno_lbl = new QLabel(ui_casing_widget); - ui_casing_steno_lbl->setText(tr("Stenographer:")); - ui_casing_steno_lbl->setToolTip(tr("If checked, you will get alerts about case " - "announcements if a stenographer spot is open.")); - - ui_casing_layout->setWidget(6, QFormLayout::LabelRole, ui_casing_steno_lbl); - - ui_casing_steno_cb = new QCheckBox(ui_casing_widget); - ui_casing_steno_cb->setChecked(ao_app->get_casing_steno_enabled()); - - ui_casing_layout->setWidget(6, QFormLayout::FieldRole, ui_casing_steno_cb); - - // -- CM ANNOUNCEMENTS - - ui_casing_cm_lbl = new QLabel(ui_casing_widget); - ui_casing_cm_lbl->setText(tr("CM:")); - ui_casing_cm_lbl->setToolTip(tr("If checked, you will appear amongst the potential " - "CMs on the server.")); - - ui_casing_layout->setWidget(7, QFormLayout::LabelRole, ui_casing_cm_lbl); - - ui_casing_cm_cb = new QCheckBox(ui_casing_widget); - ui_casing_cm_cb->setChecked(ao_app->get_casing_cm_enabled()); - - ui_casing_layout->setWidget(7, QFormLayout::FieldRole, ui_casing_cm_cb); - - // -- CM CASES ANNOUNCEMENTS - - ui_casing_cm_cases_lbl = new QLabel(ui_casing_widget); - ui_casing_cm_cases_lbl->setText(tr("Hosting cases:")); - ui_casing_cm_cases_lbl->setToolTip(tr("If you're a CM, enter what cases you are " - "willing to host.")); - - ui_casing_layout->setWidget(8, QFormLayout::LabelRole, ui_casing_cm_cases_lbl); - - ui_casing_cm_cases_textbox = new QLineEdit(ui_casing_widget); - ui_casing_cm_cases_textbox->setText(ao_app->get_casing_can_host_cases()); - - ui_casing_layout->setWidget(8, QFormLayout::FieldRole, ui_casing_cm_cases_textbox); - - // When we're done, we should continue the updates! - setUpdatesEnabled(true); -} - -void AOOptionsDialog::save_pressed() -{ - // Save everything into the config.ini. - QSettings* configini = ao_app->configini; - - configini->setValue("theme", ui_theme_combobox->currentText()); - configini->setValue("log_goes_downwards", ui_downwards_cb->isChecked()); - configini->setValue("log_maximum", ui_length_spinbox->value()); - configini->setValue("default_username", ui_username_textbox->text()); - configini->setValue("show_custom_shownames", ui_showname_cb->isChecked()); - configini->setValue("master", ui_ms_textbox->text()); - configini->setValue("discord", ui_discord_cb->isChecked()); - - QFile* callwordsini = new QFile(ao_app->get_base_path() + "callwords.ini"); - - if (!callwordsini->open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text)) - { - // Nevermind! - } - else - { - QTextStream out(callwordsini); - out << ui_callwords_textbox->toPlainText(); - callwordsini->close(); - } - - configini->setValue("default_audio_device", ui_audio_device_combobox->currentText()); - configini->setValue("default_music", ui_music_volume_spinbox->value()); - configini->setValue("default_sfx", ui_sfx_volume_spinbox->value()); - configini->setValue("default_blip", ui_blips_volume_spinbox->value()); - configini->setValue("blip_rate", ui_bliprate_spinbox->value()); - configini->setValue("blank_blip", ui_blank_blips_cb->isChecked()); - - configini->setValue("casing_enabled", ui_casing_enabled_cb->isChecked()); - configini->setValue("casing_defence_enabled", ui_casing_def_cb->isChecked()); - configini->setValue("casing_prosecution_enabled", ui_casing_pro_cb->isChecked()); - configini->setValue("casing_judge_enabled", ui_casing_jud_cb->isChecked()); - configini->setValue("casing_juror_enabled", ui_casing_jur_cb->isChecked()); - configini->setValue("casing_steno_enabled", ui_casing_steno_cb->isChecked()); - configini->setValue("casing_cm_enabled", ui_casing_cm_cb->isChecked()); - configini->setValue("casing_can_host_cases", ui_casing_cm_cases_textbox->text()); - - callwordsini->close(); - done(0); -} - -void AOOptionsDialog::discard_pressed() -{ - done(0); -} - -#if (defined (_WIN32) || defined (_WIN64)) -bool AOOptionsDialog::needs_default_audiodev() -{ - return true; -} -#elif (defined (LINUX) || defined (__linux__)) -bool AOOptionsDialog::needs_default_audiodev() -{ - return false; -} -#else -#error This operating system is not supported. -#endif diff --git a/aooptionsdialog.h b/aooptionsdialog.h deleted file mode 100644 index a65e3f59..00000000 --- a/aooptionsdialog.h +++ /dev/null @@ -1,115 +0,0 @@ -#ifndef AOOPTIONSDIALOG_H -#define AOOPTIONSDIALOG_H - -#include "aoapplication.h" -#include "bass.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -class AOOptionsDialog: public QDialog -{ - Q_OBJECT -public: - explicit AOOptionsDialog(QWidget *parent = nullptr, AOApplication *p_ao_app = nullptr); - -private: - AOApplication *ao_app; - - QVBoxLayout *ui_vertical_layout; - QTabWidget *ui_settings_tabs; - - QWidget *ui_gameplay_tab; - QWidget *ui_form_layout_widget; - QFormLayout *ui_gameplay_form; - QLabel *ui_theme_label; - QComboBox *ui_theme_combobox; - QFrame *ui_theme_log_divider; - QLabel *ui_downwards_lbl; - QCheckBox *ui_downwards_cb; - QLabel *ui_length_lbl; - QSpinBox *ui_length_spinbox; - QFrame *ui_log_names_divider; - QLineEdit *ui_username_textbox; - QLabel *ui_username_lbl; - QLabel *ui_showname_lbl; - QCheckBox *ui_showname_cb; - QFrame *ui_net_divider; - QLabel *ui_ms_lbl; - QLineEdit *ui_ms_textbox; - QLabel *ui_discord_lbl; - QCheckBox *ui_discord_cb; - - QWidget *ui_callwords_tab; - QWidget *ui_callwords_widget; - QVBoxLayout *ui_callwords_layout; - QPlainTextEdit *ui_callwords_textbox; - QLabel *ui_callwords_explain_lbl; - QCheckBox *ui_callwords_char_textbox; - - QWidget *ui_audio_tab; - QWidget *ui_audio_widget; - QFormLayout *ui_audio_layout; - QLabel *ui_audio_device_lbl; - QComboBox *ui_audio_device_combobox; - QFrame *ui_audio_volume_divider; - QSpinBox *ui_music_volume_spinbox; - QLabel *ui_music_volume_lbl; - QSpinBox *ui_sfx_volume_spinbox; - QSpinBox *ui_blips_volume_spinbox; - QLabel *ui_sfx_volume_lbl; - QLabel *ui_blips_volume_lbl; - QFrame *ui_volume_blip_divider; - QSpinBox *ui_bliprate_spinbox; - QLabel *ui_bliprate_lbl; - QCheckBox *ui_blank_blips_cb; - QLabel *ui_blank_blips_lbl; - QDialogButtonBox *ui_settings_buttons; - - QWidget *ui_casing_tab; - QWidget *ui_casing_widget; - QFormLayout *ui_casing_layout; - QLabel *ui_casing_supported_lbl; - QLabel *ui_casing_enabled_lbl; - QCheckBox *ui_casing_enabled_cb; - QLabel *ui_casing_def_lbl; - QCheckBox *ui_casing_def_cb; - QLabel *ui_casing_pro_lbl; - QCheckBox *ui_casing_pro_cb; - QLabel *ui_casing_jud_lbl; - QCheckBox *ui_casing_jud_cb; - QLabel *ui_casing_jur_lbl; - QCheckBox *ui_casing_jur_cb; - QLabel *ui_casing_steno_lbl; - QCheckBox *ui_casing_steno_cb; - QLabel *ui_casing_cm_lbl; - QCheckBox *ui_casing_cm_cb; - QLabel *ui_casing_cm_cases_lbl; - QLineEdit *ui_casing_cm_cases_textbox; - - bool needs_default_audiodev(); - -signals: - -public slots: - void save_pressed(); - void discard_pressed(); -}; - -#endif // AOOPTIONSDIALOG_H diff --git a/aopacket.cpp b/aopacket.cpp deleted file mode 100644 index b957efea..00000000 --- a/aopacket.cpp +++ /dev/null @@ -1,83 +0,0 @@ -#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; -} - -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; -} - -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("#", "").replace("%", "").replace("$", "").replace("&", ""); - - m_contents.removeAt(n_element); - m_contents.insert(n_element, f_element); - } -} - -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("", "#").replace("", "%").replace("", "$").replace("", "&"); - - m_contents.removeAt(n_element); - m_contents.insert(n_element, f_element); - } -} - diff --git a/aopacket.h b/aopacket.h deleted file mode 100644 index 21f6e0f4..00000000 --- a/aopacket.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef AOPACKET_H -#define AOPACKET_H - -#include -#include -#include - -class AOPacket -{ -public: - AOPacket(QString p_packet_string); - AOPacket(QString header, QStringList &p_contents); - ~AOPacket(); - - 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; -}; - -#endif // AOPACKET_H diff --git a/aoscene.cpp b/aoscene.cpp deleted file mode 100644 index 344522b6..00000000 --- a/aoscene.cpp +++ /dev/null @@ -1,76 +0,0 @@ -#include "aoscene.h" -#include "courtroom.h" -#include "file_functions.h" - -AOScene::AOScene(QWidget *parent, AOApplication *p_ao_app) : QLabel(parent) -{ - m_parent = parent; - ao_app = p_ao_app; - m_movie = new QMovie(this); -} - -void AOScene::set_image(QString p_image) -{ - QString background_path = ao_app->get_background_path(p_image + ".png"); - QString animated_background_path = ao_app->get_background_path(p_image + ".gif"); - QString default_path = ao_app->get_default_background_path(p_image + ".png"); - - QPixmap background(background_path); - QPixmap default_bg(default_path); - - int w = this->width(); - int h = this->height(); - - this->clear(); - this->setMovie(nullptr); - - m_movie->stop(); - m_movie->setFileName(animated_background_path); - m_movie->setScaledSize(QSize(w, h)); - - if (m_movie->isValid()) - { - this->setMovie(m_movie); - m_movie->start(); - } - else if (file_exists(background_path)) - { - this->setPixmap(background.scaled(w, h)); - } - else - { - this->setPixmap(default_bg.scaled(w, h)); - } -} - -void AOScene::set_legacy_desk(QString p_image) -{ - //vanilla desks vary in both width and height. in order to make that work with viewport rescaling, - //some INTENSE math is needed. - - QString desk_path = ao_app->get_background_path(p_image); - QString default_path = ao_app->get_default_background_path(p_image); - - QPixmap f_desk; - - if (file_exists(desk_path)) - f_desk.load(desk_path); - else - f_desk.load(default_path); - - int vp_width = m_parent->width(); - int vp_height = m_parent->height(); - - //double y_modifier = 147 / 192; - //double w_modifier = vp_width / 256; - double h_modifier = vp_height / 192; - - //int final_y = y_modifier * vp_height; - //int final_w = w_modifier * f_desk.width(); - int final_h = static_cast(h_modifier * f_desk.height()); - - //this->resize(final_w, final_h); - //this->setPixmap(f_desk.scaled(final_w, final_h)); - this->resize(vp_width, final_h); - this->setPixmap(f_desk.scaled(vp_width, final_h)); -} diff --git a/aoscene.h b/aoscene.h deleted file mode 100644 index b58c0fd0..00000000 --- a/aoscene.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef AOSCENE_H -#define AOSCENE_H - -#include -#include -#include - -class Courtroom; -class AOApplication; - -class AOScene : public QLabel -{ - Q_OBJECT -public: - explicit AOScene(QWidget *parent, AOApplication *p_ao_app); - - void set_image(QString p_image); - void set_legacy_desk(QString p_image); - -private: - QWidget *m_parent; - QMovie *m_movie; - AOApplication *ao_app; - -}; - -#endif // AOSCENE_H diff --git a/aosfxplayer.cpp b/aosfxplayer.cpp deleted file mode 100644 index 7fe7987b..00000000 --- a/aosfxplayer.cpp +++ /dev/null @@ -1,51 +0,0 @@ -#include "aosfxplayer.h" -#include "file_functions.h" - -AOSfxPlayer::AOSfxPlayer(QWidget *parent, AOApplication *p_ao_app) -{ - m_parent = parent; - ao_app = p_ao_app; -} - -void AOSfxPlayer::play(QString p_sfx, QString p_char, QString shout) -{ - BASS_ChannelStop(m_stream); - - QString misc_path = ""; - QString char_path = ""; - QString sound_path = ao_app->get_sounds_path(p_sfx); - - if (shout != "") - misc_path = ao_app->get_base_path() + "misc/" + shout + "/" + p_sfx; - if (p_char != "") - char_path = ao_app->get_character_path(p_char, p_sfx); - - QString f_path; - - if (file_exists(char_path)) - f_path = char_path; - else if (file_exists(misc_path)) - f_path = misc_path; - else - f_path = sound_path; - - m_stream = BASS_StreamCreateFile(FALSE, f_path.utf16(), 0, 0, BASS_STREAM_AUTOFREE | BASS_UNICODE | BASS_ASYNCFILE); - - set_volume(m_volume); - - if (ao_app->get_audio_output_device() != "default") - BASS_ChannelSetDevice(m_stream, BASS_GetDevice()); - BASS_ChannelPlay(m_stream, false); -} - -void AOSfxPlayer::stop() -{ - BASS_ChannelStop(m_stream); -} - -void AOSfxPlayer::set_volume(int p_value) -{ - m_volume = p_value; - float volume = p_value / 100.0f; - BASS_ChannelSetAttribute(m_stream, BASS_ATTRIB_VOL, volume); -} diff --git a/aosfxplayer.h b/aosfxplayer.h deleted file mode 100644 index 30cbe9d3..00000000 --- a/aosfxplayer.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef AOSFXPLAYER_H -#define AOSFXPLAYER_H - -#include "bass.h" -#include "aoapplication.h" - -#include -#include -#include - -class AOSfxPlayer -{ -public: - AOSfxPlayer(QWidget *parent, AOApplication *p_ao_app); - - void play(QString p_sfx, QString p_char = "", QString shout = ""); - void stop(); - void set_volume(int p_volume); - -private: - QWidget *m_parent; - AOApplication *ao_app; - - int m_volume = 0; - HSTREAM m_stream; -}; - -#endif // AOSFXPLAYER_H diff --git a/aotextarea.cpp b/aotextarea.cpp deleted file mode 100644 index 5e146326..00000000 --- a/aotextarea.cpp +++ /dev/null @@ -1,60 +0,0 @@ -#include "aotextarea.h" - -AOTextArea::AOTextArea(QWidget *p_parent) : QTextBrowser(p_parent) -{ - -} - -void AOTextArea::append_chatmessage(QString p_name, QString p_message, QString p_colour) -{ - const QTextCursor old_cursor = this->textCursor(); - const int old_scrollbar_value = this->verticalScrollBar()->value(); - const bool is_scrolled_down = old_scrollbar_value == this->verticalScrollBar()->maximum(); - - this->moveCursor(QTextCursor::End); - - this->append(""); - this->insertHtml("" + p_name.toHtmlEscaped() + ": "); - - //cheap workarounds ahoy - p_message += " "; - QString result = p_message.toHtmlEscaped().replace("\n", "
").replace(omnis_dank_url_regex, "\\1" ); - - this->insertHtml(result); - - this->auto_scroll(old_cursor, old_scrollbar_value, is_scrolled_down); -} - -void AOTextArea::append_error(QString p_message) -{ - const QTextCursor old_cursor = this->textCursor(); - const int old_scrollbar_value = this->verticalScrollBar()->value(); - const bool is_scrolled_down = old_scrollbar_value == this->verticalScrollBar()->maximum(); - - this->moveCursor(QTextCursor::End); - - this->append(""); - - p_message += " "; - QString result = p_message.replace("\n", "
").replace(omnis_dank_url_regex, "\\1" ); - - this->insertHtml("" + result + ""); - - this->auto_scroll(old_cursor, old_scrollbar_value, is_scrolled_down); -} - -void AOTextArea::auto_scroll(QTextCursor old_cursor, int old_scrollbar_value, bool is_scrolled_down) -{ - if (old_cursor.hasSelection() || !is_scrolled_down) - { - // The user has selected text or scrolled away from the bottom: maintain position. - this->setTextCursor(old_cursor); - this->verticalScrollBar()->setValue(old_scrollbar_value); - } - else - { - // The user hasn't selected any text and the scrollbar is at the bottom: scroll to the bottom. - this->moveCursor(QTextCursor::End); - this->verticalScrollBar()->setValue(this->verticalScrollBar()->maximum()); - } -} diff --git a/aotextarea.h b/aotextarea.h deleted file mode 100644 index d44596b2..00000000 --- a/aotextarea.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef AOTEXTAREA_H -#define AOTEXTAREA_H - -#include -#include -#include -#include -#include - -class AOTextArea : public QTextBrowser -{ -public: - AOTextArea(QWidget *p_parent = nullptr); - - void append_chatmessage(QString p_name, QString p_message, QString p_colour); - void append_error(QString p_message); - -private: - const QRegExp omnis_dank_url_regex = QRegExp("\\b(https?://\\S+\\.\\S+)\\b"); - - void auto_scroll(QTextCursor old_cursor, int scrollbar_value, bool is_scrolled_down); -}; - -#endif // AOTEXTAREA_H diff --git a/aotextedit.cpp b/aotextedit.cpp deleted file mode 100644 index 30e48b73..00000000 --- a/aotextedit.cpp +++ /dev/null @@ -1,21 +0,0 @@ -#include "aotextedit.h" - -AOTextEdit::AOTextEdit(QWidget *parent) : QPlainTextEdit(parent) -{ - this->setReadOnly(true); - - //connect(this, SIGNAL(returnPressed()), this, SLOT(on_enter_pressed())); -} - -void AOTextEdit::mouseDoubleClickEvent(QMouseEvent *e) -{ - QPlainTextEdit::mouseDoubleClickEvent(e); - - this->setReadOnly(false); -} - -void AOTextEdit::on_enter_pressed() -{ - this->setReadOnly(true); -} - diff --git a/aotextedit.h b/aotextedit.h deleted file mode 100644 index 85909c6e..00000000 --- a/aotextedit.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef AOTEXTEDIT_H -#define AOTEXTEDIT_H - -#include - -class AOTextEdit : public QPlainTextEdit -{ - Q_OBJECT -public: - AOTextEdit(QWidget *parent); - -protected: - void mouseDoubleClickEvent(QMouseEvent *e); - -signals: - void double_clicked(); - -private slots: - void on_enter_pressed(); - -}; - -#endif // AOTEXTEDIT_H diff --git a/charselect.cpp b/charselect.cpp deleted file mode 100644 index 8e1b9122..00000000 --- a/charselect.cpp +++ /dev/null @@ -1,268 +0,0 @@ -#include "courtroom.h" -#include "lobby.h" - -#include "file_functions.h" -#include "debug_functions.h" -#include "hardware_functions.h" - -void Courtroom::construct_char_select() -{ - ui_char_select_background = new AOImage(this, ao_app); - - ui_char_buttons = new QWidget(ui_char_select_background); - - ui_selector = new AOImage(ui_char_select_background, ao_app); - 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); - ui_char_password->setPlaceholderText(tr("Password")); - - ui_char_select_left = new AOButton(ui_char_select_background, ao_app); - ui_char_select_right = new AOButton(ui_char_select_background, ao_app); - - ui_spectator = new AOButton(ui_char_select_background, ao_app); - ui_spectator->setText(tr("Spectator")); - - ui_char_search = new QLineEdit(ui_char_select_background); - ui_char_search->setPlaceholderText(tr("Search")); - ui_char_search->setFocus(); - set_size_and_pos(ui_char_search, "char_search"); - - ui_char_passworded = new QCheckBox(ui_char_select_background); - ui_char_passworded->setText(tr("Passworded")); - set_size_and_pos(ui_char_passworded, "char_passworded"); - - ui_char_taken = new QCheckBox(ui_char_select_background); - ui_char_taken->setText(tr("Taken")); - set_size_and_pos(ui_char_taken, "char_taken"); - - ui_char_taken->setChecked(true); - ui_char_passworded->setChecked(true); - - set_size_and_pos(ui_char_buttons, "char_buttons"); - - connect (char_button_mapper, SIGNAL(mapped(int)), this, SLOT(char_clicked(int))); - connect(ui_back_to_lobby, SIGNAL(clicked()), this, SLOT(on_back_to_lobby_clicked())); - - connect(ui_char_select_left, SIGNAL(clicked()), this, SLOT(on_char_select_left_clicked())); - connect(ui_char_select_right, SIGNAL(clicked()), this, SLOT(on_char_select_right_clicked())); - - connect(ui_spectator, SIGNAL(clicked()), this, SLOT(on_spectator_clicked())); - - connect(ui_char_search, SIGNAL(textEdited(const QString&)), this, SLOT(on_char_search_changed(const QString&))); - connect(ui_char_passworded, SIGNAL(stateChanged(int)), this, SLOT(on_char_passworded_clicked(int))); - connect(ui_char_taken, SIGNAL(stateChanged(int)), this, SLOT(on_char_taken_clicked(int))); -} - -void Courtroom::set_char_select() -{ - QString filename = "courtroom_design.ini"; - - pos_size_type f_charselect = ao_app->get_element_dimensions("char_select", filename); - - if (f_charselect.width < 0 || f_charselect.height < 0) - { - qDebug() << "W: did not find courtroom width or height in courtroom_design.ini!"; - this->resize(714, 668); - } - else - this->resize(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.png"); - - filter_character_list(); - - ui_char_search->setFocus(); -} - -void Courtroom::set_char_select_page() -{ - ui_char_select_background->show(); - - ui_char_select_left->hide(); - ui_char_select_right->hide(); - - for (AOCharButton *i_button : ui_char_button_list) - { - i_button->reset(); - i_button->hide(); - i_button->move(0,0); - } - - int total_pages = ui_char_button_list_filtered.size() / max_chars_on_page; - int chars_on_page = 0; - - if (ui_char_button_list_filtered.size() % max_chars_on_page != 0) - { - ++total_pages; - //i. e. not on the last page - if (total_pages > current_char_page + 1) - chars_on_page = max_chars_on_page; - else - chars_on_page = ui_char_button_list_filtered.size() % max_chars_on_page; - - } - else - chars_on_page = max_chars_on_page; - - if (total_pages > current_char_page + 1) - ui_char_select_right->show(); - - if (current_char_page > 0) - ui_char_select_left->show(); - - put_button_in_place(current_char_page * max_chars_on_page, chars_on_page); -} - -void Courtroom::char_clicked(int n_char) -{ - QString char_ini_path = ao_app->get_character_path(char_list.at(n_char).name, "char.ini"); - - qDebug() << "char_ini_path" << char_ini_path; - - if (!file_exists(char_ini_path)) - { - call_notice("Could not find " + char_ini_path); - return; - } - - if (n_char == m_cid) - { - enter_courtroom(m_cid); - } - else - { - ao_app->send_server_packet(new AOPacket("CC#" + QString::number(ao_app->s_pv) + "#" + QString::number(n_char) + "#" + get_hdid() + "#%")); - } - - ui_ic_chat_name->setPlaceholderText(char_list.at(n_char).name); -} - -void Courtroom::put_button_in_place(int starting, int chars_on_this_page) -{ - if (ui_char_button_list_filtered.size() == 0) - return; - - QPoint f_spacing = ao_app->get_button_spacing("char_button_spacing", "courtroom_design.ini"); - - int x_spacing = f_spacing.x(); - int x_mod_count = 0; - - int y_spacing = f_spacing.y(); - int y_mod_count = 0; - - char_columns = ((ui_char_buttons->width() - button_width) / (x_spacing + button_width)) + 1; - char_rows = ((ui_char_buttons->height() - button_height) / (y_spacing + button_height)) + 1; - - max_chars_on_page = char_columns * char_rows; - - int startout = starting; - for (int n = starting ; n < startout+chars_on_this_page ; ++n) - { - int x_pos = (button_width + x_spacing) * x_mod_count; - int y_pos = (button_height + y_spacing) * y_mod_count; - - ui_char_button_list_filtered.at(n)->move(x_pos, y_pos); - ui_char_button_list_filtered.at(n)->show(); - ui_char_button_list_filtered.at(n)->apply_taken_image(); - - ++x_mod_count; - - if (x_mod_count == char_columns) - { - ++y_mod_count; - x_mod_count = 0; - } - } -} - -void Courtroom::character_loading_finished() -{ - // Zeroeth, we'll clear any leftover characters from previous server visits. - ao_app->generated_chars = 0; - if (ui_char_button_list.size() > 0) - { - foreach (AOCharButton* item, ui_char_button_list) { - delete item; - } - ui_char_button_list.clear(); - } - - // First, we'll make all the character buttons in the very beginning. - // We also hide them all, so they can't be accidentally clicked. - // Later on, we'll be revealing buttons as we need them. - for (int n = 0; n < char_list.size(); n++) - { - AOCharButton* character = new AOCharButton(ui_char_buttons, ao_app, 0, 0, char_list.at(n).taken); - character->reset(); - character->hide(); - character->set_image(char_list.at(n).name); - ui_char_button_list.append(character); - - connect(character, SIGNAL(clicked()), char_button_mapper, SLOT(map())); - char_button_mapper->setMapping(character, ui_char_button_list.size() - 1); - - // This part here serves as a way of showing to the player that the game is still running, it is - // just loading the pictures of the characters. - if (ao_app->lobby_constructed) - { - ao_app->generated_chars++; - int total_loading_size = ao_app->char_list_size * 2 + ao_app->evidence_list_size + ao_app->music_list_size; - int loading_value = int(((ao_app->loaded_chars + ao_app->generated_chars + ao_app->loaded_music + ao_app->loaded_evidence) / static_cast(total_loading_size)) * 100); - ao_app->w_lobby->set_loading_value(loading_value); - ao_app->w_lobby->set_loading_text("Generating chars:\n" + QString::number(ao_app->generated_chars) + "/" + QString::number(ao_app->char_list_size)); - } - } - - filter_character_list(); -} - -void Courtroom::filter_character_list() -{ - ui_char_button_list_filtered.clear(); - for (int i = 0; i < char_list.size(); i++) - { - AOCharButton* current_char = ui_char_button_list.at(i); - - // It seems passwording characters is unimplemented yet? - // Until then, this will stay here, I suppose. - //if (ui_char_passworded->isChecked() && character_is_passworded??) - // continue; - - if (!ui_char_taken->isChecked() && char_list.at(i).taken) - continue; - - if (!char_list.at(i).name.contains(ui_char_search->text(), Qt::CaseInsensitive)) - continue; - - // We only really need to update the fact that a character is taken - // for the buttons that actually appear. - // You'd also update the passwordedness and etc. here later. - current_char->reset(); - current_char->set_taken(char_list.at(i).taken); - - ui_char_button_list_filtered.append(current_char); - } - - current_char_page = 0; - set_char_select_page(); -} - -void Courtroom::on_char_search_changed(const QString& newtext) -{ - filter_character_list(); -} - -void Courtroom::on_char_passworded_clicked(int newstate) -{ - filter_character_list(); -} - -void Courtroom::on_char_taken_clicked(int newstate) -{ - filter_character_list(); -} diff --git a/chatlogpiece.cpp b/chatlogpiece.cpp deleted file mode 100644 index 6c861f01..00000000 --- a/chatlogpiece.cpp +++ /dev/null @@ -1,76 +0,0 @@ -#include "chatlogpiece.h" - -chatlogpiece::chatlogpiece() -{ - name = "UNKNOWN"; - showname = "UNKNOWN"; - message = "UNKNOWN"; - is_song = false; - datetime = QDateTime::currentDateTime().toUTC(); -} - -chatlogpiece::chatlogpiece(QString p_name, QString p_showname, QString p_message, bool p_song) -{ - name = p_name; - showname = p_showname; - message = p_message; - is_song = p_song; - datetime = QDateTime::currentDateTime().toUTC(); -} - -chatlogpiece::chatlogpiece(QString p_name, QString p_showname, QString p_message, bool p_song, QDateTime p_datetime) -{ - name = p_name; - showname = p_showname; - message = p_message; - is_song = p_song; - datetime = p_datetime.toUTC(); -} - -QString chatlogpiece::get_name() -{ - return name; -} - -QString chatlogpiece::get_showname() -{ - return showname; -} - -QString chatlogpiece::get_message() -{ - return message; -} - -QDateTime chatlogpiece::get_datetime() -{ - return datetime; -} - -bool chatlogpiece::get_is_song() -{ - return is_song; -} - -QString chatlogpiece::get_datetime_as_string() -{ - return datetime.toString(); -} - - -QString chatlogpiece::get_full() -{ - QString full = "["; - - full.append(get_datetime_as_string()); - full.append(" UTC] "); - full.append(get_showname()); - full.append(" ("); - full.append(get_name()); - full.append(")"); - if (is_song) - full.append(" has played a song: "); - full.append(get_message()); - - return full; -} diff --git a/chatlogpiece.h b/chatlogpiece.h deleted file mode 100644 index 34c5926b..00000000 --- a/chatlogpiece.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef CHATLOGPIECE_H -#define CHATLOGPIECE_H - -#include -#include - -class chatlogpiece -{ -public: - chatlogpiece(); - chatlogpiece(QString p_name, QString p_showname, QString p_message, bool p_song); - chatlogpiece(QString p_name, QString p_showname, QString p_message, bool p_song, QDateTime p_datetime); - - QString get_name(); - QString get_showname(); - QString get_message(); - bool get_is_song(); - QDateTime get_datetime(); - QString get_datetime_as_string(); - - QString get_full(); - -private: - QString name; - QString showname; - QString message; - QDateTime datetime; - bool is_song; -}; - -#endif // CHATLOGPIECE_H diff --git a/courtroom.cpp b/courtroom.cpp deleted file mode 100644 index 3ed1e745..00000000 --- a/courtroom.cpp +++ /dev/null @@ -1,3513 +0,0 @@ -#include "courtroom.h" - -Courtroom::Courtroom(AOApplication *p_ao_app) : QMainWindow() -{ - ao_app = p_ao_app; - - // Change the default audio output device to be the one the user has given - // in his config.ini file for now. - int a = 0; - BASS_DEVICEINFO info; - - if (ao_app->get_audio_output_device() == "default") - { - BASS_Init(-1, 48000, BASS_DEVICE_LATENCY, nullptr, nullptr); - load_bass_opus_plugin(); - } - else - { - for (a = 0; BASS_GetDeviceInfo(a, &info); a++) - { - if (ao_app->get_audio_output_device() == info.name) - { - BASS_SetDevice(a); - BASS_Init(a, 48000, BASS_DEVICE_LATENCY, nullptr, nullptr); - load_bass_opus_plugin(); - qDebug() << info.name << "was set as the default audio output device."; - break; - } - } - } - - keepalive_timer = new QTimer(this); - keepalive_timer->start(60000); - - chat_tick_timer = new QTimer(this); - - text_delay_timer = new QTimer(this); - text_delay_timer->setSingleShot(true); - - sfx_delay_timer = new QTimer(this); - sfx_delay_timer->setSingleShot(true); - - realization_timer = new QTimer(this); - realization_timer->setSingleShot(true); - - testimony_show_timer = new QTimer(this); - testimony_show_timer->setSingleShot(true); - - testimony_hide_timer = new QTimer(this); - testimony_hide_timer->setSingleShot(true); - - char_button_mapper = new QSignalMapper(this); - - music_player = new AOMusicPlayer(this, ao_app); - music_player->set_volume(0); - sfx_player = new AOSfxPlayer(this, ao_app); - sfx_player->set_volume(0); - objection_player = new AOSfxPlayer(this, ao_app); - sfx_player->set_volume(0); - blip_player = new AOBlipPlayer(this, ao_app); - blip_player->set_volume(0); - - modcall_player = new AOSfxPlayer(this, ao_app); - modcall_player->set_volume(50); - - ui_background = new AOImage(this, ao_app); - - ui_viewport = new QWidget(this); - ui_vp_background = new AOScene(ui_viewport, ao_app); - ui_vp_speedlines = new AOMovie(ui_viewport, ao_app); - ui_vp_speedlines->set_play_once(false); - ui_vp_player_char = new AOCharMovie(ui_viewport, ao_app); - ui_vp_sideplayer_char = new AOCharMovie(ui_viewport, ao_app); - ui_vp_sideplayer_char->hide(); - ui_vp_desk = new AOScene(ui_viewport, ao_app); - ui_vp_legacy_desk = new AOScene(ui_viewport, ao_app); - - ui_vp_evidence_display = new AOEvidenceDisplay(this, ao_app); - - ui_vp_chatbox = new AOImage(this, ao_app); - ui_vp_showname = new QLabel(ui_vp_chatbox); - ui_vp_message = new QTextEdit(ui_vp_chatbox); - ui_vp_message->setFrameStyle(QFrame::NoFrame); - ui_vp_message->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - ui_vp_message->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - ui_vp_message->setReadOnly(true); - - ui_vp_testimony = new AOImage(this, ao_app); - ui_vp_realization = new AOImage(this, ao_app); - ui_vp_wtce = new AOMovie(this, ao_app); - ui_vp_objection = new AOMovie(this, ao_app); - - ui_ic_chatlog = new QTextEdit(this); - ui_ic_chatlog->setReadOnly(true); - - log_maximum_blocks = ao_app->get_max_log_size(); - log_goes_downwards = ao_app->get_log_goes_downwards(); - - ui_ms_chatlog = new AOTextArea(this); - ui_ms_chatlog->setReadOnly(true); - ui_ms_chatlog->setOpenExternalLinks(true); - ui_ms_chatlog->hide(); - - ui_server_chatlog = new AOTextArea(this); - ui_server_chatlog->setReadOnly(true); - ui_server_chatlog->setOpenExternalLinks(true); - - ui_area_list = new QListWidget(this); - ui_area_list->hide(); - ui_music_list = new QListWidget(this); - - ui_ic_chat_name = new QLineEdit(this); - ui_ic_chat_name->setFrame(false); - ui_ic_chat_name->setPlaceholderText(tr("Showname")); - - ui_ic_chat_message = new QLineEdit(this); - ui_ic_chat_message->setFrame(false); - ui_ic_chat_message->setPlaceholderText(tr("Message")); - - ui_muted = new AOImage(ui_ic_chat_message, ao_app); - ui_muted->hide(); - - ui_ooc_chat_message = new QLineEdit(this); - ui_ooc_chat_message->setFrame(false); - - ui_ooc_chat_name = new QLineEdit(this); - ui_ooc_chat_name->setFrame(false); - ui_ooc_chat_name->setPlaceholderText("Name"); - ui_ooc_chat_name->setMaxLength(30); - ui_ooc_chat_name->setText(p_ao_app->get_default_username()); - - //ui_area_password = new QLineEdit(this); - //ui_area_password->setFrame(false); - ui_music_search = new QLineEdit(this); - ui_music_search->setFrame(false); - ui_music_search->setPlaceholderText(tr("Search")); - - construct_emotes(); - - ui_emote_left = new AOButton(this, ao_app); - ui_emote_right = new AOButton(this, ao_app); - - ui_emote_dropdown = new QComboBox(this); - ui_pos_dropdown = new QComboBox(this); - ui_pos_dropdown->addItem("wit"); - ui_pos_dropdown->addItem("def"); - ui_pos_dropdown->addItem("pro"); - ui_pos_dropdown->addItem("jud"); - ui_pos_dropdown->addItem("hld"); - ui_pos_dropdown->addItem("hlp"); - ui_pos_dropdown->addItem("jur"); - ui_pos_dropdown->addItem("sea"); - - ui_defense_bar = new AOImage(this, ao_app); - ui_prosecution_bar = new AOImage(this, ao_app); - - ui_music_label = new QLabel(this); - ui_sfx_label = new QLabel(this); - ui_blip_label = new QLabel(this); - - ui_log_limit_label = new QLabel(this); - - ui_hold_it = new AOButton(this, ao_app); - ui_objection = new AOButton(this, ao_app); - ui_take_that = new AOButton(this, ao_app); - - ui_ooc_toggle = new AOButton(this, ao_app); - ui_witness_testimony = new AOButton(this, ao_app); - ui_cross_examination = new AOButton(this, ao_app); - ui_guilty = new AOButton(this, ao_app); - ui_not_guilty = new AOButton(this, ao_app); - - ui_change_character = new AOButton(this, ao_app); - ui_reload_theme = new AOButton(this, ao_app); - ui_call_mod = new AOButton(this, ao_app); - ui_settings = new AOButton(this, ao_app); - ui_announce_casing = new AOButton(this, ao_app); - ui_switch_area_music = new AOButton(this, ao_app); - - ui_pre = new QCheckBox(this); - ui_pre->setText("Pre"); - ui_flip = new QCheckBox(this); - ui_flip->setText("Flip"); - ui_flip->hide(); - ui_guard = new QCheckBox(this); - ui_guard->setText("Guard"); - ui_guard->hide(); - ui_casing = new QCheckBox(this); - ui_casing->setChecked(ao_app->get_casing_enabled()); - ui_casing->setText(tr("Casing")); - ui_casing->hide(); - - ui_showname_enable = new QCheckBox(this); - ui_showname_enable->setChecked(ao_app->get_showname_enabled_by_default()); - ui_showname_enable->setText(tr("Shownames")); - - ui_pre_non_interrupt = new QCheckBox(this); - ui_pre_non_interrupt->setText(tr("No Interrupt")); - ui_pre_non_interrupt->hide(); - - ui_custom_objection = new AOButton(this, ao_app); - ui_realization = new AOButton(this, ao_app); - ui_mute = new AOButton(this, ao_app); - - ui_defense_plus = new AOButton(this, ao_app); - ui_defense_minus = new AOButton(this, ao_app); - - ui_prosecution_plus = new AOButton(this, ao_app); - ui_prosecution_minus = new AOButton(this, ao_app); - - ui_text_color = new QComboBox(this); - ui_text_color->addItem("White"); - ui_text_color->addItem("Green"); - ui_text_color->addItem("Red"); - ui_text_color->addItem("Orange"); - ui_text_color->addItem("Blue"); - ui_text_color->addItem("Yellow"); - ui_text_color->addItem("Rainbow"); - ui_text_color->addItem("Pink"); - ui_text_color->addItem("Cyan"); - - ui_music_slider = new QSlider(Qt::Horizontal, this); - ui_music_slider->setRange(0, 100); - ui_music_slider->setValue(ao_app->get_default_music()); - - ui_sfx_slider = new QSlider(Qt::Horizontal, this); - ui_sfx_slider->setRange(0, 100); - ui_sfx_slider->setValue(ao_app->get_default_sfx()); - - ui_blip_slider = new QSlider(Qt::Horizontal, this); - ui_blip_slider->setRange(0, 100); - ui_blip_slider->setValue(ao_app->get_default_blip()); - - ui_log_limit_spinbox = new QSpinBox(this); - ui_log_limit_spinbox->setRange(0, 10000); - ui_log_limit_spinbox->setValue(ao_app->get_max_log_size()); - - ui_mute_list = new QListWidget(this); - 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("% offset"); - ui_pair_button = new AOButton(this, ao_app); - - ui_evidence_button = new AOButton(this, ao_app); - - construct_evidence(); - - construct_char_select(); - - connect(keepalive_timer, SIGNAL(timeout()), this, SLOT(ping_server())); - - connect(ui_vp_objection, SIGNAL(done()), this, SLOT(objection_done())); - connect(ui_vp_player_char, SIGNAL(done()), this, SLOT(preanim_done())); - - connect(text_delay_timer, SIGNAL(timeout()), this, SLOT(start_chat_ticking())); - connect(sfx_delay_timer, SIGNAL(timeout()), this, SLOT(play_sfx())); - - connect(chat_tick_timer, SIGNAL(timeout()), this, SLOT(chat_tick())); - - connect(realization_timer, SIGNAL(timeout()), this, SLOT(realization_done())); - - connect(testimony_show_timer, SIGNAL(timeout()), this, SLOT(hide_testimony())); - connect(testimony_hide_timer, SIGNAL(timeout()), this, SLOT(show_testimony())); - - connect(ui_emote_left, SIGNAL(clicked()), this, SLOT(on_emote_left_clicked())); - connect(ui_emote_right, SIGNAL(clicked()), this, SLOT(on_emote_right_clicked())); - - connect(ui_emote_dropdown, SIGNAL(activated(int)), this, SLOT(on_emote_dropdown_changed(int))); - connect(ui_pos_dropdown, SIGNAL(currentIndexChanged(int)), this, SLOT(on_pos_dropdown_changed(int))); - - connect(ui_mute_list, SIGNAL(clicked(QModelIndex)), this, SLOT(on_mute_list_clicked(QModelIndex))); - - connect(ui_ic_chat_message, SIGNAL(returnPressed()), this, SLOT(on_chat_return_pressed())); - - connect(ui_ooc_chat_message, SIGNAL(returnPressed()), this, SLOT(on_ooc_return_pressed())); - - connect(ui_music_list, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(on_music_list_double_clicked(QModelIndex))); - connect(ui_area_list, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(on_area_list_double_clicked(QModelIndex))); - - connect(ui_hold_it, SIGNAL(clicked()), this, SLOT(on_hold_it_clicked())); - connect(ui_objection, SIGNAL(clicked()), this, SLOT(on_objection_clicked())); - connect(ui_take_that, SIGNAL(clicked()), this, SLOT(on_take_that_clicked())); - connect(ui_custom_objection, SIGNAL(clicked()), this, SLOT(on_custom_objection_clicked())); - - connect(ui_realization, SIGNAL(clicked()), this, SLOT(on_realization_clicked())); - - connect(ui_mute, SIGNAL(clicked()), this, SLOT(on_mute_clicked())); - - connect(ui_defense_minus, SIGNAL(clicked()), this, SLOT(on_defense_minus_clicked())); - connect(ui_defense_plus, SIGNAL(clicked()), this, SLOT(on_defense_plus_clicked())); - connect(ui_prosecution_minus, SIGNAL(clicked()), this, SLOT(on_prosecution_minus_clicked())); - connect(ui_prosecution_plus, SIGNAL(clicked()), this, SLOT(on_prosecution_plus_clicked())); - - connect(ui_text_color, SIGNAL(currentIndexChanged(int)), this, SLOT(on_text_color_changed(int))); - - connect(ui_music_slider, SIGNAL(valueChanged(int)), this, SLOT(on_music_slider_moved(int))); - connect(ui_sfx_slider, SIGNAL(valueChanged(int)), this, SLOT(on_sfx_slider_moved(int))); - connect(ui_blip_slider, SIGNAL(valueChanged(int)), this, SLOT(on_blip_slider_moved(int))); - - connect(ui_log_limit_spinbox, SIGNAL(valueChanged(int)), this, SLOT(on_log_limit_changed(int))); - - connect(ui_ooc_toggle, SIGNAL(clicked()), this, SLOT(on_ooc_toggle_clicked())); - - connect(ui_music_search, SIGNAL(textChanged(QString)), this, SLOT(on_music_search_edited(QString))); - - connect(ui_witness_testimony, SIGNAL(clicked()), this, SLOT(on_witness_testimony_clicked())); - connect(ui_cross_examination, SIGNAL(clicked()), this, SLOT(on_cross_examination_clicked())); - connect(ui_guilty, SIGNAL(clicked()), this, SLOT(on_guilty_clicked())); - connect(ui_not_guilty, SIGNAL(clicked()), this, SLOT(on_not_guilty_clicked())); - - connect(ui_change_character, SIGNAL(clicked()), this, SLOT(on_change_character_clicked())); - connect(ui_reload_theme, SIGNAL(clicked()), this, SLOT(on_reload_theme_clicked())); - connect(ui_call_mod, SIGNAL(clicked()), this, SLOT(on_call_mod_clicked())); - connect(ui_settings, SIGNAL(clicked()), this, SLOT(on_settings_clicked())); - connect(ui_announce_casing, SIGNAL(clicked()), this, SLOT(on_announce_casing_clicked())); - connect(ui_switch_area_music, SIGNAL(clicked()), this, SLOT(on_switch_area_music_clicked())); - - connect(ui_pre, SIGNAL(clicked()), this, SLOT(on_pre_clicked())); - connect(ui_flip, SIGNAL(clicked()), this, SLOT(on_flip_clicked())); - connect(ui_guard, SIGNAL(clicked()), this, SLOT(on_guard_clicked())); - connect(ui_casing, SIGNAL(clicked()), this, SLOT(on_casing_clicked())); - - connect(ui_showname_enable, SIGNAL(clicked()), this, SLOT(on_showname_enable_clicked())); - - connect(ui_pair_button, SIGNAL(clicked()), this, SLOT(on_pair_clicked())); - connect(ui_pair_list, SIGNAL(clicked(QModelIndex)), this, SLOT(on_pair_list_clicked(QModelIndex))); - connect(ui_pair_offset_spinbox, SIGNAL(valueChanged(int)), this, SLOT(on_pair_offset_changed(int))); - - connect(ui_evidence_button, SIGNAL(clicked()), this, SLOT(on_evidence_button_clicked())); - - set_widgets(); - - set_char_select(); -} - -void Courtroom::set_mute_list() -{ - mute_map.clear(); - - //maps which characters are muted based on cid, none are muted by default - for (int n_cid = 0 ; n_cid < char_list.size() ; n_cid++) - { - mute_map.insert(n_cid, false); - } - - QStringList sorted_mute_list; - - for (char_type i_char : char_list) - sorted_mute_list.append(i_char.name); - - sorted_mute_list.sort(); - - for (QString i_name : sorted_mute_list) - { - //mute_map.insert(i_name, false); - ui_mute_list->addItem(i_name); - } -} - -void Courtroom::set_pair_list() -{ - QStringList sorted_pair_list; - - for (char_type i_char : char_list) - sorted_pair_list.append(i_char.name); - - sorted_pair_list.sort(); - - for (QString i_name : sorted_pair_list) - { - ui_pair_list->addItem(i_name); - } -} - -void Courtroom::set_widgets() -{ - blip_rate = ao_app->read_blip_rate(); - blank_blip = ao_app->get_blank_blip(); - - QString filename = "courtroom_design.ini"; - - pos_size_type f_courtroom = ao_app->get_element_dimensions("courtroom", filename); - - if (f_courtroom.width < 0 || f_courtroom.height < 0) - { - qDebug() << "W: did not find courtroom width or height in " << filename; - - this->resize(714, 668); - } - else - { - m_courtroom_width = f_courtroom.width; - m_courtroom_height = f_courtroom.height; - - this->resize(f_courtroom.width, f_courtroom.height); - } - - set_fonts(); - - ui_background->move(0, 0); - ui_background->resize(m_courtroom_width, m_courtroom_height); - ui_background->set_image("courtroombackground.png"); - - set_size_and_pos(ui_viewport, "viewport"); - - // If there is a point to it, show all CCCC features. - // We also do this this soon so that set_size_and_pos can hide them all later, if needed. - if (ao_app->cccc_ic_support_enabled) - { - ui_pair_button->show(); - ui_pre_non_interrupt->show(); - ui_showname_enable->show(); - ui_ic_chat_name->show(); - ui_ic_chat_name->setEnabled(true); - } - else - { - ui_pair_button->hide(); - ui_pre_non_interrupt->hide(); - ui_showname_enable->hide(); - ui_ic_chat_name->hide(); - ui_ic_chat_name->setEnabled(false); - } - - if (ao_app->casing_alerts_enabled) - { - ui_announce_casing->show(); - } - else - { - ui_announce_casing->hide(); - } - - // We also show the non-server-dependent client additions. - // Once again, if the theme can't display it, set_move_and_pos will catch them. - ui_settings->show(); - ui_log_limit_label->show(); - ui_log_limit_spinbox->show(); - - ui_vp_background->move(0, 0); - ui_vp_background->resize(ui_viewport->width(), ui_viewport->height()); - - ui_vp_speedlines->move(0, 0); - ui_vp_speedlines->combo_resize(ui_viewport->width(), ui_viewport->height()); - - ui_vp_player_char->move(0, 0); - ui_vp_player_char->combo_resize(ui_viewport->width(), ui_viewport->height()); - - ui_vp_sideplayer_char->move(0, 0); - ui_vp_sideplayer_char->combo_resize(ui_viewport->width(), ui_viewport->height()); - - //the AO2 desk element - ui_vp_desk->move(0, 0); - ui_vp_desk->resize(ui_viewport->width(), ui_viewport->height()); - - //the size of the ui_vp_legacy_desk element relies on various factors and is set in set_scene() - - double y_modifier = 147.0 / 192.0; - int final_y = static_cast(y_modifier * ui_viewport->height()); - ui_vp_legacy_desk->move(0, final_y); - ui_vp_legacy_desk->hide(); - - ui_vp_evidence_display->move(0, 0); - ui_vp_evidence_display->resize(ui_viewport->width(), ui_viewport->height()); - - set_size_and_pos(ui_vp_showname, "showname"); - - set_size_and_pos(ui_vp_message, "message"); - ui_vp_message->setTextInteractionFlags(Qt::NoTextInteraction); - ui_vp_message->setStyleSheet("background-color: rgba(0, 0, 0, 0);" - "color: white"); - - ui_vp_testimony->move(ui_viewport->x(), ui_viewport->y()); - ui_vp_testimony->resize(ui_viewport->width(), ui_viewport->height()); - ui_vp_testimony->set_image("testimony.png"); - ui_vp_testimony->hide(); - - ui_vp_realization->move(ui_viewport->x(), ui_viewport->y()); - ui_vp_realization->resize(ui_viewport->width(), ui_viewport->height()); - ui_vp_realization->set_image("realizationflash.png"); - ui_vp_realization->hide(); - - ui_vp_wtce->move(ui_viewport->x(), ui_viewport->y()); - ui_vp_wtce->combo_resize(ui_viewport->width(), ui_viewport->height()); - - ui_vp_objection->move(ui_viewport->x(), ui_viewport->y()); - ui_vp_objection->combo_resize(ui_viewport->width(), ui_viewport->height()); - - set_size_and_pos(ui_ic_chatlog, "ic_chatlog"); - - set_size_and_pos(ui_ms_chatlog, "ms_chatlog"); - - set_size_and_pos(ui_server_chatlog, "server_chatlog"); - - set_size_and_pos(ui_mute_list, "mute_list"); - ui_mute_list->hide(); - - set_size_and_pos(ui_pair_list, "pair_list"); - ui_pair_list->hide(); - set_size_and_pos(ui_pair_offset_spinbox, "pair_offset_spinbox"); - ui_pair_offset_spinbox->hide(); - set_size_and_pos(ui_pair_button, "pair_button"); - ui_pair_button->set_image("pair_button.png"); - - set_size_and_pos(ui_area_list, "music_list"); - ui_area_list->setStyleSheet("background-color: rgba(0, 0, 0, 0);"); - - set_size_and_pos(ui_music_list, "music_list"); - - if (is_ao2_bg) - { - set_size_and_pos(ui_ic_chat_message, "ao2_ic_chat_message"); - set_size_and_pos(ui_vp_chatbox, "ao2_chatbox"); - set_size_and_pos(ui_ic_chat_name, "ao2_ic_chat_name"); - } - else - { - set_size_and_pos(ui_ic_chat_message, "ic_chat_message"); - set_size_and_pos(ui_vp_chatbox, "chatbox"); - set_size_and_pos(ui_ic_chat_name, "ic_chat_name"); - } - - ui_ic_chat_message->setStyleSheet("QLineEdit{background-color: rgba(100, 100, 100, 255);}"); - ui_ic_chat_name->setStyleSheet("QLineEdit{background-color: rgba(180, 180, 180, 255);}"); - - ui_vp_chatbox->set_image("chatmed.png"); - ui_vp_chatbox->hide(); - - ui_muted->resize(ui_ic_chat_message->width(), ui_ic_chat_message->height()); - ui_muted->set_image("muted.png"); - - set_size_and_pos(ui_ooc_chat_message, "ooc_chat_message"); - ui_ooc_chat_message->setStyleSheet("background-color: rgba(0, 0, 0, 0);"); - - set_size_and_pos(ui_ooc_chat_name, "ooc_chat_name"); - ui_ooc_chat_name->setStyleSheet("background-color: rgba(0, 0, 0, 0);"); - - //set_size_and_pos(ui_area_password, "area_password"); - set_size_and_pos(ui_music_search, "music_search"); - - set_size_and_pos(ui_emotes, "emotes"); - - set_size_and_pos(ui_emote_left, "emote_left"); - ui_emote_left->set_image("arrow_left.png"); - - set_size_and_pos(ui_emote_right, "emote_right"); - ui_emote_right->set_image("arrow_right.png"); - - set_size_and_pos(ui_emote_dropdown, "emote_dropdown"); - set_size_and_pos(ui_pos_dropdown, "pos_dropdown"); - - set_size_and_pos(ui_defense_bar, "defense_bar"); - ui_defense_bar->set_image("defensebar" + QString::number(defense_bar_state) + ".png"); - - set_size_and_pos(ui_prosecution_bar, "prosecution_bar"); - ui_prosecution_bar->set_image("prosecutionbar" + QString::number(prosecution_bar_state) + ".png"); - - set_size_and_pos(ui_music_label, "music_label"); - ui_music_label->setText("Music"); - set_size_and_pos(ui_sfx_label, "sfx_label"); - ui_sfx_label->setText("Sfx"); - set_size_and_pos(ui_blip_label, "blip_label"); - ui_blip_label->setText("Blips"); - - set_size_and_pos(ui_log_limit_label, "log_limit_label"); - ui_log_limit_label->setText("Log limit"); - - set_size_and_pos(ui_hold_it, "hold_it"); - ui_hold_it->set_image("holdit.png"); - set_size_and_pos(ui_objection, "objection"); - ui_objection->set_image("objection.png"); - set_size_and_pos(ui_take_that, "take_that"); - ui_take_that->set_image("takethat.png"); - - set_size_and_pos(ui_ooc_toggle, "ooc_toggle"); - ui_ooc_toggle->setText("Server"); - - set_size_and_pos(ui_witness_testimony, "witness_testimony"); - ui_witness_testimony->set_image("witnesstestimony.png"); - set_size_and_pos(ui_cross_examination, "cross_examination"); - ui_cross_examination->set_image("crossexamination.png"); - - set_size_and_pos(ui_guilty, "guilty"); - ui_guilty->set_image("guilty.png"); - set_size_and_pos(ui_not_guilty, "not_guilty"); - ui_not_guilty->set_image("notguilty.png"); - - set_size_and_pos(ui_change_character, "change_character"); - ui_change_character->setText("Change character"); - - set_size_and_pos(ui_reload_theme, "reload_theme"); - ui_reload_theme->setText("Reload theme"); - - set_size_and_pos(ui_call_mod, "call_mod"); - ui_call_mod->setText("Call mod"); - - set_size_and_pos(ui_settings, "settings"); - ui_settings->setText("Settings"); - - set_size_and_pos(ui_announce_casing, "casing_button"); - ui_announce_casing->setText("Casing"); - - set_size_and_pos(ui_switch_area_music, "switch_area_music"); - ui_switch_area_music->setText("A/M"); - - set_size_and_pos(ui_pre, "pre"); - ui_pre->setText("Preanim"); - - set_size_and_pos(ui_pre_non_interrupt, "pre_no_interrupt"); - set_size_and_pos(ui_flip, "flip"); - - set_size_and_pos(ui_guard, "guard"); - - set_size_and_pos(ui_casing, "casing"); - - set_size_and_pos(ui_showname_enable, "showname_enable"); - - set_size_and_pos(ui_custom_objection, "custom_objection"); - ui_custom_objection->set_image("custom.png"); - - set_size_and_pos(ui_realization, "realization"); - ui_realization->set_image("realization.png"); - - set_size_and_pos(ui_mute, "mute_button"); - ui_mute->set_image("mute.png"); - - set_size_and_pos(ui_defense_plus, "defense_plus"); - ui_defense_plus->set_image("defplus.png"); - - set_size_and_pos(ui_defense_minus, "defense_minus"); - ui_defense_minus->set_image("defminus.png"); - - set_size_and_pos(ui_prosecution_plus, "prosecution_plus"); - ui_prosecution_plus->set_image("proplus.png"); - - set_size_and_pos(ui_prosecution_minus, "prosecution_minus"); - ui_prosecution_minus->set_image("prominus.png"); - - set_size_and_pos(ui_text_color, "text_color"); - - set_size_and_pos(ui_music_slider, "music_slider"); - set_size_and_pos(ui_sfx_slider, "sfx_slider"); - set_size_and_pos(ui_blip_slider, "blip_slider"); - - set_size_and_pos(ui_log_limit_spinbox, "log_limit_spinbox"); - - set_size_and_pos(ui_evidence_button, "evidence_button"); - ui_evidence_button->set_image("evidencebutton.png"); - - set_size_and_pos(ui_evidence, "evidence_background"); - ui_evidence->set_image("evidencebackground.png"); - - set_size_and_pos(ui_evidence_name, "evidence_name"); - - set_size_and_pos(ui_evidence_buttons, "evidence_buttons"); - - set_size_and_pos(ui_evidence_left, "evidence_left"); - ui_evidence_left->set_image("arrow_left.png"); - - set_size_and_pos(ui_evidence_right, "evidence_right"); - ui_evidence_right->set_image("arrow_right.png"); - - set_size_and_pos(ui_evidence_present, "evidence_present"); - ui_evidence_present->set_image("present_disabled.png"); - - set_size_and_pos(ui_evidence_overlay, "evidence_overlay"); - ui_evidence_overlay->set_image("evidenceoverlay.png"); - - set_size_and_pos(ui_evidence_delete, "evidence_delete"); - ui_evidence_delete->set_image("deleteevidence.png"); - - set_size_and_pos(ui_evidence_image_name, "evidence_image_name"); - - set_size_and_pos(ui_evidence_image_button, "evidence_image_button"); - - set_size_and_pos(ui_evidence_x, "evidence_x"); - ui_evidence_x->set_image("evidencex.png"); - - set_size_and_pos(ui_evidence_description, "evidence_description"); - - ui_selector->set_image("char_selector.png"); - ui_selector->hide(); - - set_size_and_pos(ui_back_to_lobby, "back_to_lobby"); - ui_back_to_lobby->setText("Back to Lobby"); - - set_size_and_pos(ui_char_password, "char_password"); - - set_size_and_pos(ui_char_buttons, "char_buttons"); - - set_size_and_pos(ui_char_select_left, "char_select_left"); - ui_char_select_left->set_image("arrow_left.png"); - - set_size_and_pos(ui_char_select_right, "char_select_right"); - ui_char_select_right->set_image("arrow_right.png"); - - set_size_and_pos(ui_spectator, "spectator"); -} - -void Courtroom::set_fonts() -{ - set_font(ui_vp_showname, "showname"); - set_font(ui_vp_message, "message"); - set_font(ui_ic_chatlog, "ic_chatlog"); - set_font(ui_ms_chatlog, "ms_chatlog"); - set_font(ui_server_chatlog, "server_chatlog"); - set_font(ui_music_list, "music_list"); - set_font(ui_area_list, "music_list"); - - // Set color of labels and checkboxes - const QString design_file = "courtroom_fonts.ini"; - QColor f_color = ao_app->get_color("label_color", design_file); - QString color_string = "color: rgba(" + - QString::number(f_color.red()) + ", " + - QString::number(f_color.green()) + ", " + - QString::number(f_color.blue()) + ", 255); }"; - QString style_sheet_string = "QLabel {" + color_string + "}" - "QCheckBox {" + color_string + "}"; - setStyleSheet(style_sheet_string); -} - -void Courtroom::set_font(QWidget *widget, QString p_identifier) -{ - QString design_file = "courtroom_fonts.ini"; - int f_weight = ao_app->get_font_size(p_identifier, design_file); - QString class_name = widget->metaObject()->className(); - - widget->setFont(QFont("Sans", f_weight)); - - QColor f_color = ao_app->get_color(p_identifier + "_color", design_file); - - QString style_sheet_string = class_name + " { background-color: rgba(0, 0, 0, 0);\n" + - "color: rgba(" + - QString::number(f_color.red()) + ", " + - QString::number(f_color.green()) + ", " + - QString::number(f_color.blue()) + ", 255); }"; - - widget->setStyleSheet(style_sheet_string); -} - -void Courtroom::set_window_title(QString p_title) -{ - this->setWindowTitle(p_title); -} - -void Courtroom::set_size_and_pos(QWidget *p_widget, QString p_identifier) -{ - QString filename = "courtroom_design.ini"; - - pos_size_type design_ini_result = ao_app->get_element_dimensions(p_identifier, filename); - - if (design_ini_result.width < 0 || design_ini_result.height < 0) - { - qDebug() << "W: could not find \"" << p_identifier << "\" in " << filename; - p_widget->hide(); - } - else - { - p_widget->move(design_ini_result.x, design_ini_result.y); - p_widget->resize(design_ini_result.width, design_ini_result.height); - } -} - -void Courtroom::set_taken(int n_char, bool p_taken) -{ - if (n_char >= char_list.size()) - { - qDebug() << "W: set_taken attempted to set an index bigger than char_list size"; - return; - } - - char_type f_char; - f_char.name = char_list.at(n_char).name; - f_char.description = char_list.at(n_char).description; - f_char.taken = p_taken; - f_char.evidence_string = char_list.at(n_char).evidence_string; - - char_list.replace(n_char, f_char); -} - -void Courtroom::done_received() -{ - m_cid = -1; - - music_player->set_volume(0); - sfx_player->set_volume(0); - objection_player->set_volume(0); - blip_player->set_volume(0); - - set_char_select_page(); - - set_mute_list(); - set_pair_list(); - - set_char_select(); - - show(); - - ui_spectator->show(); -} - -void Courtroom::set_background(QString p_background) -{ - testimony_in_progress = false; - - current_background = p_background; - - is_ao2_bg = file_exists(ao_app->get_background_path("defensedesk.png")) && - file_exists(ao_app->get_background_path("prosecutiondesk.png")) && - file_exists(ao_app->get_background_path("stand.png")); - - if (is_ao2_bg) - { - set_size_and_pos(ui_vp_chatbox, "ao2_chatbox"); - set_size_and_pos(ui_ic_chat_message, "ao2_ic_chat_message"); - } - else - { - set_size_and_pos(ui_vp_chatbox, "chatbox"); - set_size_and_pos(ui_ic_chat_message, "ic_chat_message"); - } -} - -void Courtroom::enter_courtroom(int p_cid) -{ - m_cid = p_cid; - - QString f_char; - - if (m_cid == -1) - { - if (ao_app->is_discord_enabled()) - ao_app->discord->state_spectate(); - f_char = ""; - } - else - { - f_char = ao_app->get_char_name(char_list.at(m_cid).name); - - if (ao_app->is_discord_enabled()) - ao_app->discord->state_character(f_char.toStdString()); - } - - current_char = f_char; - - current_emote_page = 0; - current_emote = 0; - - if (m_cid == -1) - ui_emotes->hide(); - else - ui_emotes->show(); - - set_emote_page(); - set_emote_dropdown(); - - current_evidence_page = 0; - current_evidence = 0; - - set_evidence_page(); - - QString side = ao_app->get_char_side(f_char); - - if (side == "jud") - { - ui_witness_testimony->show(); - ui_cross_examination->show(); - ui_not_guilty->show(); - ui_guilty->show(); - ui_defense_minus->show(); - ui_defense_plus->show(); - ui_prosecution_minus->show(); - ui_prosecution_plus->show(); - } - else - { - ui_witness_testimony->hide(); - ui_cross_examination->hide(); - ui_guilty->hide(); - ui_not_guilty->hide(); - ui_defense_minus->hide(); - ui_defense_plus->hide(); - ui_prosecution_minus->hide(); - ui_prosecution_plus->hide(); - } - - if (ao_app->custom_objection_enabled && - (file_exists(ao_app->get_character_path(current_char, "custom.gif")) || - file_exists(ao_app->get_character_path(current_char, "custom.apng"))) && - file_exists(ao_app->get_character_path(current_char, "custom.wav"))) - ui_custom_objection->show(); - else - ui_custom_objection->hide(); - - if (ao_app->flipping_enabled) - ui_flip->show(); - else - ui_flip->hide(); - - if (ao_app->casing_alerts_enabled) - ui_casing->show(); - else - ui_casing->hide(); - - list_music(); - list_areas(); - - music_player->set_volume(ui_music_slider->value()); - sfx_player->set_volume(ui_sfx_slider->value()); - objection_player->set_volume(ui_sfx_slider->value()); - blip_player->set_volume(ui_blip_slider->value()); - - testimony_in_progress = false; - - set_widgets(); - - //ui_server_chatlog->setHtml(ui_server_chatlog->toHtml()); - - ui_char_select_background->hide(); - - ui_ic_chat_message->setEnabled(m_cid != -1); - ui_ic_chat_message->setFocus(); -} - -void Courtroom::list_music() -{ - ui_music_list->clear(); - music_row_to_number.clear(); - - QString f_file = "courtroom_design.ini"; - - QBrush found_brush(ao_app->get_color("found_song_color", f_file)); - QBrush missing_brush(ao_app->get_color("missing_song_color", f_file)); - - int n_listed_songs = 0; - - for (int n_song = 0 ; n_song < music_list.size() ; ++n_song) - { - QString i_song = music_list.at(n_song); - QString i_song_listname = i_song; - i_song_listname = i_song_listname.left(i_song_listname.lastIndexOf(".")); - - if (i_song.toLower().contains(ui_music_search->text().toLower())) - { - ui_music_list->addItem(i_song_listname); - music_row_to_number.append(n_song); - - QString song_path = ao_app->get_music_path(i_song); - - if (file_exists(song_path)) - ui_music_list->item(n_listed_songs)->setBackground(found_brush); - else - ui_music_list->item(n_listed_songs)->setBackground(missing_brush); - - ++n_listed_songs; - } - } -} - -void Courtroom::list_areas() -{ - ui_area_list->clear(); - area_row_to_number.clear(); - - QString f_file = "courtroom_design.ini"; - - QBrush free_brush(ao_app->get_color("area_free_color", f_file)); - QBrush lfp_brush(ao_app->get_color("area_lfp_color", f_file)); - QBrush casing_brush(ao_app->get_color("area_casing_color", f_file)); - QBrush recess_brush(ao_app->get_color("area_recess_color", f_file)); - QBrush rp_brush(ao_app->get_color("area_rp_color", f_file)); - QBrush gaming_brush(ao_app->get_color("area_gaming_color", f_file)); - QBrush locked_brush(ao_app->get_color("area_locked_color", f_file)); - - int n_listed_areas = 0; - - for (int n_area = 0 ; n_area < area_list.size() ; ++n_area) - { - QString i_area = ""; - i_area.append("["); - i_area.append(QString::number(n_area)); - i_area.append("] "); - - i_area.append(area_list.at(n_area)); - - if (ao_app->arup_enabled) - { - i_area.append("\n "); - - i_area.append(arup_statuses.at(n_area)); - i_area.append(" | CM: "); - i_area.append(arup_cms.at(n_area)); - - i_area.append("\n "); - - i_area.append(QString::number(arup_players.at(n_area))); - i_area.append(" users | "); - - i_area.append(arup_locks.at(n_area)); - } - - if (i_area.toLower().contains(ui_music_search->text().toLower())) - { - ui_area_list->addItem(i_area); - area_row_to_number.append(n_area); - - if (ao_app->arup_enabled) - { - // Colouring logic here. - ui_area_list->item(n_listed_areas)->setBackground(free_brush); - if (arup_locks.at(n_area) == "LOCKED") - { - ui_area_list->item(n_listed_areas)->setBackground(locked_brush); - } - else - { - if (arup_statuses.at(n_area) == "LOOKING-FOR-PLAYERS") - ui_area_list->item(n_listed_areas)->setBackground(lfp_brush); - else if (arup_statuses.at(n_area) == "CASING") - ui_area_list->item(n_listed_areas)->setBackground(casing_brush); - else if (arup_statuses.at(n_area) == "RECESS") - ui_area_list->item(n_listed_areas)->setBackground(recess_brush); - else if (arup_statuses.at(n_area) == "RP") - ui_area_list->item(n_listed_areas)->setBackground(rp_brush); - else if (arup_statuses.at(n_area) == "GAMING") - ui_area_list->item(n_listed_areas)->setBackground(gaming_brush); - } - } - else - { - ui_area_list->item(n_listed_areas)->setBackground(free_brush); - } - - ++n_listed_areas; - } - } -} - -void Courtroom::append_ms_chatmessage(QString f_name, QString f_message) -{ - ui_ms_chatlog->append_chatmessage(f_name, f_message, ao_app->get_color("ooc_default_color", "courtroom_design.ini").name()); -} - -void Courtroom::append_server_chatmessage(QString p_name, QString p_message, QString p_colour) -{ - QString colour = "#000000"; - - if (p_colour == "0") - colour = ao_app->get_color("ooc_default_color", "courtroom_design.ini").name(); - if (p_colour == "1") - colour = ao_app->get_color("ooc_server_color", "courtroom_design.ini").name(); - - ui_server_chatlog->append_chatmessage(p_name, p_message, colour); -} - -void Courtroom::on_chat_return_pressed() -{ - if (ui_ic_chat_message->text() == "" || is_muted) - return; - - if ((anim_state < 3 || text_state < 2) && - objection_state == 0) - return; - - //MS# - //deskmod# - //pre-emote# - //character# - //emote# - //message# - //side# - //sfx-name# - //emote_modifier# - //char_id# - //sfx_delay# - //objection_modifier# - //evidence# - //placeholder# - //realization# - //text_color#% - - // Additionally, in our case: - - //showname# - //other_charid# - //self_offset# - //noninterrupting_preanim#% - - QStringList packet_contents; - - QString f_side = ao_app->get_char_side(current_char); - - QString f_desk_mod = "chat"; - - if (ao_app->desk_mod_enabled) - { - f_desk_mod = QString::number(ao_app->get_desk_mod(current_char, current_emote)); - if (f_desk_mod == "-1") - f_desk_mod = "chat"; - } - - packet_contents.append(f_desk_mod); - - packet_contents.append(ao_app->get_pre_emote(current_char, current_emote)); - - packet_contents.append(current_char); - - packet_contents.append(ao_app->get_emote(current_char, current_emote)); - - packet_contents.append(ui_ic_chat_message->text()); - - packet_contents.append(f_side); - - packet_contents.append(ao_app->get_sfx_name(current_char, current_emote)); - - 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 == 5) - f_emote_mod = 6; - else - f_emote_mod = 2; - } - } - else if (ui_pre->isChecked() and !ui_pre_non_interrupt->isChecked()) - { - if (f_emote_mod == 0) - f_emote_mod = 1; - else if (f_emote_mod == 5 && ao_app->prezoom_enabled) - f_emote_mod = 4; - } - else - { - if (f_emote_mod == 1) - f_emote_mod = 0; - else if (f_emote_mod == 4) - f_emote_mod = 5; - } - - packet_contents.append(QString::number(f_emote_mod)); - packet_contents.append(QString::number(m_cid)); - - packet_contents.append(QString::number(ao_app->get_sfx_delay(current_char, current_emote))); - - QString f_obj_state; - - if ((objection_state == 4 && !ao_app->custom_objection_enabled) || - (objection_state < 0)) - f_obj_state = "0"; - else - f_obj_state = QString::number(objection_state); - - packet_contents.append(f_obj_state); - - if (is_presenting_evidence) - //the evidence index is shifted by 1 because 0 is no evidence per legacy standards - //besides, older clients crash if we pass -1 - packet_contents.append(QString::number(current_evidence + 1)); - else - packet_contents.append("0"); - - QString f_flip; - - if (ao_app->flipping_enabled) - { - if (ui_flip->isChecked()) - f_flip = "1"; - else - f_flip = "0"; - } - else - f_flip = QString::number(m_cid); - - packet_contents.append(f_flip); - - packet_contents.append(QString::number(realization_state)); - - QString f_text_color; - - if (text_color < 0) - f_text_color = "0"; - else if (text_color > 8) - f_text_color = "0"; - else - f_text_color = QString::number(text_color); - - packet_contents.append(f_text_color); - - // If the server we're on supports CCCC stuff, we should use it! - if (ao_app->cccc_ic_support_enabled) - { - // If there is a showname entered, use that -- else, just send an empty packet-part. - if (!ui_ic_chat_name->text().isEmpty()) - { - packet_contents.append(ui_ic_chat_name->text()); - } - else - { - packet_contents.append(""); - } - - // Similarly, we send over whom we're paired with, unless we have chosen ourselves. - // Or a charid of -1 or lower, through some means. - if (other_charid > -1 && other_charid != m_cid) - { - packet_contents.append(QString::number(other_charid)); - packet_contents.append(QString::number(offset_with_pair)); - } - else - { - packet_contents.append("-1"); - packet_contents.append("0"); - } - - // Finally, we send over if we want our pres to not interrupt. - if (ui_pre_non_interrupt->isChecked() && ui_pre->isChecked()) - { - packet_contents.append("1"); - } - else - { - packet_contents.append("0"); - } - } - - ao_app->send_server_packet(new AOPacket("MS", packet_contents)); -} - -void Courtroom::handle_chatmessage(QStringList *p_contents) -{ - // Instead of checking for whether a message has at least chatmessage_size - // amount of packages, we'll check if it has at least 15. - // That was the original chatmessage_size. - if (p_contents->size() < 15) - return; - - for (int n_string = 0 ; n_string < chatmessage_size ; ++n_string) - { - //m_chatmessage[n_string] = p_contents->at(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 amongst the packet's content. - // We also have to check if the server even supports CCCC's IC features, or if it's just japing us. - // Also, don't forget! A size 15 message will have indices from 0 to 14. - if (n_string < p_contents->size() && - (n_string < 15 || ao_app->cccc_ic_support_enabled)) - { - m_chatmessage[n_string] = p_contents->at(n_string); - } - else - { - m_chatmessage[n_string] = ""; - } - } - - int f_char_id = m_chatmessage[CHAR_ID].toInt(); - - if (f_char_id < 0 || f_char_id >= char_list.size()) - return; - - if (mute_map.value(m_chatmessage[CHAR_ID].toInt())) - return; - - QString f_showname; - if (m_chatmessage[SHOWNAME].isEmpty() || !ui_showname_enable->isChecked()) - { - f_showname = ao_app->get_showname(char_list.at(f_char_id).name); - } - else - { - f_showname = m_chatmessage[SHOWNAME]; - } - - - QString f_message = f_showname + ": " + m_chatmessage[MESSAGE] + '\n'; - - if (f_message == previous_ic_message) - return; - - text_state = 0; - anim_state = 0; - ui_vp_objection->stop(); - ui_vp_player_char->stop(); - chat_tick_timer->stop(); - ui_vp_evidence_display->reset(); - - chatmessage_is_empty = m_chatmessage[MESSAGE] == " " || m_chatmessage[MESSAGE] == ""; - - if (m_chatmessage[MESSAGE] == ui_ic_chat_message->text() && m_chatmessage[CHAR_ID].toInt() == m_cid) - { - ui_ic_chat_message->clear(); - objection_state = 0; - realization_state = 0; - is_presenting_evidence = false; - ui_pre->setChecked(false); - ui_hold_it->set_image("holdit.png"); - ui_objection->set_image("objection.png"); - ui_take_that->set_image("takethat.png"); - ui_custom_objection->set_image("custom.png"); - ui_realization->set_image("realization.png"); - ui_evidence_present->set_image("present_disabled.png"); - } - - chatlogpiece* temp = new chatlogpiece(ao_app->get_showname(char_list.at(f_char_id).name), f_showname, ": " + m_chatmessage[MESSAGE], false); - ic_chatlog_history.append(*temp); - - while(ic_chatlog_history.size() > log_maximum_blocks && log_maximum_blocks > 0) - { - ic_chatlog_history.removeFirst(); - } - - append_ic_text(": " + m_chatmessage[MESSAGE], f_showname); - - previous_ic_message = f_message; - - int objection_mod = m_chatmessage[OBJECTION_MOD].toInt(); - QString f_char = m_chatmessage[CHAR_NAME]; - QString f_custom_theme = ao_app->get_char_shouts(f_char); - - //if an objection is used - if (objection_mod <= 4 && objection_mod >= 1) - { - switch (objection_mod) - { - case 1: - ui_vp_objection->play("holdit", f_char, f_custom_theme); - objection_player->play("holdit.wav", f_char, f_custom_theme); - break; - case 2: - ui_vp_objection->play("objection", f_char, f_custom_theme); - objection_player->play("objection.wav", f_char, f_custom_theme); - break; - case 3: - ui_vp_objection->play("takethat", f_char, f_custom_theme); - objection_player->play("takethat.wav", f_char, f_custom_theme); - break; - //case 4 is AO2 only - case 4: - ui_vp_objection->play("custom", f_char, f_custom_theme); - objection_player->play("custom.wav", f_char, f_custom_theme); - break; - default: - qDebug() << "W: Logic error in objection switch statement!"; - } - - int emote_mod = m_chatmessage[EMOTE_MOD].toInt(); - - if (emote_mod == 0) - m_chatmessage[EMOTE_MOD] = 1; - } - else - handle_chatmessage_2(); -} - -void Courtroom::objection_done() -{ - handle_chatmessage_2(); -} - -void Courtroom::handle_chatmessage_2() -{ - ui_vp_speedlines->stop(); - ui_vp_player_char->stop(); - - if (m_chatmessage[SHOWNAME].isEmpty() || !ui_showname_enable->isChecked()) - { - QString real_name = char_list.at(m_chatmessage[CHAR_ID].toInt()).name; - - QString f_showname = ao_app->get_showname(real_name); - - ui_vp_showname->setText(f_showname); - } - else - { - ui_vp_showname->setText(m_chatmessage[SHOWNAME]); - } - - ui_vp_message->clear(); - ui_vp_chatbox->hide(); - - QString chatbox = ao_app->get_chat(m_chatmessage[CHAR_NAME]); - - if (chatbox == "") - ui_vp_chatbox->set_image("chatmed.png"); - else - { - QString chatbox_path = ao_app->get_base_path() + "misc/" + chatbox + "/chatbox.png"; - ui_vp_chatbox->set_image_from_path(chatbox_path); - } - - ui_vp_showname->setStyleSheet("QLabel { color : " + get_text_color("_showname").name() + "; }"); - - set_scene(); - set_text_color(); - - // Check if the message needs to be centered. - QString f_message = m_chatmessage[MESSAGE]; - if (f_message.size() >= 2) - { - if (f_message.startsWith("~~")) - { - message_is_centered = true; - } - else - { - message_is_centered = false; - } - } - else - { - ui_vp_message->setAlignment(Qt::AlignLeft); - } - - - int emote_mod = m_chatmessage[EMOTE_MOD].toInt(); - - if (ao_app->flipping_enabled && m_chatmessage[FLIP].toInt() == 1) - ui_vp_player_char->set_flipped(true); - else - ui_vp_player_char->set_flipped(false); - - QString side = m_chatmessage[SIDE]; - - // Making the second character appear. - if (m_chatmessage[OTHER_CHARID].isEmpty()) - { - // If there is no second character, hide 'em, and center the first. - ui_vp_sideplayer_char->hide(); - ui_vp_sideplayer_char->move(0,0); - - ui_vp_player_char->move(0,0); - } - else - { - bool ok; - int got_other_charid = m_chatmessage[OTHER_CHARID].toInt(&ok); - if (ok) - { - if (got_other_charid > -1) - { - // If there is, show them! - ui_vp_sideplayer_char->show(); - - // Depending on where we are, we offset the characters, and reorder their stacking. - if (side == "def") - { - // We also move the character down depending on how far the are to the right. - int hor_offset = m_chatmessage[SELF_OFFSET].toInt(); - int vert_offset = 0; - if (hor_offset > 0) - { - vert_offset = hor_offset / 10; - } - ui_vp_player_char->move(ui_viewport->width() * hor_offset / 100, ui_viewport->height() * vert_offset / 100); - - // We do the same with the second character. - int hor2_offset = m_chatmessage[OTHER_OFFSET].toInt(); - int vert2_offset = 0; - if (hor2_offset > 0) - { - vert2_offset = hor2_offset / 10; - } - ui_vp_sideplayer_char->move(ui_viewport->width() * hor2_offset / 100, ui_viewport->height() * vert2_offset / 100); - - // Finally, we reorder them based on who is more to the left. - // The person more to the left is more in the front. - if (hor2_offset >= hor_offset) - { - ui_vp_sideplayer_char->raise(); - ui_vp_player_char->raise(); - } - else - { - ui_vp_player_char->raise(); - ui_vp_sideplayer_char->raise(); - } - ui_vp_desk->raise(); - ui_vp_legacy_desk->raise(); - } - else if (side == "pro") - { - // Almost the same thing happens here, but in reverse. - int hor_offset = m_chatmessage[SELF_OFFSET].toInt(); - int vert_offset = 0; - if (hor_offset < 0) - { - // We don't want to RAISE the char off the floor. - vert_offset = -1 * hor_offset / 10; - } - ui_vp_player_char->move(ui_viewport->width() * hor_offset / 100, ui_viewport->height() * vert_offset / 100); - - // We do the same with the second character. - int hor2_offset = m_chatmessage[OTHER_OFFSET].toInt(); - int vert2_offset = 0; - if (hor2_offset < 0) - { - vert2_offset = -1 * hor2_offset / 10; - } - ui_vp_sideplayer_char->move(ui_viewport->width() * hor2_offset / 100, ui_viewport->height() * vert2_offset / 100); - - // Finally, we reorder them based on who is more to the right. - if (hor2_offset <= hor_offset) - { - ui_vp_sideplayer_char->raise(); - ui_vp_player_char->raise(); - } - else - { - ui_vp_player_char->raise(); - ui_vp_sideplayer_char->raise(); - } - ui_vp_desk->raise(); - ui_vp_legacy_desk->raise(); - } - else - { - // In every other case, the person more to the left is on top. - // These cases also don't move the characters down. - int hor_offset = m_chatmessage[SELF_OFFSET].toInt(); - ui_vp_player_char->move(ui_viewport->width() * hor_offset / 100, 0); - - // We do the same with the second character. - int hor2_offset = m_chatmessage[OTHER_OFFSET].toInt(); - ui_vp_sideplayer_char->move(ui_viewport->width() * hor2_offset / 100, 0); - - // Finally, we reorder them based on who is more to the left. - // The person more to the left is more in the front. - if (hor2_offset >= hor_offset) - { - ui_vp_sideplayer_char->raise(); - ui_vp_player_char->raise(); - } - else - { - ui_vp_player_char->raise(); - ui_vp_sideplayer_char->raise(); - } - ui_vp_desk->raise(); - ui_vp_legacy_desk->raise(); - } - // We should probably also play the other character's idle emote. - if (ao_app->flipping_enabled && m_chatmessage[OTHER_FLIP].toInt() == 1) - ui_vp_sideplayer_char->set_flipped(true); - else - ui_vp_sideplayer_char->set_flipped(false); - ui_vp_sideplayer_char->play_idle(m_chatmessage[OTHER_NAME], m_chatmessage[OTHER_EMOTE]); - } - else - { - // If the server understands other characters, but there - // really is no second character, hide 'em, and center the first. - ui_vp_sideplayer_char->hide(); - ui_vp_sideplayer_char->move(0,0); - - ui_vp_player_char->move(0,0); - } - } - } - - switch (emote_mod) - { - case 1: case 2: case 6: - play_preanim(false); - break; - case 0: case 5: - if (m_chatmessage[NONINTERRUPTING_PRE].toInt() == 0) - handle_chatmessage_3(); - else - play_preanim(true); - break; - default: - qDebug() << "W: invalid emote mod: " << QString::number(emote_mod); - } -} - -void Courtroom::handle_chatmessage_3() -{ - start_chat_ticking(); - - int f_evi_id = m_chatmessage[EVIDENCE_ID].toInt(); - QString f_side = m_chatmessage[SIDE]; - - if (f_evi_id > 0 && f_evi_id <= local_evidence_list.size()) - { - //shifted by 1 because 0 is no evidence per legacy standards - QString f_image = local_evidence_list.at(f_evi_id - 1).image; - //def jud and hlp should display the evidence icon on the RIGHT side - bool is_left_side = !(f_side == "def" || f_side == "hlp" || f_side == "jud" || f_side == "jur"); - ui_vp_evidence_display->show_evidence(f_image, is_left_side, ui_sfx_slider->value()); - } - - int emote_mod = m_chatmessage[EMOTE_MOD].toInt(); - - QString side = m_chatmessage[SIDE]; - - if (emote_mod == 5 || - emote_mod == 6) - { - ui_vp_desk->hide(); - ui_vp_legacy_desk->hide(); - - // Since we're zooming, hide the second character, and centre the first. - ui_vp_sideplayer_char->hide(); - ui_vp_player_char->move(0,0); - - if (side == "pro" || - side == "hlp" || - side == "wit") - ui_vp_speedlines->play("prosecution_speedlines"); - else - ui_vp_speedlines->play("defense_speedlines"); - - } - - int f_anim_state = 0; - //BLUE is from an enum in datatypes.h - bool text_is_blue = m_chatmessage[TEXT_COLOR].toInt() == BLUE; - - if (!text_is_blue && text_state == 1) - { - //talking - f_anim_state = 2; - entire_message_is_blue = false; - } - else - { - //idle - f_anim_state = 3; - entire_message_is_blue = true; - } - - if (f_anim_state <= anim_state) - return; - - ui_vp_player_char->stop(); - QString f_char = m_chatmessage[CHAR_NAME]; - QString f_emote = m_chatmessage[EMOTE]; - - if (f_anim_state == 2) { - ui_vp_player_char->play_talking(f_char, f_emote); - anim_state = 2; - } - else - { - ui_vp_player_char->play_idle(f_char, f_emote); - anim_state = 3; - } - - QString f_message = m_chatmessage[MESSAGE]; - QStringList call_words = ao_app->get_call_words(); - - for (QString word : call_words) - { - if (f_message.contains(word, Qt::CaseInsensitive)) - { - modcall_player->play(ao_app->get_sfx("word_call")); - ao_app->alert(this); - - break; - } - } - -} - -QString Courtroom::filter_ic_text(QString p_text) -{ - // Get rid of centering. - if(p_text.startsWith(": ~~")) - { - // Don't forget, the p_text part actually everything after the name! - // Hence why we check for ': ~~'. - - // Let's remove those two tildes, then. - // : _ ~ ~ - // 0 1 2 3 - p_text.remove(2,2); - } - - // Get rid of the inline-colouring. - // I know, I know, excessive code duplication. - // Nobody looks in here, I'm fine. - int trick_check_pos = 0; - bool ic_next_is_not_special = false; - QString f_character = p_text.at(trick_check_pos); - std::stack ic_colour_stack; - while (trick_check_pos < p_text.size()) - { - f_character = p_text.at(trick_check_pos); - - // Escape character. - if (f_character == "\\" and !ic_next_is_not_special) - { - ic_next_is_not_special = true; - p_text.remove(trick_check_pos,1); - } - - // Text speed modifier. - else if (f_character == "{" and !ic_next_is_not_special) - { - p_text.remove(trick_check_pos,1); - } - else if (f_character == "}" and !ic_next_is_not_special) - { - p_text.remove(trick_check_pos,1); - } - - // Orange inline colourisation. - else if (f_character == "|" and !ic_next_is_not_special) - { - if (!ic_colour_stack.empty()) - { - if (ic_colour_stack.top() == INLINE_ORANGE) - { - ic_colour_stack.pop(); - p_text.remove(trick_check_pos,1); - } - else - { - ic_colour_stack.push(INLINE_ORANGE); - p_text.remove(trick_check_pos,1); - } - } - else - { - ic_colour_stack.push(INLINE_ORANGE); - p_text.remove(trick_check_pos,1); - } - } - - // Blue inline colourisation. - else if (f_character == "(" and !ic_next_is_not_special) - { - ic_colour_stack.push(INLINE_BLUE); - trick_check_pos++; - } - else if (f_character == ")" and !ic_next_is_not_special - and !ic_colour_stack.empty()) - { - if (ic_colour_stack.top() == INLINE_BLUE) - { - ic_colour_stack.pop(); - trick_check_pos++; - } - else - { - ic_next_is_not_special = true; - } - } - - // Grey inline colourisation. - else if (f_character == "[" and !ic_next_is_not_special) - { - ic_colour_stack.push(INLINE_GREY); - trick_check_pos++; - } - else if (f_character == "]" and !ic_next_is_not_special - and !ic_colour_stack.empty()) - { - if (ic_colour_stack.top() == INLINE_GREY) - { - ic_colour_stack.pop(); - trick_check_pos++; - } - else - { - ic_next_is_not_special = true; - } - } - - // Green inline colourisation. - else if (f_character == "`" and !ic_next_is_not_special) - { - if (!ic_colour_stack.empty()) - { - if (ic_colour_stack.top() == INLINE_GREEN) - { - ic_colour_stack.pop(); - p_text.remove(trick_check_pos,1); - } - else - { - ic_colour_stack.push(INLINE_GREEN); - p_text.remove(trick_check_pos,1); - } - } - else - { - ic_colour_stack.push(INLINE_GREEN); - p_text.remove(trick_check_pos,1); - } - } - else - { - trick_check_pos++; - ic_next_is_not_special = false; - } - } - - return p_text; -} - -void Courtroom::append_ic_text(QString p_text, QString p_name, bool is_songchange) -{ - QTextCharFormat bold; - QTextCharFormat normal; - QTextCharFormat italics; - bold.setFontWeight(QFont::Bold); - normal.setFontWeight(QFont::Normal); - italics.setFontItalic(true); - const QTextCursor old_cursor = ui_ic_chatlog->textCursor(); - const int old_scrollbar_value = ui_ic_chatlog->verticalScrollBar()->value(); - - if (!is_songchange) - p_text = filter_ic_text(p_text); - - if (log_goes_downwards) - { - const bool is_scrolled_down = old_scrollbar_value == ui_ic_chatlog->verticalScrollBar()->maximum(); - - ui_ic_chatlog->moveCursor(QTextCursor::End); - - if (!first_message_sent) - { - ui_ic_chatlog->textCursor().insertText(p_name, bold); - first_message_sent = true; - } - else - { - ui_ic_chatlog->textCursor().insertText('\n' + p_name, bold); - } - - if (is_songchange) - { - ui_ic_chatlog->textCursor().insertText(" has played a song: ", normal); - ui_ic_chatlog->textCursor().insertText(p_text + ".", italics); - } - else - { - ui_ic_chatlog->textCursor().insertText(p_text, normal); - } - - // If we got too many blocks in the current log, delete some from the top. - while (ui_ic_chatlog->document()->blockCount() > log_maximum_blocks && log_maximum_blocks > 0) - { - ui_ic_chatlog->moveCursor(QTextCursor::Start); - ui_ic_chatlog->textCursor().select(QTextCursor::BlockUnderCursor); - ui_ic_chatlog->textCursor().removeSelectedText(); - ui_ic_chatlog->textCursor().deleteChar(); - //qDebug() << ui_ic_chatlog->document()->blockCount() << " < " << log_maximum_blocks; - } - - if (old_cursor.hasSelection() || !is_scrolled_down) - { - // The user has selected text or scrolled away from the bottom: maintain position. - ui_ic_chatlog->setTextCursor(old_cursor); - ui_ic_chatlog->verticalScrollBar()->setValue(old_scrollbar_value); - } - else - { - // The user hasn't selected any text and the scrollbar is at the bottom: scroll to the bottom. - ui_ic_chatlog->moveCursor(QTextCursor::End); - ui_ic_chatlog->verticalScrollBar()->setValue(ui_ic_chatlog->verticalScrollBar()->maximum()); - } - } - else - { - const bool is_scrolled_up = old_scrollbar_value == ui_ic_chatlog->verticalScrollBar()->minimum(); - - ui_ic_chatlog->moveCursor(QTextCursor::Start); - - ui_ic_chatlog->textCursor().insertText(p_name, bold); - - if (is_songchange) - { - ui_ic_chatlog->textCursor().insertText(" has played a song: ", normal); - ui_ic_chatlog->textCursor().insertText(p_text + "." + '\n', italics); - } - else - { - ui_ic_chatlog->textCursor().insertText(p_text + '\n', normal); - } - - // If we got too many blocks in the current log, delete some from the bottom. - while (ui_ic_chatlog->document()->blockCount() > log_maximum_blocks && log_maximum_blocks > 0) - { - ui_ic_chatlog->moveCursor(QTextCursor::End); - ui_ic_chatlog->textCursor().select(QTextCursor::BlockUnderCursor); - ui_ic_chatlog->textCursor().removeSelectedText(); - ui_ic_chatlog->textCursor().deletePreviousChar(); - //qDebug() << ui_ic_chatlog->document()->blockCount() << " < " << log_maximum_blocks; - } - - if (old_cursor.hasSelection() || !is_scrolled_up) - { - // The user has selected text or scrolled away from the top: maintain position. - ui_ic_chatlog->setTextCursor(old_cursor); - ui_ic_chatlog->verticalScrollBar()->setValue(old_scrollbar_value); - } - else - { - // The user hasn't selected any text and the scrollbar is at the top: scroll to the top. - ui_ic_chatlog->moveCursor(QTextCursor::Start); - ui_ic_chatlog->verticalScrollBar()->setValue(ui_ic_chatlog->verticalScrollBar()->minimum()); - } - } -} - -void Courtroom::play_preanim(bool noninterrupting) -{ - QString f_char = m_chatmessage[CHAR_NAME]; - QString f_preanim = m_chatmessage[PRE_EMOTE]; - - //all time values in char.inis are multiplied by a constant(time_mod) to get the actual time - int ao2_duration = ao_app->get_ao2_preanim_duration(f_char, f_preanim); - int text_delay = ao_app->get_text_delay(f_char, f_preanim) * time_mod; - int sfx_delay = m_chatmessage[SFX_DELAY].toInt() * 60; - - int preanim_duration; - - if (ao2_duration < 0) - preanim_duration = ao_app->get_preanim_duration(f_char, f_preanim); - else - preanim_duration = ao2_duration; - - sfx_delay_timer->start(sfx_delay); - QString anim_to_find = ao_app->get_image_suffix(ao_app->get_character_path(f_char, f_preanim)); - if (!file_exists(anim_to_find) || - preanim_duration < 0) - { - if (noninterrupting) - anim_state = 4; - else - anim_state = 1; - preanim_done(); - qDebug() << "could not find " + anim_to_find; - return; - } - - ui_vp_player_char->play_pre(f_char, f_preanim, preanim_duration); - - if (noninterrupting) - anim_state = 4; - else - anim_state = 1; - - if (text_delay >= 0) - text_delay_timer->start(text_delay); - - if (noninterrupting) - handle_chatmessage_3(); -} - -void Courtroom::preanim_done() -{ - anim_state = 1; - handle_chatmessage_3(); -} - -void Courtroom::realization_done() -{ - ui_vp_realization->hide(); -} - -void Courtroom::start_chat_ticking() -{ - //we need to ensure that the text isn't already ticking because this function can be called by two logic paths - if (text_state != 0) - return; - - if (m_chatmessage[REALIZATION] == "1") - { - realization_timer->start(60); - ui_vp_realization->show(); - sfx_player->play(ao_app->get_custom_realization(m_chatmessage[CHAR_NAME])); - } - - ui_vp_message->clear(); - set_text_color(); - rainbow_counter = 0; - - if (chatmessage_is_empty) - { - //since the message is empty, it's technically done ticking - text_state = 2; - return; - } - - // At this point, we'd do well to clear the inline colour stack. - // This stops it from flowing into next messages. - while (!inline_colour_stack.empty()) - { - inline_colour_stack.pop(); - } - - ui_vp_chatbox->show(); - - tick_pos = 0; - blip_pos = 0; - - // Just in case we somehow got inline blue text left over from a previous message, - // let's set it to false. - inline_blue_depth = 0; - - // At the start of every new message, we set the text speed to the default. - current_display_speed = 3; - chat_tick_timer->start(message_display_speed[current_display_speed]); - - QString f_gender = ao_app->get_gender(m_chatmessage[CHAR_NAME]); - - blip_player->set_blips("sfx-blip" + f_gender + ".wav"); - - //means text is currently ticking - text_state = 1; -} - -void Courtroom::chat_tick() -{ - //note: this is called fairly often(every 60 ms when char is talking) - //do not perform heavy operations here - - QString f_message = m_chatmessage[MESSAGE]; - - // Due to our new text speed system, we always need to stop the timer now. - chat_tick_timer->stop(); - - // Stops blips from playing when we have a formatting option. - bool formatting_char = false; - - // If previously, we have detected that the message is centered, now - // is the time to remove those two tildes at the start. - if (message_is_centered) - { - f_message.remove(0,2); - } - - if (tick_pos >= f_message.size()) - { - text_state = 2; - if (anim_state != 4) - { - anim_state = 3; - ui_vp_player_char->play_idle(m_chatmessage[CHAR_NAME], m_chatmessage[EMOTE]); - } - } - - else - { - QString f_character = f_message.at(tick_pos); - f_character = f_character.toHtmlEscaped(); - - if (f_character == " ") - ui_vp_message->insertPlainText(" "); - - // Escape character. - else if (f_character == "\\" and !next_character_is_not_special) - { - next_character_is_not_special = true; - formatting_char = true; - } - - // Text speed modifier. - else if (f_character == "{" and !next_character_is_not_special) - { - // ++, because it INCREASES delay! - current_display_speed++; - formatting_char = true; - } - else if (f_character == "}" and !next_character_is_not_special) - { - current_display_speed--; - formatting_char = true; - } - - // Orange inline colourisation. - else if (f_character == "|" and !next_character_is_not_special) - { - if (!inline_colour_stack.empty()) - { - if (inline_colour_stack.top() == INLINE_ORANGE) - { - inline_colour_stack.pop(); - } - else - { - inline_colour_stack.push(INLINE_ORANGE); - } - } - else - { - inline_colour_stack.push(INLINE_ORANGE); - } - formatting_char = true; - } - - // Blue inline colourisation. - else if (f_character == "(" and !next_character_is_not_special) - { - inline_colour_stack.push(INLINE_BLUE); - ui_vp_message->insertHtml("" + f_character + ""); - - // Increase how deep we are in inline blues. - inline_blue_depth++; - - // Here, we check if the entire message is blue. - // If it isn't, we stop talking. - if (!entire_message_is_blue and anim_state != 4) - { - QString f_char = m_chatmessage[CHAR_NAME]; - QString f_emote = m_chatmessage[EMOTE]; - ui_vp_player_char->play_idle(f_char, f_emote); - } - } - else if (f_character == ")" and !next_character_is_not_special - and !inline_colour_stack.empty()) - { - if (inline_colour_stack.top() == INLINE_BLUE) - { - inline_colour_stack.pop(); - ui_vp_message->insertHtml("" + f_character + ""); - - // Decrease how deep we are in inline blues. - // Just in case, we do a check if we're above zero, but we should be. - if (inline_blue_depth > 0) - { - inline_blue_depth--; - // Here, we check if the entire message is blue. - // If it isn't, we start talking if we have completely climbed out of inline blues. - if (!entire_message_is_blue) - { - // We should only go back to talking if we're out of inline blues, not during a non. int. pre, and not on the last character. - if (inline_blue_depth == 0 and anim_state != 4 and !(tick_pos+1 >= f_message.size())) - { - QString f_char = m_chatmessage[CHAR_NAME]; - QString f_emote = m_chatmessage[EMOTE]; - ui_vp_player_char->play_talking(f_char, f_emote); - } - } - } - } - else - { - next_character_is_not_special = true; - tick_pos--; - } - } - - // Grey inline colourisation. - else if (f_character == "[" and !next_character_is_not_special) - { - inline_colour_stack.push(INLINE_GREY); - ui_vp_message->insertHtml("" + f_character + ""); - } - else if (f_character == "]" and !next_character_is_not_special - and !inline_colour_stack.empty()) - { - if (inline_colour_stack.top() == INLINE_GREY) - { - inline_colour_stack.pop(); - ui_vp_message->insertHtml("" + f_character + ""); - } - else - { - next_character_is_not_special = true; - tick_pos--; - } - } - - // Green inline colourisation. - else if (f_character == "`" and !next_character_is_not_special) - { - if (!inline_colour_stack.empty()) - { - if (inline_colour_stack.top() == INLINE_GREEN) - { - inline_colour_stack.pop(); - formatting_char = true; - } - else - { - inline_colour_stack.push(INLINE_GREEN); - formatting_char = true; - } - } - else - { - inline_colour_stack.push(INLINE_GREEN); - formatting_char = true; - } - } - else - { - next_character_is_not_special = false; - if (!inline_colour_stack.empty()) - { - switch (inline_colour_stack.top()) { - case INLINE_ORANGE: - ui_vp_message->insertHtml("" + f_character + ""); - break; - case INLINE_BLUE: - ui_vp_message->insertHtml("" + f_character + ""); - break; - case INLINE_GREEN: - ui_vp_message->insertHtml("" + f_character + ""); - break; - case INLINE_GREY: - ui_vp_message->insertHtml("" + f_character + ""); - break; - default: - ui_vp_message->insertHtml(f_character); - break; - } - - } - else - { - if (m_chatmessage[TEXT_COLOR].toInt() == RAINBOW) - { - QString html_color; - - switch (rainbow_counter) - { - case 0: - html_color = get_text_color(QString::number(RED)).name(); - break; - case 1: - html_color = get_text_color(QString::number(ORANGE)).name(); - break; - case 2: - html_color = get_text_color(QString::number(YELLOW)).name(); - break; - case 3: - html_color = get_text_color(QString::number(GREEN)).name(); - break; - default: - html_color = get_text_color(QString::number(BLUE)).name(); - rainbow_counter = -1; - } - - ++rainbow_counter; - - ui_vp_message->insertHtml("" + f_character + ""); - } - else - ui_vp_message->insertHtml(f_character); - } - - if (message_is_centered) - { - ui_vp_message->setAlignment(Qt::AlignCenter); - } - else - { - ui_vp_message->setAlignment(Qt::AlignLeft); - } - } - - QScrollBar *scroll = ui_vp_message->verticalScrollBar(); - scroll->setValue(scroll->maximum()); - - if(blank_blip) - qDebug() << "blank_blip found true"; - - if (f_message.at(tick_pos) != ' ' || blank_blip) - { - - if (blip_pos % blip_rate == 0 && !formatting_char) - { - blip_pos = 0; - blip_player->blip_tick(); - } - - ++blip_pos; - } - - ++tick_pos; - - // Restart the timer, but according to the newly set speeds, if there were any. - // Keep the speed at bay. - if (current_display_speed < 0) - { - current_display_speed = 0; - } - - if (current_display_speed > 6) - { - current_display_speed = 6; - } - - // If we had a formatting char, we shouldn't wait so long again, as it won't appear! - if (formatting_char) - { - chat_tick_timer->start(1); - } - else - { - chat_tick_timer->start(message_display_speed[current_display_speed]); - } - - } -} - -void Courtroom::show_testimony() -{ - if (!testimony_in_progress || m_chatmessage[SIDE] != "wit") - return; - - ui_vp_testimony->show(); - - testimony_show_timer->start(testimony_show_time); -} - -void Courtroom::hide_testimony() -{ - ui_vp_testimony->hide(); - - if (!testimony_in_progress) - return; - - testimony_hide_timer->start(testimony_hide_time); -} - -void Courtroom::play_sfx() -{ - QString sfx_name = m_chatmessage[SFX_NAME]; - - if (sfx_name == "1") - return; - - sfx_player->play(ao_app->get_sfx_suffix(sfx_name)); -} - -void Courtroom::set_scene() -{ - if (testimony_in_progress) - show_testimony(); - - //witness is default if pos is invalid - QString f_background = "witnessempty"; - QString f_desk_image = "stand"; - QString f_desk_mod = m_chatmessage[DESK_MOD]; - QString f_side = m_chatmessage[SIDE]; - - if (f_side == "def") - { - f_background = "defenseempty"; - if (is_ao2_bg) - f_desk_image = "defensedesk"; - else - f_desk_image = "bancodefensa"; - } - else if (f_side == "pro") - { - f_background = "prosecutorempty"; - if (is_ao2_bg) - f_desk_image = "prosecutiondesk"; - else - f_desk_image = "bancoacusacion"; - } - else if (f_side == "jud") - { - f_background = "judgestand"; - f_desk_image = "judgedesk"; - } - else if (f_side == "hld") - { - f_background = "helperstand"; - f_desk_image = "helperdesk"; - } - else if (f_side == "hlp") - { - f_background = "prohelperstand"; - f_desk_image = "prohelperdesk"; - } - else if (f_side == "jur" && (file_exists(ao_app->get_background_path("jurystand.png")) || - file_exists(ao_app->get_background_path("jurystand.gif")))) - { - f_background = "jurystand"; - f_desk_image = "jurydesk"; - } - else if (f_side == "sea" && (file_exists(ao_app->get_background_path("seancestand.png")) || - file_exists(ao_app->get_background_path("seancestand.gif")))) - { - f_background = "seancestand"; - f_desk_image = "seancedesk"; - } - else - { - if (is_ao2_bg) - f_desk_image = "stand"; - else - f_desk_image = "estrado"; - } - - ui_vp_background->set_image(f_background); - ui_vp_desk->set_image(f_desk_image); - ui_vp_legacy_desk->set_legacy_desk(f_desk_image); - - if (f_desk_mod == "0" || (f_desk_mod != "1" && - (f_side == "jud" || - f_side == "hld" || - f_side == "hlp"))) - { - ui_vp_desk->hide(); - ui_vp_legacy_desk->hide(); - } - else if (is_ao2_bg || (f_side == "jud" || - f_side == "hld" || - f_side == "hlp")) - { - ui_vp_legacy_desk->hide(); - ui_vp_desk->show(); - } - else - { - if (f_side == "wit") - { - ui_vp_desk->show(); - ui_vp_legacy_desk->hide(); - } - else - { - ui_vp_desk->hide(); - ui_vp_legacy_desk->show(); - } - } -} - -void Courtroom::set_text_color() -{ - QColor textcolor = ao_app->get_chat_color(m_chatmessage[TEXT_COLOR], ao_app->get_chat(m_chatmessage[CHAR_NAME])); - - ui_vp_message->setTextBackgroundColor(QColor(0,0,0,0)); - ui_vp_message->setTextColor(textcolor); - - QString style = "background-color: rgba(0, 0, 0, 0);"; - style.append("color: rgb("); - style.append(QString::number(textcolor.red())); - style.append(", "); - style.append(QString::number(textcolor.green())); - style.append(", "); - style.append(QString::number(textcolor.blue())); - style.append(")"); - - ui_vp_message->setStyleSheet(style); -} - -QColor Courtroom::get_text_color(QString color) -{ - return ao_app->get_chat_color(color, ao_app->get_chat(m_chatmessage[CHAR_NAME])); -} - -void Courtroom::set_ip_list(QString p_list) -{ - QString f_list = p_list.replace("|", ":").replace("*", "\n"); - - ui_server_chatlog->append(f_list); -} - -void Courtroom::set_mute(bool p_muted, int p_cid) -{ - if (p_cid != m_cid && p_cid != -1) - return; - - if (p_muted) - ui_muted->show(); - else - { - ui_muted->hide(); - ui_ic_chat_message->setFocus(); - } - - ui_muted->resize(ui_ic_chat_message->width(), ui_ic_chat_message->height()); - ui_muted->set_image("muted.png"); - - is_muted = p_muted; - ui_ic_chat_message->setEnabled(!p_muted); -} - -void Courtroom::set_ban(int p_cid) -{ - if (p_cid != m_cid && p_cid != -1) - return; - - call_notice("You have been banned."); - - ao_app->construct_lobby(); - ao_app->destruct_courtroom(); -} - -void Courtroom::handle_song(QStringList *p_contents) -{ - QStringList f_contents = *p_contents; - - if (f_contents.size() < 2) - return; - - QString f_song = f_contents.at(0); - QString f_song_clear = f_song; - f_song_clear = f_song_clear.left(f_song_clear.lastIndexOf(".")); - int n_char = f_contents.at(1).toInt(); - - if (n_char < 0 || n_char >= char_list.size()) - { - music_player->play(f_song); - } - else - { - QString str_char = char_list.at(n_char).name; - QString str_show = char_list.at(n_char).name; - - if (p_contents->length() > 2) - { - str_show = p_contents->at(2); - } - - if (!mute_map.value(n_char)) - { - chatlogpiece* temp = new chatlogpiece(str_char, str_show, f_song, true); - ic_chatlog_history.append(*temp); - - while(ic_chatlog_history.size() > log_maximum_blocks && log_maximum_blocks > 0) - { - ic_chatlog_history.removeFirst(); - } - - append_ic_text(f_song_clear, str_show, true); - music_player->play(f_song); - } - } -} - -void Courtroom::handle_wtce(QString p_wtce, int variant) -{ - QString sfx_file = "courtroom_sounds.ini"; - - //witness testimony - if (p_wtce == "testimony1") - { - sfx_player->play(ao_app->get_sfx("witness_testimony")); - ui_vp_wtce->play("witnesstestimony"); - testimony_in_progress = true; - show_testimony(); - } - //cross examination - else if (p_wtce == "testimony2") - { - sfx_player->play(ao_app->get_sfx("cross_examination")); - ui_vp_wtce->play("crossexamination"); - testimony_in_progress = false; - } - else if (p_wtce == "judgeruling") - { - if (variant == 0) - { - sfx_player->play(ao_app->get_sfx("not_guilty")); - ui_vp_wtce->play("notguilty"); - testimony_in_progress = false; - } - else if (variant == 1) { - sfx_player->play(ao_app->get_sfx("guilty")); - ui_vp_wtce->play("guilty"); - testimony_in_progress = false; - } - } -} - -void Courtroom::set_hp_bar(int p_bar, int p_state) -{ - if (p_state < 0 || p_state > 10) - return; - - if (p_bar == 1) - { - ui_defense_bar->set_image("defensebar" + QString::number(p_state) + ".png"); - defense_bar_state = p_state; - } - else if (p_bar == 2) - { - ui_prosecution_bar->set_image("prosecutionbar" + QString::number(p_state) + ".png"); - prosecution_bar_state = p_state; - } -} - -void Courtroom::toggle_judge_buttons(bool is_on) -{ - if (is_on) - { - ui_witness_testimony->show(); - ui_cross_examination->show(); - ui_guilty->show(); - ui_not_guilty->show(); - ui_defense_minus->show(); - ui_defense_plus->show(); - ui_prosecution_minus->show(); - ui_prosecution_plus->show(); - } - else - { - ui_witness_testimony->hide(); - ui_cross_examination->hide(); - ui_guilty->hide(); - ui_not_guilty->hide(); - ui_defense_minus->hide(); - ui_defense_plus->hide(); - ui_prosecution_minus->hide(); - ui_prosecution_plus->hide(); - } -} - -void Courtroom::mod_called(QString p_ip) -{ - ui_server_chatlog->append(p_ip); - if (ui_guard->isChecked()) - { - modcall_player->play(ao_app->get_sfx("mod_call")); - ao_app->alert(this); - } -} - -void Courtroom::case_called(QString msg, bool def, bool pro, bool jud, bool jur, bool steno) -{ - 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_sfx("case_call")); - ao_app->alert(this); - } - } -} - -void Courtroom::on_ooc_return_pressed() -{ - QString ooc_message = ui_ooc_chat_message->text(); - - if (ooc_message == "" || ui_ooc_chat_name->text() == "") - return; - - if (ooc_message.startsWith("/pos")) - { - if (ooc_message == "/pos jud") - { - toggle_judge_buttons(true); - } - else - { - toggle_judge_buttons(false); - } - } - else if (ooc_message.startsWith("/login")) - { - ui_guard->show(); - append_server_chatmessage("CLIENT", "You were granted the Guard button.", "1"); - } - else if (ooc_message.startsWith("/rainbow") && ao_app->yellow_text_enabled && !rainbow_appended) - { - //ui_text_color->addItem("Rainbow"); - ui_ooc_chat_message->clear(); - //rainbow_appended = true; - append_server_chatmessage("CLIENT", "This does nohing, but there you go.", "1"); - return; - } - else if (ooc_message.startsWith("/settings")) - { - ui_ooc_chat_message->clear(); - ao_app->call_settings_menu(); - append_server_chatmessage("CLIENT", "You opened the settings menu.", "1"); - return; - } - else if (ooc_message.startsWith("/pair")) - { - ui_ooc_chat_message->clear(); - ooc_message.remove(0,6); - - bool ok; - int whom = ooc_message.toInt(&ok); - if (ok) - { - if (whom > -1) - { - other_charid = whom; - QString msg = "You will now pair up with "; - msg.append(char_list.at(whom).name); - msg.append(" if they also choose your character in return."); - append_server_chatmessage("CLIENT", msg, "1"); - } - else - { - append_server_chatmessage("CLIENT", "You are no longer paired with anyone.", "1"); - } - } - else - { - append_server_chatmessage("CLIENT", "Are you sure you typed that well? The char ID could not be recognised.", "1"); - } - return; - } - else if (ooc_message.startsWith("/offset")) - { - 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) - { - offset_with_pair = off; - QString msg = "You have set your offset to "; - msg.append(QString::number(off)); - msg.append("%."); - append_server_chatmessage("CLIENT", msg, "1"); - } - else - { - append_server_chatmessage("CLIENT", "Your offset must be between -100% and 100%!", "1"); - } - } - else - { - append_server_chatmessage("CLIENT", "That offset does not look like one.", "1"); - } - return; - } - else if (ooc_message.startsWith("/switch_am")) - { - append_server_chatmessage("CLIENT", "You switched your music and area list.", "1"); - on_switch_area_music_clicked(); - ui_ooc_chat_message->clear(); - return; - } - else if (ooc_message.startsWith("/enable_blocks")) - { - append_server_chatmessage("CLIENT", "You have forcefully enabled features that the server may not support. You may not be able to talk IC, or worse, because of this.", "1"); - ao_app->cccc_ic_support_enabled = true; - ao_app->arup_enabled = true; - ao_app->modcall_reason_enabled = true; - on_reload_theme_clicked(); - ui_ooc_chat_message->clear(); - return; - } - else if (ooc_message.startsWith("/non_int_pre")) - { - if (ui_pre_non_interrupt->isChecked()) - append_server_chatmessage("CLIENT", "Your pre-animations interrupt again.", "1"); - else - append_server_chatmessage("CLIENT", "Your pre-animations will not interrupt text.", "1"); - ui_pre_non_interrupt->setChecked(!ui_pre_non_interrupt->isChecked()); - ui_ooc_chat_message->clear(); - return; - } - else if (ooc_message.startsWith("/save_chatlog")) - { - QFile file("chatlog.txt"); - - if (!file.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate)) - { - append_server_chatmessage("CLIENT", "Couldn't open chatlog.txt to write into.", "1"); - ui_ooc_chat_message->clear(); - return; - } - - QTextStream out(&file); - - foreach (chatlogpiece item, ic_chatlog_history) { - out << item.get_full() << '\n'; - } - - file.close(); - - append_server_chatmessage("CLIENT", "The IC chatlog has been saved.", "1"); - ui_ooc_chat_message->clear(); - return; - } - else if (ooc_message.startsWith("/load_case")) - { - QStringList command = ooc_message.split(" ", QString::SkipEmptyParts); - - QDir casefolder("base/cases"); - if (!casefolder.exists()) - { - QDir::current().mkdir("base/" + casefolder.dirName()); - append_server_chatmessage("CLIENT", "You don't have a `base/cases/` folder! It was just made for you, but seeing as it WAS just made for you, it's likely the case file you're looking for can't be found in there.", "1"); - ui_ooc_chat_message->clear(); - return; - } - QStringList caseslist = casefolder.entryList(); - caseslist.removeOne("."); - caseslist.removeOne(".."); - caseslist.replaceInStrings(".ini",""); - - if (command.size() < 2) - { - append_server_chatmessage("CLIENT", "You need to give a filename to load (extension not needed)! Make sure that it is in the `base/cases/` folder, and that it is a correctly formatted ini.\nCases you can load: " + caseslist.join(", "), "1"); - ui_ooc_chat_message->clear(); - return; - } - - - if (command.size() > 2) - { - append_server_chatmessage("CLIENT", "Too many arguments to load a case! You only need one filename, without extension.", "1"); - ui_ooc_chat_message->clear(); - return; - } - - QSettings casefile("base/cases/" + command[1] + ".ini", QSettings::IniFormat); - - QString caseauth = casefile.value("author", "").value(); - QString casedoc = casefile.value("doc", "").value(); - QString cmdoc = casefile.value("cmdoc", "").value(); - QString casestatus = casefile.value("status", "").value(); - - if (!caseauth.isEmpty()) - append_server_chatmessage("CLIENT", "Case made by " + caseauth + ".", "1"); - if (!casedoc.isEmpty()) - ao_app->send_server_packet(new AOPacket("CT#" + ui_ooc_chat_name->text() + "#/doc " + casedoc + "#%")); - if (!casestatus.isEmpty()) - ao_app->send_server_packet(new AOPacket("CT#" + ui_ooc_chat_name->text() + "#/status " + casestatus + "#%")); - if (!cmdoc.isEmpty()) - append_server_chatmessage("CLIENT", "Navigate to " + cmdoc + " for the CM doc.", "1"); - - for (int i = local_evidence_list.size() - 1; i >= 0; i--) { - ao_app->send_server_packet(new AOPacket("DE#" + QString::number(i) + "#%")); - } - - foreach (QString evi, casefile.childGroups()) { - if (evi == "General") - continue; - - QStringList f_contents; - - f_contents.append(casefile.value(evi + "/name", "UNKNOWN").value()); - f_contents.append(casefile.value(evi + "/description", "UNKNOWN").value()); - f_contents.append(casefile.value(evi + "/image", "UNKNOWN.png").value()); - - ao_app->send_server_packet(new AOPacket("PE", f_contents)); - } - - append_server_chatmessage("CLIENT", "Your case \"" + command[1] + "\" was loaded!", "1"); - ui_ooc_chat_message->clear(); - return; - } - - QStringList packet_contents; - packet_contents.append(ui_ooc_chat_name->text()); - packet_contents.append(ooc_message); - - AOPacket *f_packet = new AOPacket("CT", packet_contents); - - if (server_ooc) - ao_app->send_server_packet(f_packet); - else - ao_app->send_ms_packet(f_packet); - - ui_ooc_chat_message->clear(); - - ui_ooc_chat_message->setFocus(); -} - -void Courtroom::on_ooc_toggle_clicked() -{ - if (server_ooc) - { - ui_ms_chatlog->show(); - ui_server_chatlog->hide(); - ui_ooc_toggle->setText("Master"); - - server_ooc = false; - } - else - { - ui_ms_chatlog->hide(); - ui_server_chatlog->show(); - ui_ooc_toggle->setText("Server"); - - server_ooc = true; - } -} - -void Courtroom::on_music_search_edited(QString p_text) -{ - //preventing compiler warnings - p_text += "a"; - list_music(); - list_areas(); -} - -void Courtroom::on_pos_dropdown_changed(int p_index) -{ - ui_ic_chat_message->setFocus(); - - if (p_index < 0 || p_index > 5) - return; - - toggle_judge_buttons(false); - - QString f_pos; - - switch (p_index) - { - case 0: - f_pos = "wit"; - break; - case 1: - f_pos = "def"; - break; - case 2: - f_pos = "pro"; - break; - case 3: - f_pos = "jud"; - toggle_judge_buttons(true); - break; - case 4: - f_pos = "hld"; - break; - case 5: - f_pos = "hlp"; - break; - default: - f_pos = ""; - } - - if (f_pos == "" || ui_ooc_chat_name->text() == "") - return; - - ao_app->send_server_packet(new AOPacket("CT#" + ui_ooc_chat_name->text() + "#/pos " + f_pos + "#%")); -} - -void Courtroom::on_mute_list_clicked(QModelIndex p_index) -{ - QListWidgetItem *f_item = ui_mute_list->item(p_index.row()); - QString f_char = f_item->text(); - QString real_char; - - if (f_char.endsWith(" [x]")) - real_char = f_char.left(f_char.size() - 4); - else - real_char = f_char; - - int f_cid = -1; - - for (int n_char = 0 ; n_char < char_list.size() ; n_char++) - { - if (char_list.at(n_char).name == real_char) - f_cid = n_char; - } - - if (f_cid < 0 || f_cid >= char_list.size()) - { - qDebug() << "W: " << real_char << " not present in char_list"; - return; - } - - if (mute_map.value(f_cid)) - { - mute_map.insert(f_cid, false); - f_item->setText(real_char); - } - else - { - mute_map.insert(f_cid, true); - f_item->setText(real_char + " [x]"); - } -} - -void Courtroom::on_pair_list_clicked(QModelIndex p_index) -{ - QListWidgetItem *f_item = ui_pair_list->item(p_index.row()); - QString f_char = f_item->text(); - QString real_char; - - if (f_char.endsWith(" [x]")) - { - real_char = f_char.left(f_char.size() - 4); - f_item->setText(real_char); - } - else - real_char = f_char; - - int f_cid = -1; - - for (int n_char = 0 ; n_char < char_list.size() ; n_char++) - { - if (char_list.at(n_char).name == real_char) - f_cid = n_char; - } - - if (f_cid < 0 || f_cid >= char_list.size()) - { - qDebug() << "W: " << real_char << " not present in char_list"; - return; - } - - other_charid = f_cid; - - // Redo the character list. - QStringList sorted_pair_list; - - for (char_type i_char : char_list) - sorted_pair_list.append(i_char.name); - - sorted_pair_list.sort(); - - for (int i = 0; i < ui_pair_list->count(); i++) { - ui_pair_list->item(i)->setText(sorted_pair_list.at(i)); - } - - f_item->setText(real_char + " [x]"); -} - -void Courtroom::on_music_list_double_clicked(QModelIndex p_model) -{ - if (is_muted) - return; - - QString p_song = music_list.at(music_row_to_number.at(p_model.row())); - - if (!ui_ic_chat_name->text().isEmpty() && ao_app->cccc_ic_support_enabled) - { - ao_app->send_server_packet(new AOPacket("MC#" + p_song + "#" + QString::number(m_cid) + "#" + ui_ic_chat_name->text() + "#%"), false); - } - else - { - ao_app->send_server_packet(new AOPacket("MC#" + p_song + "#" + QString::number(m_cid) + "#%"), false); - } -} - -void Courtroom::on_area_list_double_clicked(QModelIndex p_model) -{ - QString p_area = area_list.at(area_row_to_number.at(p_model.row())); - ao_app->send_server_packet(new AOPacket("MC#" + p_area + "#" + QString::number(m_cid) + "#%"), false); -} - -void Courtroom::on_hold_it_clicked() -{ - if (objection_state == 1) - { - ui_hold_it->set_image("holdit.png"); - objection_state = 0; - } - else - { - ui_objection->set_image("objection.png"); - ui_take_that->set_image("takethat.png"); - ui_custom_objection->set_image("custom.png"); - - ui_hold_it->set_image("holdit_selected.png"); - objection_state = 1; - } - - ui_ic_chat_message->setFocus(); -} - -void Courtroom::on_objection_clicked() -{ - if (objection_state == 2) - { - ui_objection->set_image("objection.png"); - objection_state = 0; - } - else - { - ui_hold_it->set_image("holdit.png"); - ui_take_that->set_image("takethat.png"); - ui_custom_objection->set_image("custom.png"); - - ui_objection->set_image("objection_selected.png"); - objection_state = 2; - } - - ui_ic_chat_message->setFocus(); -} - -void Courtroom::on_take_that_clicked() -{ - if (objection_state == 3) - { - ui_take_that->set_image("takethat.png"); - objection_state = 0; - } - else - { - ui_objection->set_image("objection.png"); - ui_hold_it->set_image("holdit.png"); - ui_custom_objection->set_image("custom.png"); - - ui_take_that->set_image("takethat_selected.png"); - objection_state = 3; - } - - ui_ic_chat_message->setFocus(); -} - -void Courtroom::on_custom_objection_clicked() -{ - if (objection_state == 4) - { - ui_custom_objection->set_image("custom.png"); - objection_state = 0; - } - else - { - ui_objection->set_image("objection.png"); - ui_take_that->set_image("takethat.png"); - ui_hold_it->set_image("holdit.png"); - - ui_custom_objection->set_image("custom_selected.png"); - objection_state = 4; - } - - ui_ic_chat_message->setFocus(); -} - -void Courtroom::on_realization_clicked() -{ - if (realization_state == 0) - { - realization_state = 1; - ui_realization->set_image("realization_pressed.png"); - } - else - { - realization_state = 0; - ui_realization->set_image("realization.png"); - } - - ui_ic_chat_message->setFocus(); -} - -void Courtroom::on_mute_clicked() -{ - if (ui_mute_list->isHidden()) - { - ui_mute_list->show(); - ui_pair_list->hide(); - ui_pair_offset_spinbox->hide(); - ui_pair_button->set_image("pair_button.png"); - ui_mute->set_image("mute_pressed.png"); - } - else - { - ui_mute_list->hide(); - ui_mute->set_image("mute.png"); - } -} - -void Courtroom::on_pair_clicked() -{ - if (ui_pair_list->isHidden()) - { - ui_pair_list->show(); - ui_pair_offset_spinbox->show(); - ui_mute_list->hide(); - ui_mute->set_image("mute.png"); - ui_pair_button->set_image("pair_button_pressed.png"); - } - else - { - ui_pair_list->hide(); - ui_pair_offset_spinbox->hide(); - ui_pair_button->set_image("pair_button.png"); - } -} - -void Courtroom::on_defense_minus_clicked() -{ - int f_state = defense_bar_state - 1; - - if (f_state >= 0) - ao_app->send_server_packet(new AOPacket("HP#1#" + QString::number(f_state) + "#%")); -} - -void Courtroom::on_defense_plus_clicked() -{ - int f_state = defense_bar_state + 1; - - if (f_state <= 10) - ao_app->send_server_packet(new AOPacket("HP#1#" + QString::number(f_state) + "#%")); -} - -void Courtroom::on_prosecution_minus_clicked() -{ - int f_state = prosecution_bar_state - 1; - - if (f_state >= 0) - ao_app->send_server_packet(new AOPacket("HP#2#" + QString::number(f_state) + "#%")); -} - -void Courtroom::on_prosecution_plus_clicked() -{ - int f_state = prosecution_bar_state + 1; - - if (f_state <= 10) - ao_app->send_server_packet(new AOPacket("HP#2#" + QString::number(f_state) + "#%")); -} - -void Courtroom::on_text_color_changed(int p_color) -{ - text_color = p_color; - ui_ic_chat_message->setFocus(); -} - -void Courtroom::on_music_slider_moved(int p_value) -{ - music_player->set_volume(p_value); - ui_ic_chat_message->setFocus(); -} - -void Courtroom::on_sfx_slider_moved(int p_value) -{ - sfx_player->set_volume(p_value); - objection_player->set_volume(p_value); - ui_ic_chat_message->setFocus(); -} - -void Courtroom::on_blip_slider_moved(int p_value) -{ - blip_player->set_volume(p_value); - ui_ic_chat_message->setFocus(); -} - -void Courtroom::on_log_limit_changed(int value) -{ - log_maximum_blocks = value; -} - -void Courtroom::on_pair_offset_changed(int value) -{ - offset_with_pair = value; -} - -void Courtroom::on_witness_testimony_clicked() -{ - if (is_muted) - return; - - ao_app->send_server_packet(new AOPacket("RT#testimony1#%")); - - ui_ic_chat_message->setFocus(); -} - -void Courtroom::on_cross_examination_clicked() -{ - if (is_muted) - return; - - ao_app->send_server_packet(new AOPacket("RT#testimony2#%")); - - ui_ic_chat_message->setFocus(); -} - -void Courtroom::on_not_guilty_clicked() -{ - if (is_muted) - return; - - ao_app->send_server_packet(new AOPacket("RT#judgeruling#0#%")); - - ui_ic_chat_message->setFocus(); -} - -void Courtroom::on_guilty_clicked() -{ - if (is_muted) - return; - - ao_app->send_server_packet(new AOPacket("RT#judgeruling#1#%")); - - ui_ic_chat_message->setFocus(); -} - -void Courtroom::on_change_character_clicked() -{ - music_player->set_volume(0); - sfx_player->set_volume(0); - sfx_player->set_volume(0); - blip_player->set_volume(0); - - set_char_select(); - - ui_char_select_background->show(); - ui_spectator->hide(); -} - -void Courtroom::on_reload_theme_clicked() -{ - ao_app->reload_theme(); - - //to update status on the background - set_background(current_background); - enter_courtroom(m_cid); - - anim_state = 4; - text_state = 3; -} - -void Courtroom::on_back_to_lobby_clicked() -{ - ao_app->construct_lobby(); - ao_app->destruct_courtroom(); -} - -void Courtroom::on_char_select_left_clicked() -{ - --current_char_page; - set_char_select_page(); -} - -void Courtroom::on_char_select_right_clicked() -{ - ++current_char_page; - set_char_select_page(); -} - -void Courtroom::on_spectator_clicked() -{ - enter_courtroom(-1); - - ui_emotes->hide(); - - ui_char_select_background->hide(); -} - -void Courtroom::on_call_mod_clicked() -{ - if (ao_app->modcall_reason_enabled) { - QMessageBox errorBox; - QInputDialog input; - - input.setWindowFlags(Qt::WindowSystemMenuHint); - input.setLabelText("Reason:"); - input.setWindowTitle("Call Moderator"); - auto code = input.exec(); - - if (code != QDialog::Accepted) - return; - - QString text = input.textValue(); - if (text.isEmpty()) { - errorBox.critical(nullptr, "Error", "You must provide a reason."); - return; - } else if (text.length() > 256) { - errorBox.critical(nullptr, "Error", "The message is too long."); - return; - } - - QStringList mod_reason; - mod_reason.append(text); - - ao_app->send_server_packet(new AOPacket("ZZ", mod_reason)); - } else { - ao_app->send_server_packet(new AOPacket("ZZ#%")); - } - - ui_ic_chat_message->setFocus(); -} - -void Courtroom::on_settings_clicked() -{ - ao_app->call_settings_menu(); -} - -void Courtroom::on_announce_casing_clicked() -{ - ao_app->call_announce_menu(this); -} - -void Courtroom::on_pre_clicked() -{ - ui_ic_chat_message->setFocus(); -} - -void Courtroom::on_flip_clicked() -{ - ui_ic_chat_message->setFocus(); -} - -void Courtroom::on_guard_clicked() -{ - ui_ic_chat_message->setFocus(); -} - -void Courtroom::on_showname_enable_clicked() -{ - ui_ic_chatlog->clear(); - first_message_sent = false; - - foreach (chatlogpiece item, ic_chatlog_history) { - if (ui_showname_enable->isChecked()) - { - if (item.get_is_song()) - append_ic_text(item.get_message(), item.get_showname(), true); - else - append_ic_text(item.get_message(), item.get_showname()); - } - else - { - if (item.get_is_song()) - append_ic_text(item.get_message(), item.get_name(), true); - else - append_ic_text(item.get_message(), item.get_name()); - } - } - - ui_ic_chat_message->setFocus(); -} - -void Courtroom::on_evidence_button_clicked() -{ - if (ui_evidence->isHidden()) - { - ui_evidence->show(); - ui_evidence_overlay->hide(); - } - else - { - ui_evidence->hide(); - } -} - -void Courtroom::on_switch_area_music_clicked() -{ - if (ui_area_list->isHidden()) - { - ui_area_list->show(); - ui_music_list->hide(); - } - else - { - ui_area_list->hide(); - ui_music_list->show(); - } -} - -void Courtroom::ping_server() -{ - ao_app->send_server_packet(new AOPacket("CH#" + QString::number(m_cid) + "#%")); -} - -void Courtroom::on_casing_clicked() -{ - if (ao_app->casing_alerts_enabled) - { - if (ui_casing->isChecked()) - { - QStringList f_packet; - - f_packet.append(ao_app->get_casing_can_host_cases()); - f_packet.append(QString::number(ao_app->get_casing_cm_enabled())); - f_packet.append(QString::number(ao_app->get_casing_defence_enabled())); - f_packet.append(QString::number(ao_app->get_casing_prosecution_enabled())); - f_packet.append(QString::number(ao_app->get_casing_judge_enabled())); - f_packet.append(QString::number(ao_app->get_casing_juror_enabled())); - f_packet.append(QString::number(ao_app->get_casing_steno_enabled())); - - ao_app->send_server_packet(new AOPacket("SETCASE", f_packet)); - } - else - ao_app->send_server_packet(new AOPacket("SETCASE#\"\"#0#0#0#0#0#0#%")); - } -} - -void Courtroom::announce_case(QString title, bool def, bool pro, bool jud, bool jur, bool steno) -{ - if (ao_app->casing_alerts_enabled) - { - QStringList f_packet; - - f_packet.append(title); - f_packet.append(QString::number(def)); - f_packet.append(QString::number(pro)); - f_packet.append(QString::number(jud)); - f_packet.append(QString::number(jur)); - f_packet.append(QString::number(steno)); - - ao_app->send_server_packet(new AOPacket("CASEA", f_packet)); - } -} - -Courtroom::~Courtroom() -{ - delete music_player; - delete sfx_player; - delete objection_player; - delete blip_player; -} - -#if (defined (_WIN32) || defined (_WIN64)) -void Courtroom::load_bass_opus_plugin() -{ - BASS_PluginLoad("bassopus.dll", 0); -} -#elif (defined (LINUX) || defined (__linux__)) -void Courtroom::load_bass_opus_plugin() -{ - BASS_PluginLoad("libbassopus.so", 0); -} -#else -#error This operating system is unsupported for bass plugins. -#endif diff --git a/courtroom.h b/courtroom.h deleted file mode 100644 index ec9f9ef0..00000000 --- a/courtroom.h +++ /dev/null @@ -1,671 +0,0 @@ -#ifndef COURTROOM_H -#define COURTROOM_H - -#include "aoimage.h" -#include "aobutton.h" -#include "aocharbutton.h" -#include "aoemotebutton.h" -#include "aopacket.h" -#include "aoscene.h" -#include "aomovie.h" -#include "aocharmovie.h" -#include "aomusicplayer.h" -#include "aosfxplayer.h" -#include "aoblipplayer.h" -#include "aoevidencebutton.h" -#include "aotextarea.h" -#include "aolineedit.h" -#include "aotextedit.h" -#include "aoevidencedisplay.h" -#include "datatypes.h" -#include "aoapplication.h" -#include "lobby.h" -#include "hardware_functions.h" -#include "file_functions.h" -#include "datatypes.h" -#include "debug_functions.h" -#include "chatlogpiece.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -class AOApplication; - -class Courtroom : public QMainWindow -{ - Q_OBJECT -public: - explicit Courtroom(AOApplication *p_ao_app); - - void append_char(char_type p_char){char_list.append(p_char);} - void append_evidence(evi_type p_evi){evidence_list.append(p_evi);} - void append_music(QString f_music){music_list.append(f_music);} - void append_area(QString f_area){area_list.append(f_area);} - - void fix_last_area() - { - if (area_list.size() > 0) - { - QString malplaced = area_list.last(); - area_list.removeLast(); - append_music(malplaced); - } - } - - void arup_append(int players, QString status, QString cm, QString locked) - { - arup_players.append(players); - arup_statuses.append(status); - arup_cms.append(cm); - arup_locks.append(locked); - } - - void arup_modify(int type, int place, QString value) - { - if (type == 0) - { - if (arup_players.size() > place) - arup_players[place] = value.toInt(); - } - else if (type == 1) - { - if (arup_statuses.size() > place) - arup_statuses[place] = value; - } - else if (type == 2) - { - if (arup_cms.size() > place) - arup_cms[place] = value; - } - else if (type == 3) - { - if (arup_locks.size() > place) - arup_locks[place] = value; - } - list_areas(); - } - - void character_loading_finished(); - - //sets position of widgets based on theme ini files - void set_widgets(); - //sets font size based on theme ini files - void set_font(QWidget *widget, QString p_identifier); - //helper function that calls above function on the relevant widgets - void set_fonts(); - - void set_window_title(QString p_title); - - //reads theme inis and sets size and pos based on the identifier - void set_size_and_pos(QWidget *p_widget, QString p_identifier); - - //sets status as taken on character with cid n_char and places proper shading on charselect - void set_taken(int n_char, bool p_taken); - - //sets the current background to argument. also does some checks to see if it's a legacy bg - void set_background(QString p_background); - - //sets the evidence list member variable to argument - void set_evidence_list(QVector &p_evi_list); - - //called when a DONE#% from the server was received - void done_received(); - - //sets the local mute list based on characters available on the server - void set_mute_list(); - - // Sets the local pair list based on the characters available on the server. - void set_pair_list(); - - //sets desk and bg based on pos in chatmessage - void set_scene(); - - //sets text color based on text color in chatmessage - void set_text_color(); - - // And gets the colour, too! - QColor get_text_color(QString color); - - //takes in serverD-formatted IP list as prints a converted version to server OOC - //admittedly poorly named - void set_ip_list(QString p_list); - - //disables chat if current cid matches second argument - //enables if p_muted is false - void set_mute(bool p_muted, int p_cid); - - //send a message that the player is banned and quits the server - void set_ban(int p_cid); - - //cid = character id, returns the cid of the currently selected character - int get_cid() {return m_cid;} - QString get_current_char() {return current_char;} - QString get_current_background() {return current_background;} - - //properly sets up some varibles: resets user state - void enter_courtroom(int p_cid); - - //helper function that populates ui_music_list with the contents of music_list - void list_music(); - void list_areas(); - - //these are for OOC chat - void append_ms_chatmessage(QString f_name, QString f_message); - void append_server_chatmessage(QString p_name, QString p_message, QString p_colour); - - //these functions handle chatmessages sequentially. - //The process itself is very convoluted and merits separate documentation - //But the general idea is objection animation->pre animation->talking->idle - void handle_chatmessage(QStringList *p_contents); - void handle_chatmessage_2(); - void handle_chatmessage_3(); - - //This function filters out the common CC inline text trickery, for appending to - //the IC chatlog. - QString filter_ic_text(QString p_text); - - //adds text to the IC chatlog. p_name first as bold then p_text then a newlin - //this function keeps the chatlog scrolled to the top unless there's text selected - // or the user isn't already scrolled to the top - void append_ic_text(QString p_text, QString p_name = "", bool is_songchange = false); - - //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 the second is the char id of who played it - void handle_song(QStringList *p_contents); - - void play_preanim(bool noninterrupting); - - //plays the witness testimony or cross examination animation based on argument - void handle_wtce(QString p_wtce, int variant); - - //sets the hp bar of defense(p_bar 1) or pro(p_bar 2) - //state is an number between 0 and 10 inclusive - void set_hp_bar(int p_bar, int p_state); - - //Toggles the judge buttons, whether they should appear or not. - void toggle_judge_buttons(bool is_on); - - void announce_case(QString title, bool def, bool pro, bool jud, bool jur, bool steno); - - void check_connection_received(); - - ~Courtroom(); - -private: - AOApplication *ao_app; - - int m_courtroom_width = 714; - int m_courtroom_height = 668; - - int m_viewport_x = 0; - int m_viewport_y = 0; - - int m_viewport_width = 256; - int m_viewport_height = 192; - - bool first_message_sent = false; - int maximumMessages = 0; - - // This is for inline message-colouring. - - enum INLINE_COLOURS { - INLINE_BLUE, - INLINE_GREEN, - INLINE_ORANGE, - INLINE_GREY - }; - - // A stack of inline colours. - std::stack inline_colour_stack; - - bool next_character_is_not_special = false; // If true, write the - // next character as it is. - - bool message_is_centered = false; - - int current_display_speed = 3; - int message_display_speed[7] = {30, 40, 50, 60, 75, 100, 120}; - - // This is for checking if the character should start talking again - // when an inline blue text ends. - bool entire_message_is_blue = false; - - // And this is the inline 'talking checker'. Counts how 'deep' we are - // in inline blues. - int inline_blue_depth = 0; - - // 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. - int offset_with_pair = 0; - - QVector char_list; - QVector evidence_list; - QVector music_list; - QVector area_list; - - QVector arup_players; - QVector arup_statuses; - QVector arup_cms; - QVector arup_locks; - - QSignalMapper *char_button_mapper; - - QVector ic_chatlog_history; - - // These map music row items and area row items to their actual IDs. - QVector music_row_to_number; - QVector area_row_to_number; - - //triggers ping_server() every 60 seconds - QTimer *keepalive_timer; - - //determines how fast messages tick onto screen - QTimer *chat_tick_timer; - //int chat_tick_interval = 60; - //which tick position(character in chat message) we are at - int tick_pos = 0; - //used to determine how often blips sound - int blip_pos = 0; - int blip_rate = 1; - int rainbow_counter = 0; - bool rainbow_appended = false; - bool blank_blip = false; - - // Used for getting the current maximum blocks allowed in the IC chatlog. - int log_maximum_blocks = 0; - - // True, if the log should go downwards. - bool log_goes_downwards = false; - - //delay before chat messages starts ticking - QTimer *text_delay_timer; - - //delay before sfx plays - QTimer *sfx_delay_timer; - - //keeps track of how long realization is visible(it's just a white square and should be visible less than a second) - QTimer *realization_timer; - - //times how long the blinking testimony should be shown(green one in the corner) - QTimer *testimony_show_timer; - //times how long the blinking testimony should be hidden - QTimer *testimony_hide_timer; - - //every time point in char.inis times this equals the final time - const int time_mod = 40; - - static const int chatmessage_size = 23; - QString m_chatmessage[chatmessage_size]; - bool chatmessage_is_empty = false; - - QString previous_ic_message = ""; - - bool testimony_in_progress = false; - - //in milliseconds - const int testimony_show_time = 1500; - - //in milliseconds - const int testimony_hide_time = 500; - - //char id, muted or not - QMap mute_map; - - //QVector muted_cids; - - bool is_muted = false; - - //state of animation, 0 = objecting, 1 = preanim, 2 = talking, 3 = idle, 4 = noniterrupting preanim - int anim_state = 3; - - //state of text ticking, 0 = not yet ticking, 1 = ticking in progress, 2 = ticking done - int text_state = 2; - - //character id, which index of the char_list the player is - int m_cid = -1; - //cid and this may differ in cases of ini-editing - QString current_char = ""; - - int objection_state = 0; - int realization_state = 0; - int text_color = 0; - bool is_presenting_evidence = false; - - int defense_bar_state = 0; - int prosecution_bar_state = 0; - - int current_char_page = 0; - int char_columns = 10; - int char_rows = 9; - int max_chars_on_page = 90; - - const int button_width = 60; - const int button_height = 60; - - int current_emote_page = 0; - int current_emote = 0; - int emote_columns = 5; - int emote_rows = 2; - int max_emotes_on_page = 10; - - QVector local_evidence_list; - - int current_evidence_page = 0; - int current_evidence = 0; - int evidence_columns = 6; - int evidence_rows = 3; - int max_evidence_on_page = 18; - - //is set to true if the bg folder contains defensedesk.png, prosecutiondesk.png and stand.png - bool is_ao2_bg = false; - - //whether the ooc chat is server or master chat, true is server - bool server_ooc = true; - - QString current_background = "default"; - - AOMusicPlayer *music_player; - AOSfxPlayer *sfx_player; - AOSfxPlayer *objection_player; - AOBlipPlayer *blip_player; - - AOSfxPlayer *modcall_player; - - AOImage *ui_background; - - QWidget *ui_viewport; - AOScene *ui_vp_background; - AOMovie *ui_vp_speedlines; - AOCharMovie *ui_vp_player_char; - AOCharMovie *ui_vp_sideplayer_char; - AOScene *ui_vp_desk; - AOScene *ui_vp_legacy_desk; - AOEvidenceDisplay *ui_vp_evidence_display; - AOImage *ui_vp_chatbox; - QLabel *ui_vp_showname; - QTextEdit *ui_vp_message; - AOImage *ui_vp_testimony; - AOImage *ui_vp_realization; - AOMovie *ui_vp_wtce; - AOMovie *ui_vp_objection; - - QTextEdit *ui_ic_chatlog; - - AOTextArea *ui_ms_chatlog; - AOTextArea *ui_server_chatlog; - - QListWidget *ui_mute_list; - QListWidget *ui_area_list; - QListWidget *ui_music_list; - - AOButton *ui_pair_button; - QListWidget *ui_pair_list; - QSpinBox *ui_pair_offset_spinbox; - - QLineEdit *ui_ic_chat_message; - QLineEdit *ui_ic_chat_name; - - QLineEdit *ui_ooc_chat_message; - QLineEdit *ui_ooc_chat_name; - - //QLineEdit *ui_area_password; - QLineEdit *ui_music_search; - - QWidget *ui_emotes; - QVector ui_emote_list; - AOButton *ui_emote_left; - AOButton *ui_emote_right; - - QComboBox *ui_emote_dropdown; - QComboBox *ui_pos_dropdown; - - AOImage *ui_defense_bar; - AOImage *ui_prosecution_bar; - - QLabel *ui_music_label; - QLabel *ui_sfx_label; - QLabel *ui_blip_label; - - AOButton *ui_hold_it; - AOButton *ui_objection; - AOButton *ui_take_that; - - AOButton *ui_ooc_toggle; - - AOButton *ui_witness_testimony; - AOButton *ui_cross_examination; - AOButton *ui_guilty; - AOButton *ui_not_guilty; - - AOButton *ui_change_character; - AOButton *ui_reload_theme; - AOButton *ui_call_mod; - AOButton *ui_settings; - AOButton *ui_announce_casing; - AOButton *ui_switch_area_music; - - QCheckBox *ui_pre; - QCheckBox *ui_flip; - QCheckBox *ui_guard; - QCheckBox *ui_casing; - - QCheckBox *ui_pre_non_interrupt; - QCheckBox *ui_showname_enable; - - AOButton *ui_custom_objection; - AOButton *ui_realization; - AOButton *ui_mute; - - AOButton *ui_defense_plus; - AOButton *ui_defense_minus; - - AOButton *ui_prosecution_plus; - AOButton *ui_prosecution_minus; - - QComboBox *ui_text_color; - - QSlider *ui_music_slider; - QSlider *ui_sfx_slider; - QSlider *ui_blip_slider; - - AOImage *ui_muted; - - QSpinBox *ui_log_limit_spinbox; - QLabel *ui_log_limit_label; - - AOButton *ui_evidence_button; - AOImage *ui_evidence; - AOLineEdit *ui_evidence_name; - QWidget *ui_evidence_buttons; - QVector ui_evidence_list; - AOButton *ui_evidence_left; - AOButton *ui_evidence_right; - AOButton *ui_evidence_present; - AOImage *ui_evidence_overlay; - AOButton *ui_evidence_delete; - AOLineEdit *ui_evidence_image_name; - AOButton *ui_evidence_image_button; - AOButton *ui_evidence_x; - AOTextEdit *ui_evidence_description; - - AOImage *ui_char_select_background; - - //abstract widget to hold char buttons - QWidget *ui_char_buttons; - - QVector ui_char_button_list; - QVector ui_char_button_list_filtered; - AOImage *ui_selector; - - AOButton *ui_back_to_lobby; - - QLineEdit *ui_char_password; - - AOButton *ui_char_select_left; - AOButton *ui_char_select_right; - - AOButton *ui_spectator; - - QLineEdit *ui_char_search; - QCheckBox *ui_char_passworded; - QCheckBox *ui_char_taken; - - void construct_char_select(); - void set_char_select(); - void set_char_select_page(); - void put_button_in_place(int starting, int chars_on_this_page); - void filter_character_list(); - - void construct_emotes(); - void set_emote_page(); - void set_emote_dropdown(); - - void construct_evidence(); - void set_evidence_page(); - -public slots: - void objection_done(); - void preanim_done(); - - void realization_done(); - - void show_testimony(); - void hide_testimony(); - - void mod_called(QString p_ip); - - void case_called(QString msg, bool def, bool pro, bool jud, bool jur, bool steno); - -private slots: - void start_chat_ticking(); - void play_sfx(); - - void chat_tick(); - - void on_mute_list_clicked(QModelIndex p_index); - void on_pair_list_clicked(QModelIndex p_index); - - void on_chat_return_pressed(); - - void on_ooc_return_pressed(); - - void on_music_search_edited(QString p_text); - void on_music_list_double_clicked(QModelIndex p_model); - void on_area_list_double_clicked(QModelIndex p_model); - - void select_emote(int p_id); - - void on_emote_clicked(int p_id); - - void on_emote_left_clicked(); - void on_emote_right_clicked(); - - void on_emote_dropdown_changed(int p_index); - void on_pos_dropdown_changed(int p_index); - - void on_evidence_name_edited(); - void on_evidence_image_name_edited(); - void on_evidence_image_button_clicked(); - void on_evidence_clicked(int p_id); - void on_evidence_double_clicked(int p_id); - - void on_evidence_hover(int p_id, bool p_state); - - void on_evidence_left_clicked(); - void on_evidence_right_clicked(); - void on_evidence_present_clicked(); - - void on_hold_it_clicked(); - void on_objection_clicked(); - void on_take_that_clicked(); - void on_custom_objection_clicked(); - - void on_realization_clicked(); - - void on_mute_clicked(); - void on_pair_clicked(); - - void on_defense_minus_clicked(); - void on_defense_plus_clicked(); - void on_prosecution_minus_clicked(); - void on_prosecution_plus_clicked(); - - void on_text_color_changed(int p_color); - - void on_music_slider_moved(int p_value); - void on_sfx_slider_moved(int p_value); - void on_blip_slider_moved(int p_value); - - void on_log_limit_changed(int value); - void on_pair_offset_changed(int value); - - void on_ooc_toggle_clicked(); - - void on_witness_testimony_clicked(); - void on_cross_examination_clicked(); - void on_not_guilty_clicked(); - void on_guilty_clicked(); - - void on_change_character_clicked(); - void on_reload_theme_clicked(); - void on_call_mod_clicked(); - void on_settings_clicked(); - void on_announce_casing_clicked(); - - void on_pre_clicked(); - void on_flip_clicked(); - void on_guard_clicked(); - - void on_showname_enable_clicked(); - - void on_evidence_button_clicked(); - - void on_evidence_delete_clicked(); - void on_evidence_x_clicked(); - - void on_back_to_lobby_clicked(); - - void on_char_select_left_clicked(); - void on_char_select_right_clicked(); - void on_char_search_changed(const QString& newtext); - void on_char_taken_clicked(int newstate); - void on_char_passworded_clicked(int newstate); - - void on_spectator_clicked(); - - void char_clicked(int n_char); - - void on_switch_area_music_clicked(); - - void on_casing_clicked(); - - void ping_server(); - - void load_bass_opus_plugin(); -}; - -#endif // COURTROOM_H diff --git a/datatypes.h b/datatypes.h deleted file mode 100644 index aaa5de52..00000000 --- a/datatypes.h +++ /dev/null @@ -1,119 +0,0 @@ -#ifndef DATATYPES_H -#define DATATYPES_H - -#include - -struct server_type -{ - QString name; - QString desc; - QString ip; - int port; -}; - -struct emote_type -{ - QString comment; - QString preanim; - QString anim; - int mod; - QString sfx_name; - int sfx_delay; - int sfx_duration; -}; - -struct char_type -{ - QString name; - QString description; - QString evidence_string; - bool taken; -}; - -struct evi_type -{ - QString name; - QString description; - QString image; -}; - -struct chatmessage_type -{ - QString message; - QString character; - QString side; - QString sfx_name; - QString pre_emote; - QString emote; - int emote_modifier; - int objection_modifier; - int realization; - int text_color; - int evidence; - int cid; - int sfx_delay; - int flip; -}; - -struct area_type -{ - QString name; - QString background; - bool passworded; -}; - -struct pos_type -{ - int x; - int y; -}; - -struct pos_size_type -{ - int x = 0; - int y = 0; - int width = 0; - int height = 0; -}; - -enum CHAT_MESSAGE -{ - DESK_MOD = 0, - PRE_EMOTE, - CHAR_NAME, - EMOTE, - MESSAGE, - SIDE, - SFX_NAME, - EMOTE_MOD, - CHAR_ID, - SFX_DELAY, - OBJECTION_MOD, - EVIDENCE_ID, - FLIP, - REALIZATION, - TEXT_COLOR, - SHOWNAME, - OTHER_CHARID, - OTHER_NAME, - OTHER_EMOTE, - SELF_OFFSET, - OTHER_OFFSET, - OTHER_FLIP, - NONINTERRUPTING_PRE -}; - -enum COLOR -{ - WHITE = 0, - GREEN, - RED, - ORANGE, - BLUE, - YELLOW, - RAINBOW, - PINK, - CYAN -}; - -#endif // DATATYPES_H diff --git a/debug_functions.cpp b/debug_functions.cpp deleted file mode 100644 index 77f2f35a..00000000 --- a/debug_functions.cpp +++ /dev/null @@ -1,25 +0,0 @@ -#include "debug_functions.h" - -void call_error(QString p_message) -{ - QMessageBox *msgBox = new QMessageBox; - - msgBox->setText("Error: " + p_message); - msgBox->setWindowTitle("Error"); - - - //msgBox->setWindowModality(Qt::NonModal); - msgBox->exec(); -} - -void call_notice(QString p_message) -{ - QMessageBox *msgBox = new QMessageBox; - - msgBox->setText(p_message); - msgBox->setWindowTitle("Notice"); - - - //msgBox->setWindowModality(Qt::NonModal); - msgBox->exec(); -} diff --git a/debug_functions.h b/debug_functions.h deleted file mode 100644 index 160274cc..00000000 --- a/debug_functions.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef DEBUG_FUNCTIONS_H -#define DEBUG_FUNCTIONS_H - -#include -#include - -void call_error(QString message); -void call_notice(QString message); - -#endif // DEBUG_FUNCTIONS_H diff --git a/discord-rpc.h b/discord-rpc.h deleted file mode 100644 index feb874b2..00000000 --- a/discord-rpc.h +++ /dev/null @@ -1,85 +0,0 @@ -#pragma once -#include - -// clang-format off - -#if defined(DISCORD_DYNAMIC_LIB) -# if defined(_WIN32) -# if defined(DISCORD_BUILDING_SDK) -# define DISCORD_EXPORT __declspec(dllexport) -# else -# define DISCORD_EXPORT __declspec(dllimport) -# endif -# else -# define DISCORD_EXPORT __attribute__((visibility("default"))) -# endif -#else -# define DISCORD_EXPORT -#endif - -// clang-format on - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct DiscordRichPresence { - const char* state; /* max 128 bytes */ - const char* details; /* max 128 bytes */ - int64_t startTimestamp; - int64_t endTimestamp; - const char* largeImageKey; /* max 32 bytes */ - const char* largeImageText; /* max 128 bytes */ - const char* smallImageKey; /* max 32 bytes */ - const char* smallImageText; /* max 128 bytes */ - const char* partyId; /* max 128 bytes */ - int partySize; - int partyMax; - const char* matchSecret; /* max 128 bytes */ - const char* joinSecret; /* max 128 bytes */ - const char* spectateSecret; /* max 128 bytes */ - int8_t instance; -} DiscordRichPresence; - -typedef struct DiscordJoinRequest { - const char* userId; - const char* username; - const char* discriminator; - const char* avatar; -} DiscordJoinRequest; - -typedef struct DiscordEventHandlers { - void (*ready)(void); - void (*disconnected)(int errorCode, const char* message); - void (*errored)(int errorCode, const char* message); - void (*joinGame)(const char* joinSecret); - void (*spectateGame)(const char* spectateSecret); - void (*joinRequest)(const DiscordJoinRequest* request); -} DiscordEventHandlers; - -#define DISCORD_REPLY_NO 0 -#define DISCORD_REPLY_YES 1 -#define DISCORD_REPLY_IGNORE 2 - -DISCORD_EXPORT void Discord_Initialize(const char* applicationId, - DiscordEventHandlers* handlers, - int autoRegister, - const char* optionalSteamId); -DISCORD_EXPORT void Discord_Shutdown(void); - -/* checks for incoming messages, dispatches callbacks */ -DISCORD_EXPORT void Discord_RunCallbacks(void); - -/* If you disable the lib starting its own io thread, you'll need to call this from your own */ -#ifdef DISCORD_DISABLE_IO_THREAD -DISCORD_EXPORT void Discord_UpdateConnection(void); -#endif - -DISCORD_EXPORT void Discord_UpdatePresence(const DiscordRichPresence* presence); -DISCORD_EXPORT void Discord_ClearPresence(void); - -DISCORD_EXPORT void Discord_Respond(const char* userid, /* DISCORD_REPLY_ */ int reply); - -#ifdef __cplusplus -} /* extern "C" */ -#endif diff --git a/discord_rich_presence.cpp b/discord_rich_presence.cpp deleted file mode 100644 index 10f5833e..00000000 --- a/discord_rich_presence.cpp +++ /dev/null @@ -1,103 +0,0 @@ -#include "discord_rich_presence.h" - -namespace AttorneyOnline { - -Discord::Discord() -{ - DiscordEventHandlers handlers; - std::memset(&handlers, 0, sizeof(handlers)); - handlers = {}; - handlers.ready = [] { - qInfo() << "Discord RPC ready"; - }; - handlers.disconnected = [](int errorCode, const char* message) { - qInfo() << "Discord RPC disconnected! " << message; - }; - handlers.errored = [](int errorCode, const char* message) { - qWarning() << "Discord RPC errored out! " << message; - }; - qInfo() << "Initializing Discord RPC"; - Discord_Initialize(APPLICATION_ID, &handlers, 1, nullptr); -} - -Discord::~Discord() -{ - Discord_Shutdown(); -} - -void Discord::state_lobby() -{ - DiscordRichPresence presence; - std::memset(&presence, 0, sizeof(presence)); - presence.largeImageKey = "ao2-logo"; - presence.largeImageText = "Objection!"; - presence.instance = 1; - - presence.state = "In Lobby"; - presence.details = "Idle"; - Discord_UpdatePresence(&presence); -} - -void Discord::state_server(std::string name, std::string server_id) -{ - qDebug() << "Discord RPC: Setting server state"; - - DiscordRichPresence presence; - std::memset(&presence, 0, sizeof(presence)); - presence.largeImageKey = "ao2-logo"; - presence.largeImageText = "Objection!"; - presence.instance = 1; - - auto timestamp = static_cast(std::time(nullptr)); - - presence.state = "In a Server"; - presence.details = name.c_str(); - presence.matchSecret = server_id.c_str(); - presence.startTimestamp = this->timestamp; - - this->server_id = server_id; - this->server_name = name; - this->timestamp = timestamp; - Discord_UpdatePresence(&presence); -} - -void Discord::state_character(std::string name) -{ - auto name_internal = QString(name.c_str()).toLower().replace(' ', '_').toStdString(); - auto name_friendly = QString(name.c_str()).replace('_', ' ').toStdString(); - const std::string playing_as = "Playing as " + name_friendly; - qDebug() << "Discord RPC: Setting character state (" << playing_as.c_str() << ")"; - - DiscordRichPresence presence; - std::memset(&presence, 0, sizeof(presence)); - presence.largeImageKey = "ao2-logo"; - presence.largeImageText = "Objection!"; - presence.instance = 1; - presence.details = this->server_name.c_str(); - presence.matchSecret = this->server_id.c_str(); - presence.startTimestamp = this->timestamp; - - presence.state = playing_as.c_str(); - presence.smallImageKey = name_internal.c_str(); - // presence.smallImageText = name_internal.c_str(); - Discord_UpdatePresence(&presence); -} - -void Discord::state_spectate() -{ - qDebug() << "Discord RPC: Setting specator state"; - - DiscordRichPresence presence; - std::memset(&presence, 0, sizeof(presence)); - presence.largeImageKey = "ao2-logo"; - presence.largeImageText = "Objection!"; - presence.instance = 1; - presence.details = this->server_name.c_str(); - presence.matchSecret = this->server_id.c_str(); - presence.startTimestamp = this->timestamp; - - presence.state = "Spectating"; - Discord_UpdatePresence(&presence); -} - -} diff --git a/discord_rich_presence.h b/discord_rich_presence.h deleted file mode 100644 index e7ecc6ef..00000000 --- a/discord_rich_presence.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef DISCORD_RICH_PRESENCE_H -#define DISCORD_RICH_PRESENCE_H - -#include -#include -#include -#include -#include - -#include -#include - -#include - -namespace AttorneyOnline { - -class Discord -{ -private: - const char* APPLICATION_ID = "399779271737868288"; - std::string server_name, server_id; - int64_t timestamp; -public: - Discord(); - ~Discord(); - - void state_lobby(); - void state_server(std::string name, std::string server_id); - void state_character(std::string name); - void state_spectate(); -}; - -} -#endif // DISCORD_RICH_PRESENCE_H diff --git a/emotes.cpp b/emotes.cpp deleted file mode 100644 index b6a217e6..00000000 --- a/emotes.cpp +++ /dev/null @@ -1,174 +0,0 @@ -#include "courtroom.h" - -#include "aoemotebutton.h" - -void Courtroom::construct_emotes() -{ - ui_emotes = new QWidget(this); - - set_size_and_pos(ui_emotes, "emotes"); - - QPoint f_spacing = ao_app->get_button_spacing("emote_button_spacing", "courtroom_design.ini"); - - const int button_width = 40; - int x_spacing = f_spacing.x(); - int x_mod_count = 0; - - const int button_height = 40; - int y_spacing = f_spacing.y(); - int y_mod_count = 0; - - emote_columns = ((ui_emotes->width() - button_width) / (x_spacing + button_width)) + 1; - emote_rows = ((ui_emotes->height() - button_height) / (y_spacing + button_height)) + 1; - - max_emotes_on_page = emote_columns * emote_rows; - - for (int n = 0 ; n < max_emotes_on_page ; ++n) - { - int x_pos = (button_width + x_spacing) * x_mod_count; - int y_pos = (button_height + y_spacing) * y_mod_count; - - AOEmoteButton *f_emote = new AOEmoteButton(ui_emotes, ao_app, x_pos, y_pos); - - ui_emote_list.append(f_emote); - - f_emote->set_id(n); - - connect(f_emote, SIGNAL(emote_clicked(int)), this, SLOT(on_emote_clicked(int))); - - ++x_mod_count; - - if (x_mod_count == emote_columns) - { - ++y_mod_count; - x_mod_count = 0; - } - } -} - -void Courtroom::set_emote_page() -{ - if (m_cid == -1) - return; - - int total_emotes = ao_app->get_emote_number(current_char); - - ui_emote_left->hide(); - ui_emote_right->hide(); - - for (AOEmoteButton *i_button : ui_emote_list) - { - i_button->hide(); - } - - int total_pages = total_emotes / max_emotes_on_page; - int emotes_on_page = 0; - - if (total_emotes % max_emotes_on_page != 0) - { - ++total_pages; - //i. e. not on the last page - if (total_pages > current_emote_page + 1) - emotes_on_page = max_emotes_on_page; - else - emotes_on_page = total_emotes % max_emotes_on_page; - - } - else - emotes_on_page = max_emotes_on_page; - - if (total_pages > current_emote_page + 1) - ui_emote_right->show(); - - if (current_emote_page > 0) - ui_emote_left->show(); - - for (int n_emote = 0 ; n_emote < emotes_on_page ; ++n_emote) - { - int n_real_emote = n_emote + current_emote_page * max_emotes_on_page; - AOEmoteButton *f_emote = ui_emote_list.at(n_emote); - - if (n_real_emote == current_emote) - f_emote->set_image(current_char, n_real_emote, "_on.png"); - else - f_emote->set_image(current_char, n_real_emote, "_off.png"); - - f_emote->show(); - } - -} - -void Courtroom::set_emote_dropdown() -{ - ui_emote_dropdown->clear(); - - int total_emotes = ao_app->get_emote_number(current_char); - QStringList emote_list; - - for (int n = 0 ; n < total_emotes ; ++n) - { - emote_list.append(ao_app->get_emote_comment(current_char, n)); - } - - ui_emote_dropdown->addItems(emote_list); -} - -void Courtroom::select_emote(int p_id) -{ - int min = current_emote_page * max_emotes_on_page; - int max = (max_emotes_on_page - 1) + current_emote_page * max_emotes_on_page; - - if (current_emote >= min && current_emote <= max) - ui_emote_list.at(current_emote % max_emotes_on_page)->set_image(current_char, current_emote, "_off.png"); - - int old_emote = current_emote; - - current_emote = p_id; - - if (current_emote >= min && current_emote <= max) - ui_emote_list.at(current_emote % max_emotes_on_page)->set_image(current_char, current_emote, "_on.png"); - - int emote_mod = ao_app->get_emote_mod(current_char, current_emote); - - if (old_emote == current_emote) - { - ui_pre->setChecked(!ui_pre->isChecked()); - } - else if (emote_mod == 1) - ui_pre->setChecked(true); - else - ui_pre->setChecked(false); - - ui_emote_dropdown->setCurrentIndex(current_emote); - - ui_ic_chat_message->setFocus(); -} - -void Courtroom::on_emote_clicked(int p_id) -{ - select_emote(p_id + max_emotes_on_page * current_emote_page); -} - -void Courtroom::on_emote_left_clicked() -{ - --current_emote_page; - - set_emote_page(); - - ui_ic_chat_message->setFocus(); -} - -void Courtroom::on_emote_right_clicked() -{ - qDebug() << "emote right clicked"; - ++current_emote_page; - - set_emote_page(); - - ui_ic_chat_message->setFocus(); -} - -void Courtroom::on_emote_dropdown_changed(int p_index) -{ - select_emote(p_index); -} diff --git a/encryption_functions.cpp b/encryption_functions.cpp deleted file mode 100644 index ffbe0cdb..00000000 --- a/encryption_functions.cpp +++ /dev/null @@ -1,63 +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 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 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/encryption_functions.h b/encryption_functions.h deleted file mode 100644 index dc67d122..00000000 --- a/encryption_functions.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef ENCRYPTION_FUNCTIONS_H -#define ENCRYPTION_FUNCTIONS_H - -#include - -#include -#include -#include -#include -#include - -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/evidence.cpp b/evidence.cpp deleted file mode 100644 index 4e796642..00000000 --- a/evidence.cpp +++ /dev/null @@ -1,345 +0,0 @@ -#include "courtroom.h" - -void Courtroom::construct_evidence() -{ - ui_evidence = new AOImage(this, ao_app); - - //ui_evidence_name = new QLabel(ui_evidence); - ui_evidence_name = new AOLineEdit(ui_evidence); - ui_evidence_name->setAlignment(Qt::AlignCenter); - ui_evidence_name->setFont(QFont("Arial", 14, QFont::Bold)); - ui_evidence_name->setStyleSheet("background-color: rgba(0, 0, 0, 0);" - "color: rgba(255, 128, 0, 255);"); - - ui_evidence_buttons = new QWidget(ui_evidence); - - ui_evidence_left = new AOButton(ui_evidence, ao_app); - ui_evidence_right = new AOButton(ui_evidence, ao_app); - ui_evidence_present = new AOButton(ui_evidence, ao_app); - - ui_evidence_overlay = new AOImage(ui_evidence, ao_app); - - ui_evidence_delete = new AOButton(ui_evidence_overlay, ao_app); - ui_evidence_image_name = new AOLineEdit(ui_evidence_overlay); - ui_evidence_image_button = new AOButton(ui_evidence_overlay, ao_app); - ui_evidence_image_button->setText("Choose.."); - ui_evidence_x = new AOButton(ui_evidence_overlay, ao_app); - - ui_evidence_description = new AOTextEdit(ui_evidence_overlay); - ui_evidence_description->setStyleSheet("background-color: rgba(0, 0, 0, 0);" - "color: white;"); - - set_size_and_pos(ui_evidence, "evidence_background"); - set_size_and_pos(ui_evidence_buttons, "evidence_buttons"); - - QPoint f_spacing = ao_app->get_button_spacing("evidence_button_spacing", "courtroom_design.ini"); - - const int button_width = 70; - int x_spacing = f_spacing.x(); - int x_mod_count = 0; - - const int button_height = 70; - int y_spacing = f_spacing.y(); - int y_mod_count = 0; - - evidence_columns = ((ui_evidence_buttons->width() - button_width) / (x_spacing + button_width)) + 1; - evidence_rows = ((ui_evidence_buttons->height() - button_height) / (y_spacing + button_height)) + 1; - - max_evidence_on_page = evidence_columns * evidence_rows; - - for (int n = 0 ; n < max_evidence_on_page ; ++n) - { - int x_pos = (button_width + x_spacing) * x_mod_count; - int y_pos = (button_height + y_spacing) * y_mod_count; - - AOEvidenceButton *f_evidence = new AOEvidenceButton(ui_evidence_buttons, ao_app, x_pos, y_pos); - - ui_evidence_list.append(f_evidence); - - f_evidence->set_id(n); - - connect(f_evidence, SIGNAL(evidence_clicked(int)), this, SLOT(on_evidence_clicked(int))); - connect(f_evidence, SIGNAL(evidence_double_clicked(int)), this, SLOT(on_evidence_double_clicked(int))); - connect(f_evidence, SIGNAL(on_hover(int, bool)), this, SLOT(on_evidence_hover(int, bool))); - - ++x_mod_count; - - if (x_mod_count == evidence_columns) - { - ++y_mod_count; - x_mod_count = 0; - } - } - - connect(ui_evidence_name, SIGNAL(returnPressed()), this, SLOT(on_evidence_name_edited())); - connect(ui_evidence_left, SIGNAL(clicked()), this, SLOT(on_evidence_left_clicked())); - connect(ui_evidence_right, SIGNAL(clicked()), this, SLOT(on_evidence_right_clicked())); - connect(ui_evidence_present, SIGNAL(clicked()), this, SLOT(on_evidence_present_clicked())); - connect(ui_evidence_delete, SIGNAL(clicked()), this, SLOT(on_evidence_delete_clicked())); - connect(ui_evidence_image_name, SIGNAL(returnPressed()), this, SLOT(on_evidence_image_name_edited())); - connect(ui_evidence_image_button, SIGNAL(clicked()), this, SLOT(on_evidence_image_button_clicked())); - connect(ui_evidence_x, SIGNAL(clicked()), this, SLOT(on_evidence_x_clicked())); - - ui_evidence->hide(); -} - -void Courtroom::set_evidence_list(QVector &p_evi_list) -{ - local_evidence_list.clear(); - local_evidence_list = p_evi_list; - - set_evidence_page(); -} - -void Courtroom::set_evidence_page() -{ - int total_evidence = local_evidence_list.size(); - - ui_evidence_left->hide(); - ui_evidence_right->hide(); - - for (AOEvidenceButton *i_button : ui_evidence_list) - { - i_button->reset(); - } - - //to account for the "add evidence" button - ++total_evidence; - - int total_pages = total_evidence / max_evidence_on_page; - int evidence_on_page = 0; - - if ((total_evidence % max_evidence_on_page) != 0) - { - ++total_pages; - //i. e. not on the last page - if (total_pages > current_evidence_page + 1) - evidence_on_page = max_evidence_on_page; - else - evidence_on_page = total_evidence % max_evidence_on_page; - - } - else - evidence_on_page = max_evidence_on_page; - - if (total_pages > current_evidence_page + 1) - ui_evidence_right->show(); - - if (current_evidence_page > 0) - ui_evidence_left->show(); - - for (int n_evidence_button = 0 ; n_evidence_button < evidence_on_page ; ++n_evidence_button) - { - int n_real_evidence = n_evidence_button + current_evidence_page * max_evidence_on_page; - AOEvidenceButton *f_evidence_button = ui_evidence_list.at(n_evidence_button); - - //ie. the add evidence button - if (n_real_evidence == (total_evidence - 1)) - f_evidence_button->set_theme_image("addevidence.png"); - else if (n_real_evidence < (total_evidence - 1)) - { - f_evidence_button->set_image(local_evidence_list.at(n_real_evidence).image); - - if (n_real_evidence == current_evidence) - f_evidence_button->set_selected(true); - else - f_evidence_button->set_selected(false); - } - else - f_evidence_button->set_image(""); - - f_evidence_button->show(); - } -} - -void Courtroom::on_evidence_name_edited() -{ - if (current_evidence >= local_evidence_list.size()) - return; - - QStringList f_contents; - - evi_type f_evi = local_evidence_list.at(current_evidence); - - f_contents.append(QString::number(current_evidence)); - f_contents.append(ui_evidence_name->text()); - f_contents.append(f_evi.description); - f_contents.append(f_evi.image); - - ao_app->send_server_packet(new AOPacket("EE", f_contents)); -} - -void Courtroom::on_evidence_image_name_edited() -{ - if (current_evidence >= local_evidence_list.size()) - return; - - QStringList f_contents; - - evi_type f_evi = local_evidence_list.at(current_evidence); - - f_contents.append(QString::number(current_evidence)); - f_contents.append(f_evi.name); - f_contents.append(f_evi.description); - f_contents.append(ui_evidence_image_name->text()); - - ao_app->send_server_packet(new AOPacket("EE", f_contents)); -} - -void Courtroom::on_evidence_image_button_clicked() -{ - QFileDialog dialog(this); - dialog.setFileMode(QFileDialog::ExistingFile); - dialog.setNameFilter(tr("Images (*.png)")); - dialog.setViewMode(QFileDialog::List); - dialog.setDirectory(ao_app->get_base_path() + "evidence"); - - QStringList filenames; - - if (dialog.exec()) - filenames = dialog.selectedFiles(); - - if (filenames.size() != 1) - return; - - QString filename = filenames.at(0); - - QStringList split_filename = filename.split("/"); - - filename = split_filename.at(split_filename.size() - 1); - - ui_evidence_image_name->setText(filename); - - on_evidence_image_name_edited(); -} - -void Courtroom::on_evidence_clicked(int p_id) -{ - ui_evidence_name->setReadOnly(true); - - int f_real_id = p_id + max_evidence_on_page * current_evidence_page; - - if (f_real_id == local_evidence_list.size()) - { - ao_app->send_server_packet(new AOPacket("PE###empty.png#%")); - return; - } - else if (f_real_id > local_evidence_list.size()) - return; - - ui_evidence_name->setText(local_evidence_list.at(f_real_id).name); - - for (AOEvidenceButton *i_button : ui_evidence_list) - i_button->set_selected(false); - - ui_evidence_list.at(p_id)->set_selected(true); - - current_evidence = f_real_id; - - ui_ic_chat_message->setFocus(); - -} - -void Courtroom::on_evidence_double_clicked(int p_id) -{ - int f_real_id = p_id + max_evidence_on_page * current_evidence_page; - - if (f_real_id >= local_evidence_list.size()) - return; - - current_evidence = f_real_id; - - evi_type f_evi = local_evidence_list.at(f_real_id); - - ui_evidence_description->clear(); - ui_evidence_description->appendPlainText(f_evi.description); - - ui_evidence_image_name->setText(f_evi.image); - - ui_evidence_overlay->show(); - - ui_ic_chat_message->setFocus(); -} - -void Courtroom::on_evidence_hover(int p_id, bool p_state) -{ - ui_evidence_name->setReadOnly(true); - int final_id = p_id + max_evidence_on_page * current_evidence_page; - - if (p_state) - { - if (final_id == local_evidence_list.size()) - ui_evidence_name->setText("Add new evidence..."); - else if (final_id < local_evidence_list.size()) - ui_evidence_name->setText(local_evidence_list.at(final_id).name); - } - else if (current_evidence < local_evidence_list.size()) - ui_evidence_name->setText(local_evidence_list.at(current_evidence).name); - else - ui_evidence_name->setText(""); -} - -void Courtroom::on_evidence_left_clicked() -{ - --current_evidence_page; - - set_evidence_page(); - - ui_ic_chat_message->setFocus(); -} - -void Courtroom::on_evidence_right_clicked() -{ - ++current_evidence_page; - - set_evidence_page(); - - ui_ic_chat_message->setFocus(); -} - -void Courtroom::on_evidence_present_clicked() -{ - if (is_presenting_evidence) - ui_evidence_present->set_image("present_disabled.png"); - else - ui_evidence_present->set_image("present.png"); - - is_presenting_evidence = !is_presenting_evidence; - - ui_ic_chat_message->setFocus(); -} - -void Courtroom::on_evidence_delete_clicked() -{ - ui_evidence_description->setReadOnly(true); - ui_evidence_overlay->hide(); - - ao_app->send_server_packet(new AOPacket("DE#" + QString::number(current_evidence) + "#%")); - - current_evidence = 0; - - ui_ic_chat_message->setFocus(); -} - -void Courtroom::on_evidence_x_clicked() -{ - ui_evidence_description->setReadOnly(true); - ui_evidence_overlay->hide(); - - if (current_evidence >= local_evidence_list.size()) - return; - - QStringList f_contents; - - evi_type f_evi = local_evidence_list.at(current_evidence); - - f_contents.append(QString::number(current_evidence)); - f_contents.append(f_evi.name); - f_contents.append(ui_evidence_description->toPlainText()); - f_contents.append(f_evi.image); - - ao_app->send_server_packet(new AOPacket("EE", f_contents)); - - ui_ic_chat_message->setFocus(); -} - diff --git a/file_functions.cpp b/file_functions.cpp deleted file mode 100644 index f93ee15d..00000000 --- a/file_functions.cpp +++ /dev/null @@ -1,21 +0,0 @@ -#include "file_functions.h" - -bool file_exists(QString file_path) -{ - QFileInfo check_file(file_path); - - return check_file.exists() && check_file.isFile(); -} - -bool dir_exists(QString dir_path) -{ - QDir check_dir(dir_path); - - return check_dir.exists(); -} - -bool exists(QString p_path) { - QFile file(p_path); - - return file.exists(); -} diff --git a/file_functions.h b/file_functions.h deleted file mode 100644 index 6937ed8a..00000000 --- a/file_functions.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef FILE_FUNCTIONS_H -#define FILE_FUNCTIONS_H - -#include -#include -#include - -bool file_exists(QString file_path); -bool dir_exists(QString file_path); -bool exists(QString p_path); - -#endif // FILE_FUNCTIONS_H diff --git a/hardware_functions.cpp b/hardware_functions.cpp deleted file mode 100644 index 29823cdf..00000000 --- a/hardware_functions.cpp +++ /dev/null @@ -1,57 +0,0 @@ -#include "hardware_functions.h" - -#include - -#if (defined (_WIN32) || defined (_WIN64)) -#include - -DWORD dwVolSerial; -BOOL bIsRetrieved; - -QString get_hdid() -{ - bIsRetrieved = GetVolumeInformation(TEXT("C:\\"), NULL, NULL, &dwVolSerial, NULL, NULL, NULL, NULL); - - if (bIsRetrieved) - return QString::number(dwVolSerial, 16); - else - //a totally random string - //what could possibly go wrong - return "gxsps32sa9fnwic92mfbs0"; - -} - -#elif (defined (LINUX) || defined (__linux__)) - -#include -#include - -QString get_hdid() -{ - QFile fstab_file("/etc/fstab"); - if (!fstab_file.open(QIODevice::ReadOnly)) - return "gxcps32sa9fnwic92mfbs0"; - - QTextStream in(&fstab_file); - - while(!in.atEnd()) - { - QString line = in.readLine(); - - if (line.startsWith("UUID")) - { - QStringList line_elements = line.split("="); - - if (line_elements.size() > 1) - return line_elements.at(1).left(23).trimmed(); - } - } - - return "gxcpz32sa9fnwic92mfbs0"; -} - -#else - -#error This operating system is unsupported for hardware functions. - -#endif diff --git a/hardware_functions.h b/hardware_functions.h deleted file mode 100644 index 3fcb27cb..00000000 --- a/hardware_functions.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef HARDWARE_FUNCTIONS_H -#define HARDWARE_FUNCTIONS_H - -#include - -#include - -QString get_hdid(); - -#endif // HARDWARE_FUNCTIONS_H diff --git a/hex_functions.cpp b/hex_functions.cpp deleted file mode 100644 index 4a58d2b4..00000000 --- a/hex_functions.cpp +++ /dev/null @@ -1,18 +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; - } -} diff --git a/hex_functions.h b/hex_functions.h deleted file mode 100644 index 285f096a..00000000 --- a/hex_functions.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef HEX_OPERATIONS_H -#define HEX_OPERATIONS_H - -#include -#include -#include -#include -#include -#include -#include - -namespace omni -{ - std::string int_to_hex(unsigned int input); -} - -#endif //HEX_OPERATIONS_H diff --git a/include/aoapplication.h b/include/aoapplication.h new file mode 100644 index 00000000..f4207333 --- /dev/null +++ b/include/aoapplication.h @@ -0,0 +1,318 @@ +#ifndef AOAPPLICATION_H +#define AOAPPLICATION_H + +#include "aopacket.h" +#include "datatypes.h" +#include "discord_rich_presence.h" + +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include +#include + +#include +#include +#include + +class NetworkManager; +class Lobby; +class Courtroom; + +class AOApplication : public QApplication +{ + Q_OBJECT + +public: + AOApplication(int &argc, char **argv); + ~AOApplication(); + + NetworkManager *net_manager; + Lobby *w_lobby; + Courtroom *w_courtroom; + AttorneyOnline::Discord *discord; + + bool lobby_constructed = false; + bool courtroom_constructed = false; + + void construct_lobby(); + void destruct_lobby(); + + void construct_courtroom(); + void destruct_courtroom(); + + void ms_packet_received(AOPacket *p_packet); + void server_packet_received(AOPacket *p_packet); + + void send_ms_packet(AOPacket *p_packet); + void send_server_packet(AOPacket *p_packet, bool encoded = true); + + void call_settings_menu(); + void call_announce_menu(Courtroom *court); + + /////////////////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; + bool arup_enabled = false; + bool casing_alerts_enabled = false; + bool modcall_reason_enabled = false; + + ///////////////loading info/////////////////// + + //player number, it's hardly used but might be needed for some old servers + int s_pv = 0; + + QString server_software = ""; + + int char_list_size = 0; + int loaded_chars = 0; + int generated_chars = 0; + int evidence_list_size = 0; + int loaded_evidence = 0; + int music_list_size = 0; + int loaded_music = 0; + + bool courtroom_loaded = false; + + //////////////////versioning/////////////// + + constexpr int get_release() const { return RELEASE; } + constexpr int get_major_version() const { return MAJOR_VERSION; } + constexpr int get_minor_version() const { return MINOR_VERSION; } + QString get_version_string(); + + /////////////////////////////////////////// + + void set_favorite_list(); + QVector& get_favorite_list() {return favorite_list;} + void add_favorite_server(int p_server); + + void set_server_list(); + QVector& get_server_list() {return server_list;} + + //reads the theme from config.ini and sets it accordingly + void reload_theme(); + + //Returns the character the player has currently selected + QString get_current_char(); + + //implementation in path_functions.cpp + QString get_base_path(); + QString get_data_path(); + QString get_theme_path(QString p_file); + QString get_default_theme_path(QString p_file); + QString get_custom_theme_path(QString p_theme, QString p_file); + QString get_character_path(QString p_char, QString p_file); + QString get_sounds_path(QString p_file); + QString get_music_path(QString p_song); + QString get_background_path(QString p_file); + QString get_default_background_path(QString p_file); + QString get_evidence_path(QString p_file); + QString get_case_sensitive_path(QString p_file); + + ////// Functions for reading and writing files ////// + // Implementations file_functions.cpp + + // Instead of reinventing the wheel, we'll use a QSettings class. + QSettings *configini; + + //Reads the theme from config.ini and loads it into the current_theme variable + QString read_theme(); + + //Returns the value of ooc_name in config.ini + QString get_ooc_name(); + + //Returns the blip rate from config.ini + int read_blip_rate(); + + //Returns true if blank blips is enabled in config.ini and false otherwise + bool get_blank_blip(); + + //Returns the value of default_music in config.ini + int get_default_music(); + + //Returns the value of default_sfx in config.ini + int get_default_sfx(); + + //Returns the value of default_blip in config.ini + int get_default_blip(); + + // Returns the value of whether Discord should be enabled on startup + // from the config.ini. + bool is_discord_enabled(); + + // Returns the value of the maximum amount of lines the IC chatlog + // may contain, from config.ini. + int get_max_log_size(); + + // Returns whether the log should go upwards (new behaviour) + // or downwards (vanilla behaviour). + bool get_log_goes_downwards(); + + // Returns the username the user may have set in config.ini. + QString get_default_username(); + + // Returns the audio device used for the client. + QString get_audio_output_device(); + + // Returns whether the user would like to have custom shownames on by default. + bool get_showname_enabled_by_default(); + + //Returns the list of words in callwords.ini + QStringList get_call_words(); + + //Appends the argument string to serverlist.txt + void write_to_serverlist_txt(QString p_line); + + //Returns the contents of serverlist.txt + QVector read_serverlist_txt(); + + //Returns the value of p_identifier in the design.ini file in p_design_path + QString read_design_ini(QString p_identifier, QString p_design_path); + + //Returns the coordinates of widget with p_identifier from p_file + QPoint get_button_spacing(QString p_identifier, QString p_file); + + //Returns the dimensions of widget with specified identifier from p_file + pos_size_type get_element_dimensions(QString p_identifier, QString p_file); + + //Returns the value of font_size with p_identifier from p_file + int get_font_size(QString p_identifier, QString p_file); + + //Returns the color with p_identifier from p_file + QColor get_color(QString p_identifier, QString p_file); + + // Returns the colour from the misc folder. + QColor get_chat_color(QString p_identifier, QString p_chat); + + //Returns the sfx with p_identifier from sounds.ini in the current theme path + QString get_sfx(QString p_identifier); + + //Figure out if we can opus this or if we should fall back to wav + QString get_sfx_suffix(QString sound_to_check); + + // Can we use APNG for this? If not, fall back to a gif. + QString get_image_suffix(QString path_to_check); + + //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 the side of the p_char character from that characters ini file + QString get_char_side(QString p_char); + + //Returns the showname from the ini of p_char + QString get_showname(QString p_char); + + //Returns the value of chat from the specific p_char's ini file + QString get_chat(QString p_char); + + //Returns the value of shouts from the specified p_char's ini file + QString get_char_shouts(QString p_char); + + //Returns the preanim duration of p_char's p_emote + int get_preanim_duration(QString p_char, QString p_emote); + + //Same as above, but only returns if it has a % in front(refer to Preanims section in the manual) + int get_ao2_preanim_duration(QString p_char, QString p_emote); + + //Not in use + int get_text_delay(QString p_char, QString p_emote); + + // Returns the custom realisation used by the character. + QString get_custom_realization(QString p_char); + + //Returns the name of p_char + QString get_char_name(QString p_char); + + //Returns the total amount of emotes of p_char + int get_emote_number(QString p_char); + + //Returns the emote comment of p_char's p_emote + QString get_emote_comment(QString p_char, int p_emote); + + //Returns the base name of p_char's p_emote + QString get_emote(QString p_char, int p_emote); + + //Returns the preanimation name of p_char's p_emote + QString get_pre_emote(QString p_char, int p_emote); + + //Returns the sfx of p_char's p_emote + QString get_sfx_name(QString p_char, int p_emote); + + //Not in use + int get_sfx_delay(QString p_char, int p_emote); + + //Returns the modifier for p_char's p_emote + int get_emote_mod(QString p_char, int p_emote); + + //Returns the desk modifier for p_char's p_emote + int get_desk_mod(QString p_char, int p_emote); + + //Returns p_char's gender + QString get_gender(QString p_char); + + // ====== + // These are all casing-related settings. + // ====== + + // Returns if the user has casing alerts enabled. + bool get_casing_enabled(); + + // Returns if the user wants to get alerts for the defence role. + bool get_casing_defence_enabled(); + + // Same for prosecution. + bool get_casing_prosecution_enabled(); + + // Same for judge. + bool get_casing_judge_enabled(); + + // Same for juror. + bool get_casing_juror_enabled(); + + // Same for steno. + bool get_casing_steno_enabled(); + + // Same for CM. + bool get_casing_cm_enabled(); + + // Get the message for the CM for casing alerts. + QString get_casing_can_host_cases(); + +private: + const int RELEASE = 2; + const int MAJOR_VERSION = 6; + const int MINOR_VERSION = 0; + + QString current_theme = "default"; + + QVector server_list; + QVector favorite_list; + +private slots: + void ms_connect_finished(bool connected, bool will_retry); + +public slots: + void server_disconnected(); + void loading_cancelled(); +}; + +#endif // AOAPPLICATION_H diff --git a/include/aoblipplayer.h b/include/aoblipplayer.h new file mode 100644 index 00000000..aebba77d --- /dev/null +++ b/include/aoblipplayer.h @@ -0,0 +1,30 @@ +#ifndef AOBLIPPLAYER_H +#define AOBLIPPLAYER_H + +#include "bass.h" +#include "aoapplication.h" + +#include +#include +#include + +class AOBlipPlayer +{ +public: + AOBlipPlayer(QWidget *parent, AOApplication *p_ao_app); + + void set_blips(QString p_sfx); + void blip_tick(); + void set_volume(int p_volume); + + int m_cycle = 0; + +private: + QWidget *m_parent; + AOApplication *ao_app; + + int m_volume; + HSTREAM m_stream_list[5]; +}; + +#endif // AOBLIPPLAYER_H diff --git a/include/aobutton.h b/include/aobutton.h new file mode 100644 index 00000000..4b7209ae --- /dev/null +++ b/include/aobutton.h @@ -0,0 +1,22 @@ +#ifndef AOBUTTON_H +#define AOBUTTON_H + +#include "aoapplication.h" + +#include +#include + +class AOButton : public QPushButton +{ + Q_OBJECT + +public: + AOButton(QWidget *parent, AOApplication *p_ao_app); + ~AOButton(); + + AOApplication *ao_app; + + void set_image(QString p_image); +}; + +#endif // AOBUTTON_H diff --git a/include/aocaseannouncerdialog.h b/include/aocaseannouncerdialog.h new file mode 100644 index 00000000..a238c3f2 --- /dev/null +++ b/include/aocaseannouncerdialog.h @@ -0,0 +1,45 @@ +#ifndef AOCASEANNOUNCERDIALOG_H +#define AOCASEANNOUNCERDIALOG_H + +#include "aoapplication.h" +#include "courtroom.h" + +#include +#include +#include +#include +#include +#include +#include + +class AOCaseAnnouncerDialog : public QDialog +{ + Q_OBJECT + +public: + explicit AOCaseAnnouncerDialog(QWidget *parent = nullptr, AOApplication *p_ao_app = nullptr, Courtroom *p_court = nullptr); + +private: + AOApplication *ao_app; + Courtroom *court; + + QDialogButtonBox *ui_announcer_buttons; + + QVBoxLayout *ui_vbox_layout; + QFormLayout *ui_form_layout; + + QLabel *ui_case_title_label; + QLineEdit *ui_case_title_textbox; + + QCheckBox *ui_defense_needed; + QCheckBox *ui_prosecutor_needed; + QCheckBox *ui_judge_needed; + QCheckBox *ui_juror_needed; + QCheckBox *ui_steno_needed; + +public slots: + void ok_pressed(); + void cancel_pressed(); +}; + +#endif // AOCASEANNOUNCERDIALOG_H diff --git a/include/aocharbutton.h b/include/aocharbutton.h new file mode 100644 index 00000000..f372cdf8 --- /dev/null +++ b/include/aocharbutton.h @@ -0,0 +1,44 @@ +#ifndef AOCHARBUTTON_H +#define AOCHARBUTTON_H + +#include "aoapplication.h" +#include "aoimage.h" + +#include +#include +#include +#include + +class AOCharButton : public QPushButton +{ + Q_OBJECT + +public: + AOCharButton(QWidget *parent, AOApplication *p_ao_app, int x_pos, int y_pos, bool is_taken); + + AOApplication *ao_app; + + void refresh(); + void reset(); + void set_taken(bool is_taken); + void set_passworded(); + + void apply_taken_image(); + + void set_image(QString p_character); + +private: + bool taken; + + QWidget *m_parent; + + AOImage *ui_taken; + AOImage *ui_passworded; + AOImage *ui_selector; + +protected: + void enterEvent(QEvent *e); + void leaveEvent(QEvent *e); +}; + +#endif // AOCHARBUTTON_H diff --git a/include/aocharmovie.h b/include/aocharmovie.h new file mode 100644 index 00000000..7ef7da3f --- /dev/null +++ b/include/aocharmovie.h @@ -0,0 +1,57 @@ +#ifndef AOCHARMOVIE_H +#define AOCHARMOVIE_H + +#include +#include +#include +#include +#include + +class AOApplication; + +class AOCharMovie : public QLabel +{ + Q_OBJECT + +public: + AOCharMovie(QWidget *p_parent, AOApplication *p_ao_app); + + void play(QString p_char, QString p_emote, QString emote_prefix); + void play_pre(QString p_char, QString p_emote, int duration); + void play_talking(QString p_char, QString p_emote); + void play_idle(QString p_char, QString p_emote); + + void set_flipped(bool p_flipped) {m_flipped = p_flipped;} + + void stop(); + + void move(int ax, int ay); + + void combo_resize(int w, int h); + +private: + AOApplication *ao_app; + + QMovie *m_movie; + QVector movie_frames; + QTimer *preanim_timer; + + const int time_mod = 62; + + // These are the X and Y values before they are fixed based on the sprite's width. + int x = 0; + int y = 0; + + bool m_flipped = false; + + bool play_once = true; + +signals: + void done(); + +private slots: + void frame_change(int n_frame); + void timer_done(); +}; + +#endif // AOCHARMOVIE_H diff --git a/include/aoemotebutton.h b/include/aoemotebutton.h new file mode 100644 index 00000000..c99a73b0 --- /dev/null +++ b/include/aoemotebutton.h @@ -0,0 +1,36 @@ +#ifndef AOEMOTEBUTTON_H +#define AOEMOTEBUTTON_H + +#include "aoapplication.h" + +#include +#include + +class AOEmoteButton : public QPushButton +{ + Q_OBJECT + +public: + AOEmoteButton(QWidget *p_parent, AOApplication *p_ao_app, int p_x, int p_y); + + //void set_on(QString p_char, int p_emote); + //void set_off(QString p_char, int p_emote); + void set_image(QString p_char, int p_emote, QString suffix); + + void set_id(int p_id) {m_id = p_id;} + int get_id() {return m_id;} + +private: + QWidget *parent; + AOApplication *ao_app; + + int m_id = 0; + +signals: + void emote_clicked(int p_id); + +private slots: + void on_clicked(); +}; + +#endif // AOEMOTEBUTTON_H diff --git a/include/aoevidencebutton.h b/include/aoevidencebutton.h new file mode 100644 index 00000000..27fb84b3 --- /dev/null +++ b/include/aoevidencebutton.h @@ -0,0 +1,50 @@ +#ifndef AOEVIDENCEBUTTON_H +#define AOEVIDENCEBUTTON_H + +#include "aoapplication.h" +#include "aoimage.h" + +#include +#include +#include + +class AOEvidenceButton : public QPushButton +{ + Q_OBJECT + +public: + AOEvidenceButton(QWidget *p_parent, AOApplication *p_ao_app, int p_x, int p_y); + + void reset(); + void set_image(QString p_image); + void set_theme_image(QString p_image); + void set_id(int p_id) {m_id = p_id;} + + void set_selected(bool p_selected); + +private: + AOApplication *ao_app; + QWidget *m_parent; + + AOImage *ui_selected; + AOImage *ui_selector; + + int m_id = 0; + +protected: + void enterEvent(QEvent *e); + void leaveEvent(QEvent *e); + void mouseDoubleClickEvent(QMouseEvent *e); + void dragLeaveEvent(QMouseEvent *e); + void dragEnterEvent(QMouseEvent *e); + +signals: + void evidence_clicked(int p_id); + void evidence_double_clicked(int p_id); + void on_hover(int p_id, bool p_state); + +private slots: + void on_clicked(); +}; + +#endif // AOEVIDENCEBUTTON_H diff --git a/include/aoevidencedisplay.h b/include/aoevidencedisplay.h new file mode 100644 index 00000000..13ca00d5 --- /dev/null +++ b/include/aoevidencedisplay.h @@ -0,0 +1,32 @@ +#ifndef AOEVIDENCEDISPLAY_H +#define AOEVIDENCEDISPLAY_H + +#include "aoapplication.h" +#include "aosfxplayer.h" + +#include +#include +#include + +class AOEvidenceDisplay : public QLabel +{ + Q_OBJECT + +public: + AOEvidenceDisplay(QWidget *p_parent, AOApplication *p_ao_app); + + void show_evidence(QString p_evidence_image, bool is_left_side, int p_volume); + QLabel* get_evidence_icon(); + void reset(); + +private: + AOApplication *ao_app; + QMovie *evidence_movie; + QLabel *evidence_icon; + AOSfxPlayer *sfx_player; + +private slots: + void frame_change(int p_frame); +}; + +#endif // AOEVIDENCEDISPLAY_H diff --git a/include/aoimage.h b/include/aoimage.h new file mode 100644 index 00000000..4713be0a --- /dev/null +++ b/include/aoimage.h @@ -0,0 +1,25 @@ +//This class represents a static theme-dependent image + +#ifndef AOIMAGE_H +#define AOIMAGE_H + +#include "aoapplication.h" + +#include +#include + +class AOImage : public QLabel +{ +public: + AOImage(QWidget *parent, AOApplication *p_ao_app); + ~AOImage(); + + QWidget *m_parent; + AOApplication *ao_app; + + void set_image(QString p_image); + void set_image_from_path(QString p_path); + void set_size_and_pos(QString identifier); +}; + +#endif // AOIMAGE_H diff --git a/include/aolineedit.h b/include/aolineedit.h new file mode 100644 index 00000000..ce17680d --- /dev/null +++ b/include/aolineedit.h @@ -0,0 +1,26 @@ +#ifndef AOLINEEDIT_H +#define AOLINEEDIT_H + +#include +#include + +class AOLineEdit : public QLineEdit +{ + Q_OBJECT + +public: + AOLineEdit(QWidget *parent); + +protected: + void mouseDoubleClickEvent(QMouseEvent *e); + +signals: + void double_clicked(); + +private slots: + void on_enter_pressed(); + + +}; + +#endif // AOLINEEDIT_H diff --git a/include/aomovie.h b/include/aomovie.h new file mode 100644 index 00000000..1f278bf8 --- /dev/null +++ b/include/aomovie.h @@ -0,0 +1,34 @@ +#ifndef AOMOVIE_H +#define AOMOVIE_H + +#include +#include + +class Courtroom; +class AOApplication; + +class AOMovie : public QLabel +{ + Q_OBJECT + +public: + AOMovie(QWidget *p_parent, AOApplication *p_ao_app); + + void set_play_once(bool p_play_once); + void play(QString p_gif, QString p_char = "", QString p_custom_theme = ""); + void combo_resize(int w, int h); + void stop(); + +private: + QMovie *m_movie; + AOApplication *ao_app; + bool play_once = true; + +signals: + void done(); + +private slots: + void frame_change(int n_frame); +}; + +#endif // AOMOVIE_H diff --git a/include/aomusicplayer.h b/include/aomusicplayer.h new file mode 100644 index 00000000..560a7f90 --- /dev/null +++ b/include/aomusicplayer.h @@ -0,0 +1,28 @@ +#ifndef AOMUSICPLAYER_H +#define AOMUSICPLAYER_H + +#include "bass.h" +#include "aoapplication.h" + +#include +#include +#include + +class AOMusicPlayer +{ +public: + AOMusicPlayer(QWidget *parent, AOApplication *p_ao_app); + ~AOMusicPlayer(); + + void play(QString p_song); + void set_volume(int p_value); + +private: + QWidget *m_parent; + AOApplication *ao_app; + + int m_volume = 0; + HSTREAM m_stream; +}; + +#endif // AOMUSICPLAYER_H diff --git a/include/aooptionsdialog.h b/include/aooptionsdialog.h new file mode 100644 index 00000000..a65e3f59 --- /dev/null +++ b/include/aooptionsdialog.h @@ -0,0 +1,115 @@ +#ifndef AOOPTIONSDIALOG_H +#define AOOPTIONSDIALOG_H + +#include "aoapplication.h" +#include "bass.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +class AOOptionsDialog: public QDialog +{ + Q_OBJECT +public: + explicit AOOptionsDialog(QWidget *parent = nullptr, AOApplication *p_ao_app = nullptr); + +private: + AOApplication *ao_app; + + QVBoxLayout *ui_vertical_layout; + QTabWidget *ui_settings_tabs; + + QWidget *ui_gameplay_tab; + QWidget *ui_form_layout_widget; + QFormLayout *ui_gameplay_form; + QLabel *ui_theme_label; + QComboBox *ui_theme_combobox; + QFrame *ui_theme_log_divider; + QLabel *ui_downwards_lbl; + QCheckBox *ui_downwards_cb; + QLabel *ui_length_lbl; + QSpinBox *ui_length_spinbox; + QFrame *ui_log_names_divider; + QLineEdit *ui_username_textbox; + QLabel *ui_username_lbl; + QLabel *ui_showname_lbl; + QCheckBox *ui_showname_cb; + QFrame *ui_net_divider; + QLabel *ui_ms_lbl; + QLineEdit *ui_ms_textbox; + QLabel *ui_discord_lbl; + QCheckBox *ui_discord_cb; + + QWidget *ui_callwords_tab; + QWidget *ui_callwords_widget; + QVBoxLayout *ui_callwords_layout; + QPlainTextEdit *ui_callwords_textbox; + QLabel *ui_callwords_explain_lbl; + QCheckBox *ui_callwords_char_textbox; + + QWidget *ui_audio_tab; + QWidget *ui_audio_widget; + QFormLayout *ui_audio_layout; + QLabel *ui_audio_device_lbl; + QComboBox *ui_audio_device_combobox; + QFrame *ui_audio_volume_divider; + QSpinBox *ui_music_volume_spinbox; + QLabel *ui_music_volume_lbl; + QSpinBox *ui_sfx_volume_spinbox; + QSpinBox *ui_blips_volume_spinbox; + QLabel *ui_sfx_volume_lbl; + QLabel *ui_blips_volume_lbl; + QFrame *ui_volume_blip_divider; + QSpinBox *ui_bliprate_spinbox; + QLabel *ui_bliprate_lbl; + QCheckBox *ui_blank_blips_cb; + QLabel *ui_blank_blips_lbl; + QDialogButtonBox *ui_settings_buttons; + + QWidget *ui_casing_tab; + QWidget *ui_casing_widget; + QFormLayout *ui_casing_layout; + QLabel *ui_casing_supported_lbl; + QLabel *ui_casing_enabled_lbl; + QCheckBox *ui_casing_enabled_cb; + QLabel *ui_casing_def_lbl; + QCheckBox *ui_casing_def_cb; + QLabel *ui_casing_pro_lbl; + QCheckBox *ui_casing_pro_cb; + QLabel *ui_casing_jud_lbl; + QCheckBox *ui_casing_jud_cb; + QLabel *ui_casing_jur_lbl; + QCheckBox *ui_casing_jur_cb; + QLabel *ui_casing_steno_lbl; + QCheckBox *ui_casing_steno_cb; + QLabel *ui_casing_cm_lbl; + QCheckBox *ui_casing_cm_cb; + QLabel *ui_casing_cm_cases_lbl; + QLineEdit *ui_casing_cm_cases_textbox; + + bool needs_default_audiodev(); + +signals: + +public slots: + void save_pressed(); + void discard_pressed(); +}; + +#endif // AOOPTIONSDIALOG_H diff --git a/include/aopacket.h b/include/aopacket.h new file mode 100644 index 00000000..21f6e0f4 --- /dev/null +++ b/include/aopacket.h @@ -0,0 +1,32 @@ +#ifndef AOPACKET_H +#define AOPACKET_H + +#include +#include +#include + +class AOPacket +{ +public: + AOPacket(QString p_packet_string); + AOPacket(QString header, QStringList &p_contents); + ~AOPacket(); + + 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; +}; + +#endif // AOPACKET_H diff --git a/include/aoscene.h b/include/aoscene.h new file mode 100644 index 00000000..b58c0fd0 --- /dev/null +++ b/include/aoscene.h @@ -0,0 +1,27 @@ +#ifndef AOSCENE_H +#define AOSCENE_H + +#include +#include +#include + +class Courtroom; +class AOApplication; + +class AOScene : public QLabel +{ + Q_OBJECT +public: + explicit AOScene(QWidget *parent, AOApplication *p_ao_app); + + void set_image(QString p_image); + void set_legacy_desk(QString p_image); + +private: + QWidget *m_parent; + QMovie *m_movie; + AOApplication *ao_app; + +}; + +#endif // AOSCENE_H diff --git a/include/aosfxplayer.h b/include/aosfxplayer.h new file mode 100644 index 00000000..30cbe9d3 --- /dev/null +++ b/include/aosfxplayer.h @@ -0,0 +1,28 @@ +#ifndef AOSFXPLAYER_H +#define AOSFXPLAYER_H + +#include "bass.h" +#include "aoapplication.h" + +#include +#include +#include + +class AOSfxPlayer +{ +public: + AOSfxPlayer(QWidget *parent, AOApplication *p_ao_app); + + void play(QString p_sfx, QString p_char = "", QString shout = ""); + void stop(); + void set_volume(int p_volume); + +private: + QWidget *m_parent; + AOApplication *ao_app; + + int m_volume = 0; + HSTREAM m_stream; +}; + +#endif // AOSFXPLAYER_H diff --git a/include/aotextarea.h b/include/aotextarea.h new file mode 100644 index 00000000..d44596b2 --- /dev/null +++ b/include/aotextarea.h @@ -0,0 +1,24 @@ +#ifndef AOTEXTAREA_H +#define AOTEXTAREA_H + +#include +#include +#include +#include +#include + +class AOTextArea : public QTextBrowser +{ +public: + AOTextArea(QWidget *p_parent = nullptr); + + void append_chatmessage(QString p_name, QString p_message, QString p_colour); + void append_error(QString p_message); + +private: + const QRegExp omnis_dank_url_regex = QRegExp("\\b(https?://\\S+\\.\\S+)\\b"); + + void auto_scroll(QTextCursor old_cursor, int scrollbar_value, bool is_scrolled_down); +}; + +#endif // AOTEXTAREA_H diff --git a/include/aotextedit.h b/include/aotextedit.h new file mode 100644 index 00000000..85909c6e --- /dev/null +++ b/include/aotextedit.h @@ -0,0 +1,23 @@ +#ifndef AOTEXTEDIT_H +#define AOTEXTEDIT_H + +#include + +class AOTextEdit : public QPlainTextEdit +{ + Q_OBJECT +public: + AOTextEdit(QWidget *parent); + +protected: + void mouseDoubleClickEvent(QMouseEvent *e); + +signals: + void double_clicked(); + +private slots: + void on_enter_pressed(); + +}; + +#endif // AOTEXTEDIT_H diff --git a/include/chatlogpiece.h b/include/chatlogpiece.h new file mode 100644 index 00000000..34c5926b --- /dev/null +++ b/include/chatlogpiece.h @@ -0,0 +1,31 @@ +#ifndef CHATLOGPIECE_H +#define CHATLOGPIECE_H + +#include +#include + +class chatlogpiece +{ +public: + chatlogpiece(); + chatlogpiece(QString p_name, QString p_showname, QString p_message, bool p_song); + chatlogpiece(QString p_name, QString p_showname, QString p_message, bool p_song, QDateTime p_datetime); + + QString get_name(); + QString get_showname(); + QString get_message(); + bool get_is_song(); + QDateTime get_datetime(); + QString get_datetime_as_string(); + + QString get_full(); + +private: + QString name; + QString showname; + QString message; + QDateTime datetime; + bool is_song; +}; + +#endif // CHATLOGPIECE_H diff --git a/include/courtroom.h b/include/courtroom.h new file mode 100644 index 00000000..ec9f9ef0 --- /dev/null +++ b/include/courtroom.h @@ -0,0 +1,671 @@ +#ifndef COURTROOM_H +#define COURTROOM_H + +#include "aoimage.h" +#include "aobutton.h" +#include "aocharbutton.h" +#include "aoemotebutton.h" +#include "aopacket.h" +#include "aoscene.h" +#include "aomovie.h" +#include "aocharmovie.h" +#include "aomusicplayer.h" +#include "aosfxplayer.h" +#include "aoblipplayer.h" +#include "aoevidencebutton.h" +#include "aotextarea.h" +#include "aolineedit.h" +#include "aotextedit.h" +#include "aoevidencedisplay.h" +#include "datatypes.h" +#include "aoapplication.h" +#include "lobby.h" +#include "hardware_functions.h" +#include "file_functions.h" +#include "datatypes.h" +#include "debug_functions.h" +#include "chatlogpiece.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +class AOApplication; + +class Courtroom : public QMainWindow +{ + Q_OBJECT +public: + explicit Courtroom(AOApplication *p_ao_app); + + void append_char(char_type p_char){char_list.append(p_char);} + void append_evidence(evi_type p_evi){evidence_list.append(p_evi);} + void append_music(QString f_music){music_list.append(f_music);} + void append_area(QString f_area){area_list.append(f_area);} + + void fix_last_area() + { + if (area_list.size() > 0) + { + QString malplaced = area_list.last(); + area_list.removeLast(); + append_music(malplaced); + } + } + + void arup_append(int players, QString status, QString cm, QString locked) + { + arup_players.append(players); + arup_statuses.append(status); + arup_cms.append(cm); + arup_locks.append(locked); + } + + void arup_modify(int type, int place, QString value) + { + if (type == 0) + { + if (arup_players.size() > place) + arup_players[place] = value.toInt(); + } + else if (type == 1) + { + if (arup_statuses.size() > place) + arup_statuses[place] = value; + } + else if (type == 2) + { + if (arup_cms.size() > place) + arup_cms[place] = value; + } + else if (type == 3) + { + if (arup_locks.size() > place) + arup_locks[place] = value; + } + list_areas(); + } + + void character_loading_finished(); + + //sets position of widgets based on theme ini files + void set_widgets(); + //sets font size based on theme ini files + void set_font(QWidget *widget, QString p_identifier); + //helper function that calls above function on the relevant widgets + void set_fonts(); + + void set_window_title(QString p_title); + + //reads theme inis and sets size and pos based on the identifier + void set_size_and_pos(QWidget *p_widget, QString p_identifier); + + //sets status as taken on character with cid n_char and places proper shading on charselect + void set_taken(int n_char, bool p_taken); + + //sets the current background to argument. also does some checks to see if it's a legacy bg + void set_background(QString p_background); + + //sets the evidence list member variable to argument + void set_evidence_list(QVector &p_evi_list); + + //called when a DONE#% from the server was received + void done_received(); + + //sets the local mute list based on characters available on the server + void set_mute_list(); + + // Sets the local pair list based on the characters available on the server. + void set_pair_list(); + + //sets desk and bg based on pos in chatmessage + void set_scene(); + + //sets text color based on text color in chatmessage + void set_text_color(); + + // And gets the colour, too! + QColor get_text_color(QString color); + + //takes in serverD-formatted IP list as prints a converted version to server OOC + //admittedly poorly named + void set_ip_list(QString p_list); + + //disables chat if current cid matches second argument + //enables if p_muted is false + void set_mute(bool p_muted, int p_cid); + + //send a message that the player is banned and quits the server + void set_ban(int p_cid); + + //cid = character id, returns the cid of the currently selected character + int get_cid() {return m_cid;} + QString get_current_char() {return current_char;} + QString get_current_background() {return current_background;} + + //properly sets up some varibles: resets user state + void enter_courtroom(int p_cid); + + //helper function that populates ui_music_list with the contents of music_list + void list_music(); + void list_areas(); + + //these are for OOC chat + void append_ms_chatmessage(QString f_name, QString f_message); + void append_server_chatmessage(QString p_name, QString p_message, QString p_colour); + + //these functions handle chatmessages sequentially. + //The process itself is very convoluted and merits separate documentation + //But the general idea is objection animation->pre animation->talking->idle + void handle_chatmessage(QStringList *p_contents); + void handle_chatmessage_2(); + void handle_chatmessage_3(); + + //This function filters out the common CC inline text trickery, for appending to + //the IC chatlog. + QString filter_ic_text(QString p_text); + + //adds text to the IC chatlog. p_name first as bold then p_text then a newlin + //this function keeps the chatlog scrolled to the top unless there's text selected + // or the user isn't already scrolled to the top + void append_ic_text(QString p_text, QString p_name = "", bool is_songchange = false); + + //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 the second is the char id of who played it + void handle_song(QStringList *p_contents); + + void play_preanim(bool noninterrupting); + + //plays the witness testimony or cross examination animation based on argument + void handle_wtce(QString p_wtce, int variant); + + //sets the hp bar of defense(p_bar 1) or pro(p_bar 2) + //state is an number between 0 and 10 inclusive + void set_hp_bar(int p_bar, int p_state); + + //Toggles the judge buttons, whether they should appear or not. + void toggle_judge_buttons(bool is_on); + + void announce_case(QString title, bool def, bool pro, bool jud, bool jur, bool steno); + + void check_connection_received(); + + ~Courtroom(); + +private: + AOApplication *ao_app; + + int m_courtroom_width = 714; + int m_courtroom_height = 668; + + int m_viewport_x = 0; + int m_viewport_y = 0; + + int m_viewport_width = 256; + int m_viewport_height = 192; + + bool first_message_sent = false; + int maximumMessages = 0; + + // This is for inline message-colouring. + + enum INLINE_COLOURS { + INLINE_BLUE, + INLINE_GREEN, + INLINE_ORANGE, + INLINE_GREY + }; + + // A stack of inline colours. + std::stack inline_colour_stack; + + bool next_character_is_not_special = false; // If true, write the + // next character as it is. + + bool message_is_centered = false; + + int current_display_speed = 3; + int message_display_speed[7] = {30, 40, 50, 60, 75, 100, 120}; + + // This is for checking if the character should start talking again + // when an inline blue text ends. + bool entire_message_is_blue = false; + + // And this is the inline 'talking checker'. Counts how 'deep' we are + // in inline blues. + int inline_blue_depth = 0; + + // 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. + int offset_with_pair = 0; + + QVector char_list; + QVector evidence_list; + QVector music_list; + QVector area_list; + + QVector arup_players; + QVector arup_statuses; + QVector arup_cms; + QVector arup_locks; + + QSignalMapper *char_button_mapper; + + QVector ic_chatlog_history; + + // These map music row items and area row items to their actual IDs. + QVector music_row_to_number; + QVector area_row_to_number; + + //triggers ping_server() every 60 seconds + QTimer *keepalive_timer; + + //determines how fast messages tick onto screen + QTimer *chat_tick_timer; + //int chat_tick_interval = 60; + //which tick position(character in chat message) we are at + int tick_pos = 0; + //used to determine how often blips sound + int blip_pos = 0; + int blip_rate = 1; + int rainbow_counter = 0; + bool rainbow_appended = false; + bool blank_blip = false; + + // Used for getting the current maximum blocks allowed in the IC chatlog. + int log_maximum_blocks = 0; + + // True, if the log should go downwards. + bool log_goes_downwards = false; + + //delay before chat messages starts ticking + QTimer *text_delay_timer; + + //delay before sfx plays + QTimer *sfx_delay_timer; + + //keeps track of how long realization is visible(it's just a white square and should be visible less than a second) + QTimer *realization_timer; + + //times how long the blinking testimony should be shown(green one in the corner) + QTimer *testimony_show_timer; + //times how long the blinking testimony should be hidden + QTimer *testimony_hide_timer; + + //every time point in char.inis times this equals the final time + const int time_mod = 40; + + static const int chatmessage_size = 23; + QString m_chatmessage[chatmessage_size]; + bool chatmessage_is_empty = false; + + QString previous_ic_message = ""; + + bool testimony_in_progress = false; + + //in milliseconds + const int testimony_show_time = 1500; + + //in milliseconds + const int testimony_hide_time = 500; + + //char id, muted or not + QMap mute_map; + + //QVector muted_cids; + + bool is_muted = false; + + //state of animation, 0 = objecting, 1 = preanim, 2 = talking, 3 = idle, 4 = noniterrupting preanim + int anim_state = 3; + + //state of text ticking, 0 = not yet ticking, 1 = ticking in progress, 2 = ticking done + int text_state = 2; + + //character id, which index of the char_list the player is + int m_cid = -1; + //cid and this may differ in cases of ini-editing + QString current_char = ""; + + int objection_state = 0; + int realization_state = 0; + int text_color = 0; + bool is_presenting_evidence = false; + + int defense_bar_state = 0; + int prosecution_bar_state = 0; + + int current_char_page = 0; + int char_columns = 10; + int char_rows = 9; + int max_chars_on_page = 90; + + const int button_width = 60; + const int button_height = 60; + + int current_emote_page = 0; + int current_emote = 0; + int emote_columns = 5; + int emote_rows = 2; + int max_emotes_on_page = 10; + + QVector local_evidence_list; + + int current_evidence_page = 0; + int current_evidence = 0; + int evidence_columns = 6; + int evidence_rows = 3; + int max_evidence_on_page = 18; + + //is set to true if the bg folder contains defensedesk.png, prosecutiondesk.png and stand.png + bool is_ao2_bg = false; + + //whether the ooc chat is server or master chat, true is server + bool server_ooc = true; + + QString current_background = "default"; + + AOMusicPlayer *music_player; + AOSfxPlayer *sfx_player; + AOSfxPlayer *objection_player; + AOBlipPlayer *blip_player; + + AOSfxPlayer *modcall_player; + + AOImage *ui_background; + + QWidget *ui_viewport; + AOScene *ui_vp_background; + AOMovie *ui_vp_speedlines; + AOCharMovie *ui_vp_player_char; + AOCharMovie *ui_vp_sideplayer_char; + AOScene *ui_vp_desk; + AOScene *ui_vp_legacy_desk; + AOEvidenceDisplay *ui_vp_evidence_display; + AOImage *ui_vp_chatbox; + QLabel *ui_vp_showname; + QTextEdit *ui_vp_message; + AOImage *ui_vp_testimony; + AOImage *ui_vp_realization; + AOMovie *ui_vp_wtce; + AOMovie *ui_vp_objection; + + QTextEdit *ui_ic_chatlog; + + AOTextArea *ui_ms_chatlog; + AOTextArea *ui_server_chatlog; + + QListWidget *ui_mute_list; + QListWidget *ui_area_list; + QListWidget *ui_music_list; + + AOButton *ui_pair_button; + QListWidget *ui_pair_list; + QSpinBox *ui_pair_offset_spinbox; + + QLineEdit *ui_ic_chat_message; + QLineEdit *ui_ic_chat_name; + + QLineEdit *ui_ooc_chat_message; + QLineEdit *ui_ooc_chat_name; + + //QLineEdit *ui_area_password; + QLineEdit *ui_music_search; + + QWidget *ui_emotes; + QVector ui_emote_list; + AOButton *ui_emote_left; + AOButton *ui_emote_right; + + QComboBox *ui_emote_dropdown; + QComboBox *ui_pos_dropdown; + + AOImage *ui_defense_bar; + AOImage *ui_prosecution_bar; + + QLabel *ui_music_label; + QLabel *ui_sfx_label; + QLabel *ui_blip_label; + + AOButton *ui_hold_it; + AOButton *ui_objection; + AOButton *ui_take_that; + + AOButton *ui_ooc_toggle; + + AOButton *ui_witness_testimony; + AOButton *ui_cross_examination; + AOButton *ui_guilty; + AOButton *ui_not_guilty; + + AOButton *ui_change_character; + AOButton *ui_reload_theme; + AOButton *ui_call_mod; + AOButton *ui_settings; + AOButton *ui_announce_casing; + AOButton *ui_switch_area_music; + + QCheckBox *ui_pre; + QCheckBox *ui_flip; + QCheckBox *ui_guard; + QCheckBox *ui_casing; + + QCheckBox *ui_pre_non_interrupt; + QCheckBox *ui_showname_enable; + + AOButton *ui_custom_objection; + AOButton *ui_realization; + AOButton *ui_mute; + + AOButton *ui_defense_plus; + AOButton *ui_defense_minus; + + AOButton *ui_prosecution_plus; + AOButton *ui_prosecution_minus; + + QComboBox *ui_text_color; + + QSlider *ui_music_slider; + QSlider *ui_sfx_slider; + QSlider *ui_blip_slider; + + AOImage *ui_muted; + + QSpinBox *ui_log_limit_spinbox; + QLabel *ui_log_limit_label; + + AOButton *ui_evidence_button; + AOImage *ui_evidence; + AOLineEdit *ui_evidence_name; + QWidget *ui_evidence_buttons; + QVector ui_evidence_list; + AOButton *ui_evidence_left; + AOButton *ui_evidence_right; + AOButton *ui_evidence_present; + AOImage *ui_evidence_overlay; + AOButton *ui_evidence_delete; + AOLineEdit *ui_evidence_image_name; + AOButton *ui_evidence_image_button; + AOButton *ui_evidence_x; + AOTextEdit *ui_evidence_description; + + AOImage *ui_char_select_background; + + //abstract widget to hold char buttons + QWidget *ui_char_buttons; + + QVector ui_char_button_list; + QVector ui_char_button_list_filtered; + AOImage *ui_selector; + + AOButton *ui_back_to_lobby; + + QLineEdit *ui_char_password; + + AOButton *ui_char_select_left; + AOButton *ui_char_select_right; + + AOButton *ui_spectator; + + QLineEdit *ui_char_search; + QCheckBox *ui_char_passworded; + QCheckBox *ui_char_taken; + + void construct_char_select(); + void set_char_select(); + void set_char_select_page(); + void put_button_in_place(int starting, int chars_on_this_page); + void filter_character_list(); + + void construct_emotes(); + void set_emote_page(); + void set_emote_dropdown(); + + void construct_evidence(); + void set_evidence_page(); + +public slots: + void objection_done(); + void preanim_done(); + + void realization_done(); + + void show_testimony(); + void hide_testimony(); + + void mod_called(QString p_ip); + + void case_called(QString msg, bool def, bool pro, bool jud, bool jur, bool steno); + +private slots: + void start_chat_ticking(); + void play_sfx(); + + void chat_tick(); + + void on_mute_list_clicked(QModelIndex p_index); + void on_pair_list_clicked(QModelIndex p_index); + + void on_chat_return_pressed(); + + void on_ooc_return_pressed(); + + void on_music_search_edited(QString p_text); + void on_music_list_double_clicked(QModelIndex p_model); + void on_area_list_double_clicked(QModelIndex p_model); + + void select_emote(int p_id); + + void on_emote_clicked(int p_id); + + void on_emote_left_clicked(); + void on_emote_right_clicked(); + + void on_emote_dropdown_changed(int p_index); + void on_pos_dropdown_changed(int p_index); + + void on_evidence_name_edited(); + void on_evidence_image_name_edited(); + void on_evidence_image_button_clicked(); + void on_evidence_clicked(int p_id); + void on_evidence_double_clicked(int p_id); + + void on_evidence_hover(int p_id, bool p_state); + + void on_evidence_left_clicked(); + void on_evidence_right_clicked(); + void on_evidence_present_clicked(); + + void on_hold_it_clicked(); + void on_objection_clicked(); + void on_take_that_clicked(); + void on_custom_objection_clicked(); + + void on_realization_clicked(); + + void on_mute_clicked(); + void on_pair_clicked(); + + void on_defense_minus_clicked(); + void on_defense_plus_clicked(); + void on_prosecution_minus_clicked(); + void on_prosecution_plus_clicked(); + + void on_text_color_changed(int p_color); + + void on_music_slider_moved(int p_value); + void on_sfx_slider_moved(int p_value); + void on_blip_slider_moved(int p_value); + + void on_log_limit_changed(int value); + void on_pair_offset_changed(int value); + + void on_ooc_toggle_clicked(); + + void on_witness_testimony_clicked(); + void on_cross_examination_clicked(); + void on_not_guilty_clicked(); + void on_guilty_clicked(); + + void on_change_character_clicked(); + void on_reload_theme_clicked(); + void on_call_mod_clicked(); + void on_settings_clicked(); + void on_announce_casing_clicked(); + + void on_pre_clicked(); + void on_flip_clicked(); + void on_guard_clicked(); + + void on_showname_enable_clicked(); + + void on_evidence_button_clicked(); + + void on_evidence_delete_clicked(); + void on_evidence_x_clicked(); + + void on_back_to_lobby_clicked(); + + void on_char_select_left_clicked(); + void on_char_select_right_clicked(); + void on_char_search_changed(const QString& newtext); + void on_char_taken_clicked(int newstate); + void on_char_passworded_clicked(int newstate); + + void on_spectator_clicked(); + + void char_clicked(int n_char); + + void on_switch_area_music_clicked(); + + void on_casing_clicked(); + + void ping_server(); + + void load_bass_opus_plugin(); +}; + +#endif // COURTROOM_H diff --git a/include/datatypes.h b/include/datatypes.h new file mode 100644 index 00000000..aaa5de52 --- /dev/null +++ b/include/datatypes.h @@ -0,0 +1,119 @@ +#ifndef DATATYPES_H +#define DATATYPES_H + +#include + +struct server_type +{ + QString name; + QString desc; + QString ip; + int port; +}; + +struct emote_type +{ + QString comment; + QString preanim; + QString anim; + int mod; + QString sfx_name; + int sfx_delay; + int sfx_duration; +}; + +struct char_type +{ + QString name; + QString description; + QString evidence_string; + bool taken; +}; + +struct evi_type +{ + QString name; + QString description; + QString image; +}; + +struct chatmessage_type +{ + QString message; + QString character; + QString side; + QString sfx_name; + QString pre_emote; + QString emote; + int emote_modifier; + int objection_modifier; + int realization; + int text_color; + int evidence; + int cid; + int sfx_delay; + int flip; +}; + +struct area_type +{ + QString name; + QString background; + bool passworded; +}; + +struct pos_type +{ + int x; + int y; +}; + +struct pos_size_type +{ + int x = 0; + int y = 0; + int width = 0; + int height = 0; +}; + +enum CHAT_MESSAGE +{ + DESK_MOD = 0, + PRE_EMOTE, + CHAR_NAME, + EMOTE, + MESSAGE, + SIDE, + SFX_NAME, + EMOTE_MOD, + CHAR_ID, + SFX_DELAY, + OBJECTION_MOD, + EVIDENCE_ID, + FLIP, + REALIZATION, + TEXT_COLOR, + SHOWNAME, + OTHER_CHARID, + OTHER_NAME, + OTHER_EMOTE, + SELF_OFFSET, + OTHER_OFFSET, + OTHER_FLIP, + NONINTERRUPTING_PRE +}; + +enum COLOR +{ + WHITE = 0, + GREEN, + RED, + ORANGE, + BLUE, + YELLOW, + RAINBOW, + PINK, + CYAN +}; + +#endif // DATATYPES_H diff --git a/include/debug_functions.h b/include/debug_functions.h new file mode 100644 index 00000000..160274cc --- /dev/null +++ b/include/debug_functions.h @@ -0,0 +1,10 @@ +#ifndef DEBUG_FUNCTIONS_H +#define DEBUG_FUNCTIONS_H + +#include +#include + +void call_error(QString message); +void call_notice(QString message); + +#endif // DEBUG_FUNCTIONS_H diff --git a/include/discord-rpc.h b/include/discord-rpc.h new file mode 100644 index 00000000..feb874b2 --- /dev/null +++ b/include/discord-rpc.h @@ -0,0 +1,85 @@ +#pragma once +#include + +// clang-format off + +#if defined(DISCORD_DYNAMIC_LIB) +# if defined(_WIN32) +# if defined(DISCORD_BUILDING_SDK) +# define DISCORD_EXPORT __declspec(dllexport) +# else +# define DISCORD_EXPORT __declspec(dllimport) +# endif +# else +# define DISCORD_EXPORT __attribute__((visibility("default"))) +# endif +#else +# define DISCORD_EXPORT +#endif + +// clang-format on + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct DiscordRichPresence { + const char* state; /* max 128 bytes */ + const char* details; /* max 128 bytes */ + int64_t startTimestamp; + int64_t endTimestamp; + const char* largeImageKey; /* max 32 bytes */ + const char* largeImageText; /* max 128 bytes */ + const char* smallImageKey; /* max 32 bytes */ + const char* smallImageText; /* max 128 bytes */ + const char* partyId; /* max 128 bytes */ + int partySize; + int partyMax; + const char* matchSecret; /* max 128 bytes */ + const char* joinSecret; /* max 128 bytes */ + const char* spectateSecret; /* max 128 bytes */ + int8_t instance; +} DiscordRichPresence; + +typedef struct DiscordJoinRequest { + const char* userId; + const char* username; + const char* discriminator; + const char* avatar; +} DiscordJoinRequest; + +typedef struct DiscordEventHandlers { + void (*ready)(void); + void (*disconnected)(int errorCode, const char* message); + void (*errored)(int errorCode, const char* message); + void (*joinGame)(const char* joinSecret); + void (*spectateGame)(const char* spectateSecret); + void (*joinRequest)(const DiscordJoinRequest* request); +} DiscordEventHandlers; + +#define DISCORD_REPLY_NO 0 +#define DISCORD_REPLY_YES 1 +#define DISCORD_REPLY_IGNORE 2 + +DISCORD_EXPORT void Discord_Initialize(const char* applicationId, + DiscordEventHandlers* handlers, + int autoRegister, + const char* optionalSteamId); +DISCORD_EXPORT void Discord_Shutdown(void); + +/* checks for incoming messages, dispatches callbacks */ +DISCORD_EXPORT void Discord_RunCallbacks(void); + +/* If you disable the lib starting its own io thread, you'll need to call this from your own */ +#ifdef DISCORD_DISABLE_IO_THREAD +DISCORD_EXPORT void Discord_UpdateConnection(void); +#endif + +DISCORD_EXPORT void Discord_UpdatePresence(const DiscordRichPresence* presence); +DISCORD_EXPORT void Discord_ClearPresence(void); + +DISCORD_EXPORT void Discord_Respond(const char* userid, /* DISCORD_REPLY_ */ int reply); + +#ifdef __cplusplus +} /* extern "C" */ +#endif diff --git a/include/discord_rich_presence.h b/include/discord_rich_presence.h new file mode 100644 index 00000000..e7ecc6ef --- /dev/null +++ b/include/discord_rich_presence.h @@ -0,0 +1,34 @@ +#ifndef DISCORD_RICH_PRESENCE_H +#define DISCORD_RICH_PRESENCE_H + +#include +#include +#include +#include +#include + +#include +#include + +#include + +namespace AttorneyOnline { + +class Discord +{ +private: + const char* APPLICATION_ID = "399779271737868288"; + std::string server_name, server_id; + int64_t timestamp; +public: + Discord(); + ~Discord(); + + void state_lobby(); + void state_server(std::string name, std::string server_id); + void state_character(std::string name); + void state_spectate(); +}; + +} +#endif // DISCORD_RICH_PRESENCE_H diff --git a/include/encryption_functions.h b/include/encryption_functions.h new file mode 100644 index 00000000..dc67d122 --- /dev/null +++ b/include/encryption_functions.h @@ -0,0 +1,15 @@ +#ifndef ENCRYPTION_FUNCTIONS_H +#define ENCRYPTION_FUNCTIONS_H + +#include + +#include +#include +#include +#include +#include + +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/file_functions.h b/include/file_functions.h new file mode 100644 index 00000000..6937ed8a --- /dev/null +++ b/include/file_functions.h @@ -0,0 +1,12 @@ +#ifndef FILE_FUNCTIONS_H +#define FILE_FUNCTIONS_H + +#include +#include +#include + +bool file_exists(QString file_path); +bool dir_exists(QString file_path); +bool exists(QString p_path); + +#endif // FILE_FUNCTIONS_H diff --git a/include/hardware_functions.h b/include/hardware_functions.h new file mode 100644 index 00000000..3fcb27cb --- /dev/null +++ b/include/hardware_functions.h @@ -0,0 +1,10 @@ +#ifndef HARDWARE_FUNCTIONS_H +#define HARDWARE_FUNCTIONS_H + +#include + +#include + +QString get_hdid(); + +#endif // HARDWARE_FUNCTIONS_H diff --git a/include/hex_functions.h b/include/hex_functions.h new file mode 100644 index 00000000..285f096a --- /dev/null +++ b/include/hex_functions.h @@ -0,0 +1,17 @@ +#ifndef HEX_OPERATIONS_H +#define HEX_OPERATIONS_H + +#include +#include +#include +#include +#include +#include +#include + +namespace omni +{ + std::string int_to_hex(unsigned int input); +} + +#endif //HEX_OPERATIONS_H diff --git a/include/lobby.h b/include/lobby.h new file mode 100644 index 00000000..19276a7d --- /dev/null +++ b/include/lobby.h @@ -0,0 +1,95 @@ +#ifndef LOBBY_H +#define LOBBY_H + +#include "aoimage.h" +#include "aobutton.h" +#include "aopacket.h" +#include "aotextarea.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +class AOApplication; + +class Lobby : public QMainWindow +{ + Q_OBJECT + +public: + Lobby(AOApplication *p_ao_app); + + void set_widgets(); + void list_servers(); + void list_favorites(); + void append_chatmessage(QString f_name, QString f_message); + void append_error(QString f_message); + void set_player_count(int players_online, int max_players); + void set_loading_text(QString p_text); + void show_loading_overlay(){ui_loading_background->show();} + void hide_loading_overlay(){ui_loading_background->hide();} + QString get_chatlog(); + int get_selected_server(); + void enable_connect_button(); + + void set_loading_value(int p_value); + + bool public_servers_selected = true; + + ~Lobby(); + +private: + AOApplication *ao_app; + + AOImage *ui_background; + + AOButton *ui_public_servers; + AOButton *ui_favorites; + + AOButton *ui_refresh; + AOButton *ui_add_to_fav; + AOButton *ui_connect; + + QLabel *ui_version; + AOButton *ui_about; + + QListWidget *ui_server_list; + + QLabel *ui_player_count; + AOTextArea *ui_description; + + AOTextArea *ui_chatbox; + + QLineEdit *ui_chatname; + QLineEdit *ui_chatmessage; + + AOImage *ui_loading_background; + QTextEdit *ui_loading_text; + QProgressBar *ui_progress_bar; + AOButton *ui_cancel; + + void set_size_and_pos(QWidget *p_widget, QString p_identifier); + +private slots: + void on_public_servers_clicked(); + void on_favorites_clicked(); + + void on_refresh_pressed(); + void on_refresh_released(); + void on_add_to_fav_pressed(); + void on_add_to_fav_released(); + void on_connect_pressed(); + void on_connect_released(); + void on_about_clicked(); + void on_server_list_clicked(QModelIndex p_model); + void on_chatfield_return_pressed(); +}; + +#endif // LOBBY_H diff --git a/include/misc_functions.h b/include/misc_functions.h new file mode 100644 index 00000000..026c6353 --- /dev/null +++ b/include/misc_functions.h @@ -0,0 +1,9 @@ +#ifndef MISC_FUNCTIONS_H +#define MISC_FUNCTIONS_H + +#include +#include + +void delay(int p_milliseconds); + +#endif // MISC_FUNCTIONS_H diff --git a/include/networkmanager.h b/include/networkmanager.h new file mode 100644 index 00000000..e28abfda --- /dev/null +++ b/include/networkmanager.h @@ -0,0 +1,86 @@ +#ifndef NETWORKMANAGER_H +#define NETWORKMANAGER_H + +// Qt for Android has stubbed QDnsLookup. This is not documented in any part of their wiki. +// This prevents SRV lookup/failover behavior from functioning. +// https://bugreports.qt.io/browse/QTBUG-56143 +#ifndef ANDROID +#define MS_FAILOVER_SUPPORTED +#endif + +//#define LOCAL_MS + +#ifdef LOCAL_MS +#undef MS_FAILOVER_SUPPORTED +#endif + +#include "aopacket.h" +#include "aoapplication.h" + +#include +#include +#include +#include +#include + +class NetworkManager : public QObject +{ + Q_OBJECT + +public: + NetworkManager(AOApplication *parent); + ~NetworkManager(); + + AOApplication *ao_app; + QTcpSocket *ms_socket; + QTcpSocket *server_socket; + QDnsLookup *ms_dns; + QTimer *ms_reconnect_timer; + + const QString ms_srv_hostname = "_aoms._tcp.aceattorneyonline.com"; +#ifdef LOCAL_MS + QString ms_nosrv_hostname = "localhost"; +#else + QString ms_nosrv_hostname = "master.aceattorneyonline.com"; +#endif + + const int ms_port = 27016; + const int timeout_milliseconds = 2000; + + const int ms_reconnect_delay_ms = 7000; + + // kind of arbitrary max buffer size + const size_t buffer_max_size = 16384; + + bool ms_partial_packet = false; + QString ms_temp_packet = ""; + + bool partial_packet = false; + QString temp_packet = ""; + + unsigned int s_decryptor = 5; + + void connect_to_master(); + void connect_to_master_nosrv(); + void connect_to_server(server_type p_server); + +public slots: + void ship_ms_packet(QString p_packet); + void ship_server_packet(QString p_packet); + +signals: + void ms_connect_finished(bool success, bool will_retry); + +private: + void perform_srv_lookup(); + +private slots: + void on_srv_lookup(); + void handle_ms_packet(); + void handle_server_packet(); + void on_ms_nosrv_connect_success(); + void on_ms_socket_error(QAbstractSocket::SocketError error); + void retry_ms_connect(); +}; + +#endif // NETWORKMANAGER_H diff --git a/include/text_file_functions.h b/include/text_file_functions.h new file mode 100644 index 00000000..119f38e2 --- /dev/null +++ b/include/text_file_functions.h @@ -0,0 +1,13 @@ +#ifndef TEXT_FILE_FUNCTIONS_H +#define TEXT_FILE_FUNCTIONS_H + +#include "aoapplication.h" +#include "file_functions.h" +#include +#include +#include +#include +#include +#include + +#endif // TEXT_FILE_FUNCTIONS_H diff --git a/lobby.cpp b/lobby.cpp deleted file mode 100644 index 4a96e567..00000000 --- a/lobby.cpp +++ /dev/null @@ -1,388 +0,0 @@ -#include "lobby.h" - -#include "debug_functions.h" -#include "aoapplication.h" -#include "networkmanager.h" -#include "aosfxplayer.h" - -Lobby::Lobby(AOApplication *p_ao_app) : QMainWindow() -{ - ao_app = p_ao_app; - - this->setWindowTitle("Attorney Online 2"); - this->setWindowIcon(QIcon(":/logo.png")); - - ui_background = new AOImage(this, ao_app); - ui_public_servers = new AOButton(this, ao_app); - ui_favorites = new AOButton(this, ao_app); - ui_refresh = new AOButton(this, ao_app); - ui_add_to_fav = new AOButton(this, ao_app); - ui_connect = new AOButton(this, ao_app); - ui_version = new QLabel(this); - ui_about = new AOButton(this, ao_app); - ui_server_list = new QListWidget(this); - ui_player_count = new QLabel(this); - ui_description = new AOTextArea(this); - ui_chatbox = new AOTextArea(this); - ui_chatbox->setOpenExternalLinks(true); - ui_chatname = new QLineEdit(this); - ui_chatname->setPlaceholderText("Name"); - ui_chatname->setText(ao_app->get_ooc_name()); - ui_chatmessage = new QLineEdit(this); - ui_loading_background = new AOImage(this, ao_app); - ui_loading_text = new QTextEdit(ui_loading_background); - ui_progress_bar = new QProgressBar(ui_loading_background); - ui_progress_bar->setMinimum(0); - ui_progress_bar->setMaximum(100); - ui_progress_bar->setStyleSheet("QProgressBar{ color: white; }"); - ui_cancel = new AOButton(ui_loading_background, ao_app); - - connect(ui_public_servers, SIGNAL(clicked()), this, SLOT(on_public_servers_clicked())); - connect(ui_favorites, SIGNAL(clicked()), this, SLOT(on_favorites_clicked())); - connect(ui_refresh, SIGNAL(pressed()), this, SLOT(on_refresh_pressed())); - connect(ui_refresh, SIGNAL(released()), this, SLOT(on_refresh_released())); - connect(ui_add_to_fav, SIGNAL(pressed()), this, SLOT(on_add_to_fav_pressed())); - connect(ui_add_to_fav, SIGNAL(released()), this, SLOT(on_add_to_fav_released())); - connect(ui_connect, SIGNAL(pressed()), this, SLOT(on_connect_pressed())); - connect(ui_connect, SIGNAL(released()), this, SLOT(on_connect_released())); - connect(ui_about, SIGNAL(clicked()), this, SLOT(on_about_clicked())); - connect(ui_server_list, SIGNAL(clicked(QModelIndex)), this, SLOT(on_server_list_clicked(QModelIndex))); - connect(ui_chatmessage, SIGNAL(returnPressed()), this, SLOT(on_chatfield_return_pressed())); - connect(ui_cancel, SIGNAL(clicked()), ao_app, SLOT(loading_cancelled())); - - ui_connect->setEnabled(false); - - list_servers(); - - set_widgets(); -} - -//sets images, position and size -void Lobby::set_widgets() -{ - ao_app->reload_theme(); - - QString filename = "lobby_design.ini"; - - pos_size_type f_lobby = ao_app->get_element_dimensions("lobby", filename); - - if (f_lobby.width < 0 || f_lobby.height < 0) - { - qDebug() << "W: did not find lobby width or height in " << filename; - - // Most common symptom of bad config files and missing assets. - call_notice("It doesn't look like your client is set up correctly.\n" - "Did you download all resources correctly from tiny.cc/getao, " - "including the large 'base' folder?"); - - this->resize(517, 666); - } - else - { - this->resize(f_lobby.width, f_lobby.height); - } - - set_size_and_pos(ui_background, "lobby"); - ui_background->set_image("lobbybackground.png"); - - set_size_and_pos(ui_public_servers, "public_servers"); - ui_public_servers->set_image("publicservers_selected.png"); - - set_size_and_pos(ui_favorites, "favorites"); - ui_favorites->set_image("favorites.png"); - - set_size_and_pos(ui_refresh, "refresh"); - ui_refresh->set_image("refresh.png"); - - set_size_and_pos(ui_add_to_fav, "add_to_fav"); - ui_add_to_fav->set_image("addtofav.png"); - - set_size_and_pos(ui_connect, "connect"); - ui_connect->set_image("connect.png"); - - set_size_and_pos(ui_version, "version"); - ui_version->setText("Version: " + ao_app->get_version_string()); - - set_size_and_pos(ui_about, "about"); - ui_about->set_image("about.png"); - - set_size_and_pos(ui_server_list, "server_list"); - ui_server_list->setStyleSheet("background-color: rgba(0, 0, 0, 0);" - "font: bold;"); - - set_size_and_pos(ui_player_count, "player_count"); - ui_player_count->setText("Offline"); - ui_player_count->setStyleSheet("font: bold;" - "color: white;" - "qproperty-alignment: AlignCenter;"); - - set_size_and_pos(ui_description, "description"); - ui_description->setReadOnly(true); - ui_description->setStyleSheet("background-color: rgba(0, 0, 0, 0);" - "color: white;"); - - set_size_and_pos(ui_chatbox, "chatbox"); - ui_chatbox->setReadOnly(true); - ui_chatbox->setStyleSheet("QTextBrowser{background-color: rgba(0, 0, 0, 0);}"); - - set_size_and_pos(ui_chatname, "chatname"); - ui_chatname->setStyleSheet("background-color: rgba(0, 0, 0, 0);" - "selection-background-color: rgba(0, 0, 0, 0);"); - - set_size_and_pos(ui_chatmessage, "chatmessage"); - ui_chatmessage->setStyleSheet("background-color: rgba(0, 0, 0, 0);" - "selection-background-color: rgba(0, 0, 0, 0);"); - - ui_loading_background->resize(this->width(), this->height()); - ui_loading_background->set_image("loadingbackground.png"); - - - set_size_and_pos(ui_loading_text, "loading_label"); - ui_loading_text->setFont(QFont("Arial", 20, QFont::Bold)); - ui_loading_text->setReadOnly(true); - ui_loading_text->setAlignment(Qt::AlignCenter); - ui_loading_text->setFrameStyle(QFrame::NoFrame); - ui_loading_text->setStyleSheet("background-color: rgba(0, 0, 0, 0);" - "color: rgba(255, 128, 0, 255);"); - ui_loading_text->append("Loading"); - - set_size_and_pos(ui_progress_bar, "progress_bar"); - set_size_and_pos(ui_cancel, "cancel"); - ui_cancel->setText("Cancel"); - - ui_loading_background->hide(); - -} - -void Lobby::set_size_and_pos(QWidget *p_widget, QString p_identifier) -{ - QString filename = "lobby_design.ini"; - - pos_size_type design_ini_result = ao_app->get_element_dimensions(p_identifier, filename); - - if (design_ini_result.width < 0 || design_ini_result.height < 0) - { - qDebug() << "W: could not find " << p_identifier << " in " << filename; - p_widget->hide(); - } - else - { - p_widget->move(design_ini_result.x, design_ini_result.y); - p_widget->resize(design_ini_result.width, design_ini_result.height); - } -} - -void Lobby::set_loading_text(QString p_text) -{ - ui_loading_text->clear(); - ui_loading_text->setAlignment(Qt::AlignCenter); - ui_loading_text->append(p_text); -} - -QString Lobby::get_chatlog() -{ - QString return_value = ui_chatbox->toPlainText(); - - return return_value; -} - -int Lobby::get_selected_server() -{ - return ui_server_list->currentRow(); -} - -void Lobby::set_loading_value(int p_value) -{ - ui_progress_bar->setValue(p_value); -} - -void Lobby::on_public_servers_clicked() -{ - ui_public_servers->set_image("publicservers_selected.png"); - ui_favorites->set_image("favorites.png"); - - list_servers(); - - public_servers_selected = true; -} - -void Lobby::on_favorites_clicked() -{ - ui_favorites->set_image("favorites_selected.png"); - ui_public_servers->set_image("publicservers.png"); - - ao_app->set_favorite_list(); - //ao_app->favorite_list = read_serverlist_txt(); - - list_favorites(); - - public_servers_selected = false; -} - -void Lobby::on_refresh_pressed() -{ - ui_refresh->set_image("refresh_pressed.png"); -} - -void Lobby::on_refresh_released() -{ - ui_refresh->set_image("refresh.png"); - - AOPacket *f_packet = new AOPacket("ALL#%"); - - ao_app->send_ms_packet(f_packet); -} - -void Lobby::on_add_to_fav_pressed() -{ - ui_add_to_fav->set_image("addtofav_pressed.png"); -} - -void Lobby::on_add_to_fav_released() -{ - ui_add_to_fav->set_image("addtofav.png"); - - //you cant add favorites from favorites m8 - if (!public_servers_selected) - return; - - ao_app->add_favorite_server(ui_server_list->currentRow()); -} - -void Lobby::on_connect_pressed() -{ - ui_connect->set_image("connect_pressed.png"); -} - -void Lobby::on_connect_released() -{ - ui_connect->set_image("connect.png"); - - AOPacket *f_packet; - - f_packet = new AOPacket("askchaa#%"); - - ao_app->send_server_packet(f_packet); -} - -void Lobby::on_about_clicked() -{ - QString msg = tr("

Attorney Online %1

" - "The courtroom drama simulator" - "

Source code: " - "" - "https://github.com/AttorneyOnline/AO2-Client" - "

Major development:
" - "OmniTroid, stonedDiscord, longbyte1, gameboyprinter, Cerapter" - "

Special thanks:
" - "Remy, Iamgoofball, Hibiki, Qubrick (webAO), Ruekasu (UI design), " - "Draxirch (UI design), Unishred, Argoneus (tsuserver), Fiercy, " - "Noevain, Cronnicossy") - .arg(ao_app->get_version_string()); - QMessageBox::about(this, "About", msg); -} - -void Lobby::on_server_list_clicked(QModelIndex p_model) -{ - server_type f_server; - int n_server = p_model.row(); - - if (n_server < 0) - return; - - if (public_servers_selected) - { - QVector f_server_list = ao_app->get_server_list(); - - if (n_server >= f_server_list.size()) - return; - - f_server = f_server_list.at(p_model.row()); - } - else - { - if (n_server >= ao_app->get_favorite_list().size()) - return; - - f_server = ao_app->get_favorite_list().at(p_model.row()); - } - - ui_description->clear(); - ui_description->append(f_server.desc); - - ui_description->moveCursor(QTextCursor::Start); - ui_description->ensureCursorVisible(); - - ui_player_count->setText("Offline"); - - ui_connect->setEnabled(false); - - ao_app->net_manager->connect_to_server(f_server); -} - -void Lobby::on_chatfield_return_pressed() -{ - //no you can't send empty messages - if (ui_chatname->text() == "" || ui_chatmessage->text() == "") - return; - - - QString f_header = "CT"; - QStringList f_contents{ui_chatname->text(), ui_chatmessage->text()}; - - AOPacket *f_packet = new AOPacket(f_header, f_contents); - - ao_app->send_ms_packet(f_packet); - - ui_chatmessage->clear(); -} - -void Lobby::list_servers() -{ - public_servers_selected = true; - ui_favorites->set_image("favorites.png"); - ui_public_servers->set_image("publicservers_selected.png"); - - ui_server_list->clear(); - - for (server_type i_server : ao_app->get_server_list()) - { - ui_server_list->addItem(i_server.name); - } -} - -void Lobby::list_favorites() -{ - ui_server_list->clear(); - - for (server_type i_server : ao_app->get_favorite_list()) - { - ui_server_list->addItem(i_server.name); - } -} - -void Lobby::append_chatmessage(QString f_name, QString f_message) -{ - ui_chatbox->append_chatmessage(f_name, f_message, ao_app->get_color("ooc_default_color", "courtroom_design.ini").name()); -} - -void Lobby::append_error(QString f_message) -{ - ui_chatbox->append_error(f_message); -} - -void Lobby::set_player_count(int players_online, int max_players) -{ - QString f_string = "Online: " + QString::number(players_online) + "/" + QString::number(max_players); - ui_player_count->setText(f_string); -} - -void Lobby::enable_connect_button() -{ - ui_connect->setEnabled(true); -} - -Lobby::~Lobby() -{ - -} diff --git a/lobby.h b/lobby.h deleted file mode 100644 index 19276a7d..00000000 --- a/lobby.h +++ /dev/null @@ -1,95 +0,0 @@ -#ifndef LOBBY_H -#define LOBBY_H - -#include "aoimage.h" -#include "aobutton.h" -#include "aopacket.h" -#include "aotextarea.h" - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -class AOApplication; - -class Lobby : public QMainWindow -{ - Q_OBJECT - -public: - Lobby(AOApplication *p_ao_app); - - void set_widgets(); - void list_servers(); - void list_favorites(); - void append_chatmessage(QString f_name, QString f_message); - void append_error(QString f_message); - void set_player_count(int players_online, int max_players); - void set_loading_text(QString p_text); - void show_loading_overlay(){ui_loading_background->show();} - void hide_loading_overlay(){ui_loading_background->hide();} - QString get_chatlog(); - int get_selected_server(); - void enable_connect_button(); - - void set_loading_value(int p_value); - - bool public_servers_selected = true; - - ~Lobby(); - -private: - AOApplication *ao_app; - - AOImage *ui_background; - - AOButton *ui_public_servers; - AOButton *ui_favorites; - - AOButton *ui_refresh; - AOButton *ui_add_to_fav; - AOButton *ui_connect; - - QLabel *ui_version; - AOButton *ui_about; - - QListWidget *ui_server_list; - - QLabel *ui_player_count; - AOTextArea *ui_description; - - AOTextArea *ui_chatbox; - - QLineEdit *ui_chatname; - QLineEdit *ui_chatmessage; - - AOImage *ui_loading_background; - QTextEdit *ui_loading_text; - QProgressBar *ui_progress_bar; - AOButton *ui_cancel; - - void set_size_and_pos(QWidget *p_widget, QString p_identifier); - -private slots: - void on_public_servers_clicked(); - void on_favorites_clicked(); - - void on_refresh_pressed(); - void on_refresh_released(); - void on_add_to_fav_pressed(); - void on_add_to_fav_released(); - void on_connect_pressed(); - void on_connect_released(); - void on_about_clicked(); - void on_server_list_clicked(QModelIndex p_model); - void on_chatfield_return_pressed(); -}; - -#endif // LOBBY_H diff --git a/logo.ico b/logo.ico deleted file mode 100644 index b40e7866..00000000 Binary files a/logo.ico and /dev/null differ diff --git a/logo.png b/logo.png deleted file mode 100644 index f53fe30c..00000000 Binary files a/logo.png and /dev/null differ diff --git a/main.cpp b/main.cpp deleted file mode 100644 index cf51b0af..00000000 --- a/main.cpp +++ /dev/null @@ -1,25 +0,0 @@ - -#include "aoapplication.h" - -#include "datatypes.h" -#include "networkmanager.h" -#include "lobby.h" -#include "courtroom.h" -#include -#include -Q_IMPORT_PLUGIN(ApngImagePlugin); -int main(int argc, char *argv[]) -{ -#if QT_VERSION > QT_VERSION_CHECK(5, 6, 0) - // High-DPI support is for Qt version >=5.6. - // However, many Linux distros still haven't brought their stable/LTS - // packages up to Qt 5.6, so this is conditional. - AOApplication::setAttribute(Qt::AA_EnableHighDpiScaling); -#endif - - AOApplication main_app(argc, argv); - main_app.construct_lobby(); - main_app.net_manager->connect_to_master(); - main_app.w_lobby->show(); - return main_app.exec(); -} diff --git a/misc_functions.cpp b/misc_functions.cpp deleted file mode 100644 index 23520551..00000000 --- a/misc_functions.cpp +++ /dev/null @@ -1,9 +0,0 @@ -#include "misc_functions.h" - -void delay(int p_milliseconds) -{ - QTime dieTime = QTime::currentTime().addMSecs(p_milliseconds); - - while(QTime::currentTime() < dieTime) - QCoreApplication::processEvents(QEventLoop::AllEvents, 100); -} diff --git a/misc_functions.h b/misc_functions.h deleted file mode 100644 index 026c6353..00000000 --- a/misc_functions.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef MISC_FUNCTIONS_H -#define MISC_FUNCTIONS_H - -#include -#include - -void delay(int p_milliseconds); - -#endif // MISC_FUNCTIONS_H diff --git a/networkmanager.cpp b/networkmanager.cpp deleted file mode 100644 index 288a9007..00000000 --- a/networkmanager.cpp +++ /dev/null @@ -1,252 +0,0 @@ -#include "networkmanager.h" - -#include "datatypes.h" -#include "debug_functions.h" -#include "lobby.h" - -NetworkManager::NetworkManager(AOApplication *parent) : QObject(parent) -{ - ao_app = parent; - - ms_socket = new QTcpSocket(this); - server_socket = new QTcpSocket(this); - - ms_reconnect_timer = new QTimer(this); - ms_reconnect_timer->setSingleShot(true); - QObject::connect(ms_reconnect_timer, SIGNAL(timeout()), this, SLOT(retry_ms_connect())); - - QObject::connect(ms_socket, SIGNAL(readyRead()), this, SLOT(handle_ms_packet())); - QObject::connect(server_socket, SIGNAL(readyRead()), this, SLOT(handle_server_packet())); - QObject::connect(server_socket, SIGNAL(disconnected()), ao_app, SLOT(server_disconnected())); - - QString master_config = ao_app->configini->value("master", "").value(); - if (master_config != "") - ms_nosrv_hostname = master_config; -} - -NetworkManager::~NetworkManager() -{ - -} - -void NetworkManager::connect_to_master() -{ - ms_socket->close(); - ms_socket->abort(); - -#ifdef MS_FAILOVER_SUPPORTED - perform_srv_lookup(); -#else - connect_to_master_nosrv(); -#endif -} - -void NetworkManager::connect_to_master_nosrv() -{ - QObject::connect(ms_socket, SIGNAL(error(QAbstractSocket::SocketError)), - this, SLOT(on_ms_socket_error(QAbstractSocket::SocketError))); - - QObject::connect(ms_socket, SIGNAL(connected()), - this, SLOT(on_ms_nosrv_connect_success())); - ms_socket->connectToHost(ms_nosrv_hostname, ms_port); -} - -void NetworkManager::connect_to_server(server_type p_server) -{ - server_socket->close(); - server_socket->abort(); - - server_socket->connectToHost(p_server.ip, p_server.port); -} - -void NetworkManager::ship_ms_packet(QString p_packet) -{ - if (!ms_socket->isOpen()) - { - retry_ms_connect(); - } - else - { - ms_socket->write(p_packet.toUtf8()); - } -} - -void NetworkManager::ship_server_packet(QString p_packet) -{ - server_socket->write(p_packet.toUtf8()); -} - -void NetworkManager::handle_ms_packet() -{ - char buffer[buffer_max_size]; - std::memset(buffer, 0, buffer_max_size); - ms_socket->read(buffer, buffer_max_size); - - QString in_data = buffer; - - if (!in_data.endsWith("%")) - { - ms_partial_packet = true; - ms_temp_packet += in_data; - return; - } - - else - { - if (ms_partial_packet) - { - in_data = ms_temp_packet + in_data; - ms_temp_packet = ""; - ms_partial_packet = false; - } - } - - QStringList packet_list = in_data.split("%", QString::SplitBehavior(QString::SkipEmptyParts)); - - for (QString packet : packet_list) - { - AOPacket *f_packet = new AOPacket(packet); - - ao_app->ms_packet_received(f_packet); - } -} - - -void NetworkManager::perform_srv_lookup() -{ - #ifdef MS_FAILOVER_SUPPORTED - ms_dns = new QDnsLookup(QDnsLookup::SRV, ms_srv_hostname, this); - - connect(ms_dns, SIGNAL(finished()), this, SLOT(on_srv_lookup())); - ms_dns->lookup(); - #endif -} - -void NetworkManager::on_srv_lookup() -{ - #ifdef MS_FAILOVER_SUPPORTED - bool connected = false; - if (ms_dns->error() != QDnsLookup::NoError) - { - qWarning("SRV lookup of the master server DNS failed."); - ms_dns->deleteLater(); - } - else - { - const auto srv_records = ms_dns->serviceRecords(); - - for (const QDnsServiceRecord &record : srv_records) - { - qDebug() << "Connecting to " << record.target() << ":" << record.port(); - ms_socket->connectToHost(record.target(), record.port()); - QTime timer; - timer.start(); - do - { - ao_app->processEvents(); - if (ms_socket->state() == QAbstractSocket::ConnectedState) - { - connected = true; - break; - } - else if (ms_socket->state() != QAbstractSocket::ConnectingState - && ms_socket->state() != QAbstractSocket::HostLookupState - && ms_socket->error() != -1) - { - qDebug() << ms_socket->error(); - qWarning() << "Error connecting to master server:" << ms_socket->errorString(); - ms_socket->abort(); - ms_socket->close(); - break; - } - } while (timer.elapsed() < timeout_milliseconds); // Very expensive spin-wait loop - it will bring CPU to 100%! - if (connected) - { - // Connect a one-shot signal in case the master server disconnects randomly - QObject::connect(ms_socket, SIGNAL(error(QAbstractSocket::SocketError)), - this, SLOT(on_ms_socket_error(QAbstractSocket::SocketError))); - break; - } - else - { - ms_socket->abort(); - ms_socket->close(); - } - } - } - - // Failover to non-SRV connection - if (!connected) - connect_to_master_nosrv(); - else - emit ms_connect_finished(connected, false); - #endif -} - -void NetworkManager::on_ms_nosrv_connect_success() -{ - emit ms_connect_finished(true, false); - - QObject::disconnect(ms_socket, SIGNAL(connected()), - this, SLOT(on_ms_nosrv_connect_success())); - - QObject::connect(ms_socket, SIGNAL(error(QAbstractSocket::SocketError)), - this, SLOT(on_ms_socket_error(QAbstractSocket::SocketError))); -} - -void NetworkManager::on_ms_socket_error(QAbstractSocket::SocketError error) -{ - qWarning() << "Master server socket error:" << ms_socket->errorString() - << "(" << error << ")"; - - // Disconnect the one-shot signal - this way, failover connect attempts - // don't trigger a full retry - QObject::disconnect(ms_socket, SIGNAL(error(QAbstractSocket::SocketError)), - this, SLOT(on_ms_socket_error(QAbstractSocket::SocketError))); - - emit ms_connect_finished(false, true); - - ms_reconnect_timer->start(ms_reconnect_delay_ms); -} - -void NetworkManager::retry_ms_connect() -{ - if (!ms_reconnect_timer->isActive() && ms_socket->state() != QAbstractSocket::ConnectingState) - connect_to_master(); -} - -void NetworkManager::handle_server_packet() -{ - char buffer[buffer_max_size]; - std::memset(buffer, 0, buffer_max_size); - server_socket->read(buffer, buffer_max_size); - - QString in_data = buffer; - - if (!in_data.endsWith("%")) - { - partial_packet = true; - temp_packet += in_data; - return; - } - - else - { - if (partial_packet) - { - in_data = temp_packet + in_data; - temp_packet = ""; - partial_packet = false; - } - } - - QStringList packet_list = in_data.split("%", QString::SplitBehavior(QString::SkipEmptyParts)); - - for (QString packet : packet_list) - { - AOPacket *f_packet = new AOPacket(packet); - - ao_app->server_packet_received(f_packet); - } -} - diff --git a/networkmanager.h b/networkmanager.h deleted file mode 100644 index e28abfda..00000000 --- a/networkmanager.h +++ /dev/null @@ -1,86 +0,0 @@ -#ifndef NETWORKMANAGER_H -#define NETWORKMANAGER_H - -// Qt for Android has stubbed QDnsLookup. This is not documented in any part of their wiki. -// This prevents SRV lookup/failover behavior from functioning. -// https://bugreports.qt.io/browse/QTBUG-56143 -#ifndef ANDROID -#define MS_FAILOVER_SUPPORTED -#endif - -//#define LOCAL_MS - -#ifdef LOCAL_MS -#undef MS_FAILOVER_SUPPORTED -#endif - -#include "aopacket.h" -#include "aoapplication.h" - -#include -#include -#include -#include -#include - -class NetworkManager : public QObject -{ - Q_OBJECT - -public: - NetworkManager(AOApplication *parent); - ~NetworkManager(); - - AOApplication *ao_app; - QTcpSocket *ms_socket; - QTcpSocket *server_socket; - QDnsLookup *ms_dns; - QTimer *ms_reconnect_timer; - - const QString ms_srv_hostname = "_aoms._tcp.aceattorneyonline.com"; -#ifdef LOCAL_MS - QString ms_nosrv_hostname = "localhost"; -#else - QString ms_nosrv_hostname = "master.aceattorneyonline.com"; -#endif - - const int ms_port = 27016; - const int timeout_milliseconds = 2000; - - const int ms_reconnect_delay_ms = 7000; - - // kind of arbitrary max buffer size - const size_t buffer_max_size = 16384; - - bool ms_partial_packet = false; - QString ms_temp_packet = ""; - - bool partial_packet = false; - QString temp_packet = ""; - - unsigned int s_decryptor = 5; - - void connect_to_master(); - void connect_to_master_nosrv(); - void connect_to_server(server_type p_server); - -public slots: - void ship_ms_packet(QString p_packet); - void ship_server_packet(QString p_packet); - -signals: - void ms_connect_finished(bool success, bool will_retry); - -private: - void perform_srv_lookup(); - -private slots: - void on_srv_lookup(); - void handle_ms_packet(); - void handle_server_packet(); - void on_ms_nosrv_connect_success(); - void on_ms_socket_error(QAbstractSocket::SocketError error); - void retry_ms_connect(); -}; - -#endif // NETWORKMANAGER_H diff --git a/packet_distribution.cpp b/packet_distribution.cpp deleted file mode 100644 index 954062e8..00000000 --- a/packet_distribution.cpp +++ /dev/null @@ -1,707 +0,0 @@ -#include "aoapplication.h" - -#include "lobby.h" -#include "courtroom.h" -#include "networkmanager.h" -#include "encryption_functions.h" -#include "hardware_functions.h" -#include "debug_functions.h" - -void AOApplication::ms_packet_received(AOPacket *p_packet) -{ - p_packet->net_decode(); - - QString header = p_packet->get_header(); - QStringList f_contents = p_packet->get_contents(); - - if (header != "CHECK") - qDebug() << "R(ms):" << p_packet->to_string(); - - if (header == "ALL") - { - server_list.clear(); - - for (QString i_string : p_packet->get_contents()) - { - server_type f_server; - QStringList sub_contents = i_string.split("&"); - - if (sub_contents.size() < 4) - { - qDebug() << "W: malformed packet"; - continue; - } - - f_server.name = sub_contents.at(0); - f_server.desc = sub_contents.at(1); - f_server.ip = sub_contents.at(2); - f_server.port = sub_contents.at(3).toInt(); - - server_list.append(f_server); - } - - if (lobby_constructed) - { - w_lobby->list_servers(); - } - } - else if (header == "CT") - { - QString f_name, f_message; - - if (f_contents.size() == 1) - { - f_name = ""; - f_message = f_contents.at(0); - } - else if (f_contents.size() >= 2) - { - f_name = f_contents.at(0); - f_message = f_contents.at(1); - } - else - goto end; - - if (lobby_constructed) - { - w_lobby->append_chatmessage(f_name, f_message); - } - if (courtroom_constructed && courtroom_loaded) - { - w_courtroom->append_ms_chatmessage(f_name, f_message); - } - } - else if (header == "AO2CHECK") - { - send_ms_packet(new AOPacket("ID#AO2#" + get_version_string() + "#%")); - send_ms_packet(new AOPacket("HI#" + get_hdid() + "#%")); - - if (f_contents.size() < 1) - goto end; - - QStringList version_contents = f_contents.at(0).split("."); - - if (version_contents.size() < 3) - goto end; - - int f_release = version_contents.at(0).toInt(); - int f_major = version_contents.at(1).toInt(); - int f_minor = version_contents.at(2).toInt(); - - if (get_release() > f_release) - goto end; - else if (get_release() == f_release) - { - if (get_major_version() > f_major) - goto end; - else if (get_major_version() == f_major) - { - if (get_minor_version() >= f_minor) - goto end; - } - } - - call_notice("Outdated version! Your version: " + get_version_string() - + "\nPlease go to aceattorneyonline.com to update."); - destruct_courtroom(); - destruct_lobby(); - } - else if (header == "DOOM") - { - call_notice("You have been exiled from AO." - "Have a nice day."); - destruct_courtroom(); - destruct_lobby(); - } - - end: - - delete p_packet; -} - -void AOApplication::server_packet_received(AOPacket *p_packet) -{ - p_packet->net_decode(); - - QString header = p_packet->get_header(); - QStringList f_contents = p_packet->get_contents(); - QString f_packet = p_packet->to_string(); - - if (header != "checkconnection") - qDebug() << "R:" << f_packet; - - if (header == "decryptor") - { - 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; - arup_enabled = false; - casing_alerts_enabled = false; - modcall_reason_enabled = false; - - //workaround for tsuserver4 - if (f_contents.at(0) == "NOENCRYPT") - encryption_needed = false; - - QString f_hdid; - f_hdid = get_hdid(); - - AOPacket *hi_packet = new AOPacket("HI#" + f_hdid + "#%"); - send_server_packet(hi_packet); - } - else if (header == "ID") - { - if (f_contents.size() < 2) - goto end; - - s_pv = f_contents.at(0).toInt(); - server_software = f_contents.at(1); - - send_server_packet(new AOPacket("ID#AO2#" + get_version_string() + "#%")); - } - else if (header == "CT") - { - if (f_contents.size() < 2) - goto end; - - if (courtroom_constructed) - { - if (f_contents.size() == 3) - w_courtroom->append_server_chatmessage(f_contents.at(0), f_contents.at(1), f_contents.at(2)); - else - w_courtroom->append_server_chatmessage(f_contents.at(0), f_contents.at(1), "0"); - } - } - else if (header == "FL") - { - if (f_packet.contains("yellowtext",Qt::CaseInsensitive)) - yellow_text_enabled = true; - if (f_packet.contains("flipping",Qt::CaseInsensitive)) - 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)) - evidence_enabled = true; - if (f_packet.contains("cccc_ic_support",Qt::CaseInsensitive)) - cccc_ic_support_enabled = true; - if (f_packet.contains("arup",Qt::CaseInsensitive)) - arup_enabled = true; - if (f_packet.contains("casing_alerts",Qt::CaseInsensitive)) - casing_alerts_enabled = true; - if (f_packet.contains("modcall_reason",Qt::CaseInsensitive)) - modcall_reason_enabled = true; - - w_lobby->enable_connect_button(); - } - else if (header == "PN") - { - if (f_contents.size() < 2) - goto end; - - w_lobby->set_player_count(f_contents.at(0).toInt(), f_contents.at(1).toInt()); - } - else if (header == "SI") - { - if (f_contents.size() != 3) - goto end; - - char_list_size = f_contents.at(0).toInt(); - evidence_list_size = f_contents.at(1).toInt(); - music_list_size = f_contents.at(2).toInt(); - - if (char_list_size < 1 || evidence_list_size < 0 || music_list_size < 0) - goto end; - - loaded_chars = 0; - loaded_evidence = 0; - loaded_music = 0; - generated_chars = 0; - - destruct_courtroom(); - construct_courtroom(); - - courtroom_loaded = false; - - QString window_title = "Attorney Online 2"; - int selected_server = w_lobby->get_selected_server(); - - QString server_address = "", server_name = ""; - if (w_lobby->public_servers_selected) - { - if (selected_server >= 0 && selected_server < server_list.size()) { - auto info = server_list.at(selected_server); - server_name = info.name; - server_address = QString("%1:%2").arg(info.ip, info.port); - window_title += ": " + server_name; - } - } - else - { - if (selected_server >= 0 && selected_server < favorite_list.size()) { - auto info = favorite_list.at(selected_server); - server_name = info.name; - server_address = info.ip + info.port; - window_title += ": " + server_name; - } - } - - w_courtroom->set_window_title(window_title); - - w_lobby->show_loading_overlay(); - w_lobby->set_loading_text("Loading"); - w_lobby->set_loading_value(0); - - AOPacket *f_packet; - - if(improved_loading_enabled) - f_packet = new AOPacket("RC#%"); - else - f_packet = new AOPacket("askchar2#%"); - - send_server_packet(f_packet); - - QCryptographicHash hash(QCryptographicHash::Algorithm::Sha256); - hash.addData(server_address.toUtf8()); - if (is_discord_enabled()) - 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("Loading chars:\n" + QString::number(loaded_chars) + "/" + 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(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("Loading evidence:\n" + QString::number(loaded_evidence) + "/" + 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(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("Loading music:\n" + QString::number(loaded_music) + "/" + 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(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; - - for (int n_char = 0 ; n_char < f_contents.size() ; ++n_char) - { - if (f_contents.at(n_char) == "-1") - w_courtroom->set_taken(n_char, true); - else - w_courtroom->set_taken(n_char, false); - } - } - - else if (header == "SC") - { - if (!courtroom_constructed) - goto end; - - for (int n_element = 0 ; n_element < f_contents.size() ; ++n_element) - { - QStringList sub_elements = f_contents.at(n_element).split("&"); - - char_type f_char; - f_char.name = sub_elements.at(0); - if (sub_elements.size() >= 2) - f_char.description = sub_elements.at(1); - - //temporary. the CharsCheck packet sets this properly - f_char.taken = false; - - ++loaded_chars; - - w_lobby->set_loading_text("Loading chars:\n" + QString::number(loaded_chars) + "/" + 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(total_loading_size)) * 100); - w_lobby->set_loading_value(loading_value); - } - - send_server_packet(new AOPacket("RM#%")); - } - else if (header == "SM") - { - if (!courtroom_constructed) - goto end; - - bool musics_time = false; - int areas = 0; - - for (int n_element = 0 ; n_element < f_contents.size() ; ++n_element) - { - ++loaded_music; - - w_lobby->set_loading_text("Loading music:\n" + QString::number(loaded_music) + "/" + QString::number(music_list_size)); - - if (musics_time) - { - w_courtroom->append_music(f_contents.at(n_element)); - } - else - { - if (f_contents.at(n_element).endsWith(".wav") || - f_contents.at(n_element).endsWith(".mp3") || - f_contents.at(n_element).endsWith(".mp4") || - f_contents.at(n_element).endsWith(".ogg") || - f_contents.at(n_element).endsWith(".opus")) - { - musics_time = true; - w_courtroom->fix_last_area(); - w_courtroom->append_music(f_contents.at(n_element)); - areas--; - } - else - { - w_courtroom->append_area(f_contents.at(n_element)); - 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(total_loading_size)) * 100); - w_lobby->set_loading_value(loading_value); - } - - send_server_packet(new AOPacket("RD#%")); - } - else if (header == "DONE") - { - if (!courtroom_constructed) - goto end; - - if (lobby_constructed) - w_courtroom->append_ms_chatmessage("", w_lobby->get_chatlog()); - - w_courtroom->character_loading_finished(); - w_courtroom->done_received(); - - courtroom_loaded = true; - - destruct_lobby(); - } - else if (header == "BN") - { - if (f_contents.size() < 1) - goto end; - - if (courtroom_constructed) - w_courtroom->set_background(f_contents.at(0)); - } - //server accepting char request(CC) packet - else if (header == "PV") - { - if (f_contents.size() < 3) - goto end; - - if (courtroom_constructed) - w_courtroom->enter_courtroom(f_contents.at(2).toInt()); - } - else if (header == "MS") - { - if (courtroom_constructed && courtroom_loaded) - w_courtroom->handle_chatmessage(&p_packet->get_contents()); - } - else if (header == "MC") - { - if (courtroom_constructed && courtroom_loaded) - w_courtroom->handle_song(&p_packet->get_contents()); - } - else if (header == "RT") - { - if (f_contents.size() < 1) - goto end; - if (courtroom_constructed) - { - if (f_contents.size() == 1) - w_courtroom->handle_wtce(f_contents.at(0), 0); - else if (f_contents.size() == 2) { - w_courtroom->handle_wtce(f_contents.at(0), f_contents.at(1).toInt()); - } - } - } - else if (header == "HP") - { - if (courtroom_constructed && f_contents.size() > 1) - w_courtroom->set_hp_bar(f_contents.at(0).toInt(), f_contents.at(1).toInt()); - } - else if (header == "LE") - { - if (courtroom_constructed) - { - QVector f_evi_list; - - for (QString f_string : f_contents) - { - QStringList sub_contents = f_string.split("&"); - - if (sub_contents.size() < 3) - continue; - - evi_type f_evi; - f_evi.name = sub_contents.at(0); - f_evi.description = sub_contents.at(1); - f_evi.image = sub_contents.at(2); - - f_evi_list.append(f_evi); - } - - w_courtroom->set_evidence_list(f_evi_list); - } - } - else if (header == "ARUP") - { - if (courtroom_constructed) - { - int arup_type = f_contents.at(0).toInt(); - for (int n_element = 1 ; n_element < f_contents.size() ; n_element++) - { - w_courtroom->arup_modify(arup_type, n_element - 1, f_contents.at(n_element)); - } - } - } - else if (header == "IL") - { - if (courtroom_constructed && f_contents.size() > 0) - w_courtroom->set_ip_list(f_contents.at(0)); - } - else if (header == "MU") - { - if (courtroom_constructed && f_contents.size() > 0) - w_courtroom->set_mute(true, f_contents.at(0).toInt()); - } - else if (header == "UM") - { - if (courtroom_constructed && f_contents.size() > 0) - w_courtroom->set_mute(false, f_contents.at(0).toInt()); - } - else if (header == "KK") - { - if (courtroom_constructed && f_contents.size() >= 1) - { - call_notice("You have been kicked from the server.\nReason: " + f_contents.at(0)); - construct_lobby(); - destruct_courtroom(); - } - } - else if (header == "KB") - { - if (courtroom_constructed && f_contents.size() >= 1) - { - call_notice("You have been banned from the server.\nReason: " + f_contents.at(0)); - construct_lobby(); - destruct_courtroom(); - } - - } - else if (header == "BD") - { - call_notice("You are banned on this server."); - } - else if (header == "ZZ") - { - if (courtroom_constructed && f_contents.size() > 0) - w_courtroom->mod_called(f_contents.at(0)); - } - else if (header == "CASEA") - { - if (courtroom_constructed && f_contents.size() > 6) - w_courtroom->case_called(f_contents.at(0), f_contents.at(1) == "1", f_contents.at(2) == "1", f_contents.at(3) == "1", f_contents.at(4) == "1", f_contents.at(5) == "1"); - } - - end: - - delete p_packet; -} - -void AOApplication::send_ms_packet(AOPacket *p_packet) -{ - p_packet->net_encode(); - - QString f_packet = p_packet->to_string(); - - net_manager->ship_ms_packet(f_packet); - - qDebug() << "S(ms):" << f_packet; - - delete p_packet; -} - -void AOApplication::send_server_packet(AOPacket *p_packet, bool encoded) -{ - if (encoded) - p_packet->net_encode(); - - QString f_packet = p_packet->to_string(); - - if (encryption_needed) - { - qDebug() << "S(e):" << f_packet; - - p_packet->encrypt_header(s_decryptor); - f_packet = p_packet->to_string(); - } - else - { - qDebug() << "S:" << f_packet; - } - - net_manager->ship_server_packet(f_packet); - - delete p_packet; -} diff --git a/path_functions.cpp b/path_functions.cpp deleted file mode 100644 index c51cfde3..00000000 --- a/path_functions.cpp +++ /dev/null @@ -1,162 +0,0 @@ -#include "aoapplication.h" -#include "courtroom.h" -#include "file_functions.h" - -#include -#include -#include - -#ifdef BASE_OVERRIDE -#include "base_override.h" -#endif - -//this is a quite broad generalization -//the most common OSes(mac and windows) are _usually_ case insensitive -//however, there do exist mac installations with case sensitive filesystems -//in that case, define CASE_SENSITIVE_FILESYSTEM and compile on a mac -#if (defined (LINUX) || defined (__linux__)) -#define CASE_SENSITIVE_FILESYSTEM -#endif - -QString AOApplication::get_base_path() -{ - QString base_path = ""; -#ifdef ANDROID - QString sdcard_storage = getenv("SECONDARY_STORAGE"); - if (dir_exists(sdcard_storage + "/AO2/")){ - base_path = sdcard_storage + "/AO2/"; - } - else { - QString external_storage = getenv("EXTERNAL_STORAGE"); - base_path = external_storage + "/AO2/"; - } -#else - base_path = applicationDirPath() + "/base/"; -#endif - - return base_path; -} - -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) -{ - 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) -{ - 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); -} - -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) { - //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? - if (exists(file_parent_dir + "/" + file_basename)) - return file_parent_dir + "/" + file_basename; - - //last resort, dirlist parent dir and find case insensitive match - QRegExp file_rx = QRegExp(file_basename, Qt::CaseInsensitive, QRegExp::FixedString); - QStringList files = QDir(file_parent_dir).entryList(); - - int result = files.indexOf(file_rx); - - if (result != -1) - return file_parent_dir + "/" + files.at(result); - - //if nothing is found, let the caller handle the missing file - return file_parent_dir + "/" + file_basename; -} diff --git a/resource/logo.ico b/resource/logo.ico new file mode 100644 index 00000000..b40e7866 Binary files /dev/null and b/resource/logo.ico differ diff --git a/resource/logo.png b/resource/logo.png new file mode 100644 index 00000000..f53fe30c Binary files /dev/null and b/resource/logo.png differ diff --git a/resources.qrc b/resources.qrc index 51f3693a..bc9f322e 100644 --- a/resources.qrc +++ b/resources.qrc @@ -1,6 +1,6 @@ resource/fonts/Ace-Attorney.ttf - logo.png + resource/logo.png diff --git a/src/aoapplication.cpp b/src/aoapplication.cpp new file mode 100644 index 00000000..d7c3e662 --- /dev/null +++ b/src/aoapplication.cpp @@ -0,0 +1,187 @@ +#include "aoapplication.h" + +#include "lobby.h" +#include "courtroom.h" +#include "networkmanager.h" +#include "debug_functions.h" + +#include "aooptionsdialog.h" +#include "aocaseannouncerdialog.h" + +AOApplication::AOApplication(int &argc, char **argv) : QApplication(argc, argv) +{ + // Create the QSettings class that points to the config.ini. + configini = new QSettings(get_base_path() + "config.ini", QSettings::IniFormat); + + net_manager = new NetworkManager(this); + discord = new AttorneyOnline::Discord(); + QObject::connect(net_manager, SIGNAL(ms_connect_finished(bool, bool)), + SLOT(ms_connect_finished(bool, bool))); +} + +AOApplication::~AOApplication() +{ + destruct_lobby(); + destruct_courtroom(); + delete discord; +} + +void AOApplication::construct_lobby() +{ + if (lobby_constructed) + { + qDebug() << "W: lobby was attempted constructed when it already exists"; + return; + } + + w_lobby = new Lobby(this); + lobby_constructed = true; + + QRect screenGeometry = QApplication::desktop()->screenGeometry(); + int x = (screenGeometry.width()-w_lobby->width()) / 2; + int y = (screenGeometry.height()-w_lobby->height()) / 2; + w_lobby->move(x, y); + + if (is_discord_enabled()) + discord->state_lobby(); + + w_lobby->show(); +} + +void AOApplication::destruct_lobby() +{ + if(!lobby_constructed) + { + qDebug() << "W: lobby was attempted destructed when it did not exist"; + return; + } + + delete w_lobby; + w_lobby = nullptr; + lobby_constructed = false; +} + +void AOApplication::construct_courtroom() +{ + if (courtroom_constructed) + { + qDebug() << "W: courtroom was attempted constructed when it already exists"; + return; + } + + w_courtroom = new Courtroom(this); + courtroom_constructed = true; + + QRect screenGeometry = QApplication::desktop()->screenGeometry(); + int x = (screenGeometry.width()-w_courtroom->width()) / 2; + int y = (screenGeometry.height()-w_courtroom->height()) / 2; + w_courtroom->move(x, y); +} + +void AOApplication::destruct_courtroom() +{ + if (!courtroom_constructed) + { + qDebug() << "W: courtroom was attempted destructed when it did not exist"; + return; + } + + delete w_courtroom; + w_courtroom = nullptr; + courtroom_constructed = false; +} + +QString AOApplication::get_version_string() +{ + return + QString::number(RELEASE) + "." + + QString::number(MAJOR_VERSION) + "." + + QString::number(MINOR_VERSION); +} + +void AOApplication::reload_theme() +{ + current_theme = read_theme(); +} + +void AOApplication::set_favorite_list() +{ + favorite_list = read_serverlist_txt(); +} + +QString AOApplication::get_current_char() +{ + if (courtroom_constructed) + return w_courtroom->get_current_char(); + else + return ""; +} + +void AOApplication::add_favorite_server(int p_server) +{ + if (p_server < 0 || p_server >= server_list.size()) + return; + + server_type fav_server = server_list.at(p_server); + + QString str_port = QString::number(fav_server.port); + + QString server_line = fav_server.ip + ":" + str_port + ":" + fav_server.name; + + write_to_serverlist_txt(server_line); +} + +void AOApplication::server_disconnected() +{ + if (courtroom_constructed) + { + call_notice("Disconnected from server."); + construct_lobby(); + destruct_courtroom(); + } +} + +void AOApplication::loading_cancelled() +{ + destruct_courtroom(); + + w_lobby->hide_loading_overlay(); +} + +void AOApplication::ms_connect_finished(bool connected, bool will_retry) +{ + if (connected) + { + AOPacket *f_packet = new AOPacket("ALL#%"); + send_ms_packet(f_packet); + } + else + { + if (will_retry) + { + if (lobby_constructed) + w_lobby->append_error("Error connecting to master server. Will try again in " + + QString::number(net_manager->ms_reconnect_delay_ms / 1000.f) + " seconds."); + } + else + { + call_error("There was an error connecting to the master server.\n" + "We deploy multiple master servers to mitigate any possible downtime, " + "but the client appears to have exhausted all possible methods of finding " + "and connecting to one.\n" + "Please check your Internet connection and firewall, and please try again."); + } + } +} + +void AOApplication::call_settings_menu() +{ + AOOptionsDialog settings(nullptr, this); + settings.exec(); +} + +void AOApplication::call_announce_menu(Courtroom *court) +{ + AOCaseAnnouncerDialog announcer(nullptr, this, court); + announcer.exec(); +} diff --git a/src/aoblipplayer.cpp b/src/aoblipplayer.cpp new file mode 100644 index 00000000..74757c50 --- /dev/null +++ b/src/aoblipplayer.cpp @@ -0,0 +1,47 @@ +#include "aoblipplayer.h" + +AOBlipPlayer::AOBlipPlayer(QWidget *parent, AOApplication *p_ao_app) +{ + m_parent = parent; + ao_app = p_ao_app; +} + +void AOBlipPlayer::set_blips(QString p_sfx) +{ + QString f_path = ao_app->get_sounds_path(p_sfx); + + for (int n_stream = 0 ; n_stream < 5 ; ++n_stream) + { + BASS_StreamFree(m_stream_list[n_stream]); + + m_stream_list[n_stream] = BASS_StreamCreateFile(FALSE, f_path.utf16(), 0, 0, BASS_UNICODE | BASS_ASYNCFILE); + } + + set_volume(m_volume); +} + +void AOBlipPlayer::blip_tick() +{ + int f_cycle = m_cycle++; + + if (m_cycle == 5) + m_cycle = 0; + + HSTREAM f_stream = m_stream_list[f_cycle]; + + if (ao_app->get_audio_output_device() != "default") + BASS_ChannelSetDevice(f_stream, BASS_GetDevice()); + BASS_ChannelPlay(f_stream, false); +} + +void AOBlipPlayer::set_volume(int p_value) +{ + m_volume = p_value; + + float volume = p_value / 100.0f; + + for (int n_stream = 0 ; n_stream < 5 ; ++n_stream) + { + BASS_ChannelSetAttribute(m_stream_list[n_stream], BASS_ATTRIB_VOL, volume); + } +} diff --git a/src/aobutton.cpp b/src/aobutton.cpp new file mode 100644 index 00000000..5be2e678 --- /dev/null +++ b/src/aobutton.cpp @@ -0,0 +1,26 @@ +#include "aobutton.h" + +#include "debug_functions.h" +#include "file_functions.h" + +AOButton::AOButton(QWidget *parent, AOApplication *p_ao_app) : QPushButton(parent) +{ + ao_app = p_ao_app; +} + +AOButton::~AOButton() +{ + +} + +void AOButton::set_image(QString p_image) +{ + QString image_path = ao_app->get_theme_path(p_image); + QString default_image_path = ao_app->get_default_theme_path(p_image); + + if (file_exists(image_path)) + this->setStyleSheet("border-image:url(\"" + image_path + "\")"); + else + this->setStyleSheet("border-image:url(\"" + default_image_path + "\")"); +} + diff --git a/src/aocaseannouncerdialog.cpp b/src/aocaseannouncerdialog.cpp new file mode 100644 index 00000000..5b82b64f --- /dev/null +++ b/src/aocaseannouncerdialog.cpp @@ -0,0 +1,82 @@ +#include "aocaseannouncerdialog.h" + +AOCaseAnnouncerDialog::AOCaseAnnouncerDialog(QWidget *parent, AOApplication *p_ao_app, Courtroom *p_court) + : QDialog(parent) +{ + ao_app = p_ao_app; + court = p_court; + + setWindowTitle(tr("Case Announcer")); + resize(405, 235); + + ui_announcer_buttons = new QDialogButtonBox(this); + + QSizePolicy sizepolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); + sizepolicy.setHorizontalStretch(0); + sizepolicy.setVerticalStretch(0); + sizepolicy.setHeightForWidth(ui_announcer_buttons->sizePolicy().hasHeightForWidth()); + ui_announcer_buttons->setSizePolicy(sizepolicy); + ui_announcer_buttons->setOrientation(Qt::Horizontal); + ui_announcer_buttons->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); + + QObject::connect(ui_announcer_buttons, SIGNAL(accepted()), this, SLOT(ok_pressed())); + QObject::connect(ui_announcer_buttons, SIGNAL(rejected()), this, SLOT(cancel_pressed())); + + setUpdatesEnabled(false); + + ui_vbox_layout = new QVBoxLayout(this); + + ui_form_layout = new QFormLayout(this); + ui_form_layout->setLabelAlignment(Qt::AlignLeading | Qt::AlignLeft | Qt::AlignVCenter); + ui_form_layout->setFormAlignment(Qt::AlignLeading | Qt::AlignLeft | Qt::AlignTop); + ui_form_layout->setContentsMargins(6, 6, 6, 6); + + ui_vbox_layout->addItem(ui_form_layout); + ui_vbox_layout->addWidget(ui_announcer_buttons); + + ui_case_title_label = new QLabel(this); + ui_case_title_label->setText(tr("Case title:")); + + ui_form_layout->setWidget(0, QFormLayout::LabelRole, ui_case_title_label); + + ui_case_title_textbox = new QLineEdit(this); + ui_case_title_textbox->setMaxLength(50); + + ui_form_layout->setWidget(0, QFormLayout::FieldRole, ui_case_title_textbox); + + ui_defense_needed = new QCheckBox(this); + ui_defense_needed->setText(tr("Defense needed")); + ui_prosecutor_needed = new QCheckBox(this); + ui_prosecutor_needed->setText(tr("Prosecution needed")); + ui_judge_needed = new QCheckBox(this); + ui_judge_needed->setText(tr("Judge needed")); + ui_juror_needed = new QCheckBox(this); + ui_juror_needed->setText(tr("Jurors needed")); + ui_steno_needed = new QCheckBox(this); + ui_steno_needed->setText(tr("Stenographer needed")); + + ui_form_layout->setWidget(1, QFormLayout::FieldRole, ui_defense_needed); + ui_form_layout->setWidget(2, QFormLayout::FieldRole, ui_prosecutor_needed); + ui_form_layout->setWidget(3, QFormLayout::FieldRole, ui_judge_needed); + ui_form_layout->setWidget(4, QFormLayout::FieldRole, ui_juror_needed); + ui_form_layout->setWidget(5, QFormLayout::FieldRole, ui_steno_needed); + + setUpdatesEnabled(true); +} + +void AOCaseAnnouncerDialog::ok_pressed() +{ + court->announce_case(ui_case_title_textbox->text(), + ui_defense_needed->isChecked(), + ui_prosecutor_needed->isChecked(), + ui_judge_needed->isChecked(), + ui_juror_needed->isChecked(), + ui_steno_needed->isChecked()); + + done(0); +} + +void AOCaseAnnouncerDialog::cancel_pressed() +{ + done(0); +} diff --git a/src/aocharbutton.cpp b/src/aocharbutton.cpp new file mode 100644 index 00000000..76610270 --- /dev/null +++ b/src/aocharbutton.cpp @@ -0,0 +1,97 @@ +#include "aocharbutton.h" + +#include "file_functions.h" + +AOCharButton::AOCharButton(QWidget *parent, AOApplication *p_ao_app, int x_pos, int y_pos, bool is_taken) : QPushButton(parent) +{ + m_parent = parent; + + ao_app = p_ao_app; + + taken = is_taken; + + this->resize(60, 60); + this->move(x_pos, y_pos); + + ui_taken = new AOImage(this, ao_app); + ui_taken->resize(60, 60); + ui_taken->set_image("char_taken.png"); + ui_taken->setAttribute(Qt::WA_TransparentForMouseEvents); + ui_taken->hide(); + + ui_passworded = new AOImage(this, ao_app); + 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->resize(62, 62); + ui_selector->move(x_pos - 1, y_pos - 1); + ui_selector->set_image("char_selector.png"); + ui_selector->setAttribute(Qt::WA_TransparentForMouseEvents); + ui_selector->hide(); +} + +void AOCharButton::reset() +{ + ui_taken->hide(); + ui_passworded->hide(); + ui_selector->hide(); +} + +void AOCharButton::set_taken(bool is_taken) +{ + taken = is_taken; +} + +void AOCharButton::apply_taken_image() +{ + if (taken) + { + ui_taken->move(0,0); + ui_taken->show(); + } + else + { + ui_taken->hide(); + } +} + +void AOCharButton::set_passworded() +{ + ui_passworded->show(); +} + +void AOCharButton::set_image(QString p_character) +{ + QString image_path = ao_app->get_character_path(p_character, "char_icon.png"); + + this->setText(""); + + if (file_exists(image_path)) + this->setStyleSheet("border-image:url(\"" + image_path + "\")"); + else + { + this->setStyleSheet("border-image:url()"); + this->setText(p_character); + } +} + +void AOCharButton::enterEvent(QEvent * e) +{ + ui_selector->move(this->x() - 1, this->y() - 1); + ui_selector->raise(); + ui_selector->show(); + + setFlat(false); + QPushButton::enterEvent(e); +} + +void AOCharButton::leaveEvent(QEvent * e) +{ + ui_selector->hide(); + QPushButton::leaveEvent(e); +} + + diff --git a/src/aocharmovie.cpp b/src/aocharmovie.cpp new file mode 100644 index 00000000..57487233 --- /dev/null +++ b/src/aocharmovie.cpp @@ -0,0 +1,195 @@ +#include "aocharmovie.h" + +#include "misc_functions.h" +#include "file_functions.h" +#include "aoapplication.h" + +AOCharMovie::AOCharMovie(QWidget *p_parent, AOApplication *p_ao_app) : QLabel(p_parent) +{ + ao_app = p_ao_app; + + m_movie = new QMovie(this); + + preanim_timer = new QTimer(this); + preanim_timer->setSingleShot(true); + + connect(m_movie, SIGNAL(frameChanged(int)), this, SLOT(frame_change(int))); + connect(preanim_timer, SIGNAL(timeout()), this, SLOT(timer_done())); +} + +void AOCharMovie::play(QString p_char, QString p_emote, QString emote_prefix) +{ + QString original_path = ao_app->get_character_path(p_char, emote_prefix + p_emote + ".gif"); + QString alt_path = ao_app->get_character_path(p_char, p_emote + ".png"); + QString apng_path = ao_app->get_character_path(p_char, emote_prefix + p_emote + ".apng"); + QString placeholder_path = ao_app->get_theme_path("placeholder.gif"); + QString placeholder_default_path = ao_app->get_default_theme_path("placeholder.gif"); + QString gif_path; + + if (file_exists(apng_path)) + gif_path = apng_path; + else if (file_exists(original_path)) + gif_path = original_path; + else if (file_exists(alt_path)) + gif_path = alt_path; + else if (file_exists(placeholder_path)) + gif_path = placeholder_path; + else + gif_path = placeholder_default_path; + + m_movie->stop(); + m_movie->setFileName(gif_path); + + QImageReader *reader = new QImageReader(gif_path); + + movie_frames.clear(); + QImage f_image = reader->read(); + while (!f_image.isNull()) + { + if (m_flipped) + movie_frames.append(f_image.mirrored(true, false)); + else + movie_frames.append(f_image); + f_image = reader->read(); + } + + delete reader; + + this->show(); + m_movie->start(); +} + +void AOCharMovie::play_pre(QString p_char, QString p_emote, int duration) +{ + QString gif_path = ao_app->get_character_path(p_char, p_emote); + + m_movie->stop(); + this->clear(); + m_movie->setFileName(gif_path); + m_movie->jumpToFrame(0); + + int full_duration = duration * time_mod; + int real_duration = 0; + + play_once = false; + + for (int n_frame = 0 ; n_frame < m_movie->frameCount() ; ++n_frame) + { + real_duration += m_movie->nextFrameDelay(); + m_movie->jumpToFrame(n_frame + 1); + } + +#ifdef DEBUG_GIF + qDebug() << "full_duration: " << full_duration; + qDebug() << "real_duration: " << real_duration; +#endif + + double percentage_modifier = 100.0; + + if (real_duration != 0 && duration != 0) + { + double modifier = full_duration / static_cast(real_duration); + percentage_modifier = 100 / modifier; + + if (percentage_modifier > 100.0) + percentage_modifier = 100.0; + } + +#ifdef DEBUG_GIF + qDebug() << "% mod: " << percentage_modifier; +#endif + + if (full_duration == 0 || full_duration >= real_duration) + { + play_once = true; + } + else + { + play_once = false; + preanim_timer->start(full_duration); + } + + + m_movie->setSpeed(static_cast(percentage_modifier)); + play(p_char, p_emote, ""); +} + +void AOCharMovie::play_talking(QString p_char, QString p_emote) +{ + QString gif_path = ao_app->get_character_path(p_char, "(b)" + p_emote); + + m_movie->stop(); + this->clear(); + m_movie->setFileName(gif_path); + + play_once = false; + m_movie->setSpeed(100); + play(p_char, p_emote, "(b)"); +} + +void AOCharMovie::play_idle(QString p_char, QString p_emote) +{ + QString gif_path = ao_app->get_character_path(p_char, "(a)" + p_emote); + + m_movie->stop(); + this->clear(); + m_movie->setFileName(gif_path); + + play_once = false; + m_movie->setSpeed(100); + play(p_char, p_emote, "(a)"); +} + +void AOCharMovie::stop() +{ + //for all intents and purposes, stopping is the same as hiding. at no point do we want a frozen gif to display + m_movie->stop(); + preanim_timer->stop(); + this->hide(); +} + +void AOCharMovie::combo_resize(int w, int h) +{ + QSize f_size(w, h); + this->resize(f_size); + m_movie->setScaledSize(f_size); +} + +void AOCharMovie::move(int ax, int ay) +{ + x = ax; + y = ay; + QLabel::move(x, y); +} + +void AOCharMovie::frame_change(int n_frame) +{ + + if (movie_frames.size() > n_frame) + { + QPixmap f_pixmap = QPixmap::fromImage(movie_frames.at(n_frame)); + auto aspect_ratio = Qt::KeepAspectRatio; + + if (f_pixmap.size().width() > f_pixmap.size().height()) + aspect_ratio = Qt::KeepAspectRatioByExpanding; + + if (f_pixmap.size().width() > this->size().width() || f_pixmap.size().height() > this->size().height()) + this->setPixmap(f_pixmap.scaled(this->width(), this->height(), aspect_ratio, Qt::SmoothTransformation)); + else + this->setPixmap(f_pixmap.scaled(this->width(), this->height(), aspect_ratio, Qt::FastTransformation)); + + QLabel::move(x + (this->width() - this->pixmap()->width())/2, y); + } + + if (m_movie->frameCount() - 1 == n_frame && play_once) + { + preanim_timer->start(m_movie->nextFrameDelay()); + m_movie->stop(); + } +} + +void AOCharMovie::timer_done() +{ + + done(); +} diff --git a/src/aoemotebutton.cpp b/src/aoemotebutton.cpp new file mode 100644 index 00000000..9c1d3889 --- /dev/null +++ b/src/aoemotebutton.cpp @@ -0,0 +1,36 @@ +#include "aoemotebutton.h" + +#include "file_functions.h" + +AOEmoteButton::AOEmoteButton(QWidget *p_parent, AOApplication *p_ao_app, int p_x, int p_y) : QPushButton(p_parent) +{ + parent = p_parent; + ao_app = p_ao_app; + + this->move(p_x, p_y); + this->resize(40, 40); + + connect(this, SIGNAL(clicked()), this, SLOT(on_clicked())); +} + +void AOEmoteButton::set_image(QString p_char, int p_emote, QString suffix) +{ + QString emotion_number = QString::number(p_emote + 1); + QString image_path = ao_app->get_character_path(p_char, "emotions/button" + emotion_number + suffix); + + if (file_exists(image_path)) + { + this->setText(""); + this->setStyleSheet("border-image:url(\"" + image_path + "\")"); + } + else + { + this->setText(ao_app->get_emote_comment(p_char, p_emote)); + this->setStyleSheet("border-image:url(\"\")"); + } +} + +void AOEmoteButton::on_clicked() +{ + emote_clicked(m_id); +} diff --git a/src/aoevidencebutton.cpp b/src/aoevidencebutton.cpp new file mode 100644 index 00000000..924aeb88 --- /dev/null +++ b/src/aoevidencebutton.cpp @@ -0,0 +1,119 @@ +#include "aoevidencebutton.h" + +#include "file_functions.h" + +AOEvidenceButton::AOEvidenceButton(QWidget *p_parent, AOApplication *p_ao_app, int p_x, int p_y) : QPushButton(p_parent) +{ + ao_app = p_ao_app; + m_parent = p_parent; + + ui_selected = new AOImage(p_parent, ao_app); + ui_selected->resize(70, 70); + ui_selected->move(p_x, p_y); + ui_selected->set_image("evidence_selected.png"); + ui_selected->setAttribute(Qt::WA_TransparentForMouseEvents); + ui_selected->hide(); + + ui_selector = new AOImage(p_parent, ao_app); + ui_selector->resize(71, 71); + ui_selector->move(p_x - 1, p_y - 1); + ui_selector->set_image("evidence_selector.png"); + ui_selector->setAttribute(Qt::WA_TransparentForMouseEvents); + ui_selector->hide(); + + this->move(p_x, p_y); + this->resize(70, 70); + this->setAcceptDrops(true); + + connect(this, SIGNAL(clicked()), this, SLOT(on_clicked())); +} + +void AOEvidenceButton::reset() +{ + this->hide(); + ui_selected->hide(); + ui_selector->hide(); +} + +void AOEvidenceButton::set_image(QString p_image) +{ + QString image_path = ao_app->get_evidence_path(p_image); + + if (file_exists(image_path)) + { + this->setText(""); + this->setStyleSheet("border-image:url(\"" + image_path + "\")"); + } + else + { + this->setText(p_image); + this->setStyleSheet(""); + } +} + +void AOEvidenceButton::set_theme_image(QString p_image) +{ + QString theme_image_path = ao_app->get_theme_path(p_image); + QString default_image_path = ao_app->get_default_theme_path(p_image); + + QString final_image_path; + + if (file_exists(theme_image_path)) + final_image_path = theme_image_path; + else + final_image_path = default_image_path; + + this->setText(""); + this->setStyleSheet("border-image:url(\"" + final_image_path + "\")"); +} + +void AOEvidenceButton::set_selected(bool p_selected) +{ + if (p_selected) + ui_selected->show(); + else + ui_selected->hide(); +} + +void AOEvidenceButton::on_clicked() +{ + evidence_clicked(m_id); +} + +void AOEvidenceButton::mouseDoubleClickEvent(QMouseEvent *e) +{ + QPushButton::mouseDoubleClickEvent(e); + evidence_double_clicked(m_id); +} + +void AOEvidenceButton::dragLeaveEvent(QMouseEvent *e) +{ + //QWidget::dragLeaveEvent(e); + + qDebug() << "drag leave event"; +} + +void AOEvidenceButton::dragEnterEvent(QMouseEvent *e) +{ + //QWidget::dragEnterEvent(e); + + qDebug() << "drag enter event"; +} + +void AOEvidenceButton::enterEvent(QEvent * e) +{ + ui_selector->show(); + + on_hover(m_id, true); + + setFlat(false); + QPushButton::enterEvent(e); +} + +void AOEvidenceButton::leaveEvent(QEvent * e) +{ + ui_selector->hide(); + + on_hover(m_id, false); + QPushButton::leaveEvent(e); +} diff --git a/src/aoevidencedisplay.cpp b/src/aoevidencedisplay.cpp new file mode 100644 index 00000000..9ec105dd --- /dev/null +++ b/src/aoevidencedisplay.cpp @@ -0,0 +1,96 @@ +#include "aoevidencedisplay.h" + +#include "file_functions.h" +#include "datatypes.h" +#include "misc_functions.h" + +AOEvidenceDisplay::AOEvidenceDisplay(QWidget *p_parent, AOApplication *p_ao_app) : QLabel(p_parent) +{ + ao_app = p_ao_app; + + evidence_movie = new QMovie(this); + evidence_icon = new QLabel(this); + sfx_player = new AOSfxPlayer(this, ao_app); + + connect(evidence_movie, SIGNAL(frameChanged(int)), this, SLOT(frame_change(int))); +} + +void AOEvidenceDisplay::show_evidence(QString p_evidence_image, bool is_left_side, int p_volume) +{ + this->reset(); + + sfx_player->set_volume(p_volume); + + QString f_evidence_path = ao_app->get_evidence_path(p_evidence_image); + + QPixmap f_pixmap(f_evidence_path); + + QString final_gif_path; + QString gif_name; + QString icon_identifier; + + if (is_left_side) + { + icon_identifier = "left_evidence_icon"; + gif_name = "evidence_appear_left.gif"; + } + else + { + icon_identifier = "right_evidence_icon"; + gif_name = "evidence_appear_right.gif"; + } + + pos_size_type icon_dimensions = ao_app->get_element_dimensions(icon_identifier, "courtroom_design.ini"); + + evidence_icon->move(icon_dimensions.x, icon_dimensions.y); + evidence_icon->resize(icon_dimensions.width, icon_dimensions.height); + + evidence_icon->setPixmap(f_pixmap.scaled(evidence_icon->width(), evidence_icon->height(), Qt::IgnoreAspectRatio)); + + QString f_default_gif_path = ao_app->get_default_theme_path(gif_name); + QString f_gif_path = ao_app->get_theme_path(gif_name); + + if (file_exists(f_gif_path)) + final_gif_path = f_gif_path; + else + final_gif_path = f_default_gif_path; + + evidence_movie->setFileName(final_gif_path); + + if(evidence_movie->frameCount() < 1) + return; + + this->setMovie(evidence_movie); + + evidence_movie->start(); + sfx_player->play(ao_app->get_sfx("evidence_present")); +} + +void AOEvidenceDisplay::frame_change(int p_frame) +{ + if (p_frame == (evidence_movie->frameCount() - 1)) + { + //we need this or else the last frame wont show + delay(evidence_movie->nextFrameDelay()); + + evidence_movie->stop(); + this->clear(); + + evidence_icon->show(); + } +} + +void AOEvidenceDisplay::reset() +{ + sfx_player->stop(); + evidence_movie->stop(); + evidence_icon->hide(); + this->clear(); +} + +QLabel* AOEvidenceDisplay::get_evidence_icon() +{ + return evidence_icon; +} + + diff --git a/src/aoimage.cpp b/src/aoimage.cpp new file mode 100644 index 00000000..7bb56bb6 --- /dev/null +++ b/src/aoimage.cpp @@ -0,0 +1,47 @@ +#include "file_functions.h" + +#include "aoimage.h" + +AOImage::AOImage(QWidget *parent, AOApplication *p_ao_app) : QLabel(parent) +{ + m_parent = parent; + ao_app = p_ao_app; +} + +AOImage::~AOImage() +{ + +} + +void AOImage::set_image(QString p_image) +{ + QString theme_image_path = ao_app->get_theme_path(p_image); + QString default_image_path = ao_app->get_default_theme_path(p_image); + + QString final_image_path; + + if (file_exists(theme_image_path)) + final_image_path = theme_image_path; + else + final_image_path = default_image_path; + + QPixmap f_pixmap(final_image_path); + + this->setPixmap(f_pixmap.scaled(this->width(), this->height(), Qt::IgnoreAspectRatio)); +} + +void AOImage::set_image_from_path(QString p_path) +{ + QString default_path = ao_app->get_default_theme_path("chatmed.png"); + + QString final_path; + + if (file_exists(p_path)) + final_path = p_path; + else + final_path = default_path; + + QPixmap f_pixmap(final_path); + + this->setPixmap(f_pixmap.scaled(this->width(), this->height(), Qt::IgnoreAspectRatio)); +} diff --git a/src/aolineedit.cpp b/src/aolineedit.cpp new file mode 100644 index 00000000..f6026e14 --- /dev/null +++ b/src/aolineedit.cpp @@ -0,0 +1,21 @@ +#include "aolineedit.h" + +AOLineEdit::AOLineEdit(QWidget *parent) : QLineEdit(parent) +{ + this->setReadOnly(true); + this->setFrame(false); + + connect(this, SIGNAL(returnPressed()), this, SLOT(on_enter_pressed())); +} + +void AOLineEdit::mouseDoubleClickEvent(QMouseEvent *e) +{ + QLineEdit::mouseDoubleClickEvent(e); + + this->setReadOnly(false); +} + +void AOLineEdit::on_enter_pressed() +{ + this->setReadOnly(true); +} diff --git a/src/aomovie.cpp b/src/aomovie.cpp new file mode 100644 index 00000000..edf5bdb0 --- /dev/null +++ b/src/aomovie.cpp @@ -0,0 +1,90 @@ +#include "aomovie.h" + +#include "file_functions.h" +#include "courtroom.h" +#include "misc_functions.h" + +AOMovie::AOMovie(QWidget *p_parent, AOApplication *p_ao_app) : QLabel(p_parent) +{ + ao_app = p_ao_app; + + m_movie = new QMovie(); + + this->setMovie(m_movie); + + connect(m_movie, SIGNAL(frameChanged(int)), this, SLOT(frame_change(int))); +} + +void AOMovie::set_play_once(bool p_play_once) +{ + play_once = p_play_once; +} + +void AOMovie::play(QString p_gif, QString p_char, QString p_custom_theme) +{ + m_movie->stop(); + + QString gif_path; + + QString custom_path; + if (p_gif == "custom") + custom_path = ao_app->get_image_suffix(ao_app->get_character_path(p_char, p_gif)); + else + custom_path = ao_app->get_image_suffix(ao_app->get_character_path(p_char, p_gif + "_bubble")); + + QString misc_path = ao_app->get_base_path() + "misc/" + p_custom_theme + "/" + p_gif + "_bubble.gif"; + QString custom_theme_path = ao_app->get_custom_theme_path(p_custom_theme, p_gif + ".gif"); + QString theme_path = ao_app->get_theme_path(p_gif + ".gif"); + QString default_theme_path = ao_app->get_default_theme_path(p_gif + ".gif"); + QString placeholder_path = ao_app->get_theme_path("placeholder.gif"); + QString default_placeholder_path = ao_app->get_default_theme_path("placeholder.gif"); + + if (file_exists(custom_path)) + gif_path = custom_path; + else if (file_exists(misc_path)) + gif_path = misc_path; + else if (file_exists(custom_theme_path)) + gif_path = custom_theme_path; + else if (file_exists(theme_path)) + gif_path = theme_path; + else if (file_exists(default_theme_path)) + gif_path = default_theme_path; + else if (file_exists(placeholder_path)) + gif_path = placeholder_path; + else if (file_exists(default_placeholder_path)) + gif_path = default_placeholder_path; + else + gif_path = ""; + + m_movie->setFileName(gif_path); + + this->show(); + m_movie->start(); +} + +void AOMovie::stop() +{ + m_movie->stop(); + this->hide(); +} + +void AOMovie::frame_change(int n_frame) +{ + if (n_frame == (m_movie->frameCount() - 1) && play_once) + { + //we need this or else the last frame wont show + delay(m_movie->nextFrameDelay()); + + this->stop(); + + //signal connected to courtroom object, let it figure out what to do + done(); + } +} + +void AOMovie::combo_resize(int w, int h) +{ + QSize f_size(w, h); + this->resize(f_size); + m_movie->setScaledSize(f_size); +} diff --git a/src/aomusicplayer.cpp b/src/aomusicplayer.cpp new file mode 100644 index 00000000..997d82d8 --- /dev/null +++ b/src/aomusicplayer.cpp @@ -0,0 +1,34 @@ +#include "aomusicplayer.h" + +AOMusicPlayer::AOMusicPlayer(QWidget *parent, AOApplication *p_ao_app) +{ + m_parent = parent; + ao_app = p_ao_app; +} + +AOMusicPlayer::~AOMusicPlayer() +{ + BASS_ChannelStop(m_stream); +} + +void AOMusicPlayer::play(QString p_song) +{ + BASS_ChannelStop(m_stream); + + QString f_path = ao_app->get_music_path(p_song); + + m_stream = BASS_StreamCreateFile(FALSE, f_path.utf16(), 0, 0, BASS_STREAM_AUTOFREE | BASS_UNICODE | BASS_ASYNCFILE); + + this->set_volume(m_volume); + + if (ao_app->get_audio_output_device() != "default") + BASS_ChannelSetDevice(m_stream, BASS_GetDevice()); + BASS_ChannelPlay(m_stream, false); +} + +void AOMusicPlayer::set_volume(int p_value) +{ + m_volume = p_value; + float volume = m_volume / 100.0f; + BASS_ChannelSetAttribute(m_stream, BASS_ATTRIB_VOL, volume); +} diff --git a/src/aooptionsdialog.cpp b/src/aooptionsdialog.cpp new file mode 100644 index 00000000..2b8259f5 --- /dev/null +++ b/src/aooptionsdialog.cpp @@ -0,0 +1,517 @@ +#include "aooptionsdialog.h" +#include "aoapplication.h" +#include "bass.h" + +AOOptionsDialog::AOOptionsDialog(QWidget *parent, AOApplication *p_ao_app) : QDialog(parent) +{ + ao_app = p_ao_app; + + // Setting up the basics. + // setAttribute(Qt::WA_DeleteOnClose); + setWindowTitle(tr("Settings")); + resize(398, 320); + + ui_settings_buttons = new QDialogButtonBox(this); + + QSizePolicy sizePolicy1(QSizePolicy::Expanding, QSizePolicy::Fixed); + sizePolicy1.setHorizontalStretch(0); + sizePolicy1.setVerticalStretch(0); + sizePolicy1.setHeightForWidth(ui_settings_buttons->sizePolicy().hasHeightForWidth()); + ui_settings_buttons->setSizePolicy(sizePolicy1); + ui_settings_buttons->setOrientation(Qt::Horizontal); + ui_settings_buttons->setStandardButtons(QDialogButtonBox::Cancel | QDialogButtonBox::Save); + + QObject::connect(ui_settings_buttons, SIGNAL(accepted()), this, SLOT(save_pressed())); + QObject::connect(ui_settings_buttons, SIGNAL(rejected()), this, SLOT(discard_pressed())); + + // We'll stop updates so that the window won't flicker while it's being made. + setUpdatesEnabled(false); + + // First of all, we want a tabbed dialog, so let's add some layout. + ui_vertical_layout = new QVBoxLayout(this); + ui_settings_tabs = new QTabWidget(this); + + ui_vertical_layout->addWidget(ui_settings_tabs); + ui_vertical_layout->addWidget(ui_settings_buttons); + + // Let's add the tabs one by one. + // First, we'll start with 'Gameplay'. + ui_gameplay_tab = new QWidget(); + ui_settings_tabs->addTab(ui_gameplay_tab, tr("Gameplay")); + + ui_form_layout_widget = new QWidget(ui_gameplay_tab); + ui_form_layout_widget->setGeometry(QRect(10, 10, 361, 211)); + + ui_gameplay_form = new QFormLayout(ui_form_layout_widget); + ui_gameplay_form->setLabelAlignment(Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter); + ui_gameplay_form->setFormAlignment(Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop); + ui_gameplay_form->setContentsMargins(0, 0, 0, 0); + + ui_theme_label = new QLabel(ui_form_layout_widget); + ui_theme_label->setText(tr("Theme:")); + ui_theme_label->setToolTip(tr("Sets the theme used in-game. If the new theme changes " + "the lobby's look as well, you'll need to reload the " + "lobby for the changes to take effect, such as by joining " + "a server and leaving it.")); + ui_gameplay_form->setWidget(0, QFormLayout::LabelRole, ui_theme_label); + + ui_theme_combobox = new QComboBox(ui_form_layout_widget); + + // Fill the combobox with the names of the themes. + QDirIterator it(p_ao_app->get_base_path() + "themes", QDir::Dirs, QDirIterator::NoIteratorFlags); + while (it.hasNext()) + { + QString actualname = QDir(it.next()).dirName(); + if (actualname != "." && actualname != "..") + ui_theme_combobox->addItem(actualname); + if (actualname == p_ao_app->read_theme()) + ui_theme_combobox->setCurrentIndex(ui_theme_combobox->count()-1); + } + + ui_gameplay_form->setWidget(0, QFormLayout::FieldRole, ui_theme_combobox); + + ui_theme_log_divider = new QFrame(ui_form_layout_widget); + ui_theme_log_divider->setMidLineWidth(0); + ui_theme_log_divider->setFrameShape(QFrame::HLine); + ui_theme_log_divider->setFrameShadow(QFrame::Sunken); + + ui_gameplay_form->setWidget(1, QFormLayout::FieldRole, ui_theme_log_divider); + + ui_downwards_lbl = new QLabel(ui_form_layout_widget); + ui_downwards_lbl->setText(tr("Log goes downwards:")); + ui_downwards_lbl->setToolTip(tr("If ticked, new messages will appear at " + "the bottom (like the OOC chatlog). The traditional " + "(AO1) behaviour is equivalent to this being unticked.")); + + ui_gameplay_form->setWidget(2, QFormLayout::LabelRole, ui_downwards_lbl); + + ui_downwards_cb = new QCheckBox(ui_form_layout_widget); + ui_downwards_cb->setChecked(p_ao_app->get_log_goes_downwards()); + + ui_gameplay_form->setWidget(2, QFormLayout::FieldRole, ui_downwards_cb); + + ui_length_lbl = new QLabel(ui_form_layout_widget); + ui_length_lbl->setText(tr("Log length:")); + ui_length_lbl->setToolTip(tr("The amount of messages the IC chatlog will keep before " + "deleting older messages. A value of 0 or below counts as 'infinite'.")); + + ui_gameplay_form->setWidget(3, QFormLayout::LabelRole, ui_length_lbl); + + ui_length_spinbox = new QSpinBox(ui_form_layout_widget); + ui_length_spinbox->setMaximum(10000); + ui_length_spinbox->setValue(p_ao_app->get_max_log_size()); + + ui_gameplay_form->setWidget(3, QFormLayout::FieldRole, ui_length_spinbox); + + ui_log_names_divider = new QFrame(ui_form_layout_widget); + ui_log_names_divider->setFrameShape(QFrame::HLine); + ui_log_names_divider->setFrameShadow(QFrame::Sunken); + + ui_gameplay_form->setWidget(4, QFormLayout::FieldRole, ui_log_names_divider); + + ui_username_lbl = new QLabel(ui_form_layout_widget); + ui_username_lbl->setText(tr("Default username:")); + ui_username_lbl->setToolTip(tr("Your OOC name will be automatically set to this value " + "when you join a server.")); + + ui_gameplay_form->setWidget(5, QFormLayout::LabelRole, ui_username_lbl); + + ui_username_textbox = new QLineEdit(ui_form_layout_widget); + ui_username_textbox->setMaxLength(30); + ui_username_textbox->setText(p_ao_app->get_default_username()); + + ui_gameplay_form->setWidget(5, QFormLayout::FieldRole, ui_username_textbox); + + ui_showname_lbl = new QLabel(ui_form_layout_widget); + ui_showname_lbl->setText(tr("Custom shownames:")); + ui_showname_lbl->setToolTip(tr("Gives the default value for the in-game 'Custom shownames' " + "tickbox, which in turn determines whether the client should " + "display custom in-character names.")); + + ui_gameplay_form->setWidget(6, QFormLayout::LabelRole, ui_showname_lbl); + + ui_showname_cb = new QCheckBox(ui_form_layout_widget); + ui_showname_cb->setChecked(p_ao_app->get_showname_enabled_by_default()); + + ui_gameplay_form->setWidget(6, QFormLayout::FieldRole, ui_showname_cb); + + ui_net_divider = new QFrame(ui_form_layout_widget); + ui_net_divider->setFrameShape(QFrame::HLine); + ui_net_divider->setFrameShadow(QFrame::Sunken); + + ui_gameplay_form->setWidget(7, QFormLayout::FieldRole, ui_net_divider); + + ui_ms_lbl = new QLabel(ui_form_layout_widget); + ui_ms_lbl->setText(tr("Backup MS:")); + ui_ms_lbl->setToolTip(tr("If the built-in server lookups fail, the game will try the " + "address given here and use it as a backup master server address.")); + + ui_gameplay_form->setWidget(8, QFormLayout::LabelRole, ui_ms_lbl); + + QSettings* configini = ao_app->configini; + ui_ms_textbox = new QLineEdit(ui_form_layout_widget); + ui_ms_textbox->setText(configini->value("master", "").value()); + + ui_gameplay_form->setWidget(8, QFormLayout::FieldRole, ui_ms_textbox); + + ui_discord_lbl = new QLabel(ui_form_layout_widget); + ui_discord_lbl->setText(tr("Discord:")); + ui_discord_lbl->setToolTip(tr("Allows others on Discord to see what server you are in, " + "what character are you playing, and how long you have " + "been playing for.")); + + ui_gameplay_form->setWidget(9, QFormLayout::LabelRole, ui_discord_lbl); + + ui_discord_cb = new QCheckBox(ui_form_layout_widget); + ui_discord_cb->setChecked(ao_app->is_discord_enabled()); + + ui_gameplay_form->setWidget(9, QFormLayout::FieldRole, ui_discord_cb); + + // Here we start the callwords tab. + ui_callwords_tab = new QWidget(); + ui_settings_tabs->addTab(ui_callwords_tab, tr("Callwords")); + + ui_callwords_widget = new QWidget(ui_callwords_tab); + ui_callwords_widget->setGeometry(QRect(10, 10, 361, 211)); + + ui_callwords_layout = new QVBoxLayout(ui_callwords_widget); + ui_callwords_layout->setContentsMargins(0,0,0,0); + + ui_callwords_textbox = new QPlainTextEdit(ui_callwords_widget); + QSizePolicy sizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + sizePolicy.setHorizontalStretch(0); + sizePolicy.setVerticalStretch(0); + sizePolicy.setHeightForWidth(ui_callwords_textbox->sizePolicy().hasHeightForWidth()); + ui_callwords_textbox->setSizePolicy(sizePolicy); + + // Let's fill the callwords text edit with the already present callwords. + ui_callwords_textbox->document()->clear(); + foreach (QString callword, p_ao_app->get_call_words()) { + ui_callwords_textbox->appendPlainText(callword); + } + + ui_callwords_layout->addWidget(ui_callwords_textbox); + + ui_callwords_explain_lbl = new QLabel(ui_callwords_widget); + ui_callwords_explain_lbl->setWordWrap(true); + ui_callwords_explain_lbl->setText(tr("Enter as many callwords as you would like. These are case insensitive. Make sure to leave every callword in its own line!
Do not leave a line with a space at the end -- you will be alerted everytime someone uses a space in their messages.")); + + ui_callwords_layout->addWidget(ui_callwords_explain_lbl); + + // The audio tab. + ui_audio_tab = new QWidget(); + ui_settings_tabs->addTab(ui_audio_tab, tr("Audio")); + + ui_audio_widget = new QWidget(ui_audio_tab); + ui_audio_widget->setGeometry(QRect(10, 10, 361, 211)); + + ui_audio_layout = new QFormLayout(ui_audio_widget); + ui_audio_layout->setLabelAlignment(Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter); + ui_audio_layout->setFormAlignment(Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop); + ui_audio_layout->setContentsMargins(0, 0, 0, 0); + + ui_audio_device_lbl = new QLabel(ui_audio_widget); + ui_audio_device_lbl->setText(tr("Audio device:")); + ui_audio_device_lbl->setToolTip(tr("Sets the audio device for all sounds.")); + + ui_audio_layout->setWidget(0, QFormLayout::LabelRole, ui_audio_device_lbl); + + ui_audio_device_combobox = new QComboBox(ui_audio_widget); + + // Let's fill out the combobox with the available audio devices. + int a = 0; + BASS_DEVICEINFO info; + + if (needs_default_audiodev()) + { + ui_audio_device_combobox->addItem("default"); + } + + for (a = 0; BASS_GetDeviceInfo(a, &info); a++) + { + ui_audio_device_combobox->addItem(info.name); + if (p_ao_app->get_audio_output_device() == info.name) + ui_audio_device_combobox->setCurrentIndex(ui_audio_device_combobox->count()-1); + } + + ui_audio_layout->setWidget(0, QFormLayout::FieldRole, ui_audio_device_combobox); + + ui_audio_volume_divider = new QFrame(ui_audio_widget); + ui_audio_volume_divider->setFrameShape(QFrame::HLine); + ui_audio_volume_divider->setFrameShadow(QFrame::Sunken); + + ui_audio_layout->setWidget(1, QFormLayout::FieldRole, ui_audio_volume_divider); + + ui_music_volume_lbl = new QLabel(ui_audio_widget); + ui_music_volume_lbl->setText(tr("Music:")); + ui_music_volume_lbl->setToolTip(tr("Sets the music's default volume.")); + + ui_audio_layout->setWidget(2, QFormLayout::LabelRole, ui_music_volume_lbl); + + ui_music_volume_spinbox = new QSpinBox(ui_audio_widget); + ui_music_volume_spinbox->setValue(p_ao_app->get_default_music()); + ui_music_volume_spinbox->setMaximum(100); + ui_music_volume_spinbox->setSuffix("%"); + + ui_audio_layout->setWidget(2, QFormLayout::FieldRole, ui_music_volume_spinbox); + + ui_sfx_volume_lbl = new QLabel(ui_audio_widget); + ui_sfx_volume_lbl->setText(tr("SFX:")); + ui_sfx_volume_lbl->setToolTip(tr("Sets the SFX's default volume. " + "Interjections and actual sound effects count as 'SFX'.")); + + ui_audio_layout->setWidget(3, QFormLayout::LabelRole, ui_sfx_volume_lbl); + + ui_sfx_volume_spinbox = new QSpinBox(ui_audio_widget); + ui_sfx_volume_spinbox->setValue(p_ao_app->get_default_sfx()); + ui_sfx_volume_spinbox->setMaximum(100); + ui_sfx_volume_spinbox->setSuffix("%"); + + ui_audio_layout->setWidget(3, QFormLayout::FieldRole, ui_sfx_volume_spinbox); + + ui_blips_volume_lbl = new QLabel(ui_audio_widget); + ui_blips_volume_lbl->setText(tr("Blips:")); + ui_blips_volume_lbl->setToolTip(tr("Sets the volume of the blips, the talking sound effects.")); + + ui_audio_layout->setWidget(4, QFormLayout::LabelRole, ui_blips_volume_lbl); + + ui_blips_volume_spinbox = new QSpinBox(ui_audio_widget); + ui_blips_volume_spinbox->setValue(p_ao_app->get_default_blip()); + ui_blips_volume_spinbox->setMaximum(100); + ui_blips_volume_spinbox->setSuffix("%"); + + ui_audio_layout->setWidget(4, QFormLayout::FieldRole, ui_blips_volume_spinbox); + + ui_volume_blip_divider = new QFrame(ui_audio_widget); + ui_volume_blip_divider->setFrameShape(QFrame::HLine); + ui_volume_blip_divider->setFrameShadow(QFrame::Sunken); + + ui_audio_layout->setWidget(5, QFormLayout::FieldRole, ui_volume_blip_divider); + + ui_bliprate_lbl = new QLabel(ui_audio_widget); + ui_bliprate_lbl->setText(tr("Blip rate:")); + ui_bliprate_lbl->setToolTip(tr("Sets the delay between playing the blip sounds.")); + + ui_audio_layout->setWidget(6, QFormLayout::LabelRole, ui_bliprate_lbl); + + ui_bliprate_spinbox = new QSpinBox(ui_audio_widget); + ui_bliprate_spinbox->setValue(p_ao_app->read_blip_rate()); + ui_bliprate_spinbox->setMinimum(1); + + ui_audio_layout->setWidget(6, QFormLayout::FieldRole, ui_bliprate_spinbox); + + ui_blank_blips_lbl = new QLabel(ui_audio_widget); + ui_blank_blips_lbl->setText(tr("Blank blips:")); + ui_blank_blips_lbl->setToolTip(tr("If true, the game will play a blip sound even " + "when a space is 'being said'.")); + + ui_audio_layout->setWidget(7, QFormLayout::LabelRole, ui_blank_blips_lbl); + + ui_blank_blips_cb = new QCheckBox(ui_audio_widget); + ui_blank_blips_cb->setChecked(p_ao_app->get_blank_blip()); + + ui_audio_layout->setWidget(7, QFormLayout::FieldRole, ui_blank_blips_cb); + + // The casing tab! + ui_casing_tab = new QWidget(); + ui_settings_tabs->addTab(ui_casing_tab, tr("Casing")); + + ui_casing_widget = new QWidget(ui_casing_tab); + ui_casing_widget->setGeometry(QRect(10,10, 361, 211)); + + ui_casing_layout = new QFormLayout(ui_casing_widget); + ui_casing_layout->setLabelAlignment(Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter); + ui_casing_layout->setFormAlignment(Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop); + ui_casing_layout->setContentsMargins(0, 0, 0, 0); + + // -- SERVER SUPPORTS CASING + + ui_casing_supported_lbl = new QLabel(ui_casing_widget); + if (ao_app->casing_alerts_enabled) + ui_casing_supported_lbl->setText(tr("This server supports case alerts.")); + else + ui_casing_supported_lbl->setText(tr("This server does not support case alerts.")); + ui_casing_supported_lbl->setToolTip(tr("Pretty self-explanatory.")); + + ui_casing_layout->setWidget(0, QFormLayout::FieldRole, ui_casing_supported_lbl); + + // -- CASE ANNOUNCEMENTS + + ui_casing_enabled_lbl = new QLabel(ui_casing_widget); + ui_casing_enabled_lbl->setText(tr("Casing:")); + ui_casing_enabled_lbl->setToolTip(tr("If checked, you will get alerts about case " + "announcements.")); + + ui_casing_layout->setWidget(1, QFormLayout::LabelRole, ui_casing_enabled_lbl); + + ui_casing_enabled_cb = new QCheckBox(ui_casing_widget); + ui_casing_enabled_cb->setChecked(ao_app->get_casing_enabled()); + + ui_casing_layout->setWidget(1, QFormLayout::FieldRole, ui_casing_enabled_cb); + + // -- DEFENSE ANNOUNCEMENTS + + ui_casing_def_lbl = new QLabel(ui_casing_widget); + ui_casing_def_lbl->setText(tr("Defense:")); + ui_casing_def_lbl->setToolTip(tr("If checked, you will get alerts about case " + "announcements if a defense spot is open.")); + + ui_casing_layout->setWidget(2, QFormLayout::LabelRole, ui_casing_def_lbl); + + ui_casing_def_cb = new QCheckBox(ui_casing_widget); + ui_casing_def_cb->setChecked(ao_app->get_casing_defence_enabled()); + + ui_casing_layout->setWidget(2, QFormLayout::FieldRole, ui_casing_def_cb); + + // -- PROSECUTOR ANNOUNCEMENTS + + ui_casing_pro_lbl = new QLabel(ui_casing_widget); + ui_casing_pro_lbl->setText(tr("Prosecution:")); + ui_casing_pro_lbl->setToolTip(tr("If checked, you will get alerts about case " + "announcements if a prosecutor spot is open.")); + + ui_casing_layout->setWidget(3, QFormLayout::LabelRole, ui_casing_pro_lbl); + + ui_casing_pro_cb = new QCheckBox(ui_casing_widget); + ui_casing_pro_cb->setChecked(ao_app->get_casing_prosecution_enabled()); + + ui_casing_layout->setWidget(3, QFormLayout::FieldRole, ui_casing_pro_cb); + + // -- JUDGE ANNOUNCEMENTS + + ui_casing_jud_lbl = new QLabel(ui_casing_widget); + ui_casing_jud_lbl->setText(tr("Judge:")); + ui_casing_jud_lbl->setToolTip(tr("If checked, you will get alerts about case " + "announcements if the judge spot is open.")); + + ui_casing_layout->setWidget(4, QFormLayout::LabelRole, ui_casing_jud_lbl); + + ui_casing_jud_cb = new QCheckBox(ui_casing_widget); + ui_casing_jud_cb->setChecked(ao_app->get_casing_judge_enabled()); + + ui_casing_layout->setWidget(4, QFormLayout::FieldRole, ui_casing_jud_cb); + + // -- JUROR ANNOUNCEMENTS + + ui_casing_jur_lbl = new QLabel(ui_casing_widget); + ui_casing_jur_lbl->setText(tr("Juror:")); + ui_casing_jur_lbl->setToolTip(tr("If checked, you will get alerts about case " + "announcements if a juror spot is open.")); + + ui_casing_layout->setWidget(5, QFormLayout::LabelRole, ui_casing_jur_lbl); + + ui_casing_jur_cb = new QCheckBox(ui_casing_widget); + ui_casing_jur_cb->setChecked(ao_app->get_casing_juror_enabled()); + + ui_casing_layout->setWidget(5, QFormLayout::FieldRole, ui_casing_jur_cb); + + // -- STENO ANNOUNCEMENTS + + ui_casing_steno_lbl = new QLabel(ui_casing_widget); + ui_casing_steno_lbl->setText(tr("Stenographer:")); + ui_casing_steno_lbl->setToolTip(tr("If checked, you will get alerts about case " + "announcements if a stenographer spot is open.")); + + ui_casing_layout->setWidget(6, QFormLayout::LabelRole, ui_casing_steno_lbl); + + ui_casing_steno_cb = new QCheckBox(ui_casing_widget); + ui_casing_steno_cb->setChecked(ao_app->get_casing_steno_enabled()); + + ui_casing_layout->setWidget(6, QFormLayout::FieldRole, ui_casing_steno_cb); + + // -- CM ANNOUNCEMENTS + + ui_casing_cm_lbl = new QLabel(ui_casing_widget); + ui_casing_cm_lbl->setText(tr("CM:")); + ui_casing_cm_lbl->setToolTip(tr("If checked, you will appear amongst the potential " + "CMs on the server.")); + + ui_casing_layout->setWidget(7, QFormLayout::LabelRole, ui_casing_cm_lbl); + + ui_casing_cm_cb = new QCheckBox(ui_casing_widget); + ui_casing_cm_cb->setChecked(ao_app->get_casing_cm_enabled()); + + ui_casing_layout->setWidget(7, QFormLayout::FieldRole, ui_casing_cm_cb); + + // -- CM CASES ANNOUNCEMENTS + + ui_casing_cm_cases_lbl = new QLabel(ui_casing_widget); + ui_casing_cm_cases_lbl->setText(tr("Hosting cases:")); + ui_casing_cm_cases_lbl->setToolTip(tr("If you're a CM, enter what cases you are " + "willing to host.")); + + ui_casing_layout->setWidget(8, QFormLayout::LabelRole, ui_casing_cm_cases_lbl); + + ui_casing_cm_cases_textbox = new QLineEdit(ui_casing_widget); + ui_casing_cm_cases_textbox->setText(ao_app->get_casing_can_host_cases()); + + ui_casing_layout->setWidget(8, QFormLayout::FieldRole, ui_casing_cm_cases_textbox); + + // When we're done, we should continue the updates! + setUpdatesEnabled(true); +} + +void AOOptionsDialog::save_pressed() +{ + // Save everything into the config.ini. + QSettings* configini = ao_app->configini; + + configini->setValue("theme", ui_theme_combobox->currentText()); + configini->setValue("log_goes_downwards", ui_downwards_cb->isChecked()); + configini->setValue("log_maximum", ui_length_spinbox->value()); + configini->setValue("default_username", ui_username_textbox->text()); + configini->setValue("show_custom_shownames", ui_showname_cb->isChecked()); + configini->setValue("master", ui_ms_textbox->text()); + configini->setValue("discord", ui_discord_cb->isChecked()); + + QFile* callwordsini = new QFile(ao_app->get_base_path() + "callwords.ini"); + + if (!callwordsini->open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text)) + { + // Nevermind! + } + else + { + QTextStream out(callwordsini); + out << ui_callwords_textbox->toPlainText(); + callwordsini->close(); + } + + configini->setValue("default_audio_device", ui_audio_device_combobox->currentText()); + configini->setValue("default_music", ui_music_volume_spinbox->value()); + configini->setValue("default_sfx", ui_sfx_volume_spinbox->value()); + configini->setValue("default_blip", ui_blips_volume_spinbox->value()); + configini->setValue("blip_rate", ui_bliprate_spinbox->value()); + configini->setValue("blank_blip", ui_blank_blips_cb->isChecked()); + + configini->setValue("casing_enabled", ui_casing_enabled_cb->isChecked()); + configini->setValue("casing_defence_enabled", ui_casing_def_cb->isChecked()); + configini->setValue("casing_prosecution_enabled", ui_casing_pro_cb->isChecked()); + configini->setValue("casing_judge_enabled", ui_casing_jud_cb->isChecked()); + configini->setValue("casing_juror_enabled", ui_casing_jur_cb->isChecked()); + configini->setValue("casing_steno_enabled", ui_casing_steno_cb->isChecked()); + configini->setValue("casing_cm_enabled", ui_casing_cm_cb->isChecked()); + configini->setValue("casing_can_host_cases", ui_casing_cm_cases_textbox->text()); + + callwordsini->close(); + done(0); +} + +void AOOptionsDialog::discard_pressed() +{ + done(0); +} + +#if (defined (_WIN32) || defined (_WIN64)) +bool AOOptionsDialog::needs_default_audiodev() +{ + return true; +} +#elif (defined (LINUX) || defined (__linux__)) +bool AOOptionsDialog::needs_default_audiodev() +{ + return false; +} +#else +#error This operating system is not supported. +#endif diff --git a/src/aopacket.cpp b/src/aopacket.cpp new file mode 100644 index 00000000..b957efea --- /dev/null +++ b/src/aopacket.cpp @@ -0,0 +1,83 @@ +#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; +} + +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; +} + +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("#", "").replace("%", "").replace("$", "").replace("&", ""); + + m_contents.removeAt(n_element); + m_contents.insert(n_element, f_element); + } +} + +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("", "#").replace("", "%").replace("", "$").replace("", "&"); + + m_contents.removeAt(n_element); + m_contents.insert(n_element, f_element); + } +} + diff --git a/src/aoscene.cpp b/src/aoscene.cpp new file mode 100644 index 00000000..344522b6 --- /dev/null +++ b/src/aoscene.cpp @@ -0,0 +1,76 @@ +#include "aoscene.h" +#include "courtroom.h" +#include "file_functions.h" + +AOScene::AOScene(QWidget *parent, AOApplication *p_ao_app) : QLabel(parent) +{ + m_parent = parent; + ao_app = p_ao_app; + m_movie = new QMovie(this); +} + +void AOScene::set_image(QString p_image) +{ + QString background_path = ao_app->get_background_path(p_image + ".png"); + QString animated_background_path = ao_app->get_background_path(p_image + ".gif"); + QString default_path = ao_app->get_default_background_path(p_image + ".png"); + + QPixmap background(background_path); + QPixmap default_bg(default_path); + + int w = this->width(); + int h = this->height(); + + this->clear(); + this->setMovie(nullptr); + + m_movie->stop(); + m_movie->setFileName(animated_background_path); + m_movie->setScaledSize(QSize(w, h)); + + if (m_movie->isValid()) + { + this->setMovie(m_movie); + m_movie->start(); + } + else if (file_exists(background_path)) + { + this->setPixmap(background.scaled(w, h)); + } + else + { + this->setPixmap(default_bg.scaled(w, h)); + } +} + +void AOScene::set_legacy_desk(QString p_image) +{ + //vanilla desks vary in both width and height. in order to make that work with viewport rescaling, + //some INTENSE math is needed. + + QString desk_path = ao_app->get_background_path(p_image); + QString default_path = ao_app->get_default_background_path(p_image); + + QPixmap f_desk; + + if (file_exists(desk_path)) + f_desk.load(desk_path); + else + f_desk.load(default_path); + + int vp_width = m_parent->width(); + int vp_height = m_parent->height(); + + //double y_modifier = 147 / 192; + //double w_modifier = vp_width / 256; + double h_modifier = vp_height / 192; + + //int final_y = y_modifier * vp_height; + //int final_w = w_modifier * f_desk.width(); + int final_h = static_cast(h_modifier * f_desk.height()); + + //this->resize(final_w, final_h); + //this->setPixmap(f_desk.scaled(final_w, final_h)); + this->resize(vp_width, final_h); + this->setPixmap(f_desk.scaled(vp_width, final_h)); +} diff --git a/src/aosfxplayer.cpp b/src/aosfxplayer.cpp new file mode 100644 index 00000000..7fe7987b --- /dev/null +++ b/src/aosfxplayer.cpp @@ -0,0 +1,51 @@ +#include "aosfxplayer.h" +#include "file_functions.h" + +AOSfxPlayer::AOSfxPlayer(QWidget *parent, AOApplication *p_ao_app) +{ + m_parent = parent; + ao_app = p_ao_app; +} + +void AOSfxPlayer::play(QString p_sfx, QString p_char, QString shout) +{ + BASS_ChannelStop(m_stream); + + QString misc_path = ""; + QString char_path = ""; + QString sound_path = ao_app->get_sounds_path(p_sfx); + + if (shout != "") + misc_path = ao_app->get_base_path() + "misc/" + shout + "/" + p_sfx; + if (p_char != "") + char_path = ao_app->get_character_path(p_char, p_sfx); + + QString f_path; + + if (file_exists(char_path)) + f_path = char_path; + else if (file_exists(misc_path)) + f_path = misc_path; + else + f_path = sound_path; + + m_stream = BASS_StreamCreateFile(FALSE, f_path.utf16(), 0, 0, BASS_STREAM_AUTOFREE | BASS_UNICODE | BASS_ASYNCFILE); + + set_volume(m_volume); + + if (ao_app->get_audio_output_device() != "default") + BASS_ChannelSetDevice(m_stream, BASS_GetDevice()); + BASS_ChannelPlay(m_stream, false); +} + +void AOSfxPlayer::stop() +{ + BASS_ChannelStop(m_stream); +} + +void AOSfxPlayer::set_volume(int p_value) +{ + m_volume = p_value; + float volume = p_value / 100.0f; + BASS_ChannelSetAttribute(m_stream, BASS_ATTRIB_VOL, volume); +} diff --git a/src/aotextarea.cpp b/src/aotextarea.cpp new file mode 100644 index 00000000..5e146326 --- /dev/null +++ b/src/aotextarea.cpp @@ -0,0 +1,60 @@ +#include "aotextarea.h" + +AOTextArea::AOTextArea(QWidget *p_parent) : QTextBrowser(p_parent) +{ + +} + +void AOTextArea::append_chatmessage(QString p_name, QString p_message, QString p_colour) +{ + const QTextCursor old_cursor = this->textCursor(); + const int old_scrollbar_value = this->verticalScrollBar()->value(); + const bool is_scrolled_down = old_scrollbar_value == this->verticalScrollBar()->maximum(); + + this->moveCursor(QTextCursor::End); + + this->append(""); + this->insertHtml("" + p_name.toHtmlEscaped() + ": "); + + //cheap workarounds ahoy + p_message += " "; + QString result = p_message.toHtmlEscaped().replace("\n", "
").replace(omnis_dank_url_regex, "\\1" ); + + this->insertHtml(result); + + this->auto_scroll(old_cursor, old_scrollbar_value, is_scrolled_down); +} + +void AOTextArea::append_error(QString p_message) +{ + const QTextCursor old_cursor = this->textCursor(); + const int old_scrollbar_value = this->verticalScrollBar()->value(); + const bool is_scrolled_down = old_scrollbar_value == this->verticalScrollBar()->maximum(); + + this->moveCursor(QTextCursor::End); + + this->append(""); + + p_message += " "; + QString result = p_message.replace("\n", "
").replace(omnis_dank_url_regex, "\\1" ); + + this->insertHtml("" + result + ""); + + this->auto_scroll(old_cursor, old_scrollbar_value, is_scrolled_down); +} + +void AOTextArea::auto_scroll(QTextCursor old_cursor, int old_scrollbar_value, bool is_scrolled_down) +{ + if (old_cursor.hasSelection() || !is_scrolled_down) + { + // The user has selected text or scrolled away from the bottom: maintain position. + this->setTextCursor(old_cursor); + this->verticalScrollBar()->setValue(old_scrollbar_value); + } + else + { + // The user hasn't selected any text and the scrollbar is at the bottom: scroll to the bottom. + this->moveCursor(QTextCursor::End); + this->verticalScrollBar()->setValue(this->verticalScrollBar()->maximum()); + } +} diff --git a/src/aotextedit.cpp b/src/aotextedit.cpp new file mode 100644 index 00000000..30e48b73 --- /dev/null +++ b/src/aotextedit.cpp @@ -0,0 +1,21 @@ +#include "aotextedit.h" + +AOTextEdit::AOTextEdit(QWidget *parent) : QPlainTextEdit(parent) +{ + this->setReadOnly(true); + + //connect(this, SIGNAL(returnPressed()), this, SLOT(on_enter_pressed())); +} + +void AOTextEdit::mouseDoubleClickEvent(QMouseEvent *e) +{ + QPlainTextEdit::mouseDoubleClickEvent(e); + + this->setReadOnly(false); +} + +void AOTextEdit::on_enter_pressed() +{ + this->setReadOnly(true); +} + diff --git a/src/charselect.cpp b/src/charselect.cpp new file mode 100644 index 00000000..8e1b9122 --- /dev/null +++ b/src/charselect.cpp @@ -0,0 +1,268 @@ +#include "courtroom.h" +#include "lobby.h" + +#include "file_functions.h" +#include "debug_functions.h" +#include "hardware_functions.h" + +void Courtroom::construct_char_select() +{ + ui_char_select_background = new AOImage(this, ao_app); + + ui_char_buttons = new QWidget(ui_char_select_background); + + ui_selector = new AOImage(ui_char_select_background, ao_app); + 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); + ui_char_password->setPlaceholderText(tr("Password")); + + ui_char_select_left = new AOButton(ui_char_select_background, ao_app); + ui_char_select_right = new AOButton(ui_char_select_background, ao_app); + + ui_spectator = new AOButton(ui_char_select_background, ao_app); + ui_spectator->setText(tr("Spectator")); + + ui_char_search = new QLineEdit(ui_char_select_background); + ui_char_search->setPlaceholderText(tr("Search")); + ui_char_search->setFocus(); + set_size_and_pos(ui_char_search, "char_search"); + + ui_char_passworded = new QCheckBox(ui_char_select_background); + ui_char_passworded->setText(tr("Passworded")); + set_size_and_pos(ui_char_passworded, "char_passworded"); + + ui_char_taken = new QCheckBox(ui_char_select_background); + ui_char_taken->setText(tr("Taken")); + set_size_and_pos(ui_char_taken, "char_taken"); + + ui_char_taken->setChecked(true); + ui_char_passworded->setChecked(true); + + set_size_and_pos(ui_char_buttons, "char_buttons"); + + connect (char_button_mapper, SIGNAL(mapped(int)), this, SLOT(char_clicked(int))); + connect(ui_back_to_lobby, SIGNAL(clicked()), this, SLOT(on_back_to_lobby_clicked())); + + connect(ui_char_select_left, SIGNAL(clicked()), this, SLOT(on_char_select_left_clicked())); + connect(ui_char_select_right, SIGNAL(clicked()), this, SLOT(on_char_select_right_clicked())); + + connect(ui_spectator, SIGNAL(clicked()), this, SLOT(on_spectator_clicked())); + + connect(ui_char_search, SIGNAL(textEdited(const QString&)), this, SLOT(on_char_search_changed(const QString&))); + connect(ui_char_passworded, SIGNAL(stateChanged(int)), this, SLOT(on_char_passworded_clicked(int))); + connect(ui_char_taken, SIGNAL(stateChanged(int)), this, SLOT(on_char_taken_clicked(int))); +} + +void Courtroom::set_char_select() +{ + QString filename = "courtroom_design.ini"; + + pos_size_type f_charselect = ao_app->get_element_dimensions("char_select", filename); + + if (f_charselect.width < 0 || f_charselect.height < 0) + { + qDebug() << "W: did not find courtroom width or height in courtroom_design.ini!"; + this->resize(714, 668); + } + else + this->resize(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.png"); + + filter_character_list(); + + ui_char_search->setFocus(); +} + +void Courtroom::set_char_select_page() +{ + ui_char_select_background->show(); + + ui_char_select_left->hide(); + ui_char_select_right->hide(); + + for (AOCharButton *i_button : ui_char_button_list) + { + i_button->reset(); + i_button->hide(); + i_button->move(0,0); + } + + int total_pages = ui_char_button_list_filtered.size() / max_chars_on_page; + int chars_on_page = 0; + + if (ui_char_button_list_filtered.size() % max_chars_on_page != 0) + { + ++total_pages; + //i. e. not on the last page + if (total_pages > current_char_page + 1) + chars_on_page = max_chars_on_page; + else + chars_on_page = ui_char_button_list_filtered.size() % max_chars_on_page; + + } + else + chars_on_page = max_chars_on_page; + + if (total_pages > current_char_page + 1) + ui_char_select_right->show(); + + if (current_char_page > 0) + ui_char_select_left->show(); + + put_button_in_place(current_char_page * max_chars_on_page, chars_on_page); +} + +void Courtroom::char_clicked(int n_char) +{ + QString char_ini_path = ao_app->get_character_path(char_list.at(n_char).name, "char.ini"); + + qDebug() << "char_ini_path" << char_ini_path; + + if (!file_exists(char_ini_path)) + { + call_notice("Could not find " + char_ini_path); + return; + } + + if (n_char == m_cid) + { + enter_courtroom(m_cid); + } + else + { + ao_app->send_server_packet(new AOPacket("CC#" + QString::number(ao_app->s_pv) + "#" + QString::number(n_char) + "#" + get_hdid() + "#%")); + } + + ui_ic_chat_name->setPlaceholderText(char_list.at(n_char).name); +} + +void Courtroom::put_button_in_place(int starting, int chars_on_this_page) +{ + if (ui_char_button_list_filtered.size() == 0) + return; + + QPoint f_spacing = ao_app->get_button_spacing("char_button_spacing", "courtroom_design.ini"); + + int x_spacing = f_spacing.x(); + int x_mod_count = 0; + + int y_spacing = f_spacing.y(); + int y_mod_count = 0; + + char_columns = ((ui_char_buttons->width() - button_width) / (x_spacing + button_width)) + 1; + char_rows = ((ui_char_buttons->height() - button_height) / (y_spacing + button_height)) + 1; + + max_chars_on_page = char_columns * char_rows; + + int startout = starting; + for (int n = starting ; n < startout+chars_on_this_page ; ++n) + { + int x_pos = (button_width + x_spacing) * x_mod_count; + int y_pos = (button_height + y_spacing) * y_mod_count; + + ui_char_button_list_filtered.at(n)->move(x_pos, y_pos); + ui_char_button_list_filtered.at(n)->show(); + ui_char_button_list_filtered.at(n)->apply_taken_image(); + + ++x_mod_count; + + if (x_mod_count == char_columns) + { + ++y_mod_count; + x_mod_count = 0; + } + } +} + +void Courtroom::character_loading_finished() +{ + // Zeroeth, we'll clear any leftover characters from previous server visits. + ao_app->generated_chars = 0; + if (ui_char_button_list.size() > 0) + { + foreach (AOCharButton* item, ui_char_button_list) { + delete item; + } + ui_char_button_list.clear(); + } + + // First, we'll make all the character buttons in the very beginning. + // We also hide them all, so they can't be accidentally clicked. + // Later on, we'll be revealing buttons as we need them. + for (int n = 0; n < char_list.size(); n++) + { + AOCharButton* character = new AOCharButton(ui_char_buttons, ao_app, 0, 0, char_list.at(n).taken); + character->reset(); + character->hide(); + character->set_image(char_list.at(n).name); + ui_char_button_list.append(character); + + connect(character, SIGNAL(clicked()), char_button_mapper, SLOT(map())); + char_button_mapper->setMapping(character, ui_char_button_list.size() - 1); + + // This part here serves as a way of showing to the player that the game is still running, it is + // just loading the pictures of the characters. + if (ao_app->lobby_constructed) + { + ao_app->generated_chars++; + int total_loading_size = ao_app->char_list_size * 2 + ao_app->evidence_list_size + ao_app->music_list_size; + int loading_value = int(((ao_app->loaded_chars + ao_app->generated_chars + ao_app->loaded_music + ao_app->loaded_evidence) / static_cast(total_loading_size)) * 100); + ao_app->w_lobby->set_loading_value(loading_value); + ao_app->w_lobby->set_loading_text("Generating chars:\n" + QString::number(ao_app->generated_chars) + "/" + QString::number(ao_app->char_list_size)); + } + } + + filter_character_list(); +} + +void Courtroom::filter_character_list() +{ + ui_char_button_list_filtered.clear(); + for (int i = 0; i < char_list.size(); i++) + { + AOCharButton* current_char = ui_char_button_list.at(i); + + // It seems passwording characters is unimplemented yet? + // Until then, this will stay here, I suppose. + //if (ui_char_passworded->isChecked() && character_is_passworded??) + // continue; + + if (!ui_char_taken->isChecked() && char_list.at(i).taken) + continue; + + if (!char_list.at(i).name.contains(ui_char_search->text(), Qt::CaseInsensitive)) + continue; + + // We only really need to update the fact that a character is taken + // for the buttons that actually appear. + // You'd also update the passwordedness and etc. here later. + current_char->reset(); + current_char->set_taken(char_list.at(i).taken); + + ui_char_button_list_filtered.append(current_char); + } + + current_char_page = 0; + set_char_select_page(); +} + +void Courtroom::on_char_search_changed(const QString& newtext) +{ + filter_character_list(); +} + +void Courtroom::on_char_passworded_clicked(int newstate) +{ + filter_character_list(); +} + +void Courtroom::on_char_taken_clicked(int newstate) +{ + filter_character_list(); +} diff --git a/src/chatlogpiece.cpp b/src/chatlogpiece.cpp new file mode 100644 index 00000000..6c861f01 --- /dev/null +++ b/src/chatlogpiece.cpp @@ -0,0 +1,76 @@ +#include "chatlogpiece.h" + +chatlogpiece::chatlogpiece() +{ + name = "UNKNOWN"; + showname = "UNKNOWN"; + message = "UNKNOWN"; + is_song = false; + datetime = QDateTime::currentDateTime().toUTC(); +} + +chatlogpiece::chatlogpiece(QString p_name, QString p_showname, QString p_message, bool p_song) +{ + name = p_name; + showname = p_showname; + message = p_message; + is_song = p_song; + datetime = QDateTime::currentDateTime().toUTC(); +} + +chatlogpiece::chatlogpiece(QString p_name, QString p_showname, QString p_message, bool p_song, QDateTime p_datetime) +{ + name = p_name; + showname = p_showname; + message = p_message; + is_song = p_song; + datetime = p_datetime.toUTC(); +} + +QString chatlogpiece::get_name() +{ + return name; +} + +QString chatlogpiece::get_showname() +{ + return showname; +} + +QString chatlogpiece::get_message() +{ + return message; +} + +QDateTime chatlogpiece::get_datetime() +{ + return datetime; +} + +bool chatlogpiece::get_is_song() +{ + return is_song; +} + +QString chatlogpiece::get_datetime_as_string() +{ + return datetime.toString(); +} + + +QString chatlogpiece::get_full() +{ + QString full = "["; + + full.append(get_datetime_as_string()); + full.append(" UTC] "); + full.append(get_showname()); + full.append(" ("); + full.append(get_name()); + full.append(")"); + if (is_song) + full.append(" has played a song: "); + full.append(get_message()); + + return full; +} diff --git a/src/courtroom.cpp b/src/courtroom.cpp new file mode 100644 index 00000000..3ed1e745 --- /dev/null +++ b/src/courtroom.cpp @@ -0,0 +1,3513 @@ +#include "courtroom.h" + +Courtroom::Courtroom(AOApplication *p_ao_app) : QMainWindow() +{ + ao_app = p_ao_app; + + // Change the default audio output device to be the one the user has given + // in his config.ini file for now. + int a = 0; + BASS_DEVICEINFO info; + + if (ao_app->get_audio_output_device() == "default") + { + BASS_Init(-1, 48000, BASS_DEVICE_LATENCY, nullptr, nullptr); + load_bass_opus_plugin(); + } + else + { + for (a = 0; BASS_GetDeviceInfo(a, &info); a++) + { + if (ao_app->get_audio_output_device() == info.name) + { + BASS_SetDevice(a); + BASS_Init(a, 48000, BASS_DEVICE_LATENCY, nullptr, nullptr); + load_bass_opus_plugin(); + qDebug() << info.name << "was set as the default audio output device."; + break; + } + } + } + + keepalive_timer = new QTimer(this); + keepalive_timer->start(60000); + + chat_tick_timer = new QTimer(this); + + text_delay_timer = new QTimer(this); + text_delay_timer->setSingleShot(true); + + sfx_delay_timer = new QTimer(this); + sfx_delay_timer->setSingleShot(true); + + realization_timer = new QTimer(this); + realization_timer->setSingleShot(true); + + testimony_show_timer = new QTimer(this); + testimony_show_timer->setSingleShot(true); + + testimony_hide_timer = new QTimer(this); + testimony_hide_timer->setSingleShot(true); + + char_button_mapper = new QSignalMapper(this); + + music_player = new AOMusicPlayer(this, ao_app); + music_player->set_volume(0); + sfx_player = new AOSfxPlayer(this, ao_app); + sfx_player->set_volume(0); + objection_player = new AOSfxPlayer(this, ao_app); + sfx_player->set_volume(0); + blip_player = new AOBlipPlayer(this, ao_app); + blip_player->set_volume(0); + + modcall_player = new AOSfxPlayer(this, ao_app); + modcall_player->set_volume(50); + + ui_background = new AOImage(this, ao_app); + + ui_viewport = new QWidget(this); + ui_vp_background = new AOScene(ui_viewport, ao_app); + ui_vp_speedlines = new AOMovie(ui_viewport, ao_app); + ui_vp_speedlines->set_play_once(false); + ui_vp_player_char = new AOCharMovie(ui_viewport, ao_app); + ui_vp_sideplayer_char = new AOCharMovie(ui_viewport, ao_app); + ui_vp_sideplayer_char->hide(); + ui_vp_desk = new AOScene(ui_viewport, ao_app); + ui_vp_legacy_desk = new AOScene(ui_viewport, ao_app); + + ui_vp_evidence_display = new AOEvidenceDisplay(this, ao_app); + + ui_vp_chatbox = new AOImage(this, ao_app); + ui_vp_showname = new QLabel(ui_vp_chatbox); + ui_vp_message = new QTextEdit(ui_vp_chatbox); + ui_vp_message->setFrameStyle(QFrame::NoFrame); + ui_vp_message->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + ui_vp_message->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + ui_vp_message->setReadOnly(true); + + ui_vp_testimony = new AOImage(this, ao_app); + ui_vp_realization = new AOImage(this, ao_app); + ui_vp_wtce = new AOMovie(this, ao_app); + ui_vp_objection = new AOMovie(this, ao_app); + + ui_ic_chatlog = new QTextEdit(this); + ui_ic_chatlog->setReadOnly(true); + + log_maximum_blocks = ao_app->get_max_log_size(); + log_goes_downwards = ao_app->get_log_goes_downwards(); + + ui_ms_chatlog = new AOTextArea(this); + ui_ms_chatlog->setReadOnly(true); + ui_ms_chatlog->setOpenExternalLinks(true); + ui_ms_chatlog->hide(); + + ui_server_chatlog = new AOTextArea(this); + ui_server_chatlog->setReadOnly(true); + ui_server_chatlog->setOpenExternalLinks(true); + + ui_area_list = new QListWidget(this); + ui_area_list->hide(); + ui_music_list = new QListWidget(this); + + ui_ic_chat_name = new QLineEdit(this); + ui_ic_chat_name->setFrame(false); + ui_ic_chat_name->setPlaceholderText(tr("Showname")); + + ui_ic_chat_message = new QLineEdit(this); + ui_ic_chat_message->setFrame(false); + ui_ic_chat_message->setPlaceholderText(tr("Message")); + + ui_muted = new AOImage(ui_ic_chat_message, ao_app); + ui_muted->hide(); + + ui_ooc_chat_message = new QLineEdit(this); + ui_ooc_chat_message->setFrame(false); + + ui_ooc_chat_name = new QLineEdit(this); + ui_ooc_chat_name->setFrame(false); + ui_ooc_chat_name->setPlaceholderText("Name"); + ui_ooc_chat_name->setMaxLength(30); + ui_ooc_chat_name->setText(p_ao_app->get_default_username()); + + //ui_area_password = new QLineEdit(this); + //ui_area_password->setFrame(false); + ui_music_search = new QLineEdit(this); + ui_music_search->setFrame(false); + ui_music_search->setPlaceholderText(tr("Search")); + + construct_emotes(); + + ui_emote_left = new AOButton(this, ao_app); + ui_emote_right = new AOButton(this, ao_app); + + ui_emote_dropdown = new QComboBox(this); + ui_pos_dropdown = new QComboBox(this); + ui_pos_dropdown->addItem("wit"); + ui_pos_dropdown->addItem("def"); + ui_pos_dropdown->addItem("pro"); + ui_pos_dropdown->addItem("jud"); + ui_pos_dropdown->addItem("hld"); + ui_pos_dropdown->addItem("hlp"); + ui_pos_dropdown->addItem("jur"); + ui_pos_dropdown->addItem("sea"); + + ui_defense_bar = new AOImage(this, ao_app); + ui_prosecution_bar = new AOImage(this, ao_app); + + ui_music_label = new QLabel(this); + ui_sfx_label = new QLabel(this); + ui_blip_label = new QLabel(this); + + ui_log_limit_label = new QLabel(this); + + ui_hold_it = new AOButton(this, ao_app); + ui_objection = new AOButton(this, ao_app); + ui_take_that = new AOButton(this, ao_app); + + ui_ooc_toggle = new AOButton(this, ao_app); + ui_witness_testimony = new AOButton(this, ao_app); + ui_cross_examination = new AOButton(this, ao_app); + ui_guilty = new AOButton(this, ao_app); + ui_not_guilty = new AOButton(this, ao_app); + + ui_change_character = new AOButton(this, ao_app); + ui_reload_theme = new AOButton(this, ao_app); + ui_call_mod = new AOButton(this, ao_app); + ui_settings = new AOButton(this, ao_app); + ui_announce_casing = new AOButton(this, ao_app); + ui_switch_area_music = new AOButton(this, ao_app); + + ui_pre = new QCheckBox(this); + ui_pre->setText("Pre"); + ui_flip = new QCheckBox(this); + ui_flip->setText("Flip"); + ui_flip->hide(); + ui_guard = new QCheckBox(this); + ui_guard->setText("Guard"); + ui_guard->hide(); + ui_casing = new QCheckBox(this); + ui_casing->setChecked(ao_app->get_casing_enabled()); + ui_casing->setText(tr("Casing")); + ui_casing->hide(); + + ui_showname_enable = new QCheckBox(this); + ui_showname_enable->setChecked(ao_app->get_showname_enabled_by_default()); + ui_showname_enable->setText(tr("Shownames")); + + ui_pre_non_interrupt = new QCheckBox(this); + ui_pre_non_interrupt->setText(tr("No Interrupt")); + ui_pre_non_interrupt->hide(); + + ui_custom_objection = new AOButton(this, ao_app); + ui_realization = new AOButton(this, ao_app); + ui_mute = new AOButton(this, ao_app); + + ui_defense_plus = new AOButton(this, ao_app); + ui_defense_minus = new AOButton(this, ao_app); + + ui_prosecution_plus = new AOButton(this, ao_app); + ui_prosecution_minus = new AOButton(this, ao_app); + + ui_text_color = new QComboBox(this); + ui_text_color->addItem("White"); + ui_text_color->addItem("Green"); + ui_text_color->addItem("Red"); + ui_text_color->addItem("Orange"); + ui_text_color->addItem("Blue"); + ui_text_color->addItem("Yellow"); + ui_text_color->addItem("Rainbow"); + ui_text_color->addItem("Pink"); + ui_text_color->addItem("Cyan"); + + ui_music_slider = new QSlider(Qt::Horizontal, this); + ui_music_slider->setRange(0, 100); + ui_music_slider->setValue(ao_app->get_default_music()); + + ui_sfx_slider = new QSlider(Qt::Horizontal, this); + ui_sfx_slider->setRange(0, 100); + ui_sfx_slider->setValue(ao_app->get_default_sfx()); + + ui_blip_slider = new QSlider(Qt::Horizontal, this); + ui_blip_slider->setRange(0, 100); + ui_blip_slider->setValue(ao_app->get_default_blip()); + + ui_log_limit_spinbox = new QSpinBox(this); + ui_log_limit_spinbox->setRange(0, 10000); + ui_log_limit_spinbox->setValue(ao_app->get_max_log_size()); + + ui_mute_list = new QListWidget(this); + 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("% offset"); + ui_pair_button = new AOButton(this, ao_app); + + ui_evidence_button = new AOButton(this, ao_app); + + construct_evidence(); + + construct_char_select(); + + connect(keepalive_timer, SIGNAL(timeout()), this, SLOT(ping_server())); + + connect(ui_vp_objection, SIGNAL(done()), this, SLOT(objection_done())); + connect(ui_vp_player_char, SIGNAL(done()), this, SLOT(preanim_done())); + + connect(text_delay_timer, SIGNAL(timeout()), this, SLOT(start_chat_ticking())); + connect(sfx_delay_timer, SIGNAL(timeout()), this, SLOT(play_sfx())); + + connect(chat_tick_timer, SIGNAL(timeout()), this, SLOT(chat_tick())); + + connect(realization_timer, SIGNAL(timeout()), this, SLOT(realization_done())); + + connect(testimony_show_timer, SIGNAL(timeout()), this, SLOT(hide_testimony())); + connect(testimony_hide_timer, SIGNAL(timeout()), this, SLOT(show_testimony())); + + connect(ui_emote_left, SIGNAL(clicked()), this, SLOT(on_emote_left_clicked())); + connect(ui_emote_right, SIGNAL(clicked()), this, SLOT(on_emote_right_clicked())); + + connect(ui_emote_dropdown, SIGNAL(activated(int)), this, SLOT(on_emote_dropdown_changed(int))); + connect(ui_pos_dropdown, SIGNAL(currentIndexChanged(int)), this, SLOT(on_pos_dropdown_changed(int))); + + connect(ui_mute_list, SIGNAL(clicked(QModelIndex)), this, SLOT(on_mute_list_clicked(QModelIndex))); + + connect(ui_ic_chat_message, SIGNAL(returnPressed()), this, SLOT(on_chat_return_pressed())); + + connect(ui_ooc_chat_message, SIGNAL(returnPressed()), this, SLOT(on_ooc_return_pressed())); + + connect(ui_music_list, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(on_music_list_double_clicked(QModelIndex))); + connect(ui_area_list, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(on_area_list_double_clicked(QModelIndex))); + + connect(ui_hold_it, SIGNAL(clicked()), this, SLOT(on_hold_it_clicked())); + connect(ui_objection, SIGNAL(clicked()), this, SLOT(on_objection_clicked())); + connect(ui_take_that, SIGNAL(clicked()), this, SLOT(on_take_that_clicked())); + connect(ui_custom_objection, SIGNAL(clicked()), this, SLOT(on_custom_objection_clicked())); + + connect(ui_realization, SIGNAL(clicked()), this, SLOT(on_realization_clicked())); + + connect(ui_mute, SIGNAL(clicked()), this, SLOT(on_mute_clicked())); + + connect(ui_defense_minus, SIGNAL(clicked()), this, SLOT(on_defense_minus_clicked())); + connect(ui_defense_plus, SIGNAL(clicked()), this, SLOT(on_defense_plus_clicked())); + connect(ui_prosecution_minus, SIGNAL(clicked()), this, SLOT(on_prosecution_minus_clicked())); + connect(ui_prosecution_plus, SIGNAL(clicked()), this, SLOT(on_prosecution_plus_clicked())); + + connect(ui_text_color, SIGNAL(currentIndexChanged(int)), this, SLOT(on_text_color_changed(int))); + + connect(ui_music_slider, SIGNAL(valueChanged(int)), this, SLOT(on_music_slider_moved(int))); + connect(ui_sfx_slider, SIGNAL(valueChanged(int)), this, SLOT(on_sfx_slider_moved(int))); + connect(ui_blip_slider, SIGNAL(valueChanged(int)), this, SLOT(on_blip_slider_moved(int))); + + connect(ui_log_limit_spinbox, SIGNAL(valueChanged(int)), this, SLOT(on_log_limit_changed(int))); + + connect(ui_ooc_toggle, SIGNAL(clicked()), this, SLOT(on_ooc_toggle_clicked())); + + connect(ui_music_search, SIGNAL(textChanged(QString)), this, SLOT(on_music_search_edited(QString))); + + connect(ui_witness_testimony, SIGNAL(clicked()), this, SLOT(on_witness_testimony_clicked())); + connect(ui_cross_examination, SIGNAL(clicked()), this, SLOT(on_cross_examination_clicked())); + connect(ui_guilty, SIGNAL(clicked()), this, SLOT(on_guilty_clicked())); + connect(ui_not_guilty, SIGNAL(clicked()), this, SLOT(on_not_guilty_clicked())); + + connect(ui_change_character, SIGNAL(clicked()), this, SLOT(on_change_character_clicked())); + connect(ui_reload_theme, SIGNAL(clicked()), this, SLOT(on_reload_theme_clicked())); + connect(ui_call_mod, SIGNAL(clicked()), this, SLOT(on_call_mod_clicked())); + connect(ui_settings, SIGNAL(clicked()), this, SLOT(on_settings_clicked())); + connect(ui_announce_casing, SIGNAL(clicked()), this, SLOT(on_announce_casing_clicked())); + connect(ui_switch_area_music, SIGNAL(clicked()), this, SLOT(on_switch_area_music_clicked())); + + connect(ui_pre, SIGNAL(clicked()), this, SLOT(on_pre_clicked())); + connect(ui_flip, SIGNAL(clicked()), this, SLOT(on_flip_clicked())); + connect(ui_guard, SIGNAL(clicked()), this, SLOT(on_guard_clicked())); + connect(ui_casing, SIGNAL(clicked()), this, SLOT(on_casing_clicked())); + + connect(ui_showname_enable, SIGNAL(clicked()), this, SLOT(on_showname_enable_clicked())); + + connect(ui_pair_button, SIGNAL(clicked()), this, SLOT(on_pair_clicked())); + connect(ui_pair_list, SIGNAL(clicked(QModelIndex)), this, SLOT(on_pair_list_clicked(QModelIndex))); + connect(ui_pair_offset_spinbox, SIGNAL(valueChanged(int)), this, SLOT(on_pair_offset_changed(int))); + + connect(ui_evidence_button, SIGNAL(clicked()), this, SLOT(on_evidence_button_clicked())); + + set_widgets(); + + set_char_select(); +} + +void Courtroom::set_mute_list() +{ + mute_map.clear(); + + //maps which characters are muted based on cid, none are muted by default + for (int n_cid = 0 ; n_cid < char_list.size() ; n_cid++) + { + mute_map.insert(n_cid, false); + } + + QStringList sorted_mute_list; + + for (char_type i_char : char_list) + sorted_mute_list.append(i_char.name); + + sorted_mute_list.sort(); + + for (QString i_name : sorted_mute_list) + { + //mute_map.insert(i_name, false); + ui_mute_list->addItem(i_name); + } +} + +void Courtroom::set_pair_list() +{ + QStringList sorted_pair_list; + + for (char_type i_char : char_list) + sorted_pair_list.append(i_char.name); + + sorted_pair_list.sort(); + + for (QString i_name : sorted_pair_list) + { + ui_pair_list->addItem(i_name); + } +} + +void Courtroom::set_widgets() +{ + blip_rate = ao_app->read_blip_rate(); + blank_blip = ao_app->get_blank_blip(); + + QString filename = "courtroom_design.ini"; + + pos_size_type f_courtroom = ao_app->get_element_dimensions("courtroom", filename); + + if (f_courtroom.width < 0 || f_courtroom.height < 0) + { + qDebug() << "W: did not find courtroom width or height in " << filename; + + this->resize(714, 668); + } + else + { + m_courtroom_width = f_courtroom.width; + m_courtroom_height = f_courtroom.height; + + this->resize(f_courtroom.width, f_courtroom.height); + } + + set_fonts(); + + ui_background->move(0, 0); + ui_background->resize(m_courtroom_width, m_courtroom_height); + ui_background->set_image("courtroombackground.png"); + + set_size_and_pos(ui_viewport, "viewport"); + + // If there is a point to it, show all CCCC features. + // We also do this this soon so that set_size_and_pos can hide them all later, if needed. + if (ao_app->cccc_ic_support_enabled) + { + ui_pair_button->show(); + ui_pre_non_interrupt->show(); + ui_showname_enable->show(); + ui_ic_chat_name->show(); + ui_ic_chat_name->setEnabled(true); + } + else + { + ui_pair_button->hide(); + ui_pre_non_interrupt->hide(); + ui_showname_enable->hide(); + ui_ic_chat_name->hide(); + ui_ic_chat_name->setEnabled(false); + } + + if (ao_app->casing_alerts_enabled) + { + ui_announce_casing->show(); + } + else + { + ui_announce_casing->hide(); + } + + // We also show the non-server-dependent client additions. + // Once again, if the theme can't display it, set_move_and_pos will catch them. + ui_settings->show(); + ui_log_limit_label->show(); + ui_log_limit_spinbox->show(); + + ui_vp_background->move(0, 0); + ui_vp_background->resize(ui_viewport->width(), ui_viewport->height()); + + ui_vp_speedlines->move(0, 0); + ui_vp_speedlines->combo_resize(ui_viewport->width(), ui_viewport->height()); + + ui_vp_player_char->move(0, 0); + ui_vp_player_char->combo_resize(ui_viewport->width(), ui_viewport->height()); + + ui_vp_sideplayer_char->move(0, 0); + ui_vp_sideplayer_char->combo_resize(ui_viewport->width(), ui_viewport->height()); + + //the AO2 desk element + ui_vp_desk->move(0, 0); + ui_vp_desk->resize(ui_viewport->width(), ui_viewport->height()); + + //the size of the ui_vp_legacy_desk element relies on various factors and is set in set_scene() + + double y_modifier = 147.0 / 192.0; + int final_y = static_cast(y_modifier * ui_viewport->height()); + ui_vp_legacy_desk->move(0, final_y); + ui_vp_legacy_desk->hide(); + + ui_vp_evidence_display->move(0, 0); + ui_vp_evidence_display->resize(ui_viewport->width(), ui_viewport->height()); + + set_size_and_pos(ui_vp_showname, "showname"); + + set_size_and_pos(ui_vp_message, "message"); + ui_vp_message->setTextInteractionFlags(Qt::NoTextInteraction); + ui_vp_message->setStyleSheet("background-color: rgba(0, 0, 0, 0);" + "color: white"); + + ui_vp_testimony->move(ui_viewport->x(), ui_viewport->y()); + ui_vp_testimony->resize(ui_viewport->width(), ui_viewport->height()); + ui_vp_testimony->set_image("testimony.png"); + ui_vp_testimony->hide(); + + ui_vp_realization->move(ui_viewport->x(), ui_viewport->y()); + ui_vp_realization->resize(ui_viewport->width(), ui_viewport->height()); + ui_vp_realization->set_image("realizationflash.png"); + ui_vp_realization->hide(); + + ui_vp_wtce->move(ui_viewport->x(), ui_viewport->y()); + ui_vp_wtce->combo_resize(ui_viewport->width(), ui_viewport->height()); + + ui_vp_objection->move(ui_viewport->x(), ui_viewport->y()); + ui_vp_objection->combo_resize(ui_viewport->width(), ui_viewport->height()); + + set_size_and_pos(ui_ic_chatlog, "ic_chatlog"); + + set_size_and_pos(ui_ms_chatlog, "ms_chatlog"); + + set_size_and_pos(ui_server_chatlog, "server_chatlog"); + + set_size_and_pos(ui_mute_list, "mute_list"); + ui_mute_list->hide(); + + set_size_and_pos(ui_pair_list, "pair_list"); + ui_pair_list->hide(); + set_size_and_pos(ui_pair_offset_spinbox, "pair_offset_spinbox"); + ui_pair_offset_spinbox->hide(); + set_size_and_pos(ui_pair_button, "pair_button"); + ui_pair_button->set_image("pair_button.png"); + + set_size_and_pos(ui_area_list, "music_list"); + ui_area_list->setStyleSheet("background-color: rgba(0, 0, 0, 0);"); + + set_size_and_pos(ui_music_list, "music_list"); + + if (is_ao2_bg) + { + set_size_and_pos(ui_ic_chat_message, "ao2_ic_chat_message"); + set_size_and_pos(ui_vp_chatbox, "ao2_chatbox"); + set_size_and_pos(ui_ic_chat_name, "ao2_ic_chat_name"); + } + else + { + set_size_and_pos(ui_ic_chat_message, "ic_chat_message"); + set_size_and_pos(ui_vp_chatbox, "chatbox"); + set_size_and_pos(ui_ic_chat_name, "ic_chat_name"); + } + + ui_ic_chat_message->setStyleSheet("QLineEdit{background-color: rgba(100, 100, 100, 255);}"); + ui_ic_chat_name->setStyleSheet("QLineEdit{background-color: rgba(180, 180, 180, 255);}"); + + ui_vp_chatbox->set_image("chatmed.png"); + ui_vp_chatbox->hide(); + + ui_muted->resize(ui_ic_chat_message->width(), ui_ic_chat_message->height()); + ui_muted->set_image("muted.png"); + + set_size_and_pos(ui_ooc_chat_message, "ooc_chat_message"); + ui_ooc_chat_message->setStyleSheet("background-color: rgba(0, 0, 0, 0);"); + + set_size_and_pos(ui_ooc_chat_name, "ooc_chat_name"); + ui_ooc_chat_name->setStyleSheet("background-color: rgba(0, 0, 0, 0);"); + + //set_size_and_pos(ui_area_password, "area_password"); + set_size_and_pos(ui_music_search, "music_search"); + + set_size_and_pos(ui_emotes, "emotes"); + + set_size_and_pos(ui_emote_left, "emote_left"); + ui_emote_left->set_image("arrow_left.png"); + + set_size_and_pos(ui_emote_right, "emote_right"); + ui_emote_right->set_image("arrow_right.png"); + + set_size_and_pos(ui_emote_dropdown, "emote_dropdown"); + set_size_and_pos(ui_pos_dropdown, "pos_dropdown"); + + set_size_and_pos(ui_defense_bar, "defense_bar"); + ui_defense_bar->set_image("defensebar" + QString::number(defense_bar_state) + ".png"); + + set_size_and_pos(ui_prosecution_bar, "prosecution_bar"); + ui_prosecution_bar->set_image("prosecutionbar" + QString::number(prosecution_bar_state) + ".png"); + + set_size_and_pos(ui_music_label, "music_label"); + ui_music_label->setText("Music"); + set_size_and_pos(ui_sfx_label, "sfx_label"); + ui_sfx_label->setText("Sfx"); + set_size_and_pos(ui_blip_label, "blip_label"); + ui_blip_label->setText("Blips"); + + set_size_and_pos(ui_log_limit_label, "log_limit_label"); + ui_log_limit_label->setText("Log limit"); + + set_size_and_pos(ui_hold_it, "hold_it"); + ui_hold_it->set_image("holdit.png"); + set_size_and_pos(ui_objection, "objection"); + ui_objection->set_image("objection.png"); + set_size_and_pos(ui_take_that, "take_that"); + ui_take_that->set_image("takethat.png"); + + set_size_and_pos(ui_ooc_toggle, "ooc_toggle"); + ui_ooc_toggle->setText("Server"); + + set_size_and_pos(ui_witness_testimony, "witness_testimony"); + ui_witness_testimony->set_image("witnesstestimony.png"); + set_size_and_pos(ui_cross_examination, "cross_examination"); + ui_cross_examination->set_image("crossexamination.png"); + + set_size_and_pos(ui_guilty, "guilty"); + ui_guilty->set_image("guilty.png"); + set_size_and_pos(ui_not_guilty, "not_guilty"); + ui_not_guilty->set_image("notguilty.png"); + + set_size_and_pos(ui_change_character, "change_character"); + ui_change_character->setText("Change character"); + + set_size_and_pos(ui_reload_theme, "reload_theme"); + ui_reload_theme->setText("Reload theme"); + + set_size_and_pos(ui_call_mod, "call_mod"); + ui_call_mod->setText("Call mod"); + + set_size_and_pos(ui_settings, "settings"); + ui_settings->setText("Settings"); + + set_size_and_pos(ui_announce_casing, "casing_button"); + ui_announce_casing->setText("Casing"); + + set_size_and_pos(ui_switch_area_music, "switch_area_music"); + ui_switch_area_music->setText("A/M"); + + set_size_and_pos(ui_pre, "pre"); + ui_pre->setText("Preanim"); + + set_size_and_pos(ui_pre_non_interrupt, "pre_no_interrupt"); + set_size_and_pos(ui_flip, "flip"); + + set_size_and_pos(ui_guard, "guard"); + + set_size_and_pos(ui_casing, "casing"); + + set_size_and_pos(ui_showname_enable, "showname_enable"); + + set_size_and_pos(ui_custom_objection, "custom_objection"); + ui_custom_objection->set_image("custom.png"); + + set_size_and_pos(ui_realization, "realization"); + ui_realization->set_image("realization.png"); + + set_size_and_pos(ui_mute, "mute_button"); + ui_mute->set_image("mute.png"); + + set_size_and_pos(ui_defense_plus, "defense_plus"); + ui_defense_plus->set_image("defplus.png"); + + set_size_and_pos(ui_defense_minus, "defense_minus"); + ui_defense_minus->set_image("defminus.png"); + + set_size_and_pos(ui_prosecution_plus, "prosecution_plus"); + ui_prosecution_plus->set_image("proplus.png"); + + set_size_and_pos(ui_prosecution_minus, "prosecution_minus"); + ui_prosecution_minus->set_image("prominus.png"); + + set_size_and_pos(ui_text_color, "text_color"); + + set_size_and_pos(ui_music_slider, "music_slider"); + set_size_and_pos(ui_sfx_slider, "sfx_slider"); + set_size_and_pos(ui_blip_slider, "blip_slider"); + + set_size_and_pos(ui_log_limit_spinbox, "log_limit_spinbox"); + + set_size_and_pos(ui_evidence_button, "evidence_button"); + ui_evidence_button->set_image("evidencebutton.png"); + + set_size_and_pos(ui_evidence, "evidence_background"); + ui_evidence->set_image("evidencebackground.png"); + + set_size_and_pos(ui_evidence_name, "evidence_name"); + + set_size_and_pos(ui_evidence_buttons, "evidence_buttons"); + + set_size_and_pos(ui_evidence_left, "evidence_left"); + ui_evidence_left->set_image("arrow_left.png"); + + set_size_and_pos(ui_evidence_right, "evidence_right"); + ui_evidence_right->set_image("arrow_right.png"); + + set_size_and_pos(ui_evidence_present, "evidence_present"); + ui_evidence_present->set_image("present_disabled.png"); + + set_size_and_pos(ui_evidence_overlay, "evidence_overlay"); + ui_evidence_overlay->set_image("evidenceoverlay.png"); + + set_size_and_pos(ui_evidence_delete, "evidence_delete"); + ui_evidence_delete->set_image("deleteevidence.png"); + + set_size_and_pos(ui_evidence_image_name, "evidence_image_name"); + + set_size_and_pos(ui_evidence_image_button, "evidence_image_button"); + + set_size_and_pos(ui_evidence_x, "evidence_x"); + ui_evidence_x->set_image("evidencex.png"); + + set_size_and_pos(ui_evidence_description, "evidence_description"); + + ui_selector->set_image("char_selector.png"); + ui_selector->hide(); + + set_size_and_pos(ui_back_to_lobby, "back_to_lobby"); + ui_back_to_lobby->setText("Back to Lobby"); + + set_size_and_pos(ui_char_password, "char_password"); + + set_size_and_pos(ui_char_buttons, "char_buttons"); + + set_size_and_pos(ui_char_select_left, "char_select_left"); + ui_char_select_left->set_image("arrow_left.png"); + + set_size_and_pos(ui_char_select_right, "char_select_right"); + ui_char_select_right->set_image("arrow_right.png"); + + set_size_and_pos(ui_spectator, "spectator"); +} + +void Courtroom::set_fonts() +{ + set_font(ui_vp_showname, "showname"); + set_font(ui_vp_message, "message"); + set_font(ui_ic_chatlog, "ic_chatlog"); + set_font(ui_ms_chatlog, "ms_chatlog"); + set_font(ui_server_chatlog, "server_chatlog"); + set_font(ui_music_list, "music_list"); + set_font(ui_area_list, "music_list"); + + // Set color of labels and checkboxes + const QString design_file = "courtroom_fonts.ini"; + QColor f_color = ao_app->get_color("label_color", design_file); + QString color_string = "color: rgba(" + + QString::number(f_color.red()) + ", " + + QString::number(f_color.green()) + ", " + + QString::number(f_color.blue()) + ", 255); }"; + QString style_sheet_string = "QLabel {" + color_string + "}" + "QCheckBox {" + color_string + "}"; + setStyleSheet(style_sheet_string); +} + +void Courtroom::set_font(QWidget *widget, QString p_identifier) +{ + QString design_file = "courtroom_fonts.ini"; + int f_weight = ao_app->get_font_size(p_identifier, design_file); + QString class_name = widget->metaObject()->className(); + + widget->setFont(QFont("Sans", f_weight)); + + QColor f_color = ao_app->get_color(p_identifier + "_color", design_file); + + QString style_sheet_string = class_name + " { background-color: rgba(0, 0, 0, 0);\n" + + "color: rgba(" + + QString::number(f_color.red()) + ", " + + QString::number(f_color.green()) + ", " + + QString::number(f_color.blue()) + ", 255); }"; + + widget->setStyleSheet(style_sheet_string); +} + +void Courtroom::set_window_title(QString p_title) +{ + this->setWindowTitle(p_title); +} + +void Courtroom::set_size_and_pos(QWidget *p_widget, QString p_identifier) +{ + QString filename = "courtroom_design.ini"; + + pos_size_type design_ini_result = ao_app->get_element_dimensions(p_identifier, filename); + + if (design_ini_result.width < 0 || design_ini_result.height < 0) + { + qDebug() << "W: could not find \"" << p_identifier << "\" in " << filename; + p_widget->hide(); + } + else + { + p_widget->move(design_ini_result.x, design_ini_result.y); + p_widget->resize(design_ini_result.width, design_ini_result.height); + } +} + +void Courtroom::set_taken(int n_char, bool p_taken) +{ + if (n_char >= char_list.size()) + { + qDebug() << "W: set_taken attempted to set an index bigger than char_list size"; + return; + } + + char_type f_char; + f_char.name = char_list.at(n_char).name; + f_char.description = char_list.at(n_char).description; + f_char.taken = p_taken; + f_char.evidence_string = char_list.at(n_char).evidence_string; + + char_list.replace(n_char, f_char); +} + +void Courtroom::done_received() +{ + m_cid = -1; + + music_player->set_volume(0); + sfx_player->set_volume(0); + objection_player->set_volume(0); + blip_player->set_volume(0); + + set_char_select_page(); + + set_mute_list(); + set_pair_list(); + + set_char_select(); + + show(); + + ui_spectator->show(); +} + +void Courtroom::set_background(QString p_background) +{ + testimony_in_progress = false; + + current_background = p_background; + + is_ao2_bg = file_exists(ao_app->get_background_path("defensedesk.png")) && + file_exists(ao_app->get_background_path("prosecutiondesk.png")) && + file_exists(ao_app->get_background_path("stand.png")); + + if (is_ao2_bg) + { + set_size_and_pos(ui_vp_chatbox, "ao2_chatbox"); + set_size_and_pos(ui_ic_chat_message, "ao2_ic_chat_message"); + } + else + { + set_size_and_pos(ui_vp_chatbox, "chatbox"); + set_size_and_pos(ui_ic_chat_message, "ic_chat_message"); + } +} + +void Courtroom::enter_courtroom(int p_cid) +{ + m_cid = p_cid; + + QString f_char; + + if (m_cid == -1) + { + if (ao_app->is_discord_enabled()) + ao_app->discord->state_spectate(); + f_char = ""; + } + else + { + f_char = ao_app->get_char_name(char_list.at(m_cid).name); + + if (ao_app->is_discord_enabled()) + ao_app->discord->state_character(f_char.toStdString()); + } + + current_char = f_char; + + current_emote_page = 0; + current_emote = 0; + + if (m_cid == -1) + ui_emotes->hide(); + else + ui_emotes->show(); + + set_emote_page(); + set_emote_dropdown(); + + current_evidence_page = 0; + current_evidence = 0; + + set_evidence_page(); + + QString side = ao_app->get_char_side(f_char); + + if (side == "jud") + { + ui_witness_testimony->show(); + ui_cross_examination->show(); + ui_not_guilty->show(); + ui_guilty->show(); + ui_defense_minus->show(); + ui_defense_plus->show(); + ui_prosecution_minus->show(); + ui_prosecution_plus->show(); + } + else + { + ui_witness_testimony->hide(); + ui_cross_examination->hide(); + ui_guilty->hide(); + ui_not_guilty->hide(); + ui_defense_minus->hide(); + ui_defense_plus->hide(); + ui_prosecution_minus->hide(); + ui_prosecution_plus->hide(); + } + + if (ao_app->custom_objection_enabled && + (file_exists(ao_app->get_character_path(current_char, "custom.gif")) || + file_exists(ao_app->get_character_path(current_char, "custom.apng"))) && + file_exists(ao_app->get_character_path(current_char, "custom.wav"))) + ui_custom_objection->show(); + else + ui_custom_objection->hide(); + + if (ao_app->flipping_enabled) + ui_flip->show(); + else + ui_flip->hide(); + + if (ao_app->casing_alerts_enabled) + ui_casing->show(); + else + ui_casing->hide(); + + list_music(); + list_areas(); + + music_player->set_volume(ui_music_slider->value()); + sfx_player->set_volume(ui_sfx_slider->value()); + objection_player->set_volume(ui_sfx_slider->value()); + blip_player->set_volume(ui_blip_slider->value()); + + testimony_in_progress = false; + + set_widgets(); + + //ui_server_chatlog->setHtml(ui_server_chatlog->toHtml()); + + ui_char_select_background->hide(); + + ui_ic_chat_message->setEnabled(m_cid != -1); + ui_ic_chat_message->setFocus(); +} + +void Courtroom::list_music() +{ + ui_music_list->clear(); + music_row_to_number.clear(); + + QString f_file = "courtroom_design.ini"; + + QBrush found_brush(ao_app->get_color("found_song_color", f_file)); + QBrush missing_brush(ao_app->get_color("missing_song_color", f_file)); + + int n_listed_songs = 0; + + for (int n_song = 0 ; n_song < music_list.size() ; ++n_song) + { + QString i_song = music_list.at(n_song); + QString i_song_listname = i_song; + i_song_listname = i_song_listname.left(i_song_listname.lastIndexOf(".")); + + if (i_song.toLower().contains(ui_music_search->text().toLower())) + { + ui_music_list->addItem(i_song_listname); + music_row_to_number.append(n_song); + + QString song_path = ao_app->get_music_path(i_song); + + if (file_exists(song_path)) + ui_music_list->item(n_listed_songs)->setBackground(found_brush); + else + ui_music_list->item(n_listed_songs)->setBackground(missing_brush); + + ++n_listed_songs; + } + } +} + +void Courtroom::list_areas() +{ + ui_area_list->clear(); + area_row_to_number.clear(); + + QString f_file = "courtroom_design.ini"; + + QBrush free_brush(ao_app->get_color("area_free_color", f_file)); + QBrush lfp_brush(ao_app->get_color("area_lfp_color", f_file)); + QBrush casing_brush(ao_app->get_color("area_casing_color", f_file)); + QBrush recess_brush(ao_app->get_color("area_recess_color", f_file)); + QBrush rp_brush(ao_app->get_color("area_rp_color", f_file)); + QBrush gaming_brush(ao_app->get_color("area_gaming_color", f_file)); + QBrush locked_brush(ao_app->get_color("area_locked_color", f_file)); + + int n_listed_areas = 0; + + for (int n_area = 0 ; n_area < area_list.size() ; ++n_area) + { + QString i_area = ""; + i_area.append("["); + i_area.append(QString::number(n_area)); + i_area.append("] "); + + i_area.append(area_list.at(n_area)); + + if (ao_app->arup_enabled) + { + i_area.append("\n "); + + i_area.append(arup_statuses.at(n_area)); + i_area.append(" | CM: "); + i_area.append(arup_cms.at(n_area)); + + i_area.append("\n "); + + i_area.append(QString::number(arup_players.at(n_area))); + i_area.append(" users | "); + + i_area.append(arup_locks.at(n_area)); + } + + if (i_area.toLower().contains(ui_music_search->text().toLower())) + { + ui_area_list->addItem(i_area); + area_row_to_number.append(n_area); + + if (ao_app->arup_enabled) + { + // Colouring logic here. + ui_area_list->item(n_listed_areas)->setBackground(free_brush); + if (arup_locks.at(n_area) == "LOCKED") + { + ui_area_list->item(n_listed_areas)->setBackground(locked_brush); + } + else + { + if (arup_statuses.at(n_area) == "LOOKING-FOR-PLAYERS") + ui_area_list->item(n_listed_areas)->setBackground(lfp_brush); + else if (arup_statuses.at(n_area) == "CASING") + ui_area_list->item(n_listed_areas)->setBackground(casing_brush); + else if (arup_statuses.at(n_area) == "RECESS") + ui_area_list->item(n_listed_areas)->setBackground(recess_brush); + else if (arup_statuses.at(n_area) == "RP") + ui_area_list->item(n_listed_areas)->setBackground(rp_brush); + else if (arup_statuses.at(n_area) == "GAMING") + ui_area_list->item(n_listed_areas)->setBackground(gaming_brush); + } + } + else + { + ui_area_list->item(n_listed_areas)->setBackground(free_brush); + } + + ++n_listed_areas; + } + } +} + +void Courtroom::append_ms_chatmessage(QString f_name, QString f_message) +{ + ui_ms_chatlog->append_chatmessage(f_name, f_message, ao_app->get_color("ooc_default_color", "courtroom_design.ini").name()); +} + +void Courtroom::append_server_chatmessage(QString p_name, QString p_message, QString p_colour) +{ + QString colour = "#000000"; + + if (p_colour == "0") + colour = ao_app->get_color("ooc_default_color", "courtroom_design.ini").name(); + if (p_colour == "1") + colour = ao_app->get_color("ooc_server_color", "courtroom_design.ini").name(); + + ui_server_chatlog->append_chatmessage(p_name, p_message, colour); +} + +void Courtroom::on_chat_return_pressed() +{ + if (ui_ic_chat_message->text() == "" || is_muted) + return; + + if ((anim_state < 3 || text_state < 2) && + objection_state == 0) + return; + + //MS# + //deskmod# + //pre-emote# + //character# + //emote# + //message# + //side# + //sfx-name# + //emote_modifier# + //char_id# + //sfx_delay# + //objection_modifier# + //evidence# + //placeholder# + //realization# + //text_color#% + + // Additionally, in our case: + + //showname# + //other_charid# + //self_offset# + //noninterrupting_preanim#% + + QStringList packet_contents; + + QString f_side = ao_app->get_char_side(current_char); + + QString f_desk_mod = "chat"; + + if (ao_app->desk_mod_enabled) + { + f_desk_mod = QString::number(ao_app->get_desk_mod(current_char, current_emote)); + if (f_desk_mod == "-1") + f_desk_mod = "chat"; + } + + packet_contents.append(f_desk_mod); + + packet_contents.append(ao_app->get_pre_emote(current_char, current_emote)); + + packet_contents.append(current_char); + + packet_contents.append(ao_app->get_emote(current_char, current_emote)); + + packet_contents.append(ui_ic_chat_message->text()); + + packet_contents.append(f_side); + + packet_contents.append(ao_app->get_sfx_name(current_char, current_emote)); + + 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 == 5) + f_emote_mod = 6; + else + f_emote_mod = 2; + } + } + else if (ui_pre->isChecked() and !ui_pre_non_interrupt->isChecked()) + { + if (f_emote_mod == 0) + f_emote_mod = 1; + else if (f_emote_mod == 5 && ao_app->prezoom_enabled) + f_emote_mod = 4; + } + else + { + if (f_emote_mod == 1) + f_emote_mod = 0; + else if (f_emote_mod == 4) + f_emote_mod = 5; + } + + packet_contents.append(QString::number(f_emote_mod)); + packet_contents.append(QString::number(m_cid)); + + packet_contents.append(QString::number(ao_app->get_sfx_delay(current_char, current_emote))); + + QString f_obj_state; + + if ((objection_state == 4 && !ao_app->custom_objection_enabled) || + (objection_state < 0)) + f_obj_state = "0"; + else + f_obj_state = QString::number(objection_state); + + packet_contents.append(f_obj_state); + + if (is_presenting_evidence) + //the evidence index is shifted by 1 because 0 is no evidence per legacy standards + //besides, older clients crash if we pass -1 + packet_contents.append(QString::number(current_evidence + 1)); + else + packet_contents.append("0"); + + QString f_flip; + + if (ao_app->flipping_enabled) + { + if (ui_flip->isChecked()) + f_flip = "1"; + else + f_flip = "0"; + } + else + f_flip = QString::number(m_cid); + + packet_contents.append(f_flip); + + packet_contents.append(QString::number(realization_state)); + + QString f_text_color; + + if (text_color < 0) + f_text_color = "0"; + else if (text_color > 8) + f_text_color = "0"; + else + f_text_color = QString::number(text_color); + + packet_contents.append(f_text_color); + + // If the server we're on supports CCCC stuff, we should use it! + if (ao_app->cccc_ic_support_enabled) + { + // If there is a showname entered, use that -- else, just send an empty packet-part. + if (!ui_ic_chat_name->text().isEmpty()) + { + packet_contents.append(ui_ic_chat_name->text()); + } + else + { + packet_contents.append(""); + } + + // Similarly, we send over whom we're paired with, unless we have chosen ourselves. + // Or a charid of -1 or lower, through some means. + if (other_charid > -1 && other_charid != m_cid) + { + packet_contents.append(QString::number(other_charid)); + packet_contents.append(QString::number(offset_with_pair)); + } + else + { + packet_contents.append("-1"); + packet_contents.append("0"); + } + + // Finally, we send over if we want our pres to not interrupt. + if (ui_pre_non_interrupt->isChecked() && ui_pre->isChecked()) + { + packet_contents.append("1"); + } + else + { + packet_contents.append("0"); + } + } + + ao_app->send_server_packet(new AOPacket("MS", packet_contents)); +} + +void Courtroom::handle_chatmessage(QStringList *p_contents) +{ + // Instead of checking for whether a message has at least chatmessage_size + // amount of packages, we'll check if it has at least 15. + // That was the original chatmessage_size. + if (p_contents->size() < 15) + return; + + for (int n_string = 0 ; n_string < chatmessage_size ; ++n_string) + { + //m_chatmessage[n_string] = p_contents->at(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 amongst the packet's content. + // We also have to check if the server even supports CCCC's IC features, or if it's just japing us. + // Also, don't forget! A size 15 message will have indices from 0 to 14. + if (n_string < p_contents->size() && + (n_string < 15 || ao_app->cccc_ic_support_enabled)) + { + m_chatmessage[n_string] = p_contents->at(n_string); + } + else + { + m_chatmessage[n_string] = ""; + } + } + + int f_char_id = m_chatmessage[CHAR_ID].toInt(); + + if (f_char_id < 0 || f_char_id >= char_list.size()) + return; + + if (mute_map.value(m_chatmessage[CHAR_ID].toInt())) + return; + + QString f_showname; + if (m_chatmessage[SHOWNAME].isEmpty() || !ui_showname_enable->isChecked()) + { + f_showname = ao_app->get_showname(char_list.at(f_char_id).name); + } + else + { + f_showname = m_chatmessage[SHOWNAME]; + } + + + QString f_message = f_showname + ": " + m_chatmessage[MESSAGE] + '\n'; + + if (f_message == previous_ic_message) + return; + + text_state = 0; + anim_state = 0; + ui_vp_objection->stop(); + ui_vp_player_char->stop(); + chat_tick_timer->stop(); + ui_vp_evidence_display->reset(); + + chatmessage_is_empty = m_chatmessage[MESSAGE] == " " || m_chatmessage[MESSAGE] == ""; + + if (m_chatmessage[MESSAGE] == ui_ic_chat_message->text() && m_chatmessage[CHAR_ID].toInt() == m_cid) + { + ui_ic_chat_message->clear(); + objection_state = 0; + realization_state = 0; + is_presenting_evidence = false; + ui_pre->setChecked(false); + ui_hold_it->set_image("holdit.png"); + ui_objection->set_image("objection.png"); + ui_take_that->set_image("takethat.png"); + ui_custom_objection->set_image("custom.png"); + ui_realization->set_image("realization.png"); + ui_evidence_present->set_image("present_disabled.png"); + } + + chatlogpiece* temp = new chatlogpiece(ao_app->get_showname(char_list.at(f_char_id).name), f_showname, ": " + m_chatmessage[MESSAGE], false); + ic_chatlog_history.append(*temp); + + while(ic_chatlog_history.size() > log_maximum_blocks && log_maximum_blocks > 0) + { + ic_chatlog_history.removeFirst(); + } + + append_ic_text(": " + m_chatmessage[MESSAGE], f_showname); + + previous_ic_message = f_message; + + int objection_mod = m_chatmessage[OBJECTION_MOD].toInt(); + QString f_char = m_chatmessage[CHAR_NAME]; + QString f_custom_theme = ao_app->get_char_shouts(f_char); + + //if an objection is used + if (objection_mod <= 4 && objection_mod >= 1) + { + switch (objection_mod) + { + case 1: + ui_vp_objection->play("holdit", f_char, f_custom_theme); + objection_player->play("holdit.wav", f_char, f_custom_theme); + break; + case 2: + ui_vp_objection->play("objection", f_char, f_custom_theme); + objection_player->play("objection.wav", f_char, f_custom_theme); + break; + case 3: + ui_vp_objection->play("takethat", f_char, f_custom_theme); + objection_player->play("takethat.wav", f_char, f_custom_theme); + break; + //case 4 is AO2 only + case 4: + ui_vp_objection->play("custom", f_char, f_custom_theme); + objection_player->play("custom.wav", f_char, f_custom_theme); + break; + default: + qDebug() << "W: Logic error in objection switch statement!"; + } + + int emote_mod = m_chatmessage[EMOTE_MOD].toInt(); + + if (emote_mod == 0) + m_chatmessage[EMOTE_MOD] = 1; + } + else + handle_chatmessage_2(); +} + +void Courtroom::objection_done() +{ + handle_chatmessage_2(); +} + +void Courtroom::handle_chatmessage_2() +{ + ui_vp_speedlines->stop(); + ui_vp_player_char->stop(); + + if (m_chatmessage[SHOWNAME].isEmpty() || !ui_showname_enable->isChecked()) + { + QString real_name = char_list.at(m_chatmessage[CHAR_ID].toInt()).name; + + QString f_showname = ao_app->get_showname(real_name); + + ui_vp_showname->setText(f_showname); + } + else + { + ui_vp_showname->setText(m_chatmessage[SHOWNAME]); + } + + ui_vp_message->clear(); + ui_vp_chatbox->hide(); + + QString chatbox = ao_app->get_chat(m_chatmessage[CHAR_NAME]); + + if (chatbox == "") + ui_vp_chatbox->set_image("chatmed.png"); + else + { + QString chatbox_path = ao_app->get_base_path() + "misc/" + chatbox + "/chatbox.png"; + ui_vp_chatbox->set_image_from_path(chatbox_path); + } + + ui_vp_showname->setStyleSheet("QLabel { color : " + get_text_color("_showname").name() + "; }"); + + set_scene(); + set_text_color(); + + // Check if the message needs to be centered. + QString f_message = m_chatmessage[MESSAGE]; + if (f_message.size() >= 2) + { + if (f_message.startsWith("~~")) + { + message_is_centered = true; + } + else + { + message_is_centered = false; + } + } + else + { + ui_vp_message->setAlignment(Qt::AlignLeft); + } + + + int emote_mod = m_chatmessage[EMOTE_MOD].toInt(); + + if (ao_app->flipping_enabled && m_chatmessage[FLIP].toInt() == 1) + ui_vp_player_char->set_flipped(true); + else + ui_vp_player_char->set_flipped(false); + + QString side = m_chatmessage[SIDE]; + + // Making the second character appear. + if (m_chatmessage[OTHER_CHARID].isEmpty()) + { + // If there is no second character, hide 'em, and center the first. + ui_vp_sideplayer_char->hide(); + ui_vp_sideplayer_char->move(0,0); + + ui_vp_player_char->move(0,0); + } + else + { + bool ok; + int got_other_charid = m_chatmessage[OTHER_CHARID].toInt(&ok); + if (ok) + { + if (got_other_charid > -1) + { + // If there is, show them! + ui_vp_sideplayer_char->show(); + + // Depending on where we are, we offset the characters, and reorder their stacking. + if (side == "def") + { + // We also move the character down depending on how far the are to the right. + int hor_offset = m_chatmessage[SELF_OFFSET].toInt(); + int vert_offset = 0; + if (hor_offset > 0) + { + vert_offset = hor_offset / 10; + } + ui_vp_player_char->move(ui_viewport->width() * hor_offset / 100, ui_viewport->height() * vert_offset / 100); + + // We do the same with the second character. + int hor2_offset = m_chatmessage[OTHER_OFFSET].toInt(); + int vert2_offset = 0; + if (hor2_offset > 0) + { + vert2_offset = hor2_offset / 10; + } + ui_vp_sideplayer_char->move(ui_viewport->width() * hor2_offset / 100, ui_viewport->height() * vert2_offset / 100); + + // Finally, we reorder them based on who is more to the left. + // The person more to the left is more in the front. + if (hor2_offset >= hor_offset) + { + ui_vp_sideplayer_char->raise(); + ui_vp_player_char->raise(); + } + else + { + ui_vp_player_char->raise(); + ui_vp_sideplayer_char->raise(); + } + ui_vp_desk->raise(); + ui_vp_legacy_desk->raise(); + } + else if (side == "pro") + { + // Almost the same thing happens here, but in reverse. + int hor_offset = m_chatmessage[SELF_OFFSET].toInt(); + int vert_offset = 0; + if (hor_offset < 0) + { + // We don't want to RAISE the char off the floor. + vert_offset = -1 * hor_offset / 10; + } + ui_vp_player_char->move(ui_viewport->width() * hor_offset / 100, ui_viewport->height() * vert_offset / 100); + + // We do the same with the second character. + int hor2_offset = m_chatmessage[OTHER_OFFSET].toInt(); + int vert2_offset = 0; + if (hor2_offset < 0) + { + vert2_offset = -1 * hor2_offset / 10; + } + ui_vp_sideplayer_char->move(ui_viewport->width() * hor2_offset / 100, ui_viewport->height() * vert2_offset / 100); + + // Finally, we reorder them based on who is more to the right. + if (hor2_offset <= hor_offset) + { + ui_vp_sideplayer_char->raise(); + ui_vp_player_char->raise(); + } + else + { + ui_vp_player_char->raise(); + ui_vp_sideplayer_char->raise(); + } + ui_vp_desk->raise(); + ui_vp_legacy_desk->raise(); + } + else + { + // In every other case, the person more to the left is on top. + // These cases also don't move the characters down. + int hor_offset = m_chatmessage[SELF_OFFSET].toInt(); + ui_vp_player_char->move(ui_viewport->width() * hor_offset / 100, 0); + + // We do the same with the second character. + int hor2_offset = m_chatmessage[OTHER_OFFSET].toInt(); + ui_vp_sideplayer_char->move(ui_viewport->width() * hor2_offset / 100, 0); + + // Finally, we reorder them based on who is more to the left. + // The person more to the left is more in the front. + if (hor2_offset >= hor_offset) + { + ui_vp_sideplayer_char->raise(); + ui_vp_player_char->raise(); + } + else + { + ui_vp_player_char->raise(); + ui_vp_sideplayer_char->raise(); + } + ui_vp_desk->raise(); + ui_vp_legacy_desk->raise(); + } + // We should probably also play the other character's idle emote. + if (ao_app->flipping_enabled && m_chatmessage[OTHER_FLIP].toInt() == 1) + ui_vp_sideplayer_char->set_flipped(true); + else + ui_vp_sideplayer_char->set_flipped(false); + ui_vp_sideplayer_char->play_idle(m_chatmessage[OTHER_NAME], m_chatmessage[OTHER_EMOTE]); + } + else + { + // If the server understands other characters, but there + // really is no second character, hide 'em, and center the first. + ui_vp_sideplayer_char->hide(); + ui_vp_sideplayer_char->move(0,0); + + ui_vp_player_char->move(0,0); + } + } + } + + switch (emote_mod) + { + case 1: case 2: case 6: + play_preanim(false); + break; + case 0: case 5: + if (m_chatmessage[NONINTERRUPTING_PRE].toInt() == 0) + handle_chatmessage_3(); + else + play_preanim(true); + break; + default: + qDebug() << "W: invalid emote mod: " << QString::number(emote_mod); + } +} + +void Courtroom::handle_chatmessage_3() +{ + start_chat_ticking(); + + int f_evi_id = m_chatmessage[EVIDENCE_ID].toInt(); + QString f_side = m_chatmessage[SIDE]; + + if (f_evi_id > 0 && f_evi_id <= local_evidence_list.size()) + { + //shifted by 1 because 0 is no evidence per legacy standards + QString f_image = local_evidence_list.at(f_evi_id - 1).image; + //def jud and hlp should display the evidence icon on the RIGHT side + bool is_left_side = !(f_side == "def" || f_side == "hlp" || f_side == "jud" || f_side == "jur"); + ui_vp_evidence_display->show_evidence(f_image, is_left_side, ui_sfx_slider->value()); + } + + int emote_mod = m_chatmessage[EMOTE_MOD].toInt(); + + QString side = m_chatmessage[SIDE]; + + if (emote_mod == 5 || + emote_mod == 6) + { + ui_vp_desk->hide(); + ui_vp_legacy_desk->hide(); + + // Since we're zooming, hide the second character, and centre the first. + ui_vp_sideplayer_char->hide(); + ui_vp_player_char->move(0,0); + + if (side == "pro" || + side == "hlp" || + side == "wit") + ui_vp_speedlines->play("prosecution_speedlines"); + else + ui_vp_speedlines->play("defense_speedlines"); + + } + + int f_anim_state = 0; + //BLUE is from an enum in datatypes.h + bool text_is_blue = m_chatmessage[TEXT_COLOR].toInt() == BLUE; + + if (!text_is_blue && text_state == 1) + { + //talking + f_anim_state = 2; + entire_message_is_blue = false; + } + else + { + //idle + f_anim_state = 3; + entire_message_is_blue = true; + } + + if (f_anim_state <= anim_state) + return; + + ui_vp_player_char->stop(); + QString f_char = m_chatmessage[CHAR_NAME]; + QString f_emote = m_chatmessage[EMOTE]; + + if (f_anim_state == 2) { + ui_vp_player_char->play_talking(f_char, f_emote); + anim_state = 2; + } + else + { + ui_vp_player_char->play_idle(f_char, f_emote); + anim_state = 3; + } + + QString f_message = m_chatmessage[MESSAGE]; + QStringList call_words = ao_app->get_call_words(); + + for (QString word : call_words) + { + if (f_message.contains(word, Qt::CaseInsensitive)) + { + modcall_player->play(ao_app->get_sfx("word_call")); + ao_app->alert(this); + + break; + } + } + +} + +QString Courtroom::filter_ic_text(QString p_text) +{ + // Get rid of centering. + if(p_text.startsWith(": ~~")) + { + // Don't forget, the p_text part actually everything after the name! + // Hence why we check for ': ~~'. + + // Let's remove those two tildes, then. + // : _ ~ ~ + // 0 1 2 3 + p_text.remove(2,2); + } + + // Get rid of the inline-colouring. + // I know, I know, excessive code duplication. + // Nobody looks in here, I'm fine. + int trick_check_pos = 0; + bool ic_next_is_not_special = false; + QString f_character = p_text.at(trick_check_pos); + std::stack ic_colour_stack; + while (trick_check_pos < p_text.size()) + { + f_character = p_text.at(trick_check_pos); + + // Escape character. + if (f_character == "\\" and !ic_next_is_not_special) + { + ic_next_is_not_special = true; + p_text.remove(trick_check_pos,1); + } + + // Text speed modifier. + else if (f_character == "{" and !ic_next_is_not_special) + { + p_text.remove(trick_check_pos,1); + } + else if (f_character == "}" and !ic_next_is_not_special) + { + p_text.remove(trick_check_pos,1); + } + + // Orange inline colourisation. + else if (f_character == "|" and !ic_next_is_not_special) + { + if (!ic_colour_stack.empty()) + { + if (ic_colour_stack.top() == INLINE_ORANGE) + { + ic_colour_stack.pop(); + p_text.remove(trick_check_pos,1); + } + else + { + ic_colour_stack.push(INLINE_ORANGE); + p_text.remove(trick_check_pos,1); + } + } + else + { + ic_colour_stack.push(INLINE_ORANGE); + p_text.remove(trick_check_pos,1); + } + } + + // Blue inline colourisation. + else if (f_character == "(" and !ic_next_is_not_special) + { + ic_colour_stack.push(INLINE_BLUE); + trick_check_pos++; + } + else if (f_character == ")" and !ic_next_is_not_special + and !ic_colour_stack.empty()) + { + if (ic_colour_stack.top() == INLINE_BLUE) + { + ic_colour_stack.pop(); + trick_check_pos++; + } + else + { + ic_next_is_not_special = true; + } + } + + // Grey inline colourisation. + else if (f_character == "[" and !ic_next_is_not_special) + { + ic_colour_stack.push(INLINE_GREY); + trick_check_pos++; + } + else if (f_character == "]" and !ic_next_is_not_special + and !ic_colour_stack.empty()) + { + if (ic_colour_stack.top() == INLINE_GREY) + { + ic_colour_stack.pop(); + trick_check_pos++; + } + else + { + ic_next_is_not_special = true; + } + } + + // Green inline colourisation. + else if (f_character == "`" and !ic_next_is_not_special) + { + if (!ic_colour_stack.empty()) + { + if (ic_colour_stack.top() == INLINE_GREEN) + { + ic_colour_stack.pop(); + p_text.remove(trick_check_pos,1); + } + else + { + ic_colour_stack.push(INLINE_GREEN); + p_text.remove(trick_check_pos,1); + } + } + else + { + ic_colour_stack.push(INLINE_GREEN); + p_text.remove(trick_check_pos,1); + } + } + else + { + trick_check_pos++; + ic_next_is_not_special = false; + } + } + + return p_text; +} + +void Courtroom::append_ic_text(QString p_text, QString p_name, bool is_songchange) +{ + QTextCharFormat bold; + QTextCharFormat normal; + QTextCharFormat italics; + bold.setFontWeight(QFont::Bold); + normal.setFontWeight(QFont::Normal); + italics.setFontItalic(true); + const QTextCursor old_cursor = ui_ic_chatlog->textCursor(); + const int old_scrollbar_value = ui_ic_chatlog->verticalScrollBar()->value(); + + if (!is_songchange) + p_text = filter_ic_text(p_text); + + if (log_goes_downwards) + { + const bool is_scrolled_down = old_scrollbar_value == ui_ic_chatlog->verticalScrollBar()->maximum(); + + ui_ic_chatlog->moveCursor(QTextCursor::End); + + if (!first_message_sent) + { + ui_ic_chatlog->textCursor().insertText(p_name, bold); + first_message_sent = true; + } + else + { + ui_ic_chatlog->textCursor().insertText('\n' + p_name, bold); + } + + if (is_songchange) + { + ui_ic_chatlog->textCursor().insertText(" has played a song: ", normal); + ui_ic_chatlog->textCursor().insertText(p_text + ".", italics); + } + else + { + ui_ic_chatlog->textCursor().insertText(p_text, normal); + } + + // If we got too many blocks in the current log, delete some from the top. + while (ui_ic_chatlog->document()->blockCount() > log_maximum_blocks && log_maximum_blocks > 0) + { + ui_ic_chatlog->moveCursor(QTextCursor::Start); + ui_ic_chatlog->textCursor().select(QTextCursor::BlockUnderCursor); + ui_ic_chatlog->textCursor().removeSelectedText(); + ui_ic_chatlog->textCursor().deleteChar(); + //qDebug() << ui_ic_chatlog->document()->blockCount() << " < " << log_maximum_blocks; + } + + if (old_cursor.hasSelection() || !is_scrolled_down) + { + // The user has selected text or scrolled away from the bottom: maintain position. + ui_ic_chatlog->setTextCursor(old_cursor); + ui_ic_chatlog->verticalScrollBar()->setValue(old_scrollbar_value); + } + else + { + // The user hasn't selected any text and the scrollbar is at the bottom: scroll to the bottom. + ui_ic_chatlog->moveCursor(QTextCursor::End); + ui_ic_chatlog->verticalScrollBar()->setValue(ui_ic_chatlog->verticalScrollBar()->maximum()); + } + } + else + { + const bool is_scrolled_up = old_scrollbar_value == ui_ic_chatlog->verticalScrollBar()->minimum(); + + ui_ic_chatlog->moveCursor(QTextCursor::Start); + + ui_ic_chatlog->textCursor().insertText(p_name, bold); + + if (is_songchange) + { + ui_ic_chatlog->textCursor().insertText(" has played a song: ", normal); + ui_ic_chatlog->textCursor().insertText(p_text + "." + '\n', italics); + } + else + { + ui_ic_chatlog->textCursor().insertText(p_text + '\n', normal); + } + + // If we got too many blocks in the current log, delete some from the bottom. + while (ui_ic_chatlog->document()->blockCount() > log_maximum_blocks && log_maximum_blocks > 0) + { + ui_ic_chatlog->moveCursor(QTextCursor::End); + ui_ic_chatlog->textCursor().select(QTextCursor::BlockUnderCursor); + ui_ic_chatlog->textCursor().removeSelectedText(); + ui_ic_chatlog->textCursor().deletePreviousChar(); + //qDebug() << ui_ic_chatlog->document()->blockCount() << " < " << log_maximum_blocks; + } + + if (old_cursor.hasSelection() || !is_scrolled_up) + { + // The user has selected text or scrolled away from the top: maintain position. + ui_ic_chatlog->setTextCursor(old_cursor); + ui_ic_chatlog->verticalScrollBar()->setValue(old_scrollbar_value); + } + else + { + // The user hasn't selected any text and the scrollbar is at the top: scroll to the top. + ui_ic_chatlog->moveCursor(QTextCursor::Start); + ui_ic_chatlog->verticalScrollBar()->setValue(ui_ic_chatlog->verticalScrollBar()->minimum()); + } + } +} + +void Courtroom::play_preanim(bool noninterrupting) +{ + QString f_char = m_chatmessage[CHAR_NAME]; + QString f_preanim = m_chatmessage[PRE_EMOTE]; + + //all time values in char.inis are multiplied by a constant(time_mod) to get the actual time + int ao2_duration = ao_app->get_ao2_preanim_duration(f_char, f_preanim); + int text_delay = ao_app->get_text_delay(f_char, f_preanim) * time_mod; + int sfx_delay = m_chatmessage[SFX_DELAY].toInt() * 60; + + int preanim_duration; + + if (ao2_duration < 0) + preanim_duration = ao_app->get_preanim_duration(f_char, f_preanim); + else + preanim_duration = ao2_duration; + + sfx_delay_timer->start(sfx_delay); + QString anim_to_find = ao_app->get_image_suffix(ao_app->get_character_path(f_char, f_preanim)); + if (!file_exists(anim_to_find) || + preanim_duration < 0) + { + if (noninterrupting) + anim_state = 4; + else + anim_state = 1; + preanim_done(); + qDebug() << "could not find " + anim_to_find; + return; + } + + ui_vp_player_char->play_pre(f_char, f_preanim, preanim_duration); + + if (noninterrupting) + anim_state = 4; + else + anim_state = 1; + + if (text_delay >= 0) + text_delay_timer->start(text_delay); + + if (noninterrupting) + handle_chatmessage_3(); +} + +void Courtroom::preanim_done() +{ + anim_state = 1; + handle_chatmessage_3(); +} + +void Courtroom::realization_done() +{ + ui_vp_realization->hide(); +} + +void Courtroom::start_chat_ticking() +{ + //we need to ensure that the text isn't already ticking because this function can be called by two logic paths + if (text_state != 0) + return; + + if (m_chatmessage[REALIZATION] == "1") + { + realization_timer->start(60); + ui_vp_realization->show(); + sfx_player->play(ao_app->get_custom_realization(m_chatmessage[CHAR_NAME])); + } + + ui_vp_message->clear(); + set_text_color(); + rainbow_counter = 0; + + if (chatmessage_is_empty) + { + //since the message is empty, it's technically done ticking + text_state = 2; + return; + } + + // At this point, we'd do well to clear the inline colour stack. + // This stops it from flowing into next messages. + while (!inline_colour_stack.empty()) + { + inline_colour_stack.pop(); + } + + ui_vp_chatbox->show(); + + tick_pos = 0; + blip_pos = 0; + + // Just in case we somehow got inline blue text left over from a previous message, + // let's set it to false. + inline_blue_depth = 0; + + // At the start of every new message, we set the text speed to the default. + current_display_speed = 3; + chat_tick_timer->start(message_display_speed[current_display_speed]); + + QString f_gender = ao_app->get_gender(m_chatmessage[CHAR_NAME]); + + blip_player->set_blips("sfx-blip" + f_gender + ".wav"); + + //means text is currently ticking + text_state = 1; +} + +void Courtroom::chat_tick() +{ + //note: this is called fairly often(every 60 ms when char is talking) + //do not perform heavy operations here + + QString f_message = m_chatmessage[MESSAGE]; + + // Due to our new text speed system, we always need to stop the timer now. + chat_tick_timer->stop(); + + // Stops blips from playing when we have a formatting option. + bool formatting_char = false; + + // If previously, we have detected that the message is centered, now + // is the time to remove those two tildes at the start. + if (message_is_centered) + { + f_message.remove(0,2); + } + + if (tick_pos >= f_message.size()) + { + text_state = 2; + if (anim_state != 4) + { + anim_state = 3; + ui_vp_player_char->play_idle(m_chatmessage[CHAR_NAME], m_chatmessage[EMOTE]); + } + } + + else + { + QString f_character = f_message.at(tick_pos); + f_character = f_character.toHtmlEscaped(); + + if (f_character == " ") + ui_vp_message->insertPlainText(" "); + + // Escape character. + else if (f_character == "\\" and !next_character_is_not_special) + { + next_character_is_not_special = true; + formatting_char = true; + } + + // Text speed modifier. + else if (f_character == "{" and !next_character_is_not_special) + { + // ++, because it INCREASES delay! + current_display_speed++; + formatting_char = true; + } + else if (f_character == "}" and !next_character_is_not_special) + { + current_display_speed--; + formatting_char = true; + } + + // Orange inline colourisation. + else if (f_character == "|" and !next_character_is_not_special) + { + if (!inline_colour_stack.empty()) + { + if (inline_colour_stack.top() == INLINE_ORANGE) + { + inline_colour_stack.pop(); + } + else + { + inline_colour_stack.push(INLINE_ORANGE); + } + } + else + { + inline_colour_stack.push(INLINE_ORANGE); + } + formatting_char = true; + } + + // Blue inline colourisation. + else if (f_character == "(" and !next_character_is_not_special) + { + inline_colour_stack.push(INLINE_BLUE); + ui_vp_message->insertHtml("" + f_character + ""); + + // Increase how deep we are in inline blues. + inline_blue_depth++; + + // Here, we check if the entire message is blue. + // If it isn't, we stop talking. + if (!entire_message_is_blue and anim_state != 4) + { + QString f_char = m_chatmessage[CHAR_NAME]; + QString f_emote = m_chatmessage[EMOTE]; + ui_vp_player_char->play_idle(f_char, f_emote); + } + } + else if (f_character == ")" and !next_character_is_not_special + and !inline_colour_stack.empty()) + { + if (inline_colour_stack.top() == INLINE_BLUE) + { + inline_colour_stack.pop(); + ui_vp_message->insertHtml("" + f_character + ""); + + // Decrease how deep we are in inline blues. + // Just in case, we do a check if we're above zero, but we should be. + if (inline_blue_depth > 0) + { + inline_blue_depth--; + // Here, we check if the entire message is blue. + // If it isn't, we start talking if we have completely climbed out of inline blues. + if (!entire_message_is_blue) + { + // We should only go back to talking if we're out of inline blues, not during a non. int. pre, and not on the last character. + if (inline_blue_depth == 0 and anim_state != 4 and !(tick_pos+1 >= f_message.size())) + { + QString f_char = m_chatmessage[CHAR_NAME]; + QString f_emote = m_chatmessage[EMOTE]; + ui_vp_player_char->play_talking(f_char, f_emote); + } + } + } + } + else + { + next_character_is_not_special = true; + tick_pos--; + } + } + + // Grey inline colourisation. + else if (f_character == "[" and !next_character_is_not_special) + { + inline_colour_stack.push(INLINE_GREY); + ui_vp_message->insertHtml("" + f_character + ""); + } + else if (f_character == "]" and !next_character_is_not_special + and !inline_colour_stack.empty()) + { + if (inline_colour_stack.top() == INLINE_GREY) + { + inline_colour_stack.pop(); + ui_vp_message->insertHtml("" + f_character + ""); + } + else + { + next_character_is_not_special = true; + tick_pos--; + } + } + + // Green inline colourisation. + else if (f_character == "`" and !next_character_is_not_special) + { + if (!inline_colour_stack.empty()) + { + if (inline_colour_stack.top() == INLINE_GREEN) + { + inline_colour_stack.pop(); + formatting_char = true; + } + else + { + inline_colour_stack.push(INLINE_GREEN); + formatting_char = true; + } + } + else + { + inline_colour_stack.push(INLINE_GREEN); + formatting_char = true; + } + } + else + { + next_character_is_not_special = false; + if (!inline_colour_stack.empty()) + { + switch (inline_colour_stack.top()) { + case INLINE_ORANGE: + ui_vp_message->insertHtml("" + f_character + ""); + break; + case INLINE_BLUE: + ui_vp_message->insertHtml("" + f_character + ""); + break; + case INLINE_GREEN: + ui_vp_message->insertHtml("" + f_character + ""); + break; + case INLINE_GREY: + ui_vp_message->insertHtml("" + f_character + ""); + break; + default: + ui_vp_message->insertHtml(f_character); + break; + } + + } + else + { + if (m_chatmessage[TEXT_COLOR].toInt() == RAINBOW) + { + QString html_color; + + switch (rainbow_counter) + { + case 0: + html_color = get_text_color(QString::number(RED)).name(); + break; + case 1: + html_color = get_text_color(QString::number(ORANGE)).name(); + break; + case 2: + html_color = get_text_color(QString::number(YELLOW)).name(); + break; + case 3: + html_color = get_text_color(QString::number(GREEN)).name(); + break; + default: + html_color = get_text_color(QString::number(BLUE)).name(); + rainbow_counter = -1; + } + + ++rainbow_counter; + + ui_vp_message->insertHtml("" + f_character + ""); + } + else + ui_vp_message->insertHtml(f_character); + } + + if (message_is_centered) + { + ui_vp_message->setAlignment(Qt::AlignCenter); + } + else + { + ui_vp_message->setAlignment(Qt::AlignLeft); + } + } + + QScrollBar *scroll = ui_vp_message->verticalScrollBar(); + scroll->setValue(scroll->maximum()); + + if(blank_blip) + qDebug() << "blank_blip found true"; + + if (f_message.at(tick_pos) != ' ' || blank_blip) + { + + if (blip_pos % blip_rate == 0 && !formatting_char) + { + blip_pos = 0; + blip_player->blip_tick(); + } + + ++blip_pos; + } + + ++tick_pos; + + // Restart the timer, but according to the newly set speeds, if there were any. + // Keep the speed at bay. + if (current_display_speed < 0) + { + current_display_speed = 0; + } + + if (current_display_speed > 6) + { + current_display_speed = 6; + } + + // If we had a formatting char, we shouldn't wait so long again, as it won't appear! + if (formatting_char) + { + chat_tick_timer->start(1); + } + else + { + chat_tick_timer->start(message_display_speed[current_display_speed]); + } + + } +} + +void Courtroom::show_testimony() +{ + if (!testimony_in_progress || m_chatmessage[SIDE] != "wit") + return; + + ui_vp_testimony->show(); + + testimony_show_timer->start(testimony_show_time); +} + +void Courtroom::hide_testimony() +{ + ui_vp_testimony->hide(); + + if (!testimony_in_progress) + return; + + testimony_hide_timer->start(testimony_hide_time); +} + +void Courtroom::play_sfx() +{ + QString sfx_name = m_chatmessage[SFX_NAME]; + + if (sfx_name == "1") + return; + + sfx_player->play(ao_app->get_sfx_suffix(sfx_name)); +} + +void Courtroom::set_scene() +{ + if (testimony_in_progress) + show_testimony(); + + //witness is default if pos is invalid + QString f_background = "witnessempty"; + QString f_desk_image = "stand"; + QString f_desk_mod = m_chatmessage[DESK_MOD]; + QString f_side = m_chatmessage[SIDE]; + + if (f_side == "def") + { + f_background = "defenseempty"; + if (is_ao2_bg) + f_desk_image = "defensedesk"; + else + f_desk_image = "bancodefensa"; + } + else if (f_side == "pro") + { + f_background = "prosecutorempty"; + if (is_ao2_bg) + f_desk_image = "prosecutiondesk"; + else + f_desk_image = "bancoacusacion"; + } + else if (f_side == "jud") + { + f_background = "judgestand"; + f_desk_image = "judgedesk"; + } + else if (f_side == "hld") + { + f_background = "helperstand"; + f_desk_image = "helperdesk"; + } + else if (f_side == "hlp") + { + f_background = "prohelperstand"; + f_desk_image = "prohelperdesk"; + } + else if (f_side == "jur" && (file_exists(ao_app->get_background_path("jurystand.png")) || + file_exists(ao_app->get_background_path("jurystand.gif")))) + { + f_background = "jurystand"; + f_desk_image = "jurydesk"; + } + else if (f_side == "sea" && (file_exists(ao_app->get_background_path("seancestand.png")) || + file_exists(ao_app->get_background_path("seancestand.gif")))) + { + f_background = "seancestand"; + f_desk_image = "seancedesk"; + } + else + { + if (is_ao2_bg) + f_desk_image = "stand"; + else + f_desk_image = "estrado"; + } + + ui_vp_background->set_image(f_background); + ui_vp_desk->set_image(f_desk_image); + ui_vp_legacy_desk->set_legacy_desk(f_desk_image); + + if (f_desk_mod == "0" || (f_desk_mod != "1" && + (f_side == "jud" || + f_side == "hld" || + f_side == "hlp"))) + { + ui_vp_desk->hide(); + ui_vp_legacy_desk->hide(); + } + else if (is_ao2_bg || (f_side == "jud" || + f_side == "hld" || + f_side == "hlp")) + { + ui_vp_legacy_desk->hide(); + ui_vp_desk->show(); + } + else + { + if (f_side == "wit") + { + ui_vp_desk->show(); + ui_vp_legacy_desk->hide(); + } + else + { + ui_vp_desk->hide(); + ui_vp_legacy_desk->show(); + } + } +} + +void Courtroom::set_text_color() +{ + QColor textcolor = ao_app->get_chat_color(m_chatmessage[TEXT_COLOR], ao_app->get_chat(m_chatmessage[CHAR_NAME])); + + ui_vp_message->setTextBackgroundColor(QColor(0,0,0,0)); + ui_vp_message->setTextColor(textcolor); + + QString style = "background-color: rgba(0, 0, 0, 0);"; + style.append("color: rgb("); + style.append(QString::number(textcolor.red())); + style.append(", "); + style.append(QString::number(textcolor.green())); + style.append(", "); + style.append(QString::number(textcolor.blue())); + style.append(")"); + + ui_vp_message->setStyleSheet(style); +} + +QColor Courtroom::get_text_color(QString color) +{ + return ao_app->get_chat_color(color, ao_app->get_chat(m_chatmessage[CHAR_NAME])); +} + +void Courtroom::set_ip_list(QString p_list) +{ + QString f_list = p_list.replace("|", ":").replace("*", "\n"); + + ui_server_chatlog->append(f_list); +} + +void Courtroom::set_mute(bool p_muted, int p_cid) +{ + if (p_cid != m_cid && p_cid != -1) + return; + + if (p_muted) + ui_muted->show(); + else + { + ui_muted->hide(); + ui_ic_chat_message->setFocus(); + } + + ui_muted->resize(ui_ic_chat_message->width(), ui_ic_chat_message->height()); + ui_muted->set_image("muted.png"); + + is_muted = p_muted; + ui_ic_chat_message->setEnabled(!p_muted); +} + +void Courtroom::set_ban(int p_cid) +{ + if (p_cid != m_cid && p_cid != -1) + return; + + call_notice("You have been banned."); + + ao_app->construct_lobby(); + ao_app->destruct_courtroom(); +} + +void Courtroom::handle_song(QStringList *p_contents) +{ + QStringList f_contents = *p_contents; + + if (f_contents.size() < 2) + return; + + QString f_song = f_contents.at(0); + QString f_song_clear = f_song; + f_song_clear = f_song_clear.left(f_song_clear.lastIndexOf(".")); + int n_char = f_contents.at(1).toInt(); + + if (n_char < 0 || n_char >= char_list.size()) + { + music_player->play(f_song); + } + else + { + QString str_char = char_list.at(n_char).name; + QString str_show = char_list.at(n_char).name; + + if (p_contents->length() > 2) + { + str_show = p_contents->at(2); + } + + if (!mute_map.value(n_char)) + { + chatlogpiece* temp = new chatlogpiece(str_char, str_show, f_song, true); + ic_chatlog_history.append(*temp); + + while(ic_chatlog_history.size() > log_maximum_blocks && log_maximum_blocks > 0) + { + ic_chatlog_history.removeFirst(); + } + + append_ic_text(f_song_clear, str_show, true); + music_player->play(f_song); + } + } +} + +void Courtroom::handle_wtce(QString p_wtce, int variant) +{ + QString sfx_file = "courtroom_sounds.ini"; + + //witness testimony + if (p_wtce == "testimony1") + { + sfx_player->play(ao_app->get_sfx("witness_testimony")); + ui_vp_wtce->play("witnesstestimony"); + testimony_in_progress = true; + show_testimony(); + } + //cross examination + else if (p_wtce == "testimony2") + { + sfx_player->play(ao_app->get_sfx("cross_examination")); + ui_vp_wtce->play("crossexamination"); + testimony_in_progress = false; + } + else if (p_wtce == "judgeruling") + { + if (variant == 0) + { + sfx_player->play(ao_app->get_sfx("not_guilty")); + ui_vp_wtce->play("notguilty"); + testimony_in_progress = false; + } + else if (variant == 1) { + sfx_player->play(ao_app->get_sfx("guilty")); + ui_vp_wtce->play("guilty"); + testimony_in_progress = false; + } + } +} + +void Courtroom::set_hp_bar(int p_bar, int p_state) +{ + if (p_state < 0 || p_state > 10) + return; + + if (p_bar == 1) + { + ui_defense_bar->set_image("defensebar" + QString::number(p_state) + ".png"); + defense_bar_state = p_state; + } + else if (p_bar == 2) + { + ui_prosecution_bar->set_image("prosecutionbar" + QString::number(p_state) + ".png"); + prosecution_bar_state = p_state; + } +} + +void Courtroom::toggle_judge_buttons(bool is_on) +{ + if (is_on) + { + ui_witness_testimony->show(); + ui_cross_examination->show(); + ui_guilty->show(); + ui_not_guilty->show(); + ui_defense_minus->show(); + ui_defense_plus->show(); + ui_prosecution_minus->show(); + ui_prosecution_plus->show(); + } + else + { + ui_witness_testimony->hide(); + ui_cross_examination->hide(); + ui_guilty->hide(); + ui_not_guilty->hide(); + ui_defense_minus->hide(); + ui_defense_plus->hide(); + ui_prosecution_minus->hide(); + ui_prosecution_plus->hide(); + } +} + +void Courtroom::mod_called(QString p_ip) +{ + ui_server_chatlog->append(p_ip); + if (ui_guard->isChecked()) + { + modcall_player->play(ao_app->get_sfx("mod_call")); + ao_app->alert(this); + } +} + +void Courtroom::case_called(QString msg, bool def, bool pro, bool jud, bool jur, bool steno) +{ + 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_sfx("case_call")); + ao_app->alert(this); + } + } +} + +void Courtroom::on_ooc_return_pressed() +{ + QString ooc_message = ui_ooc_chat_message->text(); + + if (ooc_message == "" || ui_ooc_chat_name->text() == "") + return; + + if (ooc_message.startsWith("/pos")) + { + if (ooc_message == "/pos jud") + { + toggle_judge_buttons(true); + } + else + { + toggle_judge_buttons(false); + } + } + else if (ooc_message.startsWith("/login")) + { + ui_guard->show(); + append_server_chatmessage("CLIENT", "You were granted the Guard button.", "1"); + } + else if (ooc_message.startsWith("/rainbow") && ao_app->yellow_text_enabled && !rainbow_appended) + { + //ui_text_color->addItem("Rainbow"); + ui_ooc_chat_message->clear(); + //rainbow_appended = true; + append_server_chatmessage("CLIENT", "This does nohing, but there you go.", "1"); + return; + } + else if (ooc_message.startsWith("/settings")) + { + ui_ooc_chat_message->clear(); + ao_app->call_settings_menu(); + append_server_chatmessage("CLIENT", "You opened the settings menu.", "1"); + return; + } + else if (ooc_message.startsWith("/pair")) + { + ui_ooc_chat_message->clear(); + ooc_message.remove(0,6); + + bool ok; + int whom = ooc_message.toInt(&ok); + if (ok) + { + if (whom > -1) + { + other_charid = whom; + QString msg = "You will now pair up with "; + msg.append(char_list.at(whom).name); + msg.append(" if they also choose your character in return."); + append_server_chatmessage("CLIENT", msg, "1"); + } + else + { + append_server_chatmessage("CLIENT", "You are no longer paired with anyone.", "1"); + } + } + else + { + append_server_chatmessage("CLIENT", "Are you sure you typed that well? The char ID could not be recognised.", "1"); + } + return; + } + else if (ooc_message.startsWith("/offset")) + { + 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) + { + offset_with_pair = off; + QString msg = "You have set your offset to "; + msg.append(QString::number(off)); + msg.append("%."); + append_server_chatmessage("CLIENT", msg, "1"); + } + else + { + append_server_chatmessage("CLIENT", "Your offset must be between -100% and 100%!", "1"); + } + } + else + { + append_server_chatmessage("CLIENT", "That offset does not look like one.", "1"); + } + return; + } + else if (ooc_message.startsWith("/switch_am")) + { + append_server_chatmessage("CLIENT", "You switched your music and area list.", "1"); + on_switch_area_music_clicked(); + ui_ooc_chat_message->clear(); + return; + } + else if (ooc_message.startsWith("/enable_blocks")) + { + append_server_chatmessage("CLIENT", "You have forcefully enabled features that the server may not support. You may not be able to talk IC, or worse, because of this.", "1"); + ao_app->cccc_ic_support_enabled = true; + ao_app->arup_enabled = true; + ao_app->modcall_reason_enabled = true; + on_reload_theme_clicked(); + ui_ooc_chat_message->clear(); + return; + } + else if (ooc_message.startsWith("/non_int_pre")) + { + if (ui_pre_non_interrupt->isChecked()) + append_server_chatmessage("CLIENT", "Your pre-animations interrupt again.", "1"); + else + append_server_chatmessage("CLIENT", "Your pre-animations will not interrupt text.", "1"); + ui_pre_non_interrupt->setChecked(!ui_pre_non_interrupt->isChecked()); + ui_ooc_chat_message->clear(); + return; + } + else if (ooc_message.startsWith("/save_chatlog")) + { + QFile file("chatlog.txt"); + + if (!file.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate)) + { + append_server_chatmessage("CLIENT", "Couldn't open chatlog.txt to write into.", "1"); + ui_ooc_chat_message->clear(); + return; + } + + QTextStream out(&file); + + foreach (chatlogpiece item, ic_chatlog_history) { + out << item.get_full() << '\n'; + } + + file.close(); + + append_server_chatmessage("CLIENT", "The IC chatlog has been saved.", "1"); + ui_ooc_chat_message->clear(); + return; + } + else if (ooc_message.startsWith("/load_case")) + { + QStringList command = ooc_message.split(" ", QString::SkipEmptyParts); + + QDir casefolder("base/cases"); + if (!casefolder.exists()) + { + QDir::current().mkdir("base/" + casefolder.dirName()); + append_server_chatmessage("CLIENT", "You don't have a `base/cases/` folder! It was just made for you, but seeing as it WAS just made for you, it's likely the case file you're looking for can't be found in there.", "1"); + ui_ooc_chat_message->clear(); + return; + } + QStringList caseslist = casefolder.entryList(); + caseslist.removeOne("."); + caseslist.removeOne(".."); + caseslist.replaceInStrings(".ini",""); + + if (command.size() < 2) + { + append_server_chatmessage("CLIENT", "You need to give a filename to load (extension not needed)! Make sure that it is in the `base/cases/` folder, and that it is a correctly formatted ini.\nCases you can load: " + caseslist.join(", "), "1"); + ui_ooc_chat_message->clear(); + return; + } + + + if (command.size() > 2) + { + append_server_chatmessage("CLIENT", "Too many arguments to load a case! You only need one filename, without extension.", "1"); + ui_ooc_chat_message->clear(); + return; + } + + QSettings casefile("base/cases/" + command[1] + ".ini", QSettings::IniFormat); + + QString caseauth = casefile.value("author", "").value(); + QString casedoc = casefile.value("doc", "").value(); + QString cmdoc = casefile.value("cmdoc", "").value(); + QString casestatus = casefile.value("status", "").value(); + + if (!caseauth.isEmpty()) + append_server_chatmessage("CLIENT", "Case made by " + caseauth + ".", "1"); + if (!casedoc.isEmpty()) + ao_app->send_server_packet(new AOPacket("CT#" + ui_ooc_chat_name->text() + "#/doc " + casedoc + "#%")); + if (!casestatus.isEmpty()) + ao_app->send_server_packet(new AOPacket("CT#" + ui_ooc_chat_name->text() + "#/status " + casestatus + "#%")); + if (!cmdoc.isEmpty()) + append_server_chatmessage("CLIENT", "Navigate to " + cmdoc + " for the CM doc.", "1"); + + for (int i = local_evidence_list.size() - 1; i >= 0; i--) { + ao_app->send_server_packet(new AOPacket("DE#" + QString::number(i) + "#%")); + } + + foreach (QString evi, casefile.childGroups()) { + if (evi == "General") + continue; + + QStringList f_contents; + + f_contents.append(casefile.value(evi + "/name", "UNKNOWN").value()); + f_contents.append(casefile.value(evi + "/description", "UNKNOWN").value()); + f_contents.append(casefile.value(evi + "/image", "UNKNOWN.png").value()); + + ao_app->send_server_packet(new AOPacket("PE", f_contents)); + } + + append_server_chatmessage("CLIENT", "Your case \"" + command[1] + "\" was loaded!", "1"); + ui_ooc_chat_message->clear(); + return; + } + + QStringList packet_contents; + packet_contents.append(ui_ooc_chat_name->text()); + packet_contents.append(ooc_message); + + AOPacket *f_packet = new AOPacket("CT", packet_contents); + + if (server_ooc) + ao_app->send_server_packet(f_packet); + else + ao_app->send_ms_packet(f_packet); + + ui_ooc_chat_message->clear(); + + ui_ooc_chat_message->setFocus(); +} + +void Courtroom::on_ooc_toggle_clicked() +{ + if (server_ooc) + { + ui_ms_chatlog->show(); + ui_server_chatlog->hide(); + ui_ooc_toggle->setText("Master"); + + server_ooc = false; + } + else + { + ui_ms_chatlog->hide(); + ui_server_chatlog->show(); + ui_ooc_toggle->setText("Server"); + + server_ooc = true; + } +} + +void Courtroom::on_music_search_edited(QString p_text) +{ + //preventing compiler warnings + p_text += "a"; + list_music(); + list_areas(); +} + +void Courtroom::on_pos_dropdown_changed(int p_index) +{ + ui_ic_chat_message->setFocus(); + + if (p_index < 0 || p_index > 5) + return; + + toggle_judge_buttons(false); + + QString f_pos; + + switch (p_index) + { + case 0: + f_pos = "wit"; + break; + case 1: + f_pos = "def"; + break; + case 2: + f_pos = "pro"; + break; + case 3: + f_pos = "jud"; + toggle_judge_buttons(true); + break; + case 4: + f_pos = "hld"; + break; + case 5: + f_pos = "hlp"; + break; + default: + f_pos = ""; + } + + if (f_pos == "" || ui_ooc_chat_name->text() == "") + return; + + ao_app->send_server_packet(new AOPacket("CT#" + ui_ooc_chat_name->text() + "#/pos " + f_pos + "#%")); +} + +void Courtroom::on_mute_list_clicked(QModelIndex p_index) +{ + QListWidgetItem *f_item = ui_mute_list->item(p_index.row()); + QString f_char = f_item->text(); + QString real_char; + + if (f_char.endsWith(" [x]")) + real_char = f_char.left(f_char.size() - 4); + else + real_char = f_char; + + int f_cid = -1; + + for (int n_char = 0 ; n_char < char_list.size() ; n_char++) + { + if (char_list.at(n_char).name == real_char) + f_cid = n_char; + } + + if (f_cid < 0 || f_cid >= char_list.size()) + { + qDebug() << "W: " << real_char << " not present in char_list"; + return; + } + + if (mute_map.value(f_cid)) + { + mute_map.insert(f_cid, false); + f_item->setText(real_char); + } + else + { + mute_map.insert(f_cid, true); + f_item->setText(real_char + " [x]"); + } +} + +void Courtroom::on_pair_list_clicked(QModelIndex p_index) +{ + QListWidgetItem *f_item = ui_pair_list->item(p_index.row()); + QString f_char = f_item->text(); + QString real_char; + + if (f_char.endsWith(" [x]")) + { + real_char = f_char.left(f_char.size() - 4); + f_item->setText(real_char); + } + else + real_char = f_char; + + int f_cid = -1; + + for (int n_char = 0 ; n_char < char_list.size() ; n_char++) + { + if (char_list.at(n_char).name == real_char) + f_cid = n_char; + } + + if (f_cid < 0 || f_cid >= char_list.size()) + { + qDebug() << "W: " << real_char << " not present in char_list"; + return; + } + + other_charid = f_cid; + + // Redo the character list. + QStringList sorted_pair_list; + + for (char_type i_char : char_list) + sorted_pair_list.append(i_char.name); + + sorted_pair_list.sort(); + + for (int i = 0; i < ui_pair_list->count(); i++) { + ui_pair_list->item(i)->setText(sorted_pair_list.at(i)); + } + + f_item->setText(real_char + " [x]"); +} + +void Courtroom::on_music_list_double_clicked(QModelIndex p_model) +{ + if (is_muted) + return; + + QString p_song = music_list.at(music_row_to_number.at(p_model.row())); + + if (!ui_ic_chat_name->text().isEmpty() && ao_app->cccc_ic_support_enabled) + { + ao_app->send_server_packet(new AOPacket("MC#" + p_song + "#" + QString::number(m_cid) + "#" + ui_ic_chat_name->text() + "#%"), false); + } + else + { + ao_app->send_server_packet(new AOPacket("MC#" + p_song + "#" + QString::number(m_cid) + "#%"), false); + } +} + +void Courtroom::on_area_list_double_clicked(QModelIndex p_model) +{ + QString p_area = area_list.at(area_row_to_number.at(p_model.row())); + ao_app->send_server_packet(new AOPacket("MC#" + p_area + "#" + QString::number(m_cid) + "#%"), false); +} + +void Courtroom::on_hold_it_clicked() +{ + if (objection_state == 1) + { + ui_hold_it->set_image("holdit.png"); + objection_state = 0; + } + else + { + ui_objection->set_image("objection.png"); + ui_take_that->set_image("takethat.png"); + ui_custom_objection->set_image("custom.png"); + + ui_hold_it->set_image("holdit_selected.png"); + objection_state = 1; + } + + ui_ic_chat_message->setFocus(); +} + +void Courtroom::on_objection_clicked() +{ + if (objection_state == 2) + { + ui_objection->set_image("objection.png"); + objection_state = 0; + } + else + { + ui_hold_it->set_image("holdit.png"); + ui_take_that->set_image("takethat.png"); + ui_custom_objection->set_image("custom.png"); + + ui_objection->set_image("objection_selected.png"); + objection_state = 2; + } + + ui_ic_chat_message->setFocus(); +} + +void Courtroom::on_take_that_clicked() +{ + if (objection_state == 3) + { + ui_take_that->set_image("takethat.png"); + objection_state = 0; + } + else + { + ui_objection->set_image("objection.png"); + ui_hold_it->set_image("holdit.png"); + ui_custom_objection->set_image("custom.png"); + + ui_take_that->set_image("takethat_selected.png"); + objection_state = 3; + } + + ui_ic_chat_message->setFocus(); +} + +void Courtroom::on_custom_objection_clicked() +{ + if (objection_state == 4) + { + ui_custom_objection->set_image("custom.png"); + objection_state = 0; + } + else + { + ui_objection->set_image("objection.png"); + ui_take_that->set_image("takethat.png"); + ui_hold_it->set_image("holdit.png"); + + ui_custom_objection->set_image("custom_selected.png"); + objection_state = 4; + } + + ui_ic_chat_message->setFocus(); +} + +void Courtroom::on_realization_clicked() +{ + if (realization_state == 0) + { + realization_state = 1; + ui_realization->set_image("realization_pressed.png"); + } + else + { + realization_state = 0; + ui_realization->set_image("realization.png"); + } + + ui_ic_chat_message->setFocus(); +} + +void Courtroom::on_mute_clicked() +{ + if (ui_mute_list->isHidden()) + { + ui_mute_list->show(); + ui_pair_list->hide(); + ui_pair_offset_spinbox->hide(); + ui_pair_button->set_image("pair_button.png"); + ui_mute->set_image("mute_pressed.png"); + } + else + { + ui_mute_list->hide(); + ui_mute->set_image("mute.png"); + } +} + +void Courtroom::on_pair_clicked() +{ + if (ui_pair_list->isHidden()) + { + ui_pair_list->show(); + ui_pair_offset_spinbox->show(); + ui_mute_list->hide(); + ui_mute->set_image("mute.png"); + ui_pair_button->set_image("pair_button_pressed.png"); + } + else + { + ui_pair_list->hide(); + ui_pair_offset_spinbox->hide(); + ui_pair_button->set_image("pair_button.png"); + } +} + +void Courtroom::on_defense_minus_clicked() +{ + int f_state = defense_bar_state - 1; + + if (f_state >= 0) + ao_app->send_server_packet(new AOPacket("HP#1#" + QString::number(f_state) + "#%")); +} + +void Courtroom::on_defense_plus_clicked() +{ + int f_state = defense_bar_state + 1; + + if (f_state <= 10) + ao_app->send_server_packet(new AOPacket("HP#1#" + QString::number(f_state) + "#%")); +} + +void Courtroom::on_prosecution_minus_clicked() +{ + int f_state = prosecution_bar_state - 1; + + if (f_state >= 0) + ao_app->send_server_packet(new AOPacket("HP#2#" + QString::number(f_state) + "#%")); +} + +void Courtroom::on_prosecution_plus_clicked() +{ + int f_state = prosecution_bar_state + 1; + + if (f_state <= 10) + ao_app->send_server_packet(new AOPacket("HP#2#" + QString::number(f_state) + "#%")); +} + +void Courtroom::on_text_color_changed(int p_color) +{ + text_color = p_color; + ui_ic_chat_message->setFocus(); +} + +void Courtroom::on_music_slider_moved(int p_value) +{ + music_player->set_volume(p_value); + ui_ic_chat_message->setFocus(); +} + +void Courtroom::on_sfx_slider_moved(int p_value) +{ + sfx_player->set_volume(p_value); + objection_player->set_volume(p_value); + ui_ic_chat_message->setFocus(); +} + +void Courtroom::on_blip_slider_moved(int p_value) +{ + blip_player->set_volume(p_value); + ui_ic_chat_message->setFocus(); +} + +void Courtroom::on_log_limit_changed(int value) +{ + log_maximum_blocks = value; +} + +void Courtroom::on_pair_offset_changed(int value) +{ + offset_with_pair = value; +} + +void Courtroom::on_witness_testimony_clicked() +{ + if (is_muted) + return; + + ao_app->send_server_packet(new AOPacket("RT#testimony1#%")); + + ui_ic_chat_message->setFocus(); +} + +void Courtroom::on_cross_examination_clicked() +{ + if (is_muted) + return; + + ao_app->send_server_packet(new AOPacket("RT#testimony2#%")); + + ui_ic_chat_message->setFocus(); +} + +void Courtroom::on_not_guilty_clicked() +{ + if (is_muted) + return; + + ao_app->send_server_packet(new AOPacket("RT#judgeruling#0#%")); + + ui_ic_chat_message->setFocus(); +} + +void Courtroom::on_guilty_clicked() +{ + if (is_muted) + return; + + ao_app->send_server_packet(new AOPacket("RT#judgeruling#1#%")); + + ui_ic_chat_message->setFocus(); +} + +void Courtroom::on_change_character_clicked() +{ + music_player->set_volume(0); + sfx_player->set_volume(0); + sfx_player->set_volume(0); + blip_player->set_volume(0); + + set_char_select(); + + ui_char_select_background->show(); + ui_spectator->hide(); +} + +void Courtroom::on_reload_theme_clicked() +{ + ao_app->reload_theme(); + + //to update status on the background + set_background(current_background); + enter_courtroom(m_cid); + + anim_state = 4; + text_state = 3; +} + +void Courtroom::on_back_to_lobby_clicked() +{ + ao_app->construct_lobby(); + ao_app->destruct_courtroom(); +} + +void Courtroom::on_char_select_left_clicked() +{ + --current_char_page; + set_char_select_page(); +} + +void Courtroom::on_char_select_right_clicked() +{ + ++current_char_page; + set_char_select_page(); +} + +void Courtroom::on_spectator_clicked() +{ + enter_courtroom(-1); + + ui_emotes->hide(); + + ui_char_select_background->hide(); +} + +void Courtroom::on_call_mod_clicked() +{ + if (ao_app->modcall_reason_enabled) { + QMessageBox errorBox; + QInputDialog input; + + input.setWindowFlags(Qt::WindowSystemMenuHint); + input.setLabelText("Reason:"); + input.setWindowTitle("Call Moderator"); + auto code = input.exec(); + + if (code != QDialog::Accepted) + return; + + QString text = input.textValue(); + if (text.isEmpty()) { + errorBox.critical(nullptr, "Error", "You must provide a reason."); + return; + } else if (text.length() > 256) { + errorBox.critical(nullptr, "Error", "The message is too long."); + return; + } + + QStringList mod_reason; + mod_reason.append(text); + + ao_app->send_server_packet(new AOPacket("ZZ", mod_reason)); + } else { + ao_app->send_server_packet(new AOPacket("ZZ#%")); + } + + ui_ic_chat_message->setFocus(); +} + +void Courtroom::on_settings_clicked() +{ + ao_app->call_settings_menu(); +} + +void Courtroom::on_announce_casing_clicked() +{ + ao_app->call_announce_menu(this); +} + +void Courtroom::on_pre_clicked() +{ + ui_ic_chat_message->setFocus(); +} + +void Courtroom::on_flip_clicked() +{ + ui_ic_chat_message->setFocus(); +} + +void Courtroom::on_guard_clicked() +{ + ui_ic_chat_message->setFocus(); +} + +void Courtroom::on_showname_enable_clicked() +{ + ui_ic_chatlog->clear(); + first_message_sent = false; + + foreach (chatlogpiece item, ic_chatlog_history) { + if (ui_showname_enable->isChecked()) + { + if (item.get_is_song()) + append_ic_text(item.get_message(), item.get_showname(), true); + else + append_ic_text(item.get_message(), item.get_showname()); + } + else + { + if (item.get_is_song()) + append_ic_text(item.get_message(), item.get_name(), true); + else + append_ic_text(item.get_message(), item.get_name()); + } + } + + ui_ic_chat_message->setFocus(); +} + +void Courtroom::on_evidence_button_clicked() +{ + if (ui_evidence->isHidden()) + { + ui_evidence->show(); + ui_evidence_overlay->hide(); + } + else + { + ui_evidence->hide(); + } +} + +void Courtroom::on_switch_area_music_clicked() +{ + if (ui_area_list->isHidden()) + { + ui_area_list->show(); + ui_music_list->hide(); + } + else + { + ui_area_list->hide(); + ui_music_list->show(); + } +} + +void Courtroom::ping_server() +{ + ao_app->send_server_packet(new AOPacket("CH#" + QString::number(m_cid) + "#%")); +} + +void Courtroom::on_casing_clicked() +{ + if (ao_app->casing_alerts_enabled) + { + if (ui_casing->isChecked()) + { + QStringList f_packet; + + f_packet.append(ao_app->get_casing_can_host_cases()); + f_packet.append(QString::number(ao_app->get_casing_cm_enabled())); + f_packet.append(QString::number(ao_app->get_casing_defence_enabled())); + f_packet.append(QString::number(ao_app->get_casing_prosecution_enabled())); + f_packet.append(QString::number(ao_app->get_casing_judge_enabled())); + f_packet.append(QString::number(ao_app->get_casing_juror_enabled())); + f_packet.append(QString::number(ao_app->get_casing_steno_enabled())); + + ao_app->send_server_packet(new AOPacket("SETCASE", f_packet)); + } + else + ao_app->send_server_packet(new AOPacket("SETCASE#\"\"#0#0#0#0#0#0#%")); + } +} + +void Courtroom::announce_case(QString title, bool def, bool pro, bool jud, bool jur, bool steno) +{ + if (ao_app->casing_alerts_enabled) + { + QStringList f_packet; + + f_packet.append(title); + f_packet.append(QString::number(def)); + f_packet.append(QString::number(pro)); + f_packet.append(QString::number(jud)); + f_packet.append(QString::number(jur)); + f_packet.append(QString::number(steno)); + + ao_app->send_server_packet(new AOPacket("CASEA", f_packet)); + } +} + +Courtroom::~Courtroom() +{ + delete music_player; + delete sfx_player; + delete objection_player; + delete blip_player; +} + +#if (defined (_WIN32) || defined (_WIN64)) +void Courtroom::load_bass_opus_plugin() +{ + BASS_PluginLoad("bassopus.dll", 0); +} +#elif (defined (LINUX) || defined (__linux__)) +void Courtroom::load_bass_opus_plugin() +{ + BASS_PluginLoad("libbassopus.so", 0); +} +#else +#error This operating system is unsupported for bass plugins. +#endif diff --git a/src/debug_functions.cpp b/src/debug_functions.cpp new file mode 100644 index 00000000..77f2f35a --- /dev/null +++ b/src/debug_functions.cpp @@ -0,0 +1,25 @@ +#include "debug_functions.h" + +void call_error(QString p_message) +{ + QMessageBox *msgBox = new QMessageBox; + + msgBox->setText("Error: " + p_message); + msgBox->setWindowTitle("Error"); + + + //msgBox->setWindowModality(Qt::NonModal); + msgBox->exec(); +} + +void call_notice(QString p_message) +{ + QMessageBox *msgBox = new QMessageBox; + + msgBox->setText(p_message); + msgBox->setWindowTitle("Notice"); + + + //msgBox->setWindowModality(Qt::NonModal); + msgBox->exec(); +} diff --git a/src/discord_rich_presence.cpp b/src/discord_rich_presence.cpp new file mode 100644 index 00000000..10f5833e --- /dev/null +++ b/src/discord_rich_presence.cpp @@ -0,0 +1,103 @@ +#include "discord_rich_presence.h" + +namespace AttorneyOnline { + +Discord::Discord() +{ + DiscordEventHandlers handlers; + std::memset(&handlers, 0, sizeof(handlers)); + handlers = {}; + handlers.ready = [] { + qInfo() << "Discord RPC ready"; + }; + handlers.disconnected = [](int errorCode, const char* message) { + qInfo() << "Discord RPC disconnected! " << message; + }; + handlers.errored = [](int errorCode, const char* message) { + qWarning() << "Discord RPC errored out! " << message; + }; + qInfo() << "Initializing Discord RPC"; + Discord_Initialize(APPLICATION_ID, &handlers, 1, nullptr); +} + +Discord::~Discord() +{ + Discord_Shutdown(); +} + +void Discord::state_lobby() +{ + DiscordRichPresence presence; + std::memset(&presence, 0, sizeof(presence)); + presence.largeImageKey = "ao2-logo"; + presence.largeImageText = "Objection!"; + presence.instance = 1; + + presence.state = "In Lobby"; + presence.details = "Idle"; + Discord_UpdatePresence(&presence); +} + +void Discord::state_server(std::string name, std::string server_id) +{ + qDebug() << "Discord RPC: Setting server state"; + + DiscordRichPresence presence; + std::memset(&presence, 0, sizeof(presence)); + presence.largeImageKey = "ao2-logo"; + presence.largeImageText = "Objection!"; + presence.instance = 1; + + auto timestamp = static_cast(std::time(nullptr)); + + presence.state = "In a Server"; + presence.details = name.c_str(); + presence.matchSecret = server_id.c_str(); + presence.startTimestamp = this->timestamp; + + this->server_id = server_id; + this->server_name = name; + this->timestamp = timestamp; + Discord_UpdatePresence(&presence); +} + +void Discord::state_character(std::string name) +{ + auto name_internal = QString(name.c_str()).toLower().replace(' ', '_').toStdString(); + auto name_friendly = QString(name.c_str()).replace('_', ' ').toStdString(); + const std::string playing_as = "Playing as " + name_friendly; + qDebug() << "Discord RPC: Setting character state (" << playing_as.c_str() << ")"; + + DiscordRichPresence presence; + std::memset(&presence, 0, sizeof(presence)); + presence.largeImageKey = "ao2-logo"; + presence.largeImageText = "Objection!"; + presence.instance = 1; + presence.details = this->server_name.c_str(); + presence.matchSecret = this->server_id.c_str(); + presence.startTimestamp = this->timestamp; + + presence.state = playing_as.c_str(); + presence.smallImageKey = name_internal.c_str(); + // presence.smallImageText = name_internal.c_str(); + Discord_UpdatePresence(&presence); +} + +void Discord::state_spectate() +{ + qDebug() << "Discord RPC: Setting specator state"; + + DiscordRichPresence presence; + std::memset(&presence, 0, sizeof(presence)); + presence.largeImageKey = "ao2-logo"; + presence.largeImageText = "Objection!"; + presence.instance = 1; + presence.details = this->server_name.c_str(); + presence.matchSecret = this->server_id.c_str(); + presence.startTimestamp = this->timestamp; + + presence.state = "Spectating"; + Discord_UpdatePresence(&presence); +} + +} diff --git a/src/emotes.cpp b/src/emotes.cpp new file mode 100644 index 00000000..b6a217e6 --- /dev/null +++ b/src/emotes.cpp @@ -0,0 +1,174 @@ +#include "courtroom.h" + +#include "aoemotebutton.h" + +void Courtroom::construct_emotes() +{ + ui_emotes = new QWidget(this); + + set_size_and_pos(ui_emotes, "emotes"); + + QPoint f_spacing = ao_app->get_button_spacing("emote_button_spacing", "courtroom_design.ini"); + + const int button_width = 40; + int x_spacing = f_spacing.x(); + int x_mod_count = 0; + + const int button_height = 40; + int y_spacing = f_spacing.y(); + int y_mod_count = 0; + + emote_columns = ((ui_emotes->width() - button_width) / (x_spacing + button_width)) + 1; + emote_rows = ((ui_emotes->height() - button_height) / (y_spacing + button_height)) + 1; + + max_emotes_on_page = emote_columns * emote_rows; + + for (int n = 0 ; n < max_emotes_on_page ; ++n) + { + int x_pos = (button_width + x_spacing) * x_mod_count; + int y_pos = (button_height + y_spacing) * y_mod_count; + + AOEmoteButton *f_emote = new AOEmoteButton(ui_emotes, ao_app, x_pos, y_pos); + + ui_emote_list.append(f_emote); + + f_emote->set_id(n); + + connect(f_emote, SIGNAL(emote_clicked(int)), this, SLOT(on_emote_clicked(int))); + + ++x_mod_count; + + if (x_mod_count == emote_columns) + { + ++y_mod_count; + x_mod_count = 0; + } + } +} + +void Courtroom::set_emote_page() +{ + if (m_cid == -1) + return; + + int total_emotes = ao_app->get_emote_number(current_char); + + ui_emote_left->hide(); + ui_emote_right->hide(); + + for (AOEmoteButton *i_button : ui_emote_list) + { + i_button->hide(); + } + + int total_pages = total_emotes / max_emotes_on_page; + int emotes_on_page = 0; + + if (total_emotes % max_emotes_on_page != 0) + { + ++total_pages; + //i. e. not on the last page + if (total_pages > current_emote_page + 1) + emotes_on_page = max_emotes_on_page; + else + emotes_on_page = total_emotes % max_emotes_on_page; + + } + else + emotes_on_page = max_emotes_on_page; + + if (total_pages > current_emote_page + 1) + ui_emote_right->show(); + + if (current_emote_page > 0) + ui_emote_left->show(); + + for (int n_emote = 0 ; n_emote < emotes_on_page ; ++n_emote) + { + int n_real_emote = n_emote + current_emote_page * max_emotes_on_page; + AOEmoteButton *f_emote = ui_emote_list.at(n_emote); + + if (n_real_emote == current_emote) + f_emote->set_image(current_char, n_real_emote, "_on.png"); + else + f_emote->set_image(current_char, n_real_emote, "_off.png"); + + f_emote->show(); + } + +} + +void Courtroom::set_emote_dropdown() +{ + ui_emote_dropdown->clear(); + + int total_emotes = ao_app->get_emote_number(current_char); + QStringList emote_list; + + for (int n = 0 ; n < total_emotes ; ++n) + { + emote_list.append(ao_app->get_emote_comment(current_char, n)); + } + + ui_emote_dropdown->addItems(emote_list); +} + +void Courtroom::select_emote(int p_id) +{ + int min = current_emote_page * max_emotes_on_page; + int max = (max_emotes_on_page - 1) + current_emote_page * max_emotes_on_page; + + if (current_emote >= min && current_emote <= max) + ui_emote_list.at(current_emote % max_emotes_on_page)->set_image(current_char, current_emote, "_off.png"); + + int old_emote = current_emote; + + current_emote = p_id; + + if (current_emote >= min && current_emote <= max) + ui_emote_list.at(current_emote % max_emotes_on_page)->set_image(current_char, current_emote, "_on.png"); + + int emote_mod = ao_app->get_emote_mod(current_char, current_emote); + + if (old_emote == current_emote) + { + ui_pre->setChecked(!ui_pre->isChecked()); + } + else if (emote_mod == 1) + ui_pre->setChecked(true); + else + ui_pre->setChecked(false); + + ui_emote_dropdown->setCurrentIndex(current_emote); + + ui_ic_chat_message->setFocus(); +} + +void Courtroom::on_emote_clicked(int p_id) +{ + select_emote(p_id + max_emotes_on_page * current_emote_page); +} + +void Courtroom::on_emote_left_clicked() +{ + --current_emote_page; + + set_emote_page(); + + ui_ic_chat_message->setFocus(); +} + +void Courtroom::on_emote_right_clicked() +{ + qDebug() << "emote right clicked"; + ++current_emote_page; + + set_emote_page(); + + ui_ic_chat_message->setFocus(); +} + +void Courtroom::on_emote_dropdown_changed(int p_index) +{ + select_emote(p_index); +} diff --git a/src/encryption_functions.cpp b/src/encryption_functions.cpp new file mode 100644 index 00000000..ffbe0cdb --- /dev/null +++ b/src/encryption_functions.cpp @@ -0,0 +1,63 @@ +#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 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 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/evidence.cpp b/src/evidence.cpp new file mode 100644 index 00000000..4e796642 --- /dev/null +++ b/src/evidence.cpp @@ -0,0 +1,345 @@ +#include "courtroom.h" + +void Courtroom::construct_evidence() +{ + ui_evidence = new AOImage(this, ao_app); + + //ui_evidence_name = new QLabel(ui_evidence); + ui_evidence_name = new AOLineEdit(ui_evidence); + ui_evidence_name->setAlignment(Qt::AlignCenter); + ui_evidence_name->setFont(QFont("Arial", 14, QFont::Bold)); + ui_evidence_name->setStyleSheet("background-color: rgba(0, 0, 0, 0);" + "color: rgba(255, 128, 0, 255);"); + + ui_evidence_buttons = new QWidget(ui_evidence); + + ui_evidence_left = new AOButton(ui_evidence, ao_app); + ui_evidence_right = new AOButton(ui_evidence, ao_app); + ui_evidence_present = new AOButton(ui_evidence, ao_app); + + ui_evidence_overlay = new AOImage(ui_evidence, ao_app); + + ui_evidence_delete = new AOButton(ui_evidence_overlay, ao_app); + ui_evidence_image_name = new AOLineEdit(ui_evidence_overlay); + ui_evidence_image_button = new AOButton(ui_evidence_overlay, ao_app); + ui_evidence_image_button->setText("Choose.."); + ui_evidence_x = new AOButton(ui_evidence_overlay, ao_app); + + ui_evidence_description = new AOTextEdit(ui_evidence_overlay); + ui_evidence_description->setStyleSheet("background-color: rgba(0, 0, 0, 0);" + "color: white;"); + + set_size_and_pos(ui_evidence, "evidence_background"); + set_size_and_pos(ui_evidence_buttons, "evidence_buttons"); + + QPoint f_spacing = ao_app->get_button_spacing("evidence_button_spacing", "courtroom_design.ini"); + + const int button_width = 70; + int x_spacing = f_spacing.x(); + int x_mod_count = 0; + + const int button_height = 70; + int y_spacing = f_spacing.y(); + int y_mod_count = 0; + + evidence_columns = ((ui_evidence_buttons->width() - button_width) / (x_spacing + button_width)) + 1; + evidence_rows = ((ui_evidence_buttons->height() - button_height) / (y_spacing + button_height)) + 1; + + max_evidence_on_page = evidence_columns * evidence_rows; + + for (int n = 0 ; n < max_evidence_on_page ; ++n) + { + int x_pos = (button_width + x_spacing) * x_mod_count; + int y_pos = (button_height + y_spacing) * y_mod_count; + + AOEvidenceButton *f_evidence = new AOEvidenceButton(ui_evidence_buttons, ao_app, x_pos, y_pos); + + ui_evidence_list.append(f_evidence); + + f_evidence->set_id(n); + + connect(f_evidence, SIGNAL(evidence_clicked(int)), this, SLOT(on_evidence_clicked(int))); + connect(f_evidence, SIGNAL(evidence_double_clicked(int)), this, SLOT(on_evidence_double_clicked(int))); + connect(f_evidence, SIGNAL(on_hover(int, bool)), this, SLOT(on_evidence_hover(int, bool))); + + ++x_mod_count; + + if (x_mod_count == evidence_columns) + { + ++y_mod_count; + x_mod_count = 0; + } + } + + connect(ui_evidence_name, SIGNAL(returnPressed()), this, SLOT(on_evidence_name_edited())); + connect(ui_evidence_left, SIGNAL(clicked()), this, SLOT(on_evidence_left_clicked())); + connect(ui_evidence_right, SIGNAL(clicked()), this, SLOT(on_evidence_right_clicked())); + connect(ui_evidence_present, SIGNAL(clicked()), this, SLOT(on_evidence_present_clicked())); + connect(ui_evidence_delete, SIGNAL(clicked()), this, SLOT(on_evidence_delete_clicked())); + connect(ui_evidence_image_name, SIGNAL(returnPressed()), this, SLOT(on_evidence_image_name_edited())); + connect(ui_evidence_image_button, SIGNAL(clicked()), this, SLOT(on_evidence_image_button_clicked())); + connect(ui_evidence_x, SIGNAL(clicked()), this, SLOT(on_evidence_x_clicked())); + + ui_evidence->hide(); +} + +void Courtroom::set_evidence_list(QVector &p_evi_list) +{ + local_evidence_list.clear(); + local_evidence_list = p_evi_list; + + set_evidence_page(); +} + +void Courtroom::set_evidence_page() +{ + int total_evidence = local_evidence_list.size(); + + ui_evidence_left->hide(); + ui_evidence_right->hide(); + + for (AOEvidenceButton *i_button : ui_evidence_list) + { + i_button->reset(); + } + + //to account for the "add evidence" button + ++total_evidence; + + int total_pages = total_evidence / max_evidence_on_page; + int evidence_on_page = 0; + + if ((total_evidence % max_evidence_on_page) != 0) + { + ++total_pages; + //i. e. not on the last page + if (total_pages > current_evidence_page + 1) + evidence_on_page = max_evidence_on_page; + else + evidence_on_page = total_evidence % max_evidence_on_page; + + } + else + evidence_on_page = max_evidence_on_page; + + if (total_pages > current_evidence_page + 1) + ui_evidence_right->show(); + + if (current_evidence_page > 0) + ui_evidence_left->show(); + + for (int n_evidence_button = 0 ; n_evidence_button < evidence_on_page ; ++n_evidence_button) + { + int n_real_evidence = n_evidence_button + current_evidence_page * max_evidence_on_page; + AOEvidenceButton *f_evidence_button = ui_evidence_list.at(n_evidence_button); + + //ie. the add evidence button + if (n_real_evidence == (total_evidence - 1)) + f_evidence_button->set_theme_image("addevidence.png"); + else if (n_real_evidence < (total_evidence - 1)) + { + f_evidence_button->set_image(local_evidence_list.at(n_real_evidence).image); + + if (n_real_evidence == current_evidence) + f_evidence_button->set_selected(true); + else + f_evidence_button->set_selected(false); + } + else + f_evidence_button->set_image(""); + + f_evidence_button->show(); + } +} + +void Courtroom::on_evidence_name_edited() +{ + if (current_evidence >= local_evidence_list.size()) + return; + + QStringList f_contents; + + evi_type f_evi = local_evidence_list.at(current_evidence); + + f_contents.append(QString::number(current_evidence)); + f_contents.append(ui_evidence_name->text()); + f_contents.append(f_evi.description); + f_contents.append(f_evi.image); + + ao_app->send_server_packet(new AOPacket("EE", f_contents)); +} + +void Courtroom::on_evidence_image_name_edited() +{ + if (current_evidence >= local_evidence_list.size()) + return; + + QStringList f_contents; + + evi_type f_evi = local_evidence_list.at(current_evidence); + + f_contents.append(QString::number(current_evidence)); + f_contents.append(f_evi.name); + f_contents.append(f_evi.description); + f_contents.append(ui_evidence_image_name->text()); + + ao_app->send_server_packet(new AOPacket("EE", f_contents)); +} + +void Courtroom::on_evidence_image_button_clicked() +{ + QFileDialog dialog(this); + dialog.setFileMode(QFileDialog::ExistingFile); + dialog.setNameFilter(tr("Images (*.png)")); + dialog.setViewMode(QFileDialog::List); + dialog.setDirectory(ao_app->get_base_path() + "evidence"); + + QStringList filenames; + + if (dialog.exec()) + filenames = dialog.selectedFiles(); + + if (filenames.size() != 1) + return; + + QString filename = filenames.at(0); + + QStringList split_filename = filename.split("/"); + + filename = split_filename.at(split_filename.size() - 1); + + ui_evidence_image_name->setText(filename); + + on_evidence_image_name_edited(); +} + +void Courtroom::on_evidence_clicked(int p_id) +{ + ui_evidence_name->setReadOnly(true); + + int f_real_id = p_id + max_evidence_on_page * current_evidence_page; + + if (f_real_id == local_evidence_list.size()) + { + ao_app->send_server_packet(new AOPacket("PE###empty.png#%")); + return; + } + else if (f_real_id > local_evidence_list.size()) + return; + + ui_evidence_name->setText(local_evidence_list.at(f_real_id).name); + + for (AOEvidenceButton *i_button : ui_evidence_list) + i_button->set_selected(false); + + ui_evidence_list.at(p_id)->set_selected(true); + + current_evidence = f_real_id; + + ui_ic_chat_message->setFocus(); + +} + +void Courtroom::on_evidence_double_clicked(int p_id) +{ + int f_real_id = p_id + max_evidence_on_page * current_evidence_page; + + if (f_real_id >= local_evidence_list.size()) + return; + + current_evidence = f_real_id; + + evi_type f_evi = local_evidence_list.at(f_real_id); + + ui_evidence_description->clear(); + ui_evidence_description->appendPlainText(f_evi.description); + + ui_evidence_image_name->setText(f_evi.image); + + ui_evidence_overlay->show(); + + ui_ic_chat_message->setFocus(); +} + +void Courtroom::on_evidence_hover(int p_id, bool p_state) +{ + ui_evidence_name->setReadOnly(true); + int final_id = p_id + max_evidence_on_page * current_evidence_page; + + if (p_state) + { + if (final_id == local_evidence_list.size()) + ui_evidence_name->setText("Add new evidence..."); + else if (final_id < local_evidence_list.size()) + ui_evidence_name->setText(local_evidence_list.at(final_id).name); + } + else if (current_evidence < local_evidence_list.size()) + ui_evidence_name->setText(local_evidence_list.at(current_evidence).name); + else + ui_evidence_name->setText(""); +} + +void Courtroom::on_evidence_left_clicked() +{ + --current_evidence_page; + + set_evidence_page(); + + ui_ic_chat_message->setFocus(); +} + +void Courtroom::on_evidence_right_clicked() +{ + ++current_evidence_page; + + set_evidence_page(); + + ui_ic_chat_message->setFocus(); +} + +void Courtroom::on_evidence_present_clicked() +{ + if (is_presenting_evidence) + ui_evidence_present->set_image("present_disabled.png"); + else + ui_evidence_present->set_image("present.png"); + + is_presenting_evidence = !is_presenting_evidence; + + ui_ic_chat_message->setFocus(); +} + +void Courtroom::on_evidence_delete_clicked() +{ + ui_evidence_description->setReadOnly(true); + ui_evidence_overlay->hide(); + + ao_app->send_server_packet(new AOPacket("DE#" + QString::number(current_evidence) + "#%")); + + current_evidence = 0; + + ui_ic_chat_message->setFocus(); +} + +void Courtroom::on_evidence_x_clicked() +{ + ui_evidence_description->setReadOnly(true); + ui_evidence_overlay->hide(); + + if (current_evidence >= local_evidence_list.size()) + return; + + QStringList f_contents; + + evi_type f_evi = local_evidence_list.at(current_evidence); + + f_contents.append(QString::number(current_evidence)); + f_contents.append(f_evi.name); + f_contents.append(ui_evidence_description->toPlainText()); + f_contents.append(f_evi.image); + + ao_app->send_server_packet(new AOPacket("EE", f_contents)); + + ui_ic_chat_message->setFocus(); +} + diff --git a/src/file_functions.cpp b/src/file_functions.cpp new file mode 100644 index 00000000..f93ee15d --- /dev/null +++ b/src/file_functions.cpp @@ -0,0 +1,21 @@ +#include "file_functions.h" + +bool file_exists(QString file_path) +{ + QFileInfo check_file(file_path); + + return check_file.exists() && check_file.isFile(); +} + +bool dir_exists(QString dir_path) +{ + QDir check_dir(dir_path); + + return check_dir.exists(); +} + +bool exists(QString p_path) { + QFile file(p_path); + + return file.exists(); +} diff --git a/src/hardware_functions.cpp b/src/hardware_functions.cpp new file mode 100644 index 00000000..29823cdf --- /dev/null +++ b/src/hardware_functions.cpp @@ -0,0 +1,57 @@ +#include "hardware_functions.h" + +#include + +#if (defined (_WIN32) || defined (_WIN64)) +#include + +DWORD dwVolSerial; +BOOL bIsRetrieved; + +QString get_hdid() +{ + bIsRetrieved = GetVolumeInformation(TEXT("C:\\"), NULL, NULL, &dwVolSerial, NULL, NULL, NULL, NULL); + + if (bIsRetrieved) + return QString::number(dwVolSerial, 16); + else + //a totally random string + //what could possibly go wrong + return "gxsps32sa9fnwic92mfbs0"; + +} + +#elif (defined (LINUX) || defined (__linux__)) + +#include +#include + +QString get_hdid() +{ + QFile fstab_file("/etc/fstab"); + if (!fstab_file.open(QIODevice::ReadOnly)) + return "gxcps32sa9fnwic92mfbs0"; + + QTextStream in(&fstab_file); + + while(!in.atEnd()) + { + QString line = in.readLine(); + + if (line.startsWith("UUID")) + { + QStringList line_elements = line.split("="); + + if (line_elements.size() > 1) + return line_elements.at(1).left(23).trimmed(); + } + } + + return "gxcpz32sa9fnwic92mfbs0"; +} + +#else + +#error This operating system is unsupported for hardware functions. + +#endif diff --git a/src/hex_functions.cpp b/src/hex_functions.cpp new file mode 100644 index 00000000..4a58d2b4 --- /dev/null +++ b/src/hex_functions.cpp @@ -0,0 +1,18 @@ +#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; + } +} diff --git a/src/lobby.cpp b/src/lobby.cpp new file mode 100644 index 00000000..4a96e567 --- /dev/null +++ b/src/lobby.cpp @@ -0,0 +1,388 @@ +#include "lobby.h" + +#include "debug_functions.h" +#include "aoapplication.h" +#include "networkmanager.h" +#include "aosfxplayer.h" + +Lobby::Lobby(AOApplication *p_ao_app) : QMainWindow() +{ + ao_app = p_ao_app; + + this->setWindowTitle("Attorney Online 2"); + this->setWindowIcon(QIcon(":/logo.png")); + + ui_background = new AOImage(this, ao_app); + ui_public_servers = new AOButton(this, ao_app); + ui_favorites = new AOButton(this, ao_app); + ui_refresh = new AOButton(this, ao_app); + ui_add_to_fav = new AOButton(this, ao_app); + ui_connect = new AOButton(this, ao_app); + ui_version = new QLabel(this); + ui_about = new AOButton(this, ao_app); + ui_server_list = new QListWidget(this); + ui_player_count = new QLabel(this); + ui_description = new AOTextArea(this); + ui_chatbox = new AOTextArea(this); + ui_chatbox->setOpenExternalLinks(true); + ui_chatname = new QLineEdit(this); + ui_chatname->setPlaceholderText("Name"); + ui_chatname->setText(ao_app->get_ooc_name()); + ui_chatmessage = new QLineEdit(this); + ui_loading_background = new AOImage(this, ao_app); + ui_loading_text = new QTextEdit(ui_loading_background); + ui_progress_bar = new QProgressBar(ui_loading_background); + ui_progress_bar->setMinimum(0); + ui_progress_bar->setMaximum(100); + ui_progress_bar->setStyleSheet("QProgressBar{ color: white; }"); + ui_cancel = new AOButton(ui_loading_background, ao_app); + + connect(ui_public_servers, SIGNAL(clicked()), this, SLOT(on_public_servers_clicked())); + connect(ui_favorites, SIGNAL(clicked()), this, SLOT(on_favorites_clicked())); + connect(ui_refresh, SIGNAL(pressed()), this, SLOT(on_refresh_pressed())); + connect(ui_refresh, SIGNAL(released()), this, SLOT(on_refresh_released())); + connect(ui_add_to_fav, SIGNAL(pressed()), this, SLOT(on_add_to_fav_pressed())); + connect(ui_add_to_fav, SIGNAL(released()), this, SLOT(on_add_to_fav_released())); + connect(ui_connect, SIGNAL(pressed()), this, SLOT(on_connect_pressed())); + connect(ui_connect, SIGNAL(released()), this, SLOT(on_connect_released())); + connect(ui_about, SIGNAL(clicked()), this, SLOT(on_about_clicked())); + connect(ui_server_list, SIGNAL(clicked(QModelIndex)), this, SLOT(on_server_list_clicked(QModelIndex))); + connect(ui_chatmessage, SIGNAL(returnPressed()), this, SLOT(on_chatfield_return_pressed())); + connect(ui_cancel, SIGNAL(clicked()), ao_app, SLOT(loading_cancelled())); + + ui_connect->setEnabled(false); + + list_servers(); + + set_widgets(); +} + +//sets images, position and size +void Lobby::set_widgets() +{ + ao_app->reload_theme(); + + QString filename = "lobby_design.ini"; + + pos_size_type f_lobby = ao_app->get_element_dimensions("lobby", filename); + + if (f_lobby.width < 0 || f_lobby.height < 0) + { + qDebug() << "W: did not find lobby width or height in " << filename; + + // Most common symptom of bad config files and missing assets. + call_notice("It doesn't look like your client is set up correctly.\n" + "Did you download all resources correctly from tiny.cc/getao, " + "including the large 'base' folder?"); + + this->resize(517, 666); + } + else + { + this->resize(f_lobby.width, f_lobby.height); + } + + set_size_and_pos(ui_background, "lobby"); + ui_background->set_image("lobbybackground.png"); + + set_size_and_pos(ui_public_servers, "public_servers"); + ui_public_servers->set_image("publicservers_selected.png"); + + set_size_and_pos(ui_favorites, "favorites"); + ui_favorites->set_image("favorites.png"); + + set_size_and_pos(ui_refresh, "refresh"); + ui_refresh->set_image("refresh.png"); + + set_size_and_pos(ui_add_to_fav, "add_to_fav"); + ui_add_to_fav->set_image("addtofav.png"); + + set_size_and_pos(ui_connect, "connect"); + ui_connect->set_image("connect.png"); + + set_size_and_pos(ui_version, "version"); + ui_version->setText("Version: " + ao_app->get_version_string()); + + set_size_and_pos(ui_about, "about"); + ui_about->set_image("about.png"); + + set_size_and_pos(ui_server_list, "server_list"); + ui_server_list->setStyleSheet("background-color: rgba(0, 0, 0, 0);" + "font: bold;"); + + set_size_and_pos(ui_player_count, "player_count"); + ui_player_count->setText("Offline"); + ui_player_count->setStyleSheet("font: bold;" + "color: white;" + "qproperty-alignment: AlignCenter;"); + + set_size_and_pos(ui_description, "description"); + ui_description->setReadOnly(true); + ui_description->setStyleSheet("background-color: rgba(0, 0, 0, 0);" + "color: white;"); + + set_size_and_pos(ui_chatbox, "chatbox"); + ui_chatbox->setReadOnly(true); + ui_chatbox->setStyleSheet("QTextBrowser{background-color: rgba(0, 0, 0, 0);}"); + + set_size_and_pos(ui_chatname, "chatname"); + ui_chatname->setStyleSheet("background-color: rgba(0, 0, 0, 0);" + "selection-background-color: rgba(0, 0, 0, 0);"); + + set_size_and_pos(ui_chatmessage, "chatmessage"); + ui_chatmessage->setStyleSheet("background-color: rgba(0, 0, 0, 0);" + "selection-background-color: rgba(0, 0, 0, 0);"); + + ui_loading_background->resize(this->width(), this->height()); + ui_loading_background->set_image("loadingbackground.png"); + + + set_size_and_pos(ui_loading_text, "loading_label"); + ui_loading_text->setFont(QFont("Arial", 20, QFont::Bold)); + ui_loading_text->setReadOnly(true); + ui_loading_text->setAlignment(Qt::AlignCenter); + ui_loading_text->setFrameStyle(QFrame::NoFrame); + ui_loading_text->setStyleSheet("background-color: rgba(0, 0, 0, 0);" + "color: rgba(255, 128, 0, 255);"); + ui_loading_text->append("Loading"); + + set_size_and_pos(ui_progress_bar, "progress_bar"); + set_size_and_pos(ui_cancel, "cancel"); + ui_cancel->setText("Cancel"); + + ui_loading_background->hide(); + +} + +void Lobby::set_size_and_pos(QWidget *p_widget, QString p_identifier) +{ + QString filename = "lobby_design.ini"; + + pos_size_type design_ini_result = ao_app->get_element_dimensions(p_identifier, filename); + + if (design_ini_result.width < 0 || design_ini_result.height < 0) + { + qDebug() << "W: could not find " << p_identifier << " in " << filename; + p_widget->hide(); + } + else + { + p_widget->move(design_ini_result.x, design_ini_result.y); + p_widget->resize(design_ini_result.width, design_ini_result.height); + } +} + +void Lobby::set_loading_text(QString p_text) +{ + ui_loading_text->clear(); + ui_loading_text->setAlignment(Qt::AlignCenter); + ui_loading_text->append(p_text); +} + +QString Lobby::get_chatlog() +{ + QString return_value = ui_chatbox->toPlainText(); + + return return_value; +} + +int Lobby::get_selected_server() +{ + return ui_server_list->currentRow(); +} + +void Lobby::set_loading_value(int p_value) +{ + ui_progress_bar->setValue(p_value); +} + +void Lobby::on_public_servers_clicked() +{ + ui_public_servers->set_image("publicservers_selected.png"); + ui_favorites->set_image("favorites.png"); + + list_servers(); + + public_servers_selected = true; +} + +void Lobby::on_favorites_clicked() +{ + ui_favorites->set_image("favorites_selected.png"); + ui_public_servers->set_image("publicservers.png"); + + ao_app->set_favorite_list(); + //ao_app->favorite_list = read_serverlist_txt(); + + list_favorites(); + + public_servers_selected = false; +} + +void Lobby::on_refresh_pressed() +{ + ui_refresh->set_image("refresh_pressed.png"); +} + +void Lobby::on_refresh_released() +{ + ui_refresh->set_image("refresh.png"); + + AOPacket *f_packet = new AOPacket("ALL#%"); + + ao_app->send_ms_packet(f_packet); +} + +void Lobby::on_add_to_fav_pressed() +{ + ui_add_to_fav->set_image("addtofav_pressed.png"); +} + +void Lobby::on_add_to_fav_released() +{ + ui_add_to_fav->set_image("addtofav.png"); + + //you cant add favorites from favorites m8 + if (!public_servers_selected) + return; + + ao_app->add_favorite_server(ui_server_list->currentRow()); +} + +void Lobby::on_connect_pressed() +{ + ui_connect->set_image("connect_pressed.png"); +} + +void Lobby::on_connect_released() +{ + ui_connect->set_image("connect.png"); + + AOPacket *f_packet; + + f_packet = new AOPacket("askchaa#%"); + + ao_app->send_server_packet(f_packet); +} + +void Lobby::on_about_clicked() +{ + QString msg = tr("

Attorney Online %1

" + "The courtroom drama simulator" + "

Source code: " + "" + "https://github.com/AttorneyOnline/AO2-Client" + "

Major development:
" + "OmniTroid, stonedDiscord, longbyte1, gameboyprinter, Cerapter" + "

Special thanks:
" + "Remy, Iamgoofball, Hibiki, Qubrick (webAO), Ruekasu (UI design), " + "Draxirch (UI design), Unishred, Argoneus (tsuserver), Fiercy, " + "Noevain, Cronnicossy") + .arg(ao_app->get_version_string()); + QMessageBox::about(this, "About", msg); +} + +void Lobby::on_server_list_clicked(QModelIndex p_model) +{ + server_type f_server; + int n_server = p_model.row(); + + if (n_server < 0) + return; + + if (public_servers_selected) + { + QVector f_server_list = ao_app->get_server_list(); + + if (n_server >= f_server_list.size()) + return; + + f_server = f_server_list.at(p_model.row()); + } + else + { + if (n_server >= ao_app->get_favorite_list().size()) + return; + + f_server = ao_app->get_favorite_list().at(p_model.row()); + } + + ui_description->clear(); + ui_description->append(f_server.desc); + + ui_description->moveCursor(QTextCursor::Start); + ui_description->ensureCursorVisible(); + + ui_player_count->setText("Offline"); + + ui_connect->setEnabled(false); + + ao_app->net_manager->connect_to_server(f_server); +} + +void Lobby::on_chatfield_return_pressed() +{ + //no you can't send empty messages + if (ui_chatname->text() == "" || ui_chatmessage->text() == "") + return; + + + QString f_header = "CT"; + QStringList f_contents{ui_chatname->text(), ui_chatmessage->text()}; + + AOPacket *f_packet = new AOPacket(f_header, f_contents); + + ao_app->send_ms_packet(f_packet); + + ui_chatmessage->clear(); +} + +void Lobby::list_servers() +{ + public_servers_selected = true; + ui_favorites->set_image("favorites.png"); + ui_public_servers->set_image("publicservers_selected.png"); + + ui_server_list->clear(); + + for (server_type i_server : ao_app->get_server_list()) + { + ui_server_list->addItem(i_server.name); + } +} + +void Lobby::list_favorites() +{ + ui_server_list->clear(); + + for (server_type i_server : ao_app->get_favorite_list()) + { + ui_server_list->addItem(i_server.name); + } +} + +void Lobby::append_chatmessage(QString f_name, QString f_message) +{ + ui_chatbox->append_chatmessage(f_name, f_message, ao_app->get_color("ooc_default_color", "courtroom_design.ini").name()); +} + +void Lobby::append_error(QString f_message) +{ + ui_chatbox->append_error(f_message); +} + +void Lobby::set_player_count(int players_online, int max_players) +{ + QString f_string = "Online: " + QString::number(players_online) + "/" + QString::number(max_players); + ui_player_count->setText(f_string); +} + +void Lobby::enable_connect_button() +{ + ui_connect->setEnabled(true); +} + +Lobby::~Lobby() +{ + +} diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 00000000..cf51b0af --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,25 @@ + +#include "aoapplication.h" + +#include "datatypes.h" +#include "networkmanager.h" +#include "lobby.h" +#include "courtroom.h" +#include +#include +Q_IMPORT_PLUGIN(ApngImagePlugin); +int main(int argc, char *argv[]) +{ +#if QT_VERSION > QT_VERSION_CHECK(5, 6, 0) + // High-DPI support is for Qt version >=5.6. + // However, many Linux distros still haven't brought their stable/LTS + // packages up to Qt 5.6, so this is conditional. + AOApplication::setAttribute(Qt::AA_EnableHighDpiScaling); +#endif + + AOApplication main_app(argc, argv); + main_app.construct_lobby(); + main_app.net_manager->connect_to_master(); + main_app.w_lobby->show(); + return main_app.exec(); +} diff --git a/src/misc_functions.cpp b/src/misc_functions.cpp new file mode 100644 index 00000000..23520551 --- /dev/null +++ b/src/misc_functions.cpp @@ -0,0 +1,9 @@ +#include "misc_functions.h" + +void delay(int p_milliseconds) +{ + QTime dieTime = QTime::currentTime().addMSecs(p_milliseconds); + + while(QTime::currentTime() < dieTime) + QCoreApplication::processEvents(QEventLoop::AllEvents, 100); +} diff --git a/src/networkmanager.cpp b/src/networkmanager.cpp new file mode 100644 index 00000000..288a9007 --- /dev/null +++ b/src/networkmanager.cpp @@ -0,0 +1,252 @@ +#include "networkmanager.h" + +#include "datatypes.h" +#include "debug_functions.h" +#include "lobby.h" + +NetworkManager::NetworkManager(AOApplication *parent) : QObject(parent) +{ + ao_app = parent; + + ms_socket = new QTcpSocket(this); + server_socket = new QTcpSocket(this); + + ms_reconnect_timer = new QTimer(this); + ms_reconnect_timer->setSingleShot(true); + QObject::connect(ms_reconnect_timer, SIGNAL(timeout()), this, SLOT(retry_ms_connect())); + + QObject::connect(ms_socket, SIGNAL(readyRead()), this, SLOT(handle_ms_packet())); + QObject::connect(server_socket, SIGNAL(readyRead()), this, SLOT(handle_server_packet())); + QObject::connect(server_socket, SIGNAL(disconnected()), ao_app, SLOT(server_disconnected())); + + QString master_config = ao_app->configini->value("master", "").value(); + if (master_config != "") + ms_nosrv_hostname = master_config; +} + +NetworkManager::~NetworkManager() +{ + +} + +void NetworkManager::connect_to_master() +{ + ms_socket->close(); + ms_socket->abort(); + +#ifdef MS_FAILOVER_SUPPORTED + perform_srv_lookup(); +#else + connect_to_master_nosrv(); +#endif +} + +void NetworkManager::connect_to_master_nosrv() +{ + QObject::connect(ms_socket, SIGNAL(error(QAbstractSocket::SocketError)), + this, SLOT(on_ms_socket_error(QAbstractSocket::SocketError))); + + QObject::connect(ms_socket, SIGNAL(connected()), + this, SLOT(on_ms_nosrv_connect_success())); + ms_socket->connectToHost(ms_nosrv_hostname, ms_port); +} + +void NetworkManager::connect_to_server(server_type p_server) +{ + server_socket->close(); + server_socket->abort(); + + server_socket->connectToHost(p_server.ip, p_server.port); +} + +void NetworkManager::ship_ms_packet(QString p_packet) +{ + if (!ms_socket->isOpen()) + { + retry_ms_connect(); + } + else + { + ms_socket->write(p_packet.toUtf8()); + } +} + +void NetworkManager::ship_server_packet(QString p_packet) +{ + server_socket->write(p_packet.toUtf8()); +} + +void NetworkManager::handle_ms_packet() +{ + char buffer[buffer_max_size]; + std::memset(buffer, 0, buffer_max_size); + ms_socket->read(buffer, buffer_max_size); + + QString in_data = buffer; + + if (!in_data.endsWith("%")) + { + ms_partial_packet = true; + ms_temp_packet += in_data; + return; + } + + else + { + if (ms_partial_packet) + { + in_data = ms_temp_packet + in_data; + ms_temp_packet = ""; + ms_partial_packet = false; + } + } + + QStringList packet_list = in_data.split("%", QString::SplitBehavior(QString::SkipEmptyParts)); + + for (QString packet : packet_list) + { + AOPacket *f_packet = new AOPacket(packet); + + ao_app->ms_packet_received(f_packet); + } +} + + +void NetworkManager::perform_srv_lookup() +{ + #ifdef MS_FAILOVER_SUPPORTED + ms_dns = new QDnsLookup(QDnsLookup::SRV, ms_srv_hostname, this); + + connect(ms_dns, SIGNAL(finished()), this, SLOT(on_srv_lookup())); + ms_dns->lookup(); + #endif +} + +void NetworkManager::on_srv_lookup() +{ + #ifdef MS_FAILOVER_SUPPORTED + bool connected = false; + if (ms_dns->error() != QDnsLookup::NoError) + { + qWarning("SRV lookup of the master server DNS failed."); + ms_dns->deleteLater(); + } + else + { + const auto srv_records = ms_dns->serviceRecords(); + + for (const QDnsServiceRecord &record : srv_records) + { + qDebug() << "Connecting to " << record.target() << ":" << record.port(); + ms_socket->connectToHost(record.target(), record.port()); + QTime timer; + timer.start(); + do + { + ao_app->processEvents(); + if (ms_socket->state() == QAbstractSocket::ConnectedState) + { + connected = true; + break; + } + else if (ms_socket->state() != QAbstractSocket::ConnectingState + && ms_socket->state() != QAbstractSocket::HostLookupState + && ms_socket->error() != -1) + { + qDebug() << ms_socket->error(); + qWarning() << "Error connecting to master server:" << ms_socket->errorString(); + ms_socket->abort(); + ms_socket->close(); + break; + } + } while (timer.elapsed() < timeout_milliseconds); // Very expensive spin-wait loop - it will bring CPU to 100%! + if (connected) + { + // Connect a one-shot signal in case the master server disconnects randomly + QObject::connect(ms_socket, SIGNAL(error(QAbstractSocket::SocketError)), + this, SLOT(on_ms_socket_error(QAbstractSocket::SocketError))); + break; + } + else + { + ms_socket->abort(); + ms_socket->close(); + } + } + } + + // Failover to non-SRV connection + if (!connected) + connect_to_master_nosrv(); + else + emit ms_connect_finished(connected, false); + #endif +} + +void NetworkManager::on_ms_nosrv_connect_success() +{ + emit ms_connect_finished(true, false); + + QObject::disconnect(ms_socket, SIGNAL(connected()), + this, SLOT(on_ms_nosrv_connect_success())); + + QObject::connect(ms_socket, SIGNAL(error(QAbstractSocket::SocketError)), + this, SLOT(on_ms_socket_error(QAbstractSocket::SocketError))); +} + +void NetworkManager::on_ms_socket_error(QAbstractSocket::SocketError error) +{ + qWarning() << "Master server socket error:" << ms_socket->errorString() + << "(" << error << ")"; + + // Disconnect the one-shot signal - this way, failover connect attempts + // don't trigger a full retry + QObject::disconnect(ms_socket, SIGNAL(error(QAbstractSocket::SocketError)), + this, SLOT(on_ms_socket_error(QAbstractSocket::SocketError))); + + emit ms_connect_finished(false, true); + + ms_reconnect_timer->start(ms_reconnect_delay_ms); +} + +void NetworkManager::retry_ms_connect() +{ + if (!ms_reconnect_timer->isActive() && ms_socket->state() != QAbstractSocket::ConnectingState) + connect_to_master(); +} + +void NetworkManager::handle_server_packet() +{ + char buffer[buffer_max_size]; + std::memset(buffer, 0, buffer_max_size); + server_socket->read(buffer, buffer_max_size); + + QString in_data = buffer; + + if (!in_data.endsWith("%")) + { + partial_packet = true; + temp_packet += in_data; + return; + } + + else + { + if (partial_packet) + { + in_data = temp_packet + in_data; + temp_packet = ""; + partial_packet = false; + } + } + + QStringList packet_list = in_data.split("%", QString::SplitBehavior(QString::SkipEmptyParts)); + + for (QString packet : packet_list) + { + AOPacket *f_packet = new AOPacket(packet); + + ao_app->server_packet_received(f_packet); + } +} + diff --git a/src/packet_distribution.cpp b/src/packet_distribution.cpp new file mode 100644 index 00000000..954062e8 --- /dev/null +++ b/src/packet_distribution.cpp @@ -0,0 +1,707 @@ +#include "aoapplication.h" + +#include "lobby.h" +#include "courtroom.h" +#include "networkmanager.h" +#include "encryption_functions.h" +#include "hardware_functions.h" +#include "debug_functions.h" + +void AOApplication::ms_packet_received(AOPacket *p_packet) +{ + p_packet->net_decode(); + + QString header = p_packet->get_header(); + QStringList f_contents = p_packet->get_contents(); + + if (header != "CHECK") + qDebug() << "R(ms):" << p_packet->to_string(); + + if (header == "ALL") + { + server_list.clear(); + + for (QString i_string : p_packet->get_contents()) + { + server_type f_server; + QStringList sub_contents = i_string.split("&"); + + if (sub_contents.size() < 4) + { + qDebug() << "W: malformed packet"; + continue; + } + + f_server.name = sub_contents.at(0); + f_server.desc = sub_contents.at(1); + f_server.ip = sub_contents.at(2); + f_server.port = sub_contents.at(3).toInt(); + + server_list.append(f_server); + } + + if (lobby_constructed) + { + w_lobby->list_servers(); + } + } + else if (header == "CT") + { + QString f_name, f_message; + + if (f_contents.size() == 1) + { + f_name = ""; + f_message = f_contents.at(0); + } + else if (f_contents.size() >= 2) + { + f_name = f_contents.at(0); + f_message = f_contents.at(1); + } + else + goto end; + + if (lobby_constructed) + { + w_lobby->append_chatmessage(f_name, f_message); + } + if (courtroom_constructed && courtroom_loaded) + { + w_courtroom->append_ms_chatmessage(f_name, f_message); + } + } + else if (header == "AO2CHECK") + { + send_ms_packet(new AOPacket("ID#AO2#" + get_version_string() + "#%")); + send_ms_packet(new AOPacket("HI#" + get_hdid() + "#%")); + + if (f_contents.size() < 1) + goto end; + + QStringList version_contents = f_contents.at(0).split("."); + + if (version_contents.size() < 3) + goto end; + + int f_release = version_contents.at(0).toInt(); + int f_major = version_contents.at(1).toInt(); + int f_minor = version_contents.at(2).toInt(); + + if (get_release() > f_release) + goto end; + else if (get_release() == f_release) + { + if (get_major_version() > f_major) + goto end; + else if (get_major_version() == f_major) + { + if (get_minor_version() >= f_minor) + goto end; + } + } + + call_notice("Outdated version! Your version: " + get_version_string() + + "\nPlease go to aceattorneyonline.com to update."); + destruct_courtroom(); + destruct_lobby(); + } + else if (header == "DOOM") + { + call_notice("You have been exiled from AO." + "Have a nice day."); + destruct_courtroom(); + destruct_lobby(); + } + + end: + + delete p_packet; +} + +void AOApplication::server_packet_received(AOPacket *p_packet) +{ + p_packet->net_decode(); + + QString header = p_packet->get_header(); + QStringList f_contents = p_packet->get_contents(); + QString f_packet = p_packet->to_string(); + + if (header != "checkconnection") + qDebug() << "R:" << f_packet; + + if (header == "decryptor") + { + 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; + arup_enabled = false; + casing_alerts_enabled = false; + modcall_reason_enabled = false; + + //workaround for tsuserver4 + if (f_contents.at(0) == "NOENCRYPT") + encryption_needed = false; + + QString f_hdid; + f_hdid = get_hdid(); + + AOPacket *hi_packet = new AOPacket("HI#" + f_hdid + "#%"); + send_server_packet(hi_packet); + } + else if (header == "ID") + { + if (f_contents.size() < 2) + goto end; + + s_pv = f_contents.at(0).toInt(); + server_software = f_contents.at(1); + + send_server_packet(new AOPacket("ID#AO2#" + get_version_string() + "#%")); + } + else if (header == "CT") + { + if (f_contents.size() < 2) + goto end; + + if (courtroom_constructed) + { + if (f_contents.size() == 3) + w_courtroom->append_server_chatmessage(f_contents.at(0), f_contents.at(1), f_contents.at(2)); + else + w_courtroom->append_server_chatmessage(f_contents.at(0), f_contents.at(1), "0"); + } + } + else if (header == "FL") + { + if (f_packet.contains("yellowtext",Qt::CaseInsensitive)) + yellow_text_enabled = true; + if (f_packet.contains("flipping",Qt::CaseInsensitive)) + 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)) + evidence_enabled = true; + if (f_packet.contains("cccc_ic_support",Qt::CaseInsensitive)) + cccc_ic_support_enabled = true; + if (f_packet.contains("arup",Qt::CaseInsensitive)) + arup_enabled = true; + if (f_packet.contains("casing_alerts",Qt::CaseInsensitive)) + casing_alerts_enabled = true; + if (f_packet.contains("modcall_reason",Qt::CaseInsensitive)) + modcall_reason_enabled = true; + + w_lobby->enable_connect_button(); + } + else if (header == "PN") + { + if (f_contents.size() < 2) + goto end; + + w_lobby->set_player_count(f_contents.at(0).toInt(), f_contents.at(1).toInt()); + } + else if (header == "SI") + { + if (f_contents.size() != 3) + goto end; + + char_list_size = f_contents.at(0).toInt(); + evidence_list_size = f_contents.at(1).toInt(); + music_list_size = f_contents.at(2).toInt(); + + if (char_list_size < 1 || evidence_list_size < 0 || music_list_size < 0) + goto end; + + loaded_chars = 0; + loaded_evidence = 0; + loaded_music = 0; + generated_chars = 0; + + destruct_courtroom(); + construct_courtroom(); + + courtroom_loaded = false; + + QString window_title = "Attorney Online 2"; + int selected_server = w_lobby->get_selected_server(); + + QString server_address = "", server_name = ""; + if (w_lobby->public_servers_selected) + { + if (selected_server >= 0 && selected_server < server_list.size()) { + auto info = server_list.at(selected_server); + server_name = info.name; + server_address = QString("%1:%2").arg(info.ip, info.port); + window_title += ": " + server_name; + } + } + else + { + if (selected_server >= 0 && selected_server < favorite_list.size()) { + auto info = favorite_list.at(selected_server); + server_name = info.name; + server_address = info.ip + info.port; + window_title += ": " + server_name; + } + } + + w_courtroom->set_window_title(window_title); + + w_lobby->show_loading_overlay(); + w_lobby->set_loading_text("Loading"); + w_lobby->set_loading_value(0); + + AOPacket *f_packet; + + if(improved_loading_enabled) + f_packet = new AOPacket("RC#%"); + else + f_packet = new AOPacket("askchar2#%"); + + send_server_packet(f_packet); + + QCryptographicHash hash(QCryptographicHash::Algorithm::Sha256); + hash.addData(server_address.toUtf8()); + if (is_discord_enabled()) + 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("Loading chars:\n" + QString::number(loaded_chars) + "/" + 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(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("Loading evidence:\n" + QString::number(loaded_evidence) + "/" + 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(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("Loading music:\n" + QString::number(loaded_music) + "/" + 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(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; + + for (int n_char = 0 ; n_char < f_contents.size() ; ++n_char) + { + if (f_contents.at(n_char) == "-1") + w_courtroom->set_taken(n_char, true); + else + w_courtroom->set_taken(n_char, false); + } + } + + else if (header == "SC") + { + if (!courtroom_constructed) + goto end; + + for (int n_element = 0 ; n_element < f_contents.size() ; ++n_element) + { + QStringList sub_elements = f_contents.at(n_element).split("&"); + + char_type f_char; + f_char.name = sub_elements.at(0); + if (sub_elements.size() >= 2) + f_char.description = sub_elements.at(1); + + //temporary. the CharsCheck packet sets this properly + f_char.taken = false; + + ++loaded_chars; + + w_lobby->set_loading_text("Loading chars:\n" + QString::number(loaded_chars) + "/" + 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(total_loading_size)) * 100); + w_lobby->set_loading_value(loading_value); + } + + send_server_packet(new AOPacket("RM#%")); + } + else if (header == "SM") + { + if (!courtroom_constructed) + goto end; + + bool musics_time = false; + int areas = 0; + + for (int n_element = 0 ; n_element < f_contents.size() ; ++n_element) + { + ++loaded_music; + + w_lobby->set_loading_text("Loading music:\n" + QString::number(loaded_music) + "/" + QString::number(music_list_size)); + + if (musics_time) + { + w_courtroom->append_music(f_contents.at(n_element)); + } + else + { + if (f_contents.at(n_element).endsWith(".wav") || + f_contents.at(n_element).endsWith(".mp3") || + f_contents.at(n_element).endsWith(".mp4") || + f_contents.at(n_element).endsWith(".ogg") || + f_contents.at(n_element).endsWith(".opus")) + { + musics_time = true; + w_courtroom->fix_last_area(); + w_courtroom->append_music(f_contents.at(n_element)); + areas--; + } + else + { + w_courtroom->append_area(f_contents.at(n_element)); + 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(total_loading_size)) * 100); + w_lobby->set_loading_value(loading_value); + } + + send_server_packet(new AOPacket("RD#%")); + } + else if (header == "DONE") + { + if (!courtroom_constructed) + goto end; + + if (lobby_constructed) + w_courtroom->append_ms_chatmessage("", w_lobby->get_chatlog()); + + w_courtroom->character_loading_finished(); + w_courtroom->done_received(); + + courtroom_loaded = true; + + destruct_lobby(); + } + else if (header == "BN") + { + if (f_contents.size() < 1) + goto end; + + if (courtroom_constructed) + w_courtroom->set_background(f_contents.at(0)); + } + //server accepting char request(CC) packet + else if (header == "PV") + { + if (f_contents.size() < 3) + goto end; + + if (courtroom_constructed) + w_courtroom->enter_courtroom(f_contents.at(2).toInt()); + } + else if (header == "MS") + { + if (courtroom_constructed && courtroom_loaded) + w_courtroom->handle_chatmessage(&p_packet->get_contents()); + } + else if (header == "MC") + { + if (courtroom_constructed && courtroom_loaded) + w_courtroom->handle_song(&p_packet->get_contents()); + } + else if (header == "RT") + { + if (f_contents.size() < 1) + goto end; + if (courtroom_constructed) + { + if (f_contents.size() == 1) + w_courtroom->handle_wtce(f_contents.at(0), 0); + else if (f_contents.size() == 2) { + w_courtroom->handle_wtce(f_contents.at(0), f_contents.at(1).toInt()); + } + } + } + else if (header == "HP") + { + if (courtroom_constructed && f_contents.size() > 1) + w_courtroom->set_hp_bar(f_contents.at(0).toInt(), f_contents.at(1).toInt()); + } + else if (header == "LE") + { + if (courtroom_constructed) + { + QVector f_evi_list; + + for (QString f_string : f_contents) + { + QStringList sub_contents = f_string.split("&"); + + if (sub_contents.size() < 3) + continue; + + evi_type f_evi; + f_evi.name = sub_contents.at(0); + f_evi.description = sub_contents.at(1); + f_evi.image = sub_contents.at(2); + + f_evi_list.append(f_evi); + } + + w_courtroom->set_evidence_list(f_evi_list); + } + } + else if (header == "ARUP") + { + if (courtroom_constructed) + { + int arup_type = f_contents.at(0).toInt(); + for (int n_element = 1 ; n_element < f_contents.size() ; n_element++) + { + w_courtroom->arup_modify(arup_type, n_element - 1, f_contents.at(n_element)); + } + } + } + else if (header == "IL") + { + if (courtroom_constructed && f_contents.size() > 0) + w_courtroom->set_ip_list(f_contents.at(0)); + } + else if (header == "MU") + { + if (courtroom_constructed && f_contents.size() > 0) + w_courtroom->set_mute(true, f_contents.at(0).toInt()); + } + else if (header == "UM") + { + if (courtroom_constructed && f_contents.size() > 0) + w_courtroom->set_mute(false, f_contents.at(0).toInt()); + } + else if (header == "KK") + { + if (courtroom_constructed && f_contents.size() >= 1) + { + call_notice("You have been kicked from the server.\nReason: " + f_contents.at(0)); + construct_lobby(); + destruct_courtroom(); + } + } + else if (header == "KB") + { + if (courtroom_constructed && f_contents.size() >= 1) + { + call_notice("You have been banned from the server.\nReason: " + f_contents.at(0)); + construct_lobby(); + destruct_courtroom(); + } + + } + else if (header == "BD") + { + call_notice("You are banned on this server."); + } + else if (header == "ZZ") + { + if (courtroom_constructed && f_contents.size() > 0) + w_courtroom->mod_called(f_contents.at(0)); + } + else if (header == "CASEA") + { + if (courtroom_constructed && f_contents.size() > 6) + w_courtroom->case_called(f_contents.at(0), f_contents.at(1) == "1", f_contents.at(2) == "1", f_contents.at(3) == "1", f_contents.at(4) == "1", f_contents.at(5) == "1"); + } + + end: + + delete p_packet; +} + +void AOApplication::send_ms_packet(AOPacket *p_packet) +{ + p_packet->net_encode(); + + QString f_packet = p_packet->to_string(); + + net_manager->ship_ms_packet(f_packet); + + qDebug() << "S(ms):" << f_packet; + + delete p_packet; +} + +void AOApplication::send_server_packet(AOPacket *p_packet, bool encoded) +{ + if (encoded) + p_packet->net_encode(); + + QString f_packet = p_packet->to_string(); + + if (encryption_needed) + { + qDebug() << "S(e):" << f_packet; + + p_packet->encrypt_header(s_decryptor); + f_packet = p_packet->to_string(); + } + else + { + qDebug() << "S:" << f_packet; + } + + net_manager->ship_server_packet(f_packet); + + delete p_packet; +} diff --git a/src/path_functions.cpp b/src/path_functions.cpp new file mode 100644 index 00000000..c51cfde3 --- /dev/null +++ b/src/path_functions.cpp @@ -0,0 +1,162 @@ +#include "aoapplication.h" +#include "courtroom.h" +#include "file_functions.h" + +#include +#include +#include + +#ifdef BASE_OVERRIDE +#include "base_override.h" +#endif + +//this is a quite broad generalization +//the most common OSes(mac and windows) are _usually_ case insensitive +//however, there do exist mac installations with case sensitive filesystems +//in that case, define CASE_SENSITIVE_FILESYSTEM and compile on a mac +#if (defined (LINUX) || defined (__linux__)) +#define CASE_SENSITIVE_FILESYSTEM +#endif + +QString AOApplication::get_base_path() +{ + QString base_path = ""; +#ifdef ANDROID + QString sdcard_storage = getenv("SECONDARY_STORAGE"); + if (dir_exists(sdcard_storage + "/AO2/")){ + base_path = sdcard_storage + "/AO2/"; + } + else { + QString external_storage = getenv("EXTERNAL_STORAGE"); + base_path = external_storage + "/AO2/"; + } +#else + base_path = applicationDirPath() + "/base/"; +#endif + + return base_path; +} + +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) +{ + 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) +{ + 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); +} + +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) { + //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? + if (exists(file_parent_dir + "/" + file_basename)) + return file_parent_dir + "/" + file_basename; + + //last resort, dirlist parent dir and find case insensitive match + QRegExp file_rx = QRegExp(file_basename, Qt::CaseInsensitive, QRegExp::FixedString); + QStringList files = QDir(file_parent_dir).entryList(); + + int result = files.indexOf(file_rx); + + if (result != -1) + return file_parent_dir + "/" + files.at(result); + + //if nothing is found, let the caller handle the missing file + return file_parent_dir + "/" + file_basename; +} diff --git a/src/text_file_functions.cpp b/src/text_file_functions.cpp new file mode 100644 index 00000000..fcb8df2c --- /dev/null +++ b/src/text_file_functions.cpp @@ -0,0 +1,639 @@ +#include "text_file_functions.h" + +QString AOApplication::read_theme() +{ + QString result = configini->value("theme", "default").value(); + return result; +} + +int AOApplication::read_blip_rate() +{ + int result = configini->value("blip_rate", 1).toInt(); + return result; +} + +QString AOApplication::get_ooc_name() +{ + QString result = configini->value("ooc_name").value(); + return result; +} + +int AOApplication::get_default_music() +{ + int result = configini->value("default_music", 50).toInt(); + return result; +} + +int AOApplication::get_default_sfx() +{ + int result = configini->value("default_sfx", 50).toInt(); + return result; +} + +int AOApplication::get_default_blip() +{ + int result = configini->value("default_blip", 50).toInt(); + return result; +} + +int AOApplication::get_max_log_size() +{ + int result = configini->value("log_maximum", 200).toInt(); + return result; +} + +bool AOApplication::get_log_goes_downwards() +{ + QString result = configini->value("log_goes_downwards", "false").value(); + return result.startsWith("true"); +} + +bool AOApplication::get_showname_enabled_by_default() +{ + QString result = configini->value("show_custom_shownames", "true").value(); + return result.startsWith("true"); +} + +QString AOApplication::get_default_username() +{ + QString result = configini->value("default_username", "").value(); + if (result.isEmpty()) + return get_ooc_name(); + else + return result; +} + +QString AOApplication::get_audio_output_device() +{ + QString result = configini->value("default_audio_device", "default").value(); + return result; +} + +QStringList AOApplication::get_call_words() +{ + QStringList return_value; + + QFile callwords_ini; + + callwords_ini.setFileName(get_base_path() + "callwords.ini"); + + if (!callwords_ini.open(QIODevice::ReadOnly)) + return return_value; + + QTextStream in(&callwords_ini); + + while (!in.atEnd()) + { + QString line = in.readLine(); + return_value.append(line); + } + + return return_value; +} + +void AOApplication::write_to_serverlist_txt(QString p_line) +{ + QFile serverlist_txt; + QString serverlist_txt_path = get_base_path() + "serverlist.txt"; + + serverlist_txt.setFileName(serverlist_txt_path); + + if (!serverlist_txt.open(QIODevice::WriteOnly | QIODevice::Append)) + { + return; + } + + QTextStream out(&serverlist_txt); + + out << "\r\n" << p_line; + + serverlist_txt.close(); +} + +QVector AOApplication::read_serverlist_txt() +{ + QVector f_server_list; + + QFile serverlist_txt; + QString serverlist_txt_path = get_base_path() + "serverlist.txt"; + + serverlist_txt.setFileName(serverlist_txt_path); + + if (!serverlist_txt.open(QIODevice::ReadOnly)) + { + return f_server_list; + } + + QTextStream in(&serverlist_txt); + + while(!in.atEnd()) + { + QString line = in.readLine(); + server_type f_server; + QStringList line_contents = line.split(":"); + + if (line_contents.size() < 3) + continue; + + f_server.ip = line_contents.at(0); + f_server.port = line_contents.at(1).toInt(); + f_server.name = line_contents.at(2); + f_server.desc = ""; + + f_server_list.append(f_server); + } + + return f_server_list; +} + +QString AOApplication::read_design_ini(QString p_identifier, QString p_design_path) +{ + QSettings settings(p_design_path, QSettings::IniFormat); + QVariant value = settings.value(p_identifier); + if (value.type() == QVariant::StringList) { + return value.toStringList().join(","); + } else { + return value.toString(); + } +} + +QPoint AOApplication::get_button_spacing(QString p_identifier, QString p_file) +{ + QString design_ini_path = get_theme_path(p_file); + QString default_path = get_default_theme_path(p_file); + QString f_result = read_design_ini(p_identifier, design_ini_path); + + QPoint return_value; + + return_value.setX(0); + return_value.setY(0); + + if (f_result == "") + { + f_result = read_design_ini(p_identifier, default_path); + + if (f_result == "") + return return_value; + } + + QStringList sub_line_elements = f_result.split(","); + + if (sub_line_elements.size() < 2) + return return_value; + + return_value.setX(sub_line_elements.at(0).toInt()); + return_value.setY(sub_line_elements.at(1).toInt()); + + return return_value; +} + +pos_size_type AOApplication::get_element_dimensions(QString p_identifier, QString p_file) +{ + QString design_ini_path = get_theme_path(p_file); + QString default_path = get_default_theme_path(p_file); + QString f_result = read_design_ini(p_identifier, design_ini_path); + + pos_size_type return_value; + + return_value.x = 0; + return_value.y = 0; + return_value.width = -1; + return_value.height = -1; + + if (f_result == "") + { + f_result = read_design_ini(p_identifier, default_path); + + if (f_result == "") + return return_value; + } + + QStringList sub_line_elements = f_result.split(","); + + if (sub_line_elements.size() < 4) + return return_value; + + return_value.x = sub_line_elements.at(0).toInt(); + return_value.y = sub_line_elements.at(1).toInt(); + return_value.width = sub_line_elements.at(2).toInt(); + return_value.height = sub_line_elements.at(3).toInt(); + + return return_value; +} + +int AOApplication::get_font_size(QString p_identifier, QString p_file) +{ + QString design_ini_path = get_theme_path(p_file); + QString default_path = get_default_theme_path(p_file); + QString f_result = read_design_ini(p_identifier, design_ini_path); + + if (f_result == "") + { + f_result = read_design_ini(p_identifier, default_path); + + if (f_result == "") + return 10; + } + + return f_result.toInt(); +} + +QColor AOApplication::get_color(QString p_identifier, QString p_file) +{ + QString design_ini_path = get_theme_path(p_file); + QString default_path = get_default_theme_path(p_file); + QString f_result = read_design_ini(p_identifier, design_ini_path); + + QColor return_color(0, 0, 0); + + if (f_result == "") + { + f_result = read_design_ini(p_identifier, default_path); + + if (f_result == "") + return return_color; + } + + QStringList color_list = f_result.split(","); + + if (color_list.size() < 3) + return return_color; + + return_color.setRed(color_list.at(0).toInt()); + return_color.setGreen(color_list.at(1).toInt()); + return_color.setBlue(color_list.at(2).toInt()); + + return return_color; +} + +QColor AOApplication::get_chat_color(QString p_identifier, QString p_chat) +{ + QColor return_color(255, 255, 255); + + if (p_identifier == "_inline_grey") + { + return_color = QColor(187, 187, 187); + } + else + { + switch (p_identifier.toInt()) { + case 1: + return_color = QColor(0, 255, 0); + break; + case 2: + return_color = QColor(255, 0, 0); + break; + case 3: + return_color = QColor(255, 165, 0); + break; + case 4: + return_color = QColor(45, 150, 255); + break; + case 5: + return_color = QColor(255, 255, 0); + break; + case 7: + return_color = QColor(255, 192, 203); + break; + case 8: + return_color = QColor(0, 255, 255); + break; + case 0: + case 6: // 6 is rainbow. + default: + return_color = QColor(255, 255, 255); + break; + } + } + + p_identifier = p_identifier.prepend("c"); + QString design_ini_path = get_base_path() + "misc/" + p_chat + "/config.ini"; + QString default_path = get_base_path() + "misc/default/config.ini"; + QString f_result = read_design_ini(p_identifier, design_ini_path); + + if (f_result == "") + { + f_result = read_design_ini(p_identifier, default_path); + + if (f_result == "") + return return_color; + } + + QStringList color_list = f_result.split(","); + + if (color_list.size() < 3) + return return_color; + + return_color.setRed(color_list.at(0).toInt()); + return_color.setGreen(color_list.at(1).toInt()); + return_color.setBlue(color_list.at(2).toInt()); + + return return_color; +} + +QString AOApplication::get_sfx(QString p_identifier) +{ + QString design_ini_path = get_theme_path("courtroom_sounds.ini"); + QString default_path = get_default_theme_path("courtroom_sounds.ini"); + QString f_result = read_design_ini(p_identifier, design_ini_path); + + QString return_sfx = ""; + + if (f_result == "") + { + f_result = read_design_ini(p_identifier, default_path); + + if (f_result == "") + return return_sfx; + } + + return_sfx = f_result; + + return return_sfx; +} + +QString AOApplication::get_sfx_suffix(QString sound_to_check) +{ + QString mp3_check = get_sounds_path(sound_to_check + ".mp3"); + QString opus_check = get_sounds_path(sound_to_check + ".opus"); + if (file_exists(opus_check)) + { + return sound_to_check + ".opus"; + } + else if (file_exists(mp3_check)) + { + return sound_to_check + ".mp3"; + } + return sound_to_check + ".wav"; +} + +QString AOApplication::get_image_suffix(QString path_to_check) +{ + QString apng_check = get_sounds_path(path_to_check + ".apng"); + if (file_exists(apng_check)) + { + return path_to_check + ".apng"; + } + return path_to_check + ".gif"; +} + + +//returns whatever is to the right of "search_line =" within target_tag and terminator_tag, trimmed +//returns the empty string if the search line couldnt be found +QString AOApplication::read_char_ini(QString p_char, QString p_search_line, QString target_tag) +{ + QSettings settings(get_character_path(p_char, "char.ini"), QSettings::IniFormat); + settings.beginGroup(target_tag); + QString value = settings.value(p_search_line).toString(); + settings.endGroup(); + return value; +} + +QString AOApplication::get_char_name(QString p_char) +{ + QString f_result = read_char_ini(p_char, "name", "Options"); + + if (f_result == "") + return p_char; + else return f_result; +} + +QString AOApplication::get_showname(QString p_char) +{ + QString f_result = read_char_ini(p_char, "showname", "Options"); + QString f_needed = read_char_ini(p_char, "needs_showname", "Options"); + + if (f_needed.startsWith("false")) + return ""; + if (f_result == "") + return p_char; + else return f_result; +} + +QString AOApplication::get_char_side(QString p_char) +{ + QString f_result = read_char_ini(p_char, "side", "Options"); + + if (f_result == "") + return "wit"; + else return f_result; +} + +QString AOApplication::get_gender(QString p_char) +{ + QString f_result = read_char_ini(p_char, "gender", "Options"); + + if (f_result == "") + return "male"; + else return f_result; +} + +QString AOApplication::get_chat(QString p_char) +{ + QString f_result = read_char_ini(p_char, "chat", "Options"); + + //handling the correct order of chat is a bit complicated, we let the caller do it + return f_result; +} + +QString AOApplication::get_char_shouts(QString p_char) +{ + QString f_result = read_char_ini(p_char, "shouts", "Options"); + + return f_result; +} + +int AOApplication::get_preanim_duration(QString p_char, QString p_emote) +{ + QString f_result = read_char_ini(p_char, p_emote, "Time"); + + if (f_result == "") + return -1; + else return f_result.toInt(); +} + +int AOApplication::get_ao2_preanim_duration(QString p_char, QString p_emote) +{ + QString f_result = read_char_ini(p_char, "%" + p_emote, "Time"); + + if (f_result == "") + return -1; + else return f_result.toInt(); +} + +int AOApplication::get_emote_number(QString p_char) +{ + QString f_result = read_char_ini(p_char, "number", "Emotions"); + + if (f_result == "") + return 0; + else return f_result.toInt(); +} + +QString AOApplication::get_emote_comment(QString p_char, int p_emote) +{ + QString f_result = read_char_ini(p_char, QString::number(p_emote + 1), "Emotions"); + + QStringList result_contents = f_result.split("#"); + + if (result_contents.size() < 4) + { + qDebug() << "W: misformatted char.ini: " << p_char << ", " << p_emote; + return "normal"; + } + else return result_contents.at(0); +} + +QString AOApplication::get_pre_emote(QString p_char, int p_emote) +{ + QString f_result = read_char_ini(p_char, QString::number(p_emote + 1), "Emotions"); + + QStringList result_contents = f_result.split("#"); + + if (result_contents.size() < 4) + { + qDebug() << "W: misformatted char.ini: " << p_char << ", " << p_emote; + return ""; + } + else return result_contents.at(1); +} + +QString AOApplication::get_emote(QString p_char, int p_emote) +{ + QString f_result = read_char_ini(p_char, QString::number(p_emote + 1), "Emotions"); + + QStringList result_contents = f_result.split("#"); + + if (result_contents.size() < 4) + { + qDebug() << "W: misformatted char.ini: " << p_char << ", " << p_emote; + return "normal"; + } + else return result_contents.at(2); +} + +int AOApplication::get_emote_mod(QString p_char, int p_emote) +{ + QString f_result = read_char_ini(p_char, QString::number(p_emote + 1), "Emotions"); + + QStringList result_contents = f_result.split("#"); + + if (result_contents.size() < 4) + { + qDebug() << "W: misformatted char.ini: " << p_char << ", " << QString::number(p_emote); + return 0; + } + else return result_contents.at(3).toInt(); +} + +int AOApplication::get_desk_mod(QString p_char, int p_emote) +{ + QString f_result = read_char_ini(p_char, QString::number(p_emote + 1), "Emotions"); + + QStringList result_contents = f_result.split("#"); + + if (result_contents.size() < 5) + return -1; + + QString string_result = result_contents.at(4); + if (string_result == "") + return -1; + + else return string_result.toInt(); +} + +QString AOApplication::get_sfx_name(QString p_char, int p_emote) +{ + QString f_result = read_char_ini(p_char, QString::number(p_emote + 1), "SoundN"); + + if (f_result == "") + return "1"; + else return f_result; +} + +int AOApplication::get_sfx_delay(QString p_char, int p_emote) +{ + QString f_result = read_char_ini(p_char, QString::number(p_emote + 1), "SoundT"); + + if (f_result == "") + return 1; + else return f_result.toInt(); +} + +int AOApplication::get_text_delay(QString p_char, QString p_emote) +{ + QString f_result = read_char_ini(p_char, p_emote, "TextDelay"); + + if (f_result == "") + return -1; + else return f_result.toInt(); +} + +QString AOApplication::get_custom_realization(QString p_char) +{ + QString f_result = read_char_ini(p_char, "realization", "Options"); + + if (f_result == "") + return get_sfx("realization"); + else return f_result; +} + +bool AOApplication::get_blank_blip() +{ + QString result = configini->value("blank_blip", "false").value(); + return result.startsWith("true"); +} + +bool AOApplication::is_discord_enabled() +{ + QString result = configini->value("discord", "true").value(); + return result.startsWith("true"); +} + +bool AOApplication::get_casing_enabled() +{ + QString result = configini->value("casing_enabled", "false").value(); + return result.startsWith("true"); +} + +bool AOApplication::get_casing_defence_enabled() +{ + QString result = configini->value("casing_defence_enabled", "false").value(); + return result.startsWith("true"); +} + +bool AOApplication::get_casing_prosecution_enabled() +{ + QString result = configini->value("casing_prosecution_enabled", "false").value(); + return result.startsWith("true"); +} + +bool AOApplication::get_casing_judge_enabled() +{ + QString result = configini->value("casing_judge_enabled", "false").value(); + return result.startsWith("true"); +} + +bool AOApplication::get_casing_juror_enabled() +{ + QString result = configini->value("casing_juror_enabled", "false").value(); + return result.startsWith("true"); +} + +bool AOApplication::get_casing_steno_enabled() +{ + QString result = configini->value("casing_steno_enabled", "false").value(); + return result.startsWith("true"); +} + +bool AOApplication::get_casing_cm_enabled() +{ + QString result = configini->value("casing_cm_enabled", "false").value(); + return result.startsWith("true"); +} + +QString AOApplication::get_casing_can_host_cases() +{ + QString result = configini->value("casing_can_host_cases", "Turnabout Check Your Settings").value(); + return result; +} diff --git a/text_file_functions.cpp b/text_file_functions.cpp deleted file mode 100644 index fcb8df2c..00000000 --- a/text_file_functions.cpp +++ /dev/null @@ -1,639 +0,0 @@ -#include "text_file_functions.h" - -QString AOApplication::read_theme() -{ - QString result = configini->value("theme", "default").value(); - return result; -} - -int AOApplication::read_blip_rate() -{ - int result = configini->value("blip_rate", 1).toInt(); - return result; -} - -QString AOApplication::get_ooc_name() -{ - QString result = configini->value("ooc_name").value(); - return result; -} - -int AOApplication::get_default_music() -{ - int result = configini->value("default_music", 50).toInt(); - return result; -} - -int AOApplication::get_default_sfx() -{ - int result = configini->value("default_sfx", 50).toInt(); - return result; -} - -int AOApplication::get_default_blip() -{ - int result = configini->value("default_blip", 50).toInt(); - return result; -} - -int AOApplication::get_max_log_size() -{ - int result = configini->value("log_maximum", 200).toInt(); - return result; -} - -bool AOApplication::get_log_goes_downwards() -{ - QString result = configini->value("log_goes_downwards", "false").value(); - return result.startsWith("true"); -} - -bool AOApplication::get_showname_enabled_by_default() -{ - QString result = configini->value("show_custom_shownames", "true").value(); - return result.startsWith("true"); -} - -QString AOApplication::get_default_username() -{ - QString result = configini->value("default_username", "").value(); - if (result.isEmpty()) - return get_ooc_name(); - else - return result; -} - -QString AOApplication::get_audio_output_device() -{ - QString result = configini->value("default_audio_device", "default").value(); - return result; -} - -QStringList AOApplication::get_call_words() -{ - QStringList return_value; - - QFile callwords_ini; - - callwords_ini.setFileName(get_base_path() + "callwords.ini"); - - if (!callwords_ini.open(QIODevice::ReadOnly)) - return return_value; - - QTextStream in(&callwords_ini); - - while (!in.atEnd()) - { - QString line = in.readLine(); - return_value.append(line); - } - - return return_value; -} - -void AOApplication::write_to_serverlist_txt(QString p_line) -{ - QFile serverlist_txt; - QString serverlist_txt_path = get_base_path() + "serverlist.txt"; - - serverlist_txt.setFileName(serverlist_txt_path); - - if (!serverlist_txt.open(QIODevice::WriteOnly | QIODevice::Append)) - { - return; - } - - QTextStream out(&serverlist_txt); - - out << "\r\n" << p_line; - - serverlist_txt.close(); -} - -QVector AOApplication::read_serverlist_txt() -{ - QVector f_server_list; - - QFile serverlist_txt; - QString serverlist_txt_path = get_base_path() + "serverlist.txt"; - - serverlist_txt.setFileName(serverlist_txt_path); - - if (!serverlist_txt.open(QIODevice::ReadOnly)) - { - return f_server_list; - } - - QTextStream in(&serverlist_txt); - - while(!in.atEnd()) - { - QString line = in.readLine(); - server_type f_server; - QStringList line_contents = line.split(":"); - - if (line_contents.size() < 3) - continue; - - f_server.ip = line_contents.at(0); - f_server.port = line_contents.at(1).toInt(); - f_server.name = line_contents.at(2); - f_server.desc = ""; - - f_server_list.append(f_server); - } - - return f_server_list; -} - -QString AOApplication::read_design_ini(QString p_identifier, QString p_design_path) -{ - QSettings settings(p_design_path, QSettings::IniFormat); - QVariant value = settings.value(p_identifier); - if (value.type() == QVariant::StringList) { - return value.toStringList().join(","); - } else { - return value.toString(); - } -} - -QPoint AOApplication::get_button_spacing(QString p_identifier, QString p_file) -{ - QString design_ini_path = get_theme_path(p_file); - QString default_path = get_default_theme_path(p_file); - QString f_result = read_design_ini(p_identifier, design_ini_path); - - QPoint return_value; - - return_value.setX(0); - return_value.setY(0); - - if (f_result == "") - { - f_result = read_design_ini(p_identifier, default_path); - - if (f_result == "") - return return_value; - } - - QStringList sub_line_elements = f_result.split(","); - - if (sub_line_elements.size() < 2) - return return_value; - - return_value.setX(sub_line_elements.at(0).toInt()); - return_value.setY(sub_line_elements.at(1).toInt()); - - return return_value; -} - -pos_size_type AOApplication::get_element_dimensions(QString p_identifier, QString p_file) -{ - QString design_ini_path = get_theme_path(p_file); - QString default_path = get_default_theme_path(p_file); - QString f_result = read_design_ini(p_identifier, design_ini_path); - - pos_size_type return_value; - - return_value.x = 0; - return_value.y = 0; - return_value.width = -1; - return_value.height = -1; - - if (f_result == "") - { - f_result = read_design_ini(p_identifier, default_path); - - if (f_result == "") - return return_value; - } - - QStringList sub_line_elements = f_result.split(","); - - if (sub_line_elements.size() < 4) - return return_value; - - return_value.x = sub_line_elements.at(0).toInt(); - return_value.y = sub_line_elements.at(1).toInt(); - return_value.width = sub_line_elements.at(2).toInt(); - return_value.height = sub_line_elements.at(3).toInt(); - - return return_value; -} - -int AOApplication::get_font_size(QString p_identifier, QString p_file) -{ - QString design_ini_path = get_theme_path(p_file); - QString default_path = get_default_theme_path(p_file); - QString f_result = read_design_ini(p_identifier, design_ini_path); - - if (f_result == "") - { - f_result = read_design_ini(p_identifier, default_path); - - if (f_result == "") - return 10; - } - - return f_result.toInt(); -} - -QColor AOApplication::get_color(QString p_identifier, QString p_file) -{ - QString design_ini_path = get_theme_path(p_file); - QString default_path = get_default_theme_path(p_file); - QString f_result = read_design_ini(p_identifier, design_ini_path); - - QColor return_color(0, 0, 0); - - if (f_result == "") - { - f_result = read_design_ini(p_identifier, default_path); - - if (f_result == "") - return return_color; - } - - QStringList color_list = f_result.split(","); - - if (color_list.size() < 3) - return return_color; - - return_color.setRed(color_list.at(0).toInt()); - return_color.setGreen(color_list.at(1).toInt()); - return_color.setBlue(color_list.at(2).toInt()); - - return return_color; -} - -QColor AOApplication::get_chat_color(QString p_identifier, QString p_chat) -{ - QColor return_color(255, 255, 255); - - if (p_identifier == "_inline_grey") - { - return_color = QColor(187, 187, 187); - } - else - { - switch (p_identifier.toInt()) { - case 1: - return_color = QColor(0, 255, 0); - break; - case 2: - return_color = QColor(255, 0, 0); - break; - case 3: - return_color = QColor(255, 165, 0); - break; - case 4: - return_color = QColor(45, 150, 255); - break; - case 5: - return_color = QColor(255, 255, 0); - break; - case 7: - return_color = QColor(255, 192, 203); - break; - case 8: - return_color = QColor(0, 255, 255); - break; - case 0: - case 6: // 6 is rainbow. - default: - return_color = QColor(255, 255, 255); - break; - } - } - - p_identifier = p_identifier.prepend("c"); - QString design_ini_path = get_base_path() + "misc/" + p_chat + "/config.ini"; - QString default_path = get_base_path() + "misc/default/config.ini"; - QString f_result = read_design_ini(p_identifier, design_ini_path); - - if (f_result == "") - { - f_result = read_design_ini(p_identifier, default_path); - - if (f_result == "") - return return_color; - } - - QStringList color_list = f_result.split(","); - - if (color_list.size() < 3) - return return_color; - - return_color.setRed(color_list.at(0).toInt()); - return_color.setGreen(color_list.at(1).toInt()); - return_color.setBlue(color_list.at(2).toInt()); - - return return_color; -} - -QString AOApplication::get_sfx(QString p_identifier) -{ - QString design_ini_path = get_theme_path("courtroom_sounds.ini"); - QString default_path = get_default_theme_path("courtroom_sounds.ini"); - QString f_result = read_design_ini(p_identifier, design_ini_path); - - QString return_sfx = ""; - - if (f_result == "") - { - f_result = read_design_ini(p_identifier, default_path); - - if (f_result == "") - return return_sfx; - } - - return_sfx = f_result; - - return return_sfx; -} - -QString AOApplication::get_sfx_suffix(QString sound_to_check) -{ - QString mp3_check = get_sounds_path(sound_to_check + ".mp3"); - QString opus_check = get_sounds_path(sound_to_check + ".opus"); - if (file_exists(opus_check)) - { - return sound_to_check + ".opus"; - } - else if (file_exists(mp3_check)) - { - return sound_to_check + ".mp3"; - } - return sound_to_check + ".wav"; -} - -QString AOApplication::get_image_suffix(QString path_to_check) -{ - QString apng_check = get_sounds_path(path_to_check + ".apng"); - if (file_exists(apng_check)) - { - return path_to_check + ".apng"; - } - return path_to_check + ".gif"; -} - - -//returns whatever is to the right of "search_line =" within target_tag and terminator_tag, trimmed -//returns the empty string if the search line couldnt be found -QString AOApplication::read_char_ini(QString p_char, QString p_search_line, QString target_tag) -{ - QSettings settings(get_character_path(p_char, "char.ini"), QSettings::IniFormat); - settings.beginGroup(target_tag); - QString value = settings.value(p_search_line).toString(); - settings.endGroup(); - return value; -} - -QString AOApplication::get_char_name(QString p_char) -{ - QString f_result = read_char_ini(p_char, "name", "Options"); - - if (f_result == "") - return p_char; - else return f_result; -} - -QString AOApplication::get_showname(QString p_char) -{ - QString f_result = read_char_ini(p_char, "showname", "Options"); - QString f_needed = read_char_ini(p_char, "needs_showname", "Options"); - - if (f_needed.startsWith("false")) - return ""; - if (f_result == "") - return p_char; - else return f_result; -} - -QString AOApplication::get_char_side(QString p_char) -{ - QString f_result = read_char_ini(p_char, "side", "Options"); - - if (f_result == "") - return "wit"; - else return f_result; -} - -QString AOApplication::get_gender(QString p_char) -{ - QString f_result = read_char_ini(p_char, "gender", "Options"); - - if (f_result == "") - return "male"; - else return f_result; -} - -QString AOApplication::get_chat(QString p_char) -{ - QString f_result = read_char_ini(p_char, "chat", "Options"); - - //handling the correct order of chat is a bit complicated, we let the caller do it - return f_result; -} - -QString AOApplication::get_char_shouts(QString p_char) -{ - QString f_result = read_char_ini(p_char, "shouts", "Options"); - - return f_result; -} - -int AOApplication::get_preanim_duration(QString p_char, QString p_emote) -{ - QString f_result = read_char_ini(p_char, p_emote, "Time"); - - if (f_result == "") - return -1; - else return f_result.toInt(); -} - -int AOApplication::get_ao2_preanim_duration(QString p_char, QString p_emote) -{ - QString f_result = read_char_ini(p_char, "%" + p_emote, "Time"); - - if (f_result == "") - return -1; - else return f_result.toInt(); -} - -int AOApplication::get_emote_number(QString p_char) -{ - QString f_result = read_char_ini(p_char, "number", "Emotions"); - - if (f_result == "") - return 0; - else return f_result.toInt(); -} - -QString AOApplication::get_emote_comment(QString p_char, int p_emote) -{ - QString f_result = read_char_ini(p_char, QString::number(p_emote + 1), "Emotions"); - - QStringList result_contents = f_result.split("#"); - - if (result_contents.size() < 4) - { - qDebug() << "W: misformatted char.ini: " << p_char << ", " << p_emote; - return "normal"; - } - else return result_contents.at(0); -} - -QString AOApplication::get_pre_emote(QString p_char, int p_emote) -{ - QString f_result = read_char_ini(p_char, QString::number(p_emote + 1), "Emotions"); - - QStringList result_contents = f_result.split("#"); - - if (result_contents.size() < 4) - { - qDebug() << "W: misformatted char.ini: " << p_char << ", " << p_emote; - return ""; - } - else return result_contents.at(1); -} - -QString AOApplication::get_emote(QString p_char, int p_emote) -{ - QString f_result = read_char_ini(p_char, QString::number(p_emote + 1), "Emotions"); - - QStringList result_contents = f_result.split("#"); - - if (result_contents.size() < 4) - { - qDebug() << "W: misformatted char.ini: " << p_char << ", " << p_emote; - return "normal"; - } - else return result_contents.at(2); -} - -int AOApplication::get_emote_mod(QString p_char, int p_emote) -{ - QString f_result = read_char_ini(p_char, QString::number(p_emote + 1), "Emotions"); - - QStringList result_contents = f_result.split("#"); - - if (result_contents.size() < 4) - { - qDebug() << "W: misformatted char.ini: " << p_char << ", " << QString::number(p_emote); - return 0; - } - else return result_contents.at(3).toInt(); -} - -int AOApplication::get_desk_mod(QString p_char, int p_emote) -{ - QString f_result = read_char_ini(p_char, QString::number(p_emote + 1), "Emotions"); - - QStringList result_contents = f_result.split("#"); - - if (result_contents.size() < 5) - return -1; - - QString string_result = result_contents.at(4); - if (string_result == "") - return -1; - - else return string_result.toInt(); -} - -QString AOApplication::get_sfx_name(QString p_char, int p_emote) -{ - QString f_result = read_char_ini(p_char, QString::number(p_emote + 1), "SoundN"); - - if (f_result == "") - return "1"; - else return f_result; -} - -int AOApplication::get_sfx_delay(QString p_char, int p_emote) -{ - QString f_result = read_char_ini(p_char, QString::number(p_emote + 1), "SoundT"); - - if (f_result == "") - return 1; - else return f_result.toInt(); -} - -int AOApplication::get_text_delay(QString p_char, QString p_emote) -{ - QString f_result = read_char_ini(p_char, p_emote, "TextDelay"); - - if (f_result == "") - return -1; - else return f_result.toInt(); -} - -QString AOApplication::get_custom_realization(QString p_char) -{ - QString f_result = read_char_ini(p_char, "realization", "Options"); - - if (f_result == "") - return get_sfx("realization"); - else return f_result; -} - -bool AOApplication::get_blank_blip() -{ - QString result = configini->value("blank_blip", "false").value(); - return result.startsWith("true"); -} - -bool AOApplication::is_discord_enabled() -{ - QString result = configini->value("discord", "true").value(); - return result.startsWith("true"); -} - -bool AOApplication::get_casing_enabled() -{ - QString result = configini->value("casing_enabled", "false").value(); - return result.startsWith("true"); -} - -bool AOApplication::get_casing_defence_enabled() -{ - QString result = configini->value("casing_defence_enabled", "false").value(); - return result.startsWith("true"); -} - -bool AOApplication::get_casing_prosecution_enabled() -{ - QString result = configini->value("casing_prosecution_enabled", "false").value(); - return result.startsWith("true"); -} - -bool AOApplication::get_casing_judge_enabled() -{ - QString result = configini->value("casing_judge_enabled", "false").value(); - return result.startsWith("true"); -} - -bool AOApplication::get_casing_juror_enabled() -{ - QString result = configini->value("casing_juror_enabled", "false").value(); - return result.startsWith("true"); -} - -bool AOApplication::get_casing_steno_enabled() -{ - QString result = configini->value("casing_steno_enabled", "false").value(); - return result.startsWith("true"); -} - -bool AOApplication::get_casing_cm_enabled() -{ - QString result = configini->value("casing_cm_enabled", "false").value(); - return result.startsWith("true"); -} - -QString AOApplication::get_casing_can_host_cases() -{ - QString result = configini->value("casing_can_host_cases", "Turnabout Check Your Settings").value(); - return result; -} diff --git a/text_file_functions.h b/text_file_functions.h deleted file mode 100644 index 119f38e2..00000000 --- a/text_file_functions.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef TEXT_FILE_FUNCTIONS_H -#define TEXT_FILE_FUNCTIONS_H - -#include "aoapplication.h" -#include "file_functions.h" -#include -#include -#include -#include -#include -#include - -#endif // TEXT_FILE_FUNCTIONS_H -- cgit From 706f5bb7c702724bd679bf116a0efe781cd1aa52 Mon Sep 17 00:00:00 2001 From: David Skoland Date: Wed, 26 Dec 2018 16:48:30 +0100 Subject: simplified the project file --- .gitignore | 1 + Attorney_Online_remake.pro | 94 +++++++--------------------------------------- 2 files changed, 15 insertions(+), 80 deletions(-) diff --git a/.gitignore b/.gitignore index 9d5dcdb9..f525d7d7 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,7 @@ bass.lib bins/ release/ debug/ +lib/ .qmake.stash diff --git a/Attorney_Online_remake.pro b/Attorney_Online_remake.pro index 2e8a5f82..4d7f3f12 100644 --- a/Attorney_Online_remake.pro +++ b/Attorney_Online_remake.pro @@ -14,77 +14,21 @@ TEMPLATE = app VERSION = 2.6.0.0 -SOURCES += main.cpp\ - lobby.cpp \ - text_file_functions.cpp \ - path_functions.cpp \ - aoimage.cpp \ - file_functions.cpp \ - aobutton.cpp \ - debug_functions.cpp \ - networkmanager.cpp \ - aoapplication.cpp \ - aopacket.cpp \ - packet_distribution.cpp \ - hex_functions.cpp \ - encryption_functions.cpp \ - courtroom.cpp \ - aocharbutton.cpp \ - hardware_functions.cpp \ - aoscene.cpp \ - aomovie.cpp \ - misc_functions.cpp \ - aocharmovie.cpp \ - aoemotebutton.cpp \ - emotes.cpp \ - aosfxplayer.cpp \ - aomusicplayer.cpp \ - aoblipplayer.cpp \ - evidence.cpp \ - aoevidencebutton.cpp \ - charselect.cpp \ - aotextarea.cpp \ - aolineedit.cpp \ - aotextedit.cpp \ - aoevidencedisplay.cpp \ - discord_rich_presence.cpp \ - aooptionsdialog.cpp \ - chatlogpiece.cpp \ - aocaseannouncerdialog.cpp +INCLUDEPATH += $$PWD/include +DESTDIR = $$PWD/bin +OBJECTS_DIR = $$PWD/build +MOC_DIR = $$PWD/build + +SOURCES += $$files($$PWD/src/*.cpp) +HEADERS += $$files($$PWD/include/*.h) +LIBS += -L$$PWD/lib + +unix:LIBS += -lbass -ldiscord-rpc +win32:LIBS += "bass.dll" -ldiscord-rpc + +CONFIG += c++11 -HEADERS += lobby.h \ - aoimage.h \ - file_functions.h \ - aobutton.h \ - debug_functions.h \ - networkmanager.h \ - aoapplication.h \ - datatypes.h \ - aopacket.h \ - hex_functions.h \ - encryption_functions.h \ - courtroom.h \ - aocharbutton.h \ - hardware_functions.h \ - aoscene.h \ - aomovie.h \ - misc_functions.h \ - aocharmovie.h \ - aoemotebutton.h \ - aosfxplayer.h \ - aomusicplayer.h \ - aoblipplayer.h \ - aoevidencebutton.h \ - aotextarea.h \ - aolineedit.h \ - aotextedit.h \ - aoevidencedisplay.h \ - discord_rich_presence.h \ - discord-rpc.h \ - aooptionsdialog.h \ - text_file_functions.h \ - chatlogpiece.h \ - aocaseannouncerdialog.h +RESOURCES += resources.qrc # 1. You need to get BASS and put the x86 bass DLL/headers in the project root folder # AND the compilation output folder. If you are compiling statically, you'll probably @@ -104,13 +48,3 @@ HEADERS += lobby.h \ # Naturally, the build process becomes significantly less convoluted if you simply # compile dynamically. If your primary distribution method is via the launcher, then # a simple dynamic compilation is recommended. -unix:LIBS += -L$$PWD -lbass -ldiscord-rpc -win32:LIBS += -L$$PWD "$$PWD/bass.dll" -ldiscord-rpc -INCLUDEPATH += $$PWD/include - -CONFIG += c++11 - -RESOURCES += \ - resources.qrc - -DISTFILES += -- cgit From 0c44a1c854ea13e0c7fba6e17d8ed2cdfc08e5cd Mon Sep 17 00:00:00 2001 From: David Skoland Date: Wed, 26 Dec 2018 16:51:11 +0100 Subject: including the bass header file is fine honestly --- include/bass.h | 1139 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1139 insertions(+) create mode 100644 include/bass.h diff --git a/include/bass.h b/include/bass.h new file mode 100644 index 00000000..1c50903c --- /dev/null +++ b/include/bass.h @@ -0,0 +1,1139 @@ +/* + BASS 2.4 C/C++ header file + Copyright (c) 1999-2018 Un4seen Developments Ltd. + + See the BASS.CHM file for more detailed documentation +*/ + +#ifndef BASS_H +#define BASS_H + +#ifdef _WIN32 +#include +typedef unsigned __int64 QWORD; +#else +#include +#define WINAPI +#define CALLBACK +typedef uint8_t BYTE; +typedef uint16_t WORD; +typedef uint32_t DWORD; +typedef uint64_t QWORD; +#ifndef __OBJC__ +typedef int BOOL; +#endif +#ifndef TRUE +#define TRUE 1 +#define FALSE 0 +#endif +#define LOBYTE(a) (BYTE)(a) +#define HIBYTE(a) (BYTE)((a)>>8) +#define LOWORD(a) (WORD)(a) +#define HIWORD(a) (WORD)((a)>>16) +#define MAKEWORD(a,b) (WORD)(((a)&0xff)|((b)<<8)) +#define MAKELONG(a,b) (DWORD)(((a)&0xffff)|((b)<<16)) +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#define BASSVERSION 0x204 // API version +#define BASSVERSIONTEXT "2.4" + +#ifndef BASSDEF +#define BASSDEF(f) WINAPI f +#else +#define NOBASSOVERLOADS +#endif + +typedef DWORD HMUSIC; // MOD music handle +typedef DWORD HSAMPLE; // sample handle +typedef DWORD HCHANNEL; // playing sample's channel handle +typedef DWORD HSTREAM; // sample stream handle +typedef DWORD HRECORD; // recording handle +typedef DWORD HSYNC; // synchronizer handle +typedef DWORD HDSP; // DSP handle +typedef DWORD HFX; // DX8 effect handle +typedef DWORD HPLUGIN; // Plugin handle + +// Error codes returned by BASS_ErrorGetCode +#define BASS_OK 0 // all is OK +#define BASS_ERROR_MEM 1 // memory error +#define BASS_ERROR_FILEOPEN 2 // can't open the file +#define BASS_ERROR_DRIVER 3 // can't find a free/valid driver +#define BASS_ERROR_BUFLOST 4 // the sample buffer was lost +#define BASS_ERROR_HANDLE 5 // invalid handle +#define BASS_ERROR_FORMAT 6 // unsupported sample format +#define BASS_ERROR_POSITION 7 // invalid position +#define BASS_ERROR_INIT 8 // BASS_Init has not been successfully called +#define BASS_ERROR_START 9 // BASS_Start has not been successfully called +#define BASS_ERROR_SSL 10 // SSL/HTTPS support isn't available +#define BASS_ERROR_ALREADY 14 // already initialized/paused/whatever +#define BASS_ERROR_NOCHAN 18 // can't get a free channel +#define BASS_ERROR_ILLTYPE 19 // an illegal type was specified +#define BASS_ERROR_ILLPARAM 20 // an illegal parameter was specified +#define BASS_ERROR_NO3D 21 // no 3D support +#define BASS_ERROR_NOEAX 22 // no EAX support +#define BASS_ERROR_DEVICE 23 // illegal device number +#define BASS_ERROR_NOPLAY 24 // not playing +#define BASS_ERROR_FREQ 25 // illegal sample rate +#define BASS_ERROR_NOTFILE 27 // the stream is not a file stream +#define BASS_ERROR_NOHW 29 // no hardware voices available +#define BASS_ERROR_EMPTY 31 // the MOD music has no sequence data +#define BASS_ERROR_NONET 32 // no internet connection could be opened +#define BASS_ERROR_CREATE 33 // couldn't create the file +#define BASS_ERROR_NOFX 34 // effects are not available +#define BASS_ERROR_NOTAVAIL 37 // requested data/action is not available +#define BASS_ERROR_DECODE 38 // the channel is/isn't a "decoding channel" +#define BASS_ERROR_DX 39 // a sufficient DirectX version is not installed +#define BASS_ERROR_TIMEOUT 40 // connection timedout +#define BASS_ERROR_FILEFORM 41 // unsupported file format +#define BASS_ERROR_SPEAKER 42 // unavailable speaker +#define BASS_ERROR_VERSION 43 // invalid BASS version (used by add-ons) +#define BASS_ERROR_CODEC 44 // codec is not available/supported +#define BASS_ERROR_ENDED 45 // the channel/file has ended +#define BASS_ERROR_BUSY 46 // the device is busy +#define BASS_ERROR_UNKNOWN -1 // some other mystery problem + +// BASS_SetConfig options +#define BASS_CONFIG_BUFFER 0 +#define BASS_CONFIG_UPDATEPERIOD 1 +#define BASS_CONFIG_GVOL_SAMPLE 4 +#define BASS_CONFIG_GVOL_STREAM 5 +#define BASS_CONFIG_GVOL_MUSIC 6 +#define BASS_CONFIG_CURVE_VOL 7 +#define BASS_CONFIG_CURVE_PAN 8 +#define BASS_CONFIG_FLOATDSP 9 +#define BASS_CONFIG_3DALGORITHM 10 +#define BASS_CONFIG_NET_TIMEOUT 11 +#define BASS_CONFIG_NET_BUFFER 12 +#define BASS_CONFIG_PAUSE_NOPLAY 13 +#define BASS_CONFIG_NET_PREBUF 15 +#define BASS_CONFIG_NET_PASSIVE 18 +#define BASS_CONFIG_REC_BUFFER 19 +#define BASS_CONFIG_NET_PLAYLIST 21 +#define BASS_CONFIG_MUSIC_VIRTUAL 22 +#define BASS_CONFIG_VERIFY 23 +#define BASS_CONFIG_UPDATETHREADS 24 +#define BASS_CONFIG_DEV_BUFFER 27 +#define BASS_CONFIG_VISTA_TRUEPOS 30 +#define BASS_CONFIG_IOS_MIXAUDIO 34 +#define BASS_CONFIG_DEV_DEFAULT 36 +#define BASS_CONFIG_NET_READTIMEOUT 37 +#define BASS_CONFIG_VISTA_SPEAKERS 38 +#define BASS_CONFIG_IOS_SPEAKER 39 +#define BASS_CONFIG_MF_DISABLE 40 +#define BASS_CONFIG_HANDLES 41 +#define BASS_CONFIG_UNICODE 42 +#define BASS_CONFIG_SRC 43 +#define BASS_CONFIG_SRC_SAMPLE 44 +#define BASS_CONFIG_ASYNCFILE_BUFFER 45 +#define BASS_CONFIG_OGG_PRESCAN 47 +#define BASS_CONFIG_MF_VIDEO 48 +#define BASS_CONFIG_AIRPLAY 49 +#define BASS_CONFIG_DEV_NONSTOP 50 +#define BASS_CONFIG_IOS_NOCATEGORY 51 +#define BASS_CONFIG_VERIFY_NET 52 +#define BASS_CONFIG_DEV_PERIOD 53 +#define BASS_CONFIG_FLOAT 54 +#define BASS_CONFIG_NET_SEEK 56 +#define BASS_CONFIG_AM_DISABLE 58 +#define BASS_CONFIG_NET_PLAYLIST_DEPTH 59 +#define BASS_CONFIG_NET_PREBUF_WAIT 60 + +// BASS_SetConfigPtr options +#define BASS_CONFIG_NET_AGENT 16 +#define BASS_CONFIG_NET_PROXY 17 +#define BASS_CONFIG_IOS_NOTIFY 46 + +// BASS_Init flags +#define BASS_DEVICE_8BITS 1 // 8 bit +#define BASS_DEVICE_MONO 2 // mono +#define BASS_DEVICE_3D 4 // enable 3D functionality +#define BASS_DEVICE_16BITS 8 // limit output to 16 bit +#define BASS_DEVICE_LATENCY 0x100 // calculate device latency (BASS_INFO struct) +#define BASS_DEVICE_CPSPEAKERS 0x400 // detect speakers via Windows control panel +#define BASS_DEVICE_SPEAKERS 0x800 // force enabling of speaker assignment +#define BASS_DEVICE_NOSPEAKER 0x1000 // ignore speaker arrangement +#define BASS_DEVICE_DMIX 0x2000 // use ALSA "dmix" plugin +#define BASS_DEVICE_FREQ 0x4000 // set device sample rate +#define BASS_DEVICE_STEREO 0x8000 // limit output to stereo +#define BASS_DEVICE_HOG 0x10000 // hog/exclusive mode +#define BASS_DEVICE_AUDIOTRACK 0x20000 // use AudioTrack output +#define BASS_DEVICE_DSOUND 0x40000 // use DirectSound output + +// DirectSound interfaces (for use with BASS_GetDSoundObject) +#define BASS_OBJECT_DS 1 // IDirectSound +#define BASS_OBJECT_DS3DL 2 // IDirectSound3DListener + +// Device info structure +typedef struct { +#if defined(_WIN32_WCE) || (WINAPI_FAMILY && WINAPI_FAMILY!=WINAPI_FAMILY_DESKTOP_APP) + const wchar_t *name; // description + const wchar_t *driver; // driver +#else + const char *name; // description + const char *driver; // driver +#endif + DWORD flags; +} BASS_DEVICEINFO; + +// BASS_DEVICEINFO flags +#define BASS_DEVICE_ENABLED 1 +#define BASS_DEVICE_DEFAULT 2 +#define BASS_DEVICE_INIT 4 +#define BASS_DEVICE_LOOPBACK 8 + +#define BASS_DEVICE_TYPE_MASK 0xff000000 +#define BASS_DEVICE_TYPE_NETWORK 0x01000000 +#define BASS_DEVICE_TYPE_SPEAKERS 0x02000000 +#define BASS_DEVICE_TYPE_LINE 0x03000000 +#define BASS_DEVICE_TYPE_HEADPHONES 0x04000000 +#define BASS_DEVICE_TYPE_MICROPHONE 0x05000000 +#define BASS_DEVICE_TYPE_HEADSET 0x06000000 +#define BASS_DEVICE_TYPE_HANDSET 0x07000000 +#define BASS_DEVICE_TYPE_DIGITAL 0x08000000 +#define BASS_DEVICE_TYPE_SPDIF 0x09000000 +#define BASS_DEVICE_TYPE_HDMI 0x0a000000 +#define BASS_DEVICE_TYPE_DISPLAYPORT 0x40000000 + +// BASS_GetDeviceInfo flags +#define BASS_DEVICES_AIRPLAY 0x1000000 + +typedef struct { + DWORD flags; // device capabilities (DSCAPS_xxx flags) + DWORD hwsize; // size of total device hardware memory + DWORD hwfree; // size of free device hardware memory + DWORD freesam; // number of free sample slots in the hardware + DWORD free3d; // number of free 3D sample slots in the hardware + DWORD minrate; // min sample rate supported by the hardware + DWORD maxrate; // max sample rate supported by the hardware + BOOL eax; // device supports EAX? (always FALSE if BASS_DEVICE_3D was not used) + DWORD minbuf; // recommended minimum buffer length in ms (requires BASS_DEVICE_LATENCY) + DWORD dsver; // DirectSound version + DWORD latency; // delay (in ms) before start of playback (requires BASS_DEVICE_LATENCY) + DWORD initflags; // BASS_Init "flags" parameter + DWORD speakers; // number of speakers available + DWORD freq; // current output rate +} BASS_INFO; + +// BASS_INFO flags (from DSOUND.H) +#define DSCAPS_CONTINUOUSRATE 0x00000010 // supports all sample rates between min/maxrate +#define DSCAPS_EMULDRIVER 0x00000020 // device does NOT have hardware DirectSound support +#define DSCAPS_CERTIFIED 0x00000040 // device driver has been certified by Microsoft +#define DSCAPS_SECONDARYMONO 0x00000100 // mono +#define DSCAPS_SECONDARYSTEREO 0x00000200 // stereo +#define DSCAPS_SECONDARY8BIT 0x00000400 // 8 bit +#define DSCAPS_SECONDARY16BIT 0x00000800 // 16 bit + +// Recording device info structure +typedef struct { + DWORD flags; // device capabilities (DSCCAPS_xxx flags) + DWORD formats; // supported standard formats (WAVE_FORMAT_xxx flags) + DWORD inputs; // number of inputs + BOOL singlein; // TRUE = only 1 input can be set at a time + DWORD freq; // current input rate +} BASS_RECORDINFO; + +// BASS_RECORDINFO flags (from DSOUND.H) +#define DSCCAPS_EMULDRIVER DSCAPS_EMULDRIVER // device does NOT have hardware DirectSound recording support +#define DSCCAPS_CERTIFIED DSCAPS_CERTIFIED // device driver has been certified by Microsoft + +// defines for formats field of BASS_RECORDINFO (from MMSYSTEM.H) +#ifndef WAVE_FORMAT_1M08 +#define WAVE_FORMAT_1M08 0x00000001 /* 11.025 kHz, Mono, 8-bit */ +#define WAVE_FORMAT_1S08 0x00000002 /* 11.025 kHz, Stereo, 8-bit */ +#define WAVE_FORMAT_1M16 0x00000004 /* 11.025 kHz, Mono, 16-bit */ +#define WAVE_FORMAT_1S16 0x00000008 /* 11.025 kHz, Stereo, 16-bit */ +#define WAVE_FORMAT_2M08 0x00000010 /* 22.05 kHz, Mono, 8-bit */ +#define WAVE_FORMAT_2S08 0x00000020 /* 22.05 kHz, Stereo, 8-bit */ +#define WAVE_FORMAT_2M16 0x00000040 /* 22.05 kHz, Mono, 16-bit */ +#define WAVE_FORMAT_2S16 0x00000080 /* 22.05 kHz, Stereo, 16-bit */ +#define WAVE_FORMAT_4M08 0x00000100 /* 44.1 kHz, Mono, 8-bit */ +#define WAVE_FORMAT_4S08 0x00000200 /* 44.1 kHz, Stereo, 8-bit */ +#define WAVE_FORMAT_4M16 0x00000400 /* 44.1 kHz, Mono, 16-bit */ +#define WAVE_FORMAT_4S16 0x00000800 /* 44.1 kHz, Stereo, 16-bit */ +#endif + +// Sample info structure +typedef struct { + DWORD freq; // default playback rate + float volume; // default volume (0-1) + float pan; // default pan (-1=left, 0=middle, 1=right) + DWORD flags; // BASS_SAMPLE_xxx flags + DWORD length; // length (in bytes) + DWORD max; // maximum simultaneous playbacks + DWORD origres; // original resolution + DWORD chans; // number of channels + DWORD mingap; // minimum gap (ms) between creating channels + DWORD mode3d; // BASS_3DMODE_xxx mode + float mindist; // minimum distance + float maxdist; // maximum distance + DWORD iangle; // angle of inside projection cone + DWORD oangle; // angle of outside projection cone + float outvol; // delta-volume outside the projection cone + DWORD vam; // voice allocation/management flags (BASS_VAM_xxx) + DWORD priority; // priority (0=lowest, 0xffffffff=highest) +} BASS_SAMPLE; + +#define BASS_SAMPLE_8BITS 1 // 8 bit +#define BASS_SAMPLE_FLOAT 256 // 32 bit floating-point +#define BASS_SAMPLE_MONO 2 // mono +#define BASS_SAMPLE_LOOP 4 // looped +#define BASS_SAMPLE_3D 8 // 3D functionality +#define BASS_SAMPLE_SOFTWARE 16 // not using hardware mixing +#define BASS_SAMPLE_MUTEMAX 32 // mute at max distance (3D only) +#define BASS_SAMPLE_VAM 64 // DX7 voice allocation & management +#define BASS_SAMPLE_FX 128 // old implementation of DX8 effects +#define BASS_SAMPLE_OVER_VOL 0x10000 // override lowest volume +#define BASS_SAMPLE_OVER_POS 0x20000 // override longest playing +#define BASS_SAMPLE_OVER_DIST 0x30000 // override furthest from listener (3D only) + +#define BASS_STREAM_PRESCAN 0x20000 // enable pin-point seeking/length (MP3/MP2/MP1) +#define BASS_STREAM_AUTOFREE 0x40000 // automatically free the stream when it stop/ends +#define BASS_STREAM_RESTRATE 0x80000 // restrict the download rate of internet file streams +#define BASS_STREAM_BLOCK 0x100000 // download/play internet file stream in small blocks +#define BASS_STREAM_DECODE 0x200000 // don't play the stream, only decode (BASS_ChannelGetData) +#define BASS_STREAM_STATUS 0x800000 // give server status info (HTTP/ICY tags) in DOWNLOADPROC + +#define BASS_MP3_IGNOREDELAY 0x200 // ignore LAME/Xing/VBRI/iTunes delay & padding info +#define BASS_MP3_SETPOS BASS_STREAM_PRESCAN + +#define BASS_MUSIC_FLOAT BASS_SAMPLE_FLOAT +#define BASS_MUSIC_MONO BASS_SAMPLE_MONO +#define BASS_MUSIC_LOOP BASS_SAMPLE_LOOP +#define BASS_MUSIC_3D BASS_SAMPLE_3D +#define BASS_MUSIC_FX BASS_SAMPLE_FX +#define BASS_MUSIC_AUTOFREE BASS_STREAM_AUTOFREE +#define BASS_MUSIC_DECODE BASS_STREAM_DECODE +#define BASS_MUSIC_PRESCAN BASS_STREAM_PRESCAN // calculate playback length +#define BASS_MUSIC_CALCLEN BASS_MUSIC_PRESCAN +#define BASS_MUSIC_RAMP 0x200 // normal ramping +#define BASS_MUSIC_RAMPS 0x400 // sensitive ramping +#define BASS_MUSIC_SURROUND 0x800 // surround sound +#define BASS_MUSIC_SURROUND2 0x1000 // surround sound (mode 2) +#define BASS_MUSIC_FT2PAN 0x2000 // apply FastTracker 2 panning to XM files +#define BASS_MUSIC_FT2MOD 0x2000 // play .MOD as FastTracker 2 does +#define BASS_MUSIC_PT1MOD 0x4000 // play .MOD as ProTracker 1 does +#define BASS_MUSIC_NONINTER 0x10000 // non-interpolated sample mixing +#define BASS_MUSIC_SINCINTER 0x800000 // sinc interpolated sample mixing +#define BASS_MUSIC_POSRESET 0x8000 // stop all notes when moving position +#define BASS_MUSIC_POSRESETEX 0x400000 // stop all notes and reset bmp/etc when moving position +#define BASS_MUSIC_STOPBACK 0x80000 // stop the music on a backwards jump effect +#define BASS_MUSIC_NOSAMPLE 0x100000 // don't load the samples + +// Speaker assignment flags +#define BASS_SPEAKER_FRONT 0x1000000 // front speakers +#define BASS_SPEAKER_REAR 0x2000000 // rear/side speakers +#define BASS_SPEAKER_CENLFE 0x3000000 // center & LFE speakers (5.1) +#define BASS_SPEAKER_REAR2 0x4000000 // rear center speakers (7.1) +#define BASS_SPEAKER_N(n) ((n)<<24) // n'th pair of speakers (max 15) +#define BASS_SPEAKER_LEFT 0x10000000 // modifier: left +#define BASS_SPEAKER_RIGHT 0x20000000 // modifier: right +#define BASS_SPEAKER_FRONTLEFT BASS_SPEAKER_FRONT|BASS_SPEAKER_LEFT +#define BASS_SPEAKER_FRONTRIGHT BASS_SPEAKER_FRONT|BASS_SPEAKER_RIGHT +#define BASS_SPEAKER_REARLEFT BASS_SPEAKER_REAR|BASS_SPEAKER_LEFT +#define BASS_SPEAKER_REARRIGHT BASS_SPEAKER_REAR|BASS_SPEAKER_RIGHT +#define BASS_SPEAKER_CENTER BASS_SPEAKER_CENLFE|BASS_SPEAKER_LEFT +#define BASS_SPEAKER_LFE BASS_SPEAKER_CENLFE|BASS_SPEAKER_RIGHT +#define BASS_SPEAKER_REAR2LEFT BASS_SPEAKER_REAR2|BASS_SPEAKER_LEFT +#define BASS_SPEAKER_REAR2RIGHT BASS_SPEAKER_REAR2|BASS_SPEAKER_RIGHT + +#define BASS_ASYNCFILE 0x40000000 +#define BASS_UNICODE 0x80000000 + +#define BASS_RECORD_PAUSE 0x8000 // start recording paused +#define BASS_RECORD_ECHOCANCEL 0x2000 +#define BASS_RECORD_AGC 0x4000 + +// DX7 voice allocation & management flags +#define BASS_VAM_HARDWARE 1 +#define BASS_VAM_SOFTWARE 2 +#define BASS_VAM_TERM_TIME 4 +#define BASS_VAM_TERM_DIST 8 +#define BASS_VAM_TERM_PRIO 16 + +// Channel info structure +typedef struct { + DWORD freq; // default playback rate + DWORD chans; // channels + DWORD flags; // BASS_SAMPLE/STREAM/MUSIC/SPEAKER flags + DWORD ctype; // type of channel + DWORD origres; // original resolution + HPLUGIN plugin; // plugin + HSAMPLE sample; // sample + const char *filename; // filename +} BASS_CHANNELINFO; + +#define BASS_ORIGRES_FLOAT 0x10000 + +// BASS_CHANNELINFO types +#define BASS_CTYPE_SAMPLE 1 +#define BASS_CTYPE_RECORD 2 +#define BASS_CTYPE_STREAM 0x10000 +#define BASS_CTYPE_STREAM_OGG 0x10002 +#define BASS_CTYPE_STREAM_MP1 0x10003 +#define BASS_CTYPE_STREAM_MP2 0x10004 +#define BASS_CTYPE_STREAM_MP3 0x10005 +#define BASS_CTYPE_STREAM_AIFF 0x10006 +#define BASS_CTYPE_STREAM_CA 0x10007 +#define BASS_CTYPE_STREAM_MF 0x10008 +#define BASS_CTYPE_STREAM_AM 0x10009 +#define BASS_CTYPE_STREAM_DUMMY 0x18000 +#define BASS_CTYPE_STREAM_DEVICE 0x18001 +#define BASS_CTYPE_STREAM_WAV 0x40000 // WAVE flag, LOWORD=codec +#define BASS_CTYPE_STREAM_WAV_PCM 0x50001 +#define BASS_CTYPE_STREAM_WAV_FLOAT 0x50003 +#define BASS_CTYPE_MUSIC_MOD 0x20000 +#define BASS_CTYPE_MUSIC_MTM 0x20001 +#define BASS_CTYPE_MUSIC_S3M 0x20002 +#define BASS_CTYPE_MUSIC_XM 0x20003 +#define BASS_CTYPE_MUSIC_IT 0x20004 +#define BASS_CTYPE_MUSIC_MO3 0x00100 // MO3 flag + +typedef struct { + DWORD ctype; // channel type +#if defined(_WIN32_WCE) || (WINAPI_FAMILY && WINAPI_FAMILY!=WINAPI_FAMILY_DESKTOP_APP) + const wchar_t *name; // format description + const wchar_t *exts; // file extension filter (*.ext1;*.ext2;etc...) +#else + const char *name; // format description + const char *exts; // file extension filter (*.ext1;*.ext2;etc...) +#endif +} BASS_PLUGINFORM; + +typedef struct { + DWORD version; // version (same form as BASS_GetVersion) + DWORD formatc; // number of formats + const BASS_PLUGINFORM *formats; // the array of formats +} BASS_PLUGININFO; + +// 3D vector (for 3D positions/velocities/orientations) +typedef struct BASS_3DVECTOR { +#ifdef __cplusplus + BASS_3DVECTOR() {}; + BASS_3DVECTOR(float _x, float _y, float _z) : x(_x), y(_y), z(_z) {}; +#endif + float x; // +=right, -=left + float y; // +=up, -=down + float z; // +=front, -=behind +} BASS_3DVECTOR; + +// 3D channel modes +#define BASS_3DMODE_NORMAL 0 // normal 3D processing +#define BASS_3DMODE_RELATIVE 1 // position is relative to the listener +#define BASS_3DMODE_OFF 2 // no 3D processing + +// software 3D mixing algorithms (used with BASS_CONFIG_3DALGORITHM) +#define BASS_3DALG_DEFAULT 0 +#define BASS_3DALG_OFF 1 +#define BASS_3DALG_FULL 2 +#define BASS_3DALG_LIGHT 3 + +// EAX environments, use with BASS_SetEAXParameters +enum +{ + EAX_ENVIRONMENT_GENERIC, + EAX_ENVIRONMENT_PADDEDCELL, + EAX_ENVIRONMENT_ROOM, + EAX_ENVIRONMENT_BATHROOM, + EAX_ENVIRONMENT_LIVINGROOM, + EAX_ENVIRONMENT_STONEROOM, + EAX_ENVIRONMENT_AUDITORIUM, + EAX_ENVIRONMENT_CONCERTHALL, + EAX_ENVIRONMENT_CAVE, + EAX_ENVIRONMENT_ARENA, + EAX_ENVIRONMENT_HANGAR, + EAX_ENVIRONMENT_CARPETEDHALLWAY, + EAX_ENVIRONMENT_HALLWAY, + EAX_ENVIRONMENT_STONECORRIDOR, + EAX_ENVIRONMENT_ALLEY, + EAX_ENVIRONMENT_FOREST, + EAX_ENVIRONMENT_CITY, + EAX_ENVIRONMENT_MOUNTAINS, + EAX_ENVIRONMENT_QUARRY, + EAX_ENVIRONMENT_PLAIN, + EAX_ENVIRONMENT_PARKINGLOT, + EAX_ENVIRONMENT_SEWERPIPE, + EAX_ENVIRONMENT_UNDERWATER, + EAX_ENVIRONMENT_DRUGGED, + EAX_ENVIRONMENT_DIZZY, + EAX_ENVIRONMENT_PSYCHOTIC, + + EAX_ENVIRONMENT_COUNT // total number of environments +}; + +// EAX presets, usage: BASS_SetEAXParameters(EAX_PRESET_xxx) +#define EAX_PRESET_GENERIC EAX_ENVIRONMENT_GENERIC,0.5F,1.493F,0.5F +#define EAX_PRESET_PADDEDCELL EAX_ENVIRONMENT_PADDEDCELL,0.25F,0.1F,0.0F +#define EAX_PRESET_ROOM EAX_ENVIRONMENT_ROOM,0.417F,0.4F,0.666F +#define EAX_PRESET_BATHROOM EAX_ENVIRONMENT_BATHROOM,0.653F,1.499F,0.166F +#define EAX_PRESET_LIVINGROOM EAX_ENVIRONMENT_LIVINGROOM,0.208F,0.478F,0.0F +#define EAX_PRESET_STONEROOM EAX_ENVIRONMENT_STONEROOM,0.5F,2.309F,0.888F +#define EAX_PRESET_AUDITORIUM EAX_ENVIRONMENT_AUDITORIUM,0.403F,4.279F,0.5F +#define EAX_PRESET_CONCERTHALL EAX_ENVIRONMENT_CONCERTHALL,0.5F,3.961F,0.5F +#define EAX_PRESET_CAVE EAX_ENVIRONMENT_CAVE,0.5F,2.886F,1.304F +#define EAX_PRESET_ARENA EAX_ENVIRONMENT_ARENA,0.361F,7.284F,0.332F +#define EAX_PRESET_HANGAR EAX_ENVIRONMENT_HANGAR,0.5F,10.0F,0.3F +#define EAX_PRESET_CARPETEDHALLWAY EAX_ENVIRONMENT_CARPETEDHALLWAY,0.153F,0.259F,2.0F +#define EAX_PRESET_HALLWAY EAX_ENVIRONMENT_HALLWAY,0.361F,1.493F,0.0F +#define EAX_PRESET_STONECORRIDOR EAX_ENVIRONMENT_STONECORRIDOR,0.444F,2.697F,0.638F +#define EAX_PRESET_ALLEY EAX_ENVIRONMENT_ALLEY,0.25F,1.752F,0.776F +#define EAX_PRESET_FOREST EAX_ENVIRONMENT_FOREST,0.111F,3.145F,0.472F +#define EAX_PRESET_CITY EAX_ENVIRONMENT_CITY,0.111F,2.767F,0.224F +#define EAX_PRESET_MOUNTAINS EAX_ENVIRONMENT_MOUNTAINS,0.194F,7.841F,0.472F +#define EAX_PRESET_QUARRY EAX_ENVIRONMENT_QUARRY,1.0F,1.499F,0.5F +#define EAX_PRESET_PLAIN EAX_ENVIRONMENT_PLAIN,0.097F,2.767F,0.224F +#define EAX_PRESET_PARKINGLOT EAX_ENVIRONMENT_PARKINGLOT,0.208F,1.652F,1.5F +#define EAX_PRESET_SEWERPIPE EAX_ENVIRONMENT_SEWERPIPE,0.652F,2.886F,0.25F +#define EAX_PRESET_UNDERWATER EAX_ENVIRONMENT_UNDERWATER,1.0F,1.499F,0.0F +#define EAX_PRESET_DRUGGED EAX_ENVIRONMENT_DRUGGED,0.875F,8.392F,1.388F +#define EAX_PRESET_DIZZY EAX_ENVIRONMENT_DIZZY,0.139F,17.234F,0.666F +#define EAX_PRESET_PSYCHOTIC EAX_ENVIRONMENT_PSYCHOTIC,0.486F,7.563F,0.806F + +typedef DWORD (CALLBACK STREAMPROC)(HSTREAM handle, void *buffer, DWORD length, void *user); +/* User stream callback function. NOTE: A stream function should obviously be as quick +as possible, other streams (and MOD musics) can't be mixed until it's finished. +handle : The stream that needs writing +buffer : Buffer to write the samples in +length : Number of bytes to write +user : The 'user' parameter value given when calling BASS_StreamCreate +RETURN : Number of bytes written. Set the BASS_STREAMPROC_END flag to end the stream. */ + +#define BASS_STREAMPROC_END 0x80000000 // end of user stream flag + +// special STREAMPROCs +#define STREAMPROC_DUMMY (STREAMPROC*)0 // "dummy" stream +#define STREAMPROC_PUSH (STREAMPROC*)-1 // push stream +#define STREAMPROC_DEVICE (STREAMPROC*)-2 // device mix stream + +// BASS_StreamCreateFileUser file systems +#define STREAMFILE_NOBUFFER 0 +#define STREAMFILE_BUFFER 1 +#define STREAMFILE_BUFFERPUSH 2 + +// User file stream callback functions +typedef void (CALLBACK FILECLOSEPROC)(void *user); +typedef QWORD (CALLBACK FILELENPROC)(void *user); +typedef DWORD (CALLBACK FILEREADPROC)(void *buffer, DWORD length, void *user); +typedef BOOL (CALLBACK FILESEEKPROC)(QWORD offset, void *user); + +typedef struct { + FILECLOSEPROC *close; + FILELENPROC *length; + FILEREADPROC *read; + FILESEEKPROC *seek; +} BASS_FILEPROCS; + +// BASS_StreamPutFileData options +#define BASS_FILEDATA_END 0 // end & close the file + +// BASS_StreamGetFilePosition modes +#define BASS_FILEPOS_CURRENT 0 +#define BASS_FILEPOS_DECODE BASS_FILEPOS_CURRENT +#define BASS_FILEPOS_DOWNLOAD 1 +#define BASS_FILEPOS_END 2 +#define BASS_FILEPOS_START 3 +#define BASS_FILEPOS_CONNECTED 4 +#define BASS_FILEPOS_BUFFER 5 +#define BASS_FILEPOS_SOCKET 6 +#define BASS_FILEPOS_ASYNCBUF 7 +#define BASS_FILEPOS_SIZE 8 +#define BASS_FILEPOS_BUFFERING 9 + +typedef void (CALLBACK DOWNLOADPROC)(const void *buffer, DWORD length, void *user); +/* Internet stream download callback function. +buffer : Buffer containing the downloaded data... NULL=end of download +length : Number of bytes in the buffer +user : The 'user' parameter value given when calling BASS_StreamCreateURL */ + +// BASS_ChannelSetSync types +#define BASS_SYNC_POS 0 +#define BASS_SYNC_END 2 +#define BASS_SYNC_META 4 +#define BASS_SYNC_SLIDE 5 +#define BASS_SYNC_STALL 6 +#define BASS_SYNC_DOWNLOAD 7 +#define BASS_SYNC_FREE 8 +#define BASS_SYNC_SETPOS 11 +#define BASS_SYNC_MUSICPOS 10 +#define BASS_SYNC_MUSICINST 1 +#define BASS_SYNC_MUSICFX 3 +#define BASS_SYNC_OGG_CHANGE 12 +#define BASS_SYNC_MIXTIME 0x40000000 // flag: sync at mixtime, else at playtime +#define BASS_SYNC_ONETIME 0x80000000 // flag: sync only once, else continuously + +typedef void (CALLBACK SYNCPROC)(HSYNC handle, DWORD channel, DWORD data, void *user); +/* Sync callback function. NOTE: a sync callback function should be very +quick as other syncs can't be processed until it has finished. If the sync +is a "mixtime" sync, then other streams and MOD musics can't be mixed until +it's finished either. +handle : The sync that has occured +channel: Channel that the sync occured in +data : Additional data associated with the sync's occurance +user : The 'user' parameter given when calling BASS_ChannelSetSync */ + +typedef void (CALLBACK DSPPROC)(HDSP handle, DWORD channel, void *buffer, DWORD length, void *user); +/* DSP callback function. NOTE: A DSP function should obviously be as quick as +possible... other DSP functions, streams and MOD musics can not be processed +until it's finished. +handle : The DSP handle +channel: Channel that the DSP is being applied to +buffer : Buffer to apply the DSP to +length : Number of bytes in the buffer +user : The 'user' parameter given when calling BASS_ChannelSetDSP */ + +typedef BOOL (CALLBACK RECORDPROC)(HRECORD handle, const void *buffer, DWORD length, void *user); +/* Recording callback function. +handle : The recording handle +buffer : Buffer containing the recorded sample data +length : Number of bytes +user : The 'user' parameter value given when calling BASS_RecordStart +RETURN : TRUE = continue recording, FALSE = stop */ + +// BASS_ChannelIsActive return values +#define BASS_ACTIVE_STOPPED 0 +#define BASS_ACTIVE_PLAYING 1 +#define BASS_ACTIVE_STALLED 2 +#define BASS_ACTIVE_PAUSED 3 + +// Channel attributes +#define BASS_ATTRIB_FREQ 1 +#define BASS_ATTRIB_VOL 2 +#define BASS_ATTRIB_PAN 3 +#define BASS_ATTRIB_EAXMIX 4 +#define BASS_ATTRIB_NOBUFFER 5 +#define BASS_ATTRIB_VBR 6 +#define BASS_ATTRIB_CPU 7 +#define BASS_ATTRIB_SRC 8 +#define BASS_ATTRIB_NET_RESUME 9 +#define BASS_ATTRIB_SCANINFO 10 +#define BASS_ATTRIB_NORAMP 11 +#define BASS_ATTRIB_BITRATE 12 +#define BASS_ATTRIB_BUFFER 13 +#define BASS_ATTRIB_MUSIC_AMPLIFY 0x100 +#define BASS_ATTRIB_MUSIC_PANSEP 0x101 +#define BASS_ATTRIB_MUSIC_PSCALER 0x102 +#define BASS_ATTRIB_MUSIC_BPM 0x103 +#define BASS_ATTRIB_MUSIC_SPEED 0x104 +#define BASS_ATTRIB_MUSIC_VOL_GLOBAL 0x105 +#define BASS_ATTRIB_MUSIC_ACTIVE 0x106 +#define BASS_ATTRIB_MUSIC_VOL_CHAN 0x200 // + channel # +#define BASS_ATTRIB_MUSIC_VOL_INST 0x300 // + instrument # + +// BASS_ChannelSlideAttribute flags +#define BASS_SLIDE_LOG 0x1000000 + +// BASS_ChannelGetData flags +#define BASS_DATA_AVAILABLE 0 // query how much data is buffered +#define BASS_DATA_FIXED 0x20000000 // flag: return 8.24 fixed-point data +#define BASS_DATA_FLOAT 0x40000000 // flag: return floating-point sample data +#define BASS_DATA_FFT256 0x80000000 // 256 sample FFT +#define BASS_DATA_FFT512 0x80000001 // 512 FFT +#define BASS_DATA_FFT1024 0x80000002 // 1024 FFT +#define BASS_DATA_FFT2048 0x80000003 // 2048 FFT +#define BASS_DATA_FFT4096 0x80000004 // 4096 FFT +#define BASS_DATA_FFT8192 0x80000005 // 8192 FFT +#define BASS_DATA_FFT16384 0x80000006 // 16384 FFT +#define BASS_DATA_FFT32768 0x80000007 // 32768 FFT +#define BASS_DATA_FFT_INDIVIDUAL 0x10 // FFT flag: FFT for each channel, else all combined +#define BASS_DATA_FFT_NOWINDOW 0x20 // FFT flag: no Hanning window +#define BASS_DATA_FFT_REMOVEDC 0x40 // FFT flag: pre-remove DC bias +#define BASS_DATA_FFT_COMPLEX 0x80 // FFT flag: return complex data + +// BASS_ChannelGetLevelEx flags +#define BASS_LEVEL_MONO 1 +#define BASS_LEVEL_STEREO 2 +#define BASS_LEVEL_RMS 4 +#define BASS_LEVEL_VOLPAN 8 + +// BASS_ChannelGetTags types : what's returned +#define BASS_TAG_ID3 0 // ID3v1 tags : TAG_ID3 structure +#define BASS_TAG_ID3V2 1 // ID3v2 tags : variable length block +#define BASS_TAG_OGG 2 // OGG comments : series of null-terminated UTF-8 strings +#define BASS_TAG_HTTP 3 // HTTP headers : series of null-terminated ANSI strings +#define BASS_TAG_ICY 4 // ICY headers : series of null-terminated ANSI strings +#define BASS_TAG_META 5 // ICY metadata : ANSI string +#define BASS_TAG_APE 6 // APE tags : series of null-terminated UTF-8 strings +#define BASS_TAG_MP4 7 // MP4/iTunes metadata : series of null-terminated UTF-8 strings +#define BASS_TAG_WMA 8 // WMA tags : series of null-terminated UTF-8 strings +#define BASS_TAG_VENDOR 9 // OGG encoder : UTF-8 string +#define BASS_TAG_LYRICS3 10 // Lyric3v2 tag : ASCII string +#define BASS_TAG_CA_CODEC 11 // CoreAudio codec info : TAG_CA_CODEC structure +#define BASS_TAG_MF 13 // Media Foundation tags : series of null-terminated UTF-8 strings +#define BASS_TAG_WAVEFORMAT 14 // WAVE format : WAVEFORMATEEX structure +#define BASS_TAG_AM_MIME 15 // Android Media MIME type : ASCII string +#define BASS_TAG_AM_NAME 16 // Android Media codec name : ASCII string +#define BASS_TAG_RIFF_INFO 0x100 // RIFF "INFO" tags : series of null-terminated ANSI strings +#define BASS_TAG_RIFF_BEXT 0x101 // RIFF/BWF "bext" tags : TAG_BEXT structure +#define BASS_TAG_RIFF_CART 0x102 // RIFF/BWF "cart" tags : TAG_CART structure +#define BASS_TAG_RIFF_DISP 0x103 // RIFF "DISP" text tag : ANSI string +#define BASS_TAG_RIFF_CUE 0x104 // RIFF "cue " chunk : TAG_CUE structure +#define BASS_TAG_RIFF_SMPL 0x105 // RIFF "smpl" chunk : TAG_SMPL structure +#define BASS_TAG_APE_BINARY 0x1000 // + index #, binary APE tag : TAG_APE_BINARY structure +#define BASS_TAG_MUSIC_NAME 0x10000 // MOD music name : ANSI string +#define BASS_TAG_MUSIC_MESSAGE 0x10001 // MOD message : ANSI string +#define BASS_TAG_MUSIC_ORDERS 0x10002 // MOD order list : BYTE array of pattern numbers +#define BASS_TAG_MUSIC_AUTH 0x10003 // MOD author : UTF-8 string +#define BASS_TAG_MUSIC_INST 0x10100 // + instrument #, MOD instrument name : ANSI string +#define BASS_TAG_MUSIC_SAMPLE 0x10300 // + sample #, MOD sample name : ANSI string + +// ID3v1 tag structure +typedef struct { + char id[3]; + char title[30]; + char artist[30]; + char album[30]; + char year[4]; + char comment[30]; + BYTE genre; +} TAG_ID3; + +// Binary APE tag structure +typedef struct { + const char *key; + const void *data; + DWORD length; +} TAG_APE_BINARY; + +// BWF "bext" tag structure +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable:4200) +#endif +#pragma pack(push,1) +typedef struct { + char Description[256]; // description + char Originator[32]; // name of the originator + char OriginatorReference[32]; // reference of the originator + char OriginationDate[10]; // date of creation (yyyy-mm-dd) + char OriginationTime[8]; // time of creation (hh-mm-ss) + QWORD TimeReference; // first sample count since midnight (little-endian) + WORD Version; // BWF version (little-endian) + BYTE UMID[64]; // SMPTE UMID + BYTE Reserved[190]; +#if defined(__GNUC__) && __GNUC__<3 + char CodingHistory[0]; // history +#elif 1 // change to 0 if compiler fails the following line + char CodingHistory[]; // history +#else + char CodingHistory[1]; // history +#endif +} TAG_BEXT; +#pragma pack(pop) + +// BWF "cart" tag structures +typedef struct +{ + DWORD dwUsage; // FOURCC timer usage ID + DWORD dwValue; // timer value in samples from head +} TAG_CART_TIMER; + +typedef struct +{ + char Version[4]; // version of the data structure + char Title[64]; // title of cart audio sequence + char Artist[64]; // artist or creator name + char CutID[64]; // cut number identification + char ClientID[64]; // client identification + char Category[64]; // category ID, PSA, NEWS, etc + char Classification[64]; // classification or auxiliary key + char OutCue[64]; // out cue text + char StartDate[10]; // yyyy-mm-dd + char StartTime[8]; // hh:mm:ss + char EndDate[10]; // yyyy-mm-dd + char EndTime[8]; // hh:mm:ss + char ProducerAppID[64]; // name of vendor or application + char ProducerAppVersion[64]; // version of producer application + char UserDef[64]; // user defined text + DWORD dwLevelReference; // sample value for 0 dB reference + TAG_CART_TIMER PostTimer[8]; // 8 time markers after head + char Reserved[276]; + char URL[1024]; // uniform resource locator +#if defined(__GNUC__) && __GNUC__<3 + char TagText[0]; // free form text for scripts or tags +#elif 1 // change to 0 if compiler fails the following line + char TagText[]; // free form text for scripts or tags +#else + char TagText[1]; // free form text for scripts or tags +#endif +} TAG_CART; + +// RIFF "cue " tag structures +typedef struct +{ + DWORD dwName; + DWORD dwPosition; + DWORD fccChunk; + DWORD dwChunkStart; + DWORD dwBlockStart; + DWORD dwSampleOffset; +} TAG_CUE_POINT; + +typedef struct +{ + DWORD dwCuePoints; +#if defined(__GNUC__) && __GNUC__<3 + TAG_CUE_POINT CuePoints[0]; +#elif 1 // change to 0 if compiler fails the following line + TAG_CUE_POINT CuePoints[]; +#else + TAG_CUE_POINT CuePoints[1]; +#endif +} TAG_CUE; + +// RIFF "smpl" tag structures +typedef struct +{ + DWORD dwIdentifier; + DWORD dwType; + DWORD dwStart; + DWORD dwEnd; + DWORD dwFraction; + DWORD dwPlayCount; +} TAG_SMPL_LOOP; + +typedef struct +{ + DWORD dwManufacturer; + DWORD dwProduct; + DWORD dwSamplePeriod; + DWORD dwMIDIUnityNote; + DWORD dwMIDIPitchFraction; + DWORD dwSMPTEFormat; + DWORD dwSMPTEOffset; + DWORD cSampleLoops; + DWORD cbSamplerData; +#if defined(__GNUC__) && __GNUC__<3 + TAG_SMPL_LOOP SampleLoops[0]; +#elif 1 // change to 0 if compiler fails the following line + TAG_SMPL_LOOP SampleLoops[]; +#else + TAG_SMPL_LOOP SampleLoops[1]; +#endif +} TAG_SMPL; +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +// CoreAudio codec info structure +typedef struct { + DWORD ftype; // file format + DWORD atype; // audio format + const char *name; // description +} TAG_CA_CODEC; + +#ifndef _WAVEFORMATEX_ +#define _WAVEFORMATEX_ +#pragma pack(push,1) +typedef struct tWAVEFORMATEX +{ + WORD wFormatTag; + WORD nChannels; + DWORD nSamplesPerSec; + DWORD nAvgBytesPerSec; + WORD nBlockAlign; + WORD wBitsPerSample; + WORD cbSize; +} WAVEFORMATEX, *PWAVEFORMATEX, *LPWAVEFORMATEX; +typedef const WAVEFORMATEX *LPCWAVEFORMATEX; +#pragma pack(pop) +#endif + +// BASS_ChannelGetLength/GetPosition/SetPosition modes +#define BASS_POS_BYTE 0 // byte position +#define BASS_POS_MUSIC_ORDER 1 // order.row position, MAKELONG(order,row) +#define BASS_POS_OGG 3 // OGG bitstream number +#define BASS_POS_RESET 0x2000000 // flag: reset user file buffers +#define BASS_POS_RELATIVE 0x4000000 // flag: seek relative to the current position +#define BASS_POS_INEXACT 0x8000000 // flag: allow seeking to inexact position +#define BASS_POS_DECODE 0x10000000 // flag: get the decoding (not playing) position +#define BASS_POS_DECODETO 0x20000000 // flag: decode to the position instead of seeking +#define BASS_POS_SCAN 0x40000000 // flag: scan to the position + +// BASS_ChannelSetDevice/GetDevice option +#define BASS_NODEVICE 0x20000 + +// BASS_RecordSetInput flags +#define BASS_INPUT_OFF 0x10000 +#define BASS_INPUT_ON 0x20000 + +#define BASS_INPUT_TYPE_MASK 0xff000000 +#define BASS_INPUT_TYPE_UNDEF 0x00000000 +#define BASS_INPUT_TYPE_DIGITAL 0x01000000 +#define BASS_INPUT_TYPE_LINE 0x02000000 +#define BASS_INPUT_TYPE_MIC 0x03000000 +#define BASS_INPUT_TYPE_SYNTH 0x04000000 +#define BASS_INPUT_TYPE_CD 0x05000000 +#define BASS_INPUT_TYPE_PHONE 0x06000000 +#define BASS_INPUT_TYPE_SPEAKER 0x07000000 +#define BASS_INPUT_TYPE_WAVE 0x08000000 +#define BASS_INPUT_TYPE_AUX 0x09000000 +#define BASS_INPUT_TYPE_ANALOG 0x0a000000 + +// BASS_ChannelSetFX effect types +#define BASS_FX_DX8_CHORUS 0 +#define BASS_FX_DX8_COMPRESSOR 1 +#define BASS_FX_DX8_DISTORTION 2 +#define BASS_FX_DX8_ECHO 3 +#define BASS_FX_DX8_FLANGER 4 +#define BASS_FX_DX8_GARGLE 5 +#define BASS_FX_DX8_I3DL2REVERB 6 +#define BASS_FX_DX8_PARAMEQ 7 +#define BASS_FX_DX8_REVERB 8 +#define BASS_FX_VOLUME 9 + +typedef struct { + float fWetDryMix; + float fDepth; + float fFeedback; + float fFrequency; + DWORD lWaveform; // 0=triangle, 1=sine + float fDelay; + DWORD lPhase; // BASS_DX8_PHASE_xxx +} BASS_DX8_CHORUS; + +typedef struct { + float fGain; + float fAttack; + float fRelease; + float fThreshold; + float fRatio; + float fPredelay; +} BASS_DX8_COMPRESSOR; + +typedef struct { + float fGain; + float fEdge; + float fPostEQCenterFrequency; + float fPostEQBandwidth; + float fPreLowpassCutoff; +} BASS_DX8_DISTORTION; + +typedef struct { + float fWetDryMix; + float fFeedback; + float fLeftDelay; + float fRightDelay; + BOOL lPanDelay; +} BASS_DX8_ECHO; + +typedef struct { + float fWetDryMix; + float fDepth; + float fFeedback; + float fFrequency; + DWORD lWaveform; // 0=triangle, 1=sine + float fDelay; + DWORD lPhase; // BASS_DX8_PHASE_xxx +} BASS_DX8_FLANGER; + +typedef struct { + DWORD dwRateHz; // Rate of modulation in hz + DWORD dwWaveShape; // 0=triangle, 1=square +} BASS_DX8_GARGLE; + +typedef struct { + int lRoom; // [-10000, 0] default: -1000 mB + int lRoomHF; // [-10000, 0] default: 0 mB + float flRoomRolloffFactor; // [0.0, 10.0] default: 0.0 + float flDecayTime; // [0.1, 20.0] default: 1.49s + float flDecayHFRatio; // [0.1, 2.0] default: 0.83 + int lReflections; // [-10000, 1000] default: -2602 mB + float flReflectionsDelay; // [0.0, 0.3] default: 0.007 s + int lReverb; // [-10000, 2000] default: 200 mB + float flReverbDelay; // [0.0, 0.1] default: 0.011 s + float flDiffusion; // [0.0, 100.0] default: 100.0 % + float flDensity; // [0.0, 100.0] default: 100.0 % + float flHFReference; // [20.0, 20000.0] default: 5000.0 Hz +} BASS_DX8_I3DL2REVERB; + +typedef struct { + float fCenter; + float fBandwidth; + float fGain; +} BASS_DX8_PARAMEQ; + +typedef struct { + float fInGain; // [-96.0,0.0] default: 0.0 dB + float fReverbMix; // [-96.0,0.0] default: 0.0 db + float fReverbTime; // [0.001,3000.0] default: 1000.0 ms + float fHighFreqRTRatio; // [0.001,0.999] default: 0.001 +} BASS_DX8_REVERB; + +#define BASS_DX8_PHASE_NEG_180 0 +#define BASS_DX8_PHASE_NEG_90 1 +#define BASS_DX8_PHASE_ZERO 2 +#define BASS_DX8_PHASE_90 3 +#define BASS_DX8_PHASE_180 4 + +typedef struct { + float fTarget; + float fCurrent; + float fTime; + DWORD lCurve; +} BASS_FX_VOLUME_PARAM; + +typedef void (CALLBACK IOSNOTIFYPROC)(DWORD status); +/* iOS notification callback function. +status : The notification (BASS_IOSNOTIFY_xxx) */ + +#define BASS_IOSNOTIFY_INTERRUPT 1 // interruption started +#define BASS_IOSNOTIFY_INTERRUPT_END 2 // interruption ended + +BOOL BASSDEF(BASS_SetConfig)(DWORD option, DWORD value); +DWORD BASSDEF(BASS_GetConfig)(DWORD option); +BOOL BASSDEF(BASS_SetConfigPtr)(DWORD option, const void *value); +void *BASSDEF(BASS_GetConfigPtr)(DWORD option); +DWORD BASSDEF(BASS_GetVersion)(); +int BASSDEF(BASS_ErrorGetCode)(); +BOOL BASSDEF(BASS_GetDeviceInfo)(DWORD device, BASS_DEVICEINFO *info); +#if defined(_WIN32) && !defined(_WIN32_WCE) && !(WINAPI_FAMILY && WINAPI_FAMILY!=WINAPI_FAMILY_DESKTOP_APP) +BOOL BASSDEF(BASS_Init)(int device, DWORD freq, DWORD flags, HWND win, const GUID *dsguid); +#else +BOOL BASSDEF(BASS_Init)(int device, DWORD freq, DWORD flags, void *win, void *dsguid); +#endif +BOOL BASSDEF(BASS_SetDevice)(DWORD device); +DWORD BASSDEF(BASS_GetDevice)(); +BOOL BASSDEF(BASS_Free)(); +#if defined(_WIN32) && !defined(_WIN32_WCE) && !(WINAPI_FAMILY && WINAPI_FAMILY!=WINAPI_FAMILY_DESKTOP_APP) +void *BASSDEF(BASS_GetDSoundObject)(DWORD object); +#endif +BOOL BASSDEF(BASS_GetInfo)(BASS_INFO *info); +BOOL BASSDEF(BASS_Update)(DWORD length); +float BASSDEF(BASS_GetCPU)(); +BOOL BASSDEF(BASS_Start)(); +BOOL BASSDEF(BASS_Stop)(); +BOOL BASSDEF(BASS_Pause)(); +BOOL BASSDEF(BASS_SetVolume)(float volume); +float BASSDEF(BASS_GetVolume)(); + +HPLUGIN BASSDEF(BASS_PluginLoad)(const char *file, DWORD flags); +BOOL BASSDEF(BASS_PluginFree)(HPLUGIN handle); +const BASS_PLUGININFO *BASSDEF(BASS_PluginGetInfo)(HPLUGIN handle); + +BOOL BASSDEF(BASS_Set3DFactors)(float distf, float rollf, float doppf); +BOOL BASSDEF(BASS_Get3DFactors)(float *distf, float *rollf, float *doppf); +BOOL BASSDEF(BASS_Set3DPosition)(const BASS_3DVECTOR *pos, const BASS_3DVECTOR *vel, const BASS_3DVECTOR *front, const BASS_3DVECTOR *top); +BOOL BASSDEF(BASS_Get3DPosition)(BASS_3DVECTOR *pos, BASS_3DVECTOR *vel, BASS_3DVECTOR *front, BASS_3DVECTOR *top); +void BASSDEF(BASS_Apply3D)(); +#if defined(_WIN32) && !defined(_WIN32_WCE) && !(WINAPI_FAMILY && WINAPI_FAMILY!=WINAPI_FAMILY_DESKTOP_APP) +BOOL BASSDEF(BASS_SetEAXParameters)(int env, float vol, float decay, float damp); +BOOL BASSDEF(BASS_GetEAXParameters)(DWORD *env, float *vol, float *decay, float *damp); +#endif + +HMUSIC BASSDEF(BASS_MusicLoad)(BOOL mem, const void *file, QWORD offset, DWORD length, DWORD flags, DWORD freq); +BOOL BASSDEF(BASS_MusicFree)(HMUSIC handle); + +HSAMPLE BASSDEF(BASS_SampleLoad)(BOOL mem, const void *file, QWORD offset, DWORD length, DWORD max, DWORD flags); +HSAMPLE BASSDEF(BASS_SampleCreate)(DWORD length, DWORD freq, DWORD chans, DWORD max, DWORD flags); +BOOL BASSDEF(BASS_SampleFree)(HSAMPLE handle); +BOOL BASSDEF(BASS_SampleSetData)(HSAMPLE handle, const void *buffer); +BOOL BASSDEF(BASS_SampleGetData)(HSAMPLE handle, void *buffer); +BOOL BASSDEF(BASS_SampleGetInfo)(HSAMPLE handle, BASS_SAMPLE *info); +BOOL BASSDEF(BASS_SampleSetInfo)(HSAMPLE handle, const BASS_SAMPLE *info); +HCHANNEL BASSDEF(BASS_SampleGetChannel)(HSAMPLE handle, BOOL onlynew); +DWORD BASSDEF(BASS_SampleGetChannels)(HSAMPLE handle, HCHANNEL *channels); +BOOL BASSDEF(BASS_SampleStop)(HSAMPLE handle); + +HSTREAM BASSDEF(BASS_StreamCreate)(DWORD freq, DWORD chans, DWORD flags, STREAMPROC *proc, void *user); +HSTREAM BASSDEF(BASS_StreamCreateFile)(BOOL mem, const void *file, QWORD offset, QWORD length, DWORD flags); +HSTREAM BASSDEF(BASS_StreamCreateURL)(const char *url, DWORD offset, DWORD flags, DOWNLOADPROC *proc, void *user); +HSTREAM BASSDEF(BASS_StreamCreateFileUser)(DWORD system, DWORD flags, const BASS_FILEPROCS *proc, void *user); +BOOL BASSDEF(BASS_StreamFree)(HSTREAM handle); +QWORD BASSDEF(BASS_StreamGetFilePosition)(HSTREAM handle, DWORD mode); +DWORD BASSDEF(BASS_StreamPutData)(HSTREAM handle, const void *buffer, DWORD length); +DWORD BASSDEF(BASS_StreamPutFileData)(HSTREAM handle, const void *buffer, DWORD length); + +BOOL BASSDEF(BASS_RecordGetDeviceInfo)(DWORD device, BASS_DEVICEINFO *info); +BOOL BASSDEF(BASS_RecordInit)(int device); +BOOL BASSDEF(BASS_RecordSetDevice)(DWORD device); +DWORD BASSDEF(BASS_RecordGetDevice)(); +BOOL BASSDEF(BASS_RecordFree)(); +BOOL BASSDEF(BASS_RecordGetInfo)(BASS_RECORDINFO *info); +const char *BASSDEF(BASS_RecordGetInputName)(int input); +BOOL BASSDEF(BASS_RecordSetInput)(int input, DWORD flags, float volume); +DWORD BASSDEF(BASS_RecordGetInput)(int input, float *volume); +HRECORD BASSDEF(BASS_RecordStart)(DWORD freq, DWORD chans, DWORD flags, RECORDPROC *proc, void *user); + +double BASSDEF(BASS_ChannelBytes2Seconds)(DWORD handle, QWORD pos); +QWORD BASSDEF(BASS_ChannelSeconds2Bytes)(DWORD handle, double pos); +DWORD BASSDEF(BASS_ChannelGetDevice)(DWORD handle); +BOOL BASSDEF(BASS_ChannelSetDevice)(DWORD handle, DWORD device); +DWORD BASSDEF(BASS_ChannelIsActive)(DWORD handle); +BOOL BASSDEF(BASS_ChannelGetInfo)(DWORD handle, BASS_CHANNELINFO *info); +const char *BASSDEF(BASS_ChannelGetTags)(DWORD handle, DWORD tags); +DWORD BASSDEF(BASS_ChannelFlags)(DWORD handle, DWORD flags, DWORD mask); +BOOL BASSDEF(BASS_ChannelUpdate)(DWORD handle, DWORD length); +BOOL BASSDEF(BASS_ChannelLock)(DWORD handle, BOOL lock); +BOOL BASSDEF(BASS_ChannelPlay)(DWORD handle, BOOL restart); +BOOL BASSDEF(BASS_ChannelStop)(DWORD handle); +BOOL BASSDEF(BASS_ChannelPause)(DWORD handle); +BOOL BASSDEF(BASS_ChannelSetAttribute)(DWORD handle, DWORD attrib, float value); +BOOL BASSDEF(BASS_ChannelGetAttribute)(DWORD handle, DWORD attrib, float *value); +BOOL BASSDEF(BASS_ChannelSlideAttribute)(DWORD handle, DWORD attrib, float value, DWORD time); +BOOL BASSDEF(BASS_ChannelIsSliding)(DWORD handle, DWORD attrib); +BOOL BASSDEF(BASS_ChannelSetAttributeEx)(DWORD handle, DWORD attrib, void *value, DWORD size); +DWORD BASSDEF(BASS_ChannelGetAttributeEx)(DWORD handle, DWORD attrib, void *value, DWORD size); +BOOL BASSDEF(BASS_ChannelSet3DAttributes)(DWORD handle, int mode, float min, float max, int iangle, int oangle, float outvol); +BOOL BASSDEF(BASS_ChannelGet3DAttributes)(DWORD handle, DWORD *mode, float *min, float *max, DWORD *iangle, DWORD *oangle, float *outvol); +BOOL BASSDEF(BASS_ChannelSet3DPosition)(DWORD handle, const BASS_3DVECTOR *pos, const BASS_3DVECTOR *orient, const BASS_3DVECTOR *vel); +BOOL BASSDEF(BASS_ChannelGet3DPosition)(DWORD handle, BASS_3DVECTOR *pos, BASS_3DVECTOR *orient, BASS_3DVECTOR *vel); +QWORD BASSDEF(BASS_ChannelGetLength)(DWORD handle, DWORD mode); +BOOL BASSDEF(BASS_ChannelSetPosition)(DWORD handle, QWORD pos, DWORD mode); +QWORD BASSDEF(BASS_ChannelGetPosition)(DWORD handle, DWORD mode); +DWORD BASSDEF(BASS_ChannelGetLevel)(DWORD handle); +BOOL BASSDEF(BASS_ChannelGetLevelEx)(DWORD handle, float *levels, float length, DWORD flags); +DWORD BASSDEF(BASS_ChannelGetData)(DWORD handle, void *buffer, DWORD length); +HSYNC BASSDEF(BASS_ChannelSetSync)(DWORD handle, DWORD type, QWORD param, SYNCPROC *proc, void *user); +BOOL BASSDEF(BASS_ChannelRemoveSync)(DWORD handle, HSYNC sync); +HDSP BASSDEF(BASS_ChannelSetDSP)(DWORD handle, DSPPROC *proc, void *user, int priority); +BOOL BASSDEF(BASS_ChannelRemoveDSP)(DWORD handle, HDSP dsp); +BOOL BASSDEF(BASS_ChannelSetLink)(DWORD handle, DWORD chan); +BOOL BASSDEF(BASS_ChannelRemoveLink)(DWORD handle, DWORD chan); +HFX BASSDEF(BASS_ChannelSetFX)(DWORD handle, DWORD type, int priority); +BOOL BASSDEF(BASS_ChannelRemoveFX)(DWORD handle, HFX fx); + +BOOL BASSDEF(BASS_FXSetParameters)(HFX handle, const void *params); +BOOL BASSDEF(BASS_FXGetParameters)(HFX handle, void *params); +BOOL BASSDEF(BASS_FXReset)(HFX handle); +BOOL BASSDEF(BASS_FXSetPriority)(HFX handle, int priority); + +#ifdef __cplusplus +} + +#if defined(_WIN32) && !defined(NOBASSOVERLOADS) +static inline HPLUGIN BASS_PluginLoad(const WCHAR *file, DWORD flags) +{ + return BASS_PluginLoad((const char*)file, flags|BASS_UNICODE); +} + +static inline HMUSIC BASS_MusicLoad(BOOL mem, const WCHAR *file, QWORD offset, DWORD length, DWORD flags, DWORD freq) +{ + return BASS_MusicLoad(mem, (const void*)file, offset, length, flags|BASS_UNICODE, freq); +} + +static inline HSAMPLE BASS_SampleLoad(BOOL mem, const WCHAR *file, QWORD offset, DWORD length, DWORD max, DWORD flags) +{ + return BASS_SampleLoad(mem, (const void*)file, offset, length, max, flags|BASS_UNICODE); +} + +static inline HSTREAM BASS_StreamCreateFile(BOOL mem, const WCHAR *file, QWORD offset, QWORD length, DWORD flags) +{ + return BASS_StreamCreateFile(mem, (const void*)file, offset, length, flags|BASS_UNICODE); +} + +static inline HSTREAM BASS_StreamCreateURL(const WCHAR *url, DWORD offset, DWORD flags, DOWNLOADPROC *proc, void *user) +{ + return BASS_StreamCreateURL((const char*)url, offset, flags|BASS_UNICODE, proc, user); +} + +static inline BOOL BASS_SetConfigPtr(DWORD option, const WCHAR *value) +{ + return BASS_SetConfigPtr(option|BASS_UNICODE, (const void*)value); +} +#endif +#endif + +#endif -- cgit From 45eae604451d2a05e13e9cdb163319c4a0dab7aa Mon Sep 17 00:00:00 2001 From: David Skoland Date: Wed, 26 Dec 2018 17:14:10 +0100 Subject: added ubuntu config script --- scripts/configure_ubuntu.sh | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100755 scripts/configure_ubuntu.sh diff --git a/scripts/configure_ubuntu.sh b/scripts/configure_ubuntu.sh new file mode 100755 index 00000000..a85f09bd --- /dev/null +++ b/scripts/configure_ubuntu.sh @@ -0,0 +1,27 @@ +#!/bin/bash + +#assumes a somewhat recent 64-bit ubuntu + +#need some openGL stuff +sudo apt install libgl1-mesa-dev + +mkdir tmp +cd tmp + +#get the bass prebuilt +curl http://www.un4seen.com/files/bass24-linux.zip -o bass_linux.zip + +unzip bass_linux.zip + +cp x64/libbass.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 + +unzip discord_rpc_linux.zip + +cp discord-rpc/linux-dynamic/lib/libdiscord-rpc.so ../../lib/ + +cd .. + +rm -rf tmp/ -- cgit From 1f754776b43d7ae8f317d480b6366d8b8f0ce2d0 Mon Sep 17 00:00:00 2001 From: David Skoland Date: Wed, 26 Dec 2018 17:31:43 +0100 Subject: finished ubuntu build script and made default plugin mode dynamic linking --- scripts/configure_ubuntu.sh | 12 +++++++++++- src/main.cpp | 1 - 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/scripts/configure_ubuntu.sh b/scripts/configure_ubuntu.sh index a85f09bd..5e587ad5 100755 --- a/scripts/configure_ubuntu.sh +++ b/scripts/configure_ubuntu.sh @@ -22,6 +22,16 @@ unzip discord_rpc_linux.zip cp discord-rpc/linux-dynamic/lib/libdiscord-rpc.so ../../lib/ +#get libqtapng plugin prebuilt +curl -L https://github.com/Skycoder42/QtApng/releases/download/1.1.0-5/build_gcc_64_5.12.0.tar.xz -o apng.tar.xz + +tar -xvf apng.tar.xz + +cp gcc_64/plugins/imageformats/libqapng.so ../../lib + cd .. -rm -rf tmp/ +rm -rf tmp + +#during runtime, the program expects the libraries to exist in the root folder +cp ../lib/* .. diff --git a/src/main.cpp b/src/main.cpp index cf51b0af..80ea93bb 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -7,7 +7,6 @@ #include "courtroom.h" #include #include -Q_IMPORT_PLUGIN(ApngImagePlugin); int main(int argc, char *argv[]) { #if QT_VERSION > QT_VERSION_CHECK(5, 6, 0) -- cgit From 73a13d9d88ac3a5bed69e781c47ece8a465872ea Mon Sep 17 00:00:00 2001 From: David Skoland Date: Wed, 26 Dec 2018 18:02:15 +0100 Subject: added lib folder to ubuntu configure script --- scripts/configure_ubuntu.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/configure_ubuntu.sh b/scripts/configure_ubuntu.sh index 5e587ad5..98586a60 100755 --- a/scripts/configure_ubuntu.sh +++ b/scripts/configure_ubuntu.sh @@ -6,6 +6,8 @@ sudo apt install libgl1-mesa-dev mkdir tmp +mkdir ../lib + cd tmp #get the bass prebuilt -- cgit From a2d3ab8b96f787f6406b962d9ebf744808274d89 Mon Sep 17 00:00:00 2001 From: David Skoland Date: Wed, 26 Dec 2018 18:11:08 +0100 Subject: adjusted gitignore files --- .gitignore | 3 ++- lib/.gitignore | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 lib/.gitignore diff --git a/.gitignore b/.gitignore index f525d7d7..6ac11d66 100644 --- a/.gitignore +++ b/.gitignore @@ -3,15 +3,16 @@ *.user *.dll *.so +*.pro.autosave base_override.h base-full/ bass.lib +bin/ bins/ release/ debug/ -lib/ .qmake.stash diff --git a/lib/.gitignore b/lib/.gitignore new file mode 100644 index 00000000..d6b7ef32 --- /dev/null +++ b/lib/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore -- cgit From 9753a16a848476c7356fd96a1261d589f02fb456 Mon Sep 17 00:00:00 2001 From: David Skoland Date: Wed, 26 Dec 2018 18:16:24 +0100 Subject: remove kebab --- Attorney_Online_remake.pro | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/Attorney_Online_remake.pro b/Attorney_Online_remake.pro index 4d7f3f12..3695a6e8 100644 --- a/Attorney_Online_remake.pro +++ b/Attorney_Online_remake.pro @@ -29,22 +29,3 @@ win32:LIBS += "bass.dll" -ldiscord-rpc CONFIG += c++11 RESOURCES += resources.qrc - -# 1. You need to get BASS and put the x86 bass DLL/headers in the project root folder -# AND the compilation output folder. If you are compiling statically, you'll probably -# need the .lib file too. MinGW-GCC is really finicky finding BASS, it seems. However, -# even with the .lib file, you still need the DLL in the final output. -# 2. You need to compile the Discord Rich Presence SDK separately and add the lib/headers -# in the same way as BASS. Discord RPC uses CMake, which does not play nicely with -# QMake, so this step must be manual. If you are compiling dynamically, it's fine to -# use the prebuilt libraries. -# 3. You also need to build QtApng (https://github.com/Skycoder42/QtApng). -# Optionally, you may install it in /usr/share/qt5/plugins/imageformats, but if you do -# so, then you must patch qapng.pri, qapngd.pri, png.pri, pngd.pri, z.pri, and zd.pri -# such that they no longer point to the builds in the original project directory -# (by removing those respective entries in QMAKE_PRL_LIBS and replacing them with -# something like `-L$$[QT_INSTALL_LIBS] -lpng -lz`). -# -# Naturally, the build process becomes significantly less convoluted if you simply -# compile dynamically. If your primary distribution method is via the launcher, then -# a simple dynamic compilation is recommended. -- cgit From ac290a38ca7144a7c883afbcf05ee7b82e620444 Mon Sep 17 00:00:00 2001 From: David Skoland Date: Wed, 26 Dec 2018 18:17:16 +0100 Subject: renamed pro file to nicer name --- Attorney_Online.pro | 31 +++++++++++++++++++++++++++++++ Attorney_Online_remake.pro | 31 ------------------------------- 2 files changed, 31 insertions(+), 31 deletions(-) create mode 100644 Attorney_Online.pro delete mode 100644 Attorney_Online_remake.pro diff --git a/Attorney_Online.pro b/Attorney_Online.pro new file mode 100644 index 00000000..3695a6e8 --- /dev/null +++ b/Attorney_Online.pro @@ -0,0 +1,31 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2016-12-29T01:14:46 +# +#------------------------------------------------- + +QT += core gui multimedia network +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +RC_ICONS = logo.ico + +TARGET = Attorney_Online +TEMPLATE = app + +VERSION = 2.6.0.0 + +INCLUDEPATH += $$PWD/include +DESTDIR = $$PWD/bin +OBJECTS_DIR = $$PWD/build +MOC_DIR = $$PWD/build + +SOURCES += $$files($$PWD/src/*.cpp) +HEADERS += $$files($$PWD/include/*.h) +LIBS += -L$$PWD/lib + +unix:LIBS += -lbass -ldiscord-rpc +win32:LIBS += "bass.dll" -ldiscord-rpc + +CONFIG += c++11 + +RESOURCES += resources.qrc diff --git a/Attorney_Online_remake.pro b/Attorney_Online_remake.pro deleted file mode 100644 index 3695a6e8..00000000 --- a/Attorney_Online_remake.pro +++ /dev/null @@ -1,31 +0,0 @@ -#------------------------------------------------- -# -# Project created by QtCreator 2016-12-29T01:14:46 -# -#------------------------------------------------- - -QT += core gui multimedia network -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets - -RC_ICONS = logo.ico - -TARGET = Attorney_Online -TEMPLATE = app - -VERSION = 2.6.0.0 - -INCLUDEPATH += $$PWD/include -DESTDIR = $$PWD/bin -OBJECTS_DIR = $$PWD/build -MOC_DIR = $$PWD/build - -SOURCES += $$files($$PWD/src/*.cpp) -HEADERS += $$files($$PWD/include/*.h) -LIBS += -L$$PWD/lib - -unix:LIBS += -lbass -ldiscord-rpc -win32:LIBS += "bass.dll" -ldiscord-rpc - -CONFIG += c++11 - -RESOURCES += resources.qrc -- cgit From bae5ef536386096a6831f1e91d04904f79d5a892 Mon Sep 17 00:00:00 2001 From: David Skoland Date: Wed, 26 Dec 2018 18:17:53 +0100 Subject: it's the official version, no need for numbers --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5e6adb24..0416e4a3 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Attorney Online 2 +# Attorney Online [Attorney Online](https://aceattorneyonline.com) is an online version of the world-renowned courtroom drama simulator that allows you to create and play out cases in an off-the-cuff format. -- cgit From 452cffcac3e3c37049470fb24749729e3260cc75 Mon Sep 17 00:00:00 2001 From: David Skoland Date: Wed, 26 Dec 2018 18:44:26 +0100 Subject: added building instructions --- README_BUILD.md | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 README_BUILD.md diff --git a/README_BUILD.md b/README_BUILD.md new file mode 100644 index 00000000..6ede9f5e --- /dev/null +++ b/README_BUILD.md @@ -0,0 +1,41 @@ +### Dependencies + +This program has five main dependencies + +* Qt 5.6+ (https://www.qt.io/download) +* BASS (http://www.un4seen.com/bass.html) +* BASS Opus Plugin (http://www.un4seen.com/bass.html#addons) +* Discord Rich Presence (https://github.com/discordapp/discord-rpc/releases) +* Qt Apng Plugin (https://github.com/Skycoder42/QtApng/releases) + +### How to build dynamically (the easy way) + +What you want to do is first download the latest version of Qt from the first link. (get the prebuilt dynamic version) +If you're on Ubuntu, go to the scripts/ folder and run configure_ubuntu.sh. This should fetch all the required dependencies automatically. +If not, go to each one of the links above and find the right dynamic library for your platform: +* Windows: .dll +* Linux: .so +* Mac: .dylib + +And put them in BOTH lib/ and the repository root (lib/ is required for linking and root is required for runtime) + +Launch Qt creator, open the .pro file and try running it. Ask in the Discord if you're having issues: https://discord.gg/wWvQ3pw + +### How to build statically (the hard way) + +You're gonna have a bad time. + +Building statically means you can distribute the final program without needing to pack alongside a lot of dynamic libraries. +This is a tricky process and is not recommended unless you know what you're doing. + +The general idea is to first build the entirety of Qt statically. To do this, check the desired version under "Sources" in the Qt maintenance tool. +After this is done, follow these instructions: https://dimitris.apeiro.gr/2015/06/24/build-a-static-qt5-for-windows-by-compiling/ +This guide is specifically for Windows, but Qt is cross-platform and you should be good with or without some minor adjustments to the guide. +After this, you need to configure the project to use the static version of qmake (for this, look into "Qt creator build configuration") + +BASS and BASS Opus only comes as dynamic libraries and is not open-source. That means you can't link it statically in the program. + +For Discord RPC, you can try downloading the source and configuring it to compile to a static library. You're gonna have to figure out how, though. + +The same goes for Qt Apng Plugin. This guide does not go into detail how to configure each of these to build a static library. + -- cgit From 44dfdb89962b6fce76ac8f7f23f3ec0d19f2cf2c Mon Sep 17 00:00:00 2001 From: David Skoland Date: Wed, 26 Dec 2018 18:48:18 +0100 Subject: clarified readme build doc --- README_BUILD.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README_BUILD.md b/README_BUILD.md index 6ede9f5e..fb45678f 100644 --- a/README_BUILD.md +++ b/README_BUILD.md @@ -28,14 +28,15 @@ You're gonna have a bad time. Building statically means you can distribute the final program without needing to pack alongside a lot of dynamic libraries. This is a tricky process and is not recommended unless you know what you're doing. -The general idea is to first build the entirety of Qt statically. To do this, check the desired version under "Sources" in the Qt maintenance tool. +First, you need to build the entirety of Qt statically. To do this, check the desired version under "Sources" in the Qt maintenance tool. After this is done, follow these instructions: https://dimitris.apeiro.gr/2015/06/24/build-a-static-qt5-for-windows-by-compiling/ This guide is specifically for Windows, but Qt is cross-platform and you should be good with or without some minor adjustments to the guide. -After this, you need to configure the project to use the static version of qmake (for this, look into "Qt creator build configuration") +Note that this **is** a computationally heavy process and will take a lot of time on a slow computer. +After this, you need to configure the project to use the static version of qmake (see http://doc.qt.io/qtcreator/creator-build-settings.html) BASS and BASS Opus only comes as dynamic libraries and is not open-source. That means you can't link it statically in the program. For Discord RPC, you can try downloading the source and configuring it to compile to a static library. You're gonna have to figure out how, though. -The same goes for Qt Apng Plugin. This guide does not go into detail how to configure each of these to build a static library. +The same goes for Qt Apng Plugin. This guide does not go into detail how to configure each of these to build a static library. You may have to add Q_IMPORT_PLUGIN(ApngImagePlugin); in main.cpp. See more about importing static plugins here: http://doc.qt.io/qt-5/plugins-howto.html#static-plugins -- cgit From fa24d4bd865a240f3c884dcb74253e9aed7fd072 Mon Sep 17 00:00:00 2001 From: David Skoland Date: Wed, 26 Dec 2018 18:53:23 +0100 Subject: discord-rpc actually has prebuilt static libraries --- README_BUILD.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README_BUILD.md b/README_BUILD.md index fb45678f..da13bdc1 100644 --- a/README_BUILD.md +++ b/README_BUILD.md @@ -36,7 +36,7 @@ After this, you need to configure the project to use the static version of qmake BASS and BASS Opus only comes as dynamic libraries and is not open-source. That means you can't link it statically in the program. -For Discord RPC, you can try downloading the source and configuring it to compile to a static library. You're gonna have to figure out how, though. +For Discord RPC, you can download prebuilt static libraries for your platform. Just put them in lib/. -The same goes for Qt Apng Plugin. This guide does not go into detail how to configure each of these to build a static library. You may have to add Q_IMPORT_PLUGIN(ApngImagePlugin); in main.cpp. See more about importing static plugins here: http://doc.qt.io/qt-5/plugins-howto.html#static-plugins +For Qt Apng Plugin, you need to compile it statically. This guide does not go into detail how to configure this to build a static library. You may have to add Q_IMPORT_PLUGIN(ApngImagePlugin); in main.cpp. See more about importing static plugins here: http://doc.qt.io/qt-5/plugins-howto.html#static-plugins -- cgit From c353b3f24ffb40611697565a8fcb5f310b5eedea Mon Sep 17 00:00:00 2001 From: David Skoland Date: Wed, 26 Dec 2018 19:33:18 +0100 Subject: same LIBS for unix and win32 is fine. and RC_ICONS is only relevant for windows --- Attorney_Online.pro | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/Attorney_Online.pro b/Attorney_Online.pro index 3695a6e8..97236fb0 100644 --- a/Attorney_Online.pro +++ b/Attorney_Online.pro @@ -7,8 +7,6 @@ QT += core gui multimedia network greaterThan(QT_MAJOR_VERSION, 4): QT += widgets -RC_ICONS = logo.ico - TARGET = Attorney_Online TEMPLATE = app @@ -21,11 +19,10 @@ MOC_DIR = $$PWD/build SOURCES += $$files($$PWD/src/*.cpp) HEADERS += $$files($$PWD/include/*.h) -LIBS += -L$$PWD/lib - -unix:LIBS += -lbass -ldiscord-rpc -win32:LIBS += "bass.dll" -ldiscord-rpc +LIBS += -L$$PWD/lib -lbass -ldiscord-rpc CONFIG += c++11 RESOURCES += resources.qrc + +win32:RC_ICONS = resource/logo.ico -- cgit From 68145616f597c4cfc65313fc2973d9480f98be89 Mon Sep 17 00:00:00 2001 From: David Skoland Date: Wed, 26 Dec 2018 19:34:38 +0100 Subject: removed redundant statement from ubuntu config script --- scripts/configure_ubuntu.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/configure_ubuntu.sh b/scripts/configure_ubuntu.sh index 98586a60..3817997c 100755 --- a/scripts/configure_ubuntu.sh +++ b/scripts/configure_ubuntu.sh @@ -6,7 +6,6 @@ sudo apt install libgl1-mesa-dev mkdir tmp -mkdir ../lib cd tmp -- cgit From 2a43d56772137d69f5787b40fdfeb7e6effd68d5 Mon Sep 17 00:00:00 2001 From: David Skoland Date: Wed, 26 Dec 2018 20:04:11 +0100 Subject: muh macos support --- src/aooptionsdialog.cpp | 5 +++++ src/courtroom.cpp | 5 +++++ src/hardware_functions.cpp | 7 +++++++ 3 files changed, 17 insertions(+) diff --git a/src/aooptionsdialog.cpp b/src/aooptionsdialog.cpp index 2b8259f5..b1d0974c 100644 --- a/src/aooptionsdialog.cpp +++ b/src/aooptionsdialog.cpp @@ -512,6 +512,11 @@ bool AOOptionsDialog::needs_default_audiodev() { return false; } +#elif defined __APPLE__ +bool AOOptionsDialog::needs_default_audiodev() +{ + return false; +} #else #error This operating system is not supported. #endif diff --git a/src/courtroom.cpp b/src/courtroom.cpp index 3ed1e745..f4b484b7 100644 --- a/src/courtroom.cpp +++ b/src/courtroom.cpp @@ -3508,6 +3508,11 @@ void Courtroom::load_bass_opus_plugin() { BASS_PluginLoad("libbassopus.so", 0); } +#elif defined __APPLE__ +void Courtroom::load_bass_opus_plugin() +{ + BASS_PluginLoad("libbassopus.dylib", 0); +} #else #error This operating system is unsupported for bass plugins. #endif diff --git a/src/hardware_functions.cpp b/src/hardware_functions.cpp index 29823cdf..ebba6ab7 100644 --- a/src/hardware_functions.cpp +++ b/src/hardware_functions.cpp @@ -50,6 +50,13 @@ QString get_hdid() return "gxcpz32sa9fnwic92mfbs0"; } +#elif defined __APPLE__ +QString get_hdid() +{ + //hdids are broken at this point anyways + return "just a mac passing by"; +} + #else #error This operating system is unsupported for hardware functions. -- cgit From 110751ac39ac2f6911e67d6ac4319ceebea6f783 Mon Sep 17 00:00:00 2001 From: David Skoland Date: Wed, 26 Dec 2018 22:19:49 +0100 Subject: added dynamic loading of qapng and fixed mac sound --- Attorney_Online.pro | 2 ++ src/aooptionsdialog.cpp | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Attorney_Online.pro b/Attorney_Online.pro index 97236fb0..c7bf3d80 100644 --- a/Attorney_Online.pro +++ b/Attorney_Online.pro @@ -26,3 +26,5 @@ CONFIG += c++11 RESOURCES += resources.qrc win32:RC_ICONS = resource/logo.ico + +QTPLUGIN += qapng diff --git a/src/aooptionsdialog.cpp b/src/aooptionsdialog.cpp index b1d0974c..cd69c76c 100644 --- a/src/aooptionsdialog.cpp +++ b/src/aooptionsdialog.cpp @@ -515,7 +515,7 @@ bool AOOptionsDialog::needs_default_audiodev() #elif defined __APPLE__ bool AOOptionsDialog::needs_default_audiodev() { - return false; + return true; } #else #error This operating system is not supported. -- cgit From 55a3bfadb908d5e2e8a482db7fc8e9427153c8f3 Mon Sep 17 00:00:00 2001 From: David Skoland Date: Wed, 26 Dec 2018 22:45:44 +0100 Subject: Update README_BUILD.md --- README_BUILD.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README_BUILD.md b/README_BUILD.md index da13bdc1..685699c9 100644 --- a/README_BUILD.md +++ b/README_BUILD.md @@ -39,4 +39,5 @@ BASS and BASS Opus only comes as dynamic libraries and is not open-source. That For Discord RPC, you can download prebuilt static libraries for your platform. Just put them in lib/. For Qt Apng Plugin, you need to compile it statically. This guide does not go into detail how to configure this to build a static library. You may have to add Q_IMPORT_PLUGIN(ApngImagePlugin); in main.cpp. See more about importing static plugins here: http://doc.qt.io/qt-5/plugins-howto.html#static-plugins +It's also possible to just link this dynamically. -- cgit From ec1057b5d7e1d39963275bc2cbd79a53cf6f3f5c Mon Sep 17 00:00:00 2001 From: David Skoland Date: Wed, 26 Dec 2018 22:48:44 +0100 Subject: added dynamic linking fix script for macos --- scripts/fix_dynamic_linking_macos.sh | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 scripts/fix_dynamic_linking_macos.sh diff --git a/scripts/fix_dynamic_linking_macos.sh b/scripts/fix_dynamic_linking_macos.sh new file mode 100644 index 00000000..a786a55a --- /dev/null +++ b/scripts/fix_dynamic_linking_macos.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +#this script relinks dynamic libraries so the .app file can be distributed as standalone + +install_name_tool -id @executable_path/../Frameworks/libbass.dylib ../bin/Attorney_Online.app/Contents/Frameworks/libbass.dylib + +install_name_tool -id @executable_path/../Frameworks/libbassopus.dylib ../bin/Attorney_Online.app/Contents/Frameworks/libbassopus.dylib + +install_name_tool -id @executable_path/../Frameworks/libdiscord-rpc.dylib ../bin/Attorney_Online.app/Contents/Frameworks/libdiscord-rpc.dylib + +install_name_tool -id @executable_path/../Frameworks/libqapng.dylib ../bin/Attorney_Online.app/Contents/Frameworks/libqapng.dylib + +install_name_tool -change @loader_path/libbass.dylib @executable_path/../Frameworks/libbass.dylib ../bin/Attorney_Online.app/Contents/MacOS/Attorney_Online + +install_name_tool -change @rpath/libdiscord-rpc.dylib @executable_path/../Frameworks/libdiscord-rpc.dylib ../bin/Attorney_Online.app/Contents/MacOS/Attorney_Online + -- cgit