aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorDavid Skoland <davidskoland@gmail.com>2018-12-26 16:43:08 +0100
committerDavid Skoland <davidskoland@gmail.com>2018-12-26 16:43:08 +0100
commit00cfd2750d39795e4c205aee2a33b92b1da2524d (patch)
tree839c1129418ca8fefe41e6814917f9dabb6efa4b /include
parent6f1bce5882676ea7affe717a2f5a00b8c3b7fe12 (diff)
moved headers into include and cpp files into src + logo into resource
Diffstat (limited to 'include')
-rw-r--r--include/aoapplication.h318
-rw-r--r--include/aoblipplayer.h30
-rw-r--r--include/aobutton.h22
-rw-r--r--include/aocaseannouncerdialog.h45
-rw-r--r--include/aocharbutton.h44
-rw-r--r--include/aocharmovie.h57
-rw-r--r--include/aoemotebutton.h36
-rw-r--r--include/aoevidencebutton.h50
-rw-r--r--include/aoevidencedisplay.h32
-rw-r--r--include/aoimage.h25
-rw-r--r--include/aolineedit.h26
-rw-r--r--include/aomovie.h34
-rw-r--r--include/aomusicplayer.h28
-rw-r--r--include/aooptionsdialog.h115
-rw-r--r--include/aopacket.h32
-rw-r--r--include/aoscene.h27
-rw-r--r--include/aosfxplayer.h28
-rw-r--r--include/aotextarea.h24
-rw-r--r--include/aotextedit.h23
-rw-r--r--include/chatlogpiece.h31
-rw-r--r--include/courtroom.h671
-rw-r--r--include/datatypes.h119
-rw-r--r--include/debug_functions.h10
-rw-r--r--include/discord-rpc.h85
-rw-r--r--include/discord_rich_presence.h34
-rw-r--r--include/encryption_functions.h15
-rw-r--r--include/file_functions.h12
-rw-r--r--include/hardware_functions.h10
-rw-r--r--include/hex_functions.h17
-rw-r--r--include/lobby.h95
-rw-r--r--include/misc_functions.h9
-rw-r--r--include/networkmanager.h86
-rw-r--r--include/text_file_functions.h13
33 files changed, 2203 insertions, 0 deletions
diff --git a/include/aoapplication.h b/include/aoapplication.h
new file mode 100644
index 0000000..f420733
--- /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 <QApplication>
+#include <QVector>
+#include <QFile>
+#include <QSettings>
+
+#include <QDebug>
+#include <QRect>
+#include <QDesktopWidget>
+
+#include <QCryptographicHash>
+
+#include <QDir>
+#include <QStandardPaths>
+
+#include <QTextStream>
+#include <QStringList>
+#include <QColor>
+
+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<server_type>& get_favorite_list() {return favorite_list;}
+ void add_favorite_server(int p_server);
+
+ void set_server_list();
+ QVector<server_type>& 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<server_type> 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_type> server_list;
+ QVector<server_type> 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 0000000..aebba77
--- /dev/null
+++ b/include/aoblipplayer.h
@@ -0,0 +1,30 @@
+#ifndef AOBLIPPLAYER_H
+#define AOBLIPPLAYER_H
+
+#include "bass.h"
+#include "aoapplication.h"
+
+#include <QWidget>
+#include <string.h>
+#include <QDebug>
+
+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 0000000..4b7209a
--- /dev/null
+++ b/include/aobutton.h
@@ -0,0 +1,22 @@
+#ifndef AOBUTTON_H
+#define AOBUTTON_H
+
+#include "aoapplication.h"
+
+#include <QPushButton>
+#include <QDebug>
+
+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 0000000..a238c3f
--- /dev/null
+++ b/include/aocaseannouncerdialog.h
@@ -0,0 +1,45 @@
+#ifndef AOCASEANNOUNCERDIALOG_H
+#define AOCASEANNOUNCERDIALOG_H
+
+#include "aoapplication.h"
+#include "courtroom.h"
+
+#include <QtWidgets/QDialog>
+#include <QDialogButtonBox>
+#include <QtWidgets/QVBoxLayout>
+#include <QtWidgets/QFormLayout>
+#include <QtWidgets/QCheckBox>
+#include <QtWidgets/QLabel>
+#include <QtWidgets/QLineEdit>
+
+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 0000000..f372cdf
--- /dev/null
+++ b/include/aocharbutton.h
@@ -0,0 +1,44 @@
+#ifndef AOCHARBUTTON_H
+#define AOCHARBUTTON_H
+
+#include "aoapplication.h"
+#include "aoimage.h"
+
+#include <QPushButton>
+#include <QString>
+#include <QWidget>
+#include <QFile>
+
+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 0000000..7ef7da3
--- /dev/null
+++ b/include/aocharmovie.h
@@ -0,0 +1,57 @@
+#ifndef AOCHARMOVIE_H
+#define AOCHARMOVIE_H
+
+#include <QMovie>
+#include <QLabel>
+#include <QTimer>
+#include <QDebug>
+#include <QImageReader>
+
+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<QImage> 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 0000000..c99a73b
--- /dev/null
+++ b/include/aoemotebutton.h
@@ -0,0 +1,36 @@
+#ifndef AOEMOTEBUTTON_H
+#define AOEMOTEBUTTON_H
+
+#include "aoapplication.h"
+
+#include <QPushButton>
+#include <QDebug>
+
+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 0000000..27fb84b
--- /dev/null
+++ b/include/aoevidencebutton.h
@@ -0,0 +1,50 @@
+#ifndef AOEVIDENCEBUTTON_H
+#define AOEVIDENCEBUTTON_H
+
+#include "aoapplication.h"
+#include "aoimage.h"
+
+#include <QPushButton>
+#include <QString>
+#include <QDebug>
+
+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 0000000..13ca00d
--- /dev/null
+++ b/include/aoevidencedisplay.h
@@ -0,0 +1,32 @@
+#ifndef AOEVIDENCEDISPLAY_H
+#define AOEVIDENCEDISPLAY_H
+
+#include "aoapplication.h"
+#include "aosfxplayer.h"
+
+#include <QLabel>
+#include <QMovie>
+#include <QDebug>
+
+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 0000000..4713be0
--- /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 <QLabel>
+#include <QDebug>
+
+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 0000000..ce17680
--- /dev/null
+++ b/include/aolineedit.h
@@ -0,0 +1,26 @@
+#ifndef AOLINEEDIT_H
+#define AOLINEEDIT_H
+
+#include <QLineEdit>
+#include <QMouseEvent>
+
+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 0000000..1f278bf
--- /dev/null
+++ b/include/aomovie.h
@@ -0,0 +1,34 @@
+#ifndef AOMOVIE_H
+#define AOMOVIE_H
+
+#include <QLabel>
+#include <QMovie>
+
+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 0000000..560a7f9
--- /dev/null
+++ b/include/aomusicplayer.h
@@ -0,0 +1,28 @@
+#ifndef AOMUSICPLAYER_H
+#define AOMUSICPLAYER_H
+
+#include "bass.h"
+#include "aoapplication.h"
+
+#include <QWidget>
+#include <string.h>
+#include <QDebug>
+
+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 0000000..a65e3f5
--- /dev/null
+++ b/include/aooptionsdialog.h
@@ -0,0 +1,115 @@
+#ifndef AOOPTIONSDIALOG_H
+#define AOOPTIONSDIALOG_H
+
+#include "aoapplication.h"
+#include "bass.h"
+
+#include <QtCore/QVariant>
+#include <QtWidgets/QApplication>
+#include <QtWidgets/QCheckBox>
+#include <QtWidgets/QComboBox>
+#include <QtWidgets/QDialog>
+#include <QtWidgets/QDialogButtonBox>
+#include <QtWidgets/QFormLayout>
+#include <QtWidgets/QFrame>
+#include <QtWidgets/QLabel>
+#include <QtWidgets/QLineEdit>
+#include <QtWidgets/QPlainTextEdit>
+#include <QtWidgets/QSpinBox>
+#include <QtWidgets/QTabWidget>
+#include <QtWidgets/QVBoxLayout>
+#include <QtWidgets/QWidget>
+
+#include <QDirIterator>
+#include <QTextStream>
+
+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 0000000..21f6e0f
--- /dev/null
+++ b/include/aopacket.h
@@ -0,0 +1,32 @@
+#ifndef AOPACKET_H
+#define AOPACKET_H
+
+#include <QString>
+#include <QStringList>
+#include <QDebug>
+
+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 0000000..b58c0fd
--- /dev/null
+++ b/include/aoscene.h
@@ -0,0 +1,27 @@
+#ifndef AOSCENE_H
+#define AOSCENE_H
+
+#include <QLabel>
+#include <QDebug>
+#include <QMovie>
+
+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 0000000..30cbe9d
--- /dev/null
+++ b/include/aosfxplayer.h
@@ -0,0 +1,28 @@
+#ifndef AOSFXPLAYER_H
+#define AOSFXPLAYER_H
+
+#include "bass.h"
+#include "aoapplication.h"
+
+#include <QWidget>
+#include <string.h>
+#include <QDebug>
+
+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 0000000..d44596b
--- /dev/null
+++ b/include/aotextarea.h
@@ -0,0 +1,24 @@
+#ifndef AOTEXTAREA_H
+#define AOTEXTAREA_H
+
+#include <QTextBrowser>
+#include <QScrollBar>
+#include <QTextCursor>
+#include <QRegExp>
+#include <QDebug>
+
+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 0000000..85909c6
--- /dev/null
+++ b/include/aotextedit.h
@@ -0,0 +1,23 @@
+#ifndef AOTEXTEDIT_H
+#define AOTEXTEDIT_H
+
+#include <QPlainTextEdit>
+
+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 0000000..34c5926
--- /dev/null
+++ b/include/chatlogpiece.h
@@ -0,0 +1,31 @@
+#ifndef CHATLOGPIECE_H
+#define CHATLOGPIECE_H
+
+#include <QString>
+#include <QDateTime>
+
+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 0000000..ec9f9ef
--- /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 <QMainWindow>
+#include <QLineEdit>
+#include <QPlainTextEdit>
+#include <QListWidget>
+#include <QCheckBox>
+#include <QComboBox>
+#include <QSlider>
+#include <QVector>
+#include <QCloseEvent>
+#include <QSignalMapper>
+#include <QMap>
+#include <QTextBrowser>
+#include <QSpinBox>
+
+#include <QDebug>
+#include <QScrollBar>
+#include <QRegExp>
+#include <QBrush>
+#include <QTextCharFormat>
+#include <QFont>
+#include <QInputDialog>
+#include <QFileDialog>
+
+#include <stack>
+
+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<evi_type> &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_COLOURS> 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_type> char_list;
+ QVector<evi_type> evidence_list;
+ QVector<QString> music_list;
+ QVector<QString> area_list;
+
+ QVector<int> arup_players;
+ QVector<QString> arup_statuses;
+ QVector<QString> arup_cms;
+ QVector<QString> arup_locks;
+
+ QSignalMapper *char_button_mapper;
+
+ QVector<chatlogpiece> ic_chatlog_history;
+
+ // These map music row items and area row items to their actual IDs.
+ QVector<int> music_row_to_number;
+ QVector<int> 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<int, bool> mute_map;
+
+ //QVector<int> 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<evi_type> 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<AOEmoteButton*> 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<AOEvidenceButton*> 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<AOCharButton*> ui_char_button_list;
+ QVector<AOCharButton*> 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 0000000..aaa5de5
--- /dev/null
+++ b/include/datatypes.h
@@ -0,0 +1,119 @@
+#ifndef DATATYPES_H
+#define DATATYPES_H
+
+#include <QString>
+
+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 0000000..160274c
--- /dev/null
+++ b/include/debug_functions.h
@@ -0,0 +1,10 @@
+#ifndef DEBUG_FUNCTIONS_H
+#define DEBUG_FUNCTIONS_H
+
+#include <QString>
+#include <QMessageBox>
+
+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 0000000..feb874b
--- /dev/null
+++ b/include/discord-rpc.h
@@ -0,0 +1,85 @@
+#pragma once
+#include <stdint.h>
+
+// 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 0000000..e7ecc6e
--- /dev/null
+++ b/include/discord_rich_presence.h
@@ -0,0 +1,34 @@
+#ifndef DISCORD_RICH_PRESENCE_H
+#define DISCORD_RICH_PRESENCE_H
+
+#include <cstring>
+#include <ctime>
+#include <QDebug>
+#include <string>
+#include <discord-rpc.h>
+
+#include <cstring>
+#include <ctime>
+
+#include <QDebug>
+
+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 0000000..dc67d12
--- /dev/null
+++ b/include/encryption_functions.h
@@ -0,0 +1,15 @@
+#ifndef ENCRYPTION_FUNCTIONS_H
+#define ENCRYPTION_FUNCTIONS_H
+
+#include <QString>
+
+#include <cstddef>
+#include <stdlib.h>
+#include <sstream>
+#include <iomanip>
+#include <QVector>
+
+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 0000000..6937ed8
--- /dev/null
+++ b/include/file_functions.h
@@ -0,0 +1,12 @@
+#ifndef FILE_FUNCTIONS_H
+#define FILE_FUNCTIONS_H
+
+#include <QFileInfo>
+#include <QDir>
+#include <QString>
+
+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 0000000..3fcb27c
--- /dev/null
+++ b/include/hardware_functions.h
@@ -0,0 +1,10 @@
+#ifndef HARDWARE_FUNCTIONS_H
+#define HARDWARE_FUNCTIONS_H
+
+#include <QString>
+
+#include <stdio.h>
+
+QString get_hdid();
+
+#endif // HARDWARE_FUNCTIONS_H
diff --git a/include/hex_functions.h b/include/hex_functions.h
new file mode 100644
index 0000000..285f096
--- /dev/null
+++ b/include/hex_functions.h
@@ -0,0 +1,17 @@
+#ifndef HEX_OPERATIONS_H
+#define HEX_OPERATIONS_H
+
+#include <bitset>
+#include <cstdint>
+#include <iostream>
+#include <algorithm>
+#include <string>
+#include <iomanip>
+#include <sstream>
+
+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 0000000..19276a7
--- /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 <QMainWindow>
+#include <QListWidget>
+#include <QLabel>
+#include <QPlainTextEdit>
+#include <QLineEdit>
+#include <QProgressBar>
+#include <QTextBrowser>
+
+#include <QDebug>
+#include <QScrollBar>
+
+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 0000000..026c635
--- /dev/null
+++ b/include/misc_functions.h
@@ -0,0 +1,9 @@
+#ifndef MISC_FUNCTIONS_H
+#define MISC_FUNCTIONS_H
+
+#include <QTime>
+#include <QCoreApplication>
+
+void delay(int p_milliseconds);
+
+#endif // MISC_FUNCTIONS_H
diff --git a/include/networkmanager.h b/include/networkmanager.h
new file mode 100644
index 0000000..e28abfd
--- /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 <QTcpSocket>
+#include <QDnsLookup>
+#include <QTime>
+#include <QTimer>
+#include <cstring>
+
+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 0000000..119f38e
--- /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 <QTextStream>
+#include <QStringList>
+#include <QVector>
+#include <QDebug>
+#include <QColor>
+#include <QSettings>
+
+#endif // TEXT_FILE_FUNCTIONS_H