Merge branch 'master' into feature/mounting
This commit is contained in:
		
						commit
						9ecd7c453c
					
				@ -3,7 +3,7 @@ QT += core gui widgets network
 | 
			
		||||
TARGET = Attorney_Online
 | 
			
		||||
TEMPLATE = app
 | 
			
		||||
 | 
			
		||||
VERSION = 2.9.0.0
 | 
			
		||||
VERSION = 2.9.1.0
 | 
			
		||||
 | 
			
		||||
INCLUDEPATH += $$PWD/include
 | 
			
		||||
DESTDIR = $$PWD/bin
 | 
			
		||||
 | 
			
		||||
@ -1 +1 @@
 | 
			
		||||
Subproject commit 126447457906992e0096c4c9416f2b1f7986ff40
 | 
			
		||||
Subproject commit 7c036c09ddfadc2680a2c5dbfa188dc98142a427
 | 
			
		||||
@ -299,6 +299,9 @@ public:
 | 
			
		||||
  // Returns whether the user would like to have custom shownames on by default.
 | 
			
		||||
  bool get_showname_enabled_by_default();
 | 
			
		||||
 | 
			
		||||
  //Returns the showname the user may have set in config.ini.
 | 
			
		||||
  QString get_default_showname();
 | 
			
		||||
 | 
			
		||||
  // Returns the list of words in callwords.ini
 | 
			
		||||
  QStringList get_call_words();
 | 
			
		||||
 | 
			
		||||
@ -401,10 +404,6 @@ public:
 | 
			
		||||
  // 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);
 | 
			
		||||
 | 
			
		||||
@ -513,6 +512,9 @@ public:
 | 
			
		||||
  // Get if the theme is animated
 | 
			
		||||
  bool get_animated_theme();
 | 
			
		||||
 | 
			
		||||
  // Get the default scaling method
 | 
			
		||||
  QString get_default_scaling();
 | 
			
		||||
 | 
			
		||||
  // Get a list of custom mount paths
 | 
			
		||||
  QStringList get_mount_paths();
 | 
			
		||||
 | 
			
		||||
