mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2025-12-21 06:42:41 -08:00
Compare commits
100 Commits
2021-11-07
...
2022-05-09
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a95b338c80 | ||
|
|
3e90f109a2 | ||
|
|
b02adccf87 | ||
|
|
accd5e4df7 | ||
|
|
d007196059 | ||
|
|
79501a4af7 | ||
|
|
64c6611ea5 | ||
|
|
a532a63403 | ||
|
|
c10c69d0a9 | ||
|
|
191d5a83a9 | ||
|
|
de69e2c41f | ||
|
|
6d200d17b7 | ||
|
|
4899b6cfef | ||
|
|
0ff59e6d1e | ||
|
|
00a2a8ab71 | ||
|
|
2c702d3579 | ||
|
|
b464fa8d99 | ||
|
|
2b330940e1 | ||
|
|
0d0337f091 | ||
|
|
533045445a | ||
|
|
21f7dd5eba | ||
|
|
f5b973e15c | ||
|
|
baaf261116 | ||
|
|
92ed53e13a | ||
|
|
2a54e9d7d1 | ||
|
|
9577ada171 | ||
|
|
217dc09c0f | ||
|
|
7108eb42c8 | ||
|
|
eb3ce1fd7e | ||
|
|
c88d44e16c | ||
|
|
ec2ad4c713 | ||
|
|
4c04b4ef5a | ||
|
|
88b861d632 | ||
|
|
408a13c937 | ||
|
|
7d0a255a49 | ||
|
|
252883f67e | ||
|
|
bf08a04cda | ||
|
|
6928a2bd98 | ||
|
|
bb16ae09ef | ||
|
|
81d031ca0f | ||
|
|
8203a2fdeb | ||
|
|
75f0d60dff | ||
|
|
992e28797f | ||
|
|
92f941a54c | ||
|
|
4c31527832 | ||
|
|
febe029ed4 | ||
|
|
1d780058c8 | ||
|
|
513fcb0908 | ||
|
|
4bb13677c8 | ||
|
|
a5baf4303c | ||
|
|
7aba404f2e | ||
|
|
1b7e8f3a16 | ||
|
|
5cf93ad61c | ||
|
|
5a52e085a7 | ||
|
|
5d31b70406 | ||
|
|
2885f93fdf | ||
|
|
d225f55e5a | ||
|
|
69edc73585 | ||
|
|
ead1143f2e | ||
|
|
2fc85e0c08 | ||
|
|
fcafcb340a | ||
|
|
ae9b8b8f34 | ||
|
|
994704d353 | ||
|
|
d61c604bf4 | ||
|
|
baaf22d0c4 | ||
|
|
368ff1793f | ||
|
|
3253ad64fd | ||
|
|
1e70989f38 | ||
|
|
f6634de18d | ||
|
|
7903cd520a | ||
|
|
26d1fcc944 | ||
|
|
59d4e64a8d | ||
|
|
1347d88ddb | ||
|
|
6981cca2ae | ||
|
|
4d6c9ede8c | ||
|
|
e845c95816 | ||
|
|
a9f2fc427b | ||
|
|
07e6aadbbe | ||
|
|
86881bbbc3 | ||
|
|
1f15445c69 | ||
|
|
811ee54c76 | ||
|
|
d1a40fd36e | ||
|
|
a3d3aaaca8 | ||
|
|
c5aaa0bc2e | ||
|
|
6dc9f004ce | ||
|
|
6ce346af4a | ||
|
|
37879c4255 | ||
|
|
0683d1aced | ||
|
|
73c5956ece | ||
|
|
7c27e955d5 | ||
|
|
6ef394000b | ||
|
|
755a09bd83 | ||
|
|
8b1daa21ef | ||
|
|
691bcb9338 | ||
|
|
911a303326 | ||
|
|
5652b56b45 | ||
|
|
26acfd5102 | ||
|
|
f789e02096 | ||
|
|
43eee6b32e | ||
|
|
45d86e7ab7 |
@@ -1,4 +1,4 @@
|
||||
FROM debian:buster
|
||||
FROM debian:10
|
||||
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
build-essential \
|
||||
@@ -19,6 +19,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
qt5-default \
|
||||
qtbase5-dev \
|
||||
qtmultimedia5-dev \
|
||||
qttools5-dev \
|
||||
qttools5-dev-tools \
|
||||
&& apt-get clean \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM ubuntu:hirsute
|
||||
FROM debian:11
|
||||
|
||||
RUN apt-get update && \
|
||||
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
|
||||
14
.ci/Fedora36/Dockerfile
Normal file
14
.ci/Fedora36/Dockerfile
Normal file
@@ -0,0 +1,14 @@
|
||||
FROM fedora:36
|
||||
|
||||
RUN dnf install -y \
|
||||
ccache \
|
||||
cmake \
|
||||
gcc-c++ \
|
||||
git \
|
||||
mariadb-devel \
|
||||
protobuf-devel \
|
||||
qt6-{qttools,qtsvg,qtmultimedia,qtwebsockets,qt5compat}-devel \
|
||||
rpm-build \
|
||||
xz-devel \
|
||||
zlib-devel \
|
||||
&& dnf clean all
|
||||
27
.ci/UbuntuJammy/Dockerfile
Normal file
27
.ci/UbuntuJammy/Dockerfile
Normal file
@@ -0,0 +1,27 @@
|
||||
FROM ubuntu:jammy
|
||||
|
||||
RUN apt-get update && \
|
||||
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
|
||||
build-essential \
|
||||
ccache \
|
||||
clang-format \
|
||||
cmake \
|
||||
file \
|
||||
g++ \
|
||||
git \
|
||||
libgl-dev \
|
||||
liblzma-dev \
|
||||
libmariadb-dev-compat \
|
||||
libprotobuf-dev \
|
||||
libqt6core5compat6-dev \
|
||||
libqt6multimedia6 \
|
||||
libqt6sql6-mysql \
|
||||
libqt6svg6-dev \
|
||||
libqt6websockets6-dev \
|
||||
protobuf-compiler \
|
||||
qt6-l10n-tools \
|
||||
qt6-multimedia-dev \
|
||||
qt6-tools-dev \
|
||||
qt6-tools-dev-tools \
|
||||
&& apt-get clean \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
143
.ci/compile.sh
143
.ci/compile.sh
@@ -2,16 +2,26 @@
|
||||
|
||||
# This script is to be used by the ci environment from the project root directory, do not use it from somewhere else.
|
||||
|
||||
# Compiles cockatrice inside of a ci environment
|
||||
# --install runs make install
|
||||
# --package [<package type>] runs make package, optionally force the type
|
||||
# --suffix <suffix> renames package with this suffix, requires arg
|
||||
# --server compiles servatrice
|
||||
# --test runs tests
|
||||
# --debug or --release sets the build type ie CMAKE_BUILD_TYPE
|
||||
# --ccache [<size>] uses ccache and shows stats, optionally provide size
|
||||
# --dir <dir> sets the name of the build dir, default is "build"
|
||||
# --parallel <core count> sets how many cores cmake should build with in parallel
|
||||
# uses env: BUILDTYPE MAKE_INSTALL MAKE_PACKAGE PACKAGE_TYPE PACKAGE_SUFFIX MAKE_SERVER MAKE_TEST USE_CCACHE CCACHE_SIZE BUILD_DIR PARALLEL_COUNT
|
||||
# (correspond to args: --debug/--release --install --package <package type> --suffix <suffix> --server --test --ccache <ccache_size> --dir <dir> --parallel <core_count>)
|
||||
# exitcode: 1 for failure, 3 for invalid arguments
|
||||
|
||||
# Read arguments
|
||||
while [[ "$@" ]]; do
|
||||
while [[ $# != 0 ]]; do
|
||||
case "$1" in
|
||||
'--')
|
||||
shift
|
||||
;;
|
||||
'--format')
|
||||
CHECK_FORMAT=1
|
||||
shift
|
||||
;;
|
||||
'--install')
|
||||
MAKE_INSTALL=1
|
||||
shift
|
||||
@@ -19,7 +29,7 @@ while [[ "$@" ]]; do
|
||||
'--package')
|
||||
MAKE_PACKAGE=1
|
||||
shift
|
||||
if [[ $# != 0 && $1 != -* ]]; then
|
||||
if [[ $# != 0 && ${1:0:1} != - ]]; then
|
||||
PACKAGE_TYPE="$1"
|
||||
shift
|
||||
fi
|
||||
@@ -28,7 +38,7 @@ while [[ "$@" ]]; do
|
||||
shift
|
||||
if [[ $# == 0 ]]; then
|
||||
echo "::error file=$0::--suffix expects an argument"
|
||||
exit 1
|
||||
exit 3
|
||||
fi
|
||||
PACKAGE_SUFFIX="$1"
|
||||
shift
|
||||
@@ -49,94 +59,137 @@ while [[ "$@" ]]; do
|
||||
BUILDTYPE="Release"
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
if [[ $1 == -* ]]; then
|
||||
echo "::error file=$0::unrecognized option: $1"
|
||||
'--ccache')
|
||||
USE_CCACHE=1
|
||||
shift
|
||||
if [[ $# != 0 && ${1:0:1} != - ]]; then
|
||||
CCACHE_SIZE="$1"
|
||||
shift
|
||||
fi
|
||||
;;
|
||||
'--dir')
|
||||
shift
|
||||
if [[ $# == 0 ]]; then
|
||||
echo "::error file=$0::--dir expects an argument"
|
||||
exit 3
|
||||
fi
|
||||
BUILDTYPE="$1"
|
||||
BUILD_DIR="$1"
|
||||
shift
|
||||
;;
|
||||
'--parallel')
|
||||
shift
|
||||
if [[ $# == 0 ]]; then
|
||||
echo "::error file=$0::--parallel expects an argument"
|
||||
exit 3
|
||||
fi
|
||||
PARALLEL_COUNT="$1"
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
echo "::error file=$0::unrecognized option: $1"
|
||||
exit 3
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Check formatting using clang-format
|
||||
if [[ $CHECK_FORMAT ]]; then
|
||||
echo "::group::Run linter"
|
||||
source ./.ci/lint.sh
|
||||
echo "::endgroup::"
|
||||
fi
|
||||
|
||||
set -e
|
||||
|
||||
# Setup
|
||||
./servatrice/check_schema_version.sh
|
||||
mkdir -p build
|
||||
cd build
|
||||
|
||||
if [[ ! $CMAKE_BUILD_PARALLEL_LEVEL ]]; then
|
||||
CMAKE_BUILD_PARALLEL_LEVEL=2 # default machines have 2 cores
|
||||
if [[ ! $BUILDTYPE ]]; then
|
||||
BUILDTYPE=Release
|
||||
fi
|
||||
if [[ ! $BUILD_DIR ]]; then
|
||||
BUILD_DIR="build"
|
||||
fi
|
||||
mkdir -p "$BUILD_DIR"
|
||||
cd "$BUILD_DIR"
|
||||
|
||||
# Add cmake flags
|
||||
flags=("-DCMAKE_BUILD_TYPE=$BUILDTYPE")
|
||||
if [[ $MAKE_SERVER ]]; then
|
||||
flags+=" -DWITH_SERVER=1"
|
||||
flags+=("-DWITH_SERVER=1")
|
||||
fi
|
||||
if [[ $MAKE_TEST ]]; then
|
||||
flags+=" -DTEST=1"
|
||||
flags+=("-DTEST=1")
|
||||
fi
|
||||
if [[ $BUILDTYPE ]]; then
|
||||
flags+=" -DCMAKE_BUILD_TYPE=$BUILDTYPE"
|
||||
if [[ $USE_CCACHE ]]; then
|
||||
flags+=("-DUSE_CCACHE=1")
|
||||
if [[ $CCACHE_SIZE ]]; then
|
||||
# note, this setting persists after running the script
|
||||
ccache --max-size "$CCACHE_SIZE"
|
||||
fi
|
||||
fi
|
||||
if [[ $PACKAGE_TYPE ]]; then
|
||||
flags+=" -DCPACK_GENERATOR=$PACKAGE_TYPE"
|
||||
flags+=("-DCPACK_GENERATOR=$PACKAGE_TYPE")
|
||||
fi
|
||||
|
||||
if [[ $(uname) == "Darwin" ]]; then
|
||||
# prepend ccache compiler binaries to path
|
||||
PATH="/usr/local/opt/ccache/libexec:$PATH"
|
||||
# Add qt install location when using homebrew
|
||||
flags+=" -DCMAKE_PREFIX_PATH=/usr/local/opt/qt5/"
|
||||
# Add cmake --build flags
|
||||
buildflags=(--config "$BUILDTYPE")
|
||||
if [[ $PARALLEL_COUNT ]]; then
|
||||
if [[ $(cmake --build /not_a_dir --parallel |& head -1) =~ parallel ]]; then
|
||||
# workaround for bionic having an old cmake
|
||||
echo "this version of cmake does not support --parallel, using native build tool -j instead"
|
||||
buildflags+=(-- -j "$PARALLEL_COUNT")
|
||||
# note, no normal build flags should be added after this
|
||||
else
|
||||
buildflags+=(--parallel "$PARALLEL_COUNT")
|
||||
fi
|
||||
fi
|
||||
|
||||
function ccachestatsverbose() {
|
||||
# note, verbose only works on newer ccache, discard the error
|
||||
local got
|
||||
if got="$(ccache --show-stats --verbose 2>/dev/null)"; then
|
||||
echo "$got"
|
||||
else
|
||||
ccache --show-stats
|
||||
fi
|
||||
}
|
||||
|
||||
# Compile
|
||||
echo "::group::Show ccache stats"
|
||||
ccache --show-stats
|
||||
echo "::endgroup::"
|
||||
if [[ $USE_CCACHE ]]; then
|
||||
echo "::group::Show ccache stats"
|
||||
ccachestatsverbose
|
||||
echo "::endgroup::"
|
||||
fi
|
||||
|
||||
echo "::group::Configure cmake"
|
||||
cmake --version
|
||||
cmake .. $flags
|
||||
cmake .. "${flags[@]}"
|
||||
echo "::endgroup::"
|
||||
|
||||
echo "::group::Build project"
|
||||
cmake --build .
|
||||
cmake --build . "${buildflags[@]}"
|
||||
echo "::endgroup::"
|
||||
|
||||
echo "::group::Show ccache stats again"
|
||||
ccache --show-stats
|
||||
echo "::endgroup::"
|
||||
if [[ $USE_CCACHE ]]; then
|
||||
echo "::group::Show ccache stats again"
|
||||
ccachestatsverbose
|
||||
echo "::endgroup::"
|
||||
fi
|
||||
|
||||
if [[ $MAKE_TEST ]]; then
|
||||
echo "::group::Run tests"
|
||||
cmake --build . --target test
|
||||
ctest -C "$BUILDTYPE"
|
||||
echo "::endgroup::"
|
||||
fi
|
||||
|
||||
if [[ $MAKE_INSTALL ]]; then
|
||||
echo "::group::Install"
|
||||
cmake --build . --target install
|
||||
cmake --build . --target install --config "$BUILDTYPE"
|
||||
echo "::endgroup::"
|
||||
fi
|
||||
|
||||
if [[ $MAKE_PACKAGE ]]; then
|
||||
echo "::group::Create package"
|
||||
cmake --build . --target package
|
||||
cmake --build . --target package --config "$BUILDTYPE"
|
||||
echo "::endgroup::"
|
||||
|
||||
if [[ $PACKAGE_SUFFIX ]]; then
|
||||
echo "::group::Update package name"
|
||||
../.ci/name_build.sh "$PACKAGE_SUFFIX"
|
||||
cd ..
|
||||
BUILD_DIR="$BUILD_DIR" .ci/name_build.sh "$PACKAGE_SUFFIX"
|
||||
echo "::endgroup::"
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -3,11 +3,15 @@
|
||||
# This script is to be used by the ci environment from the project root directory, do not use it from somewhere else.
|
||||
|
||||
# Creates or loads docker images to use in compilation, creates RUN function to start compilation on the docker image.
|
||||
# <arg> sets the name of the docker image, these correspond to directories in .ci
|
||||
# --get loads the image from a previously saved image cache, will build if no image is found
|
||||
# --build builds the image from the Dockerfile in .ci/$NAME
|
||||
# --save stores the image, if an image was loaded it will not be stored
|
||||
# --interactive immediately starts the image interactively for debugging
|
||||
# --set-cache <location> sets the location to cache the image or for ccache
|
||||
# requires: docker
|
||||
# uses env: NAME CACHE BUILD GET SAVE (correspond to args: <name> --set-cache <cache> --build --get --save)
|
||||
# uses env: NAME CACHE BUILD GET SAVE INTERACTIVE
|
||||
# (correspond to args: <name> --set-cache <cache> --build --get --save --interactive)
|
||||
# sets env: RUN CCACHE_DIR IMAGE_NAME RUN_ARGS RUN_OPTS BUILD_SCRIPT
|
||||
# exitcode: 1 for failure, 2 for missing dockerfile, 3 for invalid arguments
|
||||
export BUILD_SCRIPT=".ci/compile.sh"
|
||||
@@ -18,7 +22,7 @@ image_cache="image"
|
||||
ccache_cache=".ccache"
|
||||
|
||||
# Read arguments
|
||||
while [[ "$@" ]]; do
|
||||
while [[ $# != 0 ]]; do
|
||||
case "$1" in
|
||||
'--build')
|
||||
BUILD=1
|
||||
@@ -28,6 +32,10 @@ while [[ "$@" ]]; do
|
||||
GET=1
|
||||
shift
|
||||
;;
|
||||
'--interactive')
|
||||
INTERACTIVE=1
|
||||
shift
|
||||
;;
|
||||
'--save')
|
||||
SAVE=1
|
||||
shift
|
||||
@@ -36,12 +44,12 @@ while [[ "$@" ]]; do
|
||||
CACHE=$2
|
||||
if ! [[ -d $CACHE ]]; then
|
||||
echo "could not find cache path: $CACHE" >&2
|
||||
exit 3
|
||||
return 3
|
||||
fi
|
||||
shift 2
|
||||
;;
|
||||
*)
|
||||
if [[ $1 == -* ]]; then
|
||||
if [[ ${1:0:1} == - ]]; then
|
||||
echo "unrecognized option: $1"
|
||||
return 3
|
||||
fi
|
||||
@@ -67,27 +75,27 @@ fi
|
||||
|
||||
if ! [[ $CACHE ]]; then
|
||||
echo "cache dir is not set!" >&2
|
||||
else
|
||||
if ! [[ -d $CACHE ]]; then
|
||||
echo "could not find cache dir: $CACHE" >&2
|
||||
mkdir -p $CACHE
|
||||
unset GET # the dir is empty
|
||||
fi
|
||||
if [[ $GET || $SAVE ]]; then
|
||||
img_dir="$CACHE/$image_cache"
|
||||
img_save="$img_dir/$IMAGE_NAME$save_extension"
|
||||
if ! [[ -d $img_dir ]]; then
|
||||
echo "could not find image dir: $img_dir" >&2
|
||||
mkdir -p "$img_dir"
|
||||
fi
|
||||
fi
|
||||
export CCACHE_DIR="$CACHE/$ccache_cache"
|
||||
if ! [[ -d $CCACHE_DIR ]]; then
|
||||
echo "could not find ccache dir: $CCACHE_DIR" >&2
|
||||
mkdir -p "$CCACHE_DIR"
|
||||
CACHE="$(mktemp -d)"
|
||||
echo "set cache dir to $CACHE" >&2
|
||||
fi
|
||||
if ! [[ -d $CACHE ]]; then
|
||||
echo "could not find cache dir: $CACHE" >&2
|
||||
mkdir -p "$CACHE"
|
||||
unset GET # the dir is empty
|
||||
fi
|
||||
if [[ $GET || $SAVE ]]; then
|
||||
img_dir="$CACHE/$image_cache"
|
||||
img_save="$img_dir/$IMAGE_NAME$save_extension"
|
||||
if ! [[ -d $img_dir ]]; then
|
||||
echo "could not find image dir: $img_dir" >&2
|
||||
mkdir -p "$img_dir"
|
||||
fi
|
||||
fi
|
||||
|
||||
export CCACHE_DIR="$CACHE/$ccache_cache"
|
||||
if ! [[ -d $CCACHE_DIR ]]; then
|
||||
echo "could not find ccache dir: $CCACHE_DIR" >&2
|
||||
mkdir -p "$CCACHE_DIR"
|
||||
fi
|
||||
|
||||
# Get the docker image from previously stored save
|
||||
if [[ $GET ]]; then
|
||||
@@ -132,15 +140,26 @@ fi
|
||||
function RUN ()
|
||||
{
|
||||
echo "running image:"
|
||||
if docker images | grep "$IMAGE_NAME"; then
|
||||
args="--mount type=bind,source=$PWD,target=/src -w=/src"
|
||||
if [[ $(docker images) =~ "$IMAGE_NAME" ]]; then
|
||||
local args=(--mount "type=bind,source=$PWD,target=/src")
|
||||
args+=(--workdir "/src")
|
||||
args+=(--user "$(id -u):$(id -g)")
|
||||
if [[ $CCACHE_DIR ]]; then
|
||||
args+=" --mount type=bind,source=$CCACHE_DIR,target=/.ccache -e CCACHE_DIR=/.ccache"
|
||||
args+=(--mount "type=bind,source=$CCACHE_DIR,target=/.ccache")
|
||||
args+=(--env "CCACHE_DIR=/.ccache")
|
||||
fi
|
||||
docker run $args $RUN_ARGS "$IMAGE_NAME" bash "$BUILD_SCRIPT" $RUN_OPTS $@
|
||||
docker run "${args[@]}" $RUN_ARGS "$IMAGE_NAME" bash "$BUILD_SCRIPT" $RUN_OPTS "$@"
|
||||
return $?
|
||||
else
|
||||
echo "could not find docker image: $IMAGE_NAME" >&2
|
||||
return 3
|
||||
fi
|
||||
}
|
||||
|
||||
# for debugging, start the docker image interactively instead of building
|
||||
# starts immediately, does not require sourcing or RUN
|
||||
if [[ $INTERACTIVE ]]; then
|
||||
export BUILD_SCRIPT="-i"
|
||||
export RUN_ARGS="$RUN_ARGS -it"
|
||||
RUN
|
||||
fi
|
||||
|
||||
35
.ci/download_openssl.sh
Normal file
35
.ci/download_openssl.sh
Normal file
@@ -0,0 +1,35 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Read arguments
|
||||
while [[ $# != 0 ]]; do
|
||||
case "$1" in
|
||||
'--')
|
||||
shift
|
||||
;;
|
||||
'--arch')
|
||||
shift
|
||||
if [[ $# == 0 ]]; then
|
||||
echo "::error file=$0::--arch expects an argument"
|
||||
exit 3
|
||||
fi
|
||||
OS_ARCH="$1"
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
echo "::error file=$0::unrecognized option: $1"
|
||||
exit 3
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
set -e
|
||||
|
||||
OPEN_SSL_VERSION="1.1.1n"
|
||||
DEST_PATH="C:\OpenSSL-Win$OS_ARCH"
|
||||
|
||||
curl -JLSs "https://github.com/CristiFati/Prebuilt-Binaries/raw/master/OpenSSL/v1.1.1/OpenSSL-$OPEN_SSL_VERSION-Win-pc0$OS_ARCH.zip" -o OpenSSL.zip
|
||||
unzip -q "OpenSSL.zip"
|
||||
rm "OpenSSL.zip"
|
||||
mv "OpenSSL\OpenSSL\\$OPEN_SSL_VERSION" "$DEST_PATH"
|
||||
rm -r "OpenSSL"
|
||||
echo "Installed OpenSSL v$OPEN_SSL_VERSION to $DEST_PATH"
|
||||
@@ -42,11 +42,11 @@ ${diff#*
|
||||
|
||||
Exiting...
|
||||
EOM
|
||||
exit 2
|
||||
;;
|
||||
exit 2
|
||||
;;
|
||||
|
||||
0)
|
||||
cat <<EOM
|
||||
0)
|
||||
cat <<EOM
|
||||
|
||||
***********************************************************
|
||||
*** ***
|
||||
@@ -58,12 +58,12 @@ EOM
|
||||
|
||||
Exiting...
|
||||
EOM
|
||||
exit 0
|
||||
;;
|
||||
exit 0
|
||||
;;
|
||||
|
||||
*)
|
||||
echo ""
|
||||
echo "Something went wrong in our formatting checks: clangify returned $err" >&2
|
||||
echo ""
|
||||
;;
|
||||
esac
|
||||
*)
|
||||
echo ""
|
||||
echo "Something went wrong in our formatting checks: clangify returned $err" >&2
|
||||
echo ""
|
||||
;;
|
||||
esac
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
# renames the file to [original name][SUFFIX].[original extension]
|
||||
# where SUFFIX is either available in the environment or as the first arg
|
||||
# if MAKE_ZIP is set instead a zip is made
|
||||
# expected to be run in the build directory
|
||||
builddir="."
|
||||
# expected to be run in the build directory unless BUILD_DIR is set
|
||||
builddir="${BUILD_DIR:=.}"
|
||||
findrx="Cockatrice-*.*"
|
||||
|
||||
if [[ $1 ]]; then
|
||||
@@ -27,6 +27,7 @@ if [[ ! $file ]]; then
|
||||
echo "::error file=$0::could not find package"
|
||||
exit 1
|
||||
fi
|
||||
oldpwd="$PWD"
|
||||
if ! cd "$path"; then
|
||||
echo "::error file=$0::could not get file path"
|
||||
exit 1
|
||||
@@ -45,6 +46,9 @@ else
|
||||
echo "renaming '$file' to '$filename'"
|
||||
mv "$file" "$filename"
|
||||
fi
|
||||
ls -l "$PWD/$filename"
|
||||
echo "::set-output name=path::$PWD/$filename"
|
||||
|
||||
cd "$oldpwd"
|
||||
relative_path="$path/$filename"
|
||||
ls -l "$relative_path"
|
||||
echo "::set-output name=path::$relative_path"
|
||||
echo "::set-output name=name::$filename"
|
||||
|
||||
@@ -8,18 +8,20 @@ git push -d origin --REPLACE-WITH-BETA-LIST--
|
||||
include different targets -->
|
||||
<pre>
|
||||
<b>Pre-compiled binaries we serve:</b>
|
||||
- <kbd>Windows 7/8/10 (32-bit)</kbd></i>
|
||||
- <kbd>Windows 7/8/10 (64-bit)</kbd></i>
|
||||
- <kbd>macOS 10.14</kbd> ("Mojave")</i>
|
||||
- <kbd>macOS 10.15</kbd> ("Catalina")</i>
|
||||
- <kbd>macOS 11.0</kbd> ("Big Sur")</i>
|
||||
- <kbd>Ubuntu 18.04</kbd> ("Bionic Beaver")</i>
|
||||
- <kbd>Ubuntu 20.04</kbd> ("Focal Fossa")</i>
|
||||
- <kbd>Ubuntu 20.10</kbd> ("Groovy Gorilla")</i>
|
||||
- <kbd>Ubuntu 21.04</kbd> ("Hirsute Hippo")</i>
|
||||
- <kbd>Debian 10</kbd> ("Buster")</i>
|
||||
- <kbd>Fedora 33</kbd></i>
|
||||
- <kbd>Fedora 34</kbd></i>
|
||||
- <kbd>Windows 7/8/10/11 (32-bit)</kbd>
|
||||
- <kbd>Windows 7/8/10/11 (64-bit)</kbd>
|
||||
- <kbd>macOS 10.14</kbd> ("Mojave")
|
||||
- <kbd>macOS 10.15</kbd> ("Catalina")
|
||||
- <kbd>macOS 11.0</kbd> ("Big Sur")
|
||||
- <kbd>Ubuntu 18.04</kbd> ("Bionic Beaver")
|
||||
- <kbd>Ubuntu 20.04</kbd> ("Focal Fossa")
|
||||
- <kbd>Ubuntu 21.10</kbd> ("Impish Indri")
|
||||
- <kbd>Ubuntu 22.04</kbd> ("Jammy Jellyfish")
|
||||
- <kbd>Debian 10</kbd> ("Buster")
|
||||
- <kbd>Debian 11</kbd> ("Bullseye")
|
||||
- <kbd>Fedora 34</kbd>
|
||||
- <kbd>Fedora 35</kbd>
|
||||
- <kbd>Fedora 36</kbd>
|
||||
<kbd>We are also packaged in Arch Linux's official community repository, courtesy of @FFY00</kbd></i>
|
||||
<kbd>General linux support is available via a flatpak package (Flathub)</kbd></i>
|
||||
</pre>
|
||||
@@ -44,7 +46,7 @@ If you'd like to help contribute to Cockatrice in any way, check out our [README
|
||||
> ⚠️ **With this release, we no longer provide a ready-to-install binary for:**
|
||||
> --DEPRECATED-OS-HERE--
|
||||
-->
|
||||
|
||||
|
||||
- Run the internal software updater: <kbd>Help → Check for Client Updates</kbd>
|
||||
|
||||
Don't forget to update your card database right after! (<kbd>Help → Check for Card Updates...</kbd>)
|
||||
|
||||
106
.cmake-format.json
Normal file
106
.cmake-format.json
Normal file
@@ -0,0 +1,106 @@
|
||||
{
|
||||
"format": {
|
||||
"_help_line_width": [
|
||||
"How wide to allow formatted cmake files"
|
||||
],
|
||||
"line_width": 120,
|
||||
"_help_tab_size": [
|
||||
"How many spaces to tab for indent"
|
||||
],
|
||||
"tab_size": 2,
|
||||
"_help_max_subgroups_hwrap": [
|
||||
"If an argument group contains more than this many sub-groups",
|
||||
"(parg or kwarg groups) then force it to a vertical layout."
|
||||
],
|
||||
"max_subgroups_hwrap": 2,
|
||||
"_help_max_pargs_hwrap": [
|
||||
"If a positional argument group contains more than this many",
|
||||
"arguments, then force it to a vertical layout."
|
||||
],
|
||||
"max_pargs_hwrap": 6,
|
||||
"_help_max_rows_cmdline": [
|
||||
"If a cmdline positional group consumes more than this many",
|
||||
"lines without nesting, then invalidate the layout (and nest)"
|
||||
],
|
||||
"max_rows_cmdline": 5,
|
||||
"_help_separate_ctrl_name_with_space": [
|
||||
"If true, separate flow control names from their parentheses",
|
||||
"with a space"
|
||||
],
|
||||
"separate_ctrl_name_with_space": false,
|
||||
"_help_separate_fn_name_with_space": [
|
||||
"If true, separate function names from parentheses with a",
|
||||
"space"
|
||||
],
|
||||
"separate_fn_name_with_space": false,
|
||||
"_help_dangle_parens": [
|
||||
"If a statement is wrapped to more than one line, than dangle",
|
||||
"the closing parenthesis on its own line."
|
||||
],
|
||||
"dangle_parens": true,
|
||||
"_help_dangle_align": [
|
||||
"If the trailing parenthesis must be 'dangled' on its on",
|
||||
"line, then align it to this reference: `prefix`: the start",
|
||||
"of the statement, `prefix-indent`: the start of the",
|
||||
"statement, plus one indentation level, `child`: align to",
|
||||
"the column of the arguments"
|
||||
],
|
||||
"dangle_align": "prefix",
|
||||
"_help_min_prefix_chars": [
|
||||
"If the statement spelling length (including space and",
|
||||
"parenthesis) is smaller than this amount, then force reject",
|
||||
"nested layouts."
|
||||
],
|
||||
"min_prefix_chars": 4,
|
||||
"_help_max_prefix_chars": [
|
||||
"If the statement spelling length (including space and",
|
||||
"parenthesis) is larger than the tab width by more than this",
|
||||
"amount, then force reject un-nested layouts."
|
||||
],
|
||||
"max_prefix_chars": 10,
|
||||
"_help_max_lines_hwrap": [
|
||||
"If a candidate layout is wrapped horizontally but it exceeds",
|
||||
"this many lines, then reject the layout."
|
||||
],
|
||||
"max_lines_hwrap": 2,
|
||||
"_help_line_ending": [
|
||||
"What style line endings to use in the output."
|
||||
],
|
||||
"line_ending": "auto",
|
||||
"_help_command_case": [
|
||||
"Format command names consistently as 'lower' or 'upper' case"
|
||||
],
|
||||
"command_case": "lower",
|
||||
"_help_keyword_case": [
|
||||
"Format keywords consistently as 'lower' or 'upper' case"
|
||||
],
|
||||
"keyword_case": "upper",
|
||||
"_help_always_wrap": [
|
||||
"A list of command names which should always be wrapped"
|
||||
],
|
||||
"always_wrap": [],
|
||||
"_help_enable_sort": [
|
||||
"If true, the argument lists which are known to be sortable",
|
||||
"will be sorted lexicographically"
|
||||
],
|
||||
"enable_sort": true,
|
||||
"_help_autosort": [
|
||||
"If true, the parsers may infer whether or not an argument",
|
||||
"list is sortable (without annotation)."
|
||||
],
|
||||
"autosort": true,
|
||||
"_help_require_valid_layout": [
|
||||
"By default, if cmake-format cannot successfully fit",
|
||||
"everything into the desired line-width it will apply the",
|
||||
"last, most aggressive attempt that it made. If this flag is",
|
||||
"True, however, cmake-format will print error, exit with non-",
|
||||
"zero status code, and write-out nothing"
|
||||
],
|
||||
"require_valid_layout": false,
|
||||
"_help_layout_passes": [
|
||||
"A dictionary mapping layout nodes to a list of wrap",
|
||||
"decisions. See the documentation for more information."
|
||||
],
|
||||
"layout_passes": {}
|
||||
}
|
||||
}
|
||||
10
.github/CONTRIBUTING.md
vendored
10
.github/CONTRIBUTING.md
vendored
@@ -290,7 +290,7 @@ be included in the next release 👍
|
||||
|
||||
Basic workflow for translations:
|
||||
1. Developer adds a `tr("foo")` string in the code;
|
||||
2. Every few days, a maintainer updates the `*_en.ts files` with the new strings;
|
||||
2. Every few days, a maintainer updates the `*_en@source.ts files` with the new strings;
|
||||
3. Transifex picks up the new files from GitHub every 24 hours;
|
||||
4. Translators translate the new untranslated strings on Transifex;
|
||||
5. Before a release, a maintainer fetches the updated translations from Transifex.
|
||||
@@ -344,14 +344,14 @@ make
|
||||
If the parameter has been enabled correctly, when running "make" you should see
|
||||
a line similar to this one (the numbers may vary):
|
||||
```sh
|
||||
[ 76%] Generating ../../cockatrice/translations/cockatrice_en.ts
|
||||
Updating '../../cockatrice/translations/cockatrice_en.ts'...
|
||||
[ 76%] Generating ../../cockatrice/translations/cockatrice_en@source.ts
|
||||
Updating '../../cockatrice/translations/cockatrice_en@source.ts'...
|
||||
Found 857 source text(s) (8 new and 849 already existing)
|
||||
```
|
||||
You should then notice that the following files have uncommitted changes:
|
||||
|
||||
cockatrice/translations/cockatrice_en.ts
|
||||
oracle/translations/oracle_en.ts
|
||||
cockatrice/translations/cockatrice_en@source.ts
|
||||
oracle/translations/oracle_en@source.ts
|
||||
|
||||
It is recommended to disable the parameter afterwards using:
|
||||
```sh
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
name: Build
|
||||
name: Build Desktop
|
||||
|
||||
on:
|
||||
push:
|
||||
@@ -7,21 +7,19 @@ on:
|
||||
paths-ignore:
|
||||
- '**.md'
|
||||
- 'webclient/**'
|
||||
- '.github/workflows/web-*.yml'
|
||||
tags:
|
||||
- '*'
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
paths-ignore:
|
||||
- '**.md'
|
||||
- 'webclient/**'
|
||||
- '.github/workflows/web-*.yml'
|
||||
|
||||
jobs:
|
||||
configure:
|
||||
name: Configure
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
outputs:
|
||||
tag: ${{steps.configure.outputs.tag}}
|
||||
sha: ${{steps.configure.outputs.sha}}
|
||||
@@ -55,7 +53,7 @@ jobs:
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Prepare release paramaters
|
||||
- name: Prepare release parameters
|
||||
id: prepare
|
||||
if: steps.configure.outputs.tag != null
|
||||
shell: bash
|
||||
@@ -82,45 +80,52 @@ jobs:
|
||||
matrix:
|
||||
# these names correspond to the files in .ci/$distro
|
||||
include:
|
||||
- distro: UbuntuImpish
|
||||
package: DEB
|
||||
|
||||
- distro: UbuntuHirsute
|
||||
package: DEB
|
||||
test: skip
|
||||
|
||||
- distro: UbuntuFocal
|
||||
package: DEB
|
||||
test: skip # UbuntuFocal has a broken qt for debug builds
|
||||
|
||||
- distro: UbuntuBionic
|
||||
package: DEB
|
||||
|
||||
- distro: ArchLinux
|
||||
package: skip # we are packaged in arch already
|
||||
allow-failure: yes
|
||||
|
||||
- distro: DebianBuster
|
||||
- distro: Debian10
|
||||
package: DEB
|
||||
test: skip # running tests on all distros is superfluous
|
||||
|
||||
- distro: Fedora35
|
||||
package: RPM
|
||||
- distro: Debian11
|
||||
package: DEB
|
||||
|
||||
- distro: Fedora34
|
||||
package: RPM
|
||||
test: skip # gtest does not compile for some reason
|
||||
|
||||
- distro: Fedora35
|
||||
package: RPM
|
||||
test: skip
|
||||
|
||||
- distro: Fedora36
|
||||
package: RPM
|
||||
|
||||
- distro: UbuntuBionic
|
||||
package: DEB
|
||||
|
||||
- distro: UbuntuFocal
|
||||
package: DEB
|
||||
test: skip # UbuntuFocal has a broken qt for debug builds
|
||||
|
||||
- distro: UbuntuImpish
|
||||
package: DEB
|
||||
test: skip
|
||||
|
||||
- distro: UbuntuJammy
|
||||
package: DEB
|
||||
|
||||
name: ${{matrix.distro}}
|
||||
|
||||
needs: configure
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
continue-on-error: ${{matrix.allow-failure == 'yes'}}
|
||||
|
||||
env:
|
||||
NAME: ${{matrix.distro}}
|
||||
CACHE: /tmp/${{matrix.distro}}-cache # ${{runner.temp}} does not work?
|
||||
# cache size over the entire repo is 10Gi link:
|
||||
# https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows#usage-limits-and-eviction-policy
|
||||
CCACHE_SIZE: 200M
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
@@ -148,9 +153,11 @@ jobs:
|
||||
- name: Build debug and test
|
||||
if: matrix.test != 'skip'
|
||||
shell: bash
|
||||
env:
|
||||
distro: '${{matrix.distro}}'
|
||||
run: |
|
||||
source .ci/docker.sh
|
||||
RUN --server --debug --test
|
||||
RUN --server --debug --test --ccache "$CCACHE_SIZE" --parallel 2
|
||||
|
||||
- name: Build release package
|
||||
id: package
|
||||
@@ -159,16 +166,18 @@ jobs:
|
||||
env:
|
||||
suffix: '-${{matrix.distro}}'
|
||||
type: '${{matrix.package}}'
|
||||
distro: '${{matrix.distro}}'
|
||||
run: |
|
||||
source .ci/docker.sh
|
||||
RUN --server --release --package "$type" --suffix "$suffix"
|
||||
RUN --server --release --package "$type" --suffix "$suffix" \
|
||||
--ccache "$CCACHE_SIZE" --parallel 2
|
||||
|
||||
- name: Upload artifact
|
||||
if: matrix.package != 'skip'
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: ${{matrix.distro}}-package
|
||||
path: ./build/${{steps.package.outputs.name}}
|
||||
path: ${{steps.package.outputs.path}}
|
||||
if-no-files-found: error
|
||||
|
||||
- name: Upload to release
|
||||
@@ -178,7 +187,7 @@ jobs:
|
||||
GITHUB_TOKEN: ${{github.token}}
|
||||
with:
|
||||
upload_url: ${{needs.configure.outputs.upload_url}}
|
||||
asset_path: ./build/${{steps.package.outputs.name}}
|
||||
asset_path: ${{steps.package.outputs.path}}
|
||||
asset_name: ${{steps.package.outputs.name}}
|
||||
asset_content_type: application/octet-stream
|
||||
|
||||
@@ -186,50 +195,51 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
target:
|
||||
- Debug
|
||||
- 10.14_Mojave
|
||||
- 10.15_Catalina
|
||||
- 11_Big_Sur
|
||||
include:
|
||||
- target: Debug # tests only
|
||||
os: macos-latest
|
||||
xcode: 12.1
|
||||
xcode: 12.5.1
|
||||
qt_version: 6
|
||||
type: Debug
|
||||
do_tests: 0 # tests do not work yet on mac
|
||||
make_package: false
|
||||
do_tests: 1
|
||||
|
||||
- target: 10.14_Mojave
|
||||
os: macos-10.15 # runs on Catalina
|
||||
xcode: 10.3 # allows compatibility with macOS 10.14
|
||||
qt_version: 5
|
||||
type: Release
|
||||
do_tests: 0
|
||||
make_package: true
|
||||
# do_tests: 1 # tests do not work on qt5?
|
||||
make_package: 1
|
||||
|
||||
- target: 10.15_Catalina
|
||||
os: macos-10.15
|
||||
xcode: 12.1
|
||||
xcode: 12.4
|
||||
qt_version: 6
|
||||
type: Release
|
||||
do_tests: 0
|
||||
make_package: true
|
||||
do_tests: 1
|
||||
make_package: 1
|
||||
|
||||
- target: 11_Big_Sur
|
||||
os: macos-11
|
||||
xcode: 12.5.1
|
||||
xcode: 13.2
|
||||
qt_version: 6
|
||||
type: Release
|
||||
do_tests: 0
|
||||
make_package: true
|
||||
do_tests: 1
|
||||
make_package: 1
|
||||
|
||||
# - target: 12_Monterey
|
||||
# os: macos-12
|
||||
# xcode: 13.3
|
||||
# qt_version: 6
|
||||
# type: Release
|
||||
# do_tests: 1
|
||||
# make_package: 1
|
||||
|
||||
name: macOS ${{matrix.target}}
|
||||
|
||||
needs: configure
|
||||
|
||||
runs-on: ${{matrix.os}}
|
||||
|
||||
continue-on-error: ${{matrix.allow-failure == 'yes'}}
|
||||
|
||||
env:
|
||||
CCACHE_DIR: ~/.ccache
|
||||
DEVELOPER_DIR:
|
||||
/Applications/Xcode_${{matrix.xcode}}.app/Contents/Developer
|
||||
|
||||
@@ -241,60 +251,32 @@ jobs:
|
||||
shell: bash
|
||||
# cmake cannot find the mysql connector
|
||||
# neither of these works: mariadb-connector-c mysql-connector-c++
|
||||
run: brew install ccache protobuf
|
||||
|
||||
- name: Install QT using homebrew
|
||||
id: brew_install_qt
|
||||
continue-on-error: true
|
||||
shell: bash
|
||||
run: brew install qt@5 --force-bottle
|
||||
|
||||
- name: Install QT using actions
|
||||
if: steps.brew_install_qt.outcome != 'success'
|
||||
uses: jurplel/install-qt-action@v2
|
||||
|
||||
- name: Get ccache timestamp
|
||||
id: ccache_timestamp
|
||||
shell: bash
|
||||
run: echo "::set-output name=timestamp::$(date -u '+%Y%m%d%H%M%S')"
|
||||
|
||||
- name: Restore ccache cache
|
||||
uses: actions/cache@v2
|
||||
env:
|
||||
timestamp: ${{steps.ccache_timestamp.outputs.timestamp}}
|
||||
with:
|
||||
path: ${{env.CCACHE_DIR}}
|
||||
key: ${{runner.os}}-xcode-${{matrix.xcode}}-ccache-${{env.timestamp}}
|
||||
restore-keys: |
|
||||
${{runner.os}}-xcode-${{matrix.xcode}}-ccache-
|
||||
qt_version: 'qt@${{matrix.qt_version}}'
|
||||
run: |
|
||||
brew update
|
||||
brew install protobuf
|
||||
brew install "$qt_version" --force-bottle
|
||||
|
||||
- name: Build on Xcode ${{matrix.xcode}}
|
||||
shell: bash
|
||||
id: build
|
||||
env:
|
||||
CMAKE_BUILD_PARALLEL_LEVEL: 3 # mac machines actually have 3 cores
|
||||
run: .ci/compile.sh ${{matrix.type}} --server
|
||||
|
||||
- name: Test
|
||||
if: matrix.do_tests == 1
|
||||
shell: bash
|
||||
working-directory: build
|
||||
run: cmake --build . --target test
|
||||
|
||||
- name: Package for ${{matrix.target}}
|
||||
id: package
|
||||
if: matrix.make_package
|
||||
shell: bash
|
||||
working-directory: build
|
||||
run: |
|
||||
cmake --build . --target package
|
||||
../.ci/name_build.sh "-macOS-${{matrix.target}}"
|
||||
BUILDTYPE: '${{matrix.type}}'
|
||||
MAKE_TEST: '${{matrix.do_tests}}'
|
||||
MAKE_PACKAGE: '${{matrix.make_package}}'
|
||||
PACKAGE_SUFFIX: '-macOS-${{matrix.target}}'
|
||||
# set QTDIR to find qt5, qt6 can be found without this
|
||||
QTDIR: '/usr/local/opt/qt5'
|
||||
# Mac machines actually have 3 cores
|
||||
run: .ci/compile.sh --server --parallel 3
|
||||
|
||||
- name: Upload artifact
|
||||
if: matrix.make_package
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: macOS-${{matrix.target}}-xcode-${{matrix.xcode}}-dmg
|
||||
path: ${{steps.package.outputs.path}}
|
||||
name: macOS-${{matrix.target}}-dmg
|
||||
path: ${{steps.build.outputs.path}}
|
||||
if-no-files-found: error
|
||||
|
||||
- name: Upload to release
|
||||
@@ -304,96 +286,90 @@ jobs:
|
||||
GITHUB_TOKEN: ${{github.token}}
|
||||
with:
|
||||
upload_url: ${{needs.configure.outputs.upload_url}}
|
||||
asset_path: ${{steps.package.outputs.path}}
|
||||
asset_name: ${{steps.package.outputs.name}}
|
||||
asset_path: ${{steps.build.outputs.path}}
|
||||
asset_name: ${{steps.build.outputs.name}}
|
||||
asset_content_type: application/octet-stream
|
||||
|
||||
build-windows:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
arch:
|
||||
- 64
|
||||
- 32
|
||||
include:
|
||||
- arch: 64
|
||||
triplet: x64
|
||||
cmake: x64
|
||||
append: _64
|
||||
|
||||
- arch: 32
|
||||
triplet: x86
|
||||
cmake: Win32
|
||||
|
||||
name: Windows ${{matrix.arch}}
|
||||
vcpkg_default_triplet: x86
|
||||
qt_version: '5.15.2'
|
||||
cmake_generator_platform: Win32
|
||||
qt_arch: msvc2019
|
||||
- arch: 64
|
||||
vcpkg_default_triplet: x64
|
||||
qt_version: '6.3.0'
|
||||
cmake_generator_platform: x64
|
||||
qt_arch: msvc2019_64
|
||||
qt_modules: "qt5compat qtmultimedia qtwebsockets"
|
||||
|
||||
name: Windows (${{matrix.arch}}-bit)
|
||||
needs: configure
|
||||
|
||||
runs-on: windows-latest
|
||||
|
||||
runs-on: windows-2019
|
||||
env:
|
||||
QT_VERSION: '5.15.2'
|
||||
QT_ARCH: msvc2019${{matrix.append}}
|
||||
CMAKE_GENERATOR: 'Visual Studio 16 2019'
|
||||
|
||||
steps:
|
||||
- name: Add msbuild to PATH
|
||||
id: add-msbuild
|
||||
uses: microsoft/setup-msbuild@v1.0.2
|
||||
uses: microsoft/setup-msbuild@v1.1
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Restore Qt ${{env.QT_VERSION}} ${{matrix.arch}}-bit from cache
|
||||
- name: Restore Qt ${{matrix.qt_version}} (${{matrix.arch}}-bit) from cache
|
||||
id: cache-qt
|
||||
uses: actions/cache@v2
|
||||
uses: actions/cache@v1 # Intentionally v1, based on jurplel documentation
|
||||
with:
|
||||
key: ${{runner.os}}-QtCache-${{env.QT_VERSION}}-${{matrix.arch}}
|
||||
path: ${{runner.workspace}}/Qt
|
||||
key: ${{runner.os}}-QtCache-${{matrix.qt_version}}-${{matrix.arch}}
|
||||
path: '${{github.workspace}}/../Qt'
|
||||
|
||||
- name: Install ${{matrix.arch}}-bit Qt
|
||||
uses: jurplel/install-qt-action@v2
|
||||
- name: Install Qt ${{matrix.qt_version}} (${{matrix.arch}}-bit)
|
||||
uses: jurplel/install-qt-action@v3
|
||||
with:
|
||||
cached: ${{steps.cache-qt.outputs.cache-hit}}
|
||||
version: ${{env.QT_VERSION}}
|
||||
arch: win${{matrix.arch}}_${{env.QT_ARCH}}
|
||||
version: ${{matrix.qt_version}}
|
||||
arch: win${{matrix.arch}}_${{matrix.qt_arch}}
|
||||
modules: ${{matrix.qt_modules}}
|
||||
|
||||
- name: Restore or setup vcpkg
|
||||
uses: lukka/run-vcpkg@v6
|
||||
- name: Run vcpkg
|
||||
uses: lukka/run-vcpkg@v10.2
|
||||
with:
|
||||
vcpkgArguments: '@${{github.workspace}}/vcpkg.txt'
|
||||
vcpkgDirectory: ${{github.workspace}}/vcpkg
|
||||
appendedCacheKey: ${{hashFiles('**/vcpkg.txt')}}
|
||||
vcpkgTriplet: ${{matrix.triplet}}-windows
|
||||
runVcpkgInstall: true
|
||||
appendedCacheKey: ${{matrix.arch}}-bit
|
||||
env:
|
||||
VCPKG_DEFAULT_TRIPLET: '${{matrix.vcpkg_default_triplet}}-windows'
|
||||
VCPKG_DISABLE_METRICS: 1
|
||||
|
||||
- name: Configure Cockatrice ${{matrix.arch}}-bit
|
||||
- name: Install OpenSSL (${{matrix.arch}}-bit)
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir -p build
|
||||
cd build
|
||||
export QTDIR="${{runner.workspace}}/Qt/${{env.QT_VERSION}}/${{env.QT_ARCH}}"
|
||||
cmake .. -G "${{env.CMAKE_GENERATOR}}" -A "${{matrix.cmake}}" -DCMAKE_BUILD_TYPE="Release" -DWITH_SERVER=1 -DTEST=1
|
||||
run: .ci/download_openssl.sh --arch ${{matrix.arch}}
|
||||
|
||||
- name: Build Cockatrice ${{matrix.arch}}-bit
|
||||
id: package
|
||||
- name: Build Cockatrice (${{matrix.arch}}-bit)
|
||||
id: build
|
||||
shell: bash
|
||||
working-directory: build
|
||||
run: |
|
||||
cmake --build . --target package --config Release
|
||||
../.ci/name_build.sh "-win${{matrix.arch}}"
|
||||
env:
|
||||
PACKAGE_SUFFIX: '-win${{matrix.arch}}'
|
||||
CMAKE_GENERATOR: '${{env.CMAKE_GENERATOR}}'
|
||||
CMAKE_GENERATOR_PLATFORM: '${{matrix.cmake_generator_platform}}'
|
||||
QTDIR: '${{github.workspace}}\Qt\${{matrix.qt_version}}\win${{matrix.arch}}_${{matrix.qt_arch}}'
|
||||
run: .ci/compile.sh --server --release --test --package --parallel 2
|
||||
|
||||
- name: Run tests
|
||||
shell: bash
|
||||
working-directory: build
|
||||
run: ctest -T Test -C Release
|
||||
- name: Setup tmate session
|
||||
if: ${{ failure() }}
|
||||
uses: mxschmitt/action-tmate@v3
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v2
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: Windows-${{matrix.arch}}bit-installer
|
||||
path: ./build/${{steps.package.outputs.name}}
|
||||
path: ${{steps.build.outputs.path}}
|
||||
if-no-files-found: error
|
||||
|
||||
- name: Upload to release
|
||||
@@ -403,6 +379,6 @@ jobs:
|
||||
GITHUB_TOKEN: ${{github.token}}
|
||||
with:
|
||||
upload_url: ${{needs.configure.outputs.upload_url}}
|
||||
asset_path: ./build/${{steps.package.outputs.name}}
|
||||
asset_name: ${{steps.package.outputs.name}}
|
||||
asset_path: ${{steps.build.outputs.path}}
|
||||
asset_name: ${{steps.build.outputs.name}}
|
||||
asset_content_type: application/octet-stream
|
||||
@@ -2,11 +2,10 @@ name: Code Style (C++)
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
paths-ignore:
|
||||
- '**.md'
|
||||
- 'webclient/**'
|
||||
- '.github/workflows/web-*.yml'
|
||||
|
||||
jobs:
|
||||
clang-format:
|
||||
66
.github/workflows/translations.yml
vendored
Normal file
66
.github/workflows/translations.yml
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
name: Update translation source
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
# runs once per month
|
||||
- cron: '0 0 1 * *'
|
||||
|
||||
jobs:
|
||||
translations:
|
||||
# Do not run the scheduled workflow on forks
|
||||
if: github.event_name != 'schedule' || github.repository_owner == 'Cockatrice'
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Install lupdate
|
||||
shell: bash
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y --no-install-recommends qttools5-dev-tools
|
||||
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Update cockatrice translations
|
||||
shell: bash
|
||||
run: |
|
||||
shopt -s globstar # globstar is needed for recursive **
|
||||
lupdate -version
|
||||
echo "reading the following source files:"
|
||||
# note: there are three strings to translate in common right now
|
||||
echo {cockatrice,common}/**/*.{cpp,h}
|
||||
echo "$(echo {cockatrice,common}/**/*.{cpp,h} | wc -w) files total"
|
||||
lupdate {cockatrice,common}/**/*.{cpp,h} -ts cockatrice/translations/cockatrice_en@source.ts
|
||||
|
||||
- name: Update oracle translations
|
||||
shell: bash
|
||||
run: |
|
||||
shopt -s globstar # globstar is needed for recursive **
|
||||
lupdate -version
|
||||
echo "reading the following source files:"
|
||||
echo oracle/**/*.{cpp,h}
|
||||
echo "$(echo oracle/**/*.{cpp,h} | wc -w) files total"
|
||||
lupdate oracle/**/*.{cpp,h} -ts oracle/translations/oracle_en@source.ts
|
||||
|
||||
- name: Check for updates
|
||||
id: check
|
||||
shell: bash
|
||||
run: |
|
||||
set +e # do not fail, just save the exit state
|
||||
git diff --exit-code
|
||||
echo "::set-output name=deploy::$?"
|
||||
|
||||
- name: Commit changes
|
||||
if: steps.check.outputs.deploy == '1'
|
||||
shell: bash
|
||||
working-directory: ${{env.OUTPUT_PATH}}
|
||||
run: |
|
||||
git config user.name github-actions
|
||||
git config user.email github-actions@github.com
|
||||
git add cockatrice/translations/cockatrice_en@source.ts oracle/translations/oracle_en@source.ts
|
||||
git commit -m "Automated translation update ( $GITHUB_SHA )"
|
||||
git push
|
||||
deploy_commit=$(git rev-parse HEAD)
|
||||
echo "Created commit: $GITHUB_SERVER_URL/$GITHUB_REPOSITORY/commit/$deploy_commit"
|
||||
53
.github/workflows/web-build.yml
vendored
Normal file
53
.github/workflows/web-build.yml
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
name: Build Web
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
paths:
|
||||
- '.github/workflows/web-*.yml'
|
||||
- 'webclient/**'
|
||||
- '!**.md'
|
||||
pull_request:
|
||||
paths:
|
||||
- '.github/workflows/web-*.yml'
|
||||
- 'webclient/**'
|
||||
- '!**.md'
|
||||
|
||||
jobs:
|
||||
build-web:
|
||||
name: React (Node ${{matrix.node_version}})
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
defaults:
|
||||
run:
|
||||
working-directory: webclient
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
node_version:
|
||||
- 12
|
||||
- lts/*
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: ${{matrix.node_version}}
|
||||
cache: 'npm'
|
||||
cache-dependency-path: 'webclient/package-lock.json'
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm clean-install
|
||||
|
||||
- name: Build app
|
||||
run: npm run build
|
||||
|
||||
- name: Test app
|
||||
run: npm run test
|
||||
|
||||
32
.github/workflows/web-lint.yml
vendored
Normal file
32
.github/workflows/web-lint.yml
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
name: Code Style (TypeScript)
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- '.github/workflows/web-*.yml'
|
||||
- 'webclient/**'
|
||||
- '!**.md'
|
||||
|
||||
jobs:
|
||||
ESLint:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
defaults:
|
||||
run:
|
||||
working-directory: webclient
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
cache: 'npm'
|
||||
cache-dependency-path: 'webclient/package-lock.json'
|
||||
|
||||
- name: Install ESLint
|
||||
run: npm clean-install --ignore-scripts
|
||||
|
||||
- name: Run ESLint
|
||||
run: npm run lint
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -6,7 +6,8 @@ mysql.cnf
|
||||
.DS_Store
|
||||
.idea/
|
||||
*.aps
|
||||
cmake-build-debug/
|
||||
cmake-build-debug*
|
||||
preferences
|
||||
compile_commands.json
|
||||
.vs/
|
||||
.vscode/
|
||||
|
||||
7
.husky/pre-commit
Executable file
7
.husky/pre-commit
Executable file
@@ -0,0 +1,7 @@
|
||||
#!/bin/sh
|
||||
. "$(dirname "$0")/_/husky.sh"
|
||||
|
||||
cd webclient
|
||||
npm run translate
|
||||
|
||||
git add src/i18n-default.json
|
||||
@@ -1,13 +1,13 @@
|
||||
[main]
|
||||
host = https://www.transifex.com
|
||||
|
||||
[cockatrice.cockatrice]
|
||||
[cockatrice.cockatrice-translations-cockatrice-en-source-ts--master]
|
||||
file_filter = cockatrice/translations/cockatrice_<lang>.ts
|
||||
source_file = cockatrice/translations/cockatrice_en.ts
|
||||
source_file = cockatrice/translations/cockatrice_en@source.ts
|
||||
source_lang = en
|
||||
|
||||
[cockatrice.oracle]
|
||||
[cockatrice.oracle-translations-oracle-en-source-ts--master]
|
||||
file_filter = oracle/translations/oracle_<lang>.ts
|
||||
source_file = oracle/translations/oracle_en.ts
|
||||
source_file = oracle/translations/oracle_en@source.ts
|
||||
source_lang = en
|
||||
|
||||
|
||||
117
CMakeLists.txt
117
CMakeLists.txt
@@ -5,9 +5,26 @@
|
||||
# This file sets all the variables shared between the projects
|
||||
# like the installation path, compilation flags etc..
|
||||
|
||||
# Cmake 3.1 is required to enable C++11 support correctly
|
||||
# cmake 3.16 is required if using qt6
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
|
||||
# Early detect ccache
|
||||
option(USE_CCACHE "Cache the build results with ccache" ON)
|
||||
# Treat warnings as errors (Debug builds only)
|
||||
option(WARNING_AS_ERROR "Treat warnings as errors in debug builds" ON)
|
||||
# Check for translation updates
|
||||
option(UPDATE_TRANSLATIONS "Update translations on compile" OFF)
|
||||
# Compile servatrice
|
||||
option(WITH_SERVER "build servatrice" OFF)
|
||||
# Compile cockatrice
|
||||
option(WITH_CLIENT "build cockatrice" ON)
|
||||
# Compile oracle
|
||||
option(WITH_ORACLE "build oracle" ON)
|
||||
# Compile dbconverter
|
||||
option(WITH_DBCONVERTER "build dbconverter" ON)
|
||||
# Compile tests
|
||||
option(TEST "build tests" OFF)
|
||||
|
||||
# Default to "Release" build type
|
||||
# User-provided value for CMAKE_BUILD_TYPE must be checked before the PROJECT() call
|
||||
IF(DEFINED CMAKE_BUILD_TYPE)
|
||||
@@ -16,8 +33,6 @@ ELSE()
|
||||
SET(CMAKE_BUILD_TYPE Release CACHE STRING "Type of build")
|
||||
ENDIF()
|
||||
|
||||
# Early detect ccache
|
||||
OPTION(USE_CCACHE "Cache the build results with ccache" ON)
|
||||
if(USE_CCACHE)
|
||||
find_program(CCACHE_PROGRAM ccache)
|
||||
if(CCACHE_PROGRAM)
|
||||
@@ -41,22 +56,23 @@ endif()
|
||||
|
||||
# A project name is needed for CPack
|
||||
# Version can be overriden by git tags, see cmake/getversion.cmake
|
||||
PROJECT("Cockatrice" VERSION 2.8.1)
|
||||
project("Cockatrice" VERSION 2.8.1)
|
||||
|
||||
# Set release name if not provided via env/cmake var
|
||||
if(NOT DEFINED GIT_TAG_RELEASENAME)
|
||||
set(GIT_TAG_RELEASENAME "Prismatic Bridge")
|
||||
endif()
|
||||
|
||||
# Use c++11 for all targets
|
||||
set(CMAKE_CXX_STANDARD 11 CACHE STRING "C++ ISO Standard")
|
||||
# Use c++17 for all targets
|
||||
set(CMAKE_CXX_STANDARD 17 CACHE STRING "C++ ISO Standard")
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED True)
|
||||
|
||||
# Set conventional loops
|
||||
set(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS true)
|
||||
|
||||
# Search path for cmake modules
|
||||
SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
|
||||
set(COCKATRICE_CMAKE_PATH "${PROJECT_SOURCE_DIR}/cmake")
|
||||
list(INSERT CMAKE_MODULE_PATH 0 "${COCKATRICE_CMAKE_PATH}")
|
||||
|
||||
include(getversion)
|
||||
|
||||
@@ -76,8 +92,8 @@ if(UNIX)
|
||||
if(RULE_LAUNCH_COMPILE)
|
||||
MESSAGE(STATUS "Force enabling CCache usage under macOS")
|
||||
# Set up wrapper scripts
|
||||
configure_file(${CMAKE_MODULE_PATH}/launch-c.in launch-c)
|
||||
configure_file(${CMAKE_MODULE_PATH}/launch-cxx.in launch-cxx)
|
||||
configure_file("${COCKATRICE_CMAKE_PATH}/launch-c.in" launch-c)
|
||||
configure_file("${COCKATRICE_CMAKE_PATH}/launch-cxx.in" launch-cxx)
|
||||
execute_process(COMMAND chmod a+rx
|
||||
"${CMAKE_BINARY_DIR}/launch-c"
|
||||
"${CMAKE_BINARY_DIR}/launch-cxx")
|
||||
@@ -103,13 +119,10 @@ elseif(WIN32)
|
||||
set(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/rundir/${CMAKE_BUILD_TYPE})
|
||||
endif()
|
||||
|
||||
# Treat warnings as errors (Debug builds only)
|
||||
option(WARNING_AS_ERROR "Treat warnings as errors in debug builds" ON)
|
||||
|
||||
# Define proper compilation flags
|
||||
IF(MSVC)
|
||||
# Visual Studio: Maximum optimization, disable warning C4251
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "/Ox /MD /wd4251 ")
|
||||
# Visual Studio: Maximum optimization, disable warning C4251, establish C++17 compatibility
|
||||
SET(CMAKE_CXX_FLAGS_RELEASE "/Ox /MD /wd4251 /Zc:__cplusplus /std:c++17 /permissive-")
|
||||
# Generate complete debugging information
|
||||
#set(CMAKE_CXX_FLAGS_DEBUG "/Zi")
|
||||
ELSEIF (CMAKE_COMPILER_IS_GNUCXX)
|
||||
@@ -123,6 +136,10 @@ ELSEIF (CMAKE_COMPILER_IS_GNUCXX)
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "-ggdb -O0 -Wall -Wextra")
|
||||
endif()
|
||||
|
||||
IF(APPLE)
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++17")
|
||||
ENDIF()
|
||||
|
||||
set(ADDITIONAL_DEBUG_FLAGS -Wcast-align -Wmissing-declarations -Wno-long-long -Wno-error=extra -Wno-error=delete-non-virtual-dtor -Wno-error=sign-compare -Wno-error=missing-declarations)
|
||||
|
||||
FOREACH(FLAG ${ADDITIONAL_DEBUG_FLAGS})
|
||||
@@ -148,7 +165,7 @@ ENDIF()
|
||||
|
||||
FIND_PACKAGE(Threads REQUIRED)
|
||||
|
||||
# Find Qt5
|
||||
# Determine 32 or 64 bit build
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
set(_lib_suffix 64)
|
||||
else()
|
||||
@@ -165,28 +182,9 @@ elseif(DEFINED ENV{QTDIR})
|
||||
list(APPEND CMAKE_PREFIX_PATH "$ENV{QTDIR}")
|
||||
endif()
|
||||
|
||||
FIND_PACKAGE(Qt5Core 5.5.0 REQUIRED)
|
||||
MESSAGE(STATUS "Update Translations: ${UPDATE_TRANSLATIONS}")
|
||||
|
||||
IF(Qt5Core_FOUND)
|
||||
MESSAGE(STATUS "Found Qt ${Qt5Core_VERSION_STRING}")
|
||||
|
||||
# FIX: Qt was built with -reduce-relocations
|
||||
if (Qt5_POSITION_INDEPENDENT_CODE)
|
||||
SET(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||
endif()
|
||||
|
||||
# guess plugins and libraries directory
|
||||
set(QT_PLUGINS_DIR "${Qt5Core_DIR}/../../../plugins")
|
||||
get_target_property(QT_LIBRARY_DIR Qt5::Core LOCATION)
|
||||
get_filename_component(QT_LIBRARY_DIR ${QT_LIBRARY_DIR} PATH)
|
||||
|
||||
ELSE()
|
||||
MESSAGE(FATAL_ERROR "No Qt5 found!")
|
||||
ENDIF()
|
||||
|
||||
# Check for translation updates
|
||||
OPTION(UPDATE_TRANSLATIONS "Update translations on compile" OFF)
|
||||
MESSAGE(STATUS "UPDATE TRANSLATIONS: ${UPDATE_TRANSLATIONS}")
|
||||
include(FindQtRuntime)
|
||||
|
||||
set(CMAKE_AUTOMOC TRUE)
|
||||
|
||||
@@ -195,7 +193,7 @@ FIND_PACKAGE(Protobuf REQUIRED)
|
||||
IF(NOT EXISTS "${Protobuf_PROTOC_EXECUTABLE}")
|
||||
MESSAGE(FATAL_ERROR "No protoc command found!")
|
||||
ELSE()
|
||||
MESSAGE(STATUS "Protoc version ${Protobuf_VERSION} found!")
|
||||
MESSAGE(STATUS "Found Protobuf ${Protobuf_VERSION} at: ${Protobuf_LIBRARIES}")
|
||||
ENDIF()
|
||||
|
||||
#Find OpenSSL
|
||||
@@ -209,8 +207,8 @@ IF(MSVC)
|
||||
ENDIF()
|
||||
|
||||
# Package builder
|
||||
set(CPACK_PACKAGE_CONTACT "Zach Halpern <zahalpern+github@gmail.com>")
|
||||
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY ${PROJECT_NAME})
|
||||
set(CPACK_PACKAGE_CONTACT "Zach Halpern <zach@cockatrice.us>")
|
||||
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "${PROJECT_NAME}")
|
||||
set(CPACK_PACKAGE_VENDOR "Cockatrice Development Team")
|
||||
set(CPACK_PACKAGE_DESCRIPTION_FILE "${PROJECT_SOURCE_DIR}/README.md")
|
||||
set(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/LICENSE")
|
||||
@@ -231,15 +229,33 @@ if(UNIX)
|
||||
# linux
|
||||
IF(CPACK_GENERATOR STREQUAL "RPM")
|
||||
set(CPACK_RPM_PACKAGE_LICENSE "GPLv2")
|
||||
set(CPACK_RPM_PACKAGE_REQUIRES "protobuf, qt5-qttools, qt5-qtsvg, qt5-qtmultimedia")
|
||||
set(CPACK_RPM_MAIN_COMPONENT "cockatrice")
|
||||
IF(Qt6_FOUND)
|
||||
SET(CPACK_RPM_PACKAGE_REQUIRES "protobuf, qt6-qttools, qt6-qtsvg, qt6-qtmultimedia")
|
||||
ELSEIF(Qt5_FOUND)
|
||||
SET(CPACK_RPM_PACKAGE_REQUIRES "protobuf, qt5-qttools, qt5-qtsvg, qt5-qtmultimedia")
|
||||
ENDIF()
|
||||
set(CPACK_RPM_PACKAGE_GROUP "Amusements/Games")
|
||||
set(CPACK_RPM_PACKAGE_URL "http://github.com/Cockatrice/Cockatrice")
|
||||
# stop directories from making package conflicts
|
||||
set(CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION
|
||||
/usr/share/applications
|
||||
/usr/share/icons
|
||||
/usr/share/icons/hicolor
|
||||
/usr/share/icons/hicolor/48x48
|
||||
/usr/share/icons/hicolor/48x48/apps
|
||||
/usr/share/icons/hicolor/scalable
|
||||
/usr/share/icons/hicolor/scalable/apps)
|
||||
ELSE()
|
||||
set(CPACK_GENERATOR DEB)
|
||||
set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON)
|
||||
set(CPACK_DEBIAN_PACKAGE_SECTION "games")
|
||||
set(CPACK_DEBIAN_PACKAGE_HOMEPAGE "http://github.com/Cockatrice/Cockatrice")
|
||||
set(CPACK_DEBIAN_PACKAGE_DEPENDS "libqt5multimedia5-plugins, libqt5svg5")
|
||||
IF(Qt6_FOUND)
|
||||
set(CPACK_DEBIAN_PACKAGE_DEPENDS "libqt6multimedia6, libqt6svg6, qt6-qpa-plugins")
|
||||
ELSEIF(Qt5_FOUND)
|
||||
set(CPACK_DEBIAN_PACKAGE_DEPENDS "libqt5multimedia5-plugins, libqt5svg5")
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
endif()
|
||||
elseif(WIN32)
|
||||
@@ -252,8 +268,8 @@ elseif(WIN32)
|
||||
|
||||
# Configure file with custom definitions for NSIS.
|
||||
configure_file(
|
||||
${CMAKE_MODULE_PATH}/NSIS.definitions.nsh.in
|
||||
${PROJECT_BINARY_DIR}/NSIS.definitions.nsh
|
||||
"${COCKATRICE_CMAKE_PATH}/NSIS.definitions.nsh.in"
|
||||
"${PROJECT_BINARY_DIR}/NSIS.definitions.nsh"
|
||||
)
|
||||
|
||||
# include vcredist into the package; NSIS will take care of running it
|
||||
@@ -264,38 +280,33 @@ endif()
|
||||
|
||||
include(CPack)
|
||||
|
||||
# Compile servatrice (default off)
|
||||
option(WITH_SERVER "build servatrice" OFF)
|
||||
add_subdirectory(common)
|
||||
if(WITH_SERVER)
|
||||
add_subdirectory(servatrice)
|
||||
SET(CPACK_INSTALL_CMAKE_PROJECTS "Servatrice;Servatrice;ALL;/" ${CPACK_INSTALL_CMAKE_PROJECTS})
|
||||
endif()
|
||||
|
||||
# Compile cockatrice (default on)
|
||||
option(WITH_CLIENT "build cockatrice" ON)
|
||||
if(WITH_CLIENT)
|
||||
add_subdirectory(cockatrice)
|
||||
SET(CPACK_INSTALL_CMAKE_PROJECTS "Cockatrice;Cockatrice;ALL;/" ${CPACK_INSTALL_CMAKE_PROJECTS})
|
||||
endif()
|
||||
|
||||
# Compile oracle (default on)
|
||||
option(WITH_ORACLE "build oracle" ON)
|
||||
if(WITH_ORACLE)
|
||||
add_subdirectory(oracle)
|
||||
SET(CPACK_INSTALL_CMAKE_PROJECTS "Oracle;Oracle;ALL;/" ${CPACK_INSTALL_CMAKE_PROJECTS})
|
||||
endif()
|
||||
|
||||
# Compile dbconverter (default on)
|
||||
option(WITH_DBCONVERTER "build dbconverter" ON)
|
||||
if(WITH_DBCONVERTER)
|
||||
add_subdirectory(dbconverter)
|
||||
SET(CPACK_INSTALL_CMAKE_PROJECTS "Dbconverter;Dbconverter;ALL;/" ${CPACK_INSTALL_CMAKE_PROJECTS})
|
||||
endif()
|
||||
|
||||
# Compile tests (default off)
|
||||
option(TEST "build tests" OFF)
|
||||
if(TEST)
|
||||
include(CTest)
|
||||
add_subdirectory(tests)
|
||||
endif()
|
||||
|
||||
if(Qt6Found AND Qt6_VERSION_MINOR GREATER_EQUAL 3)
|
||||
# Qt6.3+ requires project finalization to support translations
|
||||
qt6_finalize_project()
|
||||
endif()
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
<a href="#get-involved--">Get Involved</a> <b>|</b>
|
||||
<a href="#community-resources">Community</a> <b>|</b>
|
||||
<a href="#translations-">Translations</a> <b>|</b>
|
||||
<a href="#build-">Build</a> <b>|</b>
|
||||
<a href="#build--">Build</a> <b>|</b>
|
||||
<a href="#run">Run</a> <b>|</b>
|
||||
<a href="#license-">License</a>
|
||||
</p>
|
||||
@@ -78,7 +78,7 @@ Cockatrice uses Transifex for translations. You can help us bring Cockatrice and
|
||||
Check out our [Translator FAQ](https://github.com/Cockatrice/Cockatrice/wiki/Translation-FAQ) for more information about contributing!<br>
|
||||
|
||||
|
||||
# Build [](https://github.com/Cockatrice/Cockatrice/actions/workflows/ci-builds.yml?query=branch%3Amaster+event%3Apush)
|
||||
# Build [](https://github.com/Cockatrice/Cockatrice/actions/workflows/desktop-build.yml?query=branch%3Amaster+event%3Apush) [](https://github.com/Cockatrice/Cockatrice/actions/workflows/web-build.yml?query=branch%3Amaster+event%3Apush)
|
||||
|
||||
**Detailed compiling instructions can be found on the Cockatrice wiki under [Compiling Cockatrice](https://github.com/Cockatrice/Cockatrice/wiki/Compiling-Cockatrice)**
|
||||
|
||||
@@ -117,6 +117,7 @@ The following flags can be passed to `cmake`:
|
||||
- `-DWARNING_AS_ERROR=0` Whether to treat compilation warnings as errors in debug mode (default 1 = yes).
|
||||
- `-DUPDATE_TRANSLATIONS=1` Configure `make` to update the translation .ts files for new strings in the source code. Note: Running `make clean` will remove the .ts files (default 0 = no).
|
||||
- `-DTEST=1` Enable regression tests (default 0 = no). Note: needs googletest, will be downloaded on the fly if unavailable. To run tests: ```make test```.
|
||||
- `-DFORCE_USE_QT5=1` Skip looking for Qt6 before trying to find Qt5
|
||||
|
||||
|
||||
# Run
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
# This script will run clang-format on all modified, non-3rd-party C++/Header files.
|
||||
# Never, ever, should this recieve a path with a newline in it. Don't bother proofing it for that.
|
||||
# Never, ever, should this receive a path with a newline in it. Don't bother proofing it for that.
|
||||
|
||||
|
||||
# go to the project root directory, this file should be located in the project root directory
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
# Find the LibExecinfo library - FreeBSD only
|
||||
|
||||
FIND_PATH(LIBEXECINFO_INCLUDE_DIR execinfo.h)
|
||||
FIND_LIBRARY(LIBEXECINFO_LIBRARY NAMES execinfo)
|
||||
find_path(LIBEXECINFO_INCLUDE_DIR execinfo.h)
|
||||
find_library(LIBEXECINFO_LIBRARY NAMES execinfo)
|
||||
|
||||
IF(LIBEXECINFO_INCLUDE_DIR AND LIBEXECINFO_LIBRARY)
|
||||
SET(LIBEXECINFO_FOUND TRUE)
|
||||
ENDIF()
|
||||
if(LIBEXECINFO_INCLUDE_DIR AND LIBEXECINFO_LIBRARY)
|
||||
set(LIBEXECINFO_FOUND TRUE)
|
||||
endif()
|
||||
|
||||
IF(LIBEXECINFO_FOUND)
|
||||
IF(NOT LIBEXECINFO_FIND_QUIETLY)
|
||||
MESSAGE(STATUS "Found LibExecinfo: ${EXECINFO_LIBRARY}")
|
||||
ENDIF()
|
||||
ELSE()
|
||||
IF(LIBEXECINFO_FIND_REQUIRED)
|
||||
MESSAGE(FATAL_ERROR "Could not find LibExecinfo")
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
if(LIBEXECINFO_FOUND)
|
||||
if(NOT LIBEXECINFO_FIND_QUIETLY)
|
||||
message(STATUS "Found LibExecinfo: ${EXECINFO_LIBRARY}")
|
||||
endif()
|
||||
else()
|
||||
if(LIBEXECINFO_FIND_REQUIRED)
|
||||
message(FATAL_ERROR "Could not find LibExecinfo")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
119
cmake/FindQtRuntime.cmake
Normal file
119
cmake/FindQtRuntime.cmake
Normal file
@@ -0,0 +1,119 @@
|
||||
# Find a compatible Qt version Inputs: WITH_SERVER, WITH_CLIENT, WITH_ORACLE, WITH_DBCONVERTER, FORCE_USE_QT5 Optional
|
||||
# Input: QT6_DIR -- Hint as to where Qt6 lives on the system Optional Input: QT5_DIR -- Hint as to where Qt5 lives on
|
||||
# the system Output: COCKATRICE_QT_VERSION_NAME -- Example values: Qt5, Qt6 Outputs: SERVATRICE_QT_MODULES,
|
||||
# COCKATRICE_QT_MODULES, ORACLE_QT_MODULES, DBCONVERTER_QT_MODULES, TEST_QT_MODULES
|
||||
|
||||
set(REQUIRED_QT_COMPONENTS Core)
|
||||
if(WITH_SERVER)
|
||||
set(_SERVATRICE_NEEDED Network Sql WebSockets)
|
||||
endif()
|
||||
if(WITH_CLIENT)
|
||||
set(_COCKATRICE_NEEDED
|
||||
Concurrent
|
||||
Gui
|
||||
Multimedia
|
||||
Network
|
||||
PrintSupport
|
||||
Svg
|
||||
Widgets
|
||||
WebSockets
|
||||
)
|
||||
endif()
|
||||
if(WITH_ORACLE)
|
||||
set(_ORACLE_NEEDED Concurrent Network Svg Widgets)
|
||||
endif()
|
||||
if(WITH_DBCONVERTER)
|
||||
set(_DBCONVERTER_NEEDED Network Widgets)
|
||||
endif()
|
||||
if(TEST)
|
||||
set(_TEST_NEEDED Widgets)
|
||||
endif()
|
||||
|
||||
set(REQUIRED_QT_COMPONENTS ${REQUIRED_QT_COMPONENTS} ${_SERVATRICE_NEEDED} ${_COCKATRICE_NEEDED} ${_ORACLE_NEEDED}
|
||||
${_DBCONVERTER_NEEDED} ${_TEST_NEEDED}
|
||||
)
|
||||
list(REMOVE_DUPLICATES REQUIRED_QT_COMPONENTS)
|
||||
|
||||
if(NOT FORCE_USE_QT5)
|
||||
# Core5Compat is Qt6 Only, Linguist is now a component in Qt6 instead of an external package
|
||||
find_package(
|
||||
Qt6 6.2.3
|
||||
COMPONENTS Core5Compat ${REQUIRED_QT_COMPONENTS}
|
||||
OPTIONAL_COMPONENTS Linguist
|
||||
QUIET HINTS ${Qt6_DIR}
|
||||
)
|
||||
endif()
|
||||
if(Qt6_FOUND)
|
||||
set(COCKATRICE_QT_VERSION_NAME Qt6)
|
||||
|
||||
if(Qt6LinguistTools_FOUND)
|
||||
list(FIND Qt6LinguistTools_TARGETS Qt6::lrelease QT6_LRELEASE_INDEX)
|
||||
if(QT6_LRELEASE_INDEX EQUAL -1)
|
||||
message(WARNING "Qt6 lrelease not found.")
|
||||
endif()
|
||||
|
||||
list(FIND Qt6LinguistTools_TARGETS Qt6::lupdate QT6_LUPDATE_INDEX)
|
||||
if(QT6_LUPDATE_INDEX EQUAL -1)
|
||||
message(WARNING "Qt6 lupdate not found.")
|
||||
endif()
|
||||
endif()
|
||||
else()
|
||||
find_package(
|
||||
Qt5 5.8.0
|
||||
COMPONENTS ${REQUIRED_QT_COMPONENTS}
|
||||
QUIET HINTS ${Qt5_DIR}
|
||||
)
|
||||
if(Qt5_FOUND)
|
||||
set(COCKATRICE_QT_VERSION_NAME Qt5)
|
||||
else()
|
||||
message(FATAL_ERROR "No suitable version of Qt was found")
|
||||
endif()
|
||||
|
||||
# Qt5 Linguist is in a separate package
|
||||
find_package(Qt5LinguistTools QUIET)
|
||||
if(Qt5LinguistTools_FOUND)
|
||||
if(NOT Qt5_LRELEASE_EXECUTABLE)
|
||||
message(WARNING "Qt5 lrelease not found.")
|
||||
endif()
|
||||
if(NOT Qt5_LUPDATE_EXECUTABLE)
|
||||
message(WARNING "Qt5 lupdate not found.")
|
||||
endif()
|
||||
else()
|
||||
message(WARNING "Linguist Tools not found, cannot handle translations")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(Qt5_POSITION_INDEPENDENT_CODE OR Qt6_FOUND)
|
||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||
endif()
|
||||
|
||||
# Establish Qt Plugins directory & Library directories
|
||||
get_target_property(QT_LIBRARY_DIR ${COCKATRICE_QT_VERSION_NAME}::Core LOCATION)
|
||||
get_filename_component(QT_LIBRARY_DIR ${QT_LIBRARY_DIR} DIRECTORY)
|
||||
if(Qt6_FOUND)
|
||||
get_filename_component(QT_PLUGINS_DIR "${Qt6Core_DIR}/../../../${QT6_INSTALL_PLUGINS}" ABSOLUTE)
|
||||
get_filename_component(QT_LIBRARY_DIR "${QT_LIBRARY_DIR}/../../.." ABSOLUTE)
|
||||
if(UNIX AND APPLE)
|
||||
# Mac needs a bit more help finding all necessary components
|
||||
list(APPEND QT_LIBRARY_DIR "/usr/local/lib")
|
||||
endif()
|
||||
elseif(Qt5_FOUND)
|
||||
get_filename_component(QT_PLUGINS_DIR "${Qt5Core_DIR}/../../../plugins" ABSOLUTE)
|
||||
get_filename_component(QT_LIBRARY_DIR "${QT_LIBRARY_DIR}/.." ABSOLUTE)
|
||||
endif()
|
||||
message(DEBUG "QT_PLUGINS_DIR = ${QT_PLUGINS_DIR}")
|
||||
message(DEBUG "QT_LIBRARY_DIR = ${QT_LIBRARY_DIR}")
|
||||
|
||||
# Establish exports
|
||||
string(REGEX REPLACE "([^;]+)" "${COCKATRICE_QT_VERSION_NAME}::\\1" SERVATRICE_QT_MODULES "${_SERVATRICE_NEEDED}")
|
||||
string(REGEX REPLACE "([^;]+)" "${COCKATRICE_QT_VERSION_NAME}::\\1" COCKATRICE_QT_MODULES "${_COCKATRICE_NEEDED}")
|
||||
string(REGEX REPLACE "([^;]+)" "${COCKATRICE_QT_VERSION_NAME}::\\1" ORACLE_QT_MODULES "${_ORACLE_NEEDED}")
|
||||
string(REGEX REPLACE "([^;]+)" "${COCKATRICE_QT_VERSION_NAME}::\\1" DB_CONVERTER_QT_MODULES "${_DBCONVERTER_NEEDED}")
|
||||
string(REGEX REPLACE "([^;]+)" "${COCKATRICE_QT_VERSION_NAME}::\\1" TEST_QT_MODULES "${_TEST_NEEDED}")
|
||||
if(Qt6_FOUND)
|
||||
list(APPEND SERVATRICE_QT_MODULES ${COCKATRICE_QT_VERSION_NAME}::Core5Compat)
|
||||
list(APPEND COCKATRICE_QT_MODULES ${COCKATRICE_QT_VERSION_NAME}::Core5Compat)
|
||||
list(APPEND ORACLE_QT_MODULES ${COCKATRICE_QT_VERSION_NAME}::Core5Compat)
|
||||
endif()
|
||||
|
||||
message(STATUS "Found Qt ${${COCKATRICE_QT_VERSION_NAME}_VERSION} at: ${${COCKATRICE_QT_VERSION_NAME}_DIR}")
|
||||
@@ -1,36 +1,38 @@
|
||||
# Find the MS Visual Studio VC redistributable package
|
||||
|
||||
if (WIN32)
|
||||
set(VCREDISTRUNTIME_FOUND "NO")
|
||||
if(WIN32)
|
||||
set(VCREDISTRUNTIME_FOUND "NO")
|
||||
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 8) # 64-bit
|
||||
set(REDIST_ARCH x64)
|
||||
else()
|
||||
set(REDIST_ARCH x86)
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 8) # 64-bit
|
||||
set(REDIST_ARCH x64)
|
||||
else()
|
||||
set(REDIST_ARCH x86)
|
||||
endif()
|
||||
|
||||
set(REDIST_FILE vcredist_${REDIST_ARCH}.exe)
|
||||
|
||||
set(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_SKIP TRUE)
|
||||
include(InstallRequiredSystemLibraries)
|
||||
|
||||
# Check if the list contains minimum one element, to get the path from
|
||||
list(LENGTH CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS libsCount)
|
||||
if(libsCount GREATER 0)
|
||||
list(GET CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS 0 _path)
|
||||
|
||||
get_filename_component(_path ${_path} DIRECTORY)
|
||||
get_filename_component(_path ${_path}/../../ ABSOLUTE)
|
||||
|
||||
if(EXISTS "${_path}/${REDIST_FILE}") # VS 2017
|
||||
set(VCREDISTRUNTIME_FOUND "YES")
|
||||
set(VCREDISTRUNTIME_FILE ${_path}/${REDIST_FILE})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(REDIST_FILE vcredist_${REDIST_ARCH}.exe)
|
||||
|
||||
set(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_SKIP TRUE)
|
||||
include(InstallRequiredSystemLibraries)
|
||||
|
||||
# Check if the list contains minimum one element, to get the path from
|
||||
list(LENGTH CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS libsCount)
|
||||
if (libsCount GREATER 0)
|
||||
list(GET CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS 0 _path)
|
||||
|
||||
get_filename_component(_path ${_path} DIRECTORY)
|
||||
get_filename_component(_path ${_path}/../../ ABSOLUTE)
|
||||
|
||||
if (EXISTS "${_path}/${REDIST_FILE}") # VS 2017
|
||||
set(VCREDISTRUNTIME_FOUND "YES")
|
||||
set(VCREDISTRUNTIME_FILE ${_path}/${REDIST_FILE})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(VCREDISTRUNTIME_FOUND)
|
||||
message(STATUS "Found VCredist ${VCREDISTRUNTIME_FILE}")
|
||||
else()
|
||||
message(WARNING "Could not find VCredist package. It's not required for compiling, but needs to be available at runtime.")
|
||||
endif()
|
||||
if(VCREDISTRUNTIME_FOUND)
|
||||
message(STATUS "Found VCredist ${VCREDISTRUNTIME_FILE}")
|
||||
else()
|
||||
message(
|
||||
WARNING "Could not find VCredist package. It's not required for compiling, but needs to be available at runtime."
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@@ -1,77 +1,70 @@
|
||||
# Find the OpenSSL runtime libraries (.dll) for Windows that
|
||||
# will be needed by Qt in order to access https urls.
|
||||
# Find the OpenSSL runtime libraries (.dll) for Windows that will be needed by Qt in order to access https urls.
|
||||
if(NOT DEFINED WIN32 OR NOT ${WIN32})
|
||||
message(STATUS "Non-Windows device trying to execute FindWin32SslRuntime, skipping")
|
||||
return()
|
||||
endif()
|
||||
|
||||
if (WIN32)
|
||||
# Get standard installation paths for OpenSSL under Windows
|
||||
|
||||
# http://www.slproweb.com/products/Win32OpenSSL.html
|
||||
|
||||
if( CMAKE_SIZEOF_VOID_P EQUAL 8 )
|
||||
# target win64
|
||||
set(_OPENSSL_ROOT_HINTS
|
||||
${OPENSSL_ROOT_DIR}
|
||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\OpenSSL (64-bit)_is1;Inno Setup: App Path]"
|
||||
ENV OPENSSL_ROOT_DIR
|
||||
)
|
||||
file(TO_CMAKE_PATH "$ENV{PROGRAMFILES}" _programfiles)
|
||||
set(_OPENSSL_ROOT_PATHS
|
||||
"C:/Tools/vcpkg/installed/x64-windows/bin"
|
||||
"${_programfiles}/OpenSSL-Win64"
|
||||
"C:/OpenSSL-Win64/"
|
||||
)
|
||||
unset(_programfiles)
|
||||
else( CMAKE_SIZEOF_VOID_P EQUAL 8 )
|
||||
# target win32
|
||||
set(_OPENSSL_ROOT_HINTS
|
||||
${OPENSSL_ROOT_DIR}
|
||||
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\OpenSSL (32-bit)_is1;Inno Setup: App Path]"
|
||||
ENV OPENSSL_ROOT_DIR
|
||||
)
|
||||
file(TO_CMAKE_PATH "$ENV{PROGRAMFILES}" _programfiles)
|
||||
set(_OPENSSL_ROOT_PATHS
|
||||
if("${CMAKE_GENERATOR_PLATFORM}" STREQUAL "x64")
|
||||
message(STATUS "Looking for OpenSSL for ${CMAKE_GENERATOR_PLATFORM}")
|
||||
file(TO_CMAKE_PATH "$ENV{PROGRAMFILES}" _programfiles)
|
||||
set(_OPENSSL_ROOT_PATHS "$ENV{VCPKG_PACKAGES_DIR}/x64-windows/bin" "C:/OpenSSL-Win64/bin" "C:/OpenSSL-Win64"
|
||||
"C:/Tools/vcpkg/installed/x64-windows/bin" "${_programfiles}/OpenSSL-Win64"
|
||||
)
|
||||
unset(_programfiles)
|
||||
elseif("${CMAKE_GENERATOR_PLATFORM}" STREQUAL "Win32")
|
||||
message(STATUS "Looking for OpenSSL for ${CMAKE_GENERATOR_PLATFORM}")
|
||||
file(TO_CMAKE_PATH "$ENV{PROGRAMFILES}" _programfiles)
|
||||
set(_OPENSSL_ROOT_PATHS
|
||||
"$ENV{VCPKG_PACKAGES_DIR}/x86-windows/bin"
|
||||
"C:/OpenSSL-Win32/bin"
|
||||
"C:/OpenSSL-Win32"
|
||||
"C:/OpenSSL"
|
||||
"C:/Tools/vcpkg/installed/x86-windows/bin"
|
||||
"${_programfiles}/OpenSSL"
|
||||
"${_programfiles}/OpenSSL-Win32"
|
||||
"C:/OpenSSL/"
|
||||
"C:/OpenSSL-Win32/"
|
||||
)
|
||||
unset(_programfiles)
|
||||
endif( CMAKE_SIZEOF_VOID_P EQUAL 8 )
|
||||
|
||||
else ()
|
||||
set(_OPENSSL_ROOT_HINTS
|
||||
${OPENSSL_ROOT_DIR}
|
||||
ENV OPENSSL_ROOT_DIR
|
||||
)
|
||||
endif ()
|
||||
|
||||
set(_OPENSSL_ROOT_HINTS_AND_PATHS
|
||||
HINTS ${_OPENSSL_ROOT_HINTS}
|
||||
PATHS ${_OPENSSL_ROOT_PATHS}
|
||||
)
|
||||
|
||||
# For OpenSSL < 1.1, they are named libeay32 and ssleay32 and even if the dll is 64bit, it's still suffixed as *32.dll
|
||||
# For OpenSSL >= 1.1, they are named libcrypto and libssl with no suffix
|
||||
if( CMAKE_SIZEOF_VOID_P EQUAL 8 )
|
||||
# target win64
|
||||
FIND_FILE(WIN32SSLRUNTIME_LIBEAY NAMES libcrypto-1_1-x64.dll libcrypto.dll libeay32.dll ${_OPENSSL_ROOT_HINTS_AND_PATHS})
|
||||
FIND_FILE(WIN32SSLRUNTIME_SSLEAY NAMES libssl-1_1-x64.dll libssl.dll ssleay32.dll ${_OPENSSL_ROOT_HINTS_AND_PATHS})
|
||||
else( CMAKE_SIZEOF_VOID_P EQUAL 8 )
|
||||
# target win32
|
||||
FIND_FILE(WIN32SSLRUNTIME_LIBEAY NAMES libcrypto-1_1.dll libcrypto.dll libeay32.dll ${_OPENSSL_ROOT_HINTS_AND_PATHS})
|
||||
FIND_FILE(WIN32SSLRUNTIME_SSLEAY NAMES libssl-1_1.dll libssl.dll ssleay32.dll ${_OPENSSL_ROOT_HINTS_AND_PATHS})
|
||||
endif( CMAKE_SIZEOF_VOID_P EQUAL 8 )
|
||||
|
||||
IF(WIN32SSLRUNTIME_LIBEAY AND WIN32SSLRUNTIME_SSLEAY)
|
||||
SET(WIN32SSLRUNTIME_LIBRARIES "${WIN32SSLRUNTIME_LIBEAY}" "${WIN32SSLRUNTIME_SSLEAY}")
|
||||
SET(WIN32SSLRUNTIME_FOUND "YES")
|
||||
message(STATUS "Found OpenSSL ${WIN32SSLRUNTIME_LIBRARIES}")
|
||||
ELSE()
|
||||
SET(WIN32SSLRUNTIME_FOUND "NO")
|
||||
message(WARNING "Could not find OpenSSL runtime libraries. They are not required for compiling, but needs to be available at runtime.")
|
||||
ENDIF()
|
||||
|
||||
MARK_AS_ADVANCED(
|
||||
WIN32SSLRUNTIME_LIBEAY
|
||||
WIN32SSLRUNTIME_SSLEAY
|
||||
)
|
||||
unset(_programfiles)
|
||||
endif()
|
||||
|
||||
message(STATUS "Looking for OpenSSL @ $ENV{CMAKE_GENERATOR_PLATFORM} in ${_OPENSSL_ROOT_PATHS}")
|
||||
if("$ENV{CMAKE_GENERATOR_PLATFORM}" STREQUAL "x64")
|
||||
find_file(
|
||||
WIN32SSLRUNTIME_LIBEAY
|
||||
NAMES libcrypto-1_1-x64.dll libcrypto.dll
|
||||
PATHS ${_OPENSSL_ROOT_PATHS}
|
||||
NO_DEFAULT_PATH
|
||||
)
|
||||
find_file(
|
||||
WIN32SSLRUNTIME_SSLEAY
|
||||
NAMES libssl-1_1-x64.dll libssl.dll
|
||||
PATHS ${_OPENSSL_ROOT_PATHS}
|
||||
NO_DEFAULT_PATH
|
||||
)
|
||||
elseif("$ENV{CMAKE_GENERATOR_PLATFORM}" STREQUAL "Win32")
|
||||
find_file(
|
||||
WIN32SSLRUNTIME_LIBEAY
|
||||
NAMES libcrypto-1_1.dll libcrypto.dll
|
||||
PATHS ${_OPENSSL_ROOT_PATHS}
|
||||
NO_DEFAULT_PATH
|
||||
)
|
||||
find_file(
|
||||
WIN32SSLRUNTIME_SSLEAY
|
||||
NAMES libssl-1_1.dll libssl.dll
|
||||
PATHS ${_OPENSSL_ROOT_PATHS}
|
||||
NO_DEFAULT_PATH
|
||||
)
|
||||
endif()
|
||||
|
||||
if(WIN32SSLRUNTIME_LIBEAY AND WIN32SSLRUNTIME_SSLEAY)
|
||||
set(WIN32SSLRUNTIME_LIBRARIES "${WIN32SSLRUNTIME_LIBEAY}" "${WIN32SSLRUNTIME_SSLEAY}")
|
||||
set(WIN32SSLRUNTIME_FOUND "YES")
|
||||
message(STATUS "Found OpenSSL ${WIN32SSLRUNTIME_LIBRARIES}")
|
||||
else()
|
||||
set(WIN32SSLRUNTIME_FOUND "NO")
|
||||
message(
|
||||
WARNING
|
||||
"Could not find OpenSSL runtime libraries. They are not required for compiling, but needs to be available at runtime."
|
||||
)
|
||||
endif()
|
||||
|
||||
mark_as_advanced(WIN32SSLRUNTIME_LIBEAY WIN32SSLRUNTIME_SSLEAY)
|
||||
|
||||
@@ -1,21 +1,24 @@
|
||||
set(VERSION_STRING_CPP "${PROJECT_BINARY_DIR}/version_string.cpp")
|
||||
set(VERSION_STRING_H "${PROJECT_BINARY_DIR}/version_string.h")
|
||||
INCLUDE_DIRECTORIES(${PROJECT_BINARY_DIR})
|
||||
include_directories(${PROJECT_BINARY_DIR})
|
||||
|
||||
set( hstring "extern const char *VERSION_STRING\;
|
||||
set(hstring
|
||||
"extern const char *VERSION_STRING\;
|
||||
extern const char *VERSION_COMMIT\;
|
||||
extern const char *VERSION_DATE\;\n" )
|
||||
set( cppstring "const char *VERSION_STRING = \"${PROJECT_VERSION_FRIENDLY}\"\;
|
||||
extern const char *VERSION_DATE\;\n"
|
||||
)
|
||||
set(cppstring
|
||||
"const char *VERSION_STRING = \"${PROJECT_VERSION_FRIENDLY}\"\;
|
||||
const char *VERSION_COMMIT = \"${GIT_COMMIT_ID}\"\;
|
||||
const char *VERSION_DATE = \"${GIT_COMMIT_DATE_FRIENDLY}\"\;\n")
|
||||
|
||||
file(WRITE ${PROJECT_BINARY_DIR}/version_string.cpp.txt ${cppstring} )
|
||||
file(WRITE ${PROJECT_BINARY_DIR}/version_string.h.txt ${hstring} )
|
||||
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${PROJECT_BINARY_DIR}/version_string.h.txt ${VERSION_STRING_H}
|
||||
)
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${PROJECT_BINARY_DIR}/version_string.cpp.txt ${VERSION_STRING_CPP}
|
||||
const char *VERSION_DATE = \"${GIT_COMMIT_DATE_FRIENDLY}\"\;\n"
|
||||
)
|
||||
|
||||
file(WRITE ${PROJECT_BINARY_DIR}/version_string.cpp.txt ${cppstring})
|
||||
file(WRITE ${PROJECT_BINARY_DIR}/version_string.h.txt ${hstring})
|
||||
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${PROJECT_BINARY_DIR}/version_string.h.txt ${VERSION_STRING_H}
|
||||
)
|
||||
execute_process(
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${PROJECT_BINARY_DIR}/version_string.cpp.txt ${VERSION_STRING_CPP}
|
||||
)
|
||||
|
||||
@@ -1,154 +1,183 @@
|
||||
# HELPER FUNCTIONS
|
||||
|
||||
function(get_commit_id)
|
||||
# get last commit hash
|
||||
execute_process(
|
||||
COMMAND ${GIT_EXECUTABLE} log -1 --abbrev=7 --date=short "--pretty=%h"
|
||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
|
||||
RESULT_VARIABLE res_var
|
||||
OUTPUT_VARIABLE GIT_COM_ID
|
||||
)
|
||||
if(NOT ${res_var} EQUAL 0)
|
||||
message(WARNING "Git failed (not a repo, or no tags). Build will not contain git revision info.")
|
||||
return()
|
||||
endif()
|
||||
# get last commit hash
|
||||
execute_process(
|
||||
COMMAND ${GIT_EXECUTABLE} log -1 --abbrev=7 --date=short "--pretty=%h"
|
||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
|
||||
RESULT_VARIABLE res_var
|
||||
OUTPUT_VARIABLE GIT_COM_ID
|
||||
)
|
||||
if(NOT ${res_var} EQUAL 0)
|
||||
message(WARNING "Git failed (not a repo, or no tags). Build will not contain git revision info.")
|
||||
return()
|
||||
endif()
|
||||
|
||||
string(REPLACE "\n" "" GIT_COM_ID "${GIT_COM_ID}")
|
||||
set(GIT_COMMIT_ID "${GIT_COM_ID}" PARENT_SCOPE)
|
||||
set(PROJECT_VERSION_LABEL "custom(${GIT_COM_ID})" PARENT_SCOPE)
|
||||
string(REPLACE "\n" "" GIT_COM_ID "${GIT_COM_ID}")
|
||||
set(GIT_COMMIT_ID
|
||||
"${GIT_COM_ID}"
|
||||
PARENT_SCOPE
|
||||
)
|
||||
set(PROJECT_VERSION_LABEL
|
||||
"custom(${GIT_COM_ID})"
|
||||
PARENT_SCOPE
|
||||
)
|
||||
endfunction()
|
||||
|
||||
function(get_commit_date)
|
||||
# get last commit date
|
||||
execute_process(
|
||||
COMMAND ${GIT_EXECUTABLE} log -1 --date=short "--pretty=%cd"
|
||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
|
||||
RESULT_VARIABLE res_var
|
||||
OUTPUT_VARIABLE GIT_COM_DATE
|
||||
)
|
||||
if(NOT ${res_var} EQUAL 0)
|
||||
message(WARNING "Git failed (not a repo, or no tags). Build will not contain git revision info.")
|
||||
return()
|
||||
endif()
|
||||
# get last commit date
|
||||
execute_process(
|
||||
COMMAND ${GIT_EXECUTABLE} log -1 --date=short "--pretty=%cd"
|
||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
|
||||
RESULT_VARIABLE res_var
|
||||
OUTPUT_VARIABLE GIT_COM_DATE
|
||||
)
|
||||
if(NOT ${res_var} EQUAL 0)
|
||||
message(WARNING "Git failed (not a repo, or no tags). Build will not contain git revision info.")
|
||||
return()
|
||||
endif()
|
||||
|
||||
string(REPLACE "\n" "" GIT_COM_DATE "${GIT_COM_DATE}")
|
||||
set(GIT_COMMIT_DATE_FRIENDLY "${GIT_COM_DATE}" PARENT_SCOPE)
|
||||
string(REPLACE "\n" "" GIT_COM_DATE "${GIT_COM_DATE}")
|
||||
set(GIT_COMMIT_DATE_FRIENDLY
|
||||
"${GIT_COM_DATE}"
|
||||
PARENT_SCOPE
|
||||
)
|
||||
|
||||
string(REPLACE "-" "" GIT_COM_DATE "${GIT_COM_DATE}")
|
||||
set(GIT_COMMIT_DATE "${GIT_COM_DATE}" PARENT_SCOPE)
|
||||
string(REPLACE "-" "" GIT_COM_DATE "${GIT_COM_DATE}")
|
||||
set(GIT_COMMIT_DATE
|
||||
"${GIT_COM_DATE}"
|
||||
PARENT_SCOPE
|
||||
)
|
||||
endfunction()
|
||||
|
||||
function(get_tag_name commit)
|
||||
if(${commit} STREQUAL "unknown")
|
||||
return()
|
||||
endif()
|
||||
if(${commit} STREQUAL "unknown")
|
||||
return()
|
||||
endif()
|
||||
|
||||
execute_process(
|
||||
COMMAND ${GIT_EXECUTABLE} describe --exact-match --tags ${commit}
|
||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
|
||||
RESULT_VARIABLE res_var
|
||||
OUTPUT_VARIABLE GIT_TAG
|
||||
ERROR_VARIABLE GIT_TAG_ERR
|
||||
)
|
||||
execute_process(
|
||||
COMMAND ${GIT_EXECUTABLE} describe --exact-match --tags ${commit}
|
||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
|
||||
RESULT_VARIABLE res_var
|
||||
OUTPUT_VARIABLE GIT_TAG
|
||||
ERROR_VARIABLE GIT_TAG_ERR
|
||||
)
|
||||
|
||||
if((NOT ${res_var} EQUAL 0) OR (${GIT_TAG_ERR} MATCHES "fatal: no tag exactly matches.*"))
|
||||
message(STATUS "Commit is not a release or prerelease (no git tag found)")
|
||||
return()
|
||||
endif()
|
||||
if((NOT ${res_var} EQUAL 0) OR (${GIT_TAG_ERR} MATCHES "fatal: no tag exactly matches.*"))
|
||||
message(STATUS "Commit is not a release or prerelease (no git tag found)")
|
||||
return()
|
||||
endif()
|
||||
|
||||
string(REPLACE "\n" "" GIT_TAG "${GIT_TAG}")
|
||||
message(STATUS "Commit is a release or prerelease, git tag: ${GIT_TAG}")
|
||||
string(REPLACE "\n" "" GIT_TAG "${GIT_TAG}")
|
||||
message(STATUS "Commit is a release or prerelease, git tag: ${GIT_TAG}")
|
||||
|
||||
# Extract information from tag:
|
||||
# YYYY-MM-DD-Release-MAJ.MIN.PATCH
|
||||
# YYYY-MM-DD-Development-MAJ.MIN.PATCH-beta.X
|
||||
string(REPLACE "-" ";" GIT_TAG_EXPLODED "${GIT_TAG}")
|
||||
string(REPLACE "." ";" GIT_TAG_EXPLODED "${GIT_TAG_EXPLODED}")
|
||||
# Extract information from tag: YYYY-MM-DD-Release-MAJ.MIN.PATCH YYYY-MM-DD-Development-MAJ.MIN.PATCH-beta.X
|
||||
string(REPLACE "-" ";" GIT_TAG_EXPLODED "${GIT_TAG}")
|
||||
string(REPLACE "." ";" GIT_TAG_EXPLODED "${GIT_TAG_EXPLODED}")
|
||||
|
||||
# Sanity checks: length
|
||||
list(LENGTH GIT_TAG_EXPLODED GIT_TAG_LISTCOUNT)
|
||||
if(${GIT_TAG_LISTCOUNT} LESS 7 OR ${GIT_TAG_LISTCOUNT} GREATER 9)
|
||||
message(WARNING "Invalid tag format, got ${GIT_TAG_LISTCOUNT} tokens")
|
||||
return()
|
||||
endif()
|
||||
# Sanity checks: length
|
||||
list(LENGTH GIT_TAG_EXPLODED GIT_TAG_LISTCOUNT)
|
||||
if(${GIT_TAG_LISTCOUNT} LESS 7 OR ${GIT_TAG_LISTCOUNT} GREATER 9)
|
||||
message(WARNING "Invalid tag format, got ${GIT_TAG_LISTCOUNT} tokens")
|
||||
return()
|
||||
endif()
|
||||
|
||||
# Year
|
||||
list(GET GIT_TAG_EXPLODED 0 GIT_TAG_YEAR)
|
||||
if(${GIT_TAG_YEAR} LESS 2017 OR ${GIT_TAG_LISTCOUNT} GREATER 2100)
|
||||
message(WARNING "Invalid tag year ${GIT_TAG_YEAR}")
|
||||
return()
|
||||
endif()
|
||||
# Year
|
||||
list(GET GIT_TAG_EXPLODED 0 GIT_TAG_YEAR)
|
||||
if(${GIT_TAG_YEAR} LESS 2017 OR ${GIT_TAG_LISTCOUNT} GREATER 2100)
|
||||
message(WARNING "Invalid tag year ${GIT_TAG_YEAR}")
|
||||
return()
|
||||
endif()
|
||||
|
||||
# Month
|
||||
list(GET GIT_TAG_EXPLODED 1 GIT_TAG_MONTH)
|
||||
if(${GIT_TAG_MONTH} LESS 1 OR ${GIT_TAG_MONTH} GREATER 12)
|
||||
message(WARNING "Invalid tag month ${GIT_TAG_MONTH}")
|
||||
return()
|
||||
endif()
|
||||
# Month
|
||||
list(GET GIT_TAG_EXPLODED 1 GIT_TAG_MONTH)
|
||||
if(${GIT_TAG_MONTH} LESS 1 OR ${GIT_TAG_MONTH} GREATER 12)
|
||||
message(WARNING "Invalid tag month ${GIT_TAG_MONTH}")
|
||||
return()
|
||||
endif()
|
||||
|
||||
# Day
|
||||
list(GET GIT_TAG_EXPLODED 2 GIT_TAG_DAY)
|
||||
if(${GIT_TAG_DAY} LESS 1 OR ${GIT_TAG_DAY} GREATER 31)
|
||||
message(WARNING "Invalid tag day ${GIT_TAG_DAY}")
|
||||
return()
|
||||
endif()
|
||||
# Day
|
||||
list(GET GIT_TAG_EXPLODED 2 GIT_TAG_DAY)
|
||||
if(${GIT_TAG_DAY} LESS 1 OR ${GIT_TAG_DAY} GREATER 31)
|
||||
message(WARNING "Invalid tag day ${GIT_TAG_DAY}")
|
||||
return()
|
||||
endif()
|
||||
|
||||
# Type
|
||||
list(GET GIT_TAG_EXPLODED 3 GIT_TAG_TYPE)
|
||||
if(NOT(${GIT_TAG_TYPE} STREQUAL "Release" OR ${GIT_TAG_TYPE} STREQUAL "Development"))
|
||||
message(WARNING "Invalid tag type ${GIT_TAG_TYPE}")
|
||||
return()
|
||||
endif()
|
||||
# Type
|
||||
list(GET GIT_TAG_EXPLODED 3 GIT_TAG_TYPE)
|
||||
if(NOT (${GIT_TAG_TYPE} STREQUAL "Release" OR ${GIT_TAG_TYPE} STREQUAL "Development"))
|
||||
message(WARNING "Invalid tag type ${GIT_TAG_TYPE}")
|
||||
return()
|
||||
endif()
|
||||
|
||||
# Major
|
||||
list(GET GIT_TAG_EXPLODED 4 GIT_TAG_MAJOR)
|
||||
if(${GIT_TAG_MAJOR} LESS 0 OR ${GIT_TAG_MAJOR} GREATER 99)
|
||||
message(WARNING "Invalid tag major version ${GIT_TAG_MAJOR}")
|
||||
return()
|
||||
endif()
|
||||
# Major
|
||||
list(GET GIT_TAG_EXPLODED 4 GIT_TAG_MAJOR)
|
||||
if(${GIT_TAG_MAJOR} LESS 0 OR ${GIT_TAG_MAJOR} GREATER 99)
|
||||
message(WARNING "Invalid tag major version ${GIT_TAG_MAJOR}")
|
||||
return()
|
||||
endif()
|
||||
|
||||
# Minor
|
||||
list(GET GIT_TAG_EXPLODED 5 GIT_TAG_MINOR)
|
||||
if(${GIT_TAG_MINOR} LESS 0 OR ${GIT_TAG_MINOR} GREATER 99)
|
||||
message(WARNING "Invalid tag minor version ${GIT_TAG_MINOR}")
|
||||
return()
|
||||
endif()
|
||||
# Minor
|
||||
list(GET GIT_TAG_EXPLODED 5 GIT_TAG_MINOR)
|
||||
if(${GIT_TAG_MINOR} LESS 0 OR ${GIT_TAG_MINOR} GREATER 99)
|
||||
message(WARNING "Invalid tag minor version ${GIT_TAG_MINOR}")
|
||||
return()
|
||||
endif()
|
||||
|
||||
# Patch
|
||||
list(GET GIT_TAG_EXPLODED 6 GIT_TAG_PATCH)
|
||||
if(${GIT_TAG_PATCH} LESS 0 OR ${GIT_TAG_PATCH} GREATER 99)
|
||||
message(WARNING "Invalid tag patch version ${GIT_TAG_PATCH}")
|
||||
return()
|
||||
endif()
|
||||
# Patch
|
||||
list(GET GIT_TAG_EXPLODED 6 GIT_TAG_PATCH)
|
||||
if(${GIT_TAG_PATCH} LESS 0 OR ${GIT_TAG_PATCH} GREATER 99)
|
||||
message(WARNING "Invalid tag patch version ${GIT_TAG_PATCH}")
|
||||
return()
|
||||
endif()
|
||||
|
||||
# Label
|
||||
# 7 = Stable release
|
||||
# 8 = Dev release, first beta so only "beta" attached
|
||||
# 9 = Dev release, subsequent beta so "beta.N" attached (N>=2)
|
||||
if(${GIT_TAG_LISTCOUNT} EQUAL 8)
|
||||
list(GET GIT_TAG_EXPLODED 7 GIT_TAG_LABEL)
|
||||
elseif(${GIT_TAG_LISTCOUNT} EQUAL 9)
|
||||
list(GET GIT_TAG_EXPLODED 7 GIT_TAG_LABEL)
|
||||
list(GET GIT_TAG_EXPLODED 8 GIT_TAG_LABEL_NUM)
|
||||
set(GIT_TAG_LABEL ${GIT_TAG_LABEL} ${GIT_TAG_LABEL_NUM})
|
||||
string(REPLACE ";" "." GIT_TAG_LABEL "${GIT_TAG_LABEL}")
|
||||
else()
|
||||
SET(GIT_TAG_LABEL "")
|
||||
endif()
|
||||
# Label 7 = Stable release 8 = Dev release, first beta so only "beta" attached 9 = Dev release, subsequent beta so
|
||||
# "beta.N" attached (N>=2)
|
||||
if(${GIT_TAG_LISTCOUNT} EQUAL 8)
|
||||
list(GET GIT_TAG_EXPLODED 7 GIT_TAG_LABEL)
|
||||
elseif(${GIT_TAG_LISTCOUNT} EQUAL 9)
|
||||
list(GET GIT_TAG_EXPLODED 7 GIT_TAG_LABEL)
|
||||
list(GET GIT_TAG_EXPLODED 8 GIT_TAG_LABEL_NUM)
|
||||
set(GIT_TAG_LABEL ${GIT_TAG_LABEL} ${GIT_TAG_LABEL_NUM})
|
||||
string(REPLACE ";" "." GIT_TAG_LABEL "${GIT_TAG_LABEL}")
|
||||
else()
|
||||
set(GIT_TAG_LABEL "")
|
||||
endif()
|
||||
|
||||
# Override hardcoded version with the informations from the tag
|
||||
set(PROJECT_VERSION_MAJOR ${GIT_TAG_MAJOR} PARENT_SCOPE)
|
||||
set(PROJECT_VERSION_MINOR ${GIT_TAG_MINOR} PARENT_SCOPE)
|
||||
set(PROJECT_VERSION_PATCH ${GIT_TAG_PATCH} PARENT_SCOPE)
|
||||
set(PROJECT_VERSION_LABEL ${GIT_TAG_LABEL} PARENT_SCOPE)
|
||||
# Override hardcoded version with the informations from the tag
|
||||
set(PROJECT_VERSION_MAJOR
|
||||
${GIT_TAG_MAJOR}
|
||||
PARENT_SCOPE
|
||||
)
|
||||
set(PROJECT_VERSION_MINOR
|
||||
${GIT_TAG_MINOR}
|
||||
PARENT_SCOPE
|
||||
)
|
||||
set(PROJECT_VERSION_PATCH
|
||||
${GIT_TAG_PATCH}
|
||||
PARENT_SCOPE
|
||||
)
|
||||
set(PROJECT_VERSION_LABEL
|
||||
${GIT_TAG_LABEL}
|
||||
PARENT_SCOPE
|
||||
)
|
||||
|
||||
if(${GIT_TAG_TYPE} STREQUAL "Development")
|
||||
set(PROJECT_VERSION_LABEL ${GIT_TAG_LABEL} PARENT_SCOPE)
|
||||
elseif(${GIT_TAG_TYPE} STREQUAL "Release")
|
||||
set(PROJECT_VERSION_LABEL "" PARENT_SCOPE)
|
||||
# set release name from env var
|
||||
set(PROJECT_VERSION_RELEASENAME "${GIT_TAG_RELEASENAME}" PARENT_SCOPE)
|
||||
endif()
|
||||
if(${GIT_TAG_TYPE} STREQUAL "Development")
|
||||
set(PROJECT_VERSION_LABEL
|
||||
${GIT_TAG_LABEL}
|
||||
PARENT_SCOPE
|
||||
)
|
||||
elseif(${GIT_TAG_TYPE} STREQUAL "Release")
|
||||
set(PROJECT_VERSION_LABEL
|
||||
""
|
||||
PARENT_SCOPE
|
||||
)
|
||||
# set release name from env var
|
||||
set(PROJECT_VERSION_RELEASENAME
|
||||
"${GIT_TAG_RELEASENAME}"
|
||||
PARENT_SCOPE
|
||||
)
|
||||
endif()
|
||||
|
||||
endfunction()
|
||||
|
||||
@@ -163,16 +192,16 @@ set(PROJECT_VERSION_RELEASENAME "")
|
||||
|
||||
find_package(Git)
|
||||
if(GIT_FOUND)
|
||||
get_commit_id()
|
||||
get_commit_date()
|
||||
get_tag_name(${GIT_COMMIT_ID})
|
||||
get_commit_id()
|
||||
get_commit_date()
|
||||
get_tag_name(${GIT_COMMIT_ID})
|
||||
else()
|
||||
message( WARNING "Git not found. Build will not contain git revision info." )
|
||||
message(WARNING "Git not found. Build will not contain git revision info.")
|
||||
endif()
|
||||
|
||||
set(PROJECT_VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}")
|
||||
if(PROJECT_VERSION_LABEL)
|
||||
set(PROJECT_VERSION "${PROJECT_VERSION}-${PROJECT_VERSION_LABEL}")
|
||||
set(PROJECT_VERSION "${PROJECT_VERSION}-${PROJECT_VERSION_LABEL}")
|
||||
endif()
|
||||
|
||||
set(PROJECT_VERSION_FRIENDLY "${PROJECT_VERSION} (${GIT_COMMIT_DATE_FRIENDLY})")
|
||||
@@ -180,7 +209,7 @@ set(PROJECT_VERSION_FRIENDLY "${PROJECT_VERSION} (${GIT_COMMIT_DATE_FRIENDLY})")
|
||||
# Format: <program name>[-ReleaseName]-MAJ.MIN.PATCH[-prerelease_label]
|
||||
set(PROJECT_VERSION_FILENAME "${PROJECT_NAME}")
|
||||
if(PROJECT_VERSION_RELEASENAME)
|
||||
set(PROJECT_VERSION_FILENAME "${PROJECT_VERSION_FILENAME}-${PROJECT_VERSION_RELEASENAME}")
|
||||
set(PROJECT_VERSION_FILENAME "${PROJECT_VERSION_FILENAME}-${PROJECT_VERSION_RELEASENAME}")
|
||||
endif()
|
||||
set(PROJECT_VERSION_FILENAME "${PROJECT_VERSION_FILENAME}-${PROJECT_VERSION}")
|
||||
|
||||
|
||||
14
cmakeify.sh
Executable file
14
cmakeify.sh
Executable file
@@ -0,0 +1,14 @@
|
||||
#!/bin/bash
|
||||
|
||||
# go to the project root directory, this file should be located in the project root directory
|
||||
cd "${BASH_SOURCE%/*}/" || exit 2 # could not find path, this could happen with special links etc.
|
||||
|
||||
# CMake-Format
|
||||
cmake_format_cmd="cmake-format"
|
||||
|
||||
if ! hash $cmake_format_cmd 2>/dev/null; then
|
||||
echo "could not find $cmake_format_cmd, skipping" >&2
|
||||
return
|
||||
fi
|
||||
|
||||
$cmake_format_cmd -i cmake/*.cmake */CMakeLists.txt CMakeLists.txt
|
||||
@@ -2,284 +2,391 @@
|
||||
#
|
||||
# provides the cockatrice binary
|
||||
|
||||
PROJECT(Cockatrice VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}")
|
||||
project(Cockatrice VERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}")
|
||||
|
||||
SET(cockatrice_SOURCES
|
||||
set(cockatrice_SOURCES
|
||||
src/abstractcarddragitem.cpp
|
||||
src/abstractcarditem.cpp
|
||||
src/abstractclient.cpp
|
||||
src/abstractcounter.cpp
|
||||
src/abstractgraphicsitem.cpp
|
||||
src/arrowitem.cpp
|
||||
src/arrowtarget.cpp
|
||||
src/carddatabase.cpp
|
||||
src/carddatabasemodel.cpp
|
||||
src/carddbparser/carddatabaseparser.cpp
|
||||
src/carddbparser/cockatricexml3.cpp
|
||||
src/carddbparser/cockatricexml4.cpp
|
||||
src/carddragitem.cpp
|
||||
src/cardfilter.cpp
|
||||
src/cardframe.cpp
|
||||
src/cardinfopicture.cpp
|
||||
src/cardinfotext.cpp
|
||||
src/cardinfowidget.cpp
|
||||
src/carditem.cpp
|
||||
src/cardlist.cpp
|
||||
src/cardzone.cpp
|
||||
src/chatview/chatview.cpp
|
||||
src/counter_general.cpp
|
||||
src/dlg_creategame.cpp
|
||||
src/dlg_filter_games.cpp
|
||||
src/customlineedit.cpp
|
||||
src/deck_loader.cpp
|
||||
src/decklistmodel.cpp
|
||||
src/deckstats_interface.cpp
|
||||
src/deckview.cpp
|
||||
src/dlg_connect.cpp
|
||||
src/dlg_create_token.cpp
|
||||
src/dlg_creategame.cpp
|
||||
src/dlg_edit_avatar.cpp
|
||||
src/dlg_edit_password.cpp
|
||||
src/dlg_edit_tokens.cpp
|
||||
src/dlg_edit_user.cpp
|
||||
src/dlg_filter_games.cpp
|
||||
src/dlg_forgotpasswordchallenge.cpp
|
||||
src/dlg_forgotpasswordrequest.cpp
|
||||
src/dlg_forgotpasswordreset.cpp
|
||||
src/dlg_forgotpasswordchallenge.cpp
|
||||
src/dlg_manage_sets.cpp
|
||||
src/dlg_register.cpp
|
||||
src/dlg_tip_of_the_day.cpp
|
||||
src/tip_of_the_day.cpp
|
||||
src/dlg_update.cpp
|
||||
src/dlg_viewlog.cpp
|
||||
src/abstractclient.cpp
|
||||
src/remoteclient.cpp
|
||||
src/main.cpp
|
||||
src/window_main.cpp
|
||||
src/gamesmodel.cpp
|
||||
src/player.cpp
|
||||
src/playertarget.cpp
|
||||
src/cardzone.cpp
|
||||
src/selectzone.cpp
|
||||
src/cardlist.cpp
|
||||
src/abstractcarditem.cpp
|
||||
src/carditem.cpp
|
||||
src/tablezone.cpp
|
||||
src/handzone.cpp
|
||||
src/handcounter.cpp
|
||||
src/carddatabase.cpp
|
||||
src/keysignals.cpp
|
||||
src/gameview.cpp
|
||||
src/gameselector.cpp
|
||||
src/decklistmodel.cpp
|
||||
src/deck_loader.cpp
|
||||
src/dlg_load_deck_from_clipboard.cpp
|
||||
src/dlg_load_remote_deck.cpp
|
||||
src/cardinfowidget.cpp
|
||||
src/cardframe.cpp
|
||||
src/cardinfopicture.cpp
|
||||
src/cardinfotext.cpp
|
||||
src/filterbuilder.cpp
|
||||
src/cardfilter.cpp
|
||||
src/filtertreemodel.cpp
|
||||
src/filtertree.cpp
|
||||
src/messagelogwidget.cpp
|
||||
src/zoneviewzone.cpp
|
||||
src/zoneviewwidget.cpp
|
||||
src/pilezone.cpp
|
||||
src/stackzone.cpp
|
||||
src/carddragitem.cpp
|
||||
src/carddatabasemodel.cpp
|
||||
src/setsmodel.cpp
|
||||
src/abstractgraphicsitem.cpp
|
||||
src/abstractcarddragitem.cpp
|
||||
src/dlg_manage_sets.cpp
|
||||
src/dlg_register.cpp
|
||||
src/dlg_settings.cpp
|
||||
src/phasestoolbar.cpp
|
||||
src/dlg_tip_of_the_day.cpp
|
||||
src/dlg_update.cpp
|
||||
src/dlg_viewlog.cpp
|
||||
src/filter_string.cpp
|
||||
src/filterbuilder.cpp
|
||||
src/filtertree.cpp
|
||||
src/filtertreemodel.cpp
|
||||
src/gamescene.cpp
|
||||
src/arrowitem.cpp
|
||||
src/arrowtarget.cpp
|
||||
src/tab.cpp
|
||||
src/tab_server.cpp
|
||||
src/tab_room.cpp
|
||||
src/tab_message.cpp
|
||||
src/tab_game.cpp
|
||||
src/tab_deck_storage.cpp
|
||||
src/tab_replays.cpp
|
||||
src/tab_supervisor.cpp
|
||||
src/tab_admin.cpp
|
||||
src/tab_account.cpp
|
||||
src/tab_deck_editor.cpp
|
||||
src/tab_logs.cpp
|
||||
src/replay_timeline_widget.cpp
|
||||
src/deckstats_interface.cpp
|
||||
src/tappedout_interface.cpp
|
||||
src/chatview/chatview.cpp
|
||||
src/userlist.cpp
|
||||
src/userinfobox.cpp
|
||||
src/user_context_menu.cpp
|
||||
src/remotedecklist_treewidget.cpp
|
||||
src/remotereplaylist_treewidget.cpp
|
||||
src/deckview.cpp
|
||||
src/playerlistwidget.cpp
|
||||
src/pixmapgenerator.cpp
|
||||
src/settingscache.cpp
|
||||
src/thememanager.cpp
|
||||
src/gameselector.cpp
|
||||
src/gamesmodel.cpp
|
||||
src/gameview.cpp
|
||||
src/gettextwithmax.cpp
|
||||
src/handcounter.cpp
|
||||
src/handle_public_servers.cpp
|
||||
src/handzone.cpp
|
||||
src/keysignals.cpp
|
||||
src/lineeditcompleter.cpp
|
||||
src/localclient.cpp
|
||||
src/localserver.cpp
|
||||
src/localserverinterface.cpp
|
||||
src/localclient.cpp
|
||||
src/soundengine.cpp
|
||||
src/logger.cpp
|
||||
src/main.cpp
|
||||
src/messagelogwidget.cpp
|
||||
src/pending_command.cpp
|
||||
src/phase.cpp
|
||||
src/phasestoolbar.cpp
|
||||
src/pictureloader.cpp
|
||||
src/shortcutssettings.cpp
|
||||
src/pilezone.cpp
|
||||
src/pixmapgenerator.cpp
|
||||
src/player.cpp
|
||||
src/playerlistwidget.cpp
|
||||
src/playertarget.cpp
|
||||
src/releasechannel.cpp
|
||||
src/remoteclient.cpp
|
||||
src/remotedecklist_treewidget.cpp
|
||||
src/remotereplaylist_treewidget.cpp
|
||||
src/replay_timeline_widget.cpp
|
||||
src/selectzone.cpp
|
||||
src/sequenceEdit/sequenceedit.cpp
|
||||
src/lineeditcompleter.cpp
|
||||
src/settings/settingsmanager.cpp
|
||||
src/setsmodel.cpp
|
||||
src/settings/carddatabasesettings.cpp
|
||||
src/settings/serverssettings.cpp
|
||||
src/settings/messagesettings.cpp
|
||||
src/settings/downloadsettings.cpp
|
||||
src/settings/gamefilterssettings.cpp
|
||||
src/settings/layoutssettings.cpp
|
||||
src/settings/downloadsettings.cpp
|
||||
src/update_downloader.cpp
|
||||
src/logger.cpp
|
||||
src/releasechannel.cpp
|
||||
src/userconnection_information.cpp
|
||||
src/settings/messagesettings.cpp
|
||||
src/settings/serverssettings.cpp
|
||||
src/settings/settingsmanager.cpp
|
||||
src/settingscache.cpp
|
||||
src/shortcutssettings.cpp
|
||||
src/soundengine.cpp
|
||||
src/spoilerbackgroundupdater.cpp
|
||||
src/handle_public_servers.cpp
|
||||
src/carddbparser/carddatabaseparser.cpp
|
||||
src/carddbparser/cockatricexml3.cpp
|
||||
src/carddbparser/cockatricexml4.cpp
|
||||
src/filter_string.cpp
|
||||
src/phase.cpp
|
||||
src/customlineedit.cpp
|
||||
src/stackzone.cpp
|
||||
src/tab.cpp
|
||||
src/tab_account.cpp
|
||||
src/tab_admin.cpp
|
||||
src/tab_deck_editor.cpp
|
||||
src/tab_deck_storage.cpp
|
||||
src/tab_game.cpp
|
||||
src/tab_logs.cpp
|
||||
src/tab_message.cpp
|
||||
src/tab_replays.cpp
|
||||
src/tab_room.cpp
|
||||
src/tab_server.cpp
|
||||
src/tab_supervisor.cpp
|
||||
src/tablezone.cpp
|
||||
src/tappedout_interface.cpp
|
||||
src/thememanager.cpp
|
||||
src/tip_of_the_day.cpp
|
||||
src/translatecountername.cpp
|
||||
src/update_downloader.cpp
|
||||
src/user_context_menu.cpp
|
||||
src/userconnection_information.cpp
|
||||
src/userinfobox.cpp
|
||||
src/userlist.cpp
|
||||
src/window_main.cpp
|
||||
src/zoneviewwidget.cpp
|
||||
src/zoneviewzone.cpp
|
||||
${VERSION_STRING_CPP}
|
||||
)
|
||||
)
|
||||
|
||||
add_subdirectory(sounds)
|
||||
add_subdirectory(themes)
|
||||
|
||||
set(cockatrice_RESOURCES cockatrice.qrc)
|
||||
|
||||
IF(UPDATE_TRANSLATIONS)
|
||||
FILE(GLOB_RECURSE translate_cockatrice_SRCS ${CMAKE_SOURCE_DIR}/cockatrice/src/*.cpp ${CMAKE_SOURCE_DIR}/cockatrice/src/*.h)
|
||||
FILE(GLOB_RECURSE translate_common_SRCS ${CMAKE_SOURCE_DIR}/common/*.cpp ${CMAKE_SOURCE_DIR}/common/*.h)
|
||||
SET(translate_SRCS ${translate_cockatrice_SRCS} ${translate_common_SRCS})
|
||||
SET(cockatrice_TS "${CMAKE_CURRENT_SOURCE_DIR}/translations/cockatrice_en.ts")
|
||||
ELSE()
|
||||
FILE(GLOB cockatrice_TS "${CMAKE_CURRENT_SOURCE_DIR}/translations/*.ts")
|
||||
ENDIF(UPDATE_TRANSLATIONS)
|
||||
if(UPDATE_TRANSLATIONS)
|
||||
file(GLOB_RECURSE translate_cockatrice_SRCS ${CMAKE_SOURCE_DIR}/cockatrice/src/*.cpp
|
||||
${CMAKE_SOURCE_DIR}/cockatrice/src/*.h
|
||||
)
|
||||
file(GLOB_RECURSE translate_common_SRCS ${CMAKE_SOURCE_DIR}/common/*.cpp ${CMAKE_SOURCE_DIR}/common/*.h)
|
||||
set(translate_SRCS ${translate_cockatrice_SRCS} ${translate_common_SRCS})
|
||||
set(cockatrice_TS "${CMAKE_CURRENT_SOURCE_DIR}/cockatrice_en@source.ts")
|
||||
else()
|
||||
file(GLOB cockatrice_TS "${CMAKE_CURRENT_SOURCE_DIR}/translations/*.ts")
|
||||
endif(UPDATE_TRANSLATIONS)
|
||||
|
||||
if(WIN32)
|
||||
set(cockatrice_SOURCES ${cockatrice_SOURCES} cockatrice.rc)
|
||||
set(cockatrice_SOURCES ${cockatrice_SOURCES} cockatrice.rc)
|
||||
endif(WIN32)
|
||||
|
||||
if(APPLE)
|
||||
set(MACOSX_BUNDLE_ICON_FILE appicon.icns)
|
||||
set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/resources/appicon.icns PROPERTIES MACOSX_PACKAGE_LOCATION Resources)
|
||||
set(cockatrice_SOURCES ${cockatrice_SOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/resources/appicon.icns)
|
||||
ENDIF(APPLE)
|
||||
set(MACOSX_BUNDLE_ICON_FILE appicon.icns)
|
||||
set_source_files_properties(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/resources/appicon.icns PROPERTIES MACOSX_PACKAGE_LOCATION Resources
|
||||
)
|
||||
set(cockatrice_SOURCES ${cockatrice_SOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/resources/appicon.icns)
|
||||
endif(APPLE)
|
||||
|
||||
# Qt5
|
||||
find_package(Qt5 COMPONENTS Concurrent Multimedia Network PrintSupport Svg WebSockets Widgets REQUIRED)
|
||||
set(COCKATRICE_QT_MODULES Qt5::Concurrent Qt5::Multimedia Qt5::Network Qt5::PrintSupport Qt5::Svg Qt5::Widgets Qt5::WebSockets)
|
||||
|
||||
# Qt5LinguistTools
|
||||
find_package(Qt5LinguistTools)
|
||||
if(Qt5LinguistTools_FOUND)
|
||||
list(APPEND COCKATRICE_LIBS Qt5::LinguistTools)
|
||||
|
||||
if(NOT Qt5_LRELEASE_EXECUTABLE)
|
||||
MESSAGE(WARNING "Qt's lrelease not found.")
|
||||
endif()
|
||||
|
||||
if(UPDATE_TRANSLATIONS)
|
||||
if(NOT Qt5_LUPDATE_EXECUTABLE)
|
||||
MESSAGE(WARNING "Qt's lupdate not found.")
|
||||
endif()
|
||||
QT5_CREATE_TRANSLATION(cockatrice_QM ${translate_SRCS} ${cockatrice_TS})
|
||||
else()
|
||||
QT5_ADD_TRANSLATION(cockatrice_QM ${cockatrice_TS})
|
||||
endif()
|
||||
if(Qt6_FOUND)
|
||||
qt6_add_resources(cockatrice_RESOURCES_RCC ${cockatrice_RESOURCES})
|
||||
elseif(Qt5_FOUND)
|
||||
qt5_add_resources(cockatrice_RESOURCES_RCC ${cockatrice_RESOURCES})
|
||||
endif()
|
||||
|
||||
QT5_ADD_RESOURCES(cockatrice_RESOURCES_RCC ${cockatrice_RESOURCES})
|
||||
|
||||
# Declare path variables
|
||||
set(ICONDIR share/icons CACHE STRING "icon dir")
|
||||
set(DESKTOPDIR share/applications CACHE STRING "desktop file destination")
|
||||
set(ICONDIR
|
||||
share/icons
|
||||
CACHE STRING "icon dir"
|
||||
)
|
||||
set(DESKTOPDIR
|
||||
share/applications
|
||||
CACHE STRING "desktop file destination"
|
||||
)
|
||||
|
||||
# Include directories
|
||||
INCLUDE_DIRECTORIES(../common)
|
||||
INCLUDE_DIRECTORIES(${PROTOBUF_INCLUDE_DIR})
|
||||
INCLUDE_DIRECTORIES(${CMAKE_BINARY_DIR}/common)
|
||||
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
|
||||
include_directories(../common)
|
||||
include_directories(${PROTOBUF_INCLUDE_DIR})
|
||||
include_directories(${CMAKE_BINARY_DIR}/common)
|
||||
include_directories(${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
# Build cockatrice binary and link it
|
||||
ADD_EXECUTABLE(cockatrice WIN32 MACOSX_BUNDLE ${cockatrice_SOURCES} ${cockatrice_QM} ${cockatrice_RESOURCES_RCC} ${cockatrice_MOC_SRCS})
|
||||
set(COCKATRICE_MAC_QM_INSTALL_DIR "cockatrice.app/Contents/Resources/translations")
|
||||
set(COCKATRICE_UNIX_QM_INSTALL_DIR "share/cockatrice/translations")
|
||||
set(COCKATRICE_WIN32_QM_INSTALL_DIR "translations")
|
||||
|
||||
TARGET_LINK_LIBRARIES(cockatrice cockatrice_common ${COCKATRICE_QT_MODULES})
|
||||
if(Qt6_FOUND)
|
||||
qt6_add_executable(
|
||||
cockatrice
|
||||
WIN32
|
||||
MACOSX_BUNDLE
|
||||
${cockatrice_SOURCES}
|
||||
${cockatrice_RESOURCES_RCC}
|
||||
${cockatrice_MOC_SRCS}
|
||||
MANUAL_FINALIZATION
|
||||
)
|
||||
elseif(Qt5_FOUND)
|
||||
# Qt5 Translations need to be linked at executable creation time
|
||||
if(Qt5LinguistTools_FOUND)
|
||||
if(UPDATE_TRANSLATIONS)
|
||||
qt5_create_translation(cockatrice_QM ${translate_SRCS} ${cockatrice_TS})
|
||||
else()
|
||||
qt5_add_translation(cockatrice_QM ${cockatrice_TS})
|
||||
endif()
|
||||
endif()
|
||||
add_executable(
|
||||
cockatrice WIN32 MACOSX_BUNDLE ${cockatrice_MOC_SRCS} ${cockatrice_QM} ${cockatrice_RESOURCES_RCC}
|
||||
${cockatrice_SOURCES}
|
||||
)
|
||||
if(UNIX)
|
||||
if(APPLE)
|
||||
install(FILES ${cockatrice_QM} DESTINATION ${COCKATRICE_MAC_QM_INSTALL_DIR})
|
||||
else()
|
||||
install(FILES ${cockatrice_QM} DESTINATION ${COCKATRICE_UNIX_QM_INSTALL_DIR})
|
||||
endif()
|
||||
elseif(WIN32)
|
||||
install(FILES ${cockatrice_QM} DESTINATION ${COCKATRICE_WIN32_QM_INSTALL_DIR})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(Qt5_FOUND)
|
||||
target_link_libraries(cockatrice cockatrice_common ${COCKATRICE_QT_MODULES})
|
||||
else()
|
||||
target_link_libraries(cockatrice PUBLIC cockatrice_common ${COCKATRICE_QT_MODULES})
|
||||
endif()
|
||||
|
||||
if(UNIX)
|
||||
if(APPLE)
|
||||
set(MACOSX_BUNDLE_INFO_STRING "${PROJECT_NAME}")
|
||||
set(MACOSX_BUNDLE_GUI_IDENTIFIER "com.cockatrice.${PROJECT_NAME}")
|
||||
set(MACOSX_BUNDLE_LONG_VERSION_STRING "${PROJECT_NAME}-${PROJECT_VERSION}")
|
||||
set(MACOSX_BUNDLE_BUNDLE_NAME "${PROJECT_NAME}")
|
||||
set(MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION})
|
||||
set(MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION})
|
||||
if(APPLE)
|
||||
set(MACOSX_BUNDLE_INFO_STRING "${PROJECT_NAME}")
|
||||
set(MACOSX_BUNDLE_GUI_IDENTIFIER "com.cockatrice.${PROJECT_NAME}")
|
||||
set(MACOSX_BUNDLE_LONG_VERSION_STRING "${PROJECT_NAME}-${PROJECT_VERSION}")
|
||||
set(MACOSX_BUNDLE_BUNDLE_NAME "${PROJECT_NAME}")
|
||||
set(MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION})
|
||||
set(MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION})
|
||||
|
||||
set_target_properties(cockatrice PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_SOURCE_DIR}/cmake/Info.plist)
|
||||
set_target_properties(cockatrice PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_SOURCE_DIR}/cmake/Info.plist)
|
||||
|
||||
INSTALL(TARGETS cockatrice BUNDLE DESTINATION ./)
|
||||
INSTALL(FILES ${cockatrice_QM} DESTINATION ./cockatrice.app/Contents/Resources/translations)
|
||||
else()
|
||||
# Assume linux
|
||||
INSTALL(TARGETS cockatrice RUNTIME DESTINATION bin/)
|
||||
INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/resources/cockatrice.png DESTINATION ${ICONDIR}/hicolor/48x48/apps)
|
||||
INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/resources/cockatrice.svg DESTINATION ${ICONDIR}/hicolor/scalable/apps)
|
||||
INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/cockatrice.desktop DESTINATION ${DESKTOPDIR})
|
||||
INSTALL(FILES ${cockatrice_QM} DESTINATION share/cockatrice/translations)
|
||||
endif()
|
||||
install(TARGETS cockatrice BUNDLE DESTINATION ./)
|
||||
else()
|
||||
# Assume linux
|
||||
install(TARGETS cockatrice RUNTIME DESTINATION bin/)
|
||||
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/resources/cockatrice.png DESTINATION ${ICONDIR}/hicolor/48x48/apps)
|
||||
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/resources/cockatrice.svg DESTINATION ${ICONDIR}/hicolor/scalable/apps)
|
||||
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/cockatrice.desktop DESTINATION ${DESKTOPDIR})
|
||||
endif()
|
||||
elseif(WIN32)
|
||||
INSTALL(TARGETS cockatrice RUNTIME DESTINATION ./)
|
||||
INSTALL(FILES ${cockatrice_QM} DESTINATION ./translations)
|
||||
install(TARGETS cockatrice RUNTIME DESTINATION ./)
|
||||
endif()
|
||||
|
||||
if(APPLE)
|
||||
# these needs to be relative to CMAKE_INSTALL_PREFIX
|
||||
set(plugin_dest_dir cockatrice.app/Contents/Plugins)
|
||||
set(qtconf_dest_dir cockatrice.app/Contents/Resources)
|
||||
get_filename_component(QT_LIBRARY_DIR "${QT_LIBRARY_DIR}/.." ABSOLUTE)
|
||||
# these needs to be relative to CMAKE_INSTALL_PREFIX
|
||||
set(plugin_dest_dir cockatrice.app/Contents/Plugins)
|
||||
set(qtconf_dest_dir cockatrice.app/Contents/Resources)
|
||||
|
||||
# qt5 plugins: audio, iconengines, imageformats, platforms, printsupport
|
||||
install(DIRECTORY "${QT_PLUGINS_DIR}/" DESTINATION ${plugin_dest_dir} COMPONENT Runtime
|
||||
FILES_MATCHING
|
||||
PATTERN "*.dSYM" EXCLUDE
|
||||
PATTERN "*_debug.dylib" EXCLUDE
|
||||
PATTERN "audio/*.dylib"
|
||||
PATTERN "iconengines/*.dylib"
|
||||
PATTERN "imageformats/*.dylib"
|
||||
PATTERN "platforms/*.dylib"
|
||||
PATTERN "printsupport/*.dylib"
|
||||
PATTERN "styles/*.dylib"
|
||||
)
|
||||
# Qt plugins: audio (Qt5), iconengines, imageformats, platforms, printsupport (Qt5), styles, tls (Qt6)
|
||||
install(
|
||||
DIRECTORY "${QT_PLUGINS_DIR}/"
|
||||
DESTINATION ${plugin_dest_dir}
|
||||
COMPONENT Runtime
|
||||
FILES_MATCHING
|
||||
PATTERN "*.dSYM" EXCLUDE
|
||||
PATTERN "*_debug.dylib" EXCLUDE
|
||||
PATTERN "audio/*.dylib"
|
||||
PATTERN "iconengines/*.dylib"
|
||||
PATTERN "imageformats/*.dylib"
|
||||
PATTERN "platforms/*.dylib"
|
||||
PATTERN "printsupport/*.dylib"
|
||||
PATTERN "styles/*.dylib"
|
||||
PATTERN "tls/*.dylib"
|
||||
)
|
||||
|
||||
install(CODE "
|
||||
install(
|
||||
CODE "
|
||||
file(WRITE \"\${CMAKE_INSTALL_PREFIX}/${qtconf_dest_dir}/qt.conf\" \"[Paths]
|
||||
Plugins = Plugins
|
||||
Translations = Resources/translations
|
||||
Data = Resources\")
|
||||
" COMPONENT Runtime)
|
||||
"
|
||||
COMPONENT Runtime
|
||||
)
|
||||
|
||||
install(CODE "
|
||||
install(
|
||||
CODE "
|
||||
file(GLOB_RECURSE QTPLUGINS
|
||||
\"\${CMAKE_INSTALL_PREFIX}/${plugin_dest_dir}/*.dylib\")
|
||||
set(BU_CHMOD_BUNDLE_ITEMS ON)
|
||||
include(BundleUtilities)
|
||||
fixup_bundle(\"\${CMAKE_INSTALL_PREFIX}/cockatrice.app\" \"\${QTPLUGINS}\" \"${QT_LIBRARY_DIR}\")
|
||||
" COMPONENT Runtime)
|
||||
"
|
||||
COMPONENT Runtime
|
||||
)
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
# these needs to be relative to CMAKE_INSTALL_PREFIX
|
||||
set(plugin_dest_dir Plugins)
|
||||
set(qtconf_dest_dir .)
|
||||
# these needs to be relative to CMAKE_INSTALL_PREFIX
|
||||
set(plugin_dest_dir Plugins)
|
||||
set(qtconf_dest_dir .)
|
||||
|
||||
install(DIRECTORY "${CMAKE_BINARY_DIR}/${PROJECT_NAME}/${CMAKE_BUILD_TYPE}/" DESTINATION ./ FILES_MATCHING PATTERN "*.dll")
|
||||
install(
|
||||
DIRECTORY "${CMAKE_BINARY_DIR}/${PROJECT_NAME}/${CMAKE_BUILD_TYPE}/"
|
||||
DESTINATION ./
|
||||
FILES_MATCHING
|
||||
PATTERN "*.dll"
|
||||
)
|
||||
|
||||
# qt5 plugins: audio, iconengines, imageformats, platforms, printsupport
|
||||
install(DIRECTORY "${QT_PLUGINS_DIR}/" DESTINATION ${plugin_dest_dir} COMPONENT Runtime
|
||||
FILES_MATCHING REGEX "(audio|iconengines|imageformats|platforms|printsupport|styles)/.*[^d]\\.dll")
|
||||
# Qt plugins: audio (Qt5), iconengines, imageformats, platforms, printsupport (Qt5), styles, tls (Qt6)
|
||||
install(
|
||||
DIRECTORY "${QT_PLUGINS_DIR}/"
|
||||
DESTINATION ${plugin_dest_dir}
|
||||
COMPONENT Runtime
|
||||
FILES_MATCHING
|
||||
PATTERN "audio/qtaudio_wasapi.dll"
|
||||
PATTERN "audio/qtaudio_windows.dll"
|
||||
PATTERN "iconengines/qsvgicon.dll"
|
||||
PATTERN "imageformats/qgif.dll"
|
||||
PATTERN "imageformats/qicns.dll"
|
||||
PATTERN "imageformats/qico.dll"
|
||||
PATTERN "imageformats/qjpeg.dll"
|
||||
PATTERN "imageformats/qsvg.dll"
|
||||
PATTERN "imageformats/qtga.dll"
|
||||
PATTERN "imageformats/qtiff.dll"
|
||||
PATTERN "imageformats/qwbmp.dll"
|
||||
PATTERN "imageformats/qwebp.dll"
|
||||
PATTERN "platforms/qdirect2d.dll"
|
||||
PATTERN "platforms/qminimal.dll"
|
||||
PATTERN "platforms/qoffscreen.dll"
|
||||
PATTERN "platforms/qwindows.dll"
|
||||
PATTERN "printsupport/windowsprintersupport.dll"
|
||||
PATTERN "styles/qcertonlybackend.dll"
|
||||
PATTERN "styles/qopensslbackend.dll"
|
||||
PATTERN "styles/qschannelbackend.dll"
|
||||
PATTERN "styles/qwindowsvistastyle.dll"
|
||||
PATTERN "tls/qcertonlybackend.dll"
|
||||
PATTERN "tls/qopensslbackend.dll"
|
||||
PATTERN "tls/qschannelbackend.dll"
|
||||
)
|
||||
|
||||
install(CODE "
|
||||
install(
|
||||
CODE "
|
||||
file(WRITE \"\${CMAKE_INSTALL_PREFIX}/${qtconf_dest_dir}/qt.conf\" \"[Paths]
|
||||
Plugins = Plugins
|
||||
Translations = Resources/translations
|
||||
Data = Resources\")
|
||||
" COMPONENT Runtime)
|
||||
"
|
||||
COMPONENT Runtime
|
||||
)
|
||||
|
||||
install(CODE "
|
||||
install(
|
||||
CODE "
|
||||
file(GLOB_RECURSE QTPLUGINS
|
||||
\"\${CMAKE_INSTALL_PREFIX}/${plugin_dest_dir}/*.dll\")
|
||||
set(BU_CHMOD_BUNDLE_ITEMS ON)
|
||||
include(BundleUtilities)
|
||||
fixup_bundle(\"\${CMAKE_INSTALL_PREFIX}/Cockatrice.exe\" \"\${QTPLUGINS}\" \"${QT_LIBRARY_DIR}\")
|
||||
" COMPONENT Runtime)
|
||||
"
|
||||
COMPONENT Runtime
|
||||
)
|
||||
|
||||
if(WIN32SSLRUNTIME_FOUND)
|
||||
install(FILES ${WIN32SSLRUNTIME_LIBRARIES} DESTINATION ./)
|
||||
endif()
|
||||
if(WIN32SSLRUNTIME_FOUND)
|
||||
install(FILES ${WIN32SSLRUNTIME_LIBRARIES} DESTINATION ./)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(Qt6LinguistTools_FOUND)
|
||||
# Qt6 Translations happen after the executable is built up
|
||||
if(UPDATE_TRANSLATIONS)
|
||||
qt6_add_translations(
|
||||
cockatrice
|
||||
TS_FILES
|
||||
${cockatrice_TS}
|
||||
SOURCES
|
||||
${translate_SRCS}
|
||||
QM_FILES_OUTPUT_VARIABLE
|
||||
cockatrice_QM
|
||||
)
|
||||
else()
|
||||
qt6_add_translations(cockatrice TS_FILES ${cockatrice_TS} QM_FILES_OUTPUT_VARIABLE cockatrice_QM)
|
||||
endif()
|
||||
|
||||
if(UNIX)
|
||||
if(APPLE)
|
||||
install(FILES ${cockatrice_QM} DESTINATION ${COCKATRICE_MAC_QM_INSTALL_DIR})
|
||||
else()
|
||||
install(FILES ${cockatrice_QM} DESTINATION ${COCKATRICE_UNIX_QM_INSTALL_DIR})
|
||||
endif()
|
||||
elseif(WIN32)
|
||||
install(FILES ${cockatrice_QM} DESTINATION ${COCKATRICE_WIN32_QM_INSTALL_DIR})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(Qt6_FOUND)
|
||||
qt6_finalize_target(cockatrice)
|
||||
endif()
|
||||
|
||||
@@ -126,6 +126,7 @@
|
||||
<file>resources/countries/er.svg</file>
|
||||
<file>resources/countries/es.svg</file>
|
||||
<file>resources/countries/et.svg</file>
|
||||
<file>resources/countries/eu.svg</file>
|
||||
<file>resources/countries/fi.svg</file>
|
||||
<file>resources/countries/fj.svg</file>
|
||||
<file>resources/countries/fk.svg</file>
|
||||
@@ -301,16 +302,13 @@
|
||||
<file>resources/countries/vu.svg</file>
|
||||
<file>resources/countries/wf.svg</file>
|
||||
<file>resources/countries/ws.svg</file>
|
||||
<file>resources/countries/xk.svg</file>
|
||||
<file>resources/countries/ye.svg</file>
|
||||
<file>resources/countries/yt.svg</file>
|
||||
<file>resources/countries/za.svg</file>
|
||||
<file>resources/countries/zm.svg</file>
|
||||
<file>resources/countries/zw.svg</file>
|
||||
|
||||
<file>resources/genders/male.svg</file>
|
||||
<file>resources/genders/female.svg</file>
|
||||
<file>resources/genders/unknown.svg</file>
|
||||
|
||||
<file>resources/phases/untap.svg</file>
|
||||
<file>resources/phases/upkeep.svg</file>
|
||||
<file>resources/phases/draw.svg</file>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
92
cockatrice/resources/countries/xk.svg
Normal file
92
cockatrice/resources/countries/xk.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 8.3 KiB |
@@ -1,33 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
<svg
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
version="1.0"
|
||||
width="75"
|
||||
height="75"
|
||||
id="svg34864">
|
||||
<defs
|
||||
id="defs34866" />
|
||||
<g
|
||||
transform="translate(-348.7552,-478.0905)"
|
||||
id="layer1">
|
||||
<g
|
||||
transform="matrix(1.071197,0,0,1.075147,-13.30677,-36.99488)"
|
||||
id="g3773">
|
||||
<path
|
||||
d="M 176 33 A 11 11 0 1 1 154,33 A 11 11 0 1 1 176 33 z"
|
||||
transform="matrix(1.540096,0,0,1.5384,118.8893,454.0543)"
|
||||
style="color:black;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:black;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
|
||||
id="path3939" />
|
||||
<path
|
||||
d="M 373.00525,521.74399 L 373.00525,543.28159"
|
||||
style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:4.61774349;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path3941" />
|
||||
<path
|
||||
d="M 363.76467,534.05119 L 382.24582,534.05119"
|
||||
style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:4.61774349;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path4816" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.5 KiB |
@@ -1,12 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
<svg xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" version="1.0" width="75" height="75" id="svg34864">
|
||||
<defs id="defs34866"/>
|
||||
<g transform="translate(-348.755, -478.091)" id="layer1">
|
||||
<g transform="matrix(1.94812, 0, 0, 1.93731, -342.43, -460.01)" id="g1872">
|
||||
<path d="M 387.95009,489.60348 L 378.66214,498.89143" style="opacity: 1; color: black; fill: none; fill-opacity: 0.75; fill-rule: evenodd; stroke: black; stroke-width: 3; stroke-linecap: butt; stroke-linejoin: miter; marker: none; stroke-miterlimit: 4; stroke-dasharray: none; stroke-dashoffset: 0pt; stroke-opacity: 1; visibility: visible; display: inline; overflow: visible;" id="path26867"/>
|
||||
<path d="M 49.396475 36.70454 A 15.623922 16.319134 0 1 1 18.14863,36.70454 A 15.623922 16.319134 0 1 1 49.396475 36.70454 z" transform="matrix(0.48802, 0.48802, -0.467594, 0.467594, 371.609, 473.136)" style="opacity: 1; color: black; fill: none; fill-opacity: 1; fill-rule: evenodd; stroke: black; stroke-width: 4.44072; stroke-linecap: butt; stroke-linejoin: miter; marker: none; stroke-miterlimit: 4; stroke-dasharray: none; stroke-dashoffset: 0pt; stroke-opacity: 1; visibility: visible; display: inline; overflow: visible;" id="path26871"/>
|
||||
<path d="M 379.92823,489.70212 C 387.842,489.70212 387.842,489.70212 387.842,489.70212 L 387.842,497.61589" style="fill: none; fill-rule: evenodd; stroke: black; stroke-width: 3; stroke-linecap: butt; stroke-linejoin: miter; stroke-miterlimit: 4; stroke-dasharray: none; stroke-opacity: 1;" id="path27759"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.7 KiB |
@@ -1,10 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Intersexual/Transgendered symbol by Gregory Maxwell. Copyright 2005. GFDL-1.2 only -->
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
version="1.1"
|
||||
width="210"
|
||||
height="280">
|
||||
<path d="M 188,38 v 20 l 14,-8 v -42 h -42 l -8,14 h 20 l -37,37 a 79,79 0 1,0 -59,141 v 22 h -27 v 23 h 27 v 27 h 23 v -27 h 27 v -23 h -27 v -22 a 79,79 0 0,0 52,-125 zm -100,27 a 57,57 0 1,1 0,114 a 57,57 0 1,1 0,-114 z"/>
|
||||
<!-- 88,65 // -63,-10 -->
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 500 B |
@@ -2,18 +2,15 @@
|
||||
#
|
||||
# add sounds subfolders
|
||||
|
||||
SET(defsounds
|
||||
Default
|
||||
Legacy
|
||||
)
|
||||
set(defsounds Default Legacy)
|
||||
|
||||
if(UNIX)
|
||||
if(APPLE)
|
||||
INSTALL(DIRECTORY ${defsounds} DESTINATION Cockatrice.app/Contents/Resources/sounds/)
|
||||
else()
|
||||
# Assume linux
|
||||
INSTALL(DIRECTORY ${defsounds} DESTINATION share/cockatrice/sounds/)
|
||||
endif()
|
||||
if(APPLE)
|
||||
install(DIRECTORY ${defsounds} DESTINATION Cockatrice.app/Contents/Resources/sounds/)
|
||||
else()
|
||||
# Assume linux
|
||||
install(DIRECTORY ${defsounds} DESTINATION share/cockatrice/sounds/)
|
||||
endif()
|
||||
elseif(WIN32)
|
||||
INSTALL(DIRECTORY ${defsounds} DESTINATION sounds/)
|
||||
install(DIRECTORY ${defsounds} DESTINATION sounds/)
|
||||
endif()
|
||||
|
||||
@@ -1,19 +1,17 @@
|
||||
#include <QCursor>
|
||||
#include <QGraphicsScene>
|
||||
#include <QGraphicsSceneMouseEvent>
|
||||
#include <QPainter>
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#ifdef _WIN32
|
||||
#include "round.h"
|
||||
#endif /* _WIN32 */
|
||||
#include "abstractcarditem.h"
|
||||
|
||||
#include "carddatabase.h"
|
||||
#include "gamescene.h"
|
||||
#include "main.h"
|
||||
#include "pictureloader.h"
|
||||
#include "settingscache.h"
|
||||
|
||||
#include <QCursor>
|
||||
#include <QGraphicsScene>
|
||||
#include <QGraphicsSceneMouseEvent>
|
||||
#include <QPainter>
|
||||
#include <algorithm>
|
||||
|
||||
AbstractCardItem::AbstractCardItem(const QString &_name, Player *_owner, int _id, QGraphicsItem *parent)
|
||||
: ArrowTarget(_owner, parent), id(_id), name(_name), tapped(false), facedown(false), tapAngle(0),
|
||||
bgColor(Qt::transparent), isHovered(false), realZValue(0)
|
||||
|
||||
@@ -22,7 +22,8 @@
|
||||
|
||||
#include <google/protobuf/descriptor.h>
|
||||
|
||||
AbstractClient::AbstractClient(QObject *parent) : QObject(parent), nextCmdId(0), status(StatusDisconnected)
|
||||
AbstractClient::AbstractClient(QObject *parent)
|
||||
: QObject(parent), nextCmdId(0), status(StatusDisconnected), serverSupportsPasswordHash(false)
|
||||
{
|
||||
qRegisterMetaType<QVariant>("QVariant");
|
||||
qRegisterMetaType<CommandContainer>("CommandContainer");
|
||||
@@ -47,6 +48,7 @@ AbstractClient::AbstractClient(QObject *parent) : QObject(parent), nextCmdId(0),
|
||||
qRegisterMetaType<QList<ServerInfo_User>>("QList<ServerInfo_User>");
|
||||
qRegisterMetaType<Event_ReplayAdded>("Event_ReplayAdded");
|
||||
qRegisterMetaType<QList<QString>>("missingFeatures");
|
||||
qRegisterMetaType<PendingCommand *>("pendingCommand");
|
||||
|
||||
FeatureSet features;
|
||||
features.initalizeFeatureList(clientFeatures);
|
||||
|
||||
@@ -40,6 +40,7 @@ enum ClientStatus
|
||||
StatusRequestingForgotPassword,
|
||||
StatusSubmitForgotPasswordReset,
|
||||
StatusSubmitForgotPasswordChallenge,
|
||||
StatusGettingPasswordSalt,
|
||||
};
|
||||
|
||||
class AbstractClient : public QObject
|
||||
@@ -87,7 +88,7 @@ protected slots:
|
||||
protected:
|
||||
QMap<int, PendingCommand *> pendingCommands;
|
||||
QString userName, password, email, country, realName, token;
|
||||
int gender;
|
||||
bool serverSupportsPasswordHash;
|
||||
void setStatus(ClientStatus _status);
|
||||
int getNewCmdId()
|
||||
{
|
||||
@@ -107,7 +108,11 @@ public:
|
||||
void sendCommand(const CommandContainer &cont);
|
||||
void sendCommand(PendingCommand *pend);
|
||||
|
||||
const QString getUserName()
|
||||
bool getServerSupportsPasswordHash() const
|
||||
{
|
||||
return serverSupportsPasswordHash;
|
||||
}
|
||||
const QString &getUserName() const
|
||||
{
|
||||
return userName;
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
#include <QGraphicsScene>
|
||||
#include <QGraphicsSceneMouseEvent>
|
||||
#include <QPainter>
|
||||
#include <cmath>
|
||||
#include <QtMath>
|
||||
|
||||
ArrowItem::ArrowItem(Player *_player, int _id, ArrowTarget *_startItem, ArrowTarget *_targetItem, const QColor &_color)
|
||||
: QGraphicsItem(), player(_player), id(_id), startItem(_startItem), targetItem(_targetItem), color(_color),
|
||||
@@ -71,7 +71,7 @@ void ArrowItem::updatePath(const QPointF &endPoint)
|
||||
const double arrowWidth = 15.0;
|
||||
const double headWidth = 40.0;
|
||||
const double headLength =
|
||||
headWidth / pow(2, 0.5); // aka headWidth / sqrt (2) but this produces a compile error with MSVC++
|
||||
headWidth / qPow(2, 0.5); // aka headWidth / sqrt (2) but this produces a compile error with MSVC++
|
||||
const double phi = 15;
|
||||
|
||||
if (!startItem)
|
||||
@@ -86,7 +86,7 @@ void ArrowItem::updatePath(const QPointF &endPoint)
|
||||
if (lineLength < 30)
|
||||
path = QPainterPath();
|
||||
else {
|
||||
QPointF c(lineLength / 2, tan(phi * M_PI / 180) * lineLength);
|
||||
QPointF c(lineLength / 2, qTan(phi * M_PI / 180) * lineLength);
|
||||
|
||||
QPainterPath centerLine;
|
||||
centerLine.moveTo(0, 0);
|
||||
@@ -97,22 +97,22 @@ void ArrowItem::updatePath(const QPointF &endPoint)
|
||||
QLineF testLine(arrowBodyEndPoint, centerLine.pointAtPercent(percentage + 0.001));
|
||||
qreal alpha = testLine.angle() - 90;
|
||||
QPointF endPoint1 =
|
||||
arrowBodyEndPoint + arrowWidth / 2 * QPointF(cos(alpha * M_PI / 180), -sin(alpha * M_PI / 180));
|
||||
arrowBodyEndPoint + arrowWidth / 2 * QPointF(qCos(alpha * M_PI / 180), -qSin(alpha * M_PI / 180));
|
||||
QPointF endPoint2 =
|
||||
arrowBodyEndPoint + arrowWidth / 2 * QPointF(-cos(alpha * M_PI / 180), sin(alpha * M_PI / 180));
|
||||
arrowBodyEndPoint + arrowWidth / 2 * QPointF(-qCos(alpha * M_PI / 180), qSin(alpha * M_PI / 180));
|
||||
QPointF point1 =
|
||||
endPoint1 + (headWidth - arrowWidth) / 2 * QPointF(cos(alpha * M_PI / 180), -sin(alpha * M_PI / 180));
|
||||
endPoint1 + (headWidth - arrowWidth) / 2 * QPointF(qCos(alpha * M_PI / 180), -qSin(alpha * M_PI / 180));
|
||||
QPointF point2 =
|
||||
endPoint2 + (headWidth - arrowWidth) / 2 * QPointF(-cos(alpha * M_PI / 180), sin(alpha * M_PI / 180));
|
||||
endPoint2 + (headWidth - arrowWidth) / 2 * QPointF(-qCos(alpha * M_PI / 180), qSin(alpha * M_PI / 180));
|
||||
|
||||
path = QPainterPath(-arrowWidth / 2 * QPointF(cos((phi - 90) * M_PI / 180), sin((phi - 90) * M_PI / 180)));
|
||||
path = QPainterPath(-arrowWidth / 2 * QPointF(qCos((phi - 90) * M_PI / 180), qSin((phi - 90) * M_PI / 180)));
|
||||
path.quadTo(c, endPoint1);
|
||||
path.lineTo(point1);
|
||||
path.lineTo(QPointF(lineLength, 0));
|
||||
path.lineTo(point2);
|
||||
path.lineTo(endPoint2);
|
||||
path.quadTo(c, arrowWidth / 2 * QPointF(cos((phi - 90) * M_PI / 180), sin((phi - 90) * M_PI / 180)));
|
||||
path.lineTo(-arrowWidth / 2 * QPointF(cos((phi - 90) * M_PI / 180), sin((phi - 90) * M_PI / 180)));
|
||||
path.quadTo(c, arrowWidth / 2 * QPointF(qCos((phi - 90) * M_PI / 180), qSin((phi - 90) * M_PI / 180)));
|
||||
path.lineTo(-arrowWidth / 2 * QPointF(qCos((phi - 90) * M_PI / 180), qSin((phi - 90) * M_PI / 180)));
|
||||
}
|
||||
|
||||
setPos(startPoint);
|
||||
|
||||
@@ -43,9 +43,8 @@ public:
|
||||
}
|
||||
void removeArrowFrom(ArrowItem *arrow)
|
||||
{
|
||||
arrowsFrom.removeAt(arrowsFrom.indexOf(arrow));
|
||||
arrowsFrom.removeOne(arrow);
|
||||
}
|
||||
|
||||
const QList<ArrowItem *> &getArrowsTo() const
|
||||
{
|
||||
return arrowsTo;
|
||||
@@ -56,8 +55,7 @@ public:
|
||||
}
|
||||
void removeArrowTo(ArrowItem *arrow)
|
||||
{
|
||||
arrowsTo.removeAt(arrowsTo.indexOf(arrow));
|
||||
arrowsTo.removeOne(arrow);
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -23,7 +23,7 @@ bool CockatriceXml3Parser::getCanParseFile(const QString &fileName, QIODevice &d
|
||||
QXmlStreamReader xml(&device);
|
||||
while (!xml.atEnd()) {
|
||||
if (xml.readNext() == QXmlStreamReader::StartElement) {
|
||||
if (xml.name() == COCKATRICE_XML3_TAGNAME) {
|
||||
if (xml.name().toString() == COCKATRICE_XML3_TAGNAME) {
|
||||
int version = xml.attributes().value("version").toString().toInt();
|
||||
if (version == COCKATRICE_XML3_TAGVER) {
|
||||
return true;
|
||||
@@ -52,12 +52,13 @@ void CockatriceXml3Parser::parseFile(QIODevice &device)
|
||||
break;
|
||||
}
|
||||
|
||||
if (xml.name() == "sets") {
|
||||
auto name = xml.name().toString();
|
||||
if (name == "sets") {
|
||||
loadSetsFromXml(xml);
|
||||
} else if (xml.name() == "cards") {
|
||||
} else if (name == "cards") {
|
||||
loadCardsFromXml(xml);
|
||||
} else if (xml.name() != "") {
|
||||
qDebug() << "[CockatriceXml3Parser] Unknown item" << xml.name() << ", trying to continue anyway";
|
||||
} else if (!name.isEmpty()) {
|
||||
qDebug() << "[CockatriceXml3Parser] Unknown item" << name << ", trying to continue anyway";
|
||||
xml.skipCurrentElement();
|
||||
}
|
||||
}
|
||||
@@ -72,26 +73,27 @@ void CockatriceXml3Parser::loadSetsFromXml(QXmlStreamReader &xml)
|
||||
break;
|
||||
}
|
||||
|
||||
if (xml.name() == "set") {
|
||||
auto name = xml.name().toString();
|
||||
if (name == "set") {
|
||||
QString shortName, longName, setType;
|
||||
QDate releaseDate;
|
||||
while (!xml.atEnd()) {
|
||||
if (xml.readNext() == QXmlStreamReader::EndElement) {
|
||||
break;
|
||||
}
|
||||
name = xml.name().toString();
|
||||
|
||||
if (xml.name() == "name") {
|
||||
if (name == "name") {
|
||||
shortName = xml.readElementText(QXmlStreamReader::IncludeChildElements);
|
||||
} else if (xml.name() == "longname") {
|
||||
} else if (name == "longname") {
|
||||
longName = xml.readElementText(QXmlStreamReader::IncludeChildElements);
|
||||
} else if (xml.name() == "settype") {
|
||||
} else if (name == "settype") {
|
||||
setType = xml.readElementText(QXmlStreamReader::IncludeChildElements);
|
||||
} else if (xml.name() == "releasedate") {
|
||||
} else if (name == "releasedate") {
|
||||
releaseDate =
|
||||
QDate::fromString(xml.readElementText(QXmlStreamReader::IncludeChildElements), Qt::ISODate);
|
||||
} else if (xml.name() != "") {
|
||||
qDebug() << "[CockatriceXml3Parser] Unknown set property" << xml.name()
|
||||
<< ", trying to continue anyway";
|
||||
} else if (!name.isEmpty()) {
|
||||
qDebug() << "[CockatriceXml3Parser] Unknown set property" << name << ", trying to continue anyway";
|
||||
xml.skipCurrentElement();
|
||||
}
|
||||
}
|
||||
@@ -146,7 +148,8 @@ void CockatriceXml3Parser::loadCardsFromXml(QXmlStreamReader &xml)
|
||||
break;
|
||||
}
|
||||
|
||||
if (xml.name() == "card") {
|
||||
auto xmlName = xml.name().toString();
|
||||
if (xmlName == "card") {
|
||||
QString name = QString("");
|
||||
QString text = QString("");
|
||||
QVariantHash properties = QVariantHash();
|
||||
@@ -162,37 +165,39 @@ void CockatriceXml3Parser::loadCardsFromXml(QXmlStreamReader &xml)
|
||||
if (xml.readNext() == QXmlStreamReader::EndElement) {
|
||||
break;
|
||||
}
|
||||
xmlName = xml.name().toString();
|
||||
|
||||
// variable - assigned properties
|
||||
if (xml.name() == "name") {
|
||||
if (xmlName == "name") {
|
||||
name = xml.readElementText(QXmlStreamReader::IncludeChildElements);
|
||||
} else if (xml.name() == "text") {
|
||||
} else if (xmlName == "text") {
|
||||
text = xml.readElementText(QXmlStreamReader::IncludeChildElements);
|
||||
} else if (xml.name() == "color") {
|
||||
} else if (xmlName == "color") {
|
||||
colors.append(xml.readElementText(QXmlStreamReader::IncludeChildElements));
|
||||
} else if (xml.name() == "token") {
|
||||
} else if (xmlName == "token") {
|
||||
isToken = static_cast<bool>(xml.readElementText(QXmlStreamReader::IncludeChildElements).toInt());
|
||||
// generic properties
|
||||
} else if (xml.name() == "manacost") {
|
||||
} else if (xmlName == "manacost") {
|
||||
properties.insert("manacost", xml.readElementText(QXmlStreamReader::IncludeChildElements));
|
||||
} else if (xml.name() == "cmc") {
|
||||
} else if (xmlName == "cmc") {
|
||||
properties.insert("cmc", xml.readElementText(QXmlStreamReader::IncludeChildElements));
|
||||
} else if (xml.name() == "type") {
|
||||
} else if (xmlName == "type") {
|
||||
QString type = xml.readElementText(QXmlStreamReader::IncludeChildElements);
|
||||
properties.insert("type", type);
|
||||
properties.insert("maintype", getMainCardType(type));
|
||||
} else if (xml.name() == "pt") {
|
||||
} else if (xmlName == "pt") {
|
||||
properties.insert("pt", xml.readElementText(QXmlStreamReader::IncludeChildElements));
|
||||
} else if (xml.name() == "loyalty") {
|
||||
} else if (xmlName == "loyalty") {
|
||||
properties.insert("loyalty", xml.readElementText(QXmlStreamReader::IncludeChildElements));
|
||||
// positioning info
|
||||
} else if (xml.name() == "tablerow") {
|
||||
} else if (xmlName == "tablerow") {
|
||||
tableRow = xml.readElementText(QXmlStreamReader::IncludeChildElements).toInt();
|
||||
} else if (xml.name() == "cipt") {
|
||||
} else if (xmlName == "cipt") {
|
||||
cipt = (xml.readElementText(QXmlStreamReader::IncludeChildElements) == "1");
|
||||
} else if (xml.name() == "upsidedown") {
|
||||
} else if (xmlName == "upsidedown") {
|
||||
upsideDown = (xml.readElementText(QXmlStreamReader::IncludeChildElements) == "1");
|
||||
// sets
|
||||
} else if (xml.name() == "set") {
|
||||
} else if (xmlName == "set") {
|
||||
// NOTE: attributes must be read before readElementText()
|
||||
QXmlStreamAttributes attrs = xml.attributes();
|
||||
QString setName = xml.readElementText(QXmlStreamReader::IncludeChildElements);
|
||||
@@ -217,8 +222,8 @@ void CockatriceXml3Parser::loadCardsFromXml(QXmlStreamReader &xml)
|
||||
setInfo.setProperty("rarity", attrs.value("rarity").toString());
|
||||
}
|
||||
sets.insert(setName, setInfo);
|
||||
// relatd cards
|
||||
} else if (xml.name() == "related" || xml.name() == "reverse-related") {
|
||||
// related cards
|
||||
} else if (xmlName == "related" || xmlName == "reverse-related") {
|
||||
bool attach = false;
|
||||
bool exclude = false;
|
||||
bool variable = false;
|
||||
@@ -249,13 +254,13 @@ void CockatriceXml3Parser::loadCardsFromXml(QXmlStreamReader &xml)
|
||||
}
|
||||
|
||||
auto *relation = new CardRelation(cardName, attach, exclude, variable, count);
|
||||
if (xml.name() == "reverse-related") {
|
||||
if (xmlName == "reverse-related") {
|
||||
reverseRelatedCards << relation;
|
||||
} else {
|
||||
relatedCards << relation;
|
||||
}
|
||||
} else if (xml.name() != "") {
|
||||
qDebug() << "[CockatriceXml3Parser] Unknown card property" << xml.name()
|
||||
} else if (!xmlName.isEmpty()) {
|
||||
qDebug() << "[CockatriceXml3Parser] Unknown card property" << xmlName
|
||||
<< ", trying to continue anyway";
|
||||
xml.skipCurrentElement();
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ bool CockatriceXml4Parser::getCanParseFile(const QString &fileName, QIODevice &d
|
||||
QXmlStreamReader xml(&device);
|
||||
while (!xml.atEnd()) {
|
||||
if (xml.readNext() == QXmlStreamReader::StartElement) {
|
||||
if (xml.name() == COCKATRICE_XML4_TAGNAME) {
|
||||
if (xml.name().toString() == COCKATRICE_XML4_TAGNAME) {
|
||||
int version = xml.attributes().value("version").toString().toInt();
|
||||
if (version == COCKATRICE_XML4_TAGVER) {
|
||||
return true;
|
||||
@@ -52,12 +52,13 @@ void CockatriceXml4Parser::parseFile(QIODevice &device)
|
||||
break;
|
||||
}
|
||||
|
||||
if (xml.name() == "sets") {
|
||||
auto xmlName = xml.name().toString();
|
||||
if (xmlName == "sets") {
|
||||
loadSetsFromXml(xml);
|
||||
} else if (xml.name() == "cards") {
|
||||
} else if (xmlName == "cards") {
|
||||
loadCardsFromXml(xml);
|
||||
} else if (xml.name() != "") {
|
||||
qDebug() << "[CockatriceXml4Parser] Unknown item" << xml.name() << ", trying to continue anyway";
|
||||
} else if (!xmlName.isEmpty()) {
|
||||
qDebug() << "[CockatriceXml4Parser] Unknown item" << xmlName << ", trying to continue anyway";
|
||||
xml.skipCurrentElement();
|
||||
}
|
||||
}
|
||||
@@ -72,25 +73,27 @@ void CockatriceXml4Parser::loadSetsFromXml(QXmlStreamReader &xml)
|
||||
break;
|
||||
}
|
||||
|
||||
if (xml.name() == "set") {
|
||||
auto xmlName = xml.name().toString();
|
||||
if (xmlName == "set") {
|
||||
QString shortName, longName, setType;
|
||||
QDate releaseDate;
|
||||
while (!xml.atEnd()) {
|
||||
if (xml.readNext() == QXmlStreamReader::EndElement) {
|
||||
break;
|
||||
}
|
||||
xmlName = xml.name().toString();
|
||||
|
||||
if (xml.name() == "name") {
|
||||
if (xmlName == "name") {
|
||||
shortName = xml.readElementText(QXmlStreamReader::IncludeChildElements);
|
||||
} else if (xml.name() == "longname") {
|
||||
} else if (xmlName == "longname") {
|
||||
longName = xml.readElementText(QXmlStreamReader::IncludeChildElements);
|
||||
} else if (xml.name() == "settype") {
|
||||
} else if (xmlName == "settype") {
|
||||
setType = xml.readElementText(QXmlStreamReader::IncludeChildElements);
|
||||
} else if (xml.name() == "releasedate") {
|
||||
} else if (xmlName == "releasedate") {
|
||||
releaseDate =
|
||||
QDate::fromString(xml.readElementText(QXmlStreamReader::IncludeChildElements), Qt::ISODate);
|
||||
} else if (xml.name() != "") {
|
||||
qDebug() << "[CockatriceXml4Parser] Unknown set property" << xml.name()
|
||||
} else if (!xmlName.isEmpty()) {
|
||||
qDebug() << "[CockatriceXml4Parser] Unknown set property" << xmlName
|
||||
<< ", trying to continue anyway";
|
||||
xml.skipCurrentElement();
|
||||
}
|
||||
@@ -109,8 +112,9 @@ QVariantHash CockatriceXml4Parser::loadCardPropertiesFromXml(QXmlStreamReader &x
|
||||
break;
|
||||
}
|
||||
|
||||
if (xml.name() != "") {
|
||||
properties.insert(xml.name().toString(), xml.readElementText(QXmlStreamReader::IncludeChildElements));
|
||||
auto xmlName = xml.name().toString();
|
||||
if (!xmlName.isEmpty()) {
|
||||
properties.insert(xmlName, xml.readElementText(QXmlStreamReader::IncludeChildElements));
|
||||
}
|
||||
}
|
||||
return properties;
|
||||
@@ -123,7 +127,9 @@ void CockatriceXml4Parser::loadCardsFromXml(QXmlStreamReader &xml)
|
||||
break;
|
||||
}
|
||||
|
||||
if (xml.name() == "card") {
|
||||
auto xmlName = xml.name().toString();
|
||||
|
||||
if (xmlName == "card") {
|
||||
QString name = QString("");
|
||||
QString text = QString("");
|
||||
QVariantHash properties = QVariantHash();
|
||||
@@ -138,25 +144,28 @@ void CockatriceXml4Parser::loadCardsFromXml(QXmlStreamReader &xml)
|
||||
if (xml.readNext() == QXmlStreamReader::EndElement) {
|
||||
break;
|
||||
}
|
||||
|
||||
xmlName = xml.name().toString();
|
||||
|
||||
// variable - assigned properties
|
||||
if (xml.name() == "name") {
|
||||
if (xmlName == "name") {
|
||||
name = xml.readElementText(QXmlStreamReader::IncludeChildElements);
|
||||
} else if (xml.name() == "text") {
|
||||
} else if (xmlName == "text") {
|
||||
text = xml.readElementText(QXmlStreamReader::IncludeChildElements);
|
||||
} else if (xml.name() == "token") {
|
||||
} else if (xmlName == "token") {
|
||||
isToken = static_cast<bool>(xml.readElementText(QXmlStreamReader::IncludeChildElements).toInt());
|
||||
// generic properties
|
||||
} else if (xml.name() == "prop") {
|
||||
} else if (xmlName == "prop") {
|
||||
properties = loadCardPropertiesFromXml(xml);
|
||||
// positioning info
|
||||
} else if (xml.name() == "tablerow") {
|
||||
} else if (xmlName == "tablerow") {
|
||||
tableRow = xml.readElementText(QXmlStreamReader::IncludeChildElements).toInt();
|
||||
} else if (xml.name() == "cipt") {
|
||||
} else if (xmlName == "cipt") {
|
||||
cipt = (xml.readElementText(QXmlStreamReader::IncludeChildElements) == "1");
|
||||
} else if (xml.name() == "upsidedown") {
|
||||
} else if (xmlName == "upsidedown") {
|
||||
upsideDown = (xml.readElementText(QXmlStreamReader::IncludeChildElements) == "1");
|
||||
// sets
|
||||
} else if (xml.name() == "set") {
|
||||
} else if (xmlName == "set") {
|
||||
// NOTE: attributes but be read before readElementText()
|
||||
QXmlStreamAttributes attrs = xml.attributes();
|
||||
QString setName = xml.readElementText(QXmlStreamReader::IncludeChildElements);
|
||||
@@ -171,8 +180,8 @@ void CockatriceXml4Parser::loadCardsFromXml(QXmlStreamReader &xml)
|
||||
}
|
||||
sets.insert(setName, setInfo);
|
||||
}
|
||||
// relatd cards
|
||||
} else if (xml.name() == "related" || xml.name() == "reverse-related") {
|
||||
// related cards
|
||||
} else if (xmlName == "related" || xmlName == "reverse-related") {
|
||||
bool attach = false;
|
||||
bool exclude = false;
|
||||
bool variable = false;
|
||||
@@ -203,13 +212,13 @@ void CockatriceXml4Parser::loadCardsFromXml(QXmlStreamReader &xml)
|
||||
}
|
||||
|
||||
auto *relation = new CardRelation(cardName, attach, exclude, variable, count);
|
||||
if (xml.name() == "reverse-related") {
|
||||
if (xmlName == "reverse-related") {
|
||||
reverseRelatedCards << relation;
|
||||
} else {
|
||||
relatedCards << relation;
|
||||
}
|
||||
} else if (xml.name() != "") {
|
||||
qDebug() << "[CockatriceXml4Parser] Unknown card property" << xml.name()
|
||||
} else if (!xmlName.isEmpty()) {
|
||||
qDebug() << "[CockatriceXml4Parser] Unknown card property" << xmlName
|
||||
<< ", trying to continue anyway";
|
||||
xml.skipCurrentElement();
|
||||
}
|
||||
|
||||
@@ -6,13 +6,9 @@
|
||||
#include "main.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <utility>
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 13, 0))
|
||||
#include <QScreen>
|
||||
#else
|
||||
#include <QDesktopWidget>
|
||||
#endif
|
||||
#include <QVBoxLayout>
|
||||
#include <utility>
|
||||
|
||||
CardInfoWidget::CardInfoWidget(const QString &cardName, QWidget *parent, Qt::WindowFlags flags)
|
||||
: QFrame(parent, flags), aspectRatio((qreal)CARD_HEIGHT / (qreal)CARD_WIDTH), info(nullptr)
|
||||
@@ -34,12 +30,7 @@ CardInfoWidget::CardInfoWidget(const QString &cardName, QWidget *parent, Qt::Win
|
||||
|
||||
setFrameStyle(QFrame::Panel | QFrame::Raised);
|
||||
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 13, 0))
|
||||
int pixmapHeight = qApp->primaryScreen()->geometry().height() / 3;
|
||||
#else
|
||||
QDesktopWidget desktopWidget;
|
||||
int pixmapHeight = desktopWidget.screenGeometry().height() / 3;
|
||||
#endif
|
||||
int pixmapHeight = QGuiApplication::primaryScreen()->geometry().height() / 3;
|
||||
int pixmapWidth = static_cast<int>(pixmapHeight / aspectRatio);
|
||||
pic->setFixedWidth(pixmapWidth);
|
||||
pic->setFixedHeight(pixmapHeight);
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#define CARDITEM_H
|
||||
|
||||
#include "abstractcarditem.h"
|
||||
#include "server_card.h"
|
||||
|
||||
class CardDatabase;
|
||||
class CardDragItem;
|
||||
@@ -130,7 +131,7 @@ public:
|
||||
}
|
||||
void removeAttachedCard(CardItem *card)
|
||||
{
|
||||
attachedCards.removeAt(attachedCards.indexOf(card));
|
||||
attachedCards.removeOne(card);
|
||||
}
|
||||
const QList<CardItem *> &getAttachedCards() const
|
||||
{
|
||||
|
||||
@@ -187,7 +187,7 @@ CardItem *CardZone::takeCard(int position, int cardId, bool /*canResize*/)
|
||||
|
||||
void CardZone::removeCard(CardItem *card)
|
||||
{
|
||||
cards.removeAt(cards.indexOf(card));
|
||||
cards.removeOne(card);
|
||||
reorganizeCards();
|
||||
emit cardCountChanged();
|
||||
player->deleteCard(card);
|
||||
|
||||
@@ -12,8 +12,6 @@
|
||||
#include <QDesktopServices>
|
||||
#include <QMouseEvent>
|
||||
#include <QScrollBar>
|
||||
#include <QTextDocumentFragment>
|
||||
#include <QTextEdit>
|
||||
|
||||
const QColor DEFAULT_MENTION_COLOR = QColor(194, 31, 47);
|
||||
|
||||
@@ -323,7 +321,7 @@ void ChatView::checkTag(QTextCursor &cursor, QString &message)
|
||||
|
||||
void ChatView::checkMention(QTextCursor &cursor, QString &message, const QString &userName, UserLevelFlags userLevel)
|
||||
{
|
||||
const QRegExp notALetterOrNumber = QRegExp("[^a-zA-Z0-9]");
|
||||
const static auto notALetterOrNumber = QRegularExpression("[^a-zA-Z0-9]");
|
||||
|
||||
int firstSpace = message.indexOf(' ');
|
||||
QString fullMentionUpToSpaceOrEnd = (firstSpace == -1) ? message.mid(1) : message.mid(1, firstSpace - 1);
|
||||
@@ -512,7 +510,11 @@ void ChatView::redactMessages(const QString &userName, int amount)
|
||||
}
|
||||
}
|
||||
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
||||
void ChatView::enterEvent(QEnterEvent * /*event*/)
|
||||
#else
|
||||
void ChatView::enterEvent(QEvent * /*event*/)
|
||||
#endif
|
||||
{
|
||||
setMouseTracking(true);
|
||||
}
|
||||
@@ -568,7 +570,11 @@ void ChatView::mousePressEvent(QMouseEvent *event)
|
||||
switch (hoveredItemType) {
|
||||
case HoveredCard: {
|
||||
if ((event->button() == Qt::MiddleButton) || (event->button() == Qt::LeftButton))
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
||||
emit showCardInfoPopup(event->globalPosition().toPoint(), hoveredContent);
|
||||
#else
|
||||
emit showCardInfoPopup(event->globalPos(), hoveredContent);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case HoveredUser: {
|
||||
@@ -578,7 +584,11 @@ void ChatView::mousePressEvent(QMouseEvent *event)
|
||||
switch (event->button()) {
|
||||
case Qt::RightButton: {
|
||||
UserLevelFlags userLevel(hoveredContent.left(delimiterIndex).toInt());
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
||||
userContextMenu->showContextMenu(event->globalPosition().toPoint(), userName, userLevel, this);
|
||||
#else
|
||||
userContextMenu->showContextMenu(event->globalPos(), userName, userLevel, this);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case Qt::LeftButton: {
|
||||
|
||||
@@ -103,7 +103,11 @@ public:
|
||||
void redactMessages(const QString &userName, int amount);
|
||||
|
||||
protected:
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
||||
void enterEvent(QEnterEvent *event);
|
||||
#else
|
||||
void enterEvent(QEvent *event);
|
||||
#endif
|
||||
void leaveEvent(QEvent *event);
|
||||
void mouseMoveEvent(QMouseEvent *event);
|
||||
void mousePressEvent(QMouseEvent *event);
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
#include "customlineedit.h"
|
||||
|
||||
#include "settingscache.h"
|
||||
@@ -38,8 +37,8 @@ bool LineEditUnfocusable::isUnfocusShortcut(QKeyEvent *event)
|
||||
QKeySequence key(modifier + keyNoMod);
|
||||
QList<QKeySequence> unfocusShortcut = SettingsCache::instance().shortcuts().getShortcut("Textbox/unfocusTextBox");
|
||||
|
||||
for (QList<QKeySequence>::iterator i = unfocusShortcut.begin(); i != unfocusShortcut.end(); ++i) {
|
||||
if (key.matches(*i) == QKeySequence::ExactMatch)
|
||||
for (const auto &unfocusKey : unfocusShortcut) {
|
||||
if (key.matches(unfocusKey) == QKeySequence::ExactMatch)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -12,12 +12,13 @@ class QString;
|
||||
// shortcuts and other shortcuts
|
||||
class LineEditUnfocusable : public QLineEdit
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
LineEditUnfocusable(QWidget *parent = nullptr);
|
||||
LineEditUnfocusable(const QString &contents, QWidget *parent = nullptr);
|
||||
explicit LineEditUnfocusable(QWidget *parent = nullptr);
|
||||
explicit LineEditUnfocusable(const QString &contents, QWidget *parent = nullptr);
|
||||
|
||||
private:
|
||||
bool isUnfocusShortcut(QKeyEvent *key);
|
||||
static bool isUnfocusShortcut(QKeyEvent *key);
|
||||
|
||||
protected:
|
||||
void keyPressEvent(QKeyEvent *event) override;
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
#include <QDebug>
|
||||
#include <QFile>
|
||||
#include <QRegularExpression>
|
||||
#include <QStringList>
|
||||
|
||||
const QStringList DeckLoader::fileNameFilters = QStringList()
|
||||
@@ -208,7 +209,7 @@ void DeckLoader::saveToStream_DeckHeader(QTextStream &out)
|
||||
}
|
||||
|
||||
if (!getComments().isEmpty()) {
|
||||
QStringList commentRows = getComments().split(QRegExp("\n|\r\n|\r"));
|
||||
QStringList commentRows = getComments().split(QRegularExpression("\n|\r\n|\r"));
|
||||
foreach (QString row, commentRows) {
|
||||
out << "// " << row << "\n";
|
||||
}
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
#include <QApplication>
|
||||
#include <QGraphicsSceneMouseEvent>
|
||||
#include <QMouseEvent>
|
||||
#include <QtMath>
|
||||
#include <algorithm>
|
||||
#include <math.h>
|
||||
|
||||
DeckViewCardDragItem::DeckViewCardDragItem(DeckViewCard *_item,
|
||||
const QPointF &_hotSpot,
|
||||
@@ -216,7 +216,7 @@ void DeckViewCardContainer::addCard(DeckViewCard *card)
|
||||
|
||||
void DeckViewCardContainer::removeCard(DeckViewCard *card)
|
||||
{
|
||||
cards.removeAt(cards.indexOf(card));
|
||||
cards.removeOne(card);
|
||||
cardsByType.remove(card->getInfo() ? card->getInfo()->getMainCardType() : "", card);
|
||||
}
|
||||
|
||||
@@ -238,11 +238,9 @@ int DeckViewCardContainer::getCardTypeTextWidth() const
|
||||
QFontMetrics fm(f);
|
||||
|
||||
int maxCardTypeWidth = 0;
|
||||
QMapIterator<QString, DeckViewCard *> i(cardsByType);
|
||||
while (i.hasNext()) {
|
||||
int cardTypeWidth = fm.size(Qt::TextSingleLine, i.next().key()).width();
|
||||
if (cardTypeWidth > maxCardTypeWidth)
|
||||
maxCardTypeWidth = cardTypeWidth;
|
||||
for (const auto &key : cardsByType.keys()) {
|
||||
int cardTypeWidth = fm.size(Qt::TextSingleLine, key).width();
|
||||
maxCardTypeWidth = qMax(maxCardTypeWidth, cardTypeWidth);
|
||||
}
|
||||
|
||||
return maxCardTypeWidth + 15;
|
||||
@@ -440,7 +438,7 @@ void DeckViewScene::rearrangeItems()
|
||||
const int maxRows = rowsAndColsList[maxIndex1][maxIndex2].first;
|
||||
const int maxCardCount = cardCountList[maxIndex1][maxIndex2];
|
||||
rowsAndColsList[maxIndex1][maxIndex2] =
|
||||
QPair<int, int>(maxRows + 1, (int)ceil((qreal)maxCardCount / (qreal)(maxRows + 1)));
|
||||
QPair<int, int>(maxRows + 1, (int)qCeil((qreal)maxCardCount / (qreal)(maxRows + 1)));
|
||||
}
|
||||
|
||||
totalHeight = -spacing;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "dlg_connect.h"
|
||||
|
||||
#include "settingscache.h"
|
||||
#include "stringsizes.h"
|
||||
#include "userconnection_information.h"
|
||||
|
||||
#include <QCheckBox>
|
||||
@@ -39,22 +40,27 @@ DlgConnect::DlgConnect(QWidget *parent) : QDialog(parent)
|
||||
|
||||
saveLabel = new QLabel(tr("Name:"));
|
||||
saveEdit = new QLineEdit;
|
||||
saveEdit->setMaxLength(MAX_NAME_LENGTH);
|
||||
saveLabel->setBuddy(saveEdit);
|
||||
|
||||
hostLabel = new QLabel(tr("&Host:"));
|
||||
hostEdit = new QLineEdit;
|
||||
hostEdit->setMaxLength(MAX_NAME_LENGTH);
|
||||
hostLabel->setBuddy(hostEdit);
|
||||
|
||||
portLabel = new QLabel(tr("&Port:"));
|
||||
portEdit = new QLineEdit;
|
||||
portEdit->setValidator(new QIntValidator(0, 0xffff, portEdit));
|
||||
portLabel->setBuddy(portEdit);
|
||||
|
||||
playernameLabel = new QLabel(tr("Player &name:"));
|
||||
playernameEdit = new QLineEdit;
|
||||
playernameEdit->setMaxLength(MAX_NAME_LENGTH);
|
||||
playernameLabel->setBuddy(playernameEdit);
|
||||
|
||||
passwordLabel = new QLabel(tr("P&assword:"));
|
||||
passwordEdit = new QLineEdit;
|
||||
passwordEdit->setMaxLength(MAX_NAME_LENGTH);
|
||||
passwordLabel->setBuddy(passwordEdit);
|
||||
passwordEdit->setEchoMode(QLineEdit::Password);
|
||||
|
||||
@@ -156,8 +162,7 @@ DlgConnect::DlgConnect(QWidget *parent) : QDialog(parent)
|
||||
|
||||
previousHostButton->setChecked(true);
|
||||
|
||||
connect(previousHosts, SIGNAL(currentIndexChanged(const QString &)), this,
|
||||
SLOT(updateDisplayInfo(const QString &)));
|
||||
connect(previousHosts, SIGNAL(currentTextChanged(const QString &)), this, SLOT(updateDisplayInfo(const QString &)));
|
||||
|
||||
playernameEdit->setFocus();
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "decklist.h"
|
||||
#include "main.h"
|
||||
#include "settingscache.h"
|
||||
#include "stringsizes.h"
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QCloseEvent>
|
||||
@@ -28,6 +29,7 @@ DlgCreateToken::DlgCreateToken(const QStringList &_predefinedTokens, QWidget *pa
|
||||
|
||||
nameLabel = new QLabel(tr("&Name:"));
|
||||
nameEdit = new QLineEdit(tr("Token"));
|
||||
nameEdit->setMaxLength(MAX_NAME_LENGTH);
|
||||
nameEdit->selectAll();
|
||||
connect(nameEdit, SIGNAL(textChanged(const QString &)), this, SLOT(updateSearch(const QString &)));
|
||||
nameLabel->setBuddy(nameEdit);
|
||||
@@ -45,10 +47,12 @@ DlgCreateToken::DlgCreateToken(const QStringList &_predefinedTokens, QWidget *pa
|
||||
|
||||
ptLabel = new QLabel(tr("&P/T:"));
|
||||
ptEdit = new QLineEdit;
|
||||
ptEdit->setMaxLength(MAX_NAME_LENGTH);
|
||||
ptLabel->setBuddy(ptEdit);
|
||||
|
||||
annotationLabel = new QLabel(tr("&Annotation:"));
|
||||
annotationEdit = new QLineEdit;
|
||||
annotationEdit->setMaxLength(MAX_NAME_LENGTH);
|
||||
annotationLabel->setBuddy(annotationEdit);
|
||||
|
||||
destroyCheckBox = new QCheckBox(tr("&Destroy token when it leaves the table"));
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "pb/serverinfo_game.pb.h"
|
||||
#include "pending_command.h"
|
||||
#include "settingscache.h"
|
||||
#include "stringsizes.h"
|
||||
#include "tab_room.h"
|
||||
|
||||
#include <QApplication>
|
||||
@@ -24,8 +25,8 @@ void DlgCreateGame::sharedCtor()
|
||||
rememberGameSettings = new QCheckBox(tr("Re&member settings"));
|
||||
descriptionLabel = new QLabel(tr("&Description:"));
|
||||
descriptionEdit = new QLineEdit;
|
||||
descriptionEdit->setMaxLength(MAX_NAME_LENGTH);
|
||||
descriptionLabel->setBuddy(descriptionEdit);
|
||||
descriptionEdit->setMaxLength(60);
|
||||
|
||||
maxPlayersLabel = new QLabel(tr("P&layers:"));
|
||||
maxPlayersEdit = new QSpinBox();
|
||||
@@ -57,6 +58,7 @@ void DlgCreateGame::sharedCtor()
|
||||
|
||||
passwordLabel = new QLabel(tr("&Password:"));
|
||||
passwordEdit = new QLineEdit;
|
||||
passwordEdit->setMaxLength(MAX_NAME_LENGTH);
|
||||
passwordLabel->setBuddy(passwordEdit);
|
||||
|
||||
onlyBuddiesCheckBox = new QCheckBox(tr("Only &buddies can join"));
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#include "dlg_edit_avatar.h"
|
||||
|
||||
#include "stringsizes.h"
|
||||
|
||||
#include <QBuffer>
|
||||
#include <QDebug>
|
||||
#include <QDialogButtonBox>
|
||||
@@ -72,9 +74,15 @@ QByteArray DlgEditAvatar::getImage()
|
||||
return QByteArray();
|
||||
}
|
||||
|
||||
QByteArray ba;
|
||||
QBuffer buffer(&ba);
|
||||
buffer.open(QIODevice::WriteOnly);
|
||||
image.save(&buffer, "JPG");
|
||||
return ba;
|
||||
for (;;) {
|
||||
QByteArray ba;
|
||||
QBuffer buffer(&ba);
|
||||
buffer.open(QIODevice::WriteOnly);
|
||||
image.save(&buffer, "JPG");
|
||||
if (ba.length() > MAX_FILE_LENGTH) {
|
||||
image = image.scaledToWidth(image.width() / 2); // divide the amount of pixels in four to get the size down
|
||||
} else {
|
||||
return ba;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "dlg_edit_password.h"
|
||||
|
||||
#include "settingscache.h"
|
||||
#include "stringsizes.h"
|
||||
|
||||
#include <QDialogButtonBox>
|
||||
#include <QGridLayout>
|
||||
@@ -12,6 +13,7 @@ DlgEditPassword::DlgEditPassword(QWidget *parent) : QDialog(parent)
|
||||
{
|
||||
oldPasswordLabel = new QLabel(tr("Old password:"));
|
||||
oldPasswordEdit = new QLineEdit();
|
||||
oldPasswordEdit->setMaxLength(MAX_NAME_LENGTH);
|
||||
|
||||
auto &servers = SettingsCache::instance().servers();
|
||||
if (servers.getSavePassword()) {
|
||||
@@ -23,11 +25,13 @@ DlgEditPassword::DlgEditPassword(QWidget *parent) : QDialog(parent)
|
||||
|
||||
newPasswordLabel = new QLabel(tr("New password:"));
|
||||
newPasswordEdit = new QLineEdit();
|
||||
newPasswordEdit->setMaxLength(MAX_NAME_LENGTH);
|
||||
newPasswordLabel->setBuddy(newPasswordLabel);
|
||||
newPasswordEdit->setEchoMode(QLineEdit::Password);
|
||||
|
||||
newPasswordLabel2 = new QLabel(tr("Confirm new password:"));
|
||||
newPasswordEdit2 = new QLineEdit();
|
||||
newPasswordEdit2->setMaxLength(MAX_NAME_LENGTH);
|
||||
newPasswordLabel2->setBuddy(newPasswordLabel2);
|
||||
newPasswordEdit2->setEchoMode(QLineEdit::Password);
|
||||
|
||||
@@ -55,7 +59,11 @@ DlgEditPassword::DlgEditPassword(QWidget *parent) : QDialog(parent)
|
||||
|
||||
void DlgEditPassword::actOk()
|
||||
{
|
||||
if (newPasswordEdit->text() != newPasswordEdit2->text()) {
|
||||
// TODO this stuff should be using qvalidators
|
||||
if (newPasswordEdit->text().length() < 8) {
|
||||
QMessageBox::critical(this, tr("Error"), tr("Your password is too short."));
|
||||
return;
|
||||
} else if (newPasswordEdit->text() != newPasswordEdit2->text()) {
|
||||
QMessageBox::warning(this, tr("Error"), tr("The new passwords don't match."));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
|
||||
#include "carddatabase.h"
|
||||
#include "carddatabasemodel.h"
|
||||
#include "gettextwithmax.h"
|
||||
#include "main.h"
|
||||
#include "stringsizes.h"
|
||||
|
||||
#include <QAction>
|
||||
#include <QComboBox>
|
||||
@@ -23,6 +25,7 @@ DlgEditTokens::DlgEditTokens(QWidget *parent) : QDialog(parent), currentCard(nul
|
||||
{
|
||||
nameLabel = new QLabel(tr("&Name:"));
|
||||
nameEdit = new QLineEdit;
|
||||
nameEdit->setMaxLength(MAX_NAME_LENGTH);
|
||||
nameEdit->setEnabled(false);
|
||||
nameLabel->setBuddy(nameEdit);
|
||||
|
||||
@@ -40,11 +43,13 @@ DlgEditTokens::DlgEditTokens(QWidget *parent) : QDialog(parent), currentCard(nul
|
||||
|
||||
ptLabel = new QLabel(tr("&P/T:"));
|
||||
ptEdit = new QLineEdit;
|
||||
ptEdit->setMaxLength(MAX_NAME_LENGTH);
|
||||
ptLabel->setBuddy(ptEdit);
|
||||
connect(ptEdit, SIGNAL(textChanged(QString)), this, SLOT(ptChanged(QString)));
|
||||
|
||||
annotationLabel = new QLabel(tr("&Annotation:"));
|
||||
annotationEdit = new QLineEdit;
|
||||
annotationEdit->setMaxLength(MAX_NAME_LENGTH);
|
||||
annotationLabel->setBuddy(annotationEdit);
|
||||
connect(annotationEdit, SIGNAL(textChanged(QString)), this, SLOT(annotationChanged(QString)));
|
||||
|
||||
@@ -142,9 +147,8 @@ void DlgEditTokens::tokenSelectionChanged(const QModelIndex ¤t, const QMod
|
||||
void DlgEditTokens::actAddToken()
|
||||
{
|
||||
QString name;
|
||||
bool askAgain = true;
|
||||
do {
|
||||
name = QInputDialog::getText(this, tr("Add token"), tr("Please enter the name of the token:"));
|
||||
for (;;) {
|
||||
name = getTextWithMax(this, tr("Add token"), tr("Please enter the name of the token:"));
|
||||
if (name.isEmpty())
|
||||
return;
|
||||
if (databaseModel->getDatabase()->getCard(name)) {
|
||||
@@ -152,9 +156,9 @@ void DlgEditTokens::actAddToken()
|
||||
tr("The chosen name conflicts with an existing card or token.\nMake sure to enable "
|
||||
"the 'Token' set in the \"Manage sets\" dialog to display them correctly."));
|
||||
} else {
|
||||
askAgain = false;
|
||||
break;
|
||||
}
|
||||
} while (askAgain);
|
||||
}
|
||||
|
||||
QString setName = CardDatabase::TOKENS_SETNAME;
|
||||
CardInfoPerSetMap sets;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "dlg_edit_user.h"
|
||||
|
||||
#include "settingscache.h"
|
||||
#include "stringsizes.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QDialogButtonBox>
|
||||
@@ -12,6 +13,7 @@ DlgEditUser::DlgEditUser(QWidget *parent, QString email, QString country, QStrin
|
||||
{
|
||||
emailLabel = new QLabel(tr("Email:"));
|
||||
emailEdit = new QLineEdit();
|
||||
emailEdit->setMaxLength(MAX_NAME_LENGTH);
|
||||
emailLabel->setBuddy(emailEdit);
|
||||
emailEdit->setText(email);
|
||||
|
||||
@@ -33,6 +35,7 @@ DlgEditUser::DlgEditUser(QWidget *parent, QString email, QString country, QStrin
|
||||
|
||||
realnameLabel = new QLabel(tr("Real name:"));
|
||||
realnameEdit = new QLineEdit();
|
||||
realnameEdit->setMaxLength(MAX_NAME_LENGTH);
|
||||
realnameLabel->setBuddy(realnameEdit);
|
||||
realnameEdit->setText(realName);
|
||||
|
||||
|
||||
@@ -21,10 +21,6 @@ public:
|
||||
{
|
||||
return emailEdit->text();
|
||||
}
|
||||
int getGender() const
|
||||
{
|
||||
return -1;
|
||||
} // This will return GenderUnknown for protocol purposes.
|
||||
QString getCountry() const
|
||||
{
|
||||
return countryEdit->currentIndex() == 0 ? "" : countryEdit->currentText();
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "dlg_forgotpasswordchallenge.h"
|
||||
|
||||
#include "settingscache.h"
|
||||
#include "stringsizes.h"
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QDebug>
|
||||
@@ -38,18 +39,22 @@ DlgForgotPasswordChallenge::DlgForgotPasswordChallenge(QWidget *parent) : QDialo
|
||||
|
||||
hostLabel = new QLabel(tr("&Host:"));
|
||||
hostEdit = new QLineEdit(lastfphost);
|
||||
hostEdit->setMaxLength(MAX_NAME_LENGTH);
|
||||
hostLabel->setBuddy(hostEdit);
|
||||
|
||||
portLabel = new QLabel(tr("&Port:"));
|
||||
portEdit = new QLineEdit(lastfpport);
|
||||
portEdit->setValidator(new QIntValidator(0, 0xffff, portEdit));
|
||||
portLabel->setBuddy(portEdit);
|
||||
|
||||
playernameLabel = new QLabel(tr("Player &name:"));
|
||||
playernameEdit = new QLineEdit(lastfpplayername);
|
||||
playernameEdit->setMaxLength(MAX_NAME_LENGTH);
|
||||
playernameLabel->setBuddy(playernameEdit);
|
||||
|
||||
emailLabel = new QLabel(tr("Email:"));
|
||||
emailEdit = new QLineEdit();
|
||||
emailEdit->setMaxLength(MAX_NAME_LENGTH);
|
||||
emailLabel->setBuddy(emailLabel);
|
||||
|
||||
if (!servers.getFPHostname().isEmpty() && !servers.getFPPort().isEmpty() && !servers.getFPPlayerName().isEmpty()) {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "dlg_forgotpasswordrequest.h"
|
||||
|
||||
#include "settingscache.h"
|
||||
#include "stringsizes.h"
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QDebug>
|
||||
@@ -31,14 +32,17 @@ DlgForgotPasswordRequest::DlgForgotPasswordRequest(QWidget *parent) : QDialog(pa
|
||||
|
||||
hostLabel = new QLabel(tr("&Host:"));
|
||||
hostEdit = new QLineEdit(lastfphost);
|
||||
hostEdit->setMaxLength(MAX_NAME_LENGTH);
|
||||
hostLabel->setBuddy(hostEdit);
|
||||
|
||||
portLabel = new QLabel(tr("&Port:"));
|
||||
portEdit = new QLineEdit(lastfpport);
|
||||
portEdit->setValidator(new QIntValidator(0, 0xffff, portEdit));
|
||||
portLabel->setBuddy(portEdit);
|
||||
|
||||
playernameLabel = new QLabel(tr("Player &name:"));
|
||||
playernameEdit = new QLineEdit(lastfpplayername);
|
||||
playernameEdit->setMaxLength(MAX_NAME_LENGTH);
|
||||
playernameLabel->setBuddy(playernameEdit);
|
||||
|
||||
QGridLayout *grid = new QGridLayout;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "dlg_forgotpasswordreset.h"
|
||||
|
||||
#include "settingscache.h"
|
||||
#include "stringsizes.h"
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QDebug>
|
||||
@@ -37,27 +38,33 @@ DlgForgotPasswordReset::DlgForgotPasswordReset(QWidget *parent) : QDialog(parent
|
||||
|
||||
hostLabel = new QLabel(tr("&Host:"));
|
||||
hostEdit = new QLineEdit(lastfphost);
|
||||
hostEdit->setMaxLength(MAX_NAME_LENGTH);
|
||||
hostLabel->setBuddy(hostEdit);
|
||||
|
||||
portLabel = new QLabel(tr("&Port:"));
|
||||
portEdit = new QLineEdit(lastfpport);
|
||||
portEdit->setValidator(new QIntValidator(0, 0xffff, portEdit));
|
||||
portLabel->setBuddy(portEdit);
|
||||
|
||||
playernameLabel = new QLabel(tr("Player &name:"));
|
||||
playernameEdit = new QLineEdit(lastfpplayername);
|
||||
playernameEdit->setMaxLength(MAX_NAME_LENGTH);
|
||||
playernameLabel->setBuddy(playernameEdit);
|
||||
|
||||
tokenLabel = new QLabel(tr("Token:"));
|
||||
tokenEdit = new QLineEdit();
|
||||
tokenEdit->setMaxLength(MAX_NAME_LENGTH);
|
||||
tokenLabel->setBuddy(tokenLabel);
|
||||
|
||||
newpasswordLabel = new QLabel(tr("New Password:"));
|
||||
newpasswordEdit = new QLineEdit();
|
||||
newpasswordEdit->setMaxLength(MAX_NAME_LENGTH);
|
||||
newpasswordLabel->setBuddy(newpasswordEdit);
|
||||
newpasswordEdit->setEchoMode(QLineEdit::Password);
|
||||
|
||||
newpasswordverifyLabel = new QLabel(tr("New Password:"));
|
||||
newpasswordverifyEdit = new QLineEdit();
|
||||
newpasswordverifyEdit->setMaxLength(MAX_NAME_LENGTH);
|
||||
newpasswordverifyLabel->setBuddy(newpasswordEdit);
|
||||
newpasswordverifyEdit->setEchoMode(QLineEdit::Password);
|
||||
|
||||
@@ -116,7 +123,11 @@ void DlgForgotPasswordReset::actOk()
|
||||
return;
|
||||
}
|
||||
|
||||
if (newpasswordEdit->text() != newpasswordverifyEdit->text()) {
|
||||
// TODO this stuff should be using qvalidators
|
||||
if (newpasswordEdit->text().length() < 8) {
|
||||
QMessageBox::critical(this, tr("Error"), tr("Your password is too short."));
|
||||
return;
|
||||
} else if (newpasswordEdit->text() != newpasswordverifyEdit->text()) {
|
||||
QMessageBox::critical(this, tr("Reset Password Error"), tr("The passwords do not match."));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -121,7 +121,12 @@ WndSets::WndSets(QWidget *parent) : QMainWindow(parent)
|
||||
connect(disableSomeButton, SIGNAL(clicked()), this, SLOT(actDisableSome()));
|
||||
connect(view->selectionModel(), SIGNAL(selectionChanged(const QItemSelection &, const QItemSelection &)), this,
|
||||
SLOT(actToggleButtons(const QItemSelection &, const QItemSelection &)));
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 12, 0))
|
||||
connect(searchField, SIGNAL(textChanged(const QString &)), displayModel,
|
||||
SLOT(setFilterRegularExpression(const QString &)));
|
||||
#else
|
||||
connect(searchField, SIGNAL(textChanged(const QString &)), displayModel, SLOT(setFilterRegExp(const QString &)));
|
||||
#endif
|
||||
connect(view->header(), SIGNAL(sortIndicatorChanged(int, Qt::SortOrder)), this, SLOT(actDisableSortButtons(int)));
|
||||
connect(searchField, SIGNAL(textChanged(const QString &)), this, SLOT(actDisableResetButton(const QString &)));
|
||||
|
||||
@@ -139,7 +144,6 @@ WndSets::WndSets(QWidget *parent) : QMainWindow(parent)
|
||||
tr("How to use custom card art") + "</a>"));
|
||||
|
||||
QGridLayout *hintsGrid = new QGridLayout;
|
||||
hintsGrid->setMargin(2);
|
||||
hintsGrid->addWidget(labNotes, 0, 0);
|
||||
hintsGroupBox = new QGroupBox(tr("Hints"));
|
||||
hintsGroupBox->setLayout(hintsGrid);
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include "pb/serverinfo_user.pb.h"
|
||||
#include "settingscache.h"
|
||||
#include "stringsizes.h"
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QDebug>
|
||||
@@ -20,32 +21,39 @@ DlgRegister::DlgRegister(QWidget *parent) : QDialog(parent)
|
||||
|
||||
hostLabel = new QLabel(tr("&Host:"));
|
||||
hostEdit = new QLineEdit(servers.getHostname());
|
||||
hostEdit->setMaxLength(MAX_NAME_LENGTH);
|
||||
hostLabel->setBuddy(hostEdit);
|
||||
|
||||
portLabel = new QLabel(tr("&Port:"));
|
||||
portEdit = new QLineEdit(servers.getPort());
|
||||
portEdit->setValidator(new QIntValidator(0, 0xffff, portEdit));
|
||||
portLabel->setBuddy(portEdit);
|
||||
|
||||
playernameLabel = new QLabel(tr("Player &name:"));
|
||||
playernameEdit = new QLineEdit(servers.getPlayerName());
|
||||
playernameEdit->setMaxLength(MAX_NAME_LENGTH);
|
||||
playernameLabel->setBuddy(playernameEdit);
|
||||
|
||||
passwordLabel = new QLabel(tr("P&assword:"));
|
||||
passwordEdit = new QLineEdit();
|
||||
passwordEdit->setMaxLength(MAX_NAME_LENGTH);
|
||||
passwordLabel->setBuddy(passwordEdit);
|
||||
passwordEdit->setEchoMode(QLineEdit::Password);
|
||||
|
||||
passwordConfirmationLabel = new QLabel(tr("Password (again):"));
|
||||
passwordConfirmationEdit = new QLineEdit();
|
||||
passwordConfirmationEdit->setMaxLength(MAX_NAME_LENGTH);
|
||||
passwordConfirmationLabel->setBuddy(passwordConfirmationEdit);
|
||||
passwordConfirmationEdit->setEchoMode(QLineEdit::Password);
|
||||
|
||||
emailLabel = new QLabel(tr("Email:"));
|
||||
emailEdit = new QLineEdit();
|
||||
emailEdit->setMaxLength(MAX_NAME_LENGTH);
|
||||
emailLabel->setBuddy(emailEdit);
|
||||
|
||||
emailConfirmationLabel = new QLabel(tr("Email (again):"));
|
||||
emailConfirmationEdit = new QLineEdit();
|
||||
emailConfirmationEdit->setMaxLength(MAX_NAME_LENGTH);
|
||||
emailConfirmationLabel->setBuddy(emailConfirmationEdit);
|
||||
|
||||
countryLabel = new QLabel(tr("Country:"));
|
||||
@@ -121,6 +129,7 @@ DlgRegister::DlgRegister(QWidget *parent) : QDialog(parent)
|
||||
countryEdit->addItem(QPixmap("theme:countries/er"), "er");
|
||||
countryEdit->addItem(QPixmap("theme:countries/es"), "es");
|
||||
countryEdit->addItem(QPixmap("theme:countries/et"), "et");
|
||||
countryEdit->addItem(QPixmap("theme:countries/eu"), "eu");
|
||||
countryEdit->addItem(QPixmap("theme:countries/fi"), "fi");
|
||||
countryEdit->addItem(QPixmap("theme:countries/fj"), "fj");
|
||||
countryEdit->addItem(QPixmap("theme:countries/fk"), "fk");
|
||||
@@ -296,6 +305,7 @@ DlgRegister::DlgRegister(QWidget *parent) : QDialog(parent)
|
||||
countryEdit->addItem(QPixmap("theme:countries/vu"), "vu");
|
||||
countryEdit->addItem(QPixmap("theme:countries/wf"), "wf");
|
||||
countryEdit->addItem(QPixmap("theme:countries/ws"), "ws");
|
||||
countryEdit->addItem(QPixmap("theme:countries/xk"), "xk");
|
||||
countryEdit->addItem(QPixmap("theme:countries/ye"), "ye");
|
||||
countryEdit->addItem(QPixmap("theme:countries/yt"), "yt");
|
||||
countryEdit->addItem(QPixmap("theme:countries/za"), "za");
|
||||
@@ -308,6 +318,7 @@ DlgRegister::DlgRegister(QWidget *parent) : QDialog(parent)
|
||||
|
||||
realnameLabel = new QLabel(tr("Real name:"));
|
||||
realnameEdit = new QLineEdit();
|
||||
realnameEdit->setMaxLength(MAX_NAME_LENGTH);
|
||||
realnameLabel->setBuddy(realnameEdit);
|
||||
|
||||
QGridLayout *grid = new QGridLayout;
|
||||
@@ -347,7 +358,11 @@ DlgRegister::DlgRegister(QWidget *parent) : QDialog(parent)
|
||||
|
||||
void DlgRegister::actOk()
|
||||
{
|
||||
if (passwordEdit->text() != passwordConfirmationEdit->text()) {
|
||||
// TODO this stuff should be using qvalidators
|
||||
if (passwordEdit->text().length() < 8) {
|
||||
QMessageBox::critical(this, tr("Registration Warning"), tr("Your password is too short."));
|
||||
return;
|
||||
} else if (passwordEdit->text() != passwordConfirmationEdit->text()) {
|
||||
QMessageBox::critical(this, tr("Registration Warning"), tr("Your passwords do not match, please try again."));
|
||||
return;
|
||||
} else if (emailConfirmationEdit->text() != emailEdit->text()) {
|
||||
|
||||
@@ -34,10 +34,6 @@ public:
|
||||
{
|
||||
return emailEdit->text();
|
||||
}
|
||||
int getGender() const
|
||||
{
|
||||
return -1;
|
||||
} // This will return GenderUnknown for the protocol.
|
||||
QString getCountry() const
|
||||
{
|
||||
return countryEdit->currentIndex() == 0 ? "" : countryEdit->currentText();
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "dlg_settings.h"
|
||||
|
||||
#include "carddatabase.h"
|
||||
#include "gettextwithmax.h"
|
||||
#include "main.h"
|
||||
#include "releasechannel.h"
|
||||
#include "sequenceEdit/sequenceedit.h"
|
||||
@@ -16,7 +17,6 @@
|
||||
#include <QComboBox>
|
||||
#include <QDebug>
|
||||
#include <QDesktopServices>
|
||||
#include <QDesktopWidget>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QFileDialog>
|
||||
#include <QGridLayout>
|
||||
@@ -43,18 +43,22 @@
|
||||
|
||||
GeneralSettingsPage::GeneralSettingsPage()
|
||||
{
|
||||
SettingsCache &settings = SettingsCache::instance();
|
||||
QString setLanguage = settings.getLang();
|
||||
QStringList qmFiles = findQmFiles();
|
||||
for (int i = 0; i < qmFiles.size(); i++) {
|
||||
QString langName = languageName(qmFiles[i]);
|
||||
languageBox.addItem(langName, qmFiles[i]);
|
||||
if ((qmFiles[i] == setLanguage) ||
|
||||
(setLanguage.isEmpty() && langName == QCoreApplication::translate("i18n", DEFAULT_LANG_NAME)))
|
||||
languageBox.setCurrentIndex(i);
|
||||
QStringList languageCodes = findQmFiles();
|
||||
for (const QString &code : languageCodes) {
|
||||
QString langName = languageName(code);
|
||||
languageBox.addItem(langName, code);
|
||||
}
|
||||
|
||||
QString setLanguage = QCoreApplication::translate("i18n", DEFAULT_LANG_NAME);
|
||||
int index = languageBox.findText(setLanguage, Qt::MatchExactly);
|
||||
if (index == -1) {
|
||||
qWarning() << "could not find language" << setLanguage;
|
||||
} else {
|
||||
languageBox.setCurrentIndex(index);
|
||||
}
|
||||
|
||||
// updates
|
||||
SettingsCache &settings = SettingsCache::instance();
|
||||
QList<ReleaseChannel *> channels = settings.getUpdateReleaseChannels();
|
||||
foreach (ReleaseChannel *chan, channels) {
|
||||
updateReleaseChannelBox.insertItem(chan->getIndex(), tr(chan->getName().toUtf8()));
|
||||
@@ -76,12 +80,9 @@ GeneralSettingsPage::GeneralSettingsPage()
|
||||
|
||||
connect(&languageBox, SIGNAL(currentIndexChanged(int)), this, SLOT(languageBoxChanged(int)));
|
||||
connect(&pixmapCacheEdit, SIGNAL(valueChanged(int)), &settings, SLOT(setPixmapCacheSize(int)));
|
||||
connect(&updateReleaseChannelBox, SIGNAL(currentIndexChanged(int)), &settings,
|
||||
SLOT(setUpdateReleaseChannel(int)));
|
||||
connect(&updateNotificationCheckBox, SIGNAL(stateChanged(int)), &settings,
|
||||
SLOT(setNotifyAboutUpdate(int)));
|
||||
connect(&newVersionOracleCheckBox, SIGNAL(stateChanged(int)), &settings,
|
||||
SLOT(setNotifyAboutNewVersion(int)));
|
||||
connect(&updateReleaseChannelBox, SIGNAL(currentIndexChanged(int)), &settings, SLOT(setUpdateReleaseChannel(int)));
|
||||
connect(&updateNotificationCheckBox, SIGNAL(stateChanged(int)), &settings, SLOT(setNotifyAboutUpdate(int)));
|
||||
connect(&newVersionOracleCheckBox, SIGNAL(stateChanged(int)), &settings, SLOT(setNotifyAboutNewVersion(int)));
|
||||
connect(&showTipsOnStartup, SIGNAL(clicked(bool)), &settings, SLOT(setShowTipsOnStartup(bool)));
|
||||
|
||||
auto *personalGrid = new QGridLayout;
|
||||
@@ -179,6 +180,7 @@ GeneralSettingsPage::GeneralSettingsPage()
|
||||
auto *mainLayout = new QVBoxLayout;
|
||||
mainLayout->addWidget(personalGroupBox);
|
||||
mainLayout->addWidget(pathsGroupBox);
|
||||
mainLayout->addStretch();
|
||||
|
||||
setLayout(mainLayout);
|
||||
}
|
||||
@@ -187,19 +189,21 @@ QStringList GeneralSettingsPage::findQmFiles()
|
||||
{
|
||||
QDir dir(translationPath);
|
||||
QStringList fileNames = dir.entryList(QStringList(translationPrefix + "_*.qm"), QDir::Files, QDir::Name);
|
||||
fileNames.replaceInStrings(QRegExp(translationPrefix + "_(.*)\\.qm"), "\\1");
|
||||
fileNames.replaceInStrings(QRegularExpression(translationPrefix + "_(.*)\\.qm"), "\\1");
|
||||
return fileNames;
|
||||
}
|
||||
|
||||
QString GeneralSettingsPage::languageName(const QString &qmFile)
|
||||
QString GeneralSettingsPage::languageName(const QString &lang)
|
||||
{
|
||||
if (qmFile == DEFAULT_LANG_CODE)
|
||||
return DEFAULT_LANG_NAME;
|
||||
QTranslator qTranslator;
|
||||
|
||||
QTranslator translator;
|
||||
translator.load(translationPrefix + "_" + qmFile + ".qm", translationPath);
|
||||
QString appNameHint = translationPrefix + "_" + lang;
|
||||
bool appTranslationLoaded = qTranslator.load(appNameHint, translationPath);
|
||||
if (!appTranslationLoaded) {
|
||||
qDebug() << "Unable to load" << translationPrefix << "translation" << appNameHint << "at" << translationPath;
|
||||
}
|
||||
|
||||
return translator.translate("i18n", DEFAULT_LANG_NAME);
|
||||
return qTranslator.translate("i18n", DEFAULT_LANG_NAME);
|
||||
}
|
||||
|
||||
void GeneralSettingsPage::deckPathButtonClicked()
|
||||
@@ -386,6 +390,7 @@ AppearanceSettingsPage::AppearanceSettingsPage()
|
||||
mainLayout->addWidget(cardsGroupBox);
|
||||
mainLayout->addWidget(handGroupBox);
|
||||
mainLayout->addWidget(tableGroupBox);
|
||||
mainLayout->addStretch();
|
||||
|
||||
setLayout(mainLayout);
|
||||
}
|
||||
@@ -493,6 +498,7 @@ UserInterfaceSettingsPage::UserInterfaceSettingsPage()
|
||||
mainLayout->addWidget(generalGroupBox);
|
||||
mainLayout->addWidget(notificationsGroupBox);
|
||||
mainLayout->addWidget(animationGroupBox);
|
||||
mainLayout->addStretch();
|
||||
|
||||
setLayout(mainLayout);
|
||||
}
|
||||
@@ -563,12 +569,15 @@ DeckEditorSettingsPage::DeckEditorSettingsPage()
|
||||
|
||||
auto aAdd = new QAction(this);
|
||||
aAdd->setIcon(QPixmap("theme:icons/increment"));
|
||||
aAdd->setToolTip(tr("Add New URL"));
|
||||
connect(aAdd, SIGNAL(triggered()), this, SLOT(actAddURL()));
|
||||
auto aEdit = new QAction(this);
|
||||
aEdit->setIcon(QPixmap("theme:icons/pencil"));
|
||||
aEdit->setToolTip(tr("Edit URL"));
|
||||
connect(aEdit, SIGNAL(triggered()), this, SLOT(actEditURL()));
|
||||
auto aRemove = new QAction(this);
|
||||
aRemove->setIcon(QPixmap("theme:icons/decrement"));
|
||||
aRemove->setToolTip(tr("Remove URL"));
|
||||
connect(aRemove, SIGNAL(triggered()), this, SLOT(actRemoveURL()));
|
||||
|
||||
auto *messageToolBar = new QToolBar;
|
||||
@@ -856,16 +865,15 @@ MessagesSettingsPage::MessagesSettingsPage()
|
||||
|
||||
aAdd = new QAction(this);
|
||||
aAdd->setIcon(QPixmap("theme:icons/increment"));
|
||||
aAdd->setStatusTip(tr("Add New URL"));
|
||||
|
||||
aAdd->setToolTip(tr("Add New Message"));
|
||||
connect(aAdd, SIGNAL(triggered()), this, SLOT(actAdd()));
|
||||
aEdit = new QAction(this);
|
||||
aEdit->setIcon(QPixmap("theme:icons/pencil"));
|
||||
aEdit->setStatusTip(tr("Edit URL"));
|
||||
aEdit->setToolTip(tr("Edit Message"));
|
||||
connect(aEdit, SIGNAL(triggered()), this, SLOT(actEdit()));
|
||||
aRemove = new QAction(this);
|
||||
aRemove->setIcon(QPixmap("theme:icons/decrement"));
|
||||
aRemove->setStatusTip(tr("Remove URL"));
|
||||
aRemove->setToolTip(tr("Remove Message"));
|
||||
connect(aRemove, SIGNAL(triggered()), this, SLOT(actRemove()));
|
||||
|
||||
auto *messageToolBar = new QToolBar;
|
||||
@@ -949,7 +957,8 @@ void MessagesSettingsPage::storeSettings()
|
||||
void MessagesSettingsPage::actAdd()
|
||||
{
|
||||
bool ok;
|
||||
QString msg = QInputDialog::getText(this, tr("Add message"), tr("Message:"), QLineEdit::Normal, QString(), &ok);
|
||||
QString msg =
|
||||
getTextWithMax(this, tr("Add message"), tr("Message:"), QLineEdit::Normal, QString(), &ok, MAX_TEXT_LENGTH);
|
||||
if (ok) {
|
||||
messageList->addItem(msg);
|
||||
storeSettings();
|
||||
@@ -961,7 +970,8 @@ void MessagesSettingsPage::actEdit()
|
||||
if (messageList->currentItem()) {
|
||||
QString oldText = messageList->currentItem()->text();
|
||||
bool ok;
|
||||
QString msg = QInputDialog::getText(this, tr("Edit message"), tr("Message:"), QLineEdit::Normal, oldText, &ok);
|
||||
QString msg =
|
||||
getTextWithMax(this, tr("Edit message"), tr("Message:"), QLineEdit::Normal, oldText, &ok, MAX_TEXT_LENGTH);
|
||||
if (ok) {
|
||||
messageList->currentItem()->setText(msg);
|
||||
storeSettings();
|
||||
@@ -1043,6 +1053,7 @@ SoundSettingsPage::SoundSettingsPage()
|
||||
|
||||
auto *mainLayout = new QVBoxLayout;
|
||||
mainLayout->addWidget(soundGroupBox);
|
||||
mainLayout->addStretch();
|
||||
|
||||
setLayout(mainLayout);
|
||||
}
|
||||
@@ -1232,13 +1243,8 @@ void ShortcutSettingsPage::retranslateUi()
|
||||
|
||||
DlgSettings::DlgSettings(QWidget *parent) : QDialog(parent)
|
||||
{
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 13, 0))
|
||||
QRect rec = qApp->primaryScreen()->availableGeometry();
|
||||
#else
|
||||
QRect rec = QApplication::desktop()->availableGeometry();
|
||||
#endif
|
||||
this->setMinimumSize(rec.width() / 2, rec.height() - 100);
|
||||
this->setBaseSize(rec.width(), rec.height());
|
||||
auto rec = QGuiApplication::primaryScreen()->availableGeometry();
|
||||
this->setMinimumSize(qMin(700, rec.width()), qMin(700, rec.height()));
|
||||
|
||||
connect(&SettingsCache::instance(), SIGNAL(langChanged()), this, SLOT(updateLanguage()));
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ private slots:
|
||||
|
||||
private:
|
||||
QStringList findQmFiles();
|
||||
QString languageName(const QString &qmFile);
|
||||
QString languageName(const QString &lang);
|
||||
QLineEdit *deckPathEdit;
|
||||
QLineEdit *replaysPathEdit;
|
||||
QLineEdit *picsPathEdit;
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
|
||||
#include <QByteArray>
|
||||
#include <QString>
|
||||
#include <cmath>
|
||||
#include <functional>
|
||||
|
||||
peg::parser search(R"(
|
||||
@@ -337,7 +336,7 @@ static void setupParserRules()
|
||||
|
||||
FilterString::FilterString(const QString &expr)
|
||||
{
|
||||
QByteArray ba = expr.toLocal8Bit();
|
||||
QByteArray ba = expr.simplified().toUtf8();
|
||||
|
||||
std::call_once(init, setupParserRules);
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
#include <QGraphicsSceneMouseEvent>
|
||||
#include <QGraphicsView>
|
||||
#include <QSet>
|
||||
#include <math.h>
|
||||
#include <QtMath>
|
||||
|
||||
GameScene::GameScene(PhasesToolbar *_phasesToolbar, QObject *parent)
|
||||
: QGraphicsScene(parent), phasesToolbar(_phasesToolbar), viewSize(QSize()), playerRotation(0)
|
||||
@@ -53,7 +53,7 @@ void GameScene::removePlayer(Player *player)
|
||||
zone->close();
|
||||
}
|
||||
}
|
||||
players.removeAt(players.indexOf(player));
|
||||
players.removeOne(player);
|
||||
removeItem(player);
|
||||
rearrange();
|
||||
}
|
||||
@@ -97,7 +97,7 @@ void GameScene::rearrange()
|
||||
|
||||
const int playersCount = playersPlaying.size();
|
||||
const int columns = playersCount < SettingsCache::instance().getMinPlayersForMultiColumnLayout() ? 1 : 2;
|
||||
const int rows = ceil((qreal)playersCount / columns);
|
||||
const int rows = qCeil((qreal)playersCount / columns);
|
||||
qreal sceneHeight = 0, sceneWidth = -playerAreaSpacing;
|
||||
QList<int> columnWidth;
|
||||
|
||||
@@ -178,7 +178,7 @@ void GameScene::addRevealedZoneView(Player *player,
|
||||
|
||||
void GameScene::removeZoneView(ZoneViewWidget *item)
|
||||
{
|
||||
zoneViews.removeAt(zoneViews.indexOf(item));
|
||||
zoneViews.removeOne(item);
|
||||
removeItem(item);
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "dlg_creategame.h"
|
||||
#include "dlg_filter_games.h"
|
||||
#include "gamesmodel.h"
|
||||
#include "gettextwithmax.h"
|
||||
#include "pb/response.pb.h"
|
||||
#include "pb/room_commands.pb.h"
|
||||
#include "pb/serverinfo_game.pb.h"
|
||||
@@ -243,7 +244,7 @@ void GameSelector::actJoin()
|
||||
QString password;
|
||||
if (game.with_password() && !(spectator && !game.spectators_need_password()) && !overrideRestrictions) {
|
||||
bool ok;
|
||||
password = QInputDialog::getText(this, tr("Join game"), tr("Password:"), QLineEdit::Password, QString(), &ok);
|
||||
password = getTextWithMax(this, tr("Join game"), tr("Password:"), QLineEdit::Password, QString(), &ok);
|
||||
if (!ok)
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -93,11 +93,7 @@ QVariant GamesModel::data(const QModelIndex &index, int role) const
|
||||
case CREATED: {
|
||||
switch (role) {
|
||||
case Qt::DisplayRole: {
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 8, 0))
|
||||
QDateTime then = QDateTime::fromSecsSinceEpoch(gameentry.start_time(), Qt::UTC);
|
||||
#else
|
||||
QDateTime then = QDateTime::fromTime_t(gameentry.start_time(), Qt::UTC);
|
||||
#endif
|
||||
int secs = then.secsTo(QDateTime::currentDateTimeUtc());
|
||||
return getGameCreatedString(secs);
|
||||
}
|
||||
|
||||
32
cockatrice/src/gettextwithmax.cpp
Normal file
32
cockatrice/src/gettextwithmax.cpp
Normal file
@@ -0,0 +1,32 @@
|
||||
#include "gettextwithmax.h"
|
||||
|
||||
QString getTextWithMax(QWidget *parent,
|
||||
const QString &title,
|
||||
const QString &label,
|
||||
QLineEdit::EchoMode mode,
|
||||
const QString &text,
|
||||
bool *ok,
|
||||
int max,
|
||||
Qt::WindowFlags flags,
|
||||
Qt::InputMethodHints inputMethodHints)
|
||||
{
|
||||
auto *dialog = new QInputDialog(parent, flags);
|
||||
dialog->setWindowTitle(title);
|
||||
dialog->setLabelText(label);
|
||||
dialog->setTextValue(text);
|
||||
dialog->setTextEchoMode(mode);
|
||||
dialog->setInputMethodHints(inputMethodHints);
|
||||
|
||||
// find the qlineedit that this dialog holds, there should be only one
|
||||
dialog->findChild<QLineEdit *>()->setMaxLength(max);
|
||||
|
||||
const int ret = dialog->exec();
|
||||
if (ok != nullptr) {
|
||||
*ok = !!ret;
|
||||
}
|
||||
if (ret) {
|
||||
return dialog->textValue();
|
||||
} else {
|
||||
return QString();
|
||||
}
|
||||
}
|
||||
23
cockatrice/src/gettextwithmax.h
Normal file
23
cockatrice/src/gettextwithmax.h
Normal file
@@ -0,0 +1,23 @@
|
||||
// custom QInputDialog::getText implementation that allows configuration of the max length
|
||||
#ifndef GETTEXTWITHMAX_H
|
||||
#define GETTEXTWITHMAX_H
|
||||
|
||||
#include "stringsizes.h"
|
||||
|
||||
#include <QInputDialog>
|
||||
|
||||
QString getTextWithMax(QWidget *parent,
|
||||
const QString &title,
|
||||
const QString &label,
|
||||
QLineEdit::EchoMode echo = QLineEdit::Normal,
|
||||
const QString &text = QString(),
|
||||
bool *ok = nullptr,
|
||||
int max = MAX_NAME_LENGTH,
|
||||
Qt::WindowFlags flags = Qt::WindowFlags(),
|
||||
Qt::InputMethodHints inputMethodHints = Qt::ImhNone);
|
||||
static inline QString getTextWithMax(QWidget *parent, const QString &title, const QString &label, int max)
|
||||
{
|
||||
return getTextWithMax(parent, title, label, QLineEdit::Normal, QString(), nullptr, max);
|
||||
}
|
||||
|
||||
#endif // GETTEXTWITHMAX_H
|
||||
@@ -24,8 +24,10 @@ void HandZone::updateBg()
|
||||
|
||||
void HandZone::addCardImpl(CardItem *card, int x, int /*y*/)
|
||||
{
|
||||
if (x == -1)
|
||||
// if x is negative set it to add at end
|
||||
if (x < 0 || x >= cards.size()) {
|
||||
x = cards.size();
|
||||
}
|
||||
cards.insert(x, card);
|
||||
|
||||
if (!cards.getContentsKnown()) {
|
||||
|
||||
@@ -12,8 +12,9 @@ LocalServer::LocalServer(QObject *parent) : Server(parent)
|
||||
LocalServer::~LocalServer()
|
||||
{
|
||||
// LocalServer is single threaded so it doesn't need locks on this
|
||||
while (!clients.isEmpty())
|
||||
clients.first()->prepareDestroy();
|
||||
for (auto *client : clients) {
|
||||
client->prepareDestroy();
|
||||
}
|
||||
|
||||
prepareDestroy();
|
||||
}
|
||||
@@ -42,7 +43,8 @@ AuthenticationResult LocalServer_DatabaseInterface::checkUserPassword(Server_Pro
|
||||
const QString & /* password */,
|
||||
const QString & /* clientId */,
|
||||
QString & /* reasonStr */,
|
||||
int & /* secondsLeft */)
|
||||
int & /* banSecondsLeft */,
|
||||
bool /* passwordNeedsHash */)
|
||||
{
|
||||
return UnknownUser;
|
||||
}
|
||||
|
||||
@@ -27,12 +27,14 @@ protected:
|
||||
|
||||
public:
|
||||
LocalServer_DatabaseInterface(LocalServer *_localServer);
|
||||
~LocalServer_DatabaseInterface() = default;
|
||||
AuthenticationResult checkUserPassword(Server_ProtocolHandler *handler,
|
||||
const QString &user,
|
||||
const QString &password,
|
||||
const QString &clientId,
|
||||
QString &reasonStr,
|
||||
int &secondsLeft);
|
||||
int &secondsLeft,
|
||||
bool passwordNeedsHash);
|
||||
int getNextGameId()
|
||||
{
|
||||
return localServer->getNextLocalGameId();
|
||||
|
||||
@@ -67,11 +67,29 @@ void installNewTranslator()
|
||||
{
|
||||
QString lang = SettingsCache::instance().getLang();
|
||||
|
||||
qtTranslator->load("qt_" + lang, QLibraryInfo::location(QLibraryInfo::TranslationsPath));
|
||||
QString qtNameHint = "qt_" + lang;
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
||||
QString qtTranslationPath = QLibraryInfo::path(QLibraryInfo::TranslationsPath);
|
||||
#else
|
||||
QString qtTranslationPath = QLibraryInfo::location(QLibraryInfo::TranslationsPath);
|
||||
#endif
|
||||
|
||||
bool qtTranslationLoaded = qtTranslator->load(qtNameHint, qtTranslationPath);
|
||||
if (!qtTranslationLoaded) {
|
||||
qDebug() << "Unable to load qt translation" << qtNameHint << "at" << qtTranslationPath;
|
||||
} else {
|
||||
qDebug() << "Loaded qt translation" << qtNameHint << "at" << qtTranslationPath;
|
||||
}
|
||||
qApp->installTranslator(qtTranslator);
|
||||
translator->load(translationPrefix + "_" + lang, translationPath);
|
||||
|
||||
QString appNameHint = translationPrefix + "_" + lang;
|
||||
bool appTranslationLoaded = qtTranslator->load(appNameHint, translationPath);
|
||||
if (!appTranslationLoaded) {
|
||||
qDebug() << "Unable to load" << translationPrefix << "translation" << appNameHint << "at" << translationPath;
|
||||
} else {
|
||||
qDebug() << "Loaded" << translationPrefix << "translation" << appNameHint << "at" << translationPath;
|
||||
}
|
||||
qApp->installTranslator(translator);
|
||||
qDebug() << "Language changed:" << lang;
|
||||
}
|
||||
|
||||
QString const generateClientID()
|
||||
@@ -165,7 +183,9 @@ int main(int argc, char *argv[])
|
||||
ui.show();
|
||||
qDebug("main(): ui.show() finished");
|
||||
|
||||
#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
|
||||
app.setAttribute(Qt::AA_UseHighDpiPixmaps);
|
||||
#endif
|
||||
app.exec();
|
||||
|
||||
qDebug("Event loop finished, terminating...");
|
||||
|
||||
@@ -1,18 +1,16 @@
|
||||
#include "phasestoolbar.h"
|
||||
|
||||
#include "pb/command_draw_cards.pb.h"
|
||||
#include "pb/command_next_turn.pb.h"
|
||||
#include "pb/command_set_active_phase.pb.h"
|
||||
#include "pb/command_set_card_attr.pb.h"
|
||||
#include "pixmapgenerator.h"
|
||||
|
||||
#include <QAction>
|
||||
#include <QDebug>
|
||||
#include <QPainter>
|
||||
#include <QPen>
|
||||
#include <QTimer>
|
||||
#include <cmath>
|
||||
#ifdef _WIN32
|
||||
#include "round.h"
|
||||
#endif /* _WIN32 */
|
||||
#include "pb/command_draw_cards.pb.h"
|
||||
#include "pb/command_next_turn.pb.h"
|
||||
#include "pb/command_set_active_phase.pb.h"
|
||||
#include "pb/command_set_card_attr.pb.h"
|
||||
#include "phasestoolbar.h"
|
||||
#include "pixmapgenerator.h"
|
||||
|
||||
PhaseButton::PhaseButton(const QString &_name, QGraphicsItem *parent, QAction *_doubleClickAction, bool _highlightable)
|
||||
: QObject(), QGraphicsItem(parent), name(_name), active(false), highlightable(_highlightable),
|
||||
@@ -38,8 +36,7 @@ void PhaseButton::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*op
|
||||
QRectF iconRect = boundingRect().adjusted(3, 3, -3, -3);
|
||||
QRectF translatedIconRect = painter->combinedTransform().mapRect(iconRect);
|
||||
qreal scaleFactor = translatedIconRect.width() / iconRect.width();
|
||||
QPixmap iconPixmap =
|
||||
PhasePixmapGenerator::generatePixmap(static_cast<int>(round(translatedIconRect.height())), name);
|
||||
QPixmap iconPixmap = PhasePixmapGenerator::generatePixmap(qRound(translatedIconRect.height()), name);
|
||||
|
||||
painter->setBrush(QColor(static_cast<int>(220 * (activeAnimationCounter / 10.0)),
|
||||
static_cast<int>(220 * (activeAnimationCounter / 10.0)),
|
||||
@@ -48,9 +45,8 @@ void PhaseButton::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*op
|
||||
painter->drawRect(0, 0, static_cast<int>(width - 1), static_cast<int>(width - 1));
|
||||
painter->save();
|
||||
resetPainterTransform(painter);
|
||||
painter->drawPixmap(iconPixmap.rect().translated(static_cast<int>(round(3 * scaleFactor)),
|
||||
static_cast<int>(round(3 * scaleFactor))),
|
||||
iconPixmap, iconPixmap.rect());
|
||||
painter->drawPixmap(iconPixmap.rect().translated(qRound(3 * scaleFactor), qRound(3 * scaleFactor)), iconPixmap,
|
||||
iconPixmap.rect());
|
||||
painter->restore();
|
||||
|
||||
painter->setBrush(QColor(0, 0, 0, static_cast<int>(255 * ((10 - activeAnimationCounter) / 15.0))));
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "thememanager.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QScreen>
|
||||
#include <QCryptographicHash>
|
||||
#include <QDebug>
|
||||
#include <QDir>
|
||||
@@ -572,7 +573,10 @@ void PictureLoader::getPixmap(QPixmap &pixmap, CardInfoPtr card, QSize size)
|
||||
// load the image and create a copy of the correct size
|
||||
QPixmap bigPixmap;
|
||||
if (QPixmapCache::find(key, &bigPixmap)) {
|
||||
pixmap = bigPixmap.scaled(size, Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
||||
QScreen * screen = qApp->primaryScreen();
|
||||
int dpr = screen->devicePixelRatio();
|
||||
pixmap = bigPixmap.scaled(size * dpr, Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
||||
pixmap.setDevicePixelRatio(dpr);
|
||||
QPixmapCache::insert(sizeKey, pixmap);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -44,6 +44,10 @@ void PileZone::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*optio
|
||||
void PileZone::addCardImpl(CardItem *card, int x, int /*y*/)
|
||||
{
|
||||
connect(card, SIGNAL(sigPixmapUpdated()), this, SLOT(callUpdate()));
|
||||
// if x is negative set it to add at end
|
||||
if (x < 0 || x >= cards.size()) {
|
||||
x = cards.size();
|
||||
}
|
||||
cards.insert(x, card);
|
||||
card->setPos(0, 0);
|
||||
if (!contentsKnown()) {
|
||||
|
||||
@@ -3,13 +3,9 @@
|
||||
#include "pb/serverinfo_user.pb.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QDebug>
|
||||
#include <QPainter>
|
||||
#include <QPalette>
|
||||
#include <cmath>
|
||||
#ifdef _WIN32
|
||||
#include "round.h"
|
||||
#endif /* _WIN32 */
|
||||
#include <QDebug>
|
||||
|
||||
QMap<QString, QPixmap> PhasePixmapGenerator::pmCache;
|
||||
|
||||
@@ -78,25 +74,6 @@ QPixmap PingPixmapGenerator::generatePixmap(int size, int value, int max)
|
||||
|
||||
QMap<int, QPixmap> PingPixmapGenerator::pmCache;
|
||||
|
||||
QPixmap GenderPixmapGenerator::generatePixmap(int height)
|
||||
{
|
||||
ServerInfo_User::Gender gender = ServerInfo_User::GenderUnknown;
|
||||
|
||||
int key = gender * 100000 + height;
|
||||
if (pmCache.contains(key))
|
||||
return pmCache.value(key);
|
||||
|
||||
QString genderStr;
|
||||
genderStr = "unknown";
|
||||
|
||||
QPixmap pixmap =
|
||||
QPixmap("theme:genders/" + genderStr).scaled(height, height, Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
||||
pmCache.insert(key, pixmap);
|
||||
return pixmap;
|
||||
}
|
||||
|
||||
QMap<int, QPixmap> GenderPixmapGenerator::pmCache;
|
||||
|
||||
QPixmap CountryPixmapGenerator::generatePixmap(int height, const QString &countryCode)
|
||||
{
|
||||
if (countryCode.size() != 2)
|
||||
@@ -122,7 +99,7 @@ QMap<QString, QPixmap> CountryPixmapGenerator::pmCache;
|
||||
QPixmap UserLevelPixmapGenerator::generatePixmap(int height, UserLevelFlags userLevel, bool isBuddy, QString privLevel)
|
||||
{
|
||||
|
||||
QString key = QString::number(height * 10000) + ":" + (int)userLevel + ":" + (int)isBuddy + ":" + privLevel;
|
||||
QString key = QString::number(height * 10000) + ":" + (short)userLevel + ":" + (short)isBuddy + ":" + privLevel;
|
||||
if (pmCache.contains(key))
|
||||
return pmCache.value(key);
|
||||
|
||||
|
||||
@@ -45,19 +45,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class GenderPixmapGenerator
|
||||
{
|
||||
private:
|
||||
static QMap<int, QPixmap> pmCache;
|
||||
|
||||
public:
|
||||
static QPixmap generatePixmap(int height);
|
||||
static void clear()
|
||||
{
|
||||
pmCache.clear();
|
||||
}
|
||||
};
|
||||
|
||||
class CountryPixmapGenerator
|
||||
{
|
||||
private:
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "deck_loader.h"
|
||||
#include "dlg_create_token.h"
|
||||
#include "gamescene.h"
|
||||
#include "gettextwithmax.h"
|
||||
#include "handcounter.h"
|
||||
#include "handzone.h"
|
||||
#include "main.h"
|
||||
@@ -56,6 +57,7 @@
|
||||
#include "playertarget.h"
|
||||
#include "settingscache.h"
|
||||
#include "stackzone.h"
|
||||
#include "stringsizes.h"
|
||||
#include "tab_game.h"
|
||||
#include "tablezone.h"
|
||||
#include "thememanager.h"
|
||||
@@ -64,6 +66,7 @@
|
||||
|
||||
#include <QDebug>
|
||||
#include <QMenu>
|
||||
#include <QMetaType>
|
||||
#include <QPainter>
|
||||
#include <QRegularExpression>
|
||||
#include <QRegularExpressionMatch>
|
||||
@@ -1844,11 +1847,32 @@ void Player::eventShuffle(const Event_Shuffle &event)
|
||||
if (!zone) {
|
||||
return;
|
||||
}
|
||||
auto &cardList = zone->getCards();
|
||||
int absStart = event.start();
|
||||
if (absStart < 0) { // negative indexes start from the end
|
||||
absStart += cardList.length();
|
||||
}
|
||||
|
||||
// close all views that contain shuffled cards
|
||||
for (auto *view : zone->getViews()) {
|
||||
if (view != nullptr) {
|
||||
emit view->beingDeleted();
|
||||
int length = view->getCards().length();
|
||||
// we want to close empty views as well
|
||||
if (length == 0 || length > absStart) { // note this assumes views always start at the top of the library
|
||||
view->deleteLater();
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
qWarning() << zone->getName() << "of" << getName() << "holds empty zoneview!";
|
||||
}
|
||||
}
|
||||
|
||||
// remove revealed card name on top of decks
|
||||
if (absStart == 0 && !cardList.isEmpty()) {
|
||||
cardList.first()->setName("");
|
||||
zone->update();
|
||||
}
|
||||
|
||||
emit logShuffle(this, zone, event.start(), event.end());
|
||||
}
|
||||
|
||||
@@ -1924,7 +1948,7 @@ void Player::eventSetCardAttr(const Event_SetCardAttr &event, const GameEventCon
|
||||
} else {
|
||||
CardItem *card = zone->getCard(event.card_id(), QString());
|
||||
if (!card) {
|
||||
qDebug() << "Player::eventSetCardAttr: card id=" << event.card_id() << "not found";
|
||||
qWarning() << "Player::eventSetCardAttr: card id=" << event.card_id() << "not found";
|
||||
return;
|
||||
}
|
||||
setCardAttrHelper(context, card, event.attribute(), QString::fromStdString(event.attr_value()), false);
|
||||
@@ -2324,7 +2348,7 @@ void Player::processGameEvent(GameEvent::GameEventType type, const GameEvent &ev
|
||||
eventChangeZoneProperties(event.GetExtension(Event_ChangeZoneProperties::ext));
|
||||
break;
|
||||
default: {
|
||||
qDebug() << "unhandled game event" << type;
|
||||
qWarning() << "unhandled game event" << type;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2499,7 +2523,6 @@ AbstractCounter *Player::addCounter(const ServerInfo_Counter &counter)
|
||||
|
||||
AbstractCounter *Player::addCounter(int counterId, const QString &name, QColor color, int radius, int value)
|
||||
{
|
||||
qDebug() << "addCounter:" << getName() << counterId << name;
|
||||
if (counters.contains(counterId)) {
|
||||
return nullptr;
|
||||
}
|
||||
@@ -2613,15 +2636,6 @@ void Player::clearArrows()
|
||||
void Player::rearrangeCounters()
|
||||
{
|
||||
qreal marginTop = 80;
|
||||
|
||||
// Determine total height of bounding rectangles
|
||||
qreal totalHeight = 0;
|
||||
for (const auto &counter : counters) {
|
||||
if (counter->getShownInCounterArea()) {
|
||||
totalHeight += counter->boundingRect().height();
|
||||
}
|
||||
}
|
||||
|
||||
const qreal padding = 5;
|
||||
qreal ySize = boundingRect().y() + marginTop;
|
||||
|
||||
@@ -3034,8 +3048,8 @@ void Player::actSetPT()
|
||||
}
|
||||
bool ok;
|
||||
dialogSemaphore = true;
|
||||
QString pt = QInputDialog::getText(nullptr, tr("Change power/toughness"), tr("Change stats to:"), QLineEdit::Normal,
|
||||
oldPT, &ok);
|
||||
QString pt =
|
||||
getTextWithMax(game, tr("Change power/toughness"), tr("Change stats to:"), QLineEdit::Normal, oldPT, &ok);
|
||||
dialogSemaphore = false;
|
||||
if (clearCardsToDelete() || !ok) {
|
||||
return;
|
||||
@@ -3053,7 +3067,11 @@ void Player::actSetPT()
|
||||
const auto oldpt = parsePT(card->getPT());
|
||||
int ptIter = 0;
|
||||
for (const auto &item : ptList) {
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
||||
if (item.typeId() == QMetaType::Type::Int) {
|
||||
#else
|
||||
if (item.type() == QVariant::Int) {
|
||||
#endif
|
||||
int oldItem = ptIter < oldpt.size() ? oldpt.at(ptIter).toInt() : 0;
|
||||
newpt += '/' + QString::number(oldItem + item.toInt());
|
||||
} else {
|
||||
@@ -3140,8 +3158,9 @@ void Player::actSetAnnotation()
|
||||
|
||||
bool ok;
|
||||
dialogSemaphore = true;
|
||||
QString annotation = QInputDialog::getText(nullptr, tr("Set annotation"), tr("Please enter the new annotation:"),
|
||||
QLineEdit::Normal, oldAnnotation, &ok);
|
||||
QString annotation = QInputDialog::getMultiLineText(game, tr("Set annotation"),
|
||||
tr("Please enter the new annotation:"), oldAnnotation, &ok)
|
||||
.left(MAX_NAME_LENGTH);
|
||||
dialogSemaphore = false;
|
||||
if (clearCardsToDelete() || !ok) {
|
||||
return;
|
||||
|
||||
@@ -28,7 +28,11 @@ bool PlayerListItemDelegate::editorEvent(QEvent *event,
|
||||
if ((event->type() == QEvent::MouseButtonPress) && index.isValid()) {
|
||||
QMouseEvent *const mouseEvent = static_cast<QMouseEvent *>(event);
|
||||
if (mouseEvent->button() == Qt::RightButton) {
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
||||
static_cast<PlayerListWidget *>(parent())->showContextMenu(mouseEvent->globalPosition().toPoint(), index);
|
||||
#else
|
||||
static_cast<PlayerListWidget *>(parent())->showContextMenu(mouseEvent->globalPos(), index);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,10 +7,7 @@
|
||||
#include <QDebug>
|
||||
#include <QPainter>
|
||||
#include <QPixmapCache>
|
||||
#include <cmath>
|
||||
#ifdef _WIN32
|
||||
#include "round.h"
|
||||
#endif /* _WIN32 */
|
||||
#include <QtMath>
|
||||
|
||||
PlayerCounter::PlayerCounter(Player *_player,
|
||||
int _id,
|
||||
@@ -49,7 +46,7 @@ void PlayerCounter::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*
|
||||
QSize translatedSize = translatedRect.size().toSize();
|
||||
QFont font("Serif");
|
||||
font.setWeight(QFont::Bold);
|
||||
font.setPixelSize(qMax((int)round(translatedSize.height() / 1.3), 9));
|
||||
font.setPixelSize(qMax(qRound(translatedSize.height() / 1.3), 9));
|
||||
painter->setFont(font);
|
||||
painter->setPen(Qt::white);
|
||||
painter->drawText(translatedRect, Qt::AlignCenter, QString::number(value));
|
||||
@@ -96,9 +93,9 @@ void PlayerTarget::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*o
|
||||
QPainter tempPainter(&cachedPixmap);
|
||||
// pow(foo, 0.5) equals to sqrt(foo), but using sqrt(foo) in this context will produce a compile error with
|
||||
// MSVC++
|
||||
QRadialGradient grad(translatedRect.center(), pow(translatedSize.width() * translatedSize.width() +
|
||||
translatedSize.height() * translatedSize.height(),
|
||||
0.5) /
|
||||
QRadialGradient grad(translatedRect.center(), qPow(translatedSize.width() * translatedSize.width() +
|
||||
translatedSize.height() * translatedSize.height(),
|
||||
0.5) /
|
||||
2);
|
||||
grad.setColorAt(1, Qt::black);
|
||||
grad.setColorAt(0, QColor(180, 180, 180));
|
||||
@@ -135,7 +132,7 @@ void PlayerTarget::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*o
|
||||
name = name.mid(0, 10) + "...";
|
||||
|
||||
QFont font;
|
||||
font.setPixelSize(qMax((int)round(translatedNameRect.height() / 1.5), 9));
|
||||
font.setPixelSize(qMax(qRound(translatedNameRect.height() / 1.5), 9));
|
||||
painter->setFont(font);
|
||||
painter->setPen(Qt::white);
|
||||
painter->drawText(translatedNameRect, Qt::AlignVCenter | Qt::AlignLeft, " " + name);
|
||||
|
||||
@@ -23,10 +23,9 @@
|
||||
|
||||
int ReleaseChannel::sharedIndex = 0;
|
||||
|
||||
ReleaseChannel::ReleaseChannel() : response(nullptr), lastRelease(nullptr)
|
||||
ReleaseChannel::ReleaseChannel() : netMan(new QNetworkAccessManager(this)), response(nullptr), lastRelease(nullptr)
|
||||
{
|
||||
index = sharedIndex++;
|
||||
netMan = new QNetworkAccessManager(this);
|
||||
}
|
||||
|
||||
ReleaseChannel::~ReleaseChannel()
|
||||
|
||||
@@ -78,7 +78,7 @@ class ReleaseChannel : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
ReleaseChannel();
|
||||
explicit ReleaseChannel();
|
||||
~ReleaseChannel() override;
|
||||
|
||||
protected:
|
||||
@@ -117,7 +117,7 @@ class StableReleaseChannel : public ReleaseChannel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
StableReleaseChannel() = default;
|
||||
explicit StableReleaseChannel() = default;
|
||||
~StableReleaseChannel() override = default;
|
||||
|
||||
QString getManualDownloadUrl() const override;
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
#include "remoteclient.h"
|
||||
|
||||
#include "debug_pb_message.h"
|
||||
#include "main.h"
|
||||
#include "pb/commands.pb.h"
|
||||
#include "passwordhasher.h"
|
||||
#include "pb/event_server_identification.pb.h"
|
||||
#include "pb/response_activate.pb.h"
|
||||
#include "pb/response_forgotpasswordrequest.pb.h"
|
||||
#include "pb/response_login.pb.h"
|
||||
#include "pb/response_password_salt.pb.h"
|
||||
#include "pb/response_register.pb.h"
|
||||
#include "pb/server_message.pb.h"
|
||||
#include "pb/session_commands.pb.h"
|
||||
@@ -26,7 +28,7 @@ static const unsigned int protocolVersion = 14;
|
||||
|
||||
RemoteClient::RemoteClient(QObject *parent)
|
||||
: AbstractClient(parent), timeRunning(0), lastDataReceived(0), messageInProgress(false), handshakeStarted(false),
|
||||
usingWebSocket(false), messageLength(0)
|
||||
usingWebSocket(false), messageLength(0), hashedPassword()
|
||||
{
|
||||
|
||||
clearNewClientFeatures();
|
||||
@@ -39,8 +41,13 @@ RemoteClient::RemoteClient(QObject *parent)
|
||||
socket->setSocketOption(QAbstractSocket::LowDelayOption, 1);
|
||||
connect(socket, SIGNAL(connected()), this, SLOT(slotConnected()));
|
||||
connect(socket, SIGNAL(readyRead()), this, SLOT(readData()));
|
||||
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
||||
connect(socket, &QTcpSocket::errorOccurred, this, &RemoteClient::slotSocketError);
|
||||
#else
|
||||
connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this,
|
||||
SLOT(slotSocketError(QAbstractSocket::SocketError)));
|
||||
#endif
|
||||
|
||||
websocket = new QWebSocket(QString(), QWebSocketProtocol::VersionLatest, this);
|
||||
connect(websocket, &QWebSocket::binaryMessageReceived, this, &RemoteClient::websocketMessageReceived);
|
||||
@@ -55,8 +62,8 @@ RemoteClient::RemoteClient(QObject *parent)
|
||||
connect(this, SIGNAL(sigConnectToServer(QString, unsigned int, QString, QString)), this,
|
||||
SLOT(doConnectToServer(QString, unsigned int, QString, QString)));
|
||||
connect(this, SIGNAL(sigDisconnectFromServer()), this, SLOT(doDisconnectFromServer()));
|
||||
connect(this, SIGNAL(sigRegisterToServer(QString, unsigned int, QString, QString, QString, int, QString, QString)),
|
||||
this, SLOT(doRegisterToServer(QString, unsigned int, QString, QString, QString, int, QString, QString)));
|
||||
connect(this, SIGNAL(sigRegisterToServer(QString, unsigned int, QString, QString, QString, QString, QString)), this,
|
||||
SLOT(doRegisterToServer(QString, unsigned int, QString, QString, QString, QString, QString)));
|
||||
connect(this, SIGNAL(sigActivateToServer(QString)), this, SLOT(doActivateToServer(QString)));
|
||||
connect(this, SIGNAL(sigRequestForgotPasswordToServer(QString, unsigned int, QString)), this,
|
||||
SLOT(doRequestForgotPasswordToServer(QString, unsigned int, QString)));
|
||||
@@ -109,6 +116,7 @@ void RemoteClient::processServerIdentificationEvent(const Event_ServerIdentifica
|
||||
setStatus(StatusDisconnecting);
|
||||
return;
|
||||
}
|
||||
serverSupportsPasswordHash = event.server_options() & Event_ServerIdentification::SupportsPasswordHash;
|
||||
|
||||
if (getStatus() == StatusRequestingForgotPassword) {
|
||||
Command_ForgotPasswordRequest cmdForgotPasswordRequest;
|
||||
@@ -126,7 +134,14 @@ void RemoteClient::processServerIdentificationEvent(const Event_ServerIdentifica
|
||||
cmdForgotPasswordReset.set_user_name(userName.toStdString());
|
||||
cmdForgotPasswordReset.set_clientid(getSrvClientID(lastHostname).toStdString());
|
||||
cmdForgotPasswordReset.set_token(token.toStdString());
|
||||
cmdForgotPasswordReset.set_new_password(password.toStdString());
|
||||
if (!password.isEmpty() && serverSupportsPasswordHash) {
|
||||
auto passwordSalt = PasswordHasher::generateRandomSalt();
|
||||
hashedPassword = PasswordHasher::computeHash(password, passwordSalt);
|
||||
cmdForgotPasswordReset.set_hashed_new_password(hashedPassword.toStdString());
|
||||
} else if (!password.isEmpty()) {
|
||||
qWarning() << "using plain text password to reset password";
|
||||
cmdForgotPasswordReset.set_new_password(password.toStdString());
|
||||
}
|
||||
PendingCommand *pend = prepareSessionCommand(cmdForgotPasswordReset);
|
||||
connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this,
|
||||
SLOT(submitForgotPasswordResetResponse(Response)));
|
||||
@@ -149,9 +164,15 @@ void RemoteClient::processServerIdentificationEvent(const Event_ServerIdentifica
|
||||
if (getStatus() == StatusRegistering) {
|
||||
Command_Register cmdRegister;
|
||||
cmdRegister.set_user_name(userName.toStdString());
|
||||
cmdRegister.set_password(password.toStdString());
|
||||
if (!password.isEmpty() && serverSupportsPasswordHash) {
|
||||
auto passwordSalt = PasswordHasher::generateRandomSalt();
|
||||
hashedPassword = PasswordHasher::computeHash(password, passwordSalt);
|
||||
cmdRegister.set_hashed_password(hashedPassword.toStdString());
|
||||
} else if (!password.isEmpty()) {
|
||||
qWarning() << "using plain text password to register";
|
||||
cmdRegister.set_password(password.toStdString());
|
||||
}
|
||||
cmdRegister.set_email(email.toStdString());
|
||||
cmdRegister.set_gender((ServerInfo_User_Gender)gender);
|
||||
cmdRegister.set_country(country.toStdString());
|
||||
cmdRegister.set_real_name(realName.toStdString());
|
||||
cmdRegister.set_clientid(getSrvClientID(lastHostname).toStdString());
|
||||
@@ -178,12 +199,21 @@ void RemoteClient::processServerIdentificationEvent(const Event_ServerIdentifica
|
||||
doLogin();
|
||||
}
|
||||
|
||||
void RemoteClient::doLogin()
|
||||
void RemoteClient::doRequestPasswordSalt()
|
||||
{
|
||||
setStatus(StatusGettingPasswordSalt);
|
||||
Command_RequestPasswordSalt cmdRqSalt;
|
||||
cmdRqSalt.set_user_name(userName.toStdString());
|
||||
|
||||
PendingCommand *pend = prepareSessionCommand(cmdRqSalt);
|
||||
connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this, SLOT(passwordSaltResponse(Response)));
|
||||
sendCommand(pend);
|
||||
}
|
||||
|
||||
Command_Login RemoteClient::generateCommandLogin()
|
||||
{
|
||||
setStatus(StatusLoggingIn);
|
||||
Command_Login cmdLogin;
|
||||
cmdLogin.set_user_name(userName.toStdString());
|
||||
cmdLogin.set_password(password.toStdString());
|
||||
cmdLogin.set_clientid(getSrvClientID(lastHostname).toStdString());
|
||||
cmdLogin.set_clientver(VERSION_STRING);
|
||||
|
||||
@@ -192,6 +222,41 @@ void RemoteClient::doLogin()
|
||||
for (i = clientFeatures.begin(); i != clientFeatures.end(); ++i)
|
||||
cmdLogin.add_clientfeatures(i.key().toStdString().c_str());
|
||||
}
|
||||
|
||||
return cmdLogin;
|
||||
}
|
||||
|
||||
void RemoteClient::doLogin()
|
||||
{
|
||||
if (!password.isEmpty() && serverSupportsPasswordHash) {
|
||||
// TODO store and log in using stored hashed password
|
||||
if (hashedPassword.isEmpty()) {
|
||||
doRequestPasswordSalt(); // ask salt to create hashedPassword, then log in
|
||||
} else {
|
||||
doHashedLogin(); // log in using hashed password instead
|
||||
}
|
||||
} else {
|
||||
// TODO add setting for client to reject unhashed logins
|
||||
setStatus(StatusLoggingIn);
|
||||
Command_Login cmdLogin = generateCommandLogin();
|
||||
if (!password.isEmpty()) {
|
||||
qWarning() << "using plain text password to log in";
|
||||
cmdLogin.set_password(password.toStdString());
|
||||
}
|
||||
|
||||
PendingCommand *pend = prepareSessionCommand(cmdLogin);
|
||||
connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this, SLOT(loginResponse(Response)));
|
||||
sendCommand(pend);
|
||||
}
|
||||
}
|
||||
|
||||
void RemoteClient::doHashedLogin()
|
||||
{
|
||||
setStatus(StatusLoggingIn);
|
||||
Command_Login cmdLogin = generateCommandLogin();
|
||||
|
||||
cmdLogin.set_hashed_password(hashedPassword.toStdString());
|
||||
|
||||
PendingCommand *pend = prepareSessionCommand(cmdLogin);
|
||||
connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this, SLOT(loginResponse(Response)));
|
||||
sendCommand(pend);
|
||||
@@ -202,6 +267,23 @@ void RemoteClient::processConnectionClosedEvent(const Event_ConnectionClosed & /
|
||||
doDisconnectFromServer();
|
||||
}
|
||||
|
||||
void RemoteClient::passwordSaltResponse(const Response &response)
|
||||
{
|
||||
if (response.response_code() == Response::RespOk) {
|
||||
const Response_PasswordSalt &resp = response.GetExtension(Response_PasswordSalt::ext);
|
||||
auto passwordSalt = QString::fromStdString(resp.password_salt());
|
||||
if (passwordSalt.isEmpty()) { // the server does not recognize the user but allows them to enter unregistered
|
||||
password.clear(); // the password will not be used
|
||||
doLogin();
|
||||
} else {
|
||||
hashedPassword = PasswordHasher::computeHash(password, passwordSalt);
|
||||
doHashedLogin();
|
||||
}
|
||||
} else if (response.response_code() != Response::RespNotConnected) {
|
||||
emit loginError(response.response_code(), {}, 0, {});
|
||||
}
|
||||
}
|
||||
|
||||
void RemoteClient::loginResponse(const Response &response)
|
||||
{
|
||||
const Response_Login &resp = response.GetExtension(Response_Login::ext);
|
||||
@@ -311,7 +393,7 @@ void RemoteClient::readData()
|
||||
ServerMessage newServerMessage;
|
||||
newServerMessage.ParseFromArray(inputBuffer.data(), messageLength);
|
||||
#ifdef QT_DEBUG
|
||||
qDebug() << "IN" << messageLength << QString::fromStdString(newServerMessage.ShortDebugString());
|
||||
qDebug().noquote() << "IN" << getSafeDebugString(newServerMessage);
|
||||
#endif
|
||||
inputBuffer.remove(0, messageLength);
|
||||
messageInProgress = false;
|
||||
@@ -329,7 +411,7 @@ void RemoteClient::websocketMessageReceived(const QByteArray &message)
|
||||
ServerMessage newServerMessage;
|
||||
newServerMessage.ParseFromArray(message.data(), message.length());
|
||||
#ifdef QT_DEBUG
|
||||
qDebug() << "IN" << messageLength << QString::fromStdString(newServerMessage.ShortDebugString());
|
||||
qDebug().noquote() << "IN" << getSafeDebugString(newServerMessage);
|
||||
#endif
|
||||
processProtocolItem(newServerMessage);
|
||||
}
|
||||
@@ -342,7 +424,7 @@ void RemoteClient::sendCommandContainer(const CommandContainer &cont)
|
||||
auto size = static_cast<unsigned int>(cont.ByteSize());
|
||||
#endif
|
||||
#ifdef QT_DEBUG
|
||||
qDebug() << "OUT" << size << QString::fromStdString(cont.ShortDebugString());
|
||||
qDebug().noquote() << "OUT" << getSafeDebugString(cont);
|
||||
#endif
|
||||
|
||||
QByteArray buf;
|
||||
@@ -384,6 +466,7 @@ void RemoteClient::doConnectToServer(const QString &hostname,
|
||||
password = _password;
|
||||
lastHostname = hostname;
|
||||
lastPort = port;
|
||||
hashedPassword.clear();
|
||||
|
||||
connectToHost(hostname, port);
|
||||
setStatus(StatusConnecting);
|
||||
@@ -394,7 +477,6 @@ void RemoteClient::doRegisterToServer(const QString &hostname,
|
||||
const QString &_userName,
|
||||
const QString &_password,
|
||||
const QString &_email,
|
||||
const int _gender,
|
||||
const QString &_country,
|
||||
const QString &_realname)
|
||||
{
|
||||
@@ -403,11 +485,11 @@ void RemoteClient::doRegisterToServer(const QString &hostname,
|
||||
userName = _userName;
|
||||
password = _password;
|
||||
email = _email;
|
||||
gender = _gender;
|
||||
country = _country;
|
||||
realName = _realname;
|
||||
lastHostname = hostname;
|
||||
lastPort = port;
|
||||
hashedPassword.clear();
|
||||
|
||||
connectToHost(hostname, port);
|
||||
setStatus(StatusRegistering);
|
||||
@@ -484,11 +566,10 @@ void RemoteClient::registerToServer(const QString &hostname,
|
||||
const QString &_userName,
|
||||
const QString &_password,
|
||||
const QString &_email,
|
||||
const int _gender,
|
||||
const QString &_country,
|
||||
const QString &_realname)
|
||||
{
|
||||
emit sigRegisterToServer(hostname, port, _userName, _password, _email, _gender, _country, _realname);
|
||||
emit sigRegisterToServer(hostname, port, _userName, _password, _email, _country, _realname);
|
||||
}
|
||||
|
||||
void RemoteClient::activateToServer(const QString &_token)
|
||||
@@ -510,7 +591,7 @@ QString RemoteClient::getSrvClientID(const QString &_hostname)
|
||||
QHostAddress hostAddress = hostInfo.addresses().first();
|
||||
srvClientID += hostAddress.toString();
|
||||
} else {
|
||||
qDebug() << "Warning: ClientID generation host lookup failure [" << hostInfo.errorString() << "]";
|
||||
qWarning() << "ClientID generation host lookup failure [" << hostInfo.errorString() << "]";
|
||||
srvClientID += _hostname;
|
||||
}
|
||||
QString uniqueServerClientID =
|
||||
@@ -597,6 +678,7 @@ void RemoteClient::doSubmitForgotPasswordResetToServer(const QString &hostname,
|
||||
lastPort = port;
|
||||
token = _token.trimmed();
|
||||
password = _newpassword;
|
||||
hashedPassword.clear();
|
||||
|
||||
connectToHost(lastHostname, lastPort);
|
||||
setStatus(StatusSubmitForgotPasswordReset);
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#define REMOTECLIENT_H
|
||||
|
||||
#include "abstractclient.h"
|
||||
#include "pb/commands.pb.h"
|
||||
|
||||
#include <QTcpSocket>
|
||||
#include <QWebSocket>
|
||||
@@ -26,7 +27,6 @@ signals:
|
||||
const QString &_userName,
|
||||
const QString &_password,
|
||||
const QString &_email,
|
||||
int _gender,
|
||||
const QString &_country,
|
||||
const QString &_realname);
|
||||
void sigActivateToServer(const QString &_token);
|
||||
@@ -55,6 +55,7 @@ private slots:
|
||||
void ping();
|
||||
void processServerIdentificationEvent(const Event_ServerIdentification &event);
|
||||
void processConnectionClosedEvent(const Event_ConnectionClosed &event);
|
||||
void passwordSaltResponse(const Response &response);
|
||||
void loginResponse(const Response &response);
|
||||
void registerResponse(const Response &response);
|
||||
void activateResponse(const Response &response);
|
||||
@@ -65,10 +66,12 @@ private slots:
|
||||
const QString &_userName,
|
||||
const QString &_password,
|
||||
const QString &_email,
|
||||
int _gender,
|
||||
const QString &_country,
|
||||
const QString &_realname);
|
||||
void doRequestPasswordSalt();
|
||||
void doLogin();
|
||||
void doHashedLogin();
|
||||
Command_Login generateCommandLogin();
|
||||
void doDisconnectFromServer();
|
||||
void doActivateToServer(const QString &_token);
|
||||
void doRequestForgotPasswordToServer(const QString &hostname, unsigned int port, const QString &_userName);
|
||||
@@ -98,6 +101,7 @@ private:
|
||||
QWebSocket *websocket;
|
||||
QString lastHostname;
|
||||
unsigned int lastPort;
|
||||
QString hashedPassword;
|
||||
|
||||
QString getSrvClientID(const QString &_hostname);
|
||||
bool newMissingFeatureFound(const QString &_serversMissingFeatures);
|
||||
@@ -125,7 +129,6 @@ public:
|
||||
const QString &_userName,
|
||||
const QString &_password,
|
||||
const QString &_email,
|
||||
int _gender,
|
||||
const QString &_country,
|
||||
const QString &_realname);
|
||||
void activateToServer(const QString &_token);
|
||||
|
||||
@@ -221,7 +221,7 @@ void RemoteDeckList_TreeModel::addFileToTree(const ServerInfo_DeckStorage_TreeIt
|
||||
{
|
||||
const ServerInfo_DeckStorage_File &fileInfo = file.file();
|
||||
QDateTime time;
|
||||
time.setTime_t(fileInfo.creation_time());
|
||||
time.setSecsSinceEpoch(fileInfo.creation_time());
|
||||
|
||||
beginInsertRows(nodeToIndex(parent), parent->size(), parent->size());
|
||||
parent->append(new FileNode(QString::fromStdString(file.name()), file.id(), time, parent));
|
||||
|
||||
@@ -111,7 +111,7 @@ QVariant RemoteReplayList_TreeModel::data(const QModelIndex &index, int role) co
|
||||
return playerList.join(", ");
|
||||
}
|
||||
case 4:
|
||||
return QDateTime::fromTime_t(matchInfo.time_started());
|
||||
return QDateTime::fromSecsSinceEpoch(matchInfo.time_started());
|
||||
case 5:
|
||||
return matchInfo.length();
|
||||
default:
|
||||
|
||||
@@ -4,10 +4,6 @@
|
||||
#include <QPainterPath>
|
||||
#include <QPalette>
|
||||
#include <QTimer>
|
||||
#include <cmath>
|
||||
#ifdef _WIN32
|
||||
#include "round.h"
|
||||
#endif /* _WIN32 */
|
||||
|
||||
ReplayTimelineWidget::ReplayTimelineWidget(QWidget *parent)
|
||||
: QWidget(parent), maxBinValue(1), maxTime(1), timeScaleFactor(1.0), currentTime(0), currentEvent(0)
|
||||
@@ -54,7 +50,7 @@ void ReplayTimelineWidget::paintEvent(QPaintEvent * /* event */)
|
||||
QPainterPath path;
|
||||
path.moveTo(0, height() - 1);
|
||||
for (int i = 0; i < histogram.size(); ++i)
|
||||
path.lineTo(round(i * binWidth), (height() - 1) * (1.0 - (qreal)histogram[i] / maxBinValue));
|
||||
path.lineTo(qRound(i * binWidth), (height() - 1) * (1.0 - (qreal)histogram[i] / maxBinValue));
|
||||
path.lineTo(width() - 1, height() - 1);
|
||||
path.lineTo(0, height() - 1);
|
||||
painter.fillPath(path, Qt::black);
|
||||
@@ -66,7 +62,11 @@ void ReplayTimelineWidget::paintEvent(QPaintEvent * /* event */)
|
||||
|
||||
void ReplayTimelineWidget::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
int newTime = static_cast<int>((long)maxTime * (long)event->x() / width());
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
||||
int newTime = static_cast<int>((qint64)maxTime * (qint64)event->position().x() / width());
|
||||
#else
|
||||
int newTime = static_cast<int>((qint64)maxTime * (qint64)event->x() / width());
|
||||
#endif
|
||||
newTime -= newTime % 200; // Time should always be a multiple of 200
|
||||
if (newTime < currentTime) {
|
||||
currentTime = 0;
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
#ifndef MSVC_ROUND_FIX
|
||||
#define MSVC_ROUND_FIX
|
||||
/**
|
||||
* This helper function exists only because MS VC++ 2010 does not support round() in
|
||||
* <cmath>. round() works with g++ and clang++ but is formally a C++11 extension.
|
||||
* So this file exists for MS VC++ only.
|
||||
*/
|
||||
inline double round(double val)
|
||||
{
|
||||
return floor(val + 0.5);
|
||||
}
|
||||
|
||||
#endif /* MSVC_ROUND_FIX */
|
||||
@@ -1,5 +1,7 @@
|
||||
#include "setsmodel.h"
|
||||
|
||||
#include <QSortFilterProxyModel>
|
||||
|
||||
SetsModel::SetsModel(CardDatabase *_db, QObject *parent) : QAbstractTableModel(parent), sets(_db->getSetList())
|
||||
{
|
||||
sets.sortByKey();
|
||||
@@ -274,9 +276,15 @@ bool SetsDisplayModel::filterAcceptsRow(int sourceRow, const QModelIndex &source
|
||||
auto nameIndex = sourceModel()->index(sourceRow, SetsModel::LongNameCol, sourceParent);
|
||||
auto shortNameIndex = sourceModel()->index(sourceRow, SetsModel::ShortNameCol, sourceParent);
|
||||
|
||||
return (sourceModel()->data(typeIndex).toString().contains(filterRegExp()) ||
|
||||
sourceModel()->data(nameIndex).toString().contains(filterRegExp()) ||
|
||||
sourceModel()->data(shortNameIndex).toString().contains(filterRegExp()));
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 12, 0))
|
||||
const auto filter = filterRegularExpression();
|
||||
#else
|
||||
const auto filter = filterRegExp();
|
||||
#endif
|
||||
|
||||
return (sourceModel()->data(typeIndex).toString().contains(filter) ||
|
||||
sourceModel()->data(nameIndex).toString().contains(filter) ||
|
||||
sourceModel()->data(shortNameIndex).toString().contains(filter));
|
||||
}
|
||||
|
||||
bool SetsDisplayModel::lessThan(const QModelIndex &left, const QModelIndex &right) const
|
||||
|
||||
@@ -18,7 +18,7 @@ QString SettingsCache::getDataPath()
|
||||
if (isPortableBuild)
|
||||
return qApp->applicationDirPath() + "/data";
|
||||
else
|
||||
return QStandardPaths::writableLocation(QStandardPaths::DataLocation);
|
||||
return QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
|
||||
}
|
||||
|
||||
QString SettingsCache::getSettingsPath()
|
||||
@@ -692,6 +692,7 @@ QStringList SettingsCache::getCountries() const
|
||||
<< "er"
|
||||
<< "es"
|
||||
<< "et"
|
||||
<< "eu"
|
||||
<< "fi"
|
||||
<< "fj"
|
||||
<< "fk"
|
||||
@@ -867,6 +868,7 @@ QStringList SettingsCache::getCountries() const
|
||||
<< "vu"
|
||||
<< "wf"
|
||||
<< "ws"
|
||||
<< "xk"
|
||||
<< "ye"
|
||||
<< "yt"
|
||||
<< "za"
|
||||
|
||||
@@ -20,7 +20,6 @@ class ReleaseChannel;
|
||||
#define PIXMAPCACHE_SIZE_MIN 64
|
||||
#define PIXMAPCACHE_SIZE_MAX 2047
|
||||
|
||||
#define DEFAULT_LANG_CODE "en"
|
||||
#define DEFAULT_LANG_NAME "English"
|
||||
#define CLIENT_INFO_NOT_SET "notset"
|
||||
|
||||
|
||||
@@ -2,21 +2,15 @@
|
||||
|
||||
#include "settingscache.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QAudioOutput>
|
||||
#include <QBuffer>
|
||||
#include <QDebug>
|
||||
#include <QFileInfo>
|
||||
#include <QLibraryInfo>
|
||||
#include <QStandardPaths>
|
||||
#include <QDir>
|
||||
#include <QMediaPlayer>
|
||||
|
||||
#define DEFAULT_THEME_NAME "Default"
|
||||
#define TEST_SOUND_FILENAME "player_join"
|
||||
|
||||
SoundEngine::SoundEngine(QObject *parent) : QObject(parent), player(0)
|
||||
{
|
||||
inputBuffer = new QBuffer(this);
|
||||
|
||||
ensureThemeDirectoryExists();
|
||||
connect(&SettingsCache::instance(), SIGNAL(soundThemeChanged()), this, SLOT(themeChangedSlot()));
|
||||
connect(&SettingsCache::instance(), SIGNAL(soundEnabledChanged()), this, SLOT(soundEnabledChanged()));
|
||||
@@ -31,8 +25,6 @@ SoundEngine::~SoundEngine()
|
||||
player->deleteLater();
|
||||
player = 0;
|
||||
}
|
||||
|
||||
inputBuffer->deleteLater();
|
||||
}
|
||||
|
||||
void SoundEngine::soundEnabledChanged()
|
||||
@@ -40,14 +32,11 @@ void SoundEngine::soundEnabledChanged()
|
||||
if (SettingsCache::instance().getSoundEnabled()) {
|
||||
qDebug("SoundEngine: enabling sound");
|
||||
if (!player) {
|
||||
QAudioFormat format;
|
||||
format.setSampleRate(44100);
|
||||
format.setChannelCount(1);
|
||||
format.setSampleSize(16);
|
||||
format.setCodec("audio/pcm");
|
||||
format.setByteOrder(QAudioFormat::LittleEndian);
|
||||
format.setSampleType(QAudioFormat::SignedInt);
|
||||
player = new QAudioOutput(format, this);
|
||||
player = new QMediaPlayer;
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
||||
auto qAudioOutput = new QAudioOutput;
|
||||
player->setAudioOutput(qAudioOutput);
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
qDebug("SoundEngine: disabling sound");
|
||||
@@ -61,25 +50,35 @@ void SoundEngine::soundEnabledChanged()
|
||||
|
||||
void SoundEngine::playSound(QString fileName)
|
||||
{
|
||||
if (!player)
|
||||
if (!player) {
|
||||
return;
|
||||
}
|
||||
|
||||
// still playing the previous sound?
|
||||
if (player->state() == QAudio::ActiveState)
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
||||
if (player->playbackState() == QMediaPlayer::PlaybackState::PlayingState) {
|
||||
#else
|
||||
if (player->state() == QMediaPlayer::PlayingState) {
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
if (!audioData.contains(fileName))
|
||||
if (!audioData.contains(fileName)) {
|
||||
return;
|
||||
}
|
||||
|
||||
qDebug() << "playing" << fileName;
|
||||
|
||||
inputBuffer->close();
|
||||
inputBuffer->setData(audioData[fileName]);
|
||||
inputBuffer->open(QIODevice::ReadOnly);
|
||||
|
||||
player->setVolume(SettingsCache::instance().getMasterVolume() / 100.0);
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
||||
player->audioOutput()->setVolume(SettingsCache::instance().getMasterVolume());
|
||||
player->stop();
|
||||
player->start(inputBuffer);
|
||||
player->setSource(QUrl::fromLocalFile(audioData[fileName]));
|
||||
#else
|
||||
player->setVolume(SettingsCache::instance().getMasterVolume());
|
||||
player->stop();
|
||||
player->setMedia(QUrl::fromLocalFile(audioData[fileName]));
|
||||
#endif
|
||||
player->play();
|
||||
}
|
||||
|
||||
void SoundEngine::testSound()
|
||||
@@ -105,7 +104,7 @@ QStringMap &SoundEngine::getAvailableThemes()
|
||||
|
||||
dir.setPath(SettingsCache::instance().getDataPath() + "/sounds");
|
||||
|
||||
foreach (QString themeName, dir.entryList(QDir::AllDirs | QDir::NoDotAndDotDot, QDir::Name)) {
|
||||
for (const QString &themeName : dir.entryList(QDir::AllDirs | QDir::NoDotAndDotDot, QDir::Name)) {
|
||||
if (!availableThemes.contains(themeName))
|
||||
availableThemes.insert(themeName, dir.absoluteFilePath(themeName));
|
||||
}
|
||||
@@ -121,7 +120,7 @@ QStringMap &SoundEngine::getAvailableThemes()
|
||||
#endif
|
||||
);
|
||||
|
||||
foreach (QString themeName, dir.entryList(QDir::AllDirs | QDir::NoDotAndDotDot, QDir::Name)) {
|
||||
for (const QString &themeName : dir.entryList(QDir::AllDirs | QDir::NoDotAndDotDot, QDir::Name)) {
|
||||
if (!availableThemes.contains(themeName))
|
||||
availableThemes.insert(themeName, dir.absoluteFilePath(themeName));
|
||||
}
|
||||
@@ -181,10 +180,7 @@ void SoundEngine::themeChangedSlot()
|
||||
continue;
|
||||
|
||||
QFile file(dir.filePath(fileNames[i] + ".wav"));
|
||||
file.open(QIODevice::ReadOnly);
|
||||
// 44 = length of wav header
|
||||
audioData.insert(fileNames[i], file.readAll().mid(44));
|
||||
file.close();
|
||||
audioData.insert(fileNames[i], file.fileName());
|
||||
}
|
||||
|
||||
soundEnabledChanged();
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user