Merge branch 'master' into 'bass-optional'
# Conflicts: # Attorney_Online.pro # include/aoapplication.h
This commit is contained in:
commit
4a2a167f7d
1
.gitignore
vendored
1
.gitignore
vendored
@ -5,6 +5,7 @@
|
|||||||
*.so
|
*.so
|
||||||
*.pro.autosave
|
*.pro.autosave
|
||||||
base_override.h
|
base_override.h
|
||||||
|
.DS_Store
|
||||||
|
|
||||||
base-full/
|
base-full/
|
||||||
base/
|
base/
|
||||||
|
196
.gitlab-ci.yml
Normal file
196
.gitlab-ci.yml
Normal file
@ -0,0 +1,196 @@
|
|||||||
|
stages:
|
||||||
|
- build
|
||||||
|
- deploy
|
||||||
|
- publish
|
||||||
|
|
||||||
|
cache:
|
||||||
|
key: ${CI_COMMIT_REF_SLUG}
|
||||||
|
paths:
|
||||||
|
- lib/
|
||||||
|
|
||||||
|
before_script:
|
||||||
|
- echo Current working directory is $(pwd)
|
||||||
|
|
||||||
|
build linux x86_64:
|
||||||
|
image: ubuntu
|
||||||
|
stage: build
|
||||||
|
tags:
|
||||||
|
- docker
|
||||||
|
- linux
|
||||||
|
script:
|
||||||
|
# Install dependencies
|
||||||
|
- apt-get update
|
||||||
|
- >
|
||||||
|
apt-get install --no-install-recommends -y qt5-default qtmultimedia5-dev
|
||||||
|
clang make git sudo curl ca-certificates pkg-config upx unzip
|
||||||
|
|
||||||
|
# Print versions
|
||||||
|
- qmake --version
|
||||||
|
- clang --version
|
||||||
|
|
||||||
|
# Extract BASS
|
||||||
|
- mkdir bass
|
||||||
|
- cd bass
|
||||||
|
- curl http://www.un4seen.com/files/bass24-linux.zip -o bass.zip
|
||||||
|
- unzip bass.zip
|
||||||
|
- cp x64/libbass.so ../lib
|
||||||
|
- curl http://www.un4seen.com/files/bassopus24-linux.zip -o bassopus.zip
|
||||||
|
- unzip bassopus.zip
|
||||||
|
- cp x64/libbassopus.so ../lib
|
||||||
|
- cd ..
|
||||||
|
|
||||||
|
# Extract Discord RPC
|
||||||
|
- mkdir discord-rpc
|
||||||
|
- cd discord-rpc
|
||||||
|
- curl -L https://github.com/discordapp/discord-rpc/releases/download/v3.4.0/discord-rpc-linux.zip -o discord_rpc_linux.zip
|
||||||
|
- unzip discord_rpc_linux.zip
|
||||||
|
- cp discord-rpc/linux-dynamic/lib/libdiscord-rpc.so ../lib
|
||||||
|
- cd ..
|
||||||
|
|
||||||
|
# Extract QtApng
|
||||||
|
- mkdir qtapng
|
||||||
|
- cd qtapng
|
||||||
|
- curl -L https://github.com/Skycoder42/QtApng/releases/download/1.1.0-5/build_gcc_64_5.12.0.tar.xz -o apng.tar.xz
|
||||||
|
- tar -xvf apng.tar.xz
|
||||||
|
- cp gcc_64/plugins/imageformats/libqapng.so ../lib
|
||||||
|
- cd ..
|
||||||
|
|
||||||
|
# Build
|
||||||
|
- qmake -spec linux-clang
|
||||||
|
- make -j4
|
||||||
|
|
||||||
|
# Post-processing
|
||||||
|
- upx --lzma -9 --force bin/Attorney_Online
|
||||||
|
artifacts:
|
||||||
|
paths:
|
||||||
|
- bin/
|
||||||
|
|
||||||
|
build windows i686:
|
||||||
|
image: ${CI_REGISTRY_IMAGE}/builder-windows-i686
|
||||||
|
stage: build
|
||||||
|
tags:
|
||||||
|
- docker
|
||||||
|
- linux
|
||||||
|
script:
|
||||||
|
# Install dependencies
|
||||||
|
- apt-get update
|
||||||
|
- apt-get install --no-install-recommends -y make curl ca-certificates upx unzip
|
||||||
|
|
||||||
|
# Extract BASS
|
||||||
|
- mkdir bass
|
||||||
|
- cd bass
|
||||||
|
- curl http://www.un4seen.com/files/bass24.zip -o bass.zip
|
||||||
|
- unzip bass.zip
|
||||||
|
- cp bass.dll ../lib
|
||||||
|
- curl http://www.un4seen.com/files/bassopus24.zip -o bassopus.zip
|
||||||
|
- unzip bassopus.zip
|
||||||
|
- cp bassopus.dll ../lib
|
||||||
|
- cd ..
|
||||||
|
|
||||||
|
# Build
|
||||||
|
- /opt/mxe/usr/${TARGET_SPEC}/qt5/bin/qmake
|
||||||
|
- make -j4
|
||||||
|
|
||||||
|
# Post-processing
|
||||||
|
- upx --lzma -9 --force bin/Attorney_Online.exe
|
||||||
|
artifacts:
|
||||||
|
paths:
|
||||||
|
- bin/
|
||||||
|
|
||||||
|
# Base folder
|
||||||
|
.deploy_base: &deploy_base |
|
||||||
|
mkdir base
|
||||||
|
mkdir base/themes
|
||||||
|
cp -a ../base/themes/default base/themes/
|
||||||
|
cp -a ../base/config.ini base/config.sample.ini
|
||||||
|
cp -a ../base/serverlist.txt base/serverlist.sample.txt
|
||||||
|
|
||||||
|
# Miscellaneous files
|
||||||
|
.deploy_misc: &deploy_misc |
|
||||||
|
cp -a ../README.md README.md.txt
|
||||||
|
cp -a ../LICENSE.MIT LICENSE.txt
|
||||||
|
|
||||||
|
deploy linux x86_64:
|
||||||
|
stage: deploy
|
||||||
|
dependencies:
|
||||||
|
- build linux x86_64
|
||||||
|
tags:
|
||||||
|
- docker
|
||||||
|
- linux
|
||||||
|
script:
|
||||||
|
- mkdir artifact
|
||||||
|
- cd artifact
|
||||||
|
- *deploy_base
|
||||||
|
- *deploy_misc
|
||||||
|
|
||||||
|
# Platform-specific
|
||||||
|
- cp -a ../lib/*.so .
|
||||||
|
- cp -a ../bin/Attorney_Online .
|
||||||
|
- echo "#!/bin/sh" >> ./run.sh
|
||||||
|
- echo "LD_LIBRARY_PATH=.:\$LD_LIBRARY_PATH ./Attorney_Online" >> ./run.sh
|
||||||
|
- chmod +x ./run.sh
|
||||||
|
|
||||||
|
# Zipping
|
||||||
|
# zip -r -9 -l Attorney_Online_$(git describe --tags)_linux_x86_64.zip .
|
||||||
|
- mkdir ../zip
|
||||||
|
- tar cavf ../zip/Attorney_Online_$(git describe --tags)_linux_x64.tar.xz *
|
||||||
|
- sha1sum ../zip/*
|
||||||
|
artifacts:
|
||||||
|
paths:
|
||||||
|
- zip/
|
||||||
|
|
||||||
|
deploy windows i686:
|
||||||
|
image: ubuntu
|
||||||
|
stage: deploy
|
||||||
|
dependencies:
|
||||||
|
- build windows i686
|
||||||
|
tags:
|
||||||
|
- docker
|
||||||
|
- linux
|
||||||
|
script:
|
||||||
|
- apt-get update
|
||||||
|
- apt-get install --no-install-recommends -y zip git
|
||||||
|
|
||||||
|
- mkdir artifact
|
||||||
|
- cd artifact
|
||||||
|
- *deploy_base
|
||||||
|
- *deploy_misc
|
||||||
|
|
||||||
|
# Platform-specific
|
||||||
|
- cp -a ../lib/*.dll .
|
||||||
|
- cp -a ../bin/Attorney_Online.exe .
|
||||||
|
|
||||||
|
# Zipping
|
||||||
|
# -r: recursive; -9: max compression; -l: convert to CR LF
|
||||||
|
- mkdir ../zip
|
||||||
|
- zip -r -9 -l ../zip/Attorney_Online_$(git describe --tags)_windows_x86.zip .
|
||||||
|
- sha1sum ../zip/*
|
||||||
|
artifacts:
|
||||||
|
paths:
|
||||||
|
- zip/
|
||||||
|
|
||||||
|
publish linux x86_64:
|
||||||
|
image: ubuntu
|
||||||
|
stage: publish
|
||||||
|
dependencies:
|
||||||
|
- deploy linux x86_64
|
||||||
|
when: manual
|
||||||
|
script:
|
||||||
|
- cd zip
|
||||||
|
- ../scripts/wasabi.sh
|
||||||
|
variables:
|
||||||
|
MANIFEST: program_linux_x86_64.json
|
||||||
|
ARTIFACT_SUFFIX: _linux_x64.tar.xz
|
||||||
|
|
||||||
|
publish windows i686:
|
||||||
|
image: ubuntu
|
||||||
|
stage: publish
|
||||||
|
dependencies:
|
||||||
|
- deploy windows i686
|
||||||
|
when: manual
|
||||||
|
script:
|
||||||
|
- cd zip
|
||||||
|
- ../scripts/wasabi.sh
|
||||||
|
variables:
|
||||||
|
MANIFEST: program_winnt_i386.json
|
||||||
|
ARTIFACT_SUFFIX: _windows_x86.zip
|
11
.travis.yml
Normal file
11
.travis.yml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
language: cpp
|
||||||
|
os: osx
|
||||||
|
|
||||||
|
addons:
|
||||||
|
homebrew:
|
||||||
|
packages:
|
||||||
|
- qt5
|
||||||
|
|
||||||
|
script:
|
||||||
|
- ./scripts/macos_build.sh
|
||||||
|
- ./scripts/macos_post_build.sh
|
@ -16,13 +16,13 @@ HEADERS += $$files($$PWD/include/*.h)
|
|||||||
|
|
||||||
LIBS += -L$$PWD/lib
|
LIBS += -L$$PWD/lib
|
||||||
|
|
||||||
#DEFINES += DISCORD
|
DEFINES += DISCORD
|
||||||
|
|
||||||
contains(DEFINES, DISCORD) {
|
contains(DEFINES, DISCORD) {
|
||||||
LIBS += -ldiscord-rpc
|
LIBS += -ldiscord-rpc
|
||||||
}
|
}
|
||||||
|
|
||||||
#DEFINES += BASSAUDIO
|
DEFINES += BASSAUDIO
|
||||||
|
|
||||||
contains(DEFINES, BASSAUDIO) {
|
contains(DEFINES, BASSAUDIO) {
|
||||||
LIBS += -lbass
|
LIBS += -lbass
|
||||||
@ -34,6 +34,9 @@ contains(DEFINES, QTAUDIO) {
|
|||||||
QT += multimedia
|
QT += multimedia
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macx:LIBS += -framework CoreFoundation -framework Foundation -framework CoreServices
|
||||||
|
|
||||||
|
|
||||||
CONFIG += c++14
|
CONFIG += c++14
|
||||||
|
|
||||||
RESOURCES += resources.qrc
|
RESOURCES += resources.qrc
|
||||||
|
@ -8,22 +8,40 @@ This program has five main dependencies
|
|||||||
* Discord Rich Presence (https://github.com/discordapp/discord-rpc/releases)
|
* Discord Rich Presence (https://github.com/discordapp/discord-rpc/releases)
|
||||||
* Qt Apng Plugin (https://github.com/Skycoder42/QtApng/releases)
|
* Qt Apng Plugin (https://github.com/Skycoder42/QtApng/releases)
|
||||||
|
|
||||||
|
### Help
|
||||||
|
|
||||||
|
If you're having issues with any of this, ask in the offical Discord: https://discord.gg/wWvQ3pw
|
||||||
|
Alternatively, you can ask OmniTroid#4004 on Discord.
|
||||||
|
|
||||||
### How to build dynamically (the easy way)
|
### How to build dynamically (the easy way)
|
||||||
|
|
||||||
|
#### General preparation
|
||||||
|
|
||||||
What you want to do is first download the latest version of Qt from the first link. (get the prebuilt dynamic version)
|
What you want to do is first download the latest version of Qt from the first link. (get the prebuilt dynamic version)
|
||||||
If you're on Ubuntu, go to the scripts/ folder and run configure_ubuntu.sh. This should fetch all the required dependencies automatically.
|
After going through the OS-specific steps below, compiling in Qt creator should work.
|
||||||
If not, go to each one of the links above and find the right dynamic library for your platform:
|
|
||||||
* Windows: .dll
|
|
||||||
* Linux: .so
|
|
||||||
* Mac: .dylib
|
|
||||||
|
|
||||||
And put them in BOTH lib/ and the repository root (lib/ is required for linking and root is required for runtime)
|
#### Windows
|
||||||
|
|
||||||
Launch Qt creator, open the .pro file and try running it. Ask in the Discord if you're having issues: https://discord.gg/wWvQ3pw
|
If you're on Windows, you need to go find all the dependencies (see above) and put them in the lib/ folder.
|
||||||
|
|
||||||
|
#### MacOS
|
||||||
|
|
||||||
|
If you're on MacOS, you can simply go to terminal and run ./scripts/configure_macos.sh
|
||||||
|
This will automatically fetch all the required dependencies. Additionally, if you need to create a standalone release, just run ./scripts/release_macos.sh
|
||||||
|
This will make the .app bundle in bin/ able to execute as a standalone.
|
||||||
|
|
||||||
|
#### Ubuntu
|
||||||
|
|
||||||
|
If you're on Ubuntu, just go to terminal and run ./scripts/configure_ubuntu.sh
|
||||||
|
This should fetch all the required dependencies automatically.
|
||||||
|
|
||||||
|
#### Other Linux
|
||||||
|
|
||||||
|
With some tweaks to the ubuntu script, it shouldn't be a big hassle to compile it on a modern linux. Look in the script and see what you may have to modify.
|
||||||
|
|
||||||
### How to build statically (the hard way)
|
### How to build statically (the hard way)
|
||||||
|
|
||||||
You're gonna have a bad time.
|
You're gonna have a bad time.
|
||||||
|
|
||||||
Building statically means you can distribute the final program without needing to pack alongside a lot of dynamic libraries.
|
Building statically means you can distribute the final program without needing to pack alongside a lot of dynamic libraries.
|
||||||
This is a tricky process and is not recommended unless you know what you're doing.
|
This is a tricky process and is not recommended unless you know what you're doing.
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include <QTextStream>
|
#include <QTextStream>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
#include <QColor>
|
#include <QColor>
|
||||||
|
#include <QScreen>
|
||||||
|
|
||||||
class NetworkManager;
|
class NetworkManager;
|
||||||
class Lobby;
|
class Lobby;
|
||||||
|
@ -35,8 +35,10 @@ protected:
|
|||||||
void enterEvent(QEvent *e);
|
void enterEvent(QEvent *e);
|
||||||
void leaveEvent(QEvent *e);
|
void leaveEvent(QEvent *e);
|
||||||
void mouseDoubleClickEvent(QMouseEvent *e);
|
void mouseDoubleClickEvent(QMouseEvent *e);
|
||||||
|
/*
|
||||||
void dragLeaveEvent(QMouseEvent *e);
|
void dragLeaveEvent(QMouseEvent *e);
|
||||||
void dragEnterEvent(QMouseEvent *e);
|
void dragEnterEvent(QMouseEvent *e);
|
||||||
|
*/
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void evidence_clicked(int p_id);
|
void evidence_clicked(int p_id);
|
||||||
|
@ -35,7 +35,6 @@
|
|||||||
#include <QSlider>
|
#include <QSlider>
|
||||||
#include <QVector>
|
#include <QVector>
|
||||||
#include <QCloseEvent>
|
#include <QCloseEvent>
|
||||||
#include <QSignalMapper>
|
|
||||||
#include <QMap>
|
#include <QMap>
|
||||||
#include <QTextBrowser>
|
#include <QTextBrowser>
|
||||||
#include <QSpinBox>
|
#include <QSpinBox>
|
||||||
@ -48,6 +47,7 @@
|
|||||||
#include <QFont>
|
#include <QFont>
|
||||||
#include <QInputDialog>
|
#include <QInputDialog>
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
|
#include <QTextBoundaryFinder>
|
||||||
|
|
||||||
#include <stack>
|
#include <stack>
|
||||||
|
|
||||||
@ -272,8 +272,6 @@ private:
|
|||||||
QVector<QString> arup_cms;
|
QVector<QString> arup_cms;
|
||||||
QVector<QString> arup_locks;
|
QVector<QString> arup_locks;
|
||||||
|
|
||||||
QSignalMapper *char_button_mapper;
|
|
||||||
|
|
||||||
QVector<chatlogpiece> ic_chatlog_history;
|
QVector<chatlogpiece> ic_chatlog_history;
|
||||||
|
|
||||||
// These map music row items and area row items to their actual IDs.
|
// These map music row items and area row items to their actual IDs.
|
||||||
@ -537,6 +535,7 @@ private:
|
|||||||
void construct_char_select();
|
void construct_char_select();
|
||||||
void set_char_select();
|
void set_char_select();
|
||||||
void set_char_select_page();
|
void set_char_select_page();
|
||||||
|
void char_clicked(int n_char);
|
||||||
void put_button_in_place(int starting, int chars_on_this_page);
|
void put_button_in_place(int starting, int chars_on_this_page);
|
||||||
void filter_character_list();
|
void filter_character_list();
|
||||||
|
|
||||||
@ -651,14 +650,12 @@ private slots:
|
|||||||
|
|
||||||
void on_char_select_left_clicked();
|
void on_char_select_left_clicked();
|
||||||
void on_char_select_right_clicked();
|
void on_char_select_right_clicked();
|
||||||
void on_char_search_changed(const QString& newtext);
|
void on_char_search_changed();
|
||||||
void on_char_taken_clicked(int newstate);
|
void on_char_taken_clicked();
|
||||||
void on_char_passworded_clicked(int newstate);
|
void on_char_passworded_clicked();
|
||||||
|
|
||||||
void on_spectator_clicked();
|
void on_spectator_clicked();
|
||||||
|
|
||||||
void char_clicked(int n_char);
|
|
||||||
|
|
||||||
void on_switch_area_music_clicked();
|
void on_switch_area_music_clicked();
|
||||||
|
|
||||||
void on_casing_clicked();
|
void on_casing_clicked();
|
||||||
|
@ -44,13 +44,14 @@ public:
|
|||||||
QString ms_nosrv_hostname = "master.aceattorneyonline.com";
|
QString ms_nosrv_hostname = "master.aceattorneyonline.com";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const int ms_port = 27016;
|
const quint16 ms_port = 27016;
|
||||||
const int timeout_milliseconds = 2000;
|
const int timeout_milliseconds = 2000;
|
||||||
|
|
||||||
const int ms_reconnect_delay_ms = 7000;
|
// in seconds
|
||||||
|
const int ms_reconnect_delay = 7;
|
||||||
|
|
||||||
// kind of arbitrary max buffer size
|
// kind of arbitrary max buffer size
|
||||||
const size_t buffer_max_size = 16384;
|
#define BUFFER_MAX_SIZE 16384
|
||||||
|
|
||||||
bool ms_partial_packet = false;
|
bool ms_partial_packet = false;
|
||||||
QString ms_temp_packet = "";
|
QString ms_temp_packet = "";
|
||||||
|
6
scripts/.gitignore
vendored
Normal file
6
scripts/.gitignore
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
node_modules/
|
||||||
|
|
||||||
|
# Cursed file
|
||||||
|
package-lock.json
|
||||||
|
|
||||||
|
s3_keys.sh
|
42
scripts/configure_macos.sh
Executable file
42
scripts/configure_macos.sh
Executable file
@ -0,0 +1,42 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# This script fetches all build dependencies for MacOS
|
||||||
|
# Tested on MacOS 10.14 (Mojave), Qt 5.13 and XCode 10.2
|
||||||
|
|
||||||
|
# Exit on errors and unset variables
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
ROOT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )/"
|
||||||
|
|
||||||
|
cd ${ROOT_DIR}
|
||||||
|
|
||||||
|
LIB_TARGET="../../lib"
|
||||||
|
BASS_LINK="http://uk.un4seen.com/files/bass24-osx.zip"
|
||||||
|
BASSOPUS_LINK="http://www.un4seen.com/files/bassopus24-osx.zip"
|
||||||
|
DISCORD_RPC_LINK="https://github.com/discordapp/discord-rpc/releases/download/v3.4.0/discord-rpc-osx.zip"
|
||||||
|
APNG_LINK="https://github.com/Skycoder42/QtApng/releases/download/1.1.2-2/qtapng_clang_64_5.13.0.tar.xz"
|
||||||
|
|
||||||
|
# Easier if we don't need to worry about an existing tmp folder tbh smh
|
||||||
|
# v Add a slash here for free tmp folder cleanup in true javascript community style
|
||||||
|
rm -rf tmp
|
||||||
|
mkdir tmp
|
||||||
|
cd tmp
|
||||||
|
|
||||||
|
curl -Ls ${BASS_LINK} -o bass.zip
|
||||||
|
unzip -qq bass.zip
|
||||||
|
cp libbass.dylib ${LIB_TARGET}
|
||||||
|
|
||||||
|
curl -Ls ${BASSOPUS_LINK} -o bassopus.zip
|
||||||
|
unzip -qq bassopus.zip
|
||||||
|
cp libbassopus.dylib ${LIB_TARGET}
|
||||||
|
|
||||||
|
curl -Ls ${DISCORD_RPC_LINK} -o discord_rpc.zip
|
||||||
|
unzip -qq discord_rpc.zip
|
||||||
|
cp discord-rpc/osx-dynamic/lib/libdiscord-rpc.dylib ${LIB_TARGET}
|
||||||
|
|
||||||
|
curl -Ls ${APNG_LINK} -o apng.tar.xz
|
||||||
|
tar -xf apng.tar.xz
|
||||||
|
cp clang_64/plugins/imageformats/libqapng.dylib ../../lib
|
||||||
|
|
||||||
|
cd ..
|
||||||
|
rm -rf tmp
|
@ -1,6 +1,13 @@
|
|||||||
#!/bin/bash
|
#!/bin/sh
|
||||||
|
|
||||||
#assumes a somewhat recent 64-bit ubuntu
|
# Assumes a somewhat recent 64-bit ubuntu
|
||||||
|
|
||||||
|
# Exit on errors and unset variables
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
ROOT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )/"
|
||||||
|
|
||||||
|
cd ${ROOT_DIR}
|
||||||
|
|
||||||
#need some openGL stuff
|
#need some openGL stuff
|
||||||
sudo apt install libgl1-mesa-dev
|
sudo apt install libgl1-mesa-dev
|
||||||
|
33
scripts/macos_build.sh
Executable file
33
scripts/macos_build.sh
Executable file
@ -0,0 +1,33 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -Eexo pipefail
|
||||||
|
|
||||||
|
export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/lib/pkgconfig:/usr/local/opt/openssl/lib/pkgconfig
|
||||||
|
export PATH=$PATH:/usr/local/opt/qt5/bin:/usr/local/bin
|
||||||
|
|
||||||
|
mkdir bass
|
||||||
|
cd bass
|
||||||
|
curl http://www.un4seen.com/files/bass24-osx.zip -o bass.zip
|
||||||
|
unzip bass.zip
|
||||||
|
cp libbass.dylib ../lib
|
||||||
|
|
||||||
|
curl http://www.un4seen.com/files/bassopus24-osx.zip -o bassopus.zip
|
||||||
|
unzip bassopus.zip
|
||||||
|
cp libbassopus.dylib ../lib
|
||||||
|
cd ..
|
||||||
|
|
||||||
|
mkdir discord-rpc
|
||||||
|
cd discord-rpc
|
||||||
|
curl -L https://github.com/discordapp/discord-rpc/releases/download/v3.4.0/discord-rpc-osx.zip -o discord_rpc_osx.zip
|
||||||
|
unzip discord_rpc_osx.zip
|
||||||
|
cp discord-rpc/osx-static/lib/libdiscord-rpc.a ../lib
|
||||||
|
cd ..
|
||||||
|
|
||||||
|
mkdir qtapng
|
||||||
|
cd qtapng
|
||||||
|
curl -L https://github.com/Skycoder42/QtApng/releases/download/1.1.0-5/build_clang_64_5.12.0.tar.xz -o apng.tar.xz
|
||||||
|
tar -xvf apng.tar.xz
|
||||||
|
cp clang_64/plugins/imageformats/libqapng.dylib ../lib
|
||||||
|
cd ..
|
||||||
|
|
||||||
|
qmake && make -j2
|
@ -1,16 +1,22 @@
|
|||||||
#!/bin/bash
|
#!/bin/sh
|
||||||
|
|
||||||
DST_FOLDER="./bin/Attorney_Online.app/Contents/Frameworks"
|
# This script prepares the compiled bundle for shipping as a standalone release
|
||||||
|
# Assumes the Qt bin folder is in PATH
|
||||||
|
# Should be used on a "Release" build from QT creator
|
||||||
|
# Note that this DOES NOT add the base/ folder
|
||||||
|
|
||||||
cd ..
|
# Exit on errors and unset variables
|
||||||
|
set -eu
|
||||||
|
|
||||||
mkdir $DST_FOLDER
|
ROOT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )/"
|
||||||
|
|
||||||
cp ./lib/libbass.dylib $DST_FOLDER
|
cd ${ROOT_DIR}
|
||||||
cp ./lib/libbassopus.dylib $DST_FOLDER
|
|
||||||
|
|
||||||
install_name_tool -id @executable_path/../Frameworks/libbass.dylib $DST_FOLDER/libbass.dylib
|
# This thing basically does all the work
|
||||||
|
macdeployqt ../bin/Attorney_Online.app
|
||||||
|
|
||||||
install_name_tool -id @executable_path/../Frameworks/libbassopus.dylib $DST_FOLDER/libbassopus.dylib
|
# Need to add the dependencies
|
||||||
|
cp ../lib/* ../bin/Attorney_Online.app/Contents/Frameworks
|
||||||
|
|
||||||
install_name_tool -change @loader_path/libbass.dylib @executable_path/../Frameworks/libbass.dylib ./bin/Attorney_Online.app/Contents/MacOS/Attorney_Online
|
# libbass has a funny path for some reason, just use rpath
|
||||||
|
install_name_tool -change @loader_path/libbass.dylib @rpath/libbass.dylib ../bin/Attorney_Online.app/Contents/MacOS/Attorney_Online
|
||||||
|
9
scripts/package.json
Normal file
9
scripts/package.json
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"name": "ao-ci-scripts",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"main": "update_manifest.js",
|
||||||
|
"dependencies": {
|
||||||
|
"argparse": "^1.0.10"
|
||||||
|
},
|
||||||
|
"license": "ISC"
|
||||||
|
}
|
22
scripts/release_macos.sh
Executable file
22
scripts/release_macos.sh
Executable file
@ -0,0 +1,22 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# This script prepares the compiled bundle for shipping as a standalone release
|
||||||
|
# Assumes the Qt bin folder is in PATH
|
||||||
|
# Should be used on a "Release" build from QT creator
|
||||||
|
# Note that this DOES NOT add the base/ folder
|
||||||
|
|
||||||
|
# Exit on errors and unset variables
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
ROOT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )/"
|
||||||
|
|
||||||
|
cd ${ROOT_DIR}
|
||||||
|
|
||||||
|
# This thing basically does all the work
|
||||||
|
macdeployqt ../bin/Attorney_Online.app
|
||||||
|
|
||||||
|
# Need to add the dependencies
|
||||||
|
cp ../lib/* ../bin/Attorney_Online.app/Contents/Frameworks
|
||||||
|
|
||||||
|
# libbass has a funny path for some reason, just use rpath
|
||||||
|
install_name_tool -change @loader_path/libbass.dylib @rpath/libbass.dylib ../bin/Attorney_Online.app/Contents/MacOS/Attorney_Online
|
151
scripts/update_manifest.js
Executable file
151
scripts/update_manifest.js
Executable file
@ -0,0 +1,151 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
const fs = require("fs");
|
||||||
|
const crypto = require("crypto");
|
||||||
|
const path = require("path");
|
||||||
|
const ArgumentParser = require("argparse").ArgumentParser;
|
||||||
|
|
||||||
|
function isFile(file) {
|
||||||
|
if (!fs.existsSync(file)) {
|
||||||
|
console.error(`File '${file}' not found. Try again.`);
|
||||||
|
throw Error();
|
||||||
|
}
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
|
const argParser = new ArgumentParser({
|
||||||
|
addHelp: true,
|
||||||
|
description: "Adds a new latest version to the manifest file based on the " +
|
||||||
|
"provided zip file, including an incremental update."
|
||||||
|
});
|
||||||
|
argParser.addArgument("manifestFile", {
|
||||||
|
metavar: "<manifest file>", type: isFile
|
||||||
|
});
|
||||||
|
argParser.addArgument("version", {
|
||||||
|
metavar: "<version>"
|
||||||
|
});
|
||||||
|
argParser.addArgument([ "-f", "--full" ], {
|
||||||
|
metavar: "<full zip file>", type: isFile, nargs: 1,
|
||||||
|
dest: "fullZipFileArgs"
|
||||||
|
});
|
||||||
|
argParser.addArgument([ "-i", "--incremental" ], {
|
||||||
|
type: isFile, nargs: 2, dest: "incrementalArgs",
|
||||||
|
metavar: ["<incremental zip file>", "<file containing list of changed files>"]
|
||||||
|
});
|
||||||
|
argParser.addArgument([ "-e", "--executable" ], {
|
||||||
|
metavar: "[executable file]", nargs: 1,
|
||||||
|
dest: "executableArgs"
|
||||||
|
});
|
||||||
|
|
||||||
|
const {
|
||||||
|
manifestFile,
|
||||||
|
version,
|
||||||
|
fullZipFileArgs,
|
||||||
|
incrementalArgs,
|
||||||
|
executableArgs
|
||||||
|
} = argParser.parseArgs();
|
||||||
|
|
||||||
|
const [incrementalZipFile, changesFile] = incrementalArgs || [];
|
||||||
|
const [fullZipFile] = fullZipFileArgs || [];
|
||||||
|
const [executable] = executableArgs || [];
|
||||||
|
|
||||||
|
// Do one final check
|
||||||
|
if (!incrementalZipFile && !fullZipFile) {
|
||||||
|
console.error("No download archive specified! Abort.");
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do a quick litmus test to prevent deleting everything incorrectly
|
||||||
|
if (changesFile && !fs.existsSync("base")) {
|
||||||
|
console.error("The working directory must be set to an " +
|
||||||
|
"asset folder in order for deleted directories " +
|
||||||
|
"to be calculated correctly. Abort.");
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
const manifest = JSON.parse(fs.readFileSync(manifestFile));
|
||||||
|
|
||||||
|
const dirsDeleted = new Set();
|
||||||
|
const specialActions = changesFile ?
|
||||||
|
fs.readFileSync(changesFile)
|
||||||
|
.toString()
|
||||||
|
.trim()
|
||||||
|
.split("\n")
|
||||||
|
.map(line => line.split("\t"))
|
||||||
|
.map(([mode, target, source]) => {
|
||||||
|
switch (mode[0]) {
|
||||||
|
case "D": // Deleted
|
||||||
|
// Check if the folder exists relative to the working
|
||||||
|
// directory, and if not, add it to the dirsDeleted list.
|
||||||
|
// Keep going up the tree to see how many directories were
|
||||||
|
// deleted.
|
||||||
|
let dir = path.dirname(target);
|
||||||
|
while (!dirsDeleted.has(dir) && !fs.existsSync(dir)) {
|
||||||
|
dirsDeleted.add(dir);
|
||||||
|
dir = path.dirname(dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
return { action: "delete", target };
|
||||||
|
case "R": // Renamed
|
||||||
|
// NOTE: Make sure that the launcher's implementation of
|
||||||
|
// the move action also creates directories when needed.
|
||||||
|
return { action: "move", source, target};
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
// Remove ignored file mode changes
|
||||||
|
.filter(action => action !== null)
|
||||||
|
// Create actions based on directories to be deleted.
|
||||||
|
// Always have deeper directories first, to guarantee that deleting
|
||||||
|
// higher-level directories will succeed.
|
||||||
|
.concat(Array.from(dirsDeleted.values())
|
||||||
|
.sort((a, b) => b.split("/").length - a.split("/").length)
|
||||||
|
.map(dir => {
|
||||||
|
return { action: "deleteDir", target: dir };
|
||||||
|
}))
|
||||||
|
: [];
|
||||||
|
|
||||||
|
const urlBase = "https://s3.wasabisys.com/ao-downloads/";
|
||||||
|
|
||||||
|
const versionEntry = {
|
||||||
|
version,
|
||||||
|
executable,
|
||||||
|
prev: manifest.versions[0] ? manifest.versions[0].version : undefined,
|
||||||
|
full: fullZipFile ? [
|
||||||
|
{
|
||||||
|
action: "dl",
|
||||||
|
url: urlBase + encodeURIComponent(path.basename(fullZipFile)),
|
||||||
|
hash: crypto.createHash("sha1")
|
||||||
|
.update(fs.readFileSync(fullZipFile))
|
||||||
|
.digest("hex")
|
||||||
|
}
|
||||||
|
] : undefined,
|
||||||
|
update: incrementalArgs ? [
|
||||||
|
...specialActions,
|
||||||
|
{
|
||||||
|
action: "dl",
|
||||||
|
url: urlBase + encodeURIComponent(path.basename(incrementalZipFile)),
|
||||||
|
hash: crypto.createHash("sha1")
|
||||||
|
.update(fs.readFileSync(incrementalZipFile))
|
||||||
|
.digest("hex")
|
||||||
|
}
|
||||||
|
] : undefined
|
||||||
|
};
|
||||||
|
|
||||||
|
console.log("Generated version entry:", versionEntry);
|
||||||
|
|
||||||
|
const existingVersions = manifest.versions.filter(v => v.version == version);
|
||||||
|
if (existingVersions.length > 0) {
|
||||||
|
console.warn(`Warning: version ${version} already exists. Adding new values.`);
|
||||||
|
|
||||||
|
// Don't overwrite prev - it will cause headaches
|
||||||
|
delete versionEntry.prev;
|
||||||
|
|
||||||
|
Object.assign(existingVersions[0], versionEntry);
|
||||||
|
console.log("Merged version entry:", existingVersions[0]);
|
||||||
|
} else {
|
||||||
|
manifest.versions = [versionEntry, ...manifest.versions];
|
||||||
|
}
|
||||||
|
|
||||||
|
fs.writeFileSync(manifestFile, JSON.stringify(manifest, null, 4));
|
39
scripts/update_program_manifest.js
Executable file
39
scripts/update_program_manifest.js
Executable file
@ -0,0 +1,39 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
const fs = require("fs");
|
||||||
|
const crypto = require("crypto");
|
||||||
|
|
||||||
|
const [ _nodeExe, _jsPath, manifestFile, version, zipFile ] = process.argv;
|
||||||
|
|
||||||
|
if (!manifestFile || !version || !zipFile) {
|
||||||
|
console.log(`Usage: update_program_manifest <manifest file> <version> <zip file>`);
|
||||||
|
console.log(`Adds a new latest version to the manifest file based on the ` +
|
||||||
|
`provided zip file.`);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fs.existsSync(manifestFile)) {
|
||||||
|
console.error(`Manifest file '${manifestFile}' not found. Try again.`);
|
||||||
|
process.exit(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fs.existsSync(zipFile)) {
|
||||||
|
console.error(`Zip file '${zipFile}' not found. Try again.`);
|
||||||
|
process.exit(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
const manifest = JSON.parse(fs.readFileSync(manifestFile));
|
||||||
|
|
||||||
|
manifest.versions = [{
|
||||||
|
version,
|
||||||
|
executable: "Attorney_Online.exe",
|
||||||
|
full: [
|
||||||
|
{
|
||||||
|
action: "dl",
|
||||||
|
url: "https://s3.wasabisys.com/ao-downloads/" + encodeURIComponent(zipFile),
|
||||||
|
hash: crypto.createHash("sha1").update(fs.readFileSync(zipFile)).digest("hex")
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}, ...manifest.versions];
|
||||||
|
|
||||||
|
fs.writeFileSync(manifestFile, JSON.stringify(manifest, null, 4));
|
73
scripts/wasabi.sh
Executable file
73
scripts/wasabi.sh
Executable file
@ -0,0 +1,73 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Updates the specified program manifest to a new archive and version
|
||||||
|
# and uploads the new archive and manifest to S3/Wasabi.
|
||||||
|
#
|
||||||
|
# Requires:
|
||||||
|
# MANIFEST: name of the manifest file
|
||||||
|
# S3_ACCESS_KEY, S3_SECRET_KEY: S3 credentials
|
||||||
|
# S3_MANIFESTS, S3_ARCHIVES: S3 paths to manifests and downloads
|
||||||
|
# ARCHIVE_FULL: name of the full archive (if desired)
|
||||||
|
# ARCHIVE_INCR: name of the incremental archive (if desired)
|
||||||
|
# VERSION: name of the new version
|
||||||
|
# EXECUTABLE: name of the executable (if program manifest)
|
||||||
|
|
||||||
|
|
||||||
|
# -E: inherit ERR trap by shell functions
|
||||||
|
# -e: stop script on ERR trap
|
||||||
|
# -u: stop script on unbound variables
|
||||||
|
# -x: print command before running it
|
||||||
|
# -o pipefail: fail if any command in a pipeline fails
|
||||||
|
set -Eeuxo pipefail
|
||||||
|
|
||||||
|
aws configure set aws_access_key_id ${S3_ACCESS_KEY}
|
||||||
|
aws configure set aws_secret_access_key ${S3_SECRET_KEY}
|
||||||
|
aws configure set default.region us-east-1
|
||||||
|
|
||||||
|
export S3_COPY="aws s3 cp --endpoint-url=https://s3.wasabisys.com"
|
||||||
|
|
||||||
|
export ARCHIVE_FULL_ARG=""
|
||||||
|
export ARCHIVE_INCR_ARG=""
|
||||||
|
export EXECUTABLE_ARG=""
|
||||||
|
|
||||||
|
export LAST_TAGGED_VERSION=$(git rev-list --tags --skip=1 --max-count=1)
|
||||||
|
echo "Previous tagged version: ${LAST_TAGGED_VERSION}"
|
||||||
|
echo "Current tagged version: ${VERSION}"
|
||||||
|
|
||||||
|
if [[ -n $ARCHIVE_INCR && -n $LAST_TAGGED_VERSION ]]; then
|
||||||
|
echo "Incremental archive: ${ARCHIVE_INCR}"
|
||||||
|
|
||||||
|
# Get all files
|
||||||
|
export CHANGES_FILE="changes.txt"
|
||||||
|
git diff --name-status ${LAST_TAGGED_VERSION}..HEAD > ${CHANGES_FILE}
|
||||||
|
|
||||||
|
# Get added/modified files
|
||||||
|
git diff --name-only --diff-filter=dr ${LAST_TAGGED_VERSION}..HEAD | \
|
||||||
|
zip ${ARCHIVE_INCR} -@
|
||||||
|
|
||||||
|
export ARCHIVE_INCR_ARG="-i ${ARCHIVE_INCR} ${CHANGES_FILE}"
|
||||||
|
elif [[ -n $ARCHIVE_INCR && -z $LAST_TAGGED_VERSION ]]; then
|
||||||
|
echo "Incremental archive was requested, but there is no previous version"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -n $ARCHIVE_FULL ]]; then
|
||||||
|
echo "Full archive: ${ARCHIVE_INCR}"
|
||||||
|
export ARCHIVE_FULL_ARG="-f ${ARCHIVE_FULL}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -v EXECUTABLE ]]; then
|
||||||
|
export EXECUTABLE_ARG="-e ${EXECUTABLE}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
${S3_COPY} ${S3_MANIFESTS}/${MANIFEST} .
|
||||||
|
node $(dirname $0)/update_manifest.js ${MANIFEST} ${VERSION} \
|
||||||
|
${ARCHIVE_FULL_ARG} ${ARCHIVE_INCR_ARG} ${EXECUTABLE_ARG}
|
||||||
|
|
||||||
|
if [[ -n $ARCHIVE_INCR_ARG ]]; then
|
||||||
|
${S3_COPY} ${ARCHIVE_INCR} ${S3_ARCHIVES}
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -n $ARCHIVE_FULL_ARG ]]; then
|
||||||
|
${S3_COPY} ${ARCHIVE_FULL} ${S3_ARCHIVES}
|
||||||
|
fi
|
||||||
|
|
||||||
|
${S3_COPY} ${MANIFEST} ${S3_MANIFESTS}
|
35
scripts/wasabi_program.sh
Executable file
35
scripts/wasabi_program.sh
Executable file
@ -0,0 +1,35 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# Updates the specified program manifest to a new archive and version
|
||||||
|
# and uploads the new archive and manifest to S3/Wasabi.
|
||||||
|
#
|
||||||
|
# Requires:
|
||||||
|
# MANIFEST: name of the manifest file
|
||||||
|
# ARTIFACT_SUFFIX: suffix of the archive to be uploaded (including extension)
|
||||||
|
# S3_ACCESS_KEY and S3_SECRET_KEY
|
||||||
|
|
||||||
|
|
||||||
|
# -E: inherit ERR trap by shell functions
|
||||||
|
# -e: stop script on ERR trap
|
||||||
|
# -u: stop script on unbound variables
|
||||||
|
# -x: print command before running it
|
||||||
|
# -o pipefail: fail if any command in a pipeline fails
|
||||||
|
set -Eeuxo pipefail
|
||||||
|
|
||||||
|
aws configure set aws_access_key_id ${S3_ACCESS_KEY}
|
||||||
|
aws configure set aws_secret_access_key ${S3_SECRET_KEY}
|
||||||
|
aws configure set default.region us-east-1
|
||||||
|
|
||||||
|
export S3_COPY="aws s3 cp --endpoint-url=https://s3.wasabisys.com"
|
||||||
|
export S3_MANIFESTS="s3://ao-manifests"
|
||||||
|
export S3_ARCHIVES="s3://ao-downloads"
|
||||||
|
|
||||||
|
export VERSION=$(git describe --tags)
|
||||||
|
export ARCHIVE="Attorney_Online_${VERSION}_${ARTIFACT_SUFFIX}"
|
||||||
|
|
||||||
|
${S3_COPY} ${S3_MANIFESTS}/${MANIFEST} .
|
||||||
|
node $(dirname $0)/update_manifest.js ${MANIFEST} ${VERSION} \
|
||||||
|
-f ${ARCHIVE} -e Attorney_Online.exe
|
||||||
|
${S3_COPY} ${ARCHIVE} ${S3_ARCHIVES}
|
||||||
|
${S3_COPY} ${MANIFEST} ${S3_MANIFESTS}
|
||||||
|
|
||||||
|
rm -f ${MANIFEST}
|
17
scripts/windows/Dockerfile
Normal file
17
scripts/windows/Dockerfile
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
FROM oldmud0/mxe-qt:5.12.1-win32-static-posix
|
||||||
|
#FROM fffaraz/qt:windows
|
||||||
|
|
||||||
|
ENV TARGET_SPEC i686-w64-mingw32.static.posix
|
||||||
|
|
||||||
|
# Build Discord RPC statically
|
||||||
|
RUN git clone https://github.com/discordapp/discord-rpc
|
||||||
|
WORKDIR discord-rpc/build
|
||||||
|
RUN /opt/mxe/usr/bin/${TARGET_SPEC}-cmake .. -DCMAKE_INSTALL_PREFIX=/opt/mxe/usr/${TARGET_SPEC}
|
||||||
|
RUN /opt/mxe/usr/bin/${TARGET_SPEC}-cmake --build . --config Release --target install
|
||||||
|
WORKDIR ../..
|
||||||
|
|
||||||
|
# Build QtApng statically
|
||||||
|
RUN git clone https://github.com/Skycoder42/QtApng
|
||||||
|
WORKDIR QtApng
|
||||||
|
RUN /opt/mxe/usr/${TARGET_SPEC}/qt5/bin/qmake && make qmake_all && make && make install
|
||||||
|
WORKDIR ..
|
44
scripts/windows/Dockerfile-mxe
Normal file
44
scripts/windows/Dockerfile-mxe
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
FROM ubuntu:18.04
|
||||||
|
|
||||||
|
RUN apt-get update
|
||||||
|
RUN apt-get install -y \
|
||||||
|
autoconf \
|
||||||
|
automake \
|
||||||
|
autopoint \
|
||||||
|
bash \
|
||||||
|
bison \
|
||||||
|
bzip2 \
|
||||||
|
flex \
|
||||||
|
g++ \
|
||||||
|
g++-multilib \
|
||||||
|
gettext \
|
||||||
|
git \
|
||||||
|
gperf \
|
||||||
|
intltool \
|
||||||
|
libc6-dev-i386 \
|
||||||
|
libgdk-pixbuf2.0-dev \
|
||||||
|
libltdl-dev \
|
||||||
|
libssl-dev \
|
||||||
|
libtool-bin \
|
||||||
|
libxml-parser-perl \
|
||||||
|
lzip \
|
||||||
|
make \
|
||||||
|
openssl \
|
||||||
|
p7zip-full \
|
||||||
|
patch \
|
||||||
|
perl \
|
||||||
|
pkg-config \
|
||||||
|
python \
|
||||||
|
ruby \
|
||||||
|
sed \
|
||||||
|
unzip \
|
||||||
|
wget \
|
||||||
|
xz-utils
|
||||||
|
|
||||||
|
RUN git clone https://github.com/mxe/mxe.git
|
||||||
|
RUN mv mxe /opt/mxe
|
||||||
|
WORKDIR /opt/mxe
|
||||||
|
RUN make -j4 MXE_TARGETS="i686-w64-mingw32.static.posix" qtbase qtmultimedia
|
||||||
|
ENV PATH=/opt/mxe/usr/bin:$PATH
|
||||||
|
|
||||||
|
WORKDIR /
|
19
scripts/windows/how-to-push.md
Normal file
19
scripts/windows/how-to-push.md
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
When you want to build a new version of Qt:
|
||||||
|
```docker
|
||||||
|
docker build -t mxe-windows-static . -f Dockerfile-mxe
|
||||||
|
docker tag mxe-windows-static oldmud0/mxe-qt:5.12.1-win32-static-posix
|
||||||
|
docker push oldmud0/mxe-qt:5.12.1-win32-static-posix
|
||||||
|
```
|
||||||
|
|
||||||
|
Remember to log into Docker Hub before attempting to push.
|
||||||
|
|
||||||
|
When you want to build a new version of any dependency required for building AO:
|
||||||
|
```docker
|
||||||
|
docker build -t mxe-windows-static-ao . -f Dockerfile
|
||||||
|
docker tag mxe-windows-static-ao registry.gitlab.com/attorneyonline/ao2-client/builder-windows-i686
|
||||||
|
docker push registry.gitlab.com/attorneyonline/ao2-client/builder-windows-i686
|
||||||
|
```
|
||||||
|
|
||||||
|
Remember to create an access token in GitLab before attempting to push.
|
||||||
|
|
||||||
|
GitLab CI depends on `builder-windows-i686` image to be present in the repository's registry in order for the Windows build to succeed.
|
@ -37,9 +37,9 @@ void AOApplication::construct_lobby()
|
|||||||
w_lobby = new Lobby(this);
|
w_lobby = new Lobby(this);
|
||||||
lobby_constructed = true;
|
lobby_constructed = true;
|
||||||
|
|
||||||
QRect screenGeometry = QApplication::desktop()->screenGeometry();
|
QRect geometry = QGuiApplication::primaryScreen()->geometry();
|
||||||
int x = (screenGeometry.width()-w_lobby->width()) / 2;
|
int x = (geometry.width()-w_lobby->width()) / 2;
|
||||||
int y = (screenGeometry.height()-w_lobby->height()) / 2;
|
int y = (geometry.height()-w_lobby->height()) / 2;
|
||||||
w_lobby->move(x, y);
|
w_lobby->move(x, y);
|
||||||
|
|
||||||
if (is_discord_enabled())
|
if (is_discord_enabled())
|
||||||
@ -72,9 +72,9 @@ void AOApplication::construct_courtroom()
|
|||||||
w_courtroom = new Courtroom(this);
|
w_courtroom = new Courtroom(this);
|
||||||
courtroom_constructed = true;
|
courtroom_constructed = true;
|
||||||
|
|
||||||
QRect screenGeometry = QApplication::desktop()->screenGeometry();
|
QRect geometry = QGuiApplication::primaryScreen()->geometry();
|
||||||
int x = (screenGeometry.width()-w_courtroom->width()) / 2;
|
int x = (geometry.width()-w_courtroom->width()) / 2;
|
||||||
int y = (screenGeometry.height()-w_courtroom->height()) / 2;
|
int y = (geometry.height()-w_courtroom->height()) / 2;
|
||||||
w_courtroom->move(x, y);
|
w_courtroom->move(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -161,7 +161,7 @@ void AOApplication::ms_connect_finished(bool connected, bool will_retry)
|
|||||||
{
|
{
|
||||||
if (lobby_constructed)
|
if (lobby_constructed)
|
||||||
w_lobby->append_error("Error connecting to master server. Will try again in "
|
w_lobby->append_error("Error connecting to master server. Will try again in "
|
||||||
+ QString::number(net_manager->ms_reconnect_delay_ms / 1000.f) + " seconds.");
|
+ QString::number(net_manager->ms_reconnect_delay) + " seconds.");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -86,6 +86,7 @@ void AOEvidenceButton::mouseDoubleClickEvent(QMouseEvent *e)
|
|||||||
evidence_double_clicked(m_id);
|
evidence_double_clicked(m_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
void AOEvidenceButton::dragLeaveEvent(QMouseEvent *e)
|
void AOEvidenceButton::dragLeaveEvent(QMouseEvent *e)
|
||||||
{
|
{
|
||||||
//QWidget::dragLeaveEvent(e);
|
//QWidget::dragLeaveEvent(e);
|
||||||
@ -99,6 +100,7 @@ void AOEvidenceButton::dragEnterEvent(QMouseEvent *e)
|
|||||||
|
|
||||||
qDebug() << "drag enter event";
|
qDebug() << "drag enter event";
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
void AOEvidenceButton::enterEvent(QEvent * e)
|
void AOEvidenceButton::enterEvent(QEvent * e)
|
||||||
{
|
{
|
||||||
|
@ -44,7 +44,6 @@ void Courtroom::construct_char_select()
|
|||||||
|
|
||||||
set_size_and_pos(ui_char_buttons, "char_buttons");
|
set_size_and_pos(ui_char_buttons, "char_buttons");
|
||||||
|
|
||||||
connect (char_button_mapper, SIGNAL(mapped(int)), this, SLOT(char_clicked(int)));
|
|
||||||
connect(ui_back_to_lobby, SIGNAL(clicked()), this, SLOT(on_back_to_lobby_clicked()));
|
connect(ui_back_to_lobby, SIGNAL(clicked()), this, SLOT(on_back_to_lobby_clicked()));
|
||||||
|
|
||||||
connect(ui_char_select_left, SIGNAL(clicked()), this, SLOT(on_char_select_left_clicked()));
|
connect(ui_char_select_left, SIGNAL(clicked()), this, SLOT(on_char_select_left_clicked()));
|
||||||
@ -52,9 +51,9 @@ void Courtroom::construct_char_select()
|
|||||||
|
|
||||||
connect(ui_spectator, SIGNAL(clicked()), this, SLOT(on_spectator_clicked()));
|
connect(ui_spectator, SIGNAL(clicked()), this, SLOT(on_spectator_clicked()));
|
||||||
|
|
||||||
connect(ui_char_search, SIGNAL(textEdited(const QString&)), this, SLOT(on_char_search_changed(const QString&)));
|
connect(ui_char_search, SIGNAL(textEdited(const QString&)), this, SLOT(on_char_search_changed()));
|
||||||
connect(ui_char_passworded, SIGNAL(stateChanged(int)), this, SLOT(on_char_passworded_clicked(int)));
|
connect(ui_char_passworded, SIGNAL(stateChanged(int)), this, SLOT(on_char_passworded_clicked()));
|
||||||
connect(ui_char_taken, SIGNAL(stateChanged(int)), this, SLOT(on_char_taken_clicked(int)));
|
connect(ui_char_taken, SIGNAL(stateChanged(int)), this, SLOT(on_char_taken_clicked()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Courtroom::set_char_select()
|
void Courtroom::set_char_select()
|
||||||
@ -197,14 +196,15 @@ void Courtroom::character_loading_finished()
|
|||||||
// Later on, we'll be revealing buttons as we need them.
|
// Later on, we'll be revealing buttons as we need them.
|
||||||
for (int n = 0; n < char_list.size(); n++)
|
for (int n = 0; n < char_list.size(); n++)
|
||||||
{
|
{
|
||||||
AOCharButton* character = new AOCharButton(ui_char_buttons, ao_app, 0, 0, char_list.at(n).taken);
|
AOCharButton* char_button = new AOCharButton(ui_char_buttons, ao_app, 0, 0, char_list.at(n).taken);
|
||||||
character->reset();
|
char_button->reset();
|
||||||
character->hide();
|
char_button->hide();
|
||||||
character->set_image(char_list.at(n).name);
|
char_button->set_image(char_list.at(n).name);
|
||||||
ui_char_button_list.append(character);
|
ui_char_button_list.append(char_button);
|
||||||
|
|
||||||
connect(character, SIGNAL(clicked()), char_button_mapper, SLOT(map()));
|
connect(char_button, &AOCharButton::clicked, [this, n](){
|
||||||
char_button_mapper->setMapping(character, ui_char_button_list.size() - 1);
|
this->char_clicked(n);
|
||||||
|
});
|
||||||
|
|
||||||
// This part here serves as a way of showing to the player that the game is still running, it is
|
// This part here serves as a way of showing to the player that the game is still running, it is
|
||||||
// just loading the pictures of the characters.
|
// just loading the pictures of the characters.
|
||||||
@ -252,17 +252,17 @@ void Courtroom::filter_character_list()
|
|||||||
set_char_select_page();
|
set_char_select_page();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Courtroom::on_char_search_changed(const QString& newtext)
|
void Courtroom::on_char_search_changed()
|
||||||
{
|
{
|
||||||
filter_character_list();
|
filter_character_list();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Courtroom::on_char_passworded_clicked(int newstate)
|
void Courtroom::on_char_passworded_clicked()
|
||||||
{
|
{
|
||||||
filter_character_list();
|
filter_character_list();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Courtroom::on_char_taken_clicked(int newstate)
|
void Courtroom::on_char_taken_clicked()
|
||||||
{
|
{
|
||||||
filter_character_list();
|
filter_character_list();
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ Courtroom::Courtroom(AOApplication *p_ao_app) : QMainWindow()
|
|||||||
#ifdef BASSAUDIO
|
#ifdef BASSAUDIO
|
||||||
// Change the default audio output device to be the one the user has given
|
// Change the default audio output device to be the one the user has given
|
||||||
// in his config.ini file for now.
|
// in his config.ini file for now.
|
||||||
int a = 0;
|
unsigned int a = 0;
|
||||||
BASS_DEVICEINFO info;
|
BASS_DEVICEINFO info;
|
||||||
|
|
||||||
if (ao_app->get_audio_output_device() == "default")
|
if (ao_app->get_audio_output_device() == "default")
|
||||||
@ -21,7 +21,7 @@ Courtroom::Courtroom(AOApplication *p_ao_app) : QMainWindow()
|
|||||||
if (ao_app->get_audio_output_device() == info.name)
|
if (ao_app->get_audio_output_device() == info.name)
|
||||||
{
|
{
|
||||||
BASS_SetDevice(a);
|
BASS_SetDevice(a);
|
||||||
BASS_Init(a, 48000, BASS_DEVICE_LATENCY, nullptr, nullptr);
|
BASS_Init(static_cast<int>(a), 48000, BASS_DEVICE_LATENCY, nullptr, nullptr);
|
||||||
load_bass_opus_plugin();
|
load_bass_opus_plugin();
|
||||||
qDebug() << info.name << "was set as the default audio output device.";
|
qDebug() << info.name << "was set as the default audio output device.";
|
||||||
break;
|
break;
|
||||||
@ -50,8 +50,6 @@ Courtroom::Courtroom(AOApplication *p_ao_app) : QMainWindow()
|
|||||||
testimony_hide_timer = new QTimer(this);
|
testimony_hide_timer = new QTimer(this);
|
||||||
testimony_hide_timer->setSingleShot(true);
|
testimony_hide_timer->setSingleShot(true);
|
||||||
|
|
||||||
char_button_mapper = new QSignalMapper(this);
|
|
||||||
|
|
||||||
music_player = new AOMusicPlayer(this, ao_app);
|
music_player = new AOMusicPlayer(this, ao_app);
|
||||||
music_player->set_volume(0);
|
music_player->set_volume(0);
|
||||||
sfx_player = new AOSfxPlayer(this, ao_app);
|
sfx_player = new AOSfxPlayer(this, ao_app);
|
||||||
@ -2025,6 +2023,7 @@ void Courtroom::chat_tick()
|
|||||||
//do not perform heavy operations here
|
//do not perform heavy operations here
|
||||||
|
|
||||||
QString f_message = m_chatmessage[MESSAGE];
|
QString f_message = m_chatmessage[MESSAGE];
|
||||||
|
f_message.remove(0, tick_pos);
|
||||||
|
|
||||||
// Due to our new text speed system, we always need to stop the timer now.
|
// Due to our new text speed system, we always need to stop the timer now.
|
||||||
chat_tick_timer->stop();
|
chat_tick_timer->stop();
|
||||||
@ -2039,7 +2038,7 @@ void Courtroom::chat_tick()
|
|||||||
f_message.remove(0,2);
|
f_message.remove(0,2);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tick_pos >= f_message.size())
|
if (f_message.size() == 0)
|
||||||
{
|
{
|
||||||
text_state = 2;
|
text_state = 2;
|
||||||
if (anim_state != 4)
|
if (anim_state != 4)
|
||||||
@ -2051,9 +2050,21 @@ void Courtroom::chat_tick()
|
|||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
QString f_character = f_message.at(tick_pos);
|
QTextBoundaryFinder tbf(QTextBoundaryFinder::Grapheme, f_message);
|
||||||
|
QString f_character;
|
||||||
|
int f_char_length;
|
||||||
|
|
||||||
|
tbf.toNextBoundary();
|
||||||
|
|
||||||
|
if (tbf.position() == -1)
|
||||||
|
f_character = f_message;
|
||||||
|
else
|
||||||
|
f_character = f_message.left(tbf.position());
|
||||||
|
|
||||||
|
f_char_length = f_character.length();
|
||||||
f_character = f_character.toHtmlEscaped();
|
f_character = f_character.toHtmlEscaped();
|
||||||
|
|
||||||
|
|
||||||
if (f_character == " ")
|
if (f_character == " ")
|
||||||
ui_vp_message->insertPlainText(" ");
|
ui_vp_message->insertPlainText(" ");
|
||||||
|
|
||||||
@ -2146,7 +2157,7 @@ void Courtroom::chat_tick()
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
next_character_is_not_special = true;
|
next_character_is_not_special = true;
|
||||||
tick_pos--;
|
tick_pos -= f_char_length;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2167,7 +2178,7 @@ void Courtroom::chat_tick()
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
next_character_is_not_special = true;
|
next_character_is_not_special = true;
|
||||||
tick_pos--;
|
tick_pos -= f_char_length;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2211,11 +2222,7 @@ void Courtroom::chat_tick()
|
|||||||
case INLINE_GREY:
|
case INLINE_GREY:
|
||||||
ui_vp_message->insertHtml("<font color=\""+ get_text_color("_inline_grey").name() +"\">" + f_character + "</font>");
|
ui_vp_message->insertHtml("<font color=\""+ get_text_color("_inline_grey").name() +"\">" + f_character + "</font>");
|
||||||
break;
|
break;
|
||||||
default:
|
|
||||||
ui_vp_message->insertHtml(f_character);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -2266,7 +2273,7 @@ void Courtroom::chat_tick()
|
|||||||
if(blank_blip)
|
if(blank_blip)
|
||||||
qDebug() << "blank_blip found true";
|
qDebug() << "blank_blip found true";
|
||||||
|
|
||||||
if (f_message.at(tick_pos) != ' ' || blank_blip)
|
if (f_character != ' ' || blank_blip)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (blip_pos % blip_rate == 0 && !formatting_char)
|
if (blip_pos % blip_rate == 0 && !formatting_char)
|
||||||
@ -2278,7 +2285,7 @@ void Courtroom::chat_tick()
|
|||||||
++blip_pos;
|
++blip_pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
++tick_pos;
|
tick_pos += f_char_length;
|
||||||
|
|
||||||
// Restart the timer, but according to the newly set speeds, if there were any.
|
// Restart the timer, but according to the newly set speeds, if there were any.
|
||||||
// Keep the speed at bay.
|
// Keep the speed at bay.
|
||||||
@ -2305,6 +2312,7 @@ void Courtroom::chat_tick()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Courtroom::show_testimony()
|
void Courtroom::show_testimony()
|
||||||
{
|
{
|
||||||
if (!testimony_in_progress || m_chatmessage[SIDE] != "wit")
|
if (!testimony_in_progress || m_chatmessage[SIDE] != "wit")
|
||||||
@ -2697,6 +2705,7 @@ void Courtroom::on_ooc_return_pressed()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
other_charid = -1;
|
||||||
append_server_chatmessage("CLIENT", "You are no longer paired with anyone.", "1");
|
append_server_chatmessage("CLIENT", "You are no longer paired with anyone.", "1");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2853,6 +2862,60 @@ void Courtroom::on_ooc_return_pressed()
|
|||||||
ui_ooc_chat_message->clear();
|
ui_ooc_chat_message->clear();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
else if(ooc_message.startsWith("/save_case"))
|
||||||
|
{
|
||||||
|
QStringList command = ooc_message.split(" ", QString::SkipEmptyParts);
|
||||||
|
|
||||||
|
QDir casefolder("base/cases");
|
||||||
|
if (!casefolder.exists())
|
||||||
|
{
|
||||||
|
QDir::current().mkdir("base/" + casefolder.dirName());
|
||||||
|
append_server_chatmessage("CLIENT", "You don't have a `base/cases/` folder! It was just made for you, but seeing as it WAS just made for you, it's likely that you somehow deleted it.", "1");
|
||||||
|
ui_ooc_chat_message->clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
QStringList caseslist = casefolder.entryList();
|
||||||
|
caseslist.removeOne(".");
|
||||||
|
caseslist.removeOne("..");
|
||||||
|
caseslist.replaceInStrings(".ini","");
|
||||||
|
|
||||||
|
if (command.size() < 3)
|
||||||
|
{
|
||||||
|
append_server_chatmessage("CLIENT", "You need to give a filename to save (extension not needed) and the courtroom status!", "1");
|
||||||
|
ui_ooc_chat_message->clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (command.size() > 3)
|
||||||
|
{
|
||||||
|
append_server_chatmessage("CLIENT", "Too many arguments to save a case! You only need a filename without extension and the courtroom status!", "1");
|
||||||
|
ui_ooc_chat_message->clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
QSettings casefile("base/cases/" + command[1] + ".ini", QSettings::IniFormat);
|
||||||
|
casefile.setValue("author",ui_ooc_chat_name->text());
|
||||||
|
casefile.setValue("cmdoc","");
|
||||||
|
casefile.setValue("doc", "");
|
||||||
|
casefile.setValue("status",command[2]);
|
||||||
|
casefile.sync();
|
||||||
|
for(int i = local_evidence_list.size() - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
QString clean_evidence_dsc = local_evidence_list[i].description.replace(QRegularExpression("<owner = ...>..."), "");
|
||||||
|
clean_evidence_dsc = clean_evidence_dsc.replace(clean_evidence_dsc.lastIndexOf(">"), 1, "");
|
||||||
|
casefile.beginGroup(QString::number(i));
|
||||||
|
casefile.sync();
|
||||||
|
casefile.setValue("name",local_evidence_list[i].name);
|
||||||
|
casefile.setValue("description",local_evidence_list[i].description);
|
||||||
|
casefile.setValue("image",local_evidence_list[i].image);
|
||||||
|
casefile.endGroup();
|
||||||
|
}
|
||||||
|
casefile.sync();
|
||||||
|
append_server_chatmessage("CLIENT", "Succesfully saved, edit doc and cmdoc link on the ini!", "1");
|
||||||
|
ui_ooc_chat_message->clear();
|
||||||
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
QStringList packet_contents;
|
QStringList packet_contents;
|
||||||
packet_contents.append(ui_ooc_chat_name->text());
|
packet_contents.append(ui_ooc_chat_name->text());
|
||||||
@ -2982,6 +3045,7 @@ void Courtroom::on_pair_list_clicked(QModelIndex p_index)
|
|||||||
QListWidgetItem *f_item = ui_pair_list->item(p_index.row());
|
QListWidgetItem *f_item = ui_pair_list->item(p_index.row());
|
||||||
QString f_char = f_item->text();
|
QString f_char = f_item->text();
|
||||||
QString real_char;
|
QString real_char;
|
||||||
|
int f_cid = -1;
|
||||||
|
|
||||||
if (f_char.endsWith(" [x]"))
|
if (f_char.endsWith(" [x]"))
|
||||||
{
|
{
|
||||||
@ -2989,17 +3053,19 @@ void Courtroom::on_pair_list_clicked(QModelIndex p_index)
|
|||||||
f_item->setText(real_char);
|
f_item->setText(real_char);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
real_char = f_char;
|
|
||||||
|
|
||||||
int f_cid = -1;
|
|
||||||
|
|
||||||
for (int n_char = 0 ; n_char < char_list.size() ; n_char++)
|
|
||||||
{
|
{
|
||||||
|
real_char = f_char;
|
||||||
|
for (int n_char = 0 ; n_char < char_list.size() ; n_char++)
|
||||||
|
{
|
||||||
if (char_list.at(n_char).name == real_char)
|
if (char_list.at(n_char).name == real_char)
|
||||||
f_cid = n_char;
|
f_cid = n_char;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (f_cid < 0 || f_cid >= char_list.size())
|
|
||||||
|
|
||||||
|
|
||||||
|
if (f_cid < -2 || f_cid >= char_list.size())
|
||||||
{
|
{
|
||||||
qDebug() << "W: " << real_char << " not present in char_list";
|
qDebug() << "W: " << real_char << " not present in char_list";
|
||||||
return;
|
return;
|
||||||
@ -3018,8 +3084,10 @@ void Courtroom::on_pair_list_clicked(QModelIndex p_index)
|
|||||||
for (int i = 0; i < ui_pair_list->count(); i++) {
|
for (int i = 0; i < ui_pair_list->count(); i++) {
|
||||||
ui_pair_list->item(i)->setText(sorted_pair_list.at(i));
|
ui_pair_list->item(i)->setText(sorted_pair_list.at(i));
|
||||||
}
|
}
|
||||||
|
if(other_charid != -1)
|
||||||
f_item->setText(real_char + " [x]");
|
{
|
||||||
|
f_item->setText(real_char + " [x]");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Courtroom::on_music_list_double_clicked(QModelIndex p_model)
|
void Courtroom::on_music_list_double_clicked(QModelIndex p_model)
|
||||||
|
@ -12,10 +12,10 @@ Discord::Discord()
|
|||||||
qInfo() << "Discord RPC ready";
|
qInfo() << "Discord RPC ready";
|
||||||
};
|
};
|
||||||
handlers.disconnected = [](int errorCode, const char* message) {
|
handlers.disconnected = [](int errorCode, const char* message) {
|
||||||
qInfo() << "Discord RPC disconnected! " << message;
|
qInfo() << "Discord RPC disconnected! " << message << errorCode;
|
||||||
};
|
};
|
||||||
handlers.errored = [](int errorCode, const char* message) {
|
handlers.errored = [](int errorCode, const char* message) {
|
||||||
qWarning() << "Discord RPC errored out! " << message;
|
qWarning() << "Discord RPC errored out! " << message << errorCode;
|
||||||
};
|
};
|
||||||
qInfo() << "Initializing Discord RPC";
|
qInfo() << "Initializing Discord RPC";
|
||||||
Discord_Initialize(APPLICATION_ID, &handlers, 1, nullptr);
|
Discord_Initialize(APPLICATION_ID, &handlers, 1, nullptr);
|
||||||
|
@ -188,11 +188,12 @@ void Courtroom::on_evidence_image_name_edited()
|
|||||||
|
|
||||||
void Courtroom::on_evidence_image_button_clicked()
|
void Courtroom::on_evidence_image_button_clicked()
|
||||||
{
|
{
|
||||||
|
QDir dir(ao_app->get_base_path() + "evidence");
|
||||||
QFileDialog dialog(this);
|
QFileDialog dialog(this);
|
||||||
dialog.setFileMode(QFileDialog::ExistingFile);
|
dialog.setFileMode(QFileDialog::ExistingFile);
|
||||||
dialog.setNameFilter(tr("Images (*.png)"));
|
dialog.setNameFilter(tr("Images (*.png)"));
|
||||||
dialog.setViewMode(QFileDialog::List);
|
dialog.setViewMode(QFileDialog::List);
|
||||||
dialog.setDirectory(ao_app->get_base_path() + "evidence");
|
dialog.setDirectory(dir);
|
||||||
|
|
||||||
QStringList filenames;
|
QStringList filenames;
|
||||||
|
|
||||||
@ -203,13 +204,8 @@ void Courtroom::on_evidence_image_button_clicked()
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
QString filename = filenames.at(0);
|
QString filename = filenames.at(0);
|
||||||
|
filename = dir.relativeFilePath(filename);
|
||||||
QStringList split_filename = filename.split("/");
|
|
||||||
|
|
||||||
filename = split_filename.at(split_filename.size() - 1);
|
|
||||||
|
|
||||||
ui_evidence_image_name->setText(filename);
|
ui_evidence_image_name->setText(filename);
|
||||||
|
|
||||||
on_evidence_image_name_edited();
|
on_evidence_image_name_edited();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,12 +5,12 @@
|
|||||||
#if (defined (_WIN32) || defined (_WIN64))
|
#if (defined (_WIN32) || defined (_WIN64))
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
DWORD dwVolSerial;
|
static DWORD dwVolSerial;
|
||||||
BOOL bIsRetrieved;
|
static BOOL bIsRetrieved;
|
||||||
|
|
||||||
QString get_hdid()
|
QString get_hdid()
|
||||||
{
|
{
|
||||||
bIsRetrieved = GetVolumeInformation(TEXT("C:\\"), NULL, NULL, &dwVolSerial, NULL, NULL, NULL, NULL);
|
bIsRetrieved = GetVolumeInformation(TEXT("C:\\"), nullptr, 0, &dwVolSerial, nullptr, nullptr, nullptr, 0);
|
||||||
|
|
||||||
if (bIsRetrieved)
|
if (bIsRetrieved)
|
||||||
return QString::number(dwVolSerial, 16);
|
return QString::number(dwVolSerial, 16);
|
||||||
@ -18,7 +18,6 @@ QString get_hdid()
|
|||||||
//a totally random string
|
//a totally random string
|
||||||
//what could possibly go wrong
|
//what could possibly go wrong
|
||||||
return "gxsps32sa9fnwic92mfbs0";
|
return "gxsps32sa9fnwic92mfbs0";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#elif (defined (LINUX) || defined (__linux__))
|
#elif (defined (LINUX) || defined (__linux__))
|
||||||
|
@ -78,9 +78,9 @@ void NetworkManager::ship_server_packet(QString p_packet)
|
|||||||
|
|
||||||
void NetworkManager::handle_ms_packet()
|
void NetworkManager::handle_ms_packet()
|
||||||
{
|
{
|
||||||
char buffer[buffer_max_size];
|
char buffer[BUFFER_MAX_SIZE];
|
||||||
std::memset(buffer, 0, buffer_max_size);
|
std::memset(buffer, 0, BUFFER_MAX_SIZE);
|
||||||
ms_socket->read(buffer, buffer_max_size);
|
ms_socket->read(buffer, BUFFER_MAX_SIZE);
|
||||||
|
|
||||||
QString in_data = buffer;
|
QString in_data = buffer;
|
||||||
|
|
||||||
@ -137,7 +137,9 @@ void NetworkManager::on_srv_lookup()
|
|||||||
|
|
||||||
for (const QDnsServiceRecord &record : srv_records)
|
for (const QDnsServiceRecord &record : srv_records)
|
||||||
{
|
{
|
||||||
|
#ifdef DEBUG_NETWORK
|
||||||
qDebug() << "Connecting to " << record.target() << ":" << record.port();
|
qDebug() << "Connecting to " << record.target() << ":" << record.port();
|
||||||
|
#endif
|
||||||
ms_socket->connectToHost(record.target(), record.port());
|
ms_socket->connectToHost(record.target(), record.port());
|
||||||
QTime timer;
|
QTime timer;
|
||||||
timer.start();
|
timer.start();
|
||||||
@ -206,7 +208,7 @@ void NetworkManager::on_ms_socket_error(QAbstractSocket::SocketError error)
|
|||||||
|
|
||||||
emit ms_connect_finished(false, true);
|
emit ms_connect_finished(false, true);
|
||||||
|
|
||||||
ms_reconnect_timer->start(ms_reconnect_delay_ms);
|
ms_reconnect_timer->start(ms_reconnect_delay * 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetworkManager::retry_ms_connect()
|
void NetworkManager::retry_ms_connect()
|
||||||
@ -217,9 +219,9 @@ void NetworkManager::retry_ms_connect()
|
|||||||
|
|
||||||
void NetworkManager::handle_server_packet()
|
void NetworkManager::handle_server_packet()
|
||||||
{
|
{
|
||||||
char buffer[buffer_max_size];
|
char buffer[BUFFER_MAX_SIZE];
|
||||||
std::memset(buffer, 0, buffer_max_size);
|
std::memset(buffer, 0, BUFFER_MAX_SIZE);
|
||||||
server_socket->read(buffer, buffer_max_size);
|
server_socket->read(buffer, BUFFER_MAX_SIZE);
|
||||||
|
|
||||||
QString in_data = buffer;
|
QString in_data = buffer;
|
||||||
|
|
||||||
|
@ -14,8 +14,10 @@ void AOApplication::ms_packet_received(AOPacket *p_packet)
|
|||||||
QString header = p_packet->get_header();
|
QString header = p_packet->get_header();
|
||||||
QStringList f_contents = p_packet->get_contents();
|
QStringList f_contents = p_packet->get_contents();
|
||||||
|
|
||||||
|
#ifdef DEBUG_NETWORK
|
||||||
if (header != "CHECK")
|
if (header != "CHECK")
|
||||||
qDebug() << "R(ms):" << p_packet->to_string();
|
qDebug() << "R(ms):" << p_packet->to_string();
|
||||||
|
#endif
|
||||||
|
|
||||||
if (header == "ALL")
|
if (header == "ALL")
|
||||||
{
|
{
|
||||||
@ -127,8 +129,10 @@ void AOApplication::server_packet_received(AOPacket *p_packet)
|
|||||||
QStringList f_contents = p_packet->get_contents();
|
QStringList f_contents = p_packet->get_contents();
|
||||||
QString f_packet = p_packet->to_string();
|
QString f_packet = p_packet->to_string();
|
||||||
|
|
||||||
|
#ifdef DEBUG_NETWORK
|
||||||
if (header != "checkconnection")
|
if (header != "checkconnection")
|
||||||
qDebug() << "R:" << f_packet;
|
qDebug() << "R:" << f_packet;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (header == "decryptor")
|
if (header == "decryptor")
|
||||||
{
|
{
|
||||||
@ -677,7 +681,9 @@ void AOApplication::send_ms_packet(AOPacket *p_packet)
|
|||||||
|
|
||||||
net_manager->ship_ms_packet(f_packet);
|
net_manager->ship_ms_packet(f_packet);
|
||||||
|
|
||||||
|
#ifdef DEBUG_NETWORK
|
||||||
qDebug() << "S(ms):" << f_packet;
|
qDebug() << "S(ms):" << f_packet;
|
||||||
|
#endif
|
||||||
|
|
||||||
delete p_packet;
|
delete p_packet;
|
||||||
}
|
}
|
||||||
@ -691,14 +697,18 @@ void AOApplication::send_server_packet(AOPacket *p_packet, bool encoded)
|
|||||||
|
|
||||||
if (encryption_needed)
|
if (encryption_needed)
|
||||||
{
|
{
|
||||||
|
#ifdef DEBUG_NETWORK
|
||||||
qDebug() << "S(e):" << f_packet;
|
qDebug() << "S(e):" << f_packet;
|
||||||
|
#endif
|
||||||
|
|
||||||
p_packet->encrypt_header(s_decryptor);
|
p_packet->encrypt_header(s_decryptor);
|
||||||
f_packet = p_packet->to_string();
|
f_packet = p_packet->to_string();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
#ifdef DEBUG_NETWORK
|
||||||
qDebug() << "S:" << f_packet;
|
qDebug() << "S:" << f_packet;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
net_manager->ship_server_packet(f_packet);
|
net_manager->ship_server_packet(f_packet);
|
||||||
|
Loading…
Reference in New Issue
Block a user