Merge branch 'master' into feature/timerclock

# Conflicts:
#	include/courtroom.h
#	src/courtroom.cpp
This commit is contained in:
Crystalwarrior 2021-01-10 14:27:27 +03:00
commit 1ad8f3bf24
37 changed files with 862 additions and 618 deletions

31
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@ -0,0 +1,31 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
**To reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Version:**
- OS: (e.g. Windows 10)
- Version or branch: (e.g. 2.8.5, master, ui-files, etc.)
**Additional context**
Add any other context about the problem here.

View File

@ -0,0 +1,20 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: ''
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

View File

@ -1,5 +1,6 @@
language: cpp
os: osx
osx_image: xcode12
addons:
homebrew:
update: true

View File

@ -14,6 +14,10 @@ SOURCES += $$files($$PWD/src/*.cpp)
HEADERS += $$files($$PWD/include/*.h)
LIBS += -L$$PWD/lib
QMAKE_LFLAGS += -Wl,-rpath,"'\$$ORIGIN/lib'"
# Uncomment for verbose network logging
# DEFINES += DEBUG_NETWORK
# Uncomment to enable Discord Rich Presence
# DEFINES += DISCORD
@ -31,7 +35,7 @@ LIBS += -lbassopus
macx:LIBS += -framework CoreFoundation -framework Foundation -framework CoreServices
CONFIG += c++14
CONFIG += c++17
RESOURCES += resources.qrc

View File

@ -67,14 +67,10 @@ public:
/////////////////server metadata//////////////////
unsigned int s_decryptor = 5;
bool encryption_needed = true;
bool yellow_text_enabled = false;
bool prezoom_enabled = false;
bool flipping_enabled = false;
bool custom_objection_enabled = false;
bool improved_loading_enabled = false;
bool desk_mod_enabled = false;
bool evidence_enabled = false;
bool cccc_ic_support_enabled = false;
@ -84,6 +80,8 @@ public:
bool looping_sfx_support_enabled = false;
bool additive_enabled = false;
bool effects_enabled = false;
bool y_offset_enabled = false;
bool expanded_desk_mods_enabled = false;
///////////////loading info///////////////////
@ -227,6 +225,9 @@ public:
// Returns whether the log should have a timestamp.
bool get_log_timestamp();
// Returns whether to log IC actions.
bool get_log_ic_actions();
// Returns the username the user may have set in config.ini.
QString get_default_username();
@ -407,8 +408,8 @@ public:
// 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);
// Returns p_char's blips (previously called their "gender")
QString get_blips(QString p_char);
// ======
// These are all casing-related settings.

View File

@ -22,12 +22,9 @@ public:
int m_cycle = 0;
private:
const int max_blip_ms = 60;
QWidget *m_parent;
AOApplication *ao_app;
qreal m_volume;
QElapsedTimer delay;
void set_volume_internal(qreal p_volume);

View File

@ -52,6 +52,8 @@ private:
QSpinBox *ui_log_margin_spinbox;
QLabel *ui_log_timestamp_lbl;
QCheckBox *ui_log_timestamp_cb;
QLabel *ui_log_ic_actions_lbl;
QCheckBox *ui_log_ic_actions_cb;
QFrame *ui_log_names_divider;
QLineEdit *ui_username_textbox;
QLabel *ui_username_lbl;

View File

@ -8,21 +8,16 @@
class AOPacket {
public:
AOPacket(QString p_packet_string);
AOPacket(QString header, QStringList &p_contents);
~AOPacket();
AOPacket(QString header, QStringList &p_contents) : m_header(header), m_contents(p_contents){}
QString get_header() { return m_header; }
QStringList &get_contents() { return m_contents; }
QString to_string();
void encrypt_header(unsigned int p_key);
void decrypt_header(unsigned int p_key);
void net_encode();
void net_decode();
private:
bool encrypted = false;
QString m_header;
QStringList m_contents;

View File

@ -16,8 +16,7 @@ public:
void clear();
void loop_clear();
void play(QString p_sfx, QString p_char = "", QString shout = "",
int channel = -1);
void play(QString p_sfx, QString p_char = "", QString shout = "");
void stop(int channel = -1);
void set_volume(qreal p_volume);
void set_looping(bool toggle, int channel = -1);

View File

@ -59,6 +59,7 @@
#include <QTextCharFormat>
#include <QElapsedTimer>
#include <algorithm>
#include <stack>
class AOApplication;
@ -175,6 +176,9 @@ public:
// sets desk and bg based on pos in chatmessage
void set_scene(QString f_desk_mod, QString f_side);
// sets ui_vp_player_char according to SELF_OFFSET, only a function bc it's used with desk_mod 4 and 5
void set_self_offset(QString p_list);
// takes in serverD-formatted IP list as prints a converted version to server
// OOC admittedly poorly named
void set_ip_list(QString p_list);
@ -226,14 +230,14 @@ public:
// selected
// or the user isn't already scrolled to the top
void append_ic_text(QString p_text, QString p_name = "", QString action = "",
int color = 0);
int color = 0, QDateTime timestamp = QDateTime::currentDateTime());
// prints who played the song to IC chat and plays said song(if found on local
// filesystem) takes in a list where the first element is the song name and
// the second is the char id of who played it
void handle_song(QStringList *p_contents);
void play_preanim(bool noninterrupting);
void play_preanim(bool immediate);
// plays the witness testimony or cross examination animation based on
// argument
@ -259,6 +263,8 @@ public:
void set_clock_visibility(bool visible);
qint64 pong();
// Truncates text so it fits within theme-specified boundaries and sets the tooltip to the full string
void truncate_label_text(QWidget* p_widget, QString p_identifier);
~Courtroom();
private:
@ -284,14 +290,17 @@ private:
bool message_is_centered = false;
int current_display_speed = 3;
int message_display_speed[7] = {0, 10, 25, 40, 50, 70, 90};
int message_display_speed[7] = {5, 10, 25, 40, 50, 70, 90};
// The character ID of the character this user wants to appear alongside with.
int other_charid = -1;
// The offset this user has given if they want to appear alongside someone.
// The horizontal offset this user has given if they want to appear alongside someone.
int char_offset = 0;
// The vertical offset this user has given.
int char_vert_offset = 0;
// 0 = in front, 1 = behind
int pair_order = 0;
@ -325,7 +334,7 @@ private:
int real_tick_pos = 0;
// used to determine how often blips sound
int blip_ticker = 0;
int blip_rate = 1;
int blip_rate = 2;
int rainbow_counter = 0;
bool rainbow_appended = false;
bool blank_blip = false;
@ -342,6 +351,9 @@ private:
// True, if the log should display the message like name<br>text instead of name: text
bool log_newline = false;
// True, if the log should include RP actions like interjections, showing evidence, etc.
bool log_ic_actions = true;
// Margin in pixels between log entries for the IC log.
int log_margin = 0;
@ -408,6 +420,11 @@ private:
int objection_state = 0;
QString objection_custom = "";
struct CustomObjection {
QString name;
QString filename;
};
QList<CustomObjection> custom_objections_list;
int realization_state = 0;
int screenshake_state = 0;
int text_color = 0;
@ -422,6 +439,17 @@ private:
// List of associated RGB colors for this color index
QVector<QColor> color_rgb_list;
// Same as above but populated from misc/default's config
QVector<QColor> default_color_rgb_list;
// Get a color index from an arbitrary misc config
void gen_char_rgb_list(QString p_char);
QVector<QColor> char_color_rgb_list;
// Misc we used for the last message, and the one we're using now. Used to avoid loading assets when it's not needed
QString current_misc;
QString last_misc;
// List of markdown start characters, their index is tied to the color index
QStringList color_markdown_start_list;
@ -438,8 +466,12 @@ private:
// List of all currently available pos
QStringList pos_dropdown_list;
// is the message we're about to send supposed to present evidence?
bool is_presenting_evidence = false;
// have we already presented evidence for this message?
bool evidence_presented = false;
QString effect = "";
// Music effect flags we want to send to server when we play music
@ -536,6 +568,7 @@ private:
AOButton *ui_pair_button;
QListWidget *ui_pair_list;
QSpinBox *ui_pair_offset_spinbox;
QSpinBox *ui_pair_vert_offset_spinbox;
QComboBox *ui_pair_order_dropdown;
@ -595,7 +628,7 @@ private:
QCheckBox *ui_guard;
QCheckBox *ui_casing;
QCheckBox *ui_pre_non_interrupt;
QCheckBox *ui_immediate;
QCheckBox *ui_showname_enable;
AOButton *ui_custom_objection;
@ -717,6 +750,7 @@ private slots:
void music_random();
void music_list_expand_all();
void music_list_collapse_all();
void music_stop();
void on_area_list_double_clicked(QTreeWidgetItem *p_item, int column);
void select_emote(int p_id);
@ -790,6 +824,7 @@ private slots:
void on_log_limit_changed(int value);
void on_pair_offset_changed(int value);
void on_pair_vert_offset_changed(int value);
void on_ooc_toggle_clicked();

View File

@ -91,7 +91,7 @@ enum CHAT_MESSAGE {
SELF_OFFSET,
OTHER_OFFSET,
OTHER_FLIP,
NONINTERRUPTING_PRE,
IMMEDIATE,
LOOPING_SFX,
SCREENSHAKE,
FRAME_SCREENSHAKE,

View File

@ -1,15 +0,0 @@
#ifndef ENCRYPTION_FUNCTIONS_H
#define ENCRYPTION_FUNCTIONS_H
#include <QString>
#include <QVector>
#include <cstddef>
#include <iomanip>
#include <sstream>
#include <stdlib.h>
QString fanta_encrypt(QString p_input, unsigned int key);
QString fanta_decrypt(QString p_input, unsigned int key);
#endif // ENCRYPTION_FUNCTIONS_H

View File

@ -1,16 +0,0 @@
#ifndef HEX_OPERATIONS_H
#define HEX_OPERATIONS_H
#include <algorithm>
#include <bitset>
#include <cstdint>
#include <iomanip>
#include <iostream>
#include <sstream>
#include <string>
namespace omni {
std::string int_to_hex(unsigned int input);
}
#endif // HEX_OPERATIONS_H

View File

@ -46,6 +46,7 @@ public:
void set_loading_value(int p_value);
bool public_servers_selected = true;
bool doubleclicked = false;
~Lobby();

View File

@ -20,10 +20,13 @@ cd tmp
#get the bass prebuilt
curl http://www.un4seen.com/files/bass24-linux.zip -o bass_linux.zip
curl http://www.un4seen.com/files/bassopus24-linux.zip -o bassopus_linux.zip
unzip bass_linux.zip
unzip bassopus_linux.zip
cp x64/libbass.so ../../lib
cp x64/libbassopus.so ../../lib
#get the discord-rpc prebuilt
curl -L https://github.com/discordapp/discord-rpc/releases/download/v3.4.0/discord-rpc-linux.zip -o discord_rpc_linux.zip

View File

@ -26,10 +26,6 @@ void AOBlipPlayer::set_blips(QString p_sfx)
void AOBlipPlayer::blip_tick()
{
if (delay.isValid() && delay.elapsed() < max_blip_ms)
return;
delay.start();
int f_cycle = m_cycle++;
if (m_cycle == 5)

View File

@ -3,7 +3,7 @@
AOCaseAnnouncerDialog::AOCaseAnnouncerDialog(QWidget *parent,
AOApplication *p_ao_app,
Courtroom *p_court)
: QDialog(parent)
: QDialog(parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint)
{
ao_app = p_ao_app;
court = p_court;

View File

@ -35,8 +35,8 @@ void AOCharMovie::load_image(QString p_char, QString p_emote,
ao_app->get_image_suffix(ao_app->get_character_path(
p_char, emote_prefix + "/" +
p_emote)), // Path check if it's categorized into a folder
ao_app->get_character_path(
p_char, p_emote + ".png"), // Non-animated path if emote_prefix fails
ao_app->get_image_suffix(ao_app->get_character_path(
p_char, p_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_default_theme_path(
@ -61,6 +61,15 @@ void AOCharMovie::load_image(QString p_char, QString p_emote,
return;
m_reader->setFileName(emote_path);
// set format to apng if png supports animation
if (emote_path.endsWith("png")) {
m_reader->setFormat("apng");
if (!m_reader->supportsAnimation()) {
m_reader->setFormat("png");
}
}
QPixmap f_pixmap = this->get_pixmap(m_reader->read());
int f_delay = m_reader->nextImageDelay();

View File

@ -27,6 +27,7 @@ void AOEmoteButton::set_image(QString p_image, QString p_emote_comment)
}
else if (p_image.contains("_on") && file_exists(tmp_p_image.replace("_on", "_off"))) {
QImage tmpImage(tmp_p_image);
tmpImage = tmpImage.convertToFormat(QImage::Format_ARGB32);
QPoint p1, p2;
p2.setY(tmpImage.height());

View File

@ -2,6 +2,8 @@
#include "aoimage.h"
#include <QBitmap>
AOImage::AOImage(QWidget *parent, AOApplication *p_ao_app) : QLabel(parent)
{
m_parent = parent;
@ -29,9 +31,10 @@ bool AOImage::set_image(QString p_image)
}
QPixmap f_pixmap(final_image_path);
this->setPixmap(
f_pixmap.scaled(this->width(), this->height(), Qt::IgnoreAspectRatio));
f_pixmap =
f_pixmap.scaled(this->width(), this->height(), Qt::IgnoreAspectRatio);
this->setPixmap(f_pixmap);
this->setMask(f_pixmap.mask());
return true;
}
@ -45,7 +48,9 @@ bool AOImage::set_chatbox(QString p_path)
QPixmap f_pixmap(p_path);
this->setPixmap(
f_pixmap.scaled(this->width(), this->height(), Qt::IgnoreAspectRatio));
f_pixmap =
f_pixmap.scaled(this->width(), this->height(), Qt::IgnoreAspectRatio);
this->setPixmap(f_pixmap);
this->setMask(f_pixmap.mask());
return true;
}

View File

@ -9,6 +9,7 @@ AOMovie::AOMovie(QWidget *p_parent, AOApplication *p_ao_app) : QLabel(p_parent)
ao_app = p_ao_app;
m_movie = new QMovie();
m_movie->setCacheMode(QMovie::CacheAll);
this->setMovie(m_movie);

View File

@ -23,14 +23,26 @@ void AOMusicPlayer::play(QString p_song, int channel, bool loop,
unsigned int flags = BASS_STREAM_PRESCAN | BASS_STREAM_AUTOFREE |
BASS_UNICODE | BASS_ASYNCFILE;
if (loop)
unsigned int streaming_flags = BASS_STREAM_AUTOFREE;
if (loop) {
flags |= BASS_SAMPLE_LOOP;
streaming_flags |= BASS_SAMPLE_LOOP;
}
DWORD newstream;
if (f_path.endsWith(".opus"))
newstream = BASS_OPUS_StreamCreateFile(FALSE, f_path.utf16(), 0, 0, flags);
else
newstream = BASS_StreamCreateFile(FALSE, f_path.utf16(), 0, 0, flags);
if (f_path.startsWith("http")) {
if (f_path.endsWith(".opus"))
newstream = BASS_OPUS_StreamCreateURL(f_path.toStdString().c_str(), 0, streaming_flags, nullptr, 0);
else
newstream = BASS_StreamCreateURL(f_path.toStdString().c_str(), 0, streaming_flags, nullptr, 0);
} else {
if (f_path.endsWith(".opus"))
newstream = BASS_OPUS_StreamCreateFile(FALSE, f_path.utf16(), 0, 0, flags);
else
newstream = BASS_StreamCreateFile(FALSE, f_path.utf16(), 0, 0, flags);
}
if (ao_app->get_audio_output_device() != "default")
BASS_ChannelSetDevice(m_stream_list[channel], BASS_GetDevice());

View File

@ -3,7 +3,7 @@
#include "bass.h"
AOOptionsDialog::AOOptionsDialog(QWidget *parent, AOApplication *p_ao_app)
: QDialog(parent)
: QDialog(parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint)
{
ao_app = p_ao_app;
@ -41,7 +41,7 @@ AOOptionsDialog::AOOptionsDialog(QWidget *parent, AOApplication *p_ao_app)
// Let's add the tabs one by one.
// First, we'll start with 'Gameplay'.
ui_gameplay_tab = new QWidget();
ui_gameplay_tab = new QWidget(this);
ui_gameplay_tab->setSizePolicy(sizePolicy1);
ui_settings_tabs->addTab(ui_gameplay_tab, tr("Gameplay"));
ui_form_layout_widget = new QWidget(ui_gameplay_tab);
@ -163,6 +163,19 @@ AOOptionsDialog::AOOptionsDialog(QWidget *parent, AOApplication *p_ao_app)
ui_gameplay_form->setWidget(row, QFormLayout::FieldRole, ui_log_timestamp_cb);
row += 1;
ui_log_ic_actions_lbl = new QLabel(ui_form_layout_widget);
ui_log_ic_actions_lbl->setText(tr("Log IC actions:"));
ui_log_ic_actions_lbl->setToolTip(
tr("If ticked, log will show IC actions such as shouting and presenting evidence."));
ui_gameplay_form->setWidget(row, QFormLayout::LabelRole, ui_log_ic_actions_lbl);
ui_log_ic_actions_cb = new QCheckBox(ui_form_layout_widget);
ui_log_ic_actions_cb->setChecked(p_ao_app->get_log_ic_actions());
ui_gameplay_form->setWidget(row, QFormLayout::FieldRole, ui_log_ic_actions_cb);
row += 1;
ui_log_names_divider = new QFrame(ui_form_layout_widget);
ui_log_names_divider->setFrameShape(QFrame::HLine);
@ -372,14 +385,14 @@ AOOptionsDialog::AOOptionsDialog(QWidget *parent, AOApplication *p_ao_app)
ui_gameplay_form->setWidget(row, QFormLayout::FieldRole, ui_customchat_cb);
QScrollArea *scroll = new QScrollArea;
QScrollArea *scroll = new QScrollArea(this);
scroll->setWidget(ui_form_layout_widget);
ui_gameplay_tab->setLayout(new QVBoxLayout);
ui_gameplay_tab->layout()->addWidget(scroll);
ui_gameplay_tab->show();
// Here we start the callwords tab.
ui_callwords_tab = new QWidget();
ui_callwords_tab = new QWidget(this);
ui_settings_tabs->addTab(ui_callwords_tab, tr("Callwords"));
ui_callwords_widget = new QWidget(ui_callwords_tab);
@ -416,7 +429,7 @@ AOOptionsDialog::AOOptionsDialog(QWidget *parent, AOApplication *p_ao_app)
ui_callwords_layout->addWidget(ui_callwords_explain_lbl);
// The audio tab.
ui_audio_tab = new QWidget();
ui_audio_tab = new QWidget(this);
ui_settings_tabs->addTab(ui_audio_tab, tr("Audio"));
ui_audio_widget = new QWidget(ui_audio_tab);
@ -577,7 +590,7 @@ AOOptionsDialog::AOOptionsDialog(QWidget *parent, AOApplication *p_ao_app)
ui_audio_layout->setWidget(row, QFormLayout::FieldRole, ui_objectmusic_cb);
// The casing tab!
ui_casing_tab = new QWidget();
ui_casing_tab = new QWidget(this);
ui_settings_tabs->addTab(ui_casing_tab, tr("Casing"));
ui_casing_widget = new QWidget(ui_casing_tab);
@ -756,12 +769,16 @@ void AOOptionsDialog::save_pressed()
// Save everything into the config.ini.
QSettings *configini = ao_app->configini;
const bool audioChanged = ui_audio_device_combobox->currentText() !=
ao_app->get_audio_output_device();
configini->setValue("theme", ui_theme_combobox->currentText());
configini->setValue("log_goes_downwards", ui_downwards_cb->isChecked());
configini->setValue("log_maximum", ui_length_spinbox->value());
configini->setValue("log_newline", ui_log_newline_cb->isChecked());
configini->setValue("log_margin", ui_log_margin_spinbox->value());
configini->setValue("log_timestamp", ui_log_timestamp_cb->isChecked());
configini->setValue("log_ic_actions", ui_log_ic_actions_cb->isChecked());
configini->setValue("default_username", ui_username_textbox->text());
configini->setValue("show_custom_shownames", ui_showname_cb->isChecked());
configini->setValue("master", ui_ms_textbox->text());
@ -806,7 +823,9 @@ void AOOptionsDialog::save_pressed()
configini->setValue("casing_can_host_cases",
ui_casing_cm_cases_textbox->text());
ao_app->initBASS();
if (audioChanged)
ao_app->initBASS();
callwordsini->close();
done(0);
}

View File

@ -1,80 +1,30 @@
#include "aopacket.h"
#include "encryption_functions.h"
AOPacket::AOPacket(QString p_packet_string)
{
QStringList packet_contents = p_packet_string.split("#");
m_header = packet_contents.at(0);
for (int n_string = 1; n_string < packet_contents.size() - 1; ++n_string) {
m_contents.append(packet_contents.at(n_string));
}
m_header = packet_contents.first();
m_contents = packet_contents.mid(1, packet_contents.size()-2); // trims %
}
AOPacket::AOPacket(QString p_header, QStringList &p_contents)
{
m_header = p_header;
m_contents = p_contents;
}
AOPacket::~AOPacket() {}
QString AOPacket::to_string()
{
QString f_string = m_header;
for (QString i_string : m_contents) {
f_string += ("#" + i_string);
}
f_string += "#%";
if (encrypted)
return "#" + f_string;
else
return f_string;
}
void AOPacket::encrypt_header(unsigned int p_key)
{
m_header = fanta_encrypt(m_header, p_key);
encrypted = true;
}
void AOPacket::decrypt_header(unsigned int p_key)
{
m_header = fanta_decrypt(m_header, p_key);
encrypted = false;
return m_header + "#" + m_contents.join("#") + "#%";
}
void AOPacket::net_encode()
{
for (int n_element = 0; n_element < m_contents.size(); ++n_element) {
QString f_element = m_contents.at(n_element);
f_element.replace("#", "<num>")
.replace("%", "<percent>")
.replace("$", "<dollar>")
.replace("&", "<and>");
m_contents.removeAt(n_element);
m_contents.insert(n_element, f_element);
}
m_contents.replaceInStrings("#", "<num>")
.replaceInStrings("%", "<percent>")
.replaceInStrings("$", "<dollar>")
.replaceInStrings("&", "<and>");
}
void AOPacket::net_decode()
{
for (int n_element = 0; n_element < m_contents.size(); ++n_element) {
QString f_element = m_contents.at(n_element);
f_element.replace("<num>", "#")
.replace("<percent>", "%")
.replace("<dollar>", "$")
.replace("<and>", "&");
m_contents.removeAt(n_element);
m_contents.insert(n_element, f_element);
}
m_contents.replaceInStrings("<num>", "#")
.replaceInStrings("<percent>", "%")
.replaceInStrings("<dollar>", "$")
.replaceInStrings("<and>", "&");
}

View File

@ -7,6 +7,7 @@ AOScene::AOScene(QWidget *parent, AOApplication *p_ao_app) : QLabel(parent)
m_parent = parent;
ao_app = p_ao_app;
m_movie = new QMovie(this);
m_movie->setCacheMode(QMovie::CacheAll);
last_image = "";
}

View File

@ -24,24 +24,30 @@ void AOSfxPlayer::loop_clear()
set_volume_internal(m_volume);
}
void AOSfxPlayer::play(QString p_sfx, QString p_char, QString shout,
int channel)
void AOSfxPlayer::play(QString p_sfx, QString p_char, QString shout)
{
if (channel == -1) {
if (BASS_ChannelIsActive(m_stream_list[channel]) == BASS_ACTIVE_PLAYING)
m_channel = (m_channel + 1) % m_channelmax;
channel = m_channel;
for (int i = 0; i < m_channelmax; ++i) {
if (BASS_ChannelIsActive(m_stream_list[i]) == BASS_ACTIVE_PLAYING)
m_channel = (i + 1) % m_channelmax;
else {
m_channel = i;
break;
}
}
BASS_ChannelStop(m_stream_list[channel]);
QString misc_path = "";
QString char_path = "";
QString theme_path = "";
QString sound_path = ao_app->get_sfx_suffix(ao_app->get_sounds_path(p_sfx));
if (shout != "")
if (shout != "") {
misc_path = ao_app->get_sfx_suffix(ao_app->get_base_path() + "misc/" +
shout + "/" + p_sfx);
theme_path = ao_app->get_sfx_suffix(ao_app->get_theme_path(p_sfx));
if (!file_exists(theme_path))
theme_path =
ao_app->get_sfx_suffix(ao_app->get_default_theme_path(p_sfx));
}
if (p_char != "")
char_path =
ao_app->get_sfx_suffix(ao_app->get_character_path(p_char, p_sfx));
@ -52,15 +58,17 @@ void AOSfxPlayer::play(QString p_sfx, QString p_char, QString shout,
f_path = char_path;
else if (file_exists(misc_path))
f_path = misc_path;
else if (shout != "" && file_exists(theme_path)) // only check here for shouts
f_path = theme_path;
else
f_path = sound_path;
if (f_path.endsWith(".opus"))
m_stream_list[channel] = BASS_OPUS_StreamCreateFile(
m_stream_list[m_channel] = BASS_OPUS_StreamCreateFile(
FALSE, f_path.utf16(), 0, 0,
BASS_STREAM_AUTOFREE | BASS_UNICODE | BASS_ASYNCFILE);
else
m_stream_list[channel] = BASS_StreamCreateFile(
m_stream_list[m_channel] = BASS_StreamCreateFile(
FALSE, f_path.utf16(), 0, 0,
BASS_STREAM_AUTOFREE | BASS_UNICODE | BASS_ASYNCFILE);
@ -74,7 +82,7 @@ void AOSfxPlayer::play(QString p_sfx, QString p_char, QString shout,
}
BASS_ChannelPlay(m_stream_list[m_channel], false);
BASS_ChannelSetSync(m_stream_list[channel], BASS_SYNC_DEV_FAIL, 0,
BASS_ChannelSetSync(m_stream_list[m_channel], BASS_SYNC_DEV_FAIL, 0,
ao_app->BASSreset, 0);
}

View File

@ -7,6 +7,8 @@
void Courtroom::construct_char_select()
{
this->setWindowFlags( (this->windowFlags() | Qt::CustomizeWindowHint) & ~Qt::WindowMaximizeButtonHint);
ui_char_select_background = new AOImage(this, ao_app);
ui_char_buttons = new QWidget(ui_char_select_background);
@ -60,6 +62,9 @@ void Courtroom::construct_char_select()
SLOT(on_char_passworded_clicked()));
connect(ui_char_taken, SIGNAL(stateChanged(int)), this,
SLOT(on_char_taken_clicked()));
truncate_label_text(ui_char_taken, "char_taken");
truncate_label_text(ui_char_passworded, "char_passworded");
}
void Courtroom::set_char_select()
@ -72,10 +77,10 @@ void Courtroom::set_char_select()
if (f_charselect.width < 0 || f_charselect.height < 0) {
qDebug() << "W: did not find char_select width or height in "
"courtroom_design.ini!";
this->resize(714, 668);
this->setFixedSize(714, 668);
}
else
this->resize(f_charselect.width, f_charselect.height);
this->setFixedSize(f_charselect.width, f_charselect.height);
ui_char_select_background->resize(f_charselect.width, f_charselect.height);
ui_char_select_background->set_image("charselect_background");
@ -131,7 +136,7 @@ void Courtroom::char_clicked(int n_char)
qDebug() << "char_ini_path" << char_ini_path;
if (!file_exists(char_ini_path)) {
call_notice("Could not find " + char_ini_path);
call_error("Could not find " + char_ini_path);
return;
}
}
@ -146,8 +151,6 @@ void Courtroom::char_clicked(int n_char)
else
update_character(n_char);
enter_courtroom();
if (n_char != -1)
ui_ic_chat_name->setPlaceholderText(char_list.at(n_char).name);
}

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,7 @@
#include <QCoreApplication>
#include <QMessageBox>
#include <QTimer>
#include <functional>
#include "debug_functions.h"
@ -7,6 +9,7 @@ void call_error(QString p_message)
{
QMessageBox *msgBox = new QMessageBox;
msgBox->setAttribute(Qt::WA_DeleteOnClose);
msgBox->setText(QCoreApplication::translate("debug_functions", "Error: %1")
.arg(p_message));
msgBox->setWindowTitle(
@ -20,10 +23,15 @@ void call_notice(QString p_message)
{
QMessageBox *msgBox = new QMessageBox;
msgBox->setAttribute(Qt::WA_DeleteOnClose);
msgBox->setText(p_message);
msgBox->setWindowTitle(
QCoreApplication::translate("debug_functions", "Notice"));
// msgBox->setWindowModality(Qt::NonModal);
msgBox->exec();
msgBox->setStandardButtons(QMessageBox::NoButton);
QTimer::singleShot(3000, msgBox, std::bind(&QMessageBox::setStandardButtons,msgBox,QMessageBox::Ok));
msgBox->exec();
}

View File

@ -1,58 +0,0 @@
#include "encryption_functions.h"
#include "hex_functions.h"
QString fanta_encrypt(QString temp_input, unsigned int p_key)
{
// using standard stdlib types is actually easier here because of implicit
// char<->int conversion which in turn makes encryption arithmetic easier
unsigned int key = p_key;
unsigned int C1 = 53761;
unsigned int C2 = 32618;
QVector<uint_fast8_t> temp_result;
std::string input = temp_input.toUtf8().constData();
for (unsigned int pos = 0; pos < input.size(); ++pos) {
uint_fast8_t output = input.at(pos) ^ (key >> 8) % 256;
temp_result.append(output);
key = (temp_result.at(pos) + key) * C1 + C2;
}
std::string result = "";
for (uint_fast8_t i_int : temp_result) {
result += omni::int_to_hex(i_int);
}
QString final_result = QString::fromStdString(result);
return final_result;
}
QString fanta_decrypt(QString temp_input, unsigned int key)
{
std::string input = temp_input.toUtf8().constData();
QVector<unsigned int> unhexed_vector;
for (unsigned int i = 0; i < input.length(); i += 2) {
std::string byte = input.substr(i, 2);
unsigned int hex_int = strtoul(byte.c_str(), nullptr, 16);
unhexed_vector.append(hex_int);
}
unsigned int C1 = 53761;
unsigned int C2 = 32618;
std::string result = "";
for (int pos = 0; pos < unhexed_vector.size(); ++pos) {
unsigned char output = unhexed_vector.at(pos) ^ (key >> 8) % 256;
result += output;
key = (unhexed_vector.at(pos) + key) * C1 + C2;
}
return QString::fromStdString(result);
}

View File

@ -258,8 +258,9 @@ void Courtroom::set_evidence_list(QVector<evi_type> &p_evi_list)
else if (compare_evidence_changed(
old_list.at(current_evidence),
local_evidence_list.at(current_evidence))) {
QMessageBox *msgBox = new QMessageBox;
QMessageBox *msgBox = new QMessageBox(this);
msgBox->setAttribute(Qt::WA_DeleteOnClose);
msgBox->setText(tr("The piece of evidence you've been editing has changed."));
msgBox->setInformativeText(tr("Do you wish to keep your changes?"));
msgBox->setDetailedText(tr(
@ -552,7 +553,8 @@ void Courtroom::on_evidence_x_clicked()
evidence_close();
return;
}
QMessageBox *msgBox = new QMessageBox;
QMessageBox *msgBox = new QMessageBox(this);
msgBox->setAttribute(Qt::WA_DeleteOnClose);
msgBox->setText(tr("Evidence has been modified."));
msgBox->setInformativeText(tr("Do you want to save your changes?"));
msgBox->setStandardButtons(QMessageBox::Save | QMessageBox::Discard |
@ -655,7 +657,8 @@ void Courtroom::on_evidence_transfer_clicked()
private_evidence_list.append(f_evi);
}
QMessageBox *msgBox = new QMessageBox;
QMessageBox *msgBox = new QMessageBox(this);
msgBox->setAttribute(Qt::WA_DeleteOnClose);
msgBox->setText(tr("\"%1\" has been transferred.").arg(name));
msgBox->setStandardButtons(QMessageBox::Ok);
msgBox->setDefaultButton(QMessageBox::Ok);

View File

@ -1,17 +0,0 @@
#include "hex_functions.h"
namespace omni {
std::string int_to_hex(unsigned int input)
{
if (input > 255)
return "FF";
std::stringstream stream;
stream << std::setfill('0') << std::setw(sizeof(char) * 2) << std::hex
<< input;
std::string result(stream.str());
std::transform(result.begin(), result.end(), result.begin(), ::toupper);
return result;
}
} // namespace omni

View File

@ -13,6 +13,7 @@ Lobby::Lobby(AOApplication *p_ao_app) : QMainWindow()
this->setWindowTitle(tr("Attorney Online 2"));
this->setWindowIcon(QIcon(":/logo.png"));
this->setWindowFlags( (this->windowFlags() | Qt::CustomizeWindowHint) & ~Qt::WindowMaximizeButtonHint);
ui_background = new AOImage(this, ao_app);
ui_public_servers = new AOButton(this, ao_app);
@ -97,10 +98,10 @@ void Lobby::set_widgets()
"Did you download all resources correctly from tiny.cc/getao, "
"including the large 'base' folder?"));
this->resize(517, 666);
this->setFixedSize(517, 666);
}
else {
this->resize(f_lobby.width, f_lobby.height);
this->setFixedSize(f_lobby.width, f_lobby.height);
}
set_size_and_pos(ui_background, "lobby");
@ -282,7 +283,10 @@ QString Lobby::get_chatlog()
int Lobby::get_selected_server()
{
return ui_server_list->currentItem()->text(0).toInt();
if (auto item = ui_server_list->currentItem()) {
return item->text(0).toInt();
}
return -1;
}
void Lobby::set_loading_value(int p_value)
@ -332,12 +336,12 @@ void Lobby::on_add_to_fav_pressed()
void Lobby::on_add_to_fav_released()
{
ui_add_to_fav->set_image("addtofav");
// you cant add favorites from favorites m8
if (!public_servers_selected)
return;
ao_app->add_favorite_server(get_selected_server());
if (public_servers_selected) {
int selection = get_selected_server();
if (selection > -1) {
ao_app->add_favorite_server(selection);
}
}
}
void Lobby::on_connect_pressed() { ui_connect->set_image("connect_pressed"); }
@ -355,7 +359,7 @@ void Lobby::on_connect_released()
void Lobby::on_about_clicked()
{
const bool hasApng = QImageReader::supportedImageFormats().contains("APNG");
const bool hasApng = QImageReader::supportedImageFormats().contains("apng");
QString msg =
tr("<h2>Attorney Online %1</h2>"
@ -441,8 +445,9 @@ void Lobby::on_server_list_clicked(QTreeWidgetItem *p_item, int column)
// doubleclicked on an item in the serverlist so we'll connect right away
void Lobby::on_server_list_doubleclicked(QTreeWidgetItem *p_item, int column)
{
doubleclicked = true;
on_server_list_clicked(p_item, column);
on_connect_released();
//on_connect_released();
}
void Lobby::on_server_search_edited(QString p_text)

View File

@ -21,6 +21,8 @@ int main(int argc, char *argv[])
AOApplication main_app(argc, argv);
AOApplication::addLibraryPath(AOApplication::applicationDirPath() + "/lib");
QSettings *configini = main_app.configini;
QPluginLoader apngPlugin("qapng");

View File

@ -2,7 +2,6 @@
#include "courtroom.h"
#include "debug_functions.h"
#include "encryption_functions.h"
#include "hardware_functions.h"
#include "lobby.h"
#include "networkmanager.h"
@ -120,16 +119,11 @@ void AOApplication::server_packet_received(AOPacket *p_packet)
if (f_contents.size() == 0)
goto end;
// you may ask where 322 comes from. that would be a good question.
s_decryptor = fanta_decrypt(f_contents.at(0), 322).toUInt();
// default(legacy) values
encryption_needed = true;
yellow_text_enabled = false;
prezoom_enabled = false;
flipping_enabled = false;
custom_objection_enabled = false;
improved_loading_enabled = false;
desk_mod_enabled = false;
evidence_enabled = false;
cccc_ic_support_enabled = false;
@ -139,10 +133,7 @@ void AOApplication::server_packet_received(AOPacket *p_packet)
looping_sfx_support_enabled = false;
additive_enabled = false;
effects_enabled = false;
// workaround for tsuserver4
if (f_contents.at(0) == "NOENCRYPT")
encryption_needed = false;
y_offset_enabled = false;
QString f_hdid;
f_hdid = get_hdid();
@ -176,12 +167,10 @@ void AOApplication::server_packet_received(AOPacket *p_packet)
}
}
else if (header == "FL") {
// encryption_needed = true;
yellow_text_enabled = false;
prezoom_enabled = false;
flipping_enabled = false;
custom_objection_enabled = false;
improved_loading_enabled = false;
desk_mod_enabled = false;
evidence_enabled = false;
cccc_ic_support_enabled = false;
@ -191,6 +180,7 @@ void AOApplication::server_packet_received(AOPacket *p_packet)
looping_sfx_support_enabled = false;
additive_enabled = false;
effects_enabled = false;
expanded_desk_mods_enabled = false;
if (f_packet.contains("yellowtext", Qt::CaseInsensitive))
yellow_text_enabled = true;
if (f_packet.contains("prezoom", Qt::CaseInsensitive))
@ -199,10 +189,6 @@ void AOApplication::server_packet_received(AOPacket *p_packet)
flipping_enabled = true;
if (f_packet.contains("customobjections", Qt::CaseInsensitive))
custom_objection_enabled = true;
if (f_packet.contains("fastloading", Qt::CaseInsensitive))
improved_loading_enabled = true;
if (f_packet.contains("noencryption", Qt::CaseInsensitive))
encryption_needed = false;
if (f_packet.contains("deskmod", Qt::CaseInsensitive))
desk_mod_enabled = true;
if (f_packet.contains("evidence", Qt::CaseInsensitive))
@ -221,6 +207,10 @@ void AOApplication::server_packet_received(AOPacket *p_packet)
additive_enabled = true;
if (f_packet.contains("effects", Qt::CaseInsensitive))
effects_enabled = true;
if (f_packet.contains("y_offset", Qt::CaseInsensitive))
y_offset_enabled = true;
if (f_packet.contains("expanded_desk_mods", Qt::CaseInsensitive))
expanded_desk_mods_enabled = true;
}
else if (header == "PN") {
if (f_contents.size() < 2)
@ -228,6 +218,11 @@ void AOApplication::server_packet_received(AOPacket *p_packet)
w_lobby->set_player_count(f_contents.at(0).toInt(),
f_contents.at(1).toInt());
if (w_lobby->doubleclicked) {
send_server_packet(new AOPacket("askchaa#%"));
w_lobby->doubleclicked = false;
}
}
else if (header == "SI") {
if (f_contents.size() != 3)
@ -283,11 +278,7 @@ void AOApplication::server_packet_received(AOPacket *p_packet)
AOPacket *f_packet;
if (improved_loading_enabled)
f_packet = new AOPacket("RC#%");
else
f_packet = new AOPacket("askchar2#%");
f_packet = new AOPacket("RC#%");
send_server_packet(f_packet);
// Remove any characters not accepted in folder names for the server_name
@ -308,152 +299,6 @@ void AOApplication::server_packet_received(AOPacket *p_packet)
discord->state_server(server_name.toStdString(),
hash.result().toBase64().toStdString());
}
else if (header == "CI") {
if (!courtroom_constructed)
goto end;
for (int n_element = 0; n_element < f_contents.size(); n_element += 2) {
if (f_contents.at(n_element).toInt() != loaded_chars)
break;
// this means we are on the last element and checking n + 1 element will
// be game over so
if (n_element == f_contents.size() - 1)
break;
QStringList sub_elements = f_contents.at(n_element + 1).split("&");
if (sub_elements.size() < 2)
break;
char_type f_char;
f_char.name = sub_elements.at(0);
f_char.description = sub_elements.at(1);
f_char.evidence_string = sub_elements.at(3);
// temporary. the CharsCheck packet sets this properly
f_char.taken = false;
++loaded_chars;
w_lobby->set_loading_text(tr("Loading chars:\n%1/%2")
.arg(QString::number(loaded_chars))
.arg(QString::number(char_list_size)));
w_courtroom->append_char(f_char);
int total_loading_size =
char_list_size * 2 + evidence_list_size + music_list_size;
int loading_value = int(
((loaded_chars + generated_chars + loaded_music + loaded_evidence) /
static_cast<double>(total_loading_size)) *
100);
w_lobby->set_loading_value(loading_value);
}
if (improved_loading_enabled)
send_server_packet(new AOPacket("RE#%"));
else {
QString next_packet_number =
QString::number(((loaded_chars - 1) / 10) + 1);
send_server_packet(new AOPacket("AN#" + next_packet_number + "#%"));
}
}
else if (header == "EI") {
if (!courtroom_constructed)
goto end;
// +1 because evidence starts at 1 rather than 0 for whatever reason
// enjoy fanta
if (f_contents.at(0).toInt() != loaded_evidence + 1)
goto end;
if (f_contents.size() < 2)
goto end;
QStringList sub_elements = f_contents.at(1).split("&");
if (sub_elements.size() < 4)
goto end;
evi_type f_evi;
f_evi.name = sub_elements.at(0);
f_evi.description = sub_elements.at(1);
// no idea what the number at position 2 is. probably an identifier?
f_evi.image = sub_elements.at(3);
++loaded_evidence;
w_lobby->set_loading_text(tr("Loading evidence:\n%1/%2")
.arg(QString::number(loaded_evidence))
.arg(QString::number(evidence_list_size)));
w_courtroom->append_evidence(f_evi);
int total_loading_size =
char_list_size * 2 + evidence_list_size + music_list_size;
int loading_value =
int(((loaded_chars + generated_chars + loaded_music + loaded_evidence) /
static_cast<double>(total_loading_size)) *
100);
w_lobby->set_loading_value(loading_value);
QString next_packet_number = QString::number(loaded_evidence);
send_server_packet(new AOPacket("AE#" + next_packet_number + "#%"));
}
else if (header == "EM") {
if (!courtroom_constructed)
goto end;
bool musics_time = false;
int areas = 0;
for (int n_element = 0; n_element < f_contents.size(); n_element += 2) {
if (f_contents.at(n_element).toInt() != loaded_music)
break;
if (n_element == f_contents.size() - 1)
break;
QString f_music = f_contents.at(n_element + 1);
++loaded_music;
w_lobby->set_loading_text(tr("Loading music:\n%1/%2")
.arg(QString::number(loaded_music))
.arg(QString::number(music_list_size)));
if (musics_time) {
w_courtroom->append_music(f_music);
}
else {
if (f_music.endsWith(".wav") || f_music.endsWith(".mp3") ||
f_music.endsWith(".mp4") || f_music.endsWith(".ogg") ||
f_music.endsWith(".opus")) {
musics_time = true;
areas--;
w_courtroom->fix_last_area();
w_courtroom->append_music(f_music);
}
else {
w_courtroom->append_area(f_music);
areas++;
}
}
for (int area_n = 0; area_n < areas; area_n++) {
w_courtroom->arup_append(0, "Unknown", "Unknown", "Unknown");
}
int total_loading_size =
char_list_size * 2 + evidence_list_size + music_list_size;
int loading_value = int(
((loaded_chars + generated_chars + loaded_music + loaded_evidence) /
static_cast<double>(total_loading_size)) *
100);
w_lobby->set_loading_value(loading_value);
}
QString next_packet_number = QString::number(((loaded_music - 1) / 10) + 1);
send_server_packet(new AOPacket("AM#" + next_packet_number + "#%"));
}
else if (header == "CharsCheck") {
if (!courtroom_constructed)
goto end;
@ -621,6 +466,8 @@ void AOApplication::server_packet_received(AOPacket *p_packet)
if (f_contents.size() < 3)
goto end;
w_courtroom->enter_courtroom();
if (courtroom_constructed)
w_courtroom->update_character(f_contents.at(2).toInt());
}
@ -691,6 +538,11 @@ void AOApplication::server_packet_received(AOPacket *p_packet)
if (courtroom_constructed && f_contents.size() > 0)
w_courtroom->set_mute(false, f_contents.at(0).toInt());
}
else if (header == "BB") {
if (courtroom_constructed && f_contents.size() >= 1) {
call_notice(f_contents.at(0));
}
}
else if (header == "KK") {
if (courtroom_constructed && f_contents.size() >= 1) {
call_notice(tr("You have been kicked from the server.\nReason: %1")
@ -803,19 +655,9 @@ void AOApplication::send_server_packet(AOPacket *p_packet, bool encoded)
QString f_packet = p_packet->to_string();
if (encryption_needed) {
#ifdef DEBUG_NETWORK
qDebug() << "S(e):" << f_packet;
#endif
p_packet->encrypt_header(s_decryptor);
f_packet = p_packet->to_string();
}
else {
#ifdef DEBUG_NETWORK
qDebug() << "S:" << f_packet;
#endif
}
net_manager->ship_server_packet(f_packet);

View File

@ -44,61 +44,40 @@ QString AOApplication::get_data_path() { return get_base_path() + "data/"; }
QString AOApplication::get_default_theme_path(QString p_file)
{
QString path = get_base_path() + "themes/default/" + p_file;
#ifndef CASE_SENSITIVE_FILESYSTEM
return path;
#else
return get_case_sensitive_path(path);
#endif
}
QString AOApplication::get_custom_theme_path(QString p_theme, QString p_file)
{
QString path = get_base_path() + "themes/" + p_theme + "/" + p_file;
#ifndef CASE_SENSITIVE_FILESYSTEM
return path;
#else
return get_case_sensitive_path(path);
#endif
}
QString AOApplication::get_theme_path(QString p_file)
{
QString path = get_base_path() + "themes/" + current_theme + "/" + p_file;
#ifndef CASE_SENSITIVE_FILESYSTEM
return path;
#else
return get_case_sensitive_path(path);
#endif
}
QString AOApplication::get_character_path(QString p_char, QString p_file)
{
QString path = get_base_path() + "characters/" + p_char + "/" + p_file;
#ifndef CASE_SENSITIVE_FILESYSTEM
return path;
#else
return get_case_sensitive_path(path);
#endif
}
QString AOApplication::get_sounds_path(QString p_file)
{
QString path = get_base_path() + "sounds/general/" + p_file;
#ifndef CASE_SENSITIVE_FILESYSTEM
return path;
#else
return get_case_sensitive_path(path);
#endif
}
QString AOApplication::get_music_path(QString p_song)
{
if (p_song.startsWith("http")) {
return p_song; // url
}
QString path = get_base_path() + "sounds/music/" + p_song;
#ifndef CASE_SENSITIVE_FILESYSTEM
return path;
#else
return get_case_sensitive_path(path);
#endif
}
QString AOApplication::get_background_path(QString p_file)
@ -106,11 +85,7 @@ QString AOApplication::get_background_path(QString p_file)
QString path = get_base_path() + "background/" +
w_courtroom->get_current_background() + "/" + p_file;
if (courtroom_constructed) {
#ifndef CASE_SENSITIVE_FILESYSTEM
return path;
#else
return get_case_sensitive_path(path);
#endif
}
return get_default_background_path(p_file);
}
@ -118,33 +93,30 @@ QString AOApplication::get_background_path(QString p_file)
QString AOApplication::get_default_background_path(QString p_file)
{
QString path = get_base_path() + "background/default/" + p_file;
#ifndef CASE_SENSITIVE_FILESYSTEM
return path;
#else
return get_case_sensitive_path(path);
#endif
}
QString AOApplication::get_evidence_path(QString p_file)
{
QString path = get_base_path() + "evidence/" + p_file;
#ifndef CASE_SENSITIVE_FILESYSTEM
return path;
#else
return get_case_sensitive_path(path);
#endif
}
QString AOApplication::get_case_sensitive_path(QString p_file)
{
QFileInfo file(p_file);
QString file_basename = file.fileName();
// no path traversal above base folder
if (!(file.absolutePath().startsWith(get_base_path())))
return get_base_path() + file_basename;
#ifdef CASE_SENSITIVE_FILESYSTEM
// first, check to see if it's actually there (also serves as base case for
// recursion)
if (exists(p_file))
return p_file;
QFileInfo file(p_file);
QString file_basename = file.fileName();
QString file_parent_dir = get_case_sensitive_path(file.absolutePath());
// second, does it exist in the new parent dir?
@ -163,4 +135,7 @@ QString AOApplication::get_case_sensitive_path(QString p_file)
// if nothing is found, let the caller handle the missing file
return file_parent_dir + "/" + file_basename;
#else
return p_file;
#endif
}

View File

@ -73,6 +73,13 @@ bool AOApplication::get_log_timestamp()
return result.startsWith("true");
}
bool AOApplication::get_log_ic_actions()
{
QString result =
configini->value("log_ic_actions", "true").value<QString>();
return result.startsWith("true");
}
bool AOApplication::get_showname_enabled_by_default()
{
QString result =
@ -618,12 +625,15 @@ QString AOApplication::get_char_side(QString p_char)
return f_result;
}
QString AOApplication::get_gender(QString p_char)
QString AOApplication::get_blips(QString p_char)
{
QString f_result = read_char_ini(p_char, "gender", "Options");
QString f_result = read_char_ini(p_char, "blips", "Options");
if (f_result == "")
f_result = "male";
if (f_result == "") {
f_result = read_char_ini(p_char, "gender", "Options"); // not very PC, FanatSors
if (f_result == "")
f_result = "male";
}
if (!file_exists(get_sfx_suffix(get_sounds_path(f_result)))) {
if (file_exists(get_sfx_suffix(get_sounds_path("../blips/" + f_result))))
@ -636,6 +646,8 @@ QString AOApplication::get_gender(QString p_char)
QString AOApplication::get_chat(QString p_char)
{
if (p_char == "default")
return "default";
QString f_result = read_char_ini(p_char, "chat", "Options");
// handling the correct order of chat is a bit complicated, we let the caller