@ -525,6 +527,16 @@ public:
 | 
			
		||||
  // The file name of the log file in base/logs.
 | 
			
		||||
  QString log_filename;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * @brief A QString of an URL that defines the content repository
 | 
			
		||||
   *        send by the server.
 | 
			
		||||
   *
 | 
			
		||||
   * @details Introduced in Version 2.9.2.
 | 
			
		||||
   *        Addresses the issue of contenturl devlivery for WebAO
 | 
			
		||||
   *        without relying on someone adding the link manually.
 | 
			
		||||
   */
 | 
			
		||||
  QString asset_url;
 | 
			
		||||
 | 
			
		||||
  void initBASS();
 | 
			
		||||
  static void load_bass_opus_plugin();
 | 
			
		||||
  static void CALLBACK BASSreset(HSTREAM handle, DWORD channel, DWORD data,
 | 
			
		||||
@ -537,7 +549,7 @@ public:
 | 
			
		||||
private:
 | 
			
		||||
  const int RELEASE = 2;
 | 
			
		||||
  const int MAJOR_VERSION = 9;
 | 
			
		||||
  const int MINOR_VERSION = 0;
 | 
			
		||||
  const int MINOR_VERSION = 1;
 | 
			
		||||
 | 
			
		||||
  QVector<server_type> server_list;
 | 
			
		||||
  QVector<server_type> favorite_list;
 | 
			
		||||
 | 
			
		||||
@ -11,7 +11,7 @@
 | 
			
		||||
 | 
			
		||||
class AOImage : public QLabel {
 | 
			
		||||
public:
 | 
			
		||||
  AOImage(QWidget *parent, AOApplication *p_ao_app);
 | 
			
		||||
  AOImage(QWidget *parent, AOApplication *p_ao_app, bool make_static = false);
 | 
			
		||||
  ~AOImage();
 | 
			
		||||
 | 
			
		||||
  QWidget *m_parent;
 | 
			
		||||
@ -20,6 +20,8 @@ public:
 | 
			
		||||
 | 
			
		||||
  QString path;
 | 
			
		||||
 | 
			
		||||
  bool is_static = false;
 | 
			
		||||
 | 
			
		||||
  bool set_image(QString p_image, QString p_misc = "");
 | 
			
		||||
  void set_size_and_pos(QString identifier);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -53,6 +53,7 @@ public:
 | 
			
		||||
  bool force_continuous = false;
 | 
			
		||||
  Qt::TransformationMode transform_mode = Qt::FastTransformation; // transformation mode to use for this image
 | 
			
		||||
  bool stretch = false; // Should we stretch/squash this image to fill the screen?
 | 
			
		||||
  bool masked = true; // Set a mask to the dimensions of the widget?
 | 
			
		||||
 | 
			
		||||
  // Set the movie's image to provided paths, preparing for playback.
 | 
			
		||||
  void start_playback(QString p_image);
 | 
			
		||||
@ -104,10 +105,6 @@ protected:
 | 
			
		||||
 | 
			
		||||
  QElapsedTimer actual_time;
 | 
			
		||||
 | 
			
		||||
  // Usually used to turn seconds into milliseconds such as for [Time] tag in
 | 
			
		||||
  // char.ini (which is no longer used)
 | 
			
		||||
  const int tick_ms = 60;
 | 
			
		||||
 | 
			
		||||
  // These are the X and Y values before they are fixed based on the sprite's
 | 
			
		||||
  // width.
 | 
			
		||||
  int x = 0;
 | 
			
		||||
 | 
			
		||||
@ -25,7 +25,7 @@ public:
 | 
			
		||||
  int loop_end[4] = {0, 0, 0, 0};
 | 
			
		||||
 | 
			
		||||
public slots:
 | 
			
		||||
  void play(QString p_song, int channel = 0, bool loop = false,
 | 
			
		||||
  int play(QString p_song, int channel = 0, bool loop = false,
 | 
			
		||||
            int effect_flags = 0);
 | 
			
		||||
  void stop(int channel = 0);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -79,6 +79,8 @@ private:
 | 
			
		||||
  QLabel *ui_username_lbl;
 | 
			
		||||
  QLabel *ui_showname_lbl;
 | 
			
		||||
  QCheckBox *ui_showname_cb;
 | 
			
		||||
  QLabel *ui_default_showname_lbl;
 | 
			
		||||
  QLineEdit *ui_default_showname_textbox;
 | 
			
		||||
  QFrame *ui_net_divider;
 | 
			
		||||
  QLabel *ui_ms_lbl;
 | 
			
		||||
  QLineEdit *ui_ms_textbox;
 | 
			
		||||
@ -86,6 +88,8 @@ private:
 | 
			
		||||
  QCheckBox *ui_discord_cb;
 | 
			
		||||
  QLabel *ui_language_label;
 | 
			
		||||
  QComboBox *ui_language_combobox;
 | 
			
		||||
  QLabel *ui_scaling_label;
 | 
			
		||||
  QComboBox *ui_scaling_combobox;
 | 
			
		||||
 | 
			
		||||
  QLabel *ui_shake_lbl;
 | 
			
		||||
  QCheckBox *ui_shake_cb;
 | 
			
		||||
 | 
			
		||||
@ -226,13 +226,16 @@ public:
 | 
			
		||||
  // Parse the chat message packet and unpack it into the m_chatmessage[ITEM] format
 | 
			
		||||
  void unpack_chatmessage(QStringList p_contents);
 | 
			
		||||
 | 
			
		||||
  // Skip the current queue, adding all the queue messages to the logs if desynchronized logs are disabled
 | 
			
		||||
  void skip_chatmessage_queue();
 | 
			
		||||
 | 
			
		||||
  enum LogMode {
 | 
			
		||||
    IO_ONLY,
 | 
			
		||||
    DISPLAY_ONLY,
 | 
			
		||||
    DISPLAY_AND_IO
 | 
			
		||||
  };
 | 
			
		||||
  // Log the message contents and information such as evidence presenting etc. into the log file, the IC log, or both.
 | 
			
		||||
  void log_chatmessage(QString f_message, int f_char_id, QString f_showname = "", int f_color = 0, LogMode f_log_mode=IO_ONLY);
 | 
			
		||||
  void log_chatmessage(QString f_message, int f_char_id, QString f_showname = "", QString f_char = "", QString f_objection_mod = "", int f_evi_id = 0, int f_color = 0, LogMode f_log_mode=IO_ONLY);
 | 
			
		||||
 | 
			
		||||
  // Log the message contents and information such as evidence presenting etc. into the IC logs
 | 
			
		||||
  void handle_callwords();
 | 
			
		||||
@ -752,7 +755,6 @@ private:
 | 
			
		||||
 | 
			
		||||
  QVector<AOCharButton *> ui_char_button_list;
 | 
			
		||||
  QVector<AOCharButton *> ui_char_button_list_filtered;
 | 
			
		||||
  AOImage *ui_selector;
 | 
			
		||||
 | 
			
		||||
  AOButton *ui_back_to_lobby;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -10,6 +10,7 @@
 | 
			
		||||
#include <QTcpSocket>
 | 
			
		||||
#include <QTimer>
 | 
			
		||||
#include <QFileDialog>
 | 
			
		||||
#include <QMessageBox>
 | 
			
		||||
 | 
			
		||||
class DemoServer : public QObject
 | 
			
		||||
{
 | 
			
		||||
@ -24,6 +25,7 @@ public:
 | 
			
		||||
private:
 | 
			
		||||
    void handle_packet(AOPacket packet);
 | 
			
		||||
    void load_demo(QString filename);
 | 
			
		||||
    void reset_state();
 | 
			
		||||
 | 
			
		||||
    QTcpServer* tcp_server;
 | 
			
		||||
    QTcpSocket* client_sock = nullptr;
 | 
			
		||||
 | 
			
		||||
@ -15,19 +15,19 @@ AOCharButton::AOCharButton(QWidget *parent, AOApplication *p_ao_app, int x_pos,
 | 
			
		||||
  this->resize(60, 60);
 | 
			
		||||
  this->move(x_pos, y_pos);
 | 
			
		||||
 | 
			
		||||
  ui_taken = new AOImage(this, ao_app);
 | 
			
		||||
  ui_taken = new AOImage(this, ao_app, true);
 | 
			
		||||
  ui_taken->resize(60, 60);
 | 
			
		||||
  ui_taken->set_image("char_taken");
 | 
			
		||||
  ui_taken->setAttribute(Qt::WA_TransparentForMouseEvents);
 | 
			
		||||
  ui_taken->hide();
 | 
			
		||||
 | 
			
		||||
  ui_passworded = new AOImage(this, ao_app);
 | 
			
		||||
  ui_passworded = new AOImage(this, ao_app, true);
 | 
			
		||||
  ui_passworded->resize(60, 60);
 | 
			
		||||
  ui_passworded->set_image("char_passworded");
 | 
			
		||||
  ui_passworded->setAttribute(Qt::WA_TransparentForMouseEvents);
 | 
			
		||||
  ui_passworded->hide();
 | 
			
		||||
 | 
			
		||||
  ui_selector = new AOImage(parent, ao_app);
 | 
			
		||||
  ui_selector = new AOImage(parent, ao_app, true);
 | 
			
		||||
  ui_selector->resize(62, 62);
 | 
			
		||||
  ui_selector->move(x_pos - 1, y_pos - 1);
 | 
			
		||||
  ui_selector->set_image("char_selector");
 | 
			
		||||
 | 
			
		||||
@ -9,14 +9,14 @@ AOEvidenceButton::AOEvidenceButton(QWidget *p_parent, AOApplication *p_ao_app,
 | 
			
		||||
  ao_app = p_ao_app;
 | 
			
		||||
  m_parent = p_parent;
 | 
			
		||||
 | 
			
		||||
  ui_selected = new AOImage(this, ao_app);
 | 
			
		||||
  ui_selected = new AOImage(this, ao_app, true);
 | 
			
		||||
  ui_selected->resize(p_w, p_h);
 | 
			
		||||
  //  ui_selected->move(p_x, p_y);
 | 
			
		||||
  ui_selected->set_image("evidence_selected");
 | 
			
		||||
  ui_selected->setAttribute(Qt::WA_TransparentForMouseEvents);
 | 
			
		||||
  ui_selected->hide();
 | 
			
		||||
 | 
			
		||||
  ui_selector = new AOImage(this, ao_app);
 | 
			
		||||
  ui_selector = new AOImage(this, ao_app, true);
 | 
			
		||||
  ui_selector->resize(p_w, p_h);
 | 
			
		||||
  //  ui_selector->move(p_x - 1, p_y - 1);
 | 
			
		||||
  ui_selector->set_image("evidence_selector");
 | 
			
		||||
 | 
			
		||||
@ -4,18 +4,22 @@
 | 
			
		||||
 | 
			
		||||
#include <QBitmap>
 | 
			
		||||
 | 
			
		||||
AOImage::AOImage(QWidget *parent, AOApplication *p_ao_app) : QLabel(parent)
 | 
			
		||||
AOImage::AOImage(QWidget *parent, AOApplication *p_ao_app, bool make_static) : QLabel(parent)
 | 
			
		||||
{
 | 
			
		||||
  m_parent = parent;
 | 
			
		||||
  ao_app = p_ao_app;
 | 
			
		||||
  movie = new QMovie();
 | 
			
		||||
  connect(movie, &QMovie::frameChanged, [=]{
 | 
			
		||||
    QPixmap f_pixmap = movie->currentPixmap();
 | 
			
		||||
    f_pixmap =
 | 
			
		||||
        f_pixmap.scaled(this->size(), Qt::IgnoreAspectRatio);
 | 
			
		||||
    this->setPixmap(f_pixmap);
 | 
			
		||||
    this->setMask(f_pixmap.mask());
 | 
			
		||||
  });
 | 
			
		||||
  is_static = make_static;
 | 
			
		||||
  if (!is_static) // Only create the QMovie if we're non-static
 | 
			
		||||
  {
 | 
			
		||||
    movie = new QMovie(this);
 | 
			
		||||
    connect(movie, &QMovie::frameChanged, [=]{
 | 
			
		||||
      QPixmap f_pixmap = movie->currentPixmap();
 | 
			
		||||
      f_pixmap =
 | 
			
		||||
          f_pixmap.scaled(this->size(), Qt::IgnoreAspectRatio);
 | 
			
		||||
      this->setPixmap(f_pixmap);
 | 
			
		||||
      this->setMask(f_pixmap.mask());
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
AOImage::~AOImage() {}
 | 
			
		||||
@ -23,19 +27,21 @@ AOImage::~AOImage() {}
 | 
			
		||||
bool AOImage::set_image(QString p_image, QString p_misc)
 | 
			
		||||
{
 | 
			
		||||
  p_image = ao_app->get_image(p_image, ao_app->current_theme, ao_app->get_subtheme(),
 | 
			
		||||
                             ao_app->default_theme, p_misc, "", "", !ao_app->get_animated_theme());
 | 
			
		||||
                             ao_app->default_theme, p_misc, "", "", is_static || !ao_app->get_animated_theme());
 | 
			
		||||
 | 
			
		||||
  if (!file_exists(p_image)) {
 | 
			
		||||
    qDebug() << "Warning: Image" << p_image << "not found! Can't set!";
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
  path = p_image;
 | 
			
		||||
  movie->stop();
 | 
			
		||||
  movie->setFileName(path);
 | 
			
		||||
  if (ao_app->get_animated_theme() && movie->frameCount() > 1) {
 | 
			
		||||
    movie->start();
 | 
			
		||||
  if (!is_static) {
 | 
			
		||||
    movie->stop();
 | 
			
		||||
    movie->setFileName(path);
 | 
			
		||||
    if (ao_app->get_animated_theme() && movie->frameCount() > 1) {
 | 
			
		||||
      movie->start();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  else {
 | 
			
		||||
  if (is_static || !ao_app->get_animated_theme() || movie->frameCount() <= 1) {
 | 
			
		||||
    QPixmap f_pixmap(path);
 | 
			
		||||
 | 
			
		||||
    f_pixmap =
 | 
			
		||||
 | 
			
		||||
@ -98,9 +98,10 @@ void AOLayer::center_pixmap(QPixmap f_pixmap) {
 | 
			
		||||
      x + (f_w - f_pixmap.width()) / 2,
 | 
			
		||||
      y + (f_h - f_pixmap.height())); // Always center horizontally, always put
 | 
			
		||||
                                      // at the bottom vertically
 | 
			
		||||
  this->setMask(
 | 
			
		||||
      QRegion((f_pixmap.width() - f_w) / 2, (f_pixmap.height() - f_h) / 2, f_w,
 | 
			
		||||
              f_h)); // make sure we don't escape the area we've been given
 | 
			
		||||
  if (masked)
 | 
			
		||||
      this->setMask(
 | 
			
		||||
          QRegion((f_pixmap.width() - f_w) / 2, (f_pixmap.height() - f_h) / 2, f_w,
 | 
			
		||||
                  f_h)); // make sure we don't escape the area we've been given
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void AOLayer::combo_resize(int w, int h)
 | 
			
		||||
@ -145,6 +146,7 @@ void BackgroundLayer::load_image(QString p_filename)
 | 
			
		||||
  qDebug() << "[BackgroundLayer] BG loaded: " << p_filename;
 | 
			
		||||
#endif
 | 
			
		||||
  start_playback(ao_app->get_image_suffix(ao_app->get_background_path(p_filename)));
 | 
			
		||||
  play();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CharLayer::load_image(QString p_filename, QString p_charname,
 | 
			
		||||
@ -156,7 +158,7 @@ void CharLayer::load_image(QString p_filename, QString p_charname,
 | 
			
		||||
  transform_mode = ao_app->get_scaling(
 | 
			
		||||
      ao_app->get_emote_property(p_charname, p_filename, "scaling"));
 | 
			
		||||
  stretch = ao_app->get_emote_property(p_charname, p_filename, "stretch")
 | 
			
		||||
                .startsWith(true);
 | 
			
		||||
                .startsWith("true");
 | 
			
		||||
  if ((p_charname == last_char) &&
 | 
			
		||||
      ((p_filename == last_emote) ||
 | 
			
		||||
       (p_filename.mid(3, -1) == last_emote.mid(3, -1))) &&
 | 
			
		||||
@ -188,28 +190,29 @@ void CharLayer::load_image(QString p_filename, QString p_charname,
 | 
			
		||||
    }
 | 
			
		||||
    is_preanim = true;
 | 
			
		||||
    play_once = true;
 | 
			
		||||
    preanim_timer->start(duration * tick_ms);
 | 
			
		||||
    preanim_timer->start(duration);
 | 
			
		||||
  }
 | 
			
		||||
#ifdef DEBUG_MOVIE
 | 
			
		||||
  qDebug() << "[CharLayer] anim loaded: prefix " << prefix << " filename "
 | 
			
		||||
           << current_emote << " from character: " << p_charname
 | 
			
		||||
           << " continuous: " << continuous;
 | 
			
		||||
#endif
 | 
			
		||||
  QStringList pathlist = {
 | 
			
		||||
      ao_app->get_image_suffix(ao_app->get_character_path(
 | 
			
		||||
          p_charname, prefix + current_emote)), // Default path
 | 
			
		||||
      ao_app->get_image_suffix(ao_app->get_character_path(
 | 
			
		||||
  QVector<VPath> pathlist {
 | 
			
		||||
      ao_app->get_character_path(
 | 
			
		||||
          p_charname, prefix + current_emote), // Default path
 | 
			
		||||
      ao_app->get_character_path(
 | 
			
		||||
          p_charname,
 | 
			
		||||
          prefix + "/" + current_emote)), // Path check if it's categorized
 | 
			
		||||
          prefix + "/" + current_emote), // Path check if it's categorized
 | 
			
		||||
                                          // into a folder
 | 
			
		||||
      ao_app->get_image_suffix(ao_app->get_character_path(
 | 
			
		||||
      ao_app->get_character_path(
 | 
			
		||||
          p_charname,
 | 
			
		||||
          current_emote)), // Just use the non-prefixed image, animated or not
 | 
			
		||||
      ao_app->get_image_suffix(
 | 
			
		||||
          ao_app->get_theme_path("placeholder")), // Theme placeholder path
 | 
			
		||||
      ao_app->get_image_suffix(ao_app->get_theme_path(
 | 
			
		||||
          "placeholder", ao_app->default_theme))}; // Default theme placeholder path
 | 
			
		||||
  start_playback(find_image(pathlist));
 | 
			
		||||
          current_emote), // Just use the non-prefixed image, animated or not
 | 
			
		||||
      VPath(current_emote), // The path by itself after the above fail
 | 
			
		||||
      ao_app->get_theme_path("placeholder"), // Theme placeholder path
 | 
			
		||||
      ao_app->get_theme_path(
 | 
			
		||||
          "placeholder", ao_app->default_theme)}; // Default theme placeholder path
 | 
			
		||||
  start_playback(ao_app->get_image_path(pathlist));
 | 
			
		||||
  play();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SplashLayer::load_image(QString p_filename, QString p_charname,
 | 
			
		||||
@ -218,6 +221,7 @@ void SplashLayer::load_image(QString p_filename, QString p_charname,
 | 
			
		||||
  transform_mode = ao_app->get_misc_scaling(p_miscname);
 | 
			
		||||
  QString final_image = ao_app->get_image(p_filename, ao_app->current_theme, ao_app->get_subtheme(), ao_app->default_theme, p_miscname, p_charname, "placeholder");
 | 
			
		||||
  start_playback(final_image);
 | 
			
		||||
  play();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void EffectLayer::load_image(QString p_filename, bool p_looping)
 | 
			
		||||
@ -229,13 +233,16 @@ void EffectLayer::load_image(QString p_filename, bool p_looping)
 | 
			
		||||
  continuous = false;
 | 
			
		||||
  force_continuous = true;
 | 
			
		||||
  start_playback(p_filename); // handled in its own file before we see it
 | 
			
		||||
  play();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void InterfaceLayer::load_image(QString p_filename, QString p_miscname)
 | 
			
		||||
{
 | 
			
		||||
  last_path = "";
 | 
			
		||||
  stretch = true;
 | 
			
		||||
  QString final_image = ao_app->get_image(p_filename, ao_app->current_theme, ao_app->get_subtheme(), ao_app->default_theme, p_miscname);
 | 
			
		||||
  start_playback(final_image);
 | 
			
		||||
  play();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void StickerLayer::load_image(QString p_charname)
 | 
			
		||||
@ -246,6 +253,7 @@ void StickerLayer::load_image(QString p_charname)
 | 
			
		||||
  transform_mode = ao_app->get_misc_scaling(p_miscname);
 | 
			
		||||
  QString final_image = ao_app->get_image("sticker/" + p_charname, ao_app->current_theme, ao_app->get_subtheme(), ao_app->default_theme, p_miscname);
 | 
			
		||||
  start_playback(final_image);
 | 
			
		||||
  play();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CharLayer::start_playback(QString p_image)
 | 
			
		||||
@ -256,6 +264,7 @@ void CharLayer::start_playback(QString p_image)
 | 
			
		||||
    load_network_effects();
 | 
			
		||||
  else // Use default ini FX
 | 
			
		||||
    load_effects();
 | 
			
		||||
  play();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void AOLayer::start_playback(QString p_image)
 | 
			
		||||
@ -274,7 +283,7 @@ void AOLayer::start_playback(QString p_image)
 | 
			
		||||
  actual_time.restart();
 | 
			
		||||
#endif
 | 
			
		||||
  this->clear();
 | 
			
		||||
  freeze();
 | 
			
		||||
  this->freeze();
 | 
			
		||||
  movie_frames.clear();
 | 
			
		||||
  movie_delays.clear();
 | 
			
		||||
  QString scaling_override =
 | 
			
		||||
@ -328,14 +337,12 @@ void AOLayer::start_playback(QString p_image)
 | 
			
		||||
  }
 | 
			
		||||
  else if (max_frames <= 1) {
 | 
			
		||||
    duration = static_duration;
 | 
			
		||||
    play_once = false;
 | 
			
		||||
#ifdef DEBUG_MOVIE
 | 
			
		||||
    qDebug() << "max_frames is <= 1, using static duration";
 | 
			
		||||
#endif
 | 
			
		||||
  }
 | 
			
		||||
  if (duration > 0 && cull_image == true)
 | 
			
		||||
    shfx_timer->start(duration);
 | 
			
		||||
  play();
 | 
			
		||||
#ifdef DEBUG_MOVIE
 | 
			
		||||
  qDebug() << max_frames << "Setting image to " << image_path
 | 
			
		||||
           << "Time taken to process image:" << actual_time.elapsed();
 | 
			
		||||
@ -346,6 +353,12 @@ void AOLayer::start_playback(QString p_image)
 | 
			
		||||
 | 
			
		||||
void CharLayer::play()
 | 
			
		||||
{
 | 
			
		||||
  if (max_frames <= 1) {
 | 
			
		||||
    if (play_once) {
 | 
			
		||||
      preanim_timer->start(qMax(0, duration));
 | 
			
		||||
    }
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
  play_frame_effect(frame);
 | 
			
		||||
  AOLayer::play();
 | 
			
		||||
}
 | 
			
		||||
@ -353,8 +366,12 @@ void CharLayer::play()
 | 
			
		||||
void AOLayer::play()
 | 
			
		||||
{
 | 
			
		||||
  if (max_frames <= 1) {
 | 
			
		||||
    if (play_once)
 | 
			
		||||
      ticker->start(tick_ms);
 | 
			
		||||
    if (play_once) {
 | 
			
		||||
      if (duration > 0)
 | 
			
		||||
        ticker->start(duration);
 | 
			
		||||
      else
 | 
			
		||||
        preanim_done();
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
      this->freeze();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -13,12 +13,12 @@ AOMusicPlayer::~AOMusicPlayer()
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void AOMusicPlayer::play(QString p_song, int channel, bool loop,
 | 
			
		||||
int AOMusicPlayer::play(QString p_song, int channel, bool loop,
 | 
			
		||||
                         int effect_flags)
 | 
			
		||||
{
 | 
			
		||||
  channel = channel % m_channelmax;
 | 
			
		||||
  if (channel < 0) // wtf?
 | 
			
		||||
    return;
 | 
			
		||||
    return BASS_ERROR_NOCHAN;
 | 
			
		||||
  QString f_path = ao_app->get_real_path(ao_app->get_music_path(p_song));
 | 
			
		||||
 | 
			
		||||
  unsigned int flags = BASS_STREAM_PRESCAN | BASS_STREAM_AUTOFREE |
 | 
			
		||||
@ -125,6 +125,7 @@ void AOMusicPlayer::play(QString p_song, int channel, bool loop,
 | 
			
		||||
 | 
			
		||||
  this->set_looping(loop, channel); // Have to do this here due to any
 | 
			
		||||
                                    // crossfading-related changes, etc.
 | 
			
		||||
  return BASS_ErrorGetCode();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void AOMusicPlayer::stop(int channel)
 | 
			
		||||
 | 
			
		||||
@ -334,6 +334,20 @@ AOOptionsDialog::AOOptionsDialog(QWidget *parent, AOApplication *p_ao_app)
 | 
			
		||||
 | 
			
		||||
  ui_gameplay_form->setWidget(row, QFormLayout::FieldRole, ui_showname_cb);
 | 
			
		||||
 | 
			
		||||
  row +=1;
 | 
			
		||||
  ui_default_showname_lbl = new QLabel(ui_form_layout_widget);
 | 
			
		||||
  ui_default_showname_lbl->setText(tr("Default showname:"));
 | 
			
		||||
  ui_default_showname_lbl->setToolTip(
 | 
			
		||||
              tr("Your showname will be automatically set to this value "
 | 
			
		||||
                 "when you join a server."));
 | 
			
		||||
 | 
			
		||||
  ui_gameplay_form->setWidget(row, QFormLayout::LabelRole, ui_default_showname_lbl);
 | 
			
		||||
 | 
			
		||||
  ui_default_showname_textbox = new QLineEdit(ui_form_layout_widget);
 | 
			
		||||
  ui_default_showname_textbox->setMaxLength(30);
 | 
			
		||||
 | 
			
		||||
  ui_gameplay_form->setWidget(row, QFormLayout::FieldRole, ui_default_showname_textbox);
 | 
			
		||||
 | 
			
		||||
  row += 1;
 | 
			
		||||
  ui_net_divider = new QFrame(ui_form_layout_widget);
 | 
			
		||||
  ui_net_divider->setFrameShape(QFrame::HLine);
 | 
			
		||||
@ -390,6 +404,20 @@ AOOptionsDialog::AOOptionsDialog(QWidget *parent, AOApplication *p_ao_app)
 | 
			
		||||
  ui_gameplay_form->setWidget(row, QFormLayout::FieldRole,
 | 
			
		||||
                              ui_language_combobox);
 | 
			
		||||
 | 
			
		||||
  row += 1;
 | 
			
		||||
  ui_scaling_label = new QLabel(ui_form_layout_widget);
 | 
			
		||||
  ui_scaling_label->setText(tr("Scaling:"));
 | 
			
		||||
  ui_scaling_label->setToolTip(
 | 
			
		||||
        tr("Sets the default scaling method, if there is not one already defined "
 | 
			
		||||
           "specifically for the character."));
 | 
			
		||||
  ui_gameplay_form->setWidget(row, QFormLayout::LabelRole, ui_scaling_label);
 | 
			
		||||
 | 
			
		||||
  ui_scaling_combobox = new QComboBox(ui_form_layout_widget);
 | 
			
		||||
  // Corresponds with Qt::TransformationMode enum. Please don't change the order.
 | 
			
		||||
  ui_scaling_combobox->addItem(tr("Pixel"), "fast");
 | 
			
		||||
  ui_scaling_combobox->addItem(tr("Smooth"), "smooth");
 | 
			
		||||
  ui_gameplay_form->setWidget(row, QFormLayout::FieldRole, ui_scaling_combobox);
 | 
			
		||||
 | 
			
		||||
  row += 1;
 | 
			
		||||
  ui_shake_lbl = new QLabel(ui_form_layout_widget);
 | 
			
		||||
  ui_shake_lbl->setText(tr("Allow Screenshake:"));
 | 
			
		||||
@ -1029,6 +1057,9 @@ void AOOptionsDialog::update_values() {
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  Qt::TransformationMode scaling = ao_app->get_scaling(ao_app->get_default_scaling());
 | 
			
		||||
  ui_scaling_combobox->setCurrentIndex(scaling);
 | 
			
		||||
 | 
			
		||||
  // Let's fill the callwords text edit with the already present callwords.
 | 
			
		||||
  ui_callwords_textbox->document()->clear();
 | 
			
		||||
  foreach (QString callword, ao_app->get_call_words()) {
 | 
			
		||||
@ -1042,7 +1073,7 @@ void AOOptionsDialog::update_values() {
 | 
			
		||||
  ui_log_newline_cb->setChecked(ao_app->get_log_newline());
 | 
			
		||||
  ui_log_timestamp_cb->setChecked(ao_app->get_log_timestamp());
 | 
			
		||||
  ui_log_ic_actions_cb->setChecked(ao_app->get_log_ic_actions());
 | 
			
		||||
  ui_desync_logs_cb->setChecked(ao_app->get_log_timestamp());
 | 
			
		||||
  ui_desync_logs_cb->setChecked(ao_app->is_desyncrhonized_logs_enabled());
 | 
			
		||||
  ui_instant_objection_cb->setChecked(ao_app->is_instant_objection_enabled());
 | 
			
		||||
  ui_showname_cb->setChecked(ao_app->get_showname_enabled_by_default());
 | 
			
		||||
  ui_discord_cb->setChecked(ao_app->is_discord_enabled());
 | 
			
		||||
@ -1077,6 +1108,7 @@ void AOOptionsDialog::update_values() {
 | 
			
		||||
  ui_sfx_volume_spinbox->setValue(ao_app->get_default_sfx());
 | 
			
		||||
  ui_blips_volume_spinbox->setValue(ao_app->get_default_blip());
 | 
			
		||||
  ui_bliprate_spinbox->setValue(ao_app->read_blip_rate());
 | 
			
		||||
  ui_default_showname_textbox->setText(ao_app->get_default_showname());
 | 
			
		||||
 | 
			
		||||
  auto *defaultMount = new QListWidgetItem(tr("%1 (default)")
 | 
			
		||||
                                           .arg(ao_app->get_base_path()));
 | 
			
		||||
@ -1109,9 +1141,11 @@ void AOOptionsDialog::save_pressed()
 | 
			
		||||
  configini->setValue("chat_ratelimit", ui_chat_ratelimit_spinbox->value());
 | 
			
		||||
  configini->setValue("default_username", ui_username_textbox->text());
 | 
			
		||||
  configini->setValue("show_custom_shownames", ui_showname_cb->isChecked());
 | 
			
		||||
  configini->setValue("default_showname", ui_default_showname_textbox->text());
 | 
			
		||||
  configini->setValue("master", ui_ms_textbox->text());
 | 
			
		||||
  configini->setValue("discord", ui_discord_cb->isChecked());
 | 
			
		||||
  configini->setValue("language", ui_language_combobox->currentText().left(2));
 | 
			
		||||
  configini->setValue("default_scaling", ui_scaling_combobox->currentData());
 | 
			
		||||
  configini->setValue("shake", ui_shake_cb->isChecked());
 | 
			
		||||
  configini->setValue("effects", ui_effects_cb->isChecked());
 | 
			
		||||
  configini->setValue("framenetwork", ui_framenetwork_cb->isChecked());
 | 
			
		||||
 | 
			
		||||
@ -10,6 +10,7 @@ void Courtroom::construct_char_select()
 | 
			
		||||
  this->setWindowFlags( (this->windowFlags() | Qt::CustomizeWindowHint) & ~Qt::WindowMaximizeButtonHint);
 | 
			
		||||
 | 
			
		||||
  ui_char_select_background = new AOImage(this, ao_app);
 | 
			
		||||
  ui_char_select_background->setObjectName("ui_char_select_background");
 | 
			
		||||
 | 
			
		||||
  ui_char_list = new QTreeWidget(ui_char_select_background);
 | 
			
		||||
  ui_char_list->setColumnCount(2);
 | 
			
		||||
@ -18,32 +19,38 @@ void Courtroom::construct_char_select()
 | 
			
		||||
  ui_char_list->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
 | 
			
		||||
  ui_char_list->hideColumn(1);
 | 
			
		||||
  ui_char_list->setDropIndicatorShown(true);
 | 
			
		||||
  ui_char_list->setObjectName("ui_char_list");
 | 
			
		||||
 | 
			
		||||
  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_char_buttons->setObjectName("ui_char_buttons");
 | 
			
		||||
 | 
			
		||||
  ui_back_to_lobby = new AOButton(ui_char_select_background, ao_app);
 | 
			
		||||
  ui_back_to_lobby->setObjectName("ui_back_to_lobby");
 | 
			
		||||
 | 
			
		||||
  ui_char_password = new QLineEdit(ui_char_select_background);
 | 
			
		||||
  ui_char_password->setPlaceholderText(tr("Password"));
 | 
			
		||||
  ui_char_password->setObjectName("ui_char_password");
 | 
			
		||||
 | 
			
		||||
  ui_char_select_left = new AOButton(ui_char_select_background, ao_app);
 | 
			
		||||
  ui_char_select_left->setObjectName("ui_char_select_left");
 | 
			
		||||
  ui_char_select_right = new AOButton(ui_char_select_background, ao_app);
 | 
			
		||||
  ui_char_select_right->setObjectName("ui_char_select_right");
 | 
			
		||||
 | 
			
		||||
  ui_spectator = new AOButton(ui_char_select_background, ao_app);
 | 
			
		||||
  ui_spectator->setText(tr("Spectator"));
 | 
			
		||||
  ui_spectator->setObjectName("ui_spectator");
 | 
			
		||||
 | 
			
		||||
  ui_char_search = new QLineEdit(ui_char_select_background);
 | 
			
		||||
  ui_char_search->setPlaceholderText(tr("Search"));
 | 
			
		||||
  ui_char_search->setObjectName("ui_char_search");
 | 
			
		||||
 | 
			
		||||
  ui_char_passworded = new QCheckBox(ui_char_select_background);
 | 
			
		||||
  ui_char_passworded->setText(tr("Passworded"));
 | 
			
		||||
  ui_char_passworded->setObjectName("ui_char_passworded");
 | 
			
		||||
 | 
			
		||||
  ui_char_taken = new QCheckBox(ui_char_select_background);
 | 
			
		||||
  ui_char_taken->setText(tr("Taken"));
 | 
			
		||||
  ui_char_taken->setObjectName("ui_char_taken");
 | 
			
		||||
 | 
			
		||||
  connect(ui_char_list, SIGNAL(itemDoubleClicked(QTreeWidgetItem *, int)),
 | 
			
		||||
          this, SLOT(on_char_list_double_clicked(QTreeWidgetItem *, int)));
 | 
			
		||||
@ -168,14 +175,14 @@ void Courtroom::char_clicked(int n_char)
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (n_char != m_cid) {
 | 
			
		||||
  if (n_char != m_cid || n_char == -1) {
 | 
			
		||||
    ao_app->send_server_packet(
 | 
			
		||||
        new AOPacket("PW#" + ui_char_password->text() + "#%"));
 | 
			
		||||
    ao_app->send_server_packet(
 | 
			
		||||
        new AOPacket("CC#" + QString::number(ao_app->s_pv) + "#" +
 | 
			
		||||
                     QString::number(n_char) + "#" + get_hdid() + "#%"));
 | 
			
		||||
  }
 | 
			
		||||
  else {
 | 
			
		||||
  if (n_char == m_cid || n_char == -1) {
 | 
			
		||||
    update_character(n_char);
 | 
			
		||||
    enter_courtroom();
 | 
			
		||||
    set_courtroom_size();
 | 
			
		||||
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@ -150,7 +150,8 @@ void DemoServer::handle_packet(AOPacket packet)
 | 
			
		||||
    }
 | 
			
		||||
    else if (header == "CC") {
 | 
			
		||||
        client_sock->write("PV#0#CID#-1#%");
 | 
			
		||||
        client_sock->write("CT#DEMO#Demo file loaded. Send /play or > in OOC to begin playback.#1#%");
 | 
			
		||||
        QString packet = "CT#DEMO#" + tr("Demo file loaded. Send /play or > in OOC to begin playback.") + "#1#%";
 | 
			
		||||
        client_sock->write(packet.toUtf8());
 | 
			
		||||
    }
 | 
			
		||||
    else if (header == "CT") {
 | 
			
		||||
        if (contents[1].startsWith("/load"))
 | 
			
		||||
@ -159,14 +160,17 @@ void DemoServer::handle_packet(AOPacket packet)
 | 
			
		||||
          if (path.isEmpty())
 | 
			
		||||
            return;
 | 
			
		||||
          load_demo(path);
 | 
			
		||||
          client_sock->write("CT#DEMO#Demo file loaded. Send /play or > in OOC to begin playback.#1#%");
 | 
			
		||||
          QString packet = "CT#DEMO#" + tr("Demo file loaded. Send /play or > in OOC to begin playback.") + "#1#%";
 | 
			
		||||
          client_sock->write(packet.toUtf8());
 | 
			
		||||
          reset_state();
 | 
			
		||||
        }
 | 
			
		||||
        else if (contents[1].startsWith("/play") || contents[1] == ">")
 | 
			
		||||
        {
 | 
			
		||||
          if (timer->interval() != 0 && !timer->isActive())
 | 
			
		||||
          {
 | 
			
		||||
            timer->start();
 | 
			
		||||
            client_sock->write("CT#DEMO#Resuming playback.#1#%");
 | 
			
		||||
            QString packet = "CT#DEMO#" + tr("Resuming playback.") + "#1#%";
 | 
			
		||||
            client_sock->write(packet.toUtf8());
 | 
			
		||||
          }
 | 
			
		||||
          else
 | 
			
		||||
          {
 | 
			
		||||
@ -180,7 +184,8 @@ void DemoServer::handle_packet(AOPacket packet)
 | 
			
		||||
          int timeleft = timer->remainingTime();
 | 
			
		||||
          timer->stop();
 | 
			
		||||
          timer->setInterval(timeleft);
 | 
			
		||||
          client_sock->write("CT#DEMO#Pausing playback.#1#%");
 | 
			
		||||
          QString packet = "CT#DEMO#" + tr("Pausing playback.") + "#1#%";
 | 
			
		||||
          client_sock->write(packet.toUtf8());
 | 
			
		||||
        }
 | 
			
		||||
        else if (contents[1].startsWith("/max_wait"))
 | 
			
		||||
        {
 | 
			
		||||
@ -194,29 +199,44 @@ void DemoServer::handle_packet(AOPacket packet)
 | 
			
		||||
              if (p_max_wait < 0)
 | 
			
		||||
                p_max_wait = -1;
 | 
			
		||||
              max_wait = p_max_wait;
 | 
			
		||||
              client_sock->write("CT#DEMO#Setting max_wait to ");
 | 
			
		||||
              QString packet = "CT#DEMO#" + tr("Setting max_wait to") + " ";
 | 
			
		||||
              client_sock->write(packet.toUtf8());
 | 
			
		||||
              client_sock->write(QString::number(max_wait).toUtf8());
 | 
			
		||||
              client_sock->write(" milliseconds.#1#%");
 | 
			
		||||
              packet = " " + tr("milliseconds.") + "#1#%";
 | 
			
		||||
              client_sock->write(packet.toUtf8());
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
              client_sock->write("CT#DEMO#Not a valid integer!#1#%");
 | 
			
		||||
              QString packet = "CT#DEMO#" + tr("Not a valid integer!") + "#1#%";
 | 
			
		||||
              client_sock->write(packet.toUtf8());
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
          else
 | 
			
		||||
          {
 | 
			
		||||
            client_sock->write("CT#DEMO#Current max_wait is ");
 | 
			
		||||
            client_sock->write(QString::number(max_wait).toUtf8());
 | 
			
		||||
            client_sock->write(" milliseconds.#1#%");
 | 
			
		||||
 | 
			
		||||
              QString packet = "CT#DEMO#" + tr("Current max_wait is") + " ";
 | 
			
		||||
              client_sock->write(packet.toUtf8());
 | 
			
		||||
              client_sock->write(QString::number(max_wait).toUtf8());
 | 
			
		||||
              packet = " " + tr("milliseconds.") + "#1#%";
 | 
			
		||||
              client_sock->write(packet.toUtf8());
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
        else if (contents[1].startsWith("/reload"))
 | 
			
		||||
        {
 | 
			
		||||
            load_demo(p_path);
 | 
			
		||||
            QString packet = "CT#DEMO#" + tr("Current demo file reloaded. Send /play or > in OOC to begin playback.") + "#1#%";
 | 
			
		||||
            client_sock->write(packet.toUtf8());
 | 
			
		||||
            reset_state();
 | 
			
		||||
        }
 | 
			
		||||
        else if (contents[1].startsWith("/min_wait"))
 | 
			
		||||
        {
 | 
			
		||||
            client_sock->write("CT#DEMO#min_wait is deprecated. Use the client Settings for minimum wait instead!");
 | 
			
		||||
            QString packet = "CT#DEMO#" + tr("min_wait is deprecated. Use the client Settings for minimum wait instead!") + "#1#%";
 | 
			
		||||
            client_sock->write(packet.toUtf8());
 | 
			
		||||
        }
 | 
			
		||||
        else if (contents[1].startsWith("/help"))
 | 
			
		||||
        {
 | 
			
		||||
            client_sock->write("CT#DEMO#Available commands:\nload, play, pause, max_wait, help#1#%");
 | 
			
		||||
            QString packet = "CT#DEMO#" + tr("Available commands:\nload, reload, play, pause, max_wait, help") + "#1#%";
 | 
			
		||||
            client_sock->write(packet.toUtf8());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -227,18 +247,96 @@ void DemoServer::load_demo(QString filename)
 | 
			
		||||
    demo_file.open(QIODevice::ReadOnly);
 | 
			
		||||
    if (!demo_file.isOpen())
 | 
			
		||||
        return;
 | 
			
		||||
    // Clear demo data
 | 
			
		||||
    demo_data.clear();
 | 
			
		||||
    // Set the demo filepath
 | 
			
		||||
    p_path = filename;
 | 
			
		||||
    // Process the demo file
 | 
			
		||||
    QTextStream demo_stream(&demo_file);
 | 
			
		||||
    demo_stream.setCodec("UTF-8");
 | 
			
		||||
    QString line = demo_stream.readLine();
 | 
			
		||||
    while (!line.isNull()) {
 | 
			
		||||
        if (!line.endsWith("%")) {
 | 
			
		||||
        while (!line.endsWith("%")) {
 | 
			
		||||
          line += "\n";
 | 
			
		||||
          line += demo_stream.readLine();
 | 
			
		||||
        }
 | 
			
		||||
        demo_data.enqueue(line);
 | 
			
		||||
        line = demo_stream.readLine();
 | 
			
		||||
    }
 | 
			
		||||
    demo_file.flush();
 | 
			
		||||
    demo_file.close();
 | 
			
		||||
 | 
			
		||||
    // No-shenanigans 2.9.0 demo file with the dreaded demo desync bug detected https://github.com/AttorneyOnline/AO2-Client/pull/496
 | 
			
		||||
    // If we don't start with the SC packet this means user-edited weirdo shenanigans. Don't screw around with those.
 | 
			
		||||
    if (demo_data.head().startsWith("SC#") && demo_data.last().startsWith("wait#")) {
 | 
			
		||||
      qDebug() << "Loaded a broken pre-2.9.1 demo file, with the wait desync issue!";
 | 
			
		||||
      QMessageBox *msgBox = new QMessageBox;
 | 
			
		||||
      msgBox->setAttribute(Qt::WA_DeleteOnClose);
 | 
			
		||||
      msgBox->setTextFormat(Qt::RichText);
 | 
			
		||||
      msgBox->setText("This appears to be a <b>broken</b> pre-2.9.1 demo file with the <a href=https://github.com/AttorneyOnline/AO2-Client/pull/496>wait desync issue</a>!<br>Do you want to correct this file? <i>If you refuse, this demo will be desynchronized!</i>");
 | 
			
		||||
      msgBox->setWindowTitle("Pre-2.9.1 demo detected!");
 | 
			
		||||
      msgBox->setStandardButtons(QMessageBox::NoButton);
 | 
			
		||||
      QTimer::singleShot(2000, msgBox, std::bind(&QMessageBox::setStandardButtons,msgBox,QMessageBox::Yes|QMessageBox::No));
 | 
			
		||||
      int ret = msgBox->exec();
 | 
			
		||||
      QQueue <QString> p_demo_data;
 | 
			
		||||
      switch (ret) {
 | 
			
		||||
        case QMessageBox::Yes:
 | 
			
		||||
          qDebug() << "Making a backup of the broken demo...";
 | 
			
		||||
          QFile::copy(filename, filename + ".backup");
 | 
			
		||||
          while (!demo_data.isEmpty()) {
 | 
			
		||||
            QString current_packet = demo_data.dequeue();
 | 
			
		||||
            // TODO: faster way of doing this, maybe with QtConcurrent's MapReduce methods?
 | 
			
		||||
            if (!current_packet.startsWith("SC#") && current_packet.startsWith("wait#")) {
 | 
			
		||||
              p_demo_data.insert(qMax(1, p_demo_data.size()-1), current_packet);
 | 
			
		||||
              continue;
 | 
			
		||||
            }
 | 
			
		||||
            p_demo_data.enqueue(current_packet);
 | 
			
		||||
          }
 | 
			
		||||
          if (demo_file.open(QIODevice::WriteOnly | QIODevice::Text |
 | 
			
		||||
                         QIODevice::Truncate)) {
 | 
			
		||||
            QTextStream out(&demo_file);
 | 
			
		||||
            out.setCodec("UTF-8");
 | 
			
		||||
            out << p_demo_data.dequeue();
 | 
			
		||||
            for (QString line : p_demo_data) {
 | 
			
		||||
              out << "\n" << line;
 | 
			
		||||
            }
 | 
			
		||||
            demo_file.flush();
 | 
			
		||||
            demo_file.close();
 | 
			
		||||
          }
 | 
			
		||||
          load_demo(filename);
 | 
			
		||||
          break;
 | 
			
		||||
        case QMessageBox::No:
 | 
			
		||||
          // No was clicked
 | 
			
		||||
          break;
 | 
			
		||||
        default:
 | 
			
		||||
          // should never be reached
 | 
			
		||||
          break;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void DemoServer::reset_state()
 | 
			
		||||
{
 | 
			
		||||
    // Reset evidence list
 | 
			
		||||
    client_sock->write("LE##%");
 | 
			
		||||
 | 
			
		||||
    // Reset timers
 | 
			
		||||
    client_sock->write("TI#0#3#0#%");
 | 
			
		||||
    client_sock->write("TI#0#1#0#%");
 | 
			
		||||
    client_sock->write("TI#1#1#0#%");
 | 
			
		||||
    client_sock->write("TI#1#3#0#%");
 | 
			
		||||
    client_sock->write("TI#2#1#0#%");
 | 
			
		||||
    client_sock->write("TI#2#3#0#%");
 | 
			
		||||
    client_sock->write("TI#3#1#0#%");
 | 
			
		||||
    client_sock->write("TI#3#3#0#%");
 | 
			
		||||
    client_sock->write("TI#4#1#0#%");
 | 
			
		||||
    client_sock->write("TI#4#3#0#%");
 | 
			
		||||
 | 
			
		||||
    // Set the BG to default (also breaks up the message queue)
 | 
			
		||||
    client_sock->write("BN#default#wit#%");
 | 
			
		||||
 | 
			
		||||
    // Stop the wait packet timer
 | 
			
		||||
    timer->stop();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void DemoServer::playback()
 | 
			
		||||
@ -251,25 +349,33 @@ void DemoServer::playback()
 | 
			
		||||
    if (current_packet.startsWith("MS#"))
 | 
			
		||||
      elapsed_time = 0;
 | 
			
		||||
 | 
			
		||||
    while (!current_packet.startsWith("wait") && !demo_data.isEmpty()) {
 | 
			
		||||
    while (!current_packet.startsWith("wait#")) {
 | 
			
		||||
        client_sock->write(current_packet.toUtf8());
 | 
			
		||||
        if (demo_data.isEmpty())
 | 
			
		||||
          break;
 | 
			
		||||
        current_packet = demo_data.dequeue();
 | 
			
		||||
    }
 | 
			
		||||
    if (!demo_data.isEmpty()) {
 | 
			
		||||
        AOPacket wait_packet = AOPacket(current_packet);
 | 
			
		||||
 | 
			
		||||
        int duration = wait_packet.get_contents().at(0).toInt();
 | 
			
		||||
        if (max_wait != -1 && duration + elapsed_time > max_wait) {
 | 
			
		||||
          duration = qMax(0, max_wait - elapsed_time);
 | 
			
		||||
          // Skip the difference on the timers
 | 
			
		||||
          emit skip_timers(wait_packet.get_contents().at(0).toInt() - duration);
 | 
			
		||||
        if (max_wait != -1) {
 | 
			
		||||
          if (duration + elapsed_time > max_wait) {
 | 
			
		||||
            duration = qMax(0, max_wait - elapsed_time);
 | 
			
		||||
            // Skip the difference on the timers
 | 
			
		||||
            emit skip_timers(wait_packet.get_contents().at(0).toInt() - duration);
 | 
			
		||||
          }
 | 
			
		||||
          else if (timer->interval() != 0 && duration + elapsed_time > timer->interval()) {
 | 
			
		||||
              duration = qMax(0, timer->interval() - elapsed_time);
 | 
			
		||||
              emit skip_timers(wait_packet.get_contents().at(0).toInt() - duration);
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
        elapsed_time += duration;
 | 
			
		||||
        timer->start(duration);
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
      client_sock->write("CT#DEMO#Reached the end of the demo file. Send /play or > in OOC to restart, or /load to open a new file.#1#%");
 | 
			
		||||
    else {
 | 
			
		||||
      QString end_packet = "CT#DEMO#" + tr("Reached the end of the demo file. Send /play or > in OOC to restart, or /load to open a new file.") + "#1#%";
 | 
			
		||||
      client_sock->write(end_packet.toUtf8());
 | 
			
		||||
      timer->setInterval(0);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -5,11 +5,15 @@
 | 
			
		||||
void Courtroom::initialize_emotes()
 | 
			
		||||
{
 | 
			
		||||
  ui_emotes = new QWidget(this);
 | 
			
		||||
  ui_emotes->setObjectName("ui_emotes");
 | 
			
		||||
 | 
			
		||||
  ui_emote_left = new AOButton(this, ao_app);
 | 
			
		||||
  ui_emote_left->setObjectName("ui_emote_left");
 | 
			
		||||
  ui_emote_right = new AOButton(this, ao_app);
 | 
			
		||||
  ui_emote_right->setObjectName("ui_emote_right");
 | 
			
		||||
 | 
			
		||||
  ui_emote_dropdown = new QComboBox(this);
 | 
			
		||||
  ui_emote_dropdown->setObjectName("ui_emote_dropdown");
 | 
			
		||||
 | 
			
		||||
  connect(ui_emote_left, SIGNAL(clicked()), this,
 | 
			
		||||
          SLOT(on_emote_left_clicked()));
 | 
			
		||||
 | 
			
		||||
@ -3,47 +3,64 @@
 | 
			
		||||
void Courtroom::initialize_evidence()
 | 
			
		||||
{
 | 
			
		||||
  ui_evidence = new AOImage(this, ao_app);
 | 
			
		||||
  ui_evidence->setObjectName("ui_evidence");
 | 
			
		||||
 | 
			
		||||
  // ui_evidence_name = new QLabel(ui_evidence);
 | 
			
		||||
  ui_evidence_name = new AOLineEdit(ui_evidence);
 | 
			
		||||
  ui_evidence_name->setAlignment(Qt::AlignCenter);
 | 
			
		||||
  ui_evidence_name->setFrame(false);
 | 
			
		||||
  ui_evidence_name->setObjectName("ui_evidence_name");
 | 
			
		||||
 | 
			
		||||
  ui_evidence_buttons = new QWidget(ui_evidence);
 | 
			
		||||
  ui_evidence_buttons->setObjectName("ui_evidence_buttons");
 | 
			
		||||
 | 
			
		||||
  ui_evidence_left = new AOButton(ui_evidence, ao_app);
 | 
			
		||||
  ui_evidence_left->setObjectName("ui_evidence_left");
 | 
			
		||||
  ui_evidence_right = new AOButton(ui_evidence, ao_app);
 | 
			
		||||
  ui_evidence_right->setObjectName("ui_evidence_right");
 | 
			
		||||
  ui_evidence_present = new AOButton(ui_evidence, ao_app);
 | 
			
		||||
  ui_evidence_present->setToolTip(tr("Present this piece of evidence to "
 | 
			
		||||
                                     "everyone on your next spoken message"));
 | 
			
		||||
  ui_evidence_present->setObjectName("ui_evidence_present");
 | 
			
		||||
 | 
			
		||||
  ui_evidence_switch = new AOButton(ui_evidence, ao_app);
 | 
			
		||||
  ui_evidence_switch->setObjectName("ui_evidence_switch");
 | 
			
		||||
  ui_evidence_transfer = new AOButton(ui_evidence, ao_app);
 | 
			
		||||
  ui_evidence_transfer->setObjectName("ui_evidence_transfer");
 | 
			
		||||
 | 
			
		||||
  ui_evidence_save = new AOButton(ui_evidence, ao_app);
 | 
			
		||||
  ui_evidence_save->setToolTip(tr("Save evidence to an .ini file."));
 | 
			
		||||
  ui_evidence_save->setObjectName("ui_evidence_save");
 | 
			
		||||
  ui_evidence_load = new AOButton(ui_evidence, ao_app);
 | 
			
		||||
  ui_evidence_load->setToolTip(tr("Load evidence from an .ini file."));
 | 
			
		||||
  ui_evidence_load->setObjectName("ui_evidence_load");
 | 
			
		||||
 | 
			
		||||
  ui_evidence_overlay = new AOImage(ui_evidence, ao_app);
 | 
			
		||||
  ui_evidence_overlay->setObjectName("ui_evidence_overlay");
 | 
			
		||||
 | 
			
		||||
  ui_evidence_delete = new AOButton(ui_evidence_overlay, ao_app);
 | 
			
		||||
  ui_evidence_delete->setToolTip(tr("Destroy this piece of evidence"));
 | 
			
		||||
  ui_evidence_delete->setObjectName("ui_evidence_delete");
 | 
			
		||||
  ui_evidence_image_name = new AOLineEdit(ui_evidence_overlay);
 | 
			
		||||
  ui_evidence_image_name->setObjectName("ui_evidence_image_name");
 | 
			
		||||
  ui_evidence_image_button = new AOButton(ui_evidence_overlay, ao_app);
 | 
			
		||||
  ui_evidence_image_button->setText(tr("Choose.."));
 | 
			
		||||
  ui_evidence_image_button->setObjectName("ui_evidence_image_button");
 | 
			
		||||
  ui_evidence_x = new AOButton(ui_evidence_overlay, ao_app);
 | 
			
		||||
  ui_evidence_x->setToolTip(
 | 
			
		||||
      tr("Close the evidence display/editing overlay.\n"
 | 
			
		||||
         "You will be prompted if there's any unsaved changes."));
 | 
			
		||||
  ui_evidence_x->setObjectName("ui_evidence_x");
 | 
			
		||||
  ui_evidence_ok = new AOButton(ui_evidence_overlay, ao_app);
 | 
			
		||||
  ui_evidence_ok->setToolTip(tr("Save any changes made to this piece of "
 | 
			
		||||
                                "evidence and send them to server."));
 | 
			
		||||
  ui_evidence_ok->setObjectName("ui_evidence_ok");
 | 
			
		||||
 | 
			
		||||
  ui_evidence_description = new AOTextEdit(ui_evidence_overlay);
 | 
			
		||||
  ui_evidence_description->setFrameStyle(QFrame::NoFrame);
 | 
			
		||||
  ui_evidence_description->setToolTip(
 | 
			
		||||
      tr("Double-click to edit. Press [X] to update your changes."));
 | 
			
		||||
  ui_evidence_description->setObjectName("ui_evidence_description");
 | 
			
		||||
 | 
			
		||||
  connect(ui_evidence_name, SIGNAL(returnPressed()), this,
 | 
			
		||||
          SLOT(on_evidence_name_edited()));
 | 
			
		||||
 | 
			
		||||
@ -12,50 +12,68 @@ Lobby::Lobby(AOApplication *p_ao_app) : QMainWindow()
 | 
			
		||||
{
 | 
			
		||||
  ao_app = p_ao_app;
 | 
			
		||||
 | 
			
		||||
  //
 | 
			
		||||
  this->setWindowTitle(tr("Attorney Online 2"));
 | 
			
		||||
  this->setWindowIcon(QIcon(":/logo.png"));
 | 
			
		||||
  this->setWindowFlags( (this->windowFlags() | Qt::CustomizeWindowHint) & ~Qt::WindowMaximizeButtonHint);
 | 
			
		||||
 | 
			
		||||
  ui_background = new AOImage(this, ao_app);
 | 
			
		||||
  ui_background->setObjectName("ui_background");
 | 
			
		||||
  ui_public_servers = new AOButton(this, ao_app);
 | 
			
		||||
  ui_public_servers->setObjectName("ui_public_servers");
 | 
			
		||||
  ui_favorites = new AOButton(this, ao_app);
 | 
			
		||||
  ui_favorites->setObjectName("ui_favorites");
 | 
			
		||||
  ui_refresh = new AOButton(this, ao_app);
 | 
			
		||||
  ui_refresh->setObjectName("ui_refresh");
 | 
			
		||||
  ui_add_to_fav = new AOButton(this, ao_app);
 | 
			
		||||
  ui_add_to_fav->setObjectName("ui_add_to_fav");
 | 
			
		||||
  ui_connect = new AOButton(this, ao_app);
 | 
			
		||||
  ui_connect->setObjectName("ui_connect");
 | 
			
		||||
  ui_version = new QLabel(this);
 | 
			
		||||
  ui_version->setObjectName("ui_version");
 | 
			
		||||
  ui_about = new AOButton(this, ao_app);
 | 
			
		||||
  ui_about->setObjectName("ui_about");
 | 
			
		||||
  ui_settings = new AOButton(this, ao_app);
 | 
			
		||||
  ui_settings->setObjectName("ui_settings");
 | 
			
		||||
 | 
			
		||||
  ui_server_list = new QTreeWidget(this);
 | 
			
		||||
  ui_server_list->setHeaderLabels({"#", "Name"}); //, "Players"});
 | 
			
		||||
  ui_server_list->setHeaderLabels({"#", "Name"});
 | 
			
		||||
  ui_server_list->setTextElideMode(Qt::ElideNone);
 | 
			
		||||
  ui_server_list->header()->setMinimumSectionSize(24);
 | 
			
		||||
  ui_server_list->header()->setSectionsMovable(false);
 | 
			
		||||
  ui_server_list->setColumnWidth(0, 0);
 | 
			
		||||
  ui_server_list->setIndentation(0);
 | 
			
		||||
//  ui_server_list->hideColumn(0);
 | 
			
		||||
//  ui_server_list->setHeaderHidden(true);
 | 
			
		||||
  ui_server_list->setObjectName("ui_server_list");
 | 
			
		||||
 | 
			
		||||
  ui_server_search = new QLineEdit(this);
 | 
			
		||||
  ui_server_search->setFrame(false);
 | 
			
		||||
  ui_server_search->setPlaceholderText(tr("Search"));
 | 
			
		||||
  ui_server_search->setObjectName("ui_server_search");
 | 
			
		||||
 | 
			
		||||
  ui_player_count = new QLabel(this);
 | 
			
		||||
  ui_player_count->setObjectName("ui_player_count");
 | 
			
		||||
  ui_description = new AOTextArea(this);
 | 
			
		||||
  ui_description->setOpenExternalLinks(true);
 | 
			
		||||
  ui_description->setObjectName("ui_description");
 | 
			
		||||
  ui_chatbox = new AOTextArea(this);
 | 
			
		||||
  ui_chatbox->setOpenExternalLinks(true);
 | 
			
		||||
  ui_chatbox->setObjectName("ui_chatbox");
 | 
			
		||||
  ui_chatname = new QLineEdit(this);
 | 
			
		||||
  ui_chatname->setPlaceholderText(tr("Name"));
 | 
			
		||||
  ui_chatname->setText(ao_app->get_ooc_name());
 | 
			
		||||
  ui_chatname->setObjectName("ui_chatname");
 | 
			
		||||
  ui_chatmessage = new QLineEdit(this);
 | 
			
		||||
  ui_chatmessage->setObjectName("ui_chatmessage");
 | 
			
		||||
  ui_loading_background = new AOImage(this, ao_app);
 | 
			
		||||
  ui_loading_background->setObjectName("ui_loading_background");
 | 
			
		||||
  ui_loading_text = new QTextEdit(ui_loading_background);
 | 
			
		||||
  ui_loading_text->setObjectName("ui_loading_text");
 | 
			
		||||
  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_progress_bar->setObjectName("ui_progress_bar");
 | 
			
		||||
  ui_cancel = new AOButton(ui_loading_background, ao_app);
 | 
			
		||||
  ui_cancel->setObjectName("ui_cancel");
 | 
			
		||||
 | 
			
		||||
  connect(ui_public_servers, SIGNAL(clicked()), this,
 | 
			
		||||
          SLOT(on_public_servers_clicked()));
 | 
			
		||||
 | 
			
		||||
@ -121,6 +121,7 @@ void AOApplication::append_to_demofile(QString packet_string)
 | 
			
		||||
void AOApplication::server_packet_received(AOPacket *p_packet)
 | 
			
		||||
{
 | 
			
		||||
  QStringList f_contents_encoded = p_packet->get_contents();
 | 
			
		||||
  QString f_packet_encoded = p_packet->to_string();
 | 
			
		||||
  p_packet->net_decode();
 | 
			
		||||
 | 
			
		||||
  QString header = p_packet->get_header();
 | 
			
		||||
@ -182,7 +183,7 @@ void AOApplication::server_packet_received(AOPacket *p_packet)
 | 
			
		||||
        w_courtroom->append_server_chatmessage(f_contents.at(0),
 | 
			
		||||
                                               f_contents.at(1), "0");
 | 
			
		||||
 | 
			
		||||
      append_to_demofile(p_packet->to_string(true));
 | 
			
		||||
      append_to_demofile(f_packet_encoded);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  else if (header == "FL") {
 | 
			
		||||
@ -307,7 +308,7 @@ void AOApplication::server_packet_received(AOPacket *p_packet)
 | 
			
		||||
      this->log_filename = QDateTime::currentDateTime().toUTC().toString(
 | 
			
		||||
          "'logs/" + server_name.remove(QRegExp("[\\\\/:*?\"<>|\']")) +
 | 
			
		||||
          "/'yyyy-MM-dd hh-mm-ss t'.log'");
 | 
			
		||||
      this->write_to_file("Joined server " + server_name + " on address " +
 | 
			
		||||
      this->write_to_file("Joined server " + server_name + " hosted on address " +
 | 
			
		||||
                              server_address + " on " +
 | 
			
		||||
                              QDateTime::currentDateTime().toUTC().toString(),
 | 
			
		||||
                          log_filename, true);
 | 
			
		||||
@ -368,7 +369,7 @@ void AOApplication::server_packet_received(AOPacket *p_packet)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    send_server_packet(new AOPacket("RM#%"));
 | 
			
		||||
    append_to_demofile(p_packet->to_string(true));
 | 
			
		||||
    append_to_demofile(f_packet_encoded);
 | 
			
		||||
  }
 | 
			
		||||
  else if (header == "SM") {
 | 
			
		||||
    if (!courtroom_constructed || courtroom_loaded)
 | 
			
		||||
@ -471,7 +472,7 @@ void AOApplication::server_packet_received(AOPacket *p_packet)
 | 
			
		||||
          2) // We have a pos included in the background packet!
 | 
			
		||||
        w_courtroom->set_side(f_contents.at(1));
 | 
			
		||||
      w_courtroom->set_background(f_contents.at(0), f_contents.size() >= 2);
 | 
			
		||||
      append_to_demofile(p_packet->to_string(true));
 | 
			
		||||
      append_to_demofile(f_packet_encoded);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  else if (header == "SP") {
 | 
			
		||||
@ -481,7 +482,7 @@ void AOApplication::server_packet_received(AOPacket *p_packet)
 | 
			
		||||
    if (courtroom_constructed) // We were sent a "set position" packet
 | 
			
		||||
    {
 | 
			
		||||
      w_courtroom->set_side(f_contents.at(0));
 | 
			
		||||
      append_to_demofile(p_packet->to_string(true));
 | 
			
		||||
      append_to_demofile(f_packet_encoded);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  else if (header == "SD") // Send pos dropdown
 | 
			
		||||
@ -507,14 +508,14 @@ void AOApplication::server_packet_received(AOPacket *p_packet)
 | 
			
		||||
    if (courtroom_constructed && courtroom_loaded)
 | 
			
		||||
    {
 | 
			
		||||
      w_courtroom->chatmessage_enqueue(p_packet->get_contents());
 | 
			
		||||
      append_to_demofile(p_packet->to_string(true));
 | 
			
		||||
      append_to_demofile(f_packet_encoded);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  else if (header == "MC") {
 | 
			
		||||
    if (courtroom_constructed && courtroom_loaded)
 | 
			
		||||
    {
 | 
			
		||||
      w_courtroom->handle_song(&p_packet->get_contents());
 | 
			
		||||
      append_to_demofile(p_packet->to_string(true));
 | 
			
		||||
      append_to_demofile(f_packet_encoded);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  else if (header == "RT") {
 | 
			
		||||
@ -525,7 +526,7 @@ void AOApplication::server_packet_received(AOPacket *p_packet)
 | 
			
		||||
          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());
 | 
			
		||||
        append_to_demofile(p_packet->to_string(true));
 | 
			
		||||
        append_to_demofile(f_packet_encoded);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
@ -534,7 +535,7 @@ void AOApplication::server_packet_received(AOPacket *p_packet)
 | 
			
		||||
    {
 | 
			
		||||
      w_courtroom->set_hp_bar(f_contents.at(0).toInt(),
 | 
			
		||||
                              f_contents.at(1).toInt());
 | 
			
		||||
      append_to_demofile(p_packet->to_string(true));
 | 
			
		||||
      append_to_demofile(f_packet_encoded);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  else if (header == "LE") {
 | 
			
		||||
@ -560,7 +561,7 @@ void AOApplication::server_packet_received(AOPacket *p_packet)
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      w_courtroom->set_evidence_list(f_evi_list);
 | 
			
		||||
      append_to_demofile(p_packet->to_string(true));
 | 
			
		||||
      append_to_demofile(f_packet_encoded);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  else if (header == "ARUP") {
 | 
			
		||||
@ -615,7 +616,7 @@ void AOApplication::server_packet_received(AOPacket *p_packet)
 | 
			
		||||
      w_courtroom->mod_called(f_contents.at(0));
 | 
			
		||||
  }
 | 
			
		||||
  else if (header == "CASEA") {
 | 
			
		||||
    if (courtroom_constructed && f_contents.size() > 6)
 | 
			
		||||
    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",
 | 
			
		||||
@ -665,7 +666,7 @@ void AOApplication::server_packet_received(AOPacket *p_packet)
 | 
			
		||||
      w_courtroom->set_clock_visibility(id, true);
 | 
			
		||||
    else if (type == 3)
 | 
			
		||||
      w_courtroom->set_clock_visibility(id, false);
 | 
			
		||||
    append_to_demofile(p_packet->to_string(true));
 | 
			
		||||
    append_to_demofile(f_packet_encoded);
 | 
			
		||||
  }
 | 
			
		||||
  else if (header == "CHECK") {
 | 
			
		||||
    if (!courtroom_constructed)
 | 
			
		||||
@ -702,6 +703,16 @@ void AOApplication::server_packet_received(AOPacket *p_packet)
 | 
			
		||||
    w_courtroom->on_authentication_state_received(authenticated);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 //AssetURL Packet
 | 
			
		||||
  else if (header == "ASS") {
 | 
			
		||||
    if (f_contents.size() > 1 || f_contents.size() == 0) { // This can never be more than one link.
 | 
			
		||||
      goto end;
 | 
			
		||||
    }
 | 
			
		||||
    QUrl t_asset_url = QUrl::fromPercentEncoding(f_contents.at(0).toUtf8());
 | 
			
		||||
    if (t_asset_url.isValid())
 | 
			
		||||
    asset_url = t_asset_url.toString();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
end:
 | 
			
		||||
 | 
			
		||||
  delete p_packet;
 | 
			
		||||
 | 
			
		||||
@ -91,7 +91,6 @@ VPath AOApplication::get_evidence_path(QString p_file)
 | 
			
		||||
QVector<VPath> AOApplication::get_asset_paths(QString p_element, QString p_theme, QString p_subtheme, QString p_default_theme, QString p_misc, QString p_character, QString p_placeholder)
 | 
			
		||||
{
 | 
			
		||||
    QVector<VPath> pathlist;
 | 
			
		||||
    pathlist += VPath(p_element); // The path by itself
 | 
			
		||||
    if (p_character != "")
 | 
			
		||||
      pathlist += get_character_path(p_character, p_element); // Character folder
 | 
			
		||||
    if (p_misc != "" && p_theme != "" && p_subtheme != "")
 | 
			
		||||
@ -106,6 +105,7 @@ QVector<VPath> AOApplication::get_asset_paths(QString p_element, QString p_theme
 | 
			
		||||
      pathlist += get_theme_path(p_element, p_theme); // Theme path
 | 
			
		||||
    if (p_default_theme != "")
 | 
			
		||||
      pathlist += get_theme_path(p_element, p_default_theme); // Default theme path
 | 
			
		||||
    pathlist += VPath(p_element); // The path by itself
 | 
			
		||||
    if (p_placeholder != "" && p_theme != "")
 | 
			
		||||
      pathlist += get_theme_path(p_placeholder, p_theme); // Placeholder path
 | 
			
		||||
    if (p_placeholder != "" && p_default_theme != "")
 | 
			
		||||
@ -154,6 +154,7 @@ QString AOApplication::get_config_value(QString p_identifier, QString p_config,
 | 
			
		||||
        path = get_real_path(p);
 | 
			
		||||
        if (!path.isEmpty()) {
 | 
			
		||||
            QSettings settings(path, QSettings::IniFormat);
 | 
			
		||||
            settings.setIniCodec("UTF-8");
 | 
			
		||||
            QVariant value = settings.value(p_identifier);
 | 
			
		||||
            if (value.type() == QVariant::StringList) {
 | 
			
		||||
//              qDebug() << "got" << p << "is a string list, returning" << value.toStringList().join(",");
 | 
			
		||||
 | 
			
		||||
@ -112,6 +112,12 @@ QString AOApplication::get_default_username()
 | 
			
		||||
    return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QString AOApplication::get_default_showname()
 | 
			
		||||
{
 | 
			
		||||
    QString result = configini->value("default_showname", "").value<QString>();
 | 
			
		||||
    return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QString AOApplication::get_audio_output_device()
 | 
			
		||||
{
 | 
			
		||||
  QString result =
 | 
			
		||||
@ -248,33 +254,31 @@ QVector<server_type> AOApplication::read_serverlist_txt()
 | 
			
		||||
 | 
			
		||||
  serverlist_txt.setFileName(serverlist_txt_path);
 | 
			
		||||
 | 
			
		||||
  if (!serverlist_txt.open(QIODevice::ReadOnly)) {
 | 
			
		||||
    return f_server_list;
 | 
			
		||||
  }
 | 
			
		||||
  if (serverlist_txt.open(QIODevice::ReadOnly)) {
 | 
			
		||||
      QTextStream in(&serverlist_txt);
 | 
			
		||||
 | 
			
		||||
  QTextStream in(&serverlist_txt);
 | 
			
		||||
      while (!in.atEnd()) {
 | 
			
		||||
        QString line = in.readLine();
 | 
			
		||||
        server_type f_server;
 | 
			
		||||
        QStringList line_contents = line.split(":");
 | 
			
		||||
 | 
			
		||||
  while (!in.atEnd()) {
 | 
			
		||||
    QString line = in.readLine();
 | 
			
		||||
    server_type f_server;
 | 
			
		||||
    QStringList line_contents = line.split(":");
 | 
			
		||||
        if (line_contents.size() < 3)
 | 
			
		||||
          continue;
 | 
			
		||||
 | 
			
		||||
    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.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);
 | 
			
		||||
        f_server_list.append(f_server);
 | 
			
		||||
      }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  server_type demo_server;
 | 
			
		||||
  demo_server.ip = "127.0.0.1";
 | 
			
		||||
  demo_server.port = 99999;
 | 
			
		||||
  demo_server.name = "Demo playback";
 | 
			
		||||
  demo_server.desc = "Play back demos you have previously recorded";
 | 
			
		||||
  demo_server.name = tr("Demo playback");
 | 
			
		||||
  demo_server.desc = tr("Play back demos you have previously recorded");
 | 
			
		||||
  f_server_list.append(demo_server);
 | 
			
		||||
 | 
			
		||||
  return f_server_list;
 | 
			
		||||
@ -290,6 +294,7 @@ QString AOApplication::read_design_ini(QString p_identifier,
 | 
			
		||||
                                       QString p_design_path)
 | 
			
		||||
{
 | 
			
		||||
  QSettings settings(p_design_path, QSettings::IniFormat);
 | 
			
		||||
  settings.setIniCodec("UTF-8");
 | 
			
		||||
  QVariant value = settings.value(p_identifier);
 | 
			
		||||
  if (value.type() == QVariant::StringList) {
 | 
			
		||||
    return value.toStringList().join(",");
 | 
			
		||||
@ -302,6 +307,9 @@ QString AOApplication::read_design_ini(QString p_identifier,
 | 
			
		||||
 | 
			
		||||
Qt::TransformationMode AOApplication::get_scaling(QString p_scaling)
 | 
			
		||||
{
 | 
			
		||||
  if (p_scaling.isEmpty())
 | 
			
		||||
    p_scaling = get_default_scaling();
 | 
			
		||||
 | 
			
		||||
  if (p_scaling == "smooth")
 | 
			
		||||
    return Qt::SmoothTransformation;
 | 
			
		||||
  return Qt::FastTransformation;
 | 
			
		||||
@ -448,20 +456,20 @@ QString AOApplication::get_chat_markup(QString p_identifier, QString p_chat)
 | 
			
		||||
  // New Chadly method
 | 
			
		||||
  QString value = get_config_value(p_identifier, "chat_config.ini", current_theme, get_subtheme(), default_theme, p_chat);
 | 
			
		||||
  if (!value.isEmpty())
 | 
			
		||||
    return value.toLatin1();
 | 
			
		||||
    return value.toUtf8();
 | 
			
		||||
 | 
			
		||||
  // Backwards ass compatibility
 | 
			
		||||
  QVector<VPath> backwards_paths {
 | 
			
		||||
    get_theme_path("misc/" + p_chat + "/config.ini"),
 | 
			
		||||
    VPath("misc/" + p_chat + "/config.ini"),
 | 
			
		||||
    VPath("misc/default/config.ini"),
 | 
			
		||||
    get_theme_path("misc/default/config.ini")
 | 
			
		||||
    get_theme_path("misc/default/config.ini"),
 | 
			
		||||
    VPath("misc/default/config.ini")
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  for (const VPath &p : backwards_paths) {
 | 
			
		||||
    QString value = read_design_ini(p_identifier, p);
 | 
			
		||||
    if (!value.isEmpty()) {
 | 
			
		||||
      return value.toLatin1();
 | 
			
		||||
      return value.toUtf8();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -491,7 +499,7 @@ QString AOApplication::get_court_sfx(QString p_identifier, QString p_misc)
 | 
			
		||||
{
 | 
			
		||||
  QString value = get_config_value(p_identifier, "courtroom_sounds.ini", current_theme, get_subtheme(), default_theme, p_misc);
 | 
			
		||||
  if (!value.isEmpty())
 | 
			
		||||
    return value.toLatin1();
 | 
			
		||||
    return value.toUtf8();
 | 
			
		||||
  return "";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -521,6 +529,7 @@ QString AOApplication::read_char_ini(QString p_char, QString p_search_line,
 | 
			
		||||
  QSettings settings(get_real_path(get_character_path(p_char, "char.ini")),
 | 
			
		||||
                     QSettings::IniFormat);
 | 
			
		||||
  settings.beginGroup(target_tag);
 | 
			
		||||
  settings.setIniCodec("UTF-8");
 | 
			
		||||
  QString value = settings.value(p_search_line).value<QString>();
 | 
			
		||||
  settings.endGroup();
 | 
			
		||||
  return value;
 | 
			
		||||
@ -541,6 +550,7 @@ QStringList AOApplication::read_ini_tags(VPath p_path, QString target_tag)
 | 
			
		||||
{
 | 
			
		||||
  QStringList r_values;
 | 
			
		||||
  QSettings settings(get_real_path(p_path), QSettings::IniFormat);
 | 
			
		||||
  settings.setIniCodec("UTF-8");
 | 
			
		||||
  if (!target_tag.isEmpty())
 | 
			
		||||
    settings.beginGroup(target_tag);
 | 
			
		||||
  QStringList keys = settings.allKeys();
 | 
			
		||||
@ -666,15 +676,6 @@ int AOApplication::get_preanim_duration(QString p_char, QString p_emote)
 | 
			
		||||
  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;
 | 
			
		||||
  return f_result.toInt();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int AOApplication::get_emote_number(QString p_char)
 | 
			
		||||
{
 | 
			
		||||
  QString f_result = read_char_ini(p_char, "number", "Emotions");
 | 
			
		||||
@ -842,7 +843,7 @@ QStringList AOApplication::get_effects(QString p_char)
 | 
			
		||||
{
 | 
			
		||||
  QString p_misc = read_char_ini(p_char, "effects", "Options");
 | 
			
		||||
  QString p_path = get_asset("effects/effects.ini", current_theme, get_subtheme(), default_theme, "");
 | 
			
		||||
  QString p_misc_path = get_asset("effects/effects.ini", current_theme, get_subtheme(), default_theme, p_misc);
 | 
			
		||||
  QString p_misc_path = get_asset("effects.ini", current_theme, get_subtheme(), default_theme, p_misc);
 | 
			
		||||
  QStringList effects;
 | 
			
		||||
 | 
			
		||||
  QStringList lines = read_file(p_path).split("\n");
 | 
			
		||||
@ -865,10 +866,13 @@ QString AOApplication::get_effect(QString effect, QString p_char,
 | 
			
		||||
  if (p_folder == "")
 | 
			
		||||
    p_folder = read_char_ini(p_char, "effects", "Options");
 | 
			
		||||
 | 
			
		||||
  QString p_path = get_image("effects/" + effect, current_theme, get_subtheme(), default_theme, p_folder);
 | 
			
		||||
  QString p_path = get_image("effects/" + effect, current_theme, get_subtheme(), default_theme, "");
 | 
			
		||||
  QString p_misc_path = get_image(effect, current_theme, get_subtheme(), default_theme, p_folder);
 | 
			
		||||
 | 
			
		||||
  if (!file_exists(p_path))
 | 
			
		||||
  if (!file_exists(p_misc_path) && !file_exists(p_path))
 | 
			
		||||
    return "";
 | 
			
		||||
  else if (file_exists(p_misc_path))
 | 
			
		||||
    return p_misc_path;
 | 
			
		||||
  return p_path;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -881,7 +885,9 @@ QString AOApplication::get_effect_property(QString fx_name, QString p_char,
 | 
			
		||||
  else
 | 
			
		||||
    f_property = fx_name + "_" + p_property;
 | 
			
		||||
 | 
			
		||||
  QString f_result = get_config_value(f_property, "effects/effects.ini", current_theme, get_subtheme(), default_theme, read_char_ini(p_char, "effects", "Options"));
 | 
			
		||||
  QString f_result = get_config_value(f_property, "effects.ini", current_theme, get_subtheme(), default_theme, read_char_ini(p_char, "effects", "Options"));
 | 
			
		||||
  if (f_result == "")
 | 
			
		||||
      f_result = get_config_value(f_property, "effects/effects.ini", current_theme, get_subtheme(), default_theme, "");
 | 
			
		||||
  if (fx_name == "realization" && p_property == "sound") {
 | 
			
		||||
    f_result = get_custom_realization(p_char);
 | 
			
		||||
  }
 | 
			
		||||
@ -1083,6 +1089,11 @@ bool AOApplication::get_animated_theme()
 | 
			
		||||
  return result.startsWith("true");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QString AOApplication::get_default_scaling()
 | 
			
		||||
{
 | 
			
		||||
  return configini->value("default_scaling", "fast").value<QString>();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QStringList AOApplication::get_mount_paths()
 | 
			
		||||
{
 | 
			
		||||
  return configini->value("mount_paths").value<QStringList>();
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user