mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2025-12-21 06:42:41 -08:00
Compare commits
284 Commits
2021-11-07
...
address_cr
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
eb712d25dc | ||
|
|
0e97cc1712 | ||
|
|
d550e42441 | ||
|
|
4279753030 | ||
|
|
2f6c018b7a | ||
|
|
be5d42baba | ||
|
|
f174614496 | ||
|
|
e8c7fba8b0 | ||
|
|
5c49283023 | ||
|
|
ad56b431a3 | ||
|
|
b0d8a33d5f | ||
|
|
1715bcb216 | ||
|
|
96caeaca72 | ||
|
|
c8723ae935 | ||
|
|
94e39c044c | ||
|
|
9776ea53c9 | ||
|
|
675d07dac0 | ||
|
|
1217820288 | ||
|
|
90e1a3cb76 | ||
|
|
7c1095ea50 | ||
|
|
203e916a07 | ||
|
|
7201e34b38 | ||
|
|
6d032c378f | ||
|
|
badd8952f5 | ||
|
|
7209eddb2d | ||
|
|
a7ffd43b29 | ||
|
|
724ba69483 | ||
|
|
1716801437 | ||
|
|
fa727524dc | ||
|
|
28f80e18a0 | ||
|
|
4acc8bfe80 | ||
|
|
9f86ed7887 | ||
|
|
cb18a55338 | ||
|
|
78a928464c | ||
|
|
07a8cd0a5f | ||
|
|
b73ef58567 | ||
|
|
519531f3a0 | ||
|
|
4b8e47d079 | ||
|
|
ed170f7e07 | ||
|
|
6bb559874c | ||
|
|
9cd68e25b3 | ||
|
|
72ac441598 | ||
|
|
f5fe56c85d | ||
|
|
d4fc1be2cc | ||
|
|
7b3617a273 | ||
|
|
3e8adae3de | ||
|
|
9943133d6d | ||
|
|
a5706a47af | ||
|
|
b3b911c64d | ||
|
|
05beb4fcaf | ||
|
|
324b50e381 | ||
|
|
186f4289e9 | ||
|
|
cb90a8356b | ||
|
|
e9c502ab32 | ||
|
|
f728520e97 | ||
|
|
c1b0d50237 | ||
|
|
b9cfc29059 | ||
|
|
6bf7c79891 | ||
|
|
2bd0e58354 | ||
|
|
ee674cb0cf | ||
|
|
dd1b354d48 | ||
|
|
d3e96f4a99 | ||
|
|
90e2eb3db9 | ||
|
|
102be6a350 | ||
|
|
be6152948c | ||
|
|
f14bf4b205 | ||
|
|
123ac2ca25 | ||
|
|
7216b976ec | ||
|
|
7fb698cfbf | ||
|
|
b0470ab678 | ||
|
|
0deb037035 | ||
|
|
064b362d60 | ||
|
|
6bbe228a84 | ||
|
|
a8ba8b6ab5 | ||
|
|
e850f6c2a5 | ||
|
|
e9eb7d6db1 | ||
|
|
56d21321d0 | ||
|
|
3888a74212 | ||
|
|
0035e29f9e | ||
|
|
90679d5669 | ||
|
|
ac5dc2578a | ||
|
|
671e6823be | ||
|
|
0d76662311 | ||
|
|
8dd59cf3cf | ||
|
|
332d25dc00 | ||
|
|
0fa81a77dc | ||
|
|
9a74d8f72d | ||
|
|
8c539351e3 | ||
|
|
e3552fc0ae | ||
|
|
ca308636c3 | ||
|
|
244cb847fb | ||
|
|
176c52daf2 | ||
|
|
ee3525ec64 | ||
|
|
adce921be7 | ||
|
|
20ceb1c284 | ||
|
|
db4364b8f8 | ||
|
|
48d6435e09 | ||
|
|
7c20e9ab34 | ||
|
|
cb52605928 | ||
|
|
bd3100dcda | ||
|
|
afb7c35cfd | ||
|
|
5b694a55d2 | ||
|
|
f750a4cd72 | ||
|
|
eddeaaf52a | ||
|
|
2b42bee424 | ||
|
|
b9706c0cc1 | ||
|
|
800b21b000 | ||
|
|
d1736a25bb | ||
|
|
f269e5fe58 | ||
|
|
45a5296013 | ||
|
|
5f0ab2a177 | ||
|
|
70ab02987a | ||
|
|
421da882d8 | ||
|
|
1a40102f71 | ||
|
|
1fbc10cd77 | ||
|
|
87462398d8 | ||
|
|
b33246b29f | ||
|
|
dbffe30f63 | ||
|
|
9ce450d0b0 | ||
|
|
f5f8acf1fd | ||
|
|
304ed3cd60 | ||
|
|
07248692ce | ||
|
|
cef99cba71 | ||
|
|
cab5f29b57 | ||
|
|
55a2f75d16 | ||
|
|
a416ee8f2b | ||
|
|
c14936c63c | ||
|
|
42e7a8b423 | ||
|
|
4558b1c7ef | ||
|
|
f444ba9665 | ||
|
|
787c8d740b | ||
|
|
ef38a8bb2b | ||
|
|
b5d35d346a | ||
|
|
9a7b15d19b | ||
|
|
ba35a11e82 | ||
|
|
00c9efe541 | ||
|
|
44d1ab348b | ||
|
|
f25e4785ae | ||
|
|
4c290aec57 | ||
|
|
42d1d66d9b | ||
|
|
06c25301a5 | ||
|
|
43dbb45cc6 | ||
|
|
9fb62de5cb | ||
|
|
b282df2e27 | ||
|
|
da8f57f397 | ||
|
|
e9f1992c7f | ||
|
|
2c94a6a64e | ||
|
|
6a5e0a8501 | ||
|
|
26d7fe2ff0 | ||
|
|
5854a635ca | ||
|
|
3d4858b840 | ||
|
|
dec2a252fa | ||
|
|
f619ef23fd | ||
|
|
72743e834e | ||
|
|
8e4ddf366c | ||
|
|
b99bd0176a | ||
|
|
a68b98b245 | ||
|
|
a69d6ff1b4 | ||
|
|
ec679e95fd | ||
|
|
3f78235a74 | ||
|
|
c8a2fd78b0 | ||
|
|
45cf08111a | ||
|
|
527ac36129 | ||
|
|
a7232513a7 | ||
|
|
90f187e885 | ||
|
|
235adbbdf1 | ||
|
|
40c88fe385 | ||
|
|
54b7943d17 | ||
|
|
2f100f2ba3 | ||
|
|
b5305aa5e4 | ||
|
|
a2624e36f3 | ||
|
|
540511befd | ||
|
|
014e73d569 | ||
|
|
e2c256db5b | ||
|
|
28aa473362 | ||
|
|
b79506fbcf | ||
|
|
afbd7252ac | ||
|
|
3e5b7cd392 | ||
|
|
77622095d5 | ||
|
|
8ee71300a2 | ||
|
|
d79971edbc | ||
|
|
273ebb22e4 | ||
|
|
6b86e4d463 | ||
|
|
a8e1dc3b18 | ||
|
|
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 |
@@ -8,9 +8,11 @@ RUN pacman --sync --refresh --sysupgrade --needed --noconfirm \
|
||||
gtest \
|
||||
mariadb-libs \
|
||||
protobuf \
|
||||
qt5-base \
|
||||
qt5-multimedia \
|
||||
qt5-svg \
|
||||
qt5-tools \
|
||||
qt5-websockets \
|
||||
qt6-base \
|
||||
qt6-imageformats \
|
||||
qt6-multimedia \
|
||||
qt6-svg \
|
||||
qt6-tools \
|
||||
qt6-translations \
|
||||
qt6-websockets \
|
||||
&& pacman --sync --clean --clean --noconfirm
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM ubuntu:impish
|
||||
FROM debian:11
|
||||
|
||||
RUN apt-get update && \
|
||||
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
|
||||
@@ -17,6 +17,7 @@ RUN apt-get update && \
|
||||
libqt5svg5-dev \
|
||||
libqt5websockets5-dev \
|
||||
protobuf-compiler \
|
||||
qt5-image-formats-plugins \
|
||||
qtmultimedia5-dev \
|
||||
qttools5-dev \
|
||||
qttools5-dev-tools \
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM ubuntu:hirsute
|
||||
FROM debian:12
|
||||
|
||||
RUN apt-get update && \
|
||||
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
|
||||
@@ -9,16 +9,19 @@ RUN apt-get update && \
|
||||
file \
|
||||
g++ \
|
||||
git \
|
||||
libgl-dev \
|
||||
liblzma-dev \
|
||||
libmariadb-dev-compat \
|
||||
libprotobuf-dev \
|
||||
libqt5multimedia5-plugins \
|
||||
libqt5sql5-mysql \
|
||||
libqt5svg5-dev \
|
||||
libqt5websockets5-dev \
|
||||
libqt6multimedia6 \
|
||||
libqt6sql6-mysql \
|
||||
qt6-svg-dev \
|
||||
qt6-websockets-dev \
|
||||
protobuf-compiler \
|
||||
qtmultimedia5-dev \
|
||||
qttools5-dev \
|
||||
qttools5-dev-tools \
|
||||
qt6-image-formats-plugins \
|
||||
qt6-l10n-tools \
|
||||
qt6-multimedia-dev \
|
||||
qt6-tools-dev \
|
||||
qt6-tools-dev-tools \
|
||||
&& apt-get clean \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
@@ -1,24 +0,0 @@
|
||||
FROM debian:buster
|
||||
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
build-essential \
|
||||
ccache \
|
||||
clang-format \
|
||||
cmake \
|
||||
file \
|
||||
g++ \
|
||||
git \
|
||||
liblzma-dev \
|
||||
libmariadb-dev-compat \
|
||||
libprotobuf-dev \
|
||||
libqt5multimedia5-plugins \
|
||||
libqt5sql5-mysql \
|
||||
libqt5svg5-dev \
|
||||
libqt5websockets5-dev \
|
||||
protobuf-compiler \
|
||||
qt5-default \
|
||||
qtbase5-dev \
|
||||
qtmultimedia5-dev \
|
||||
qttools5-dev-tools \
|
||||
&& apt-get clean \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
@@ -1,21 +0,0 @@
|
||||
FROM fedora:34
|
||||
|
||||
RUN dnf install -y \
|
||||
@development-tools \
|
||||
ccache \
|
||||
cmake \
|
||||
desktop-file-utils \
|
||||
file \
|
||||
gcc-c++ \
|
||||
git \
|
||||
hicolor-icon-theme \
|
||||
libappstream-glib \
|
||||
mariadb-devel \
|
||||
protobuf-devel \
|
||||
qt5-{qttools,qtsvg,qtmultimedia,qtwebsockets}-devel \
|
||||
rpm-build \
|
||||
sqlite-devel \
|
||||
wget \
|
||||
xz-devel \
|
||||
zlib-devel \
|
||||
&& dnf clean all
|
||||
@@ -1,21 +0,0 @@
|
||||
FROM fedora:35
|
||||
|
||||
RUN dnf install -y \
|
||||
@development-tools \
|
||||
ccache \
|
||||
cmake \
|
||||
desktop-file-utils \
|
||||
file \
|
||||
gcc-c++ \
|
||||
git \
|
||||
hicolor-icon-theme \
|
||||
libappstream-glib \
|
||||
mariadb-devel \
|
||||
protobuf-devel \
|
||||
qt5-{qttools,qtsvg,qtmultimedia,qtwebsockets}-devel \
|
||||
rpm-build \
|
||||
sqlite-devel \
|
||||
wget \
|
||||
xz-devel \
|
||||
zlib-devel \
|
||||
&& dnf clean all
|
||||
15
.ci/Fedora39/Dockerfile
Normal file
15
.ci/Fedora39/Dockerfile
Normal file
@@ -0,0 +1,15 @@
|
||||
FROM fedora:39
|
||||
|
||||
RUN dnf install -y \
|
||||
ccache \
|
||||
cmake \
|
||||
gcc-c++ \
|
||||
git \
|
||||
mariadb-devel \
|
||||
protobuf-devel \
|
||||
qt6-{qttools,qtsvg,qtmultimedia,qtwebsockets}-devel \
|
||||
qt6-qtimageformats \
|
||||
rpm-build \
|
||||
xz-devel \
|
||||
zlib-devel \
|
||||
&& dnf clean all
|
||||
15
.ci/Fedora40/Dockerfile
Normal file
15
.ci/Fedora40/Dockerfile
Normal file
@@ -0,0 +1,15 @@
|
||||
FROM fedora:40
|
||||
|
||||
RUN dnf install -y \
|
||||
ccache \
|
||||
cmake \
|
||||
gcc-c++ \
|
||||
git \
|
||||
mariadb-devel \
|
||||
protobuf-devel \
|
||||
qt6-{qttools,qtsvg,qtmultimedia,qtwebsockets}-devel \
|
||||
qt6-qtimageformats \
|
||||
rpm-build \
|
||||
xz-devel \
|
||||
zlib-devel \
|
||||
&& dnf clean all
|
||||
@@ -17,6 +17,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
libqt5websockets5-dev \
|
||||
protobuf-compiler \
|
||||
qt5-default \
|
||||
qt5-image-formats-plugins \
|
||||
qtmultimedia5-dev \
|
||||
qttools5-dev \
|
||||
qttools5-dev-tools \
|
||||
|
||||
@@ -18,6 +18,7 @@ RUN apt-get update && \
|
||||
libqt5websockets5-dev \
|
||||
protobuf-compiler \
|
||||
qt5-default \
|
||||
qt5-image-formats-plugins \
|
||||
qtmultimedia5-dev \
|
||||
qttools5-dev \
|
||||
qttools5-dev-tools \
|
||||
|
||||
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 \
|
||||
libqt6multimedia6 \
|
||||
libqt6sql6-mysql \
|
||||
libqt6svg6-dev \
|
||||
libqt6websockets6-dev \
|
||||
protobuf-compiler \
|
||||
qt6-image-formats-plugins \
|
||||
qt6-l10n-tools \
|
||||
qt6-multimedia-dev \
|
||||
qt6-tools-dev \
|
||||
qt6-tools-dev-tools \
|
||||
&& apt-get clean \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
27
.ci/UbuntuNoble/Dockerfile
Normal file
27
.ci/UbuntuNoble/Dockerfile
Normal file
@@ -0,0 +1,27 @@
|
||||
FROM ubuntu:noble
|
||||
|
||||
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 \
|
||||
libqt6multimedia6 \
|
||||
libqt6sql6-mysql \
|
||||
qt6-svg-dev \
|
||||
qt6-websockets-dev \
|
||||
protobuf-compiler \
|
||||
qt6-image-formats-plugins \
|
||||
qt6-l10n-tools \
|
||||
qt6-multimedia-dev \
|
||||
qt6-tools-dev \
|
||||
qt6-tools-dev-tools \
|
||||
&& apt-get clean \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
149
.ci/compile.sh
149
.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,143 @@ 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 2>&1 | 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 .
|
||||
if [[ $RUNNER_OS == Windows ]]; then
|
||||
# Enable MTT, see https://devblogs.microsoft.com/cppblog/improved-parallelism-in-msbuild/
|
||||
# and https://devblogs.microsoft.com/cppblog/cpp-build-throughput-investigation-and-tune-up/#multitooltask-mtt
|
||||
cmake --build . "${buildflags[@]}" -- -p:UseMultiToolTask=true
|
||||
else
|
||||
cmake --build . "${buildflags[@]}"
|
||||
fi
|
||||
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" --output-on-failure
|
||||
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
|
||||
|
||||
@@ -10,10 +10,10 @@ if ! git merge-base origin/master HEAD; then
|
||||
git fetch --unshallow
|
||||
fi
|
||||
|
||||
# Check formatting using clangify
|
||||
echo "Checking your code using clang-format..."
|
||||
# Check formatting using format.sh
|
||||
echo "Checking your code using clang-format/cmake-format..."
|
||||
|
||||
diff="$(./clangify.sh --diff --cf-version --branch origin/master)"
|
||||
diff="$(./format.sh --diff --cmake --cf-version --branch origin/master)"
|
||||
err=$?
|
||||
|
||||
case $err in
|
||||
@@ -24,7 +24,7 @@ case $err in
|
||||
*** ***
|
||||
*** Your code does not comply with our style guide. ***
|
||||
*** ***
|
||||
*** Please correct it or run the "clangify.sh" script. ***
|
||||
*** Please correct it or run the "format.sh" script. ***
|
||||
*** Then commit and push those changes to this branch. ***
|
||||
*** Check our CONTRIBUTING.md file for more details. ***
|
||||
*** ***
|
||||
@@ -32,21 +32,23 @@ case $err in
|
||||
*** ***
|
||||
***********************************************************
|
||||
|
||||
Used clang-format version:
|
||||
Used version:
|
||||
${diff%%
|
||||
----------
|
||||
*}
|
||||
|
||||
The following changes should be made:
|
||||
${diff#*
|
||||
----------
|
||||
}
|
||||
|
||||
Exiting...
|
||||
EOM
|
||||
exit 2
|
||||
;;
|
||||
exit 2
|
||||
;;
|
||||
|
||||
0)
|
||||
cat <<EOM
|
||||
0)
|
||||
cat <<EOM
|
||||
|
||||
***********************************************************
|
||||
*** ***
|
||||
@@ -58,12 +60,10 @@ EOM
|
||||
|
||||
Exiting...
|
||||
EOM
|
||||
exit 0
|
||||
;;
|
||||
exit 0
|
||||
;;
|
||||
|
||||
*)
|
||||
echo ""
|
||||
echo "Something went wrong in our formatting checks: clangify returned $err" >&2
|
||||
echo ""
|
||||
;;
|
||||
esac
|
||||
*)
|
||||
echo "Something went wrong in our formatting checks: format.sh returned $err" >&2
|
||||
;;
|
||||
esac
|
||||
|
||||
@@ -3,8 +3,9 @@
|
||||
# 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
|
||||
# adds output to GITHUB_OUTPUT
|
||||
builddir="${BUILD_DIR:=.}"
|
||||
findrx="Cockatrice-*.*"
|
||||
|
||||
if [[ $1 ]]; then
|
||||
@@ -27,6 +28,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 +47,9 @@ else
|
||||
echo "renaming '$file' to '$filename'"
|
||||
mv "$file" "$filename"
|
||||
fi
|
||||
ls -l "$PWD/$filename"
|
||||
echo "::set-output name=path::$PWD/$filename"
|
||||
echo "::set-output name=name::$filename"
|
||||
|
||||
cd "$oldpwd"
|
||||
relative_path="$path/$filename"
|
||||
ls -l "$relative_path"
|
||||
echo "path=$relative_path" >>"$GITHUB_OUTPUT"
|
||||
echo "name=$filename" >>"$GITHUB_OUTPUT"
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
# the releases are first made as drafts and will be vetted by a human
|
||||
# it just has to provide a template
|
||||
# this requires the repo to be unshallowed
|
||||
# adds output to GITHUB_OUTPUT
|
||||
template_path=".ci/release_template.md"
|
||||
body_path="/tmp/release.md"
|
||||
beta_regex='beta'
|
||||
@@ -22,22 +23,22 @@ fi
|
||||
|
||||
# create title
|
||||
if [[ $TAG =~ $beta_regex ]]; then
|
||||
echo "::set-output name=is_beta::yes"
|
||||
echo "is_beta=yes" >>"$GITHUB_OUTPUT"
|
||||
title="$TAG"
|
||||
echo "creating beta release '$title'"
|
||||
elif [[ ! $(cat CMakeLists.txt) =~ $name_regex ]]; then
|
||||
echo "::error file=$0::could not find releasename in CMakeLists.txt"
|
||||
exit 1
|
||||
else
|
||||
echo "::set-output name=is_beta::no"
|
||||
echo "is_beta=no" >>"$GITHUB_OUTPUT"
|
||||
name="${BASH_REMATCH[1]}"
|
||||
version="${TAG##*-}"
|
||||
title="Cockatrice $version: $name"
|
||||
no_beta=1
|
||||
echo "::set-output name=friendly_name::$name"
|
||||
echo "friendly_name=$name" >>"$GITHUB_OUTPUT"
|
||||
echo "creating full release '$title'"
|
||||
fi
|
||||
echo "::set-output name=title::$title"
|
||||
echo "title=$title" >>"$GITHUB_OUTPUT"
|
||||
|
||||
# add release notes template
|
||||
if [[ $no_beta ]]; then
|
||||
@@ -60,9 +61,9 @@ fi
|
||||
all_tags="
|
||||
$(git tag)" # tags are ordered alphabetically
|
||||
before="${all_tags%%
|
||||
$TAG*}" # strip line with current tag an all lines after it
|
||||
"$TAG"*}" # strip line with current tag an all lines after it
|
||||
# note the extra newlines are needed to always have a last line
|
||||
if [[ $all_tags == $before ]]; then
|
||||
if [[ $all_tags == "$before" ]]; then
|
||||
echo "::warning file=$0::could not find current tag"
|
||||
else
|
||||
while
|
||||
@@ -74,7 +75,7 @@ else
|
||||
beta_list+=" $previous" # add to list of skipped betas
|
||||
next_before="${before%
|
||||
*}" # strip the last line
|
||||
if [[ $next_before == $before ]]; then
|
||||
if [[ $next_before == "$before" ]]; then
|
||||
unset previous
|
||||
break
|
||||
fi
|
||||
@@ -108,5 +109,5 @@ else
|
||||
fi
|
||||
|
||||
# write to file
|
||||
echo "::set-output name=body_path::$body_path"
|
||||
echo "body_path=$body_path" >>"$GITHUB_OUTPUT"
|
||||
echo "$body" >"$body_path"
|
||||
|
||||
@@ -8,26 +8,25 @@ 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+</kbd>
|
||||
- <kbd>Windows 10+</kbd>
|
||||
- <kbd>macOS 10.15+</kbd> ("Catalina")
|
||||
- <kbd>macOS 13+</kbd> ("Ventura")
|
||||
- <kbd>Ubuntu 18.04 LTS</kbd> ("Bionic Beaver")
|
||||
- <kbd>Ubuntu 20.04 LTS</kbd> ("Focal Fossa")
|
||||
- <kbd>Ubuntu 22.04 LTS</kbd> ("Jammy Jellyfish")
|
||||
- <kbd>Ubuntu 24.04 LTS</kbd> ("Noble Numbat")
|
||||
- <kbd>Debian 11</kbd> ("Bullseye")
|
||||
- <kbd>Debian 12</kbd> ("Bookworm")
|
||||
- <kbd>Fedora 39</kbd>
|
||||
- <kbd>Fedora 40</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>
|
||||
<kbd>General Linux support is available via a flatpak package (Flathub)</kbd></i>
|
||||
</pre>
|
||||
|
||||
|
||||
## General Notes
|
||||
|
||||
<!-- --REPLACE-WITH-RELEASE-TITLE-- should be placed here by the ci -->
|
||||
We're pleased to announce the newest official release: <kbd>--REPLACE-WITH-RELEASE-TITLE--</kbd>
|
||||
|
||||
We hope you enjoy the changes made and we have listed all changes, with their corresponding tickets, since the last version of Cockatrice was released for your convenience.
|
||||
@@ -44,7 +43,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>)
|
||||
|
||||
58
.ci/update_translation_source_strings.sh
Executable file
58
.ci/update_translation_source_strings.sh
Executable file
@@ -0,0 +1,58 @@
|
||||
#!/bin/bash
|
||||
|
||||
# ci script to update translation files
|
||||
# usage:
|
||||
# $0 cockatrice/cockatrice_en@source.ts cockatrice/src common
|
||||
# or
|
||||
# FILE="cockatrice/cockatrice_en@source.ts"
|
||||
# DIRS="cockatrice/src common"
|
||||
# $0
|
||||
# note: directories can't contain spaces
|
||||
|
||||
# check parameters
|
||||
if [[ ! $FILE ]]; then
|
||||
FILE="$1"
|
||||
shift
|
||||
fi
|
||||
if [[ ! $FILE ]]; then
|
||||
echo "no output file selected" >&2
|
||||
exit 2;
|
||||
fi
|
||||
if [[ ! $DIRS ]]; then
|
||||
DIRS="$*"
|
||||
fi
|
||||
if [[ ! $DIRS ]]; then
|
||||
echo "no source directories selected to translate" >&2
|
||||
exit 2;
|
||||
fi
|
||||
if [[ ! -e $FILE ]]; then
|
||||
echo "output file does not exist at: $FILE" >&2
|
||||
exit 3;
|
||||
fi
|
||||
|
||||
# print version
|
||||
if ! lupdate -version; then
|
||||
echo "failed to run lupdate" >&2
|
||||
exit 4;
|
||||
fi
|
||||
|
||||
# run lupdate, duplicating the output in stderr and saving it
|
||||
# for convenience we ignore that $DIRS will be split on spaces
|
||||
# shellcheck disable=SC2086
|
||||
if ! got="$(lupdate $DIRS -ts "$FILE" | tee /dev/stderr)"; then
|
||||
echo "failed to update $FILE with $DIRS" >&2
|
||||
exit 4;
|
||||
fi
|
||||
|
||||
# trim output
|
||||
# the line we are interested in is:
|
||||
# Found xxx source text(s) (x new and xxx already existing)
|
||||
output="${got##* source text(s) (}" # get stuff in between brackets
|
||||
output="${output%%)*}" # trim everything after first )
|
||||
if [[ $output == "$got" ]]; then
|
||||
echo "could not parse generated output" >&2
|
||||
exit 4;
|
||||
fi
|
||||
|
||||
# write output to ci environment file
|
||||
echo "output=$output" >> "$GITHUB_OUTPUT"
|
||||
14
.ci/update_translation_source_strings_template.md
Normal file
14
.ci/update_translation_source_strings_template.md
Normal file
@@ -0,0 +1,14 @@
|
||||
Updated source strings for translations:
|
||||
- {{ .cockatrice_output }} (Cockatrice)
|
||||
- {{ .oracle_output }} (Oracle)
|
||||
|
||||
<br>
|
||||
|
||||
Last changes are based on commit {{ .commit }}.
|
||||
|
||||
---
|
||||
*This PR is automatically generated and updated by the workflow at `.github/workflows/translations-push.yml`. Review [action runs][2].*<br>
|
||||
*After merging, all changes to the source language are available for translation at [Transifex][1] shortly.*
|
||||
|
||||
[1]: https://app.transifex.com/cockatrice/cockatrice/
|
||||
[2]: https://github.com/Cockatrice/Cockatrice/actions/workflows/translations-push.yml?query=branch%3Amaster
|
||||
109
.cmake-format.json
Normal file
109
.cmake-format.json
Normal file
@@ -0,0 +1,109 @@
|
||||
{
|
||||
"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": {}
|
||||
},
|
||||
"markup": {
|
||||
"enable_markup": false
|
||||
}
|
||||
}
|
||||
93
.github/CONTRIBUTING.md
vendored
93
.github/CONTRIBUTING.md
vendored
@@ -41,8 +41,8 @@ albeit slightly less active.
|
||||
|
||||
We use a separate job on the CI to check your code for formatting issues. If
|
||||
your pull request failed the test, you can check the output on the checks tab.
|
||||
It's the first job called "linter", you can click the "Run clangify" step to
|
||||
see the output of the test.
|
||||
It's the first job called "linter", you can click the "Check code formatting"
|
||||
step to see the output of the test.
|
||||
|
||||
The message will look like this:
|
||||
```
|
||||
@@ -50,7 +50,7 @@ The message will look like this:
|
||||
*** ***
|
||||
*** Your code does not comply with our style guide. ***
|
||||
*** ***
|
||||
*** Please correct it or run the "clangify.sh" script. ***
|
||||
*** Please correct it or run the "format.sh" script. ***
|
||||
*** Then commit and push those changes to this branch. ***
|
||||
*** Check our CONTRIBUTING.md file for more details. ***
|
||||
*** ***
|
||||
@@ -81,9 +81,9 @@ The handy tool `clang-format` can format your code for you, it is available for
|
||||
almost any environment. A special `.clang-format` configuration file is
|
||||
included in the project and is used to format your code.
|
||||
|
||||
We've also included a bash script, `clangify.sh`, that will use clang-format to
|
||||
format all files in your pr in one go. Use `./clangify.sh --help` to show a
|
||||
full help page.
|
||||
We've also included a bash script, `format.sh`, that will use clang-format to
|
||||
format all files in your pr in one go. Use `./format.sh --help` to show a full
|
||||
help page.
|
||||
|
||||
To run clang-format on a single source file simply use the command
|
||||
`clang-format -i <filename>` to format it in place. (Some systems install
|
||||
@@ -290,20 +290,21 @@ 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;
|
||||
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.
|
||||
2. CI updates the `*_en@source.ts files` regularly and creates a PR automatically;
|
||||
3. Maintainer verifies and merges the change;
|
||||
4. Transifex picks up the new files from GitHub automatically;
|
||||
5. Translators translate the new untranslated strings on Transifex;
|
||||
6. Before a release, a maintainer fetches the updated translations from Transifex.
|
||||
|
||||
### Using Translations (for developers) ###
|
||||
|
||||
All the user-interface strings inside Cockatrice's source code must be written
|
||||
in English(US).
|
||||
All user interface strings inside Cockatrice's source code must be written
|
||||
in English (US).
|
||||
Translations to other languages are managed using [Transifex](
|
||||
https://www.transifex.com/projects/p/cockatrice/).
|
||||
|
||||
Adding a new string to translate is as easy as adding the string in the
|
||||
'tr("")' function, the string will be picked up as translatable automatically
|
||||
`tr("")` function, the string will be picked up as translatable automatically
|
||||
and translated as needed.
|
||||
For example, setting the text of a label in the way that the string
|
||||
`"My name is:"` can be translated:
|
||||
@@ -312,7 +313,7 @@ nameLabel.setText(tr("My name is:"));
|
||||
```
|
||||
|
||||
To translate a string that would have plural forms you can add the amount to
|
||||
the tr call, also you can add an extra string as a hint for translators:
|
||||
the tr() call, also you can add an extra string as a hint for translators:
|
||||
```c++
|
||||
QString message = tr("Everyone draws %n cards", "pop up message", amount);
|
||||
```
|
||||
@@ -321,20 +322,46 @@ https://doc.qt.io/qt-5/i18n-source-translation.html#handling-plurals)
|
||||
|
||||
If you're about to propose a change that adds or modifies any translatable
|
||||
string in the code, you don't need to take care of adding the new strings to
|
||||
the translation files.
|
||||
Every few days, or when a lot of new strings have been added, someone from the
|
||||
development team will take care of extracting all the new strings and adding
|
||||
them to the english translation files and making them available to translators
|
||||
on Transifex.
|
||||
the translation files.<br>
|
||||
We have an automated process to update our language source files on a schedule
|
||||
and provide the translators on Transifex with the new contents.<br>
|
||||
Maintainers can also manually trigger this on demand.
|
||||
|
||||
### Maintaining Translations (for maintainers) ###
|
||||
|
||||
When new translatable strings have been added to the code, a maintainer should
|
||||
make them available to translators on Transifex. Every few days, or when a lot
|
||||
of new strings have been added, a maintainer should take care of extracting all
|
||||
the new strings and add them to the english translation files.
|
||||
When new translatable strings have been added to the code, a maintainer has to
|
||||
make them available to translators on Transifex.
|
||||
|
||||
To update the english translation files, re-run cmake enabling the appropriate
|
||||
To help with that, we have an automated CI workflow, that regularly looks at the
|
||||
code in the master branch, extracts all strings and updates dedicated source string
|
||||
files with any changes. These updates are not commited right away, the CI creates a
|
||||
PR for reviewing instead.<br>
|
||||
After approval, our translation tool automatically picks the changes up and deploys
|
||||
them to our translators. Be mindful when merging only a few changes!
|
||||
|
||||
Once a release is planned, or when a lot of strings have been added or changed, a
|
||||
maintainer can manually trigger a CI run to extract all strings on demand.
|
||||
|
||||
<details>
|
||||
<summary><b>Manually trigger CI run (Workflow Dispatch)</b></summary>
|
||||
|
||||
Maintainers can always request the CI to run on demand if it's required.
|
||||
|
||||
Go to the `Actions` tab and select our dedicated translation workflow:
|
||||
https://github.com/Cockatrice/Cockatrice/actions/workflows/translations.yml
|
||||
|
||||
You see a "This workflow has a workflow_dispatch event trigger." hint at the top of
|
||||
the list.<br>
|
||||
Select `Run workflow` on the right and trigger a run from master branch.
|
||||
|
||||
The CI will now check for changed strings and create a PR if there are any updates.
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><b>Manually update source strings locally</b></summary>
|
||||
|
||||
To update the english source files for translation, re-run cmake enabling the appropriate
|
||||
parameter and then run make:
|
||||
```sh
|
||||
cd cockatrice/build
|
||||
@@ -344,24 +371,26 @@ 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
|
||||
cmake .. -DUPDATE_TRANSLATIONS=OFF
|
||||
```
|
||||
Now you are ready to propose your change.
|
||||
Now you are ready to commit your changes and open a PR.
|
||||
|
||||
Once your change gets merged, Transifex will pick up the modified files
|
||||
automatically (checked every 24 hours) and update the interface where
|
||||
translators will be able to translate the new strings.
|
||||
</details>
|
||||
|
||||
Once the changes get merged, Transifex will pick up the modified files
|
||||
automatically (checked every few hours) and update their online editor where
|
||||
translators will be able to translate the new strings right in the browser.
|
||||
|
||||
### Releasing Translations (for maintainers) ###
|
||||
|
||||
|
||||
49
.github/dependabot.yml
vendored
Normal file
49
.github/dependabot.yml
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
# Configuration options: https://docs.github.com/en/github/administering-a-repository/configuration-options-for-dependency-updates
|
||||
|
||||
version: 2
|
||||
updates:
|
||||
# # Enable version updates for git submodules
|
||||
# Not yet possible to bump only on tags or releases, see:
|
||||
# https://github.com/dependabot/dependabot-core/issues/1639
|
||||
# https://github.com/dependabot/dependabot-core/issues/2192
|
||||
# Alternative: Action that updates submodule and can be manually run on demand (workflow_dispatch)
|
||||
# - package-ecosystem: "gitsubmodule"
|
||||
# # Look for `.gitmodules` in the `root` directory
|
||||
# directory: "/"
|
||||
# # Check for updates once a month
|
||||
# schedule:
|
||||
# interval: "monthly"
|
||||
# # Limit the amout of open PR's (default = 5, disabled = 0, security updates are not impacted)
|
||||
# open-pull-requests-limit: 1
|
||||
|
||||
# # Enable version updates for Docker
|
||||
# Not yet possible to bump from one LTS version to the next and skip others, see:
|
||||
# https://github.com/dependabot/dependabot-core/issues/2247
|
||||
# - package-ecosystem: "docker"
|
||||
# # Look for a `Dockerfile` in the `root` directory
|
||||
# directory: "/"
|
||||
# # Check for updates once a week
|
||||
# schedule:
|
||||
# interval: "weekly"
|
||||
# # Limit the amout of open PR's (default = 5, disabled = 0, security updates are not impacted)
|
||||
# open-pull-requests-limit: 1
|
||||
|
||||
# Enable version updates for GitHub Actions
|
||||
- package-ecosystem: "github-actions"
|
||||
# Directory must be set to "/" to check for workflow files in .github/workflows
|
||||
directory: "/"
|
||||
# Check for updates to GitHub Actions once a week
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
# Limit the amout of open PR's (default = 5, disabled = 0, security updates are not impacted)
|
||||
open-pull-requests-limit: 2
|
||||
|
||||
# # Enable version updates for npm
|
||||
# - package-ecosystem: "npm"
|
||||
# # Look for `package.json` and `lock` files in the `webclient` subdirectory
|
||||
# directory: "/webclient"
|
||||
# # Check the npm registry for updates once a week
|
||||
# schedule:
|
||||
# interval: "weekly"
|
||||
# # Limit the amout of open PR's (default = 5, disabled = 0, security updates are not impacted)
|
||||
# open-pull-requests-limit: 5
|
||||
408
.github/workflows/ci-builds.yml
vendored
408
.github/workflows/ci-builds.yml
vendored
@@ -1,408 +0,0 @@
|
||||
name: Build
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
paths-ignore:
|
||||
- '**.md'
|
||||
- 'webclient/**'
|
||||
tags:
|
||||
- '*'
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
paths-ignore:
|
||||
- '**.md'
|
||||
- 'webclient/**'
|
||||
|
||||
jobs:
|
||||
configure:
|
||||
name: Configure
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
outputs:
|
||||
tag: ${{steps.configure.outputs.tag}}
|
||||
sha: ${{steps.configure.outputs.sha}}
|
||||
upload_url: ${{steps.create_release.outputs.upload_url}}
|
||||
|
||||
steps:
|
||||
- name: Cancel previous runs
|
||||
uses: styfle/cancel-workflow-action@0.6.0
|
||||
with:
|
||||
access_token: ${{github.token}} # needs other token https://github.com/styfle/cancel-workflow-action/issues/7
|
||||
|
||||
- name: Configure
|
||||
id: configure
|
||||
shell: bash
|
||||
run: |
|
||||
tag_regex='^refs/tags/'
|
||||
if [[ $GITHUB_EVENT_NAME == pull-request ]]; then # pull request
|
||||
sha="${{github.event.pull_request.head.sha}}"
|
||||
elif [[ $GITHUB_REF =~ $tag_regex ]]; then # release
|
||||
sha="$GITHUB_SHA"
|
||||
tag="${GITHUB_REF/refs\/tags\//}"
|
||||
echo "::set-output name=tag::$tag"
|
||||
else # push to branch
|
||||
sha="$GITHUB_SHA"
|
||||
fi
|
||||
echo "::set-output name=sha::$sha"
|
||||
|
||||
- name: Checkout
|
||||
if: steps.configure.outputs.tag != null
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Prepare release paramaters
|
||||
id: prepare
|
||||
if: steps.configure.outputs.tag != null
|
||||
shell: bash
|
||||
env:
|
||||
TAG: ${{steps.configure.outputs.tag}}
|
||||
run: .ci/prep_release.sh
|
||||
|
||||
- name: Create release
|
||||
if: steps.configure.outputs.tag != null
|
||||
id: create_release
|
||||
uses: actions/create-release@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{github.token}}
|
||||
with:
|
||||
tag_name: ${{github.ref}}
|
||||
release_name: ${{steps.prepare.outputs.title}}
|
||||
body_path: ${{steps.prepare.outputs.body_path}}
|
||||
draft: true
|
||||
prerelease: ${{steps.prepare.outputs.is_beta == 'yes'}}
|
||||
|
||||
build-linux:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
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
|
||||
package: DEB
|
||||
|
||||
- distro: Fedora35
|
||||
package: RPM
|
||||
|
||||
- distro: Fedora34
|
||||
package: RPM
|
||||
test: skip # gtest does not compile for some reason
|
||||
|
||||
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?
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Get cache timestamp
|
||||
id: cache_timestamp
|
||||
shell: bash
|
||||
run: echo "::set-output name=timestamp::$(date -u '+%Y%m%d%H%M%S')"
|
||||
|
||||
- name: Restore cache
|
||||
uses: actions/cache@v2
|
||||
env:
|
||||
timestamp: ${{steps.cache_timestamp.outputs.timestamp}}
|
||||
with:
|
||||
path: ${{env.CACHE}}
|
||||
key: docker-${{matrix.distro}}-cache-${{env.timestamp}}
|
||||
restore-keys: |
|
||||
docker-${{matrix.distro}}-cache-
|
||||
|
||||
- name: Build ${{matrix.distro}} Docker image
|
||||
shell: bash
|
||||
run: source .ci/docker.sh --build
|
||||
|
||||
- name: Build debug and test
|
||||
if: matrix.test != 'skip'
|
||||
shell: bash
|
||||
run: |
|
||||
source .ci/docker.sh
|
||||
RUN --server --debug --test
|
||||
|
||||
- name: Build release package
|
||||
id: package
|
||||
if: matrix.package != 'skip'
|
||||
shell: bash
|
||||
env:
|
||||
suffix: '-${{matrix.distro}}'
|
||||
type: '${{matrix.package}}'
|
||||
run: |
|
||||
source .ci/docker.sh
|
||||
RUN --server --release --package "$type" --suffix "$suffix"
|
||||
|
||||
- name: Upload artifact
|
||||
if: matrix.package != 'skip'
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: ${{matrix.distro}}-package
|
||||
path: ./build/${{steps.package.outputs.name}}
|
||||
if-no-files-found: error
|
||||
|
||||
- name: Upload to release
|
||||
if: matrix.package != 'skip' && needs.configure.outputs.tag != null
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
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_content_type: application/octet-stream
|
||||
|
||||
build-macos:
|
||||
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
|
||||
type: Debug
|
||||
do_tests: 0 # tests do not work yet on mac
|
||||
make_package: false
|
||||
|
||||
- target: 10.14_Mojave
|
||||
os: macos-10.15 # runs on Catalina
|
||||
xcode: 10.3 # allows compatibility with macOS 10.14
|
||||
type: Release
|
||||
do_tests: 0
|
||||
make_package: true
|
||||
|
||||
- target: 10.15_Catalina
|
||||
os: macos-10.15
|
||||
xcode: 12.1
|
||||
type: Release
|
||||
do_tests: 0
|
||||
make_package: true
|
||||
|
||||
- target: 11_Big_Sur
|
||||
os: macos-11
|
||||
xcode: 12.5.1
|
||||
type: Release
|
||||
do_tests: 0
|
||||
make_package: true
|
||||
|
||||
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
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Install dependencies using homebrew
|
||||
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-
|
||||
|
||||
- name: Build on Xcode ${{matrix.xcode}}
|
||||
shell: bash
|
||||
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}}"
|
||||
|
||||
- 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}}
|
||||
if-no-files-found: error
|
||||
|
||||
- name: Upload to release
|
||||
if: matrix.make_package && needs.configure.outputs.tag != null
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
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_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}}
|
||||
|
||||
needs: configure
|
||||
|
||||
runs-on: windows-latest
|
||||
|
||||
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
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Restore Qt ${{env.QT_VERSION}} ${{matrix.arch}}-bit from cache
|
||||
id: cache-qt
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
key: ${{runner.os}}-QtCache-${{env.QT_VERSION}}-${{matrix.arch}}
|
||||
path: ${{runner.workspace}}/Qt
|
||||
|
||||
- name: Install ${{matrix.arch}}-bit Qt
|
||||
uses: jurplel/install-qt-action@v2
|
||||
with:
|
||||
cached: ${{steps.cache-qt.outputs.cache-hit}}
|
||||
version: ${{env.QT_VERSION}}
|
||||
arch: win${{matrix.arch}}_${{env.QT_ARCH}}
|
||||
|
||||
- name: Restore or setup vcpkg
|
||||
uses: lukka/run-vcpkg@v6
|
||||
with:
|
||||
vcpkgArguments: '@${{github.workspace}}/vcpkg.txt'
|
||||
vcpkgDirectory: ${{github.workspace}}/vcpkg
|
||||
appendedCacheKey: ${{hashFiles('**/vcpkg.txt')}}
|
||||
vcpkgTriplet: ${{matrix.triplet}}-windows
|
||||
|
||||
- name: Configure Cockatrice ${{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
|
||||
|
||||
- name: Build Cockatrice ${{matrix.arch}}-bit
|
||||
id: package
|
||||
shell: bash
|
||||
working-directory: build
|
||||
run: |
|
||||
cmake --build . --target package --config Release
|
||||
../.ci/name_build.sh "-win${{matrix.arch}}"
|
||||
|
||||
- name: Run tests
|
||||
shell: bash
|
||||
working-directory: build
|
||||
run: ctest -T Test -C Release
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: Windows-${{matrix.arch}}bit-installer
|
||||
path: ./build/${{steps.package.outputs.name}}
|
||||
if-no-files-found: error
|
||||
|
||||
- name: Upload to release
|
||||
if: needs.configure.outputs.tag != null
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
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_content_type: application/octet-stream
|
||||
380
.github/workflows/desktop-build.yml
vendored
Normal file
380
.github/workflows/desktop-build.yml
vendored
Normal file
@@ -0,0 +1,380 @@
|
||||
name: Build Desktop
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
paths-ignore:
|
||||
- '**.md'
|
||||
- 'webclient/**'
|
||||
- '.github/workflows/web-*.yml'
|
||||
- '.github/workflows/translations-*.yml'
|
||||
tags:
|
||||
- '*'
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- '**.md'
|
||||
- 'webclient/**'
|
||||
- '.github/workflows/web-*.yml'
|
||||
- '.github/workflows/translations-*.yml'
|
||||
|
||||
# Cancel earlier, unfinished runs of this workflow on the same branch (unless on master)
|
||||
concurrency:
|
||||
group: "${{ github.workflow }} @ ${{ github.ref_name }}"
|
||||
cancel-in-progress: ${{ github.ref_name != 'master' }}
|
||||
|
||||
jobs:
|
||||
configure:
|
||||
name: Configure
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
tag: ${{steps.configure.outputs.tag}}
|
||||
sha: ${{steps.configure.outputs.sha}}
|
||||
|
||||
steps:
|
||||
- name: Configure
|
||||
id: configure
|
||||
shell: bash
|
||||
run: |
|
||||
tag_regex='^refs/tags/'
|
||||
if [[ $GITHUB_EVENT_NAME == pull-request ]]; then # pull request
|
||||
sha="${{github.event.pull_request.head.sha}}"
|
||||
elif [[ $GITHUB_REF =~ $tag_regex ]]; then # release
|
||||
sha="$GITHUB_SHA"
|
||||
tag="${GITHUB_REF/refs\/tags\//}"
|
||||
echo "tag=$tag" >>"$GITHUB_OUTPUT"
|
||||
else # push to branch
|
||||
sha="$GITHUB_SHA"
|
||||
fi
|
||||
echo "sha=$sha" >>"$GITHUB_OUTPUT"
|
||||
|
||||
- name: Checkout
|
||||
if: steps.configure.outputs.tag != null
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Prepare release parameters
|
||||
id: prepare
|
||||
if: steps.configure.outputs.tag != null
|
||||
shell: bash
|
||||
env:
|
||||
TAG: ${{steps.configure.outputs.tag}}
|
||||
run: .ci/prep_release.sh
|
||||
|
||||
- name: Create release
|
||||
if: steps.configure.outputs.tag != null
|
||||
id: create_release
|
||||
shell: bash
|
||||
env:
|
||||
GH_TOKEN: ${{github.token}}
|
||||
tag_name: ${{steps.configure.outputs.tag}}
|
||||
target: ${{steps.configure.outputs.sha}}
|
||||
release_name: ${{steps.prepare.outputs.title}}
|
||||
body_path: ${{steps.prepare.outputs.body_path}}
|
||||
prerelease: ${{steps.prepare.outputs.is_beta}}
|
||||
run: |
|
||||
if [[ $prerelease == yes ]]; then
|
||||
args="--prerelease"
|
||||
fi
|
||||
gh release create "$tag_name" --draft --verify-tag $args \
|
||||
--target "$target" --title "$release_name" \
|
||||
--notes-file "$body_path"
|
||||
|
||||
build-linux:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
# these names correspond to the files in .ci/$distro
|
||||
include:
|
||||
- distro: ArchLinux
|
||||
package: skip # we are packaged in arch already
|
||||
allow-failure: yes
|
||||
|
||||
- distro: Debian11
|
||||
package: DEB
|
||||
|
||||
- distro: Debian12
|
||||
package: DEB
|
||||
|
||||
- distro: Fedora39
|
||||
package: RPM
|
||||
|
||||
- distro: Fedora40
|
||||
package: RPM
|
||||
|
||||
- distro: UbuntuBionic
|
||||
package: DEB
|
||||
|
||||
- distro: UbuntuFocal
|
||||
package: DEB
|
||||
test: skip # UbuntuFocal has a broken qt for debug builds
|
||||
|
||||
- distro: UbuntuJammy
|
||||
package: DEB
|
||||
test: skip # running tests on all distros is superfluous
|
||||
|
||||
- distro: UbuntuNoble
|
||||
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
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Get cache timestamp
|
||||
id: cache_timestamp
|
||||
shell: bash
|
||||
run: echo "timestamp=$(date -u '+%Y%m%d%H%M%S')" >>"$GITHUB_OUTPUT"
|
||||
|
||||
- name: Restore cache
|
||||
uses: actions/cache@v4
|
||||
env:
|
||||
timestamp: ${{steps.cache_timestamp.outputs.timestamp}}
|
||||
with:
|
||||
path: ${{env.CACHE}}
|
||||
key: docker-${{matrix.distro}}-cache-${{env.timestamp}}
|
||||
restore-keys: |
|
||||
docker-${{matrix.distro}}-cache-
|
||||
|
||||
- name: Build ${{matrix.distro}} Docker image
|
||||
shell: bash
|
||||
run: source .ci/docker.sh --build
|
||||
|
||||
- name: Build debug and test
|
||||
if: matrix.test != 'skip'
|
||||
shell: bash
|
||||
env:
|
||||
distro: '${{matrix.distro}}'
|
||||
run: |
|
||||
source .ci/docker.sh
|
||||
RUN --server --debug --test --ccache "$CCACHE_SIZE" --parallel 4
|
||||
|
||||
- name: Build release package
|
||||
id: build
|
||||
if: matrix.package != 'skip'
|
||||
shell: bash
|
||||
env:
|
||||
BUILD_DIR: build
|
||||
SUFFIX: '-${{matrix.distro}}'
|
||||
distro: '${{matrix.distro}}'
|
||||
type: '${{matrix.package}}'
|
||||
run: |
|
||||
source .ci/docker.sh
|
||||
RUN --server --release --package "$type" --dir "$BUILD_DIR" \
|
||||
--ccache "$CCACHE_SIZE" --parallel 4
|
||||
.ci/name_build.sh
|
||||
|
||||
- name: Upload artifact
|
||||
if: matrix.package != 'skip'
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{matrix.distro}}-package
|
||||
path: ${{steps.build.outputs.path}}
|
||||
if-no-files-found: error
|
||||
|
||||
- name: Upload to release
|
||||
if: matrix.package != 'skip' && needs.configure.outputs.tag != null
|
||||
shell: bash
|
||||
env:
|
||||
GH_TOKEN: ${{github.token}}
|
||||
tag_name: ${{needs.configure.outputs.tag}}
|
||||
asset_path: ${{steps.build.outputs.path}}
|
||||
asset_name: ${{steps.build.outputs.name}}
|
||||
run: gh release upload "$tag_name" "$asset_path#$asset_name"
|
||||
|
||||
build-macos:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- target: Debug # tests only
|
||||
os: macos-latest
|
||||
xcode: 14.2
|
||||
qt_version: homebrew
|
||||
type: Debug
|
||||
do_tests: 1
|
||||
|
||||
- target: 10.15_Catalina
|
||||
os: macos-11
|
||||
xcode: 11.7 # allows using macOS 10.15 SDK
|
||||
qt_version: 6.2.* # 6.2 is last LTS compatible with 10.15, see https://doc.qt.io/qt-6.5/macos.html
|
||||
qt_modules: "qtmultimedia qtwebsockets"
|
||||
type: Release
|
||||
do_tests: 1
|
||||
make_package: 1
|
||||
use_old_protobuf: 1
|
||||
qt_py7zrversion: '==0.20.*'
|
||||
|
||||
- target: 13_Ventura
|
||||
os: macos-13
|
||||
xcode: 14.3.1
|
||||
qt_version: homebrew
|
||||
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:
|
||||
DEVELOPER_DIR:
|
||||
/Applications/Xcode_${{matrix.xcode}}.app/Contents/Developer
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install dependencies using homebrew
|
||||
shell: bash
|
||||
# cmake cannot find the mysql connector
|
||||
# neither of these works: mariadb-connector-c mysql-connector-c++
|
||||
env:
|
||||
install_qt: ${{matrix.qt_version}}
|
||||
use_old_protobuf: ${{matrix.use_old_protobuf}}
|
||||
HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK: 1
|
||||
run: |
|
||||
brew update
|
||||
if [[ $use_old_protobuf == 1 ]]; then
|
||||
brew install protobuf@21
|
||||
brew link --force protobuf@21
|
||||
else
|
||||
brew install protobuf
|
||||
brew link --force protobuf
|
||||
fi
|
||||
if [[ $install_qt == homebrew ]]; then
|
||||
brew install qt --force-bottle
|
||||
else # for some reason the tests fail with the action installed qt?
|
||||
brew install googletest
|
||||
fi
|
||||
|
||||
- name: Install Qt ${{matrix.qt_version}} for ${{matrix.target}}
|
||||
if: matrix.qt_version != 'homebrew'
|
||||
uses: jurplel/install-qt-action@v3
|
||||
with:
|
||||
cache: true
|
||||
setup-python: false
|
||||
version: ${{matrix.qt_version}}
|
||||
modules: ${{matrix.qt_modules}}
|
||||
py7zrversion: ${{matrix.qt_py7zrversion}}
|
||||
|
||||
- name: Build on Xcode ${{matrix.xcode}}
|
||||
shell: bash
|
||||
id: build
|
||||
env:
|
||||
BUILDTYPE: '${{matrix.type}}'
|
||||
MAKE_TEST: '${{matrix.do_tests}}'
|
||||
MAKE_PACKAGE: '${{matrix.make_package}}'
|
||||
PACKAGE_SUFFIX: '-macOS-${{matrix.target}}'
|
||||
# macOS runner actually have only 3 cores
|
||||
# See https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners/about-github-hosted-runners#supported-runners-and-hardware-resources
|
||||
run: .ci/compile.sh --server --parallel 3
|
||||
|
||||
- name: Upload artifact
|
||||
if: matrix.make_package
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: macOS-${{matrix.target}}-dmg
|
||||
path: ${{steps.build.outputs.path}}
|
||||
if-no-files-found: error
|
||||
|
||||
- name: Upload to release
|
||||
if: matrix.package != 'skip' && needs.configure.outputs.tag != null
|
||||
shell: bash
|
||||
env:
|
||||
GH_TOKEN: ${{github.token}}
|
||||
tag_name: ${{needs.configure.outputs.tag}}
|
||||
asset_path: ${{steps.build.outputs.path}}
|
||||
asset_name: ${{steps.build.outputs.name}}
|
||||
run: gh release upload "$tag_name" "$asset_path#$asset_name"
|
||||
|
||||
build-windows:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- target: 7
|
||||
qt_version: 5.15.*
|
||||
qt_arch: msvc2019_64
|
||||
qt_tools: "tools_opensslv3_x64"
|
||||
|
||||
- target: 10
|
||||
qt_version: 6.5.*
|
||||
qt_arch: msvc2019_64
|
||||
qt_tools: "tools_opensslv3_x64"
|
||||
qt_modules: "qtmultimedia qtwebsockets"
|
||||
|
||||
name: Windows ${{matrix.target}}
|
||||
needs: configure
|
||||
runs-on: windows-2019
|
||||
env:
|
||||
CMAKE_GENERATOR: 'Visual Studio 16 2019'
|
||||
|
||||
steps:
|
||||
- name: Add msbuild to PATH
|
||||
id: add-msbuild
|
||||
uses: microsoft/setup-msbuild@v2
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Install Qt ${{matrix.qt_version}}
|
||||
uses: jurplel/install-qt-action@v3
|
||||
with:
|
||||
cache: true
|
||||
setup-python: false
|
||||
version: ${{matrix.qt_version}}
|
||||
arch: win64_${{matrix.qt_arch}}
|
||||
tools: ${{matrix.qt_tools}}
|
||||
modules: ${{matrix.qt_modules}}
|
||||
|
||||
- name: Run vcpkg
|
||||
uses: lukka/run-vcpkg@v11
|
||||
with:
|
||||
runVcpkgInstall: true
|
||||
doNotCache: false
|
||||
env:
|
||||
VCPKG_DEFAULT_TRIPLET: 'x64-windows'
|
||||
VCPKG_DISABLE_METRICS: 1
|
||||
|
||||
- name: Build Cockatrice
|
||||
id: build
|
||||
shell: bash
|
||||
env:
|
||||
PACKAGE_SUFFIX: '-Win${{matrix.target}}'
|
||||
CMAKE_GENERATOR: '${{env.CMAKE_GENERATOR}}'
|
||||
CMAKE_GENERATOR_PLATFORM: 'x64'
|
||||
QTDIR: '${{github.workspace}}\Qt\${{matrix.qt_version}}\win64_${{matrix.qt_arch}}'
|
||||
# No need for --parallel flag, MTT is added in the compile script to let cmake/msbuild manage core count,
|
||||
# project and process parallelism: https://devblogs.microsoft.com/cppblog/improved-parallelism-in-msbuild/
|
||||
run: .ci/compile.sh --server --release --test --package
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: Windows${{matrix.target}}-installer
|
||||
path: ${{steps.build.outputs.path}}
|
||||
if-no-files-found: error
|
||||
|
||||
- name: Upload to release
|
||||
if: matrix.package != 'skip' && needs.configure.outputs.tag != null
|
||||
shell: bash
|
||||
env:
|
||||
GH_TOKEN: ${{github.token}}
|
||||
tag_name: ${{needs.configure.outputs.tag}}
|
||||
asset_path: ${{steps.build.outputs.path}}
|
||||
asset_name: ${{steps.build.outputs.name}}
|
||||
run: gh release upload "$tag_name" "$asset_path#$asset_name"
|
||||
@@ -2,28 +2,28 @@ name: Code Style (C++)
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
paths-ignore:
|
||||
- '**.md'
|
||||
- 'webclient/**'
|
||||
- '.github/workflows/web-*.yml'
|
||||
- '.github/workflows/translations-*.yml'
|
||||
|
||||
jobs:
|
||||
clang-format:
|
||||
runs-on: ubuntu-latest
|
||||
format:
|
||||
runs-on: ubuntu-22.04
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 20 # should be enough to find merge base
|
||||
|
||||
- name: Install clang-format
|
||||
- name: Install dependencies
|
||||
shell: bash
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y --no-install-recommends clang-format
|
||||
sudo apt-get install -y --no-install-recommends clang-format cmake-format
|
||||
|
||||
- name: Run clangify
|
||||
- name: Check code formatting
|
||||
shell: bash
|
||||
run: ./.ci/lint_cpp.sh
|
||||
72
.github/workflows/translations-pull.yml
vendored
Normal file
72
.github/workflows/translations-pull.yml
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
name: Update Translations
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
# runs in the middle of each month starting a quarter (UTC) = two weeks after new strings are built
|
||||
- cron: '0 0 15 1,4,7,10 *'
|
||||
pull_request:
|
||||
paths:
|
||||
- '.github/workflows/translations-pull.yml'
|
||||
|
||||
jobs:
|
||||
translations:
|
||||
# Do not run the scheduled workflow on forks
|
||||
if: github.event_name != 'schedule' || github.repository_owner == 'Cockatrice'
|
||||
|
||||
name: Pull languages
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Pull translated strings from Transifex
|
||||
uses: transifex/cli-action@v2
|
||||
with:
|
||||
# used config file: https://github.com/Cockatrice/Cockatrice/blob/master/.tx/config
|
||||
# https://github.com/transifex/cli#pulling-files-from-transifex
|
||||
token: ${{ secrets.TX_TOKEN }}
|
||||
args: pull --force --all
|
||||
|
||||
- name: Create pull request
|
||||
if: github.event_name != 'pull_request'
|
||||
id: create_pr
|
||||
uses: peter-evans/create-pull-request@v6
|
||||
with:
|
||||
add-paths: |
|
||||
cockatrice/translations/*.ts
|
||||
oracle/translations/*.ts
|
||||
webclient/public/locales/*/translation.json
|
||||
commit-message: Update translation files
|
||||
# author is the owner of the commit
|
||||
author: github-actions <github-actions@github.com>
|
||||
branch: ci-update_translations
|
||||
delete-branch: true
|
||||
title: 'Update translations'
|
||||
body: |
|
||||
Pulled all translated strings from [Transifex][1].
|
||||
|
||||
---
|
||||
*This PR is automatically generated and updated by the workflow at `.github/workflows/translations-pull.yml`. Review [action runs][2].*<br>
|
||||
*After merging, all new languages and translations are available in the next build.*
|
||||
|
||||
[1]: https://app.transifex.com/cockatrice/cockatrice/
|
||||
[2]: https://github.com/Cockatrice/Cockatrice/actions/workflows/translations-pull.yml?query=branch%3Amaster
|
||||
labels: |
|
||||
CI
|
||||
Translation
|
||||
draft: false
|
||||
|
||||
- name: PR Status
|
||||
if: github.event_name != 'pull_request'
|
||||
shell: bash
|
||||
env:
|
||||
STATUS: ${{ steps.create_pr.outputs.pull-request-operation }}
|
||||
run: |
|
||||
if [[ "$STATUS" == "" ]]; then
|
||||
echo "PR #${{ steps.create_pr.outputs.pull-request-number }} unchanged!" >> $GITHUB_STEP_SUMMARY
|
||||
else
|
||||
echo "PR #${{ steps.create_pr.outputs.pull-request-number }} $STATUS!" >> $GITHUB_STEP_SUMMARY
|
||||
fi
|
||||
echo "URL: ${{ steps.create_pr.outputs.pull-request-url }}" >> $GITHUB_STEP_SUMMARY
|
||||
87
.github/workflows/translations-push.yml
vendored
Normal file
87
.github/workflows/translations-push.yml
vendored
Normal file
@@ -0,0 +1,87 @@
|
||||
name: Update Translation Source
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
# runs at the start of each quarter (UTC)
|
||||
- cron: '0 0 1 1,4,7,10 *'
|
||||
pull_request:
|
||||
paths:
|
||||
- '.github/workflows/translations-push.yml'
|
||||
|
||||
jobs:
|
||||
translations:
|
||||
# Do not run the scheduled workflow on forks
|
||||
if: github.event_name != 'schedule' || github.repository_owner == 'Cockatrice'
|
||||
|
||||
name: Push strings
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install lupdate
|
||||
shell: bash
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y --no-install-recommends qttools5-dev-tools
|
||||
|
||||
- name: Update Cockatrice translation source
|
||||
id: cockatrice
|
||||
shell: bash
|
||||
env:
|
||||
FILE: 'cockatrice/cockatrice_en@source.ts'
|
||||
DIRS: 'cockatrice/src common'
|
||||
run: .ci/update_translation_source_strings.sh
|
||||
|
||||
- name: Update Oracle translation source
|
||||
id: oracle
|
||||
shell: bash
|
||||
env:
|
||||
FILE: 'oracle/oracle_en@source.ts'
|
||||
DIRS: 'oracle/src'
|
||||
run: .ci/update_translation_source_strings.sh
|
||||
|
||||
- name: Render template
|
||||
id: template
|
||||
uses: chuhlomin/render-template@v1
|
||||
with:
|
||||
template: .ci/update_translation_source_strings_template.md
|
||||
vars: |
|
||||
cockatrice_output: ${{ steps.cockatrice.outputs.output }}
|
||||
oracle_output: ${{ steps.oracle.outputs.output }}
|
||||
commit: ${{ github.sha }}
|
||||
|
||||
- name: Create pull request
|
||||
if: github.event_name != 'pull_request'
|
||||
id: create_pr
|
||||
uses: peter-evans/create-pull-request@v6
|
||||
with:
|
||||
add-paths: |
|
||||
cockatrice/cockatrice_en@source.ts
|
||||
oracle/oracle_en@source.ts
|
||||
commit-message: Update translation source strings
|
||||
# author is the owner of the commit
|
||||
author: github-actions <github-actions@github.com>
|
||||
branch: ci-update_translation_source
|
||||
delete-branch: true
|
||||
title: 'Update source strings'
|
||||
body: ${{ steps.template.outputs.result }}
|
||||
labels: |
|
||||
CI
|
||||
Translation
|
||||
draft: false
|
||||
|
||||
- name: PR Status
|
||||
if: github.event_name != 'pull_request'
|
||||
shell: bash
|
||||
env:
|
||||
STATUS: ${{ steps.create_pr.outputs.pull-request-operation }}
|
||||
run: |
|
||||
if [[ "$STATUS" == "" ]]; then
|
||||
echo "PR #${{ steps.create_pr.outputs.pull-request-number }} unchanged!" >> $GITHUB_STEP_SUMMARY
|
||||
else
|
||||
echo "PR #${{ steps.create_pr.outputs.pull-request-number }} $STATUS!" >> $GITHUB_STEP_SUMMARY
|
||||
fi
|
||||
echo "URL: ${{ steps.create_pr.outputs.pull-request-url }}" >> $GITHUB_STEP_SUMMARY
|
||||
52
.github/workflows/web-build.yml
vendored
Normal file
52
.github/workflows/web-build.yml
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
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:
|
||||
- 16
|
||||
- lts/*
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
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@v4
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
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
|
||||
5
.gitignore
vendored
5
.gitignore
vendored
@@ -6,7 +6,10 @@ mysql.cnf
|
||||
.DS_Store
|
||||
.idea/
|
||||
*.aps
|
||||
cmake-build-debug/
|
||||
cmake-build-debug*
|
||||
preferences
|
||||
compile_commands.json
|
||||
.vs/
|
||||
.vscode/
|
||||
.cache
|
||||
.gdb_history
|
||||
|
||||
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
|
||||
27
.tx/config
27
.tx/config
@@ -1,13 +1,26 @@
|
||||
[main]
|
||||
host = https://www.transifex.com
|
||||
host = https://app.transifex.com
|
||||
|
||||
[cockatrice.cockatrice]
|
||||
[o:cockatrice:p:cockatrice:r:cockatrice-cockatrice-en-source-ts--master]
|
||||
resource_name = Cockatrice
|
||||
source_lang = en
|
||||
source_file = cockatrice/cockatrice_en@source.ts
|
||||
file_filter = cockatrice/translations/cockatrice_<lang>.ts
|
||||
source_file = cockatrice/translations/cockatrice_en.ts
|
||||
source_lang = en
|
||||
type = QT
|
||||
minimum_perc = 10
|
||||
|
||||
[cockatrice.oracle]
|
||||
[o:cockatrice:p:cockatrice:r:oracle-oracle-en-source-ts--master]
|
||||
resource_name = Oracle
|
||||
source_lang = en
|
||||
source_file = oracle/oracle_en@source.ts
|
||||
file_filter = oracle/translations/oracle_<lang>.ts
|
||||
source_file = oracle/translations/oracle_en.ts
|
||||
source_lang = en
|
||||
type = QT
|
||||
minimum_perc = 10
|
||||
|
||||
[o:cockatrice:p:cockatrice:r:webclient-src-i18n-default-json--master]
|
||||
resource_name = Webclient
|
||||
source_lang = en
|
||||
source_file = webclient/src/i18n-default.json
|
||||
file_filter = webclient/public/locales/<lang>/translation.json
|
||||
type = KEYVALUEJSON
|
||||
minimum_perc = 10
|
||||
|
||||
438
CMakeLists.txt
438
CMakeLists.txt
@@ -5,58 +5,95 @@
|
||||
# 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)
|
||||
SET(CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE} CACHE STRING "Type of build")
|
||||
ELSE()
|
||||
SET(CMAKE_BUILD_TYPE Release CACHE STRING "Type of build")
|
||||
ENDIF()
|
||||
if(DEFINED CMAKE_BUILD_TYPE)
|
||||
set(CMAKE_BUILD_TYPE
|
||||
${CMAKE_BUILD_TYPE}
|
||||
CACHE STRING "Type of build"
|
||||
)
|
||||
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)
|
||||
# Support Unix Makefiles and Ninja
|
||||
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${CCACHE_PROGRAM}")
|
||||
MESSAGE(STATUS "Found CCache ${CCACHE_PROGRAM}")
|
||||
endif()
|
||||
find_program(CCACHE_PROGRAM ccache)
|
||||
if(CCACHE_PROGRAM)
|
||||
# Support Unix Makefiles and Ninja
|
||||
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${CCACHE_PROGRAM}")
|
||||
message(STATUS "Found CCache ${CCACHE_PROGRAM}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
# Use vcpkg toolchain on Windows
|
||||
set(CMAKE_TOOLCHAIN_FILE ${CMAKE_CURRENT_SOURCE_DIR}/vcpkg/scripts/buildsystems/vcpkg.cmake
|
||||
CACHE STRING "Vcpkg toolchain file")
|
||||
# Qt path set by user or env var
|
||||
if (QTDIR OR DEFINED ENV{QTDIR} OR DEFINED ENV{QTDIR32} OR DEFINED ENV{QTDIR64})
|
||||
else()
|
||||
set(QTDIR "" CACHE PATH "Path to Qt (e.g. C:/Qt/5.7/msvc2015_64)")
|
||||
message(WARNING "QTDIR variable is missing. Please set this variable to specify path to Qt (e.g. C:/Qt/5.7/msvc2015_64)")
|
||||
endif()
|
||||
# Use vcpkg toolchain on Windows
|
||||
set(CMAKE_TOOLCHAIN_FILE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/vcpkg/scripts/buildsystems/vcpkg.cmake
|
||||
CACHE STRING "Vcpkg toolchain file"
|
||||
)
|
||||
# Qt path set by user or env var
|
||||
if(QTDIR
|
||||
OR DEFINED ENV{QTDIR}
|
||||
OR DEFINED ENV{QTDIR32}
|
||||
OR DEFINED ENV{QTDIR64}
|
||||
)
|
||||
|
||||
else()
|
||||
set(QTDIR
|
||||
""
|
||||
CACHE PATH "Path to Qt (e.g. C:/Qt/5.7/msvc2015_64)"
|
||||
)
|
||||
message(
|
||||
WARNING "QTDIR variable is missing. Please set this variable to specify path to Qt (e.g. C:/Qt/5.7/msvc2015_64)"
|
||||
)
|
||||
endif()
|
||||
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.9.1)
|
||||
|
||||
# Set release name if not provided via env/cmake var
|
||||
if(NOT DEFINED GIT_TAG_RELEASENAME)
|
||||
set(GIT_TAG_RELEASENAME "Prismatic Bridge")
|
||||
set(GIT_TAG_RELEASENAME "Rings of the Wild")
|
||||
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)
|
||||
|
||||
@@ -65,152 +102,150 @@ include(createversionfile)
|
||||
|
||||
# Define a proper install path
|
||||
if(UNIX)
|
||||
if(APPLE)
|
||||
# macOS
|
||||
# Due to the special bundle structure ignore
|
||||
# the prefix eventually set by the user.
|
||||
set(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/release)
|
||||
if(APPLE)
|
||||
# macOS
|
||||
# Due to the special bundle structure ignore
|
||||
# the prefix eventually set by the user.
|
||||
set(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/release)
|
||||
|
||||
# Force ccache usage if available
|
||||
get_property(RULE_LAUNCH_COMPILE GLOBAL PROPERTY RULE_LAUNCH_COMPILE)
|
||||
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)
|
||||
execute_process(COMMAND chmod a+rx
|
||||
"${CMAKE_BINARY_DIR}/launch-c"
|
||||
"${CMAKE_BINARY_DIR}/launch-cxx")
|
||||
# Force ccache usage if available
|
||||
get_property(RULE_LAUNCH_COMPILE GLOBAL PROPERTY RULE_LAUNCH_COMPILE)
|
||||
if(RULE_LAUNCH_COMPILE)
|
||||
message(STATUS "Force enabling CCache usage under macOS")
|
||||
# Set up wrapper scripts
|
||||
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")
|
||||
|
||||
# Set Xcode project attributes to route compilation through our scripts
|
||||
set(CMAKE_XCODE_ATTRIBUTE_CC "${CMAKE_BINARY_DIR}/launch-c")
|
||||
set(CMAKE_XCODE_ATTRIBUTE_CXX "${CMAKE_BINARY_DIR}/launch-cxx")
|
||||
set(CMAKE_XCODE_ATTRIBUTE_LD "${CMAKE_BINARY_DIR}/launch-c")
|
||||
set(CMAKE_XCODE_ATTRIBUTE_LDPLUSPLUS "${CMAKE_BINARY_DIR}/launch-cxx")
|
||||
endif()
|
||||
else()
|
||||
# Linux / BSD
|
||||
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
|
||||
#fix package build
|
||||
if(PREFIX)
|
||||
set(CMAKE_INSTALL_PREFIX ${PREFIX})
|
||||
else()
|
||||
set(CMAKE_INSTALL_PREFIX /usr/local)
|
||||
endif()
|
||||
endif()
|
||||
# Set Xcode project attributes to route compilation through our scripts
|
||||
set(CMAKE_XCODE_ATTRIBUTE_CC "${CMAKE_BINARY_DIR}/launch-c")
|
||||
set(CMAKE_XCODE_ATTRIBUTE_CXX "${CMAKE_BINARY_DIR}/launch-cxx")
|
||||
set(CMAKE_XCODE_ATTRIBUTE_LD "${CMAKE_BINARY_DIR}/launch-c")
|
||||
set(CMAKE_XCODE_ATTRIBUTE_LDPLUSPLUS "${CMAKE_BINARY_DIR}/launch-cxx")
|
||||
endif()
|
||||
else()
|
||||
# Linux / BSD
|
||||
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
|
||||
#fix package build
|
||||
if(PREFIX)
|
||||
set(CMAKE_INSTALL_PREFIX ${PREFIX})
|
||||
else()
|
||||
set(CMAKE_INSTALL_PREFIX /usr/local)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
elseif(WIN32)
|
||||
set(CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/rundir/${CMAKE_BUILD_TYPE})
|
||||
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 ")
|
||||
# Generate complete debugging information
|
||||
#set(CMAKE_CXX_FLAGS_DEBUG "/Zi")
|
||||
ELSEIF (CMAKE_COMPILER_IS_GNUCXX)
|
||||
# linux/gcc, bsd/gcc, windows/mingw
|
||||
include(CheckCXXCompilerFlag)
|
||||
if(MSVC)
|
||||
# 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- /W4")
|
||||
# Generate complete debugging information
|
||||
#set(CMAKE_CXX_FLAGS_DEBUG "/Zi")
|
||||
elseif(CMAKE_COMPILER_IS_GNUCXX)
|
||||
# linux/gcc, bsd/gcc, windows/mingw
|
||||
include(CheckCXXCompilerFlag)
|
||||
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "-s -O2")
|
||||
if(WARNING_AS_ERROR)
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "-ggdb -O0 -Wall -Wextra -Werror")
|
||||
else()
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "-ggdb -O0 -Wall -Wextra")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "-s -O2")
|
||||
if(WARNING_AS_ERROR)
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "-ggdb -O0 -Wall -Wextra -Werror")
|
||||
else()
|
||||
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})
|
||||
check_cxx_compiler_flag("${FLAG}" CXX_HAS_WARNING_${FLAG})
|
||||
if(CXX_HAS_WARNING_${FLAG})
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${FLAG}")
|
||||
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})
|
||||
CHECK_CXX_COMPILER_FLAG("${FLAG}" CXX_HAS_WARNING_${FLAG})
|
||||
IF(CXX_HAS_WARNING_${FLAG})
|
||||
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${FLAG}")
|
||||
ENDIF()
|
||||
ENDFOREACH()
|
||||
ELSE()
|
||||
# other: osx/llvm, bsd/llvm
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "-O2")
|
||||
if(WARNING_AS_ERROR)
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "-g -O0 -Wall -Wextra -Werror")
|
||||
else()
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "-g -O0 -Wall -Wextra")
|
||||
endif()
|
||||
ENDIF()
|
||||
endforeach()
|
||||
else()
|
||||
# other: osx/llvm, bsd/llvm
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "-O2")
|
||||
if(WARNING_AS_ERROR)
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "-g -O0 -Wall -Wextra -Werror -Wno-unused-parameter")
|
||||
else()
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "-g -O0 -Wall -Wextra")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# GNU systems need to define the Mersenne exponent for the RNG to compile w/o warning
|
||||
IF(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
|
||||
ADD_DEFINITIONS("-DSFMT_MEXP=19937")
|
||||
ENDIF()
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
|
||||
add_definitions("-DSFMT_MEXP=19937")
|
||||
endif()
|
||||
|
||||
FIND_PACKAGE(Threads REQUIRED)
|
||||
find_package(Threads REQUIRED)
|
||||
|
||||
# Find Qt5
|
||||
# Determine 32 or 64 bit build
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
set(_lib_suffix 64)
|
||||
set(_lib_suffix 64)
|
||||
else()
|
||||
set(_lib_suffix 32)
|
||||
set(_lib_suffix 32)
|
||||
endif()
|
||||
|
||||
if(DEFINED QTDIR${_lib_suffix})
|
||||
list(APPEND CMAKE_PREFIX_PATH "${QTDIR${_lib_suffix}}")
|
||||
list(APPEND CMAKE_PREFIX_PATH "${QTDIR${_lib_suffix}}")
|
||||
elseif(DEFINED QTDIR)
|
||||
list(APPEND CMAKE_PREFIX_PATH "${QTDIR}")
|
||||
list(APPEND CMAKE_PREFIX_PATH "${QTDIR}")
|
||||
elseif(DEFINED ENV{QTDIR${_lib_suffix}})
|
||||
list(APPEND CMAKE_PREFIX_PATH "$ENV{QTDIR${_lib_suffix}}")
|
||||
list(APPEND CMAKE_PREFIX_PATH "$ENV{QTDIR${_lib_suffix}}")
|
||||
elseif(DEFINED ENV{QTDIR})
|
||||
list(APPEND CMAKE_PREFIX_PATH "$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)
|
||||
|
||||
# Find other needed libraries
|
||||
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!")
|
||||
ENDIF()
|
||||
find_package(Protobuf CONFIG)
|
||||
if(NOT Protobuf_FOUND)
|
||||
find_package(Protobuf REQUIRED)
|
||||
endif()
|
||||
|
||||
if(${Protobuf_VERSION} VERSION_LESS "3.21.0.0" AND NOT EXISTS "${Protobuf_PROTOC_EXECUTABLE}")
|
||||
message(FATAL_ERROR "No protoc command found!")
|
||||
endif()
|
||||
|
||||
#Find OpenSSL
|
||||
IF(WIN32)
|
||||
FIND_PACKAGE(Win32SslRuntime)
|
||||
ENDIF()
|
||||
if(WIN32)
|
||||
find_package(OpenSSL REQUIRED)
|
||||
if(OPENSSL_FOUND)
|
||||
include_directories(${OPENSSL_INCLUDE_DIRS})
|
||||
else()
|
||||
message(
|
||||
WARNING
|
||||
"Could not find OpenSSL runtime libraries. They are not required for compiling, but needs to be available at runtime."
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
#Find VCredist
|
||||
IF(MSVC)
|
||||
FIND_PACKAGE(VCredistRuntime)
|
||||
ENDIF()
|
||||
if(MSVC)
|
||||
find_package(VCredistRuntime)
|
||||
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")
|
||||
@@ -220,82 +255,95 @@ set(CPACK_PACKAGE_VERSION_PATCH "${PROJECT_VERSION_PATCH}")
|
||||
set(CPACK_PACKAGE_FILE_NAME "${PROJECT_VERSION_FILENAME}")
|
||||
|
||||
if(UNIX)
|
||||
if(APPLE)
|
||||
set(CPACK_GENERATOR DragNDrop ${CPACK_GENERATOR})
|
||||
set(CPACK_GENERATOR "DragNDrop")
|
||||
set(CPACK_DMG_FORMAT "UDBZ")
|
||||
set(CPACK_DMG_VOLUME_NAME "${PROJECT_NAME}")
|
||||
set(CPACK_SYSTEM_NAME "OSX")
|
||||
set(CPACK_PACKAGE_ICON "${CMAKE_CURRENT_SOURCE_DIR}/cockatrice/resources/appicon.icns")
|
||||
if(APPLE)
|
||||
set(CPACK_GENERATOR DragNDrop ${CPACK_GENERATOR})
|
||||
set(CPACK_GENERATOR "DragNDrop")
|
||||
set(CPACK_DMG_FORMAT "UDBZ")
|
||||
set(CPACK_DMG_VOLUME_NAME "${PROJECT_NAME}")
|
||||
set(CPACK_SYSTEM_NAME "OSX")
|
||||
set(CPACK_PACKAGE_ICON "${CMAKE_CURRENT_SOURCE_DIR}/cockatrice/resources/appicon.icns")
|
||||
set(CPACK_DMG_DS_STORE_SETUP_SCRIPT "${CMAKE_CURRENT_SOURCE_DIR}/cmake/CMakeDMGSetup.script")
|
||||
set(CPACK_DMG_BACKGROUND_IMAGE "${CMAKE_CURRENT_SOURCE_DIR}/cmake/dmgBackground.tif")
|
||||
else()
|
||||
# linux
|
||||
if(CPACK_GENERATOR STREQUAL "RPM")
|
||||
set(CPACK_RPM_PACKAGE_LICENSE "GPLv2")
|
||||
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()
|
||||
# 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_PACKAGE_GROUP "Amusements/Games")
|
||||
set(CPACK_RPM_PACKAGE_URL "http://github.com/Cockatrice/Cockatrice")
|
||||
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")
|
||||
ENDIF()
|
||||
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")
|
||||
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)
|
||||
set(CPACK_GENERATOR NSIS ${CPACK_GENERATOR})
|
||||
if("${CMAKE_GENERATOR_PLATFORM}" MATCHES "(x64)")
|
||||
set(TRICE_IS_64_BIT 1)
|
||||
else()
|
||||
set(TRICE_IS_64_BIT 0)
|
||||
endif()
|
||||
set(CPACK_GENERATOR NSIS ${CPACK_GENERATOR})
|
||||
if("${CMAKE_GENERATOR_PLATFORM}" MATCHES "(x64)")
|
||||
set(TRICE_IS_64_BIT 1)
|
||||
else()
|
||||
set(TRICE_IS_64_BIT 0)
|
||||
endif()
|
||||
|
||||
# Configure file with custom definitions for NSIS.
|
||||
configure_file(
|
||||
${CMAKE_MODULE_PATH}/NSIS.definitions.nsh.in
|
||||
${PROJECT_BINARY_DIR}/NSIS.definitions.nsh
|
||||
)
|
||||
# Configure file with custom definitions for NSIS.
|
||||
configure_file("${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
|
||||
if(VCREDISTRUNTIME_FOUND)
|
||||
INSTALL(FILES "${VCREDISTRUNTIME_FILE}" DESTINATION ./)
|
||||
endif()
|
||||
# include vcredist into the package; NSIS will take care of running it
|
||||
if(VCREDISTRUNTIME_FOUND)
|
||||
install(FILES "${VCREDISTRUNTIME_FILE}" DESTINATION ./)
|
||||
endif()
|
||||
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})
|
||||
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})
|
||||
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})
|
||||
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})
|
||||
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)
|
||||
include(CTest)
|
||||
add_subdirectory(tests)
|
||||
endif()
|
||||
|
||||
if(Qt6_FOUND AND Qt6_VERSION_MINOR GREATER_EQUAL 3)
|
||||
# Qt6.3+ requires project finalization to support translations
|
||||
qt6_finalize_project()
|
||||
endif()
|
||||
|
||||
19
README.md
19
README.md
@@ -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>
|
||||
@@ -18,7 +18,7 @@
|
||||
<br><pre>
|
||||
<b>To get started, ⇢ [view our webpage](https://cockatrice.github.io/)</b><br>
|
||||
<b>To get support or suggest changes ⇢ [file an issue](https://github.com/Cockatrice/Cockatrice/issues) ([How?](https://github.com/Cockatrice/Cockatrice/wiki/How-to-Create-a-GitHub-Ticket-Regarding-Cockatrice))</b>
|
||||
<b>To help with development, see how to [get involved](#get-involved-)</b>
|
||||
<b>To help with development, see how to [get involved](#get-involved--)</b>
|
||||
</pre><br>
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ Downloads are available for full releases and the current beta version in develo
|
||||
- To be a Cockatrice Beta Tester, use this version. Find more information [here](https://github.com/Cockatrice/Cockatrice/wiki/Release-Channels)!
|
||||
|
||||
|
||||
# Get Involved [](https://discord.gg/3Z9yzmA) [](https://gitter.im/Cockatrice/Cockatrice)
|
||||
# Get Involved [](https://discord.gg/3Z9yzmA)
|
||||
|
||||
Join our [Discord community](https://discord.gg/3Z9yzmA) to connect with the project or fellow users of the app. The Cockatrice developers are also available on [Gitter](https://gitter.im/Cockatrice/Cockatrice). Come here to talk about the application, features, or just to hang out.<br>
|
||||
For support regarding specific servers, please contact that server's admin or forum for support rather than asking here.<br>
|
||||
@@ -52,8 +52,6 @@ We maintain two tags for contributors to find issues to work on:
|
||||
|
||||
For both tags, we're willing to provide help to contributors in showing them where and how they can make changes, as well as code review for changes they submit.
|
||||
|
||||
Read the long-term project **roadmap** to see planned edits and milestones [here](https://docs.google.com/document/d/1Ewe5uSaRE2nR2pNPMaGmP6gVZdqgFbBgwSscGqIr4W0/edit).
|
||||
|
||||
We try to be responsive to new issues. We'll provide advice on how best to implement a feature; alternately, we can show you where the codebase is doing something similar before you get too far along.
|
||||
|
||||
Cockatrice uses the [Google Developer Documentation Style Guide](https://developers.google.com/style/) to ensure consistent documentation. We encourage you to improve the documentation by suggesting edits based on this guide.
|
||||
@@ -67,18 +65,14 @@ Cockatrice uses the [Google Developer Documentation Style Guide](https://develop
|
||||
- [reddit r/Cockatrice](https://reddit.com/r/cockatrice)
|
||||
|
||||
|
||||
# Translations [](https://www.transifex.com/projects/p/cockatrice/)
|
||||
# Translations [](https://transifex.com/cockatrice/cockatrice/)
|
||||
|
||||
Cockatrice uses Transifex for translations. You can help us bring Cockatrice and Oracle to your language or just edit single wordings right from within your browser by visiting our [Transifex project page](https://www.transifex.com/projects/p/cockatrice/).<br>
|
||||
|
||||
| Cockatrice | Oracle |
|
||||
|:-:|:-:|
|
||||
| [](https://www.transifex.com/projects/p/cockatrice/) | [](https://www.transifex.com/projects/p/cockatrice/) |
|
||||
Cockatrice uses Transifex for translations. You can help us bring Cockatrice, Oracle and Webatrice to your language or just adjust single wordings right from within your browser by visiting our [Transifex project page](https://transifex.com/cockatrice/cockatrice/).<br>
|
||||
|
||||
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 +111,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
|
||||
|
||||
55
cmake/CMakeDMGSetup.script
Normal file
55
cmake/CMakeDMGSetup.script
Normal file
@@ -0,0 +1,55 @@
|
||||
on run argv
|
||||
set image_name to item 1 of argv
|
||||
|
||||
tell application "Finder"
|
||||
tell disk image_name
|
||||
|
||||
-- wait for the image to finish mounting
|
||||
set open_attempts to 0
|
||||
repeat while open_attempts < 4
|
||||
try
|
||||
open
|
||||
delay 1
|
||||
set open_attempts to 5
|
||||
close
|
||||
on error errStr number errorNumber
|
||||
set open_attempts to open_attempts + 1
|
||||
delay 10
|
||||
end try
|
||||
end repeat
|
||||
delay 5
|
||||
|
||||
-- open the image the first time and save a DS_Store with just
|
||||
-- background and icon setup
|
||||
open
|
||||
set current view of container window to icon view
|
||||
set theViewOptions to the icon view options of container window
|
||||
set background picture of theViewOptions to file ".background:background.tif"
|
||||
set arrangement of theViewOptions to not arranged
|
||||
set icon size of theViewOptions to 128
|
||||
delay 5
|
||||
close
|
||||
|
||||
-- next setup the position of the app and Applications symlink
|
||||
-- plus hide all the window decoration
|
||||
open
|
||||
update without registering applications
|
||||
tell container window
|
||||
set sidebar width to 0
|
||||
set statusbar visible to false
|
||||
set toolbar visible to false
|
||||
set the bounds to { 400, 100, 1400, 922 }
|
||||
set position of item "Cockatrice.app" to { 139, 214 }
|
||||
set position of item "Oracle.app" to { 139, 414 }
|
||||
set position of item "Servatrice.app" to { 139, 614 }
|
||||
set position of item "dbconverter.app" to { 1400, 1400 }
|
||||
set position of item "Applications" to { 861, 414 }
|
||||
end tell
|
||||
update without registering applications
|
||||
delay 5
|
||||
close
|
||||
|
||||
end tell
|
||||
delay 1
|
||||
end tell
|
||||
end run
|
||||
@@ -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()
|
||||
|
||||
117
cmake/FindQtRuntime.cmake
Normal file
117
cmake/FindQtRuntime.cmake
Normal file
@@ -0,0 +1,117 @@
|
||||
# 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
|
||||
# Output: SERVATRICE_QT_MODULES
|
||||
# Output: COCKATRICE_QT_MODULES
|
||||
# Output: ORACLE_QT_MODULES
|
||||
# Output: DBCONVERTER_QT_MODULES
|
||||
# Output: 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
|
||||
WebSockets
|
||||
Widgets
|
||||
)
|
||||
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)
|
||||
# Linguist is now a component in Qt6 instead of an external package
|
||||
find_package(
|
||||
Qt6 6.2.3
|
||||
COMPONENTS ${REQUIRED_QT_COMPONENTS} Linguist
|
||||
QUIET HINTS ${Qt6_DIR}
|
||||
)
|
||||
endif()
|
||||
if(Qt6_FOUND)
|
||||
set(COCKATRICE_QT_VERSION_NAME Qt6)
|
||||
|
||||
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()
|
||||
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}")
|
||||
|
||||
message(STATUS "Found Qt ${${COCKATRICE_QT_VERSION_NAME}_VERSION} at: ${${COCKATRICE_QT_VERSION_NAME}_DIR}")
|
||||
@@ -1,36 +1,42 @@
|
||||
# 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)
|
||||
endif()
|
||||
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)
|
||||
# VS 2017 uses vcredist_ARCH.exe, VS 2022 uses vc_redist.ARCH.exe
|
||||
set(REDIST_FILE_NAMES vcredist_${REDIST_ARCH}.exe vcredist.${REDIST_ARCH}.exe vc_redist.${REDIST_ARCH}.exe)
|
||||
|
||||
set(CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS_SKIP TRUE)
|
||||
include(InstallRequiredSystemLibraries)
|
||||
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)
|
||||
# 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)
|
||||
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()
|
||||
foreach(redist_file ${REDIST_FILE_NAMES})
|
||||
if(EXISTS "${_path}/${REDIST_FILE}")
|
||||
set(VCREDISTRUNTIME_FOUND "YES")
|
||||
set(VCREDISTRUNTIME_FILE ${_path}/${redist_file})
|
||||
break()
|
||||
endif()
|
||||
endforeach()
|
||||
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 +0,0 @@
|
||||
# Find the OpenSSL runtime libraries (.dll) for Windows that
|
||||
# will be needed by Qt in order to access https urls.
|
||||
|
||||
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
|
||||
"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
|
||||
)
|
||||
@@ -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}
|
||||
)
|
||||
|
||||
BIN
cmake/dmgBackground.tif
Normal file
BIN
cmake/dmgBackground.tif
Normal file
Binary file not shown.
@@ -1,154 +1,187 @@
|
||||
# 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 +196,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 +213,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}")
|
||||
|
||||
|
||||
@@ -2,284 +2,385 @@
|
||||
#
|
||||
# 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/*.dll"
|
||||
PATTERN "mediaservice/dsengine.dll"
|
||||
PATTERN "mediaservice/wmfengine.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(OPENSSL_FOUND)
|
||||
install(FILES ${OPENSSL_INCLUDE_DIRS} DESTINATION ./)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(Qt6_FOUND AND 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>
|
||||
@@ -353,10 +351,10 @@
|
||||
<file>resources/tips/images/cockatrice_wiki.png</file>
|
||||
<file>resources/tips/images/coin_flip.png</file>
|
||||
<file>resources/tips/images/counter_expression.png</file>
|
||||
<file>resources/tips/images/discord.png</file>
|
||||
<file>resources/tips/images/face_down.png</file>
|
||||
<file>resources/tips/images/filter_games.png</file>
|
||||
<file>resources/tips/images/github_logo.png</file>
|
||||
<file>resources/tips/images/gitter.png</file>
|
||||
<file>resources/tips/images/setpt.png</file>
|
||||
<file>resources/tips/images/shortcuts.png</file>
|
||||
<file>resources/tips/images/themes.png</file>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
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 |
@@ -1,6 +1,7 @@
|
||||
## Syntax Help
|
||||
## Search Syntax Help
|
||||
-----
|
||||
The search bar recognizes a set of special commands similar to some other card databases. Here is a list with examples. Each entry can be clicked to test the query and has a small explanation. Note that all searches are case insensitive.
|
||||
The search bar recognizes a set of special commands similar to some other card databases.<br>
|
||||
In this list of examples below, each entry has an explanation and can be clicked to test the query. Note that all searches are case insensitive.
|
||||
<dl>
|
||||
<dt>Name:</dt>
|
||||
<dd>[birds of paradise](#birds of paradise) <small>(Any card name containing the words birds, of, and paradise)</small></dd>
|
||||
@@ -46,8 +47,7 @@ The search bar recognizes a set of special commands similar to some other card d
|
||||
|
||||
<dt><u>E</u>dition:</dt>
|
||||
<dd>[set:lea](#set:lea) <small>(Cards that appear in Alpha, which has the set code LEA)</small></dd>
|
||||
<dd>[e:lea,leb](#e:lea,leb) <small>(Cards that appear in Alpha or Beta)</small></dd>
|
||||
<dd><a href="#e:lea,leb -(e:lea e:leb)">e:lea,leb -(e:lea e:leb)</a> <small>(Cards that appear in Alpha or Beta but not in both editions)</small></dd>
|
||||
<dd>[e:lea or e:leb](#e:lea or e:leb) <small>(Cards that appear in Alpha or Beta)</small></dd>
|
||||
|
||||
<dt>Negate:</dt>
|
||||
<dd>[c:wu -c:m](#c:wu -c:m) <small>(Any card that is white or blue, but not multicolored)</small></dd>
|
||||
|
||||
BIN
cockatrice/resources/tips/images/discord.png
Normal file
BIN
cockatrice/resources/tips/images/discord.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 30 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 5.9 KiB |
@@ -7,9 +7,9 @@
|
||||
</tip>
|
||||
<tip>
|
||||
<title>Suggesting New Tips</title>
|
||||
<text>You can suggest new Tips of the Day by reaching out to the development team on <a href="https://gitter.im/cockatrice/cockatrice">Gitter</a>!</text>
|
||||
<image>gitter.png</image>
|
||||
<date>2018-03-01</date>
|
||||
<text>You can suggest new Tips of the Day by reaching out to the development team on <a href="https://discord.gg/3Z9yzmA">Discord</a>!</text>
|
||||
<image>discord.png</image>
|
||||
<date>2023-10-18</date>
|
||||
</tip>
|
||||
<tip>
|
||||
<title>Reporting Bugs</title>
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -20,13 +20,8 @@ AbstractCardDragItem::AbstractCardDragItem(AbstractCardItem *_item,
|
||||
parentDrag->addChildDrag(this);
|
||||
setZValue(2000000007 + hotSpot.x() * 1000000 + hotSpot.y() * 1000 + 1000);
|
||||
} else {
|
||||
if ((hotSpot.x() < 0) || (hotSpot.y() < 0)) {
|
||||
qDebug() << "CardDragItem: coordinate overflow: x =" << hotSpot.x() << ", y =" << hotSpot.y();
|
||||
hotSpot = QPointF();
|
||||
} else if ((hotSpot.x() > CARD_WIDTH) || (hotSpot.y() > CARD_HEIGHT)) {
|
||||
qDebug() << "CardDragItem: coordinate overflow: x =" << hotSpot.x() << ", y =" << hotSpot.y();
|
||||
hotSpot = QPointF(CARD_WIDTH, CARD_HEIGHT);
|
||||
}
|
||||
hotSpot = QPointF{qBound(0.0, hotSpot.x(), static_cast<qreal>(CARD_WIDTH - 1)),
|
||||
qBound(0.0, hotSpot.y(), static_cast<qreal>(CARD_HEIGHT - 1))};
|
||||
setCursor(Qt::ClosedHandCursor);
|
||||
setZValue(2000000007);
|
||||
}
|
||||
@@ -45,12 +40,19 @@ AbstractCardDragItem::~AbstractCardDragItem()
|
||||
delete childDrags[i];
|
||||
}
|
||||
|
||||
QPainterPath AbstractCardDragItem::shape() const
|
||||
{
|
||||
QPainterPath shape;
|
||||
shape.addRoundedRect(boundingRect(), 0.05 * CARD_WIDTH, 0.05 * CARD_WIDTH);
|
||||
return shape;
|
||||
}
|
||||
|
||||
void AbstractCardDragItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
|
||||
{
|
||||
item->paint(painter, option, widget);
|
||||
|
||||
// adds a mask to the card so it looks like the card hasnt been placed yet
|
||||
painter->fillRect(boundingRect(), GHOST_MASK);
|
||||
painter->fillPath(shape(), GHOST_MASK);
|
||||
}
|
||||
|
||||
void AbstractCardDragItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
||||
|
||||
@@ -21,17 +21,18 @@ public:
|
||||
{
|
||||
Type = typeCardDrag
|
||||
};
|
||||
int type() const
|
||||
int type() const override
|
||||
{
|
||||
return Type;
|
||||
}
|
||||
AbstractCardDragItem(AbstractCardItem *_item, const QPointF &_hotSpot, AbstractCardDragItem *parentDrag = 0);
|
||||
~AbstractCardDragItem();
|
||||
QRectF boundingRect() const
|
||||
QRectF boundingRect() const override
|
||||
{
|
||||
return QRectF(0, 0, CARD_WIDTH, CARD_HEIGHT);
|
||||
}
|
||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
|
||||
QPainterPath shape() const override;
|
||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
|
||||
AbstractCardItem *getItem() const
|
||||
{
|
||||
return item;
|
||||
@@ -44,7 +45,7 @@ public:
|
||||
virtual void updatePosition(const QPointF &cursorScenePos) = 0;
|
||||
|
||||
protected:
|
||||
void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
|
||||
void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override;
|
||||
};
|
||||
|
||||
#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)
|
||||
@@ -36,6 +34,13 @@ QRectF AbstractCardItem::boundingRect() const
|
||||
return QRectF(0, 0, CARD_WIDTH, CARD_HEIGHT);
|
||||
}
|
||||
|
||||
QPainterPath AbstractCardItem::shape() const
|
||||
{
|
||||
QPainterPath shape;
|
||||
shape.addRoundedRect(boundingRect(), 0.05 * CARD_WIDTH, 0.05 * CARD_WIDTH);
|
||||
return shape;
|
||||
}
|
||||
|
||||
void AbstractCardItem::pixmapUpdated()
|
||||
{
|
||||
update();
|
||||
@@ -115,24 +120,14 @@ void AbstractCardItem::paintPicture(QPainter *painter, const QSizeF &translatedS
|
||||
|
||||
if (paintImage) {
|
||||
painter->save();
|
||||
transformPainter(painter, translatedSize, angle);
|
||||
painter->drawPixmap(QPointF(1, 1), translatedPixmap);
|
||||
painter->setClipPath(shape());
|
||||
painter->drawPixmap(boundingRect(), translatedPixmap, QRectF({0, 0}, translatedPixmap.size()));
|
||||
painter->restore();
|
||||
} else {
|
||||
painter->setBrush(bgColor);
|
||||
painter->drawPath(shape());
|
||||
}
|
||||
|
||||
QPen pen(Qt::black);
|
||||
pen.setJoinStyle(Qt::MiterJoin);
|
||||
const int penWidth = 2;
|
||||
pen.setWidth(penWidth);
|
||||
painter->setPen(pen);
|
||||
|
||||
if (!angle)
|
||||
painter->drawRect(QRectF(0, 0, CARD_WIDTH - 1, CARD_HEIGHT - penWidth));
|
||||
else
|
||||
painter->drawRect(QRectF(1, 1, CARD_WIDTH - 2, CARD_HEIGHT - 1.5));
|
||||
|
||||
if (translatedPixmap.isNull() || SettingsCache::instance().getDisplayCardNames() || facedown) {
|
||||
painter->save();
|
||||
transformPainter(painter, translatedSize, angle);
|
||||
@@ -160,9 +155,7 @@ void AbstractCardItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *
|
||||
QSizeF translatedSize = getTranslatedSize(painter);
|
||||
paintPicture(painter, translatedSize, tapAngle);
|
||||
|
||||
painter->save();
|
||||
painter->setRenderHint(QPainter::Antialiasing, false);
|
||||
transformPainter(painter, translatedSize, tapAngle);
|
||||
|
||||
if (isSelected() || isHovered) {
|
||||
QPen pen;
|
||||
@@ -170,15 +163,12 @@ void AbstractCardItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *
|
||||
pen.setColor(Qt::yellow);
|
||||
if (isSelected())
|
||||
pen.setColor(Qt::red);
|
||||
const int penWidth = 1;
|
||||
pen.setWidth(penWidth);
|
||||
pen.setWidth(0); // Cosmetic pen
|
||||
painter->setPen(pen);
|
||||
painter->drawRect(QRectF(0, 0, translatedSize.width() + penWidth, translatedSize.height() - penWidth));
|
||||
painter->drawPath(shape());
|
||||
}
|
||||
|
||||
painter->restore();
|
||||
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
void AbstractCardItem::setName(const QString &_name)
|
||||
|
||||
@@ -44,7 +44,7 @@ public:
|
||||
{
|
||||
Type = typeCard
|
||||
};
|
||||
int type() const
|
||||
int type() const override
|
||||
{
|
||||
return Type;
|
||||
}
|
||||
@@ -53,10 +53,11 @@ public:
|
||||
int _id = -1,
|
||||
QGraphicsItem *parent = nullptr);
|
||||
~AbstractCardItem();
|
||||
QRectF boundingRect() const;
|
||||
QRectF boundingRect() const override;
|
||||
QPainterPath shape() const override;
|
||||
QSizeF getTranslatedSize(QPainter *painter) const;
|
||||
void paintPicture(QPainter *painter, const QSizeF &translatedSize, int angle);
|
||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
|
||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
|
||||
CardInfoPtr getInfo() const
|
||||
{
|
||||
return info;
|
||||
@@ -103,9 +104,9 @@ public:
|
||||
|
||||
protected:
|
||||
void transformPainter(QPainter *painter, const QSizeF &translatedSize, int angle);
|
||||
void mousePressEvent(QGraphicsSceneMouseEvent *event);
|
||||
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
|
||||
QVariant itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value);
|
||||
void mousePressEvent(QGraphicsSceneMouseEvent *event) override;
|
||||
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;
|
||||
QVariant itemChange(QGraphicsItem::GraphicsItemChange change, const QVariant &value) override;
|
||||
void cacheBgColor();
|
||||
};
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
#include "abstractclient.h"
|
||||
|
||||
#include "client_metatypes.h"
|
||||
#include "featureset.h"
|
||||
#include "get_pb_extension.h"
|
||||
#include "pb/commands.pb.h"
|
||||
@@ -22,7 +21,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 +47,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);
|
||||
@@ -138,8 +138,8 @@ void ArrowItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
|
||||
}
|
||||
|
||||
QList<QGraphicsItem *> colliding = scene()->items(event->scenePos());
|
||||
for (int i = 0; i < colliding.size(); ++i) {
|
||||
if (qgraphicsitem_cast<CardItem *>(colliding[i])) {
|
||||
for (QGraphicsItem *item : colliding) {
|
||||
if (qgraphicsitem_cast<CardItem *>(item)) {
|
||||
event->ignore();
|
||||
return;
|
||||
}
|
||||
@@ -205,8 +205,8 @@ void ArrowDragItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
||||
}
|
||||
update();
|
||||
|
||||
for (int i = 0; i < childArrows.size(); ++i) {
|
||||
childArrows[i]->mouseMoveEvent(event);
|
||||
for (ArrowDragItem *child : childArrows) {
|
||||
child->mouseMoveEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -251,8 +251,9 @@ void ArrowDragItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
||||
}
|
||||
delArrow();
|
||||
|
||||
for (int i = 0; i < childArrows.size(); ++i)
|
||||
childArrows[i]->mouseReleaseEvent(event);
|
||||
for (ArrowDragItem *child : childArrows) {
|
||||
child->mouseReleaseEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
ArrowAttachItem::ArrowAttachItem(ArrowTarget *_startItem)
|
||||
@@ -260,6 +261,11 @@ ArrowAttachItem::ArrowAttachItem(ArrowTarget *_startItem)
|
||||
{
|
||||
}
|
||||
|
||||
void ArrowAttachItem::addChildArrow(ArrowAttachItem *childArrow)
|
||||
{
|
||||
childArrows.append(childArrow);
|
||||
}
|
||||
|
||||
void ArrowAttachItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
if (!startItem)
|
||||
@@ -295,9 +301,13 @@ void ArrowAttachItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
||||
updatePath();
|
||||
}
|
||||
update();
|
||||
|
||||
for (ArrowAttachItem *child : childArrows) {
|
||||
child->mouseMoveEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
void ArrowAttachItem::mouseReleaseEvent(QGraphicsSceneMouseEvent * /*event*/)
|
||||
void ArrowAttachItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
if (!startItem)
|
||||
return;
|
||||
@@ -319,4 +329,8 @@ void ArrowAttachItem::mouseReleaseEvent(QGraphicsSceneMouseEvent * /*event*/)
|
||||
}
|
||||
|
||||
delArrow();
|
||||
|
||||
for (ArrowAttachItem *child : childArrows) {
|
||||
child->mouseReleaseEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,8 +85,12 @@ protected:
|
||||
class ArrowAttachItem : public ArrowItem
|
||||
{
|
||||
Q_OBJECT
|
||||
private:
|
||||
QList<ArrowAttachItem *> childArrows;
|
||||
|
||||
public:
|
||||
ArrowAttachItem(ArrowTarget *_startItem);
|
||||
void addChildArrow(ArrowAttachItem *childArrow);
|
||||
|
||||
protected:
|
||||
void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -266,9 +266,14 @@ CardInfoPtr CardInfo::newInstance(const QString &_name,
|
||||
|
||||
QString CardInfo::getCorrectedName() const
|
||||
{
|
||||
// remove all the characters reserved in windows file paths,
|
||||
// other oses only disallow a subset of these so it covers all
|
||||
static const QRegularExpression rmrx(R"(( // |[*<>:"\\?\x00-\x08\x10-\x1f]))");
|
||||
static const QRegularExpression spacerx(R"([/\x09-\x0f])");
|
||||
static const QString space(' ');
|
||||
QString result = name;
|
||||
// Fire // Ice, Circle of Protection: Red, "Ach! Hans, Run!", Who/What/When/Where/Why, Question Elemental?
|
||||
return result.remove(" // ").remove(':').remove('"').remove('?').replace('/', ' ');
|
||||
return result.remove(rmrx).replace(spacerx, space);
|
||||
}
|
||||
|
||||
void CardInfo::addToSet(const CardSetPtr &_set, const CardInfoPerSet _info)
|
||||
@@ -587,9 +592,9 @@ void CardDatabase::refreshCachedReverseRelatedCards()
|
||||
continue;
|
||||
}
|
||||
|
||||
auto *newCardRelation = new CardRelation(card->getName(), cardRelation->getDoesAttach(),
|
||||
cardRelation->getIsCreateAllExclusion(),
|
||||
cardRelation->getIsVariable(), cardRelation->getDefaultCount());
|
||||
auto *newCardRelation = new CardRelation(
|
||||
card->getName(), cardRelation->getAttachType(), cardRelation->getIsCreateAllExclusion(),
|
||||
cardRelation->getIsVariable(), cardRelation->getDefaultCount(), cardRelation->getIsPersistent());
|
||||
cards.value(targetCard)->addReverseRelatedCards2Me(newCardRelation);
|
||||
}
|
||||
}
|
||||
@@ -607,22 +612,22 @@ QStringList CardDatabase::getAllMainCardTypes() const
|
||||
|
||||
void CardDatabase::checkUnknownSets()
|
||||
{
|
||||
SetList sets = getSetList();
|
||||
auto _sets = getSetList();
|
||||
|
||||
if (sets.getEnabledSetsNum()) {
|
||||
if (_sets.getEnabledSetsNum()) {
|
||||
// if some sets are first found on this run, ask the user
|
||||
int numUnknownSets = sets.getUnknownSetsNum();
|
||||
QStringList unknownSetNames = sets.getUnknownSetsNames();
|
||||
int numUnknownSets = _sets.getUnknownSetsNum();
|
||||
QStringList unknownSetNames = _sets.getUnknownSetsNames();
|
||||
if (numUnknownSets > 0) {
|
||||
emit cardDatabaseNewSetsFound(numUnknownSets, unknownSetNames);
|
||||
} else {
|
||||
sets.markAllAsKnown();
|
||||
_sets.markAllAsKnown();
|
||||
}
|
||||
} else {
|
||||
// No set enabled. Probably this is the first time running trice
|
||||
sets.guessSortKeys();
|
||||
sets.sortByKey();
|
||||
sets.enableAll();
|
||||
_sets.guessSortKeys();
|
||||
_sets.sortByKey();
|
||||
_sets.enableAll();
|
||||
notifyEnabledSetsChanged();
|
||||
|
||||
emit cardDatabaseAllNewSetsEnabled();
|
||||
@@ -631,14 +636,14 @@ void CardDatabase::checkUnknownSets()
|
||||
|
||||
void CardDatabase::enableAllUnknownSets()
|
||||
{
|
||||
SetList sets = getSetList();
|
||||
sets.enableAllUnknown();
|
||||
auto _sets = getSetList();
|
||||
_sets.enableAllUnknown();
|
||||
}
|
||||
|
||||
void CardDatabase::markAllSetsAsKnown()
|
||||
{
|
||||
SetList sets = getSetList();
|
||||
sets.markAllAsKnown();
|
||||
auto _sets = getSetList();
|
||||
_sets.markAllAsKnown();
|
||||
}
|
||||
|
||||
void CardDatabase::notifyEnabledSetsChanged()
|
||||
@@ -672,12 +677,13 @@ bool CardDatabase::saveCustomTokensToFile()
|
||||
}
|
||||
|
||||
CardRelation::CardRelation(const QString &_name,
|
||||
bool _doesAttach,
|
||||
AttachType _attachType,
|
||||
bool _isCreateAllExclusion,
|
||||
bool _isVariableCount,
|
||||
int _defaultCount)
|
||||
: name(_name), doesAttach(_doesAttach), isCreateAllExclusion(_isCreateAllExclusion),
|
||||
isVariableCount(_isVariableCount), defaultCount(_defaultCount)
|
||||
int _defaultCount,
|
||||
bool _isPersistent)
|
||||
: name(_name), attachType(_attachType), isCreateAllExclusion(_isCreateAllExclusion),
|
||||
isVariableCount(_isVariableCount), defaultCount(_defaultCount), isPersistent(_isPersistent)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -452,31 +452,60 @@ signals:
|
||||
class CardRelation : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum AttachType
|
||||
{
|
||||
DoesNotAttach = 0,
|
||||
AttachTo = 1,
|
||||
TransformInto = 2,
|
||||
};
|
||||
|
||||
private:
|
||||
QString name;
|
||||
bool doesAttach;
|
||||
AttachType attachType;
|
||||
bool isCreateAllExclusion;
|
||||
bool isVariableCount;
|
||||
int defaultCount;
|
||||
bool isPersistent;
|
||||
|
||||
public:
|
||||
explicit CardRelation(const QString &_name = QString(),
|
||||
bool _doesAttach = false,
|
||||
AttachType _attachType = DoesNotAttach,
|
||||
bool _isCreateAllExclusion = false,
|
||||
bool _isVariableCount = false,
|
||||
int _defaultCount = 1);
|
||||
int _defaultCount = 1,
|
||||
bool _isPersistent = false);
|
||||
|
||||
inline const QString &getName() const
|
||||
{
|
||||
return name;
|
||||
}
|
||||
AttachType getAttachType() const
|
||||
{
|
||||
return attachType;
|
||||
}
|
||||
bool getDoesAttach() const
|
||||
{
|
||||
return doesAttach;
|
||||
return attachType != DoesNotAttach;
|
||||
}
|
||||
bool getDoesTransform() const
|
||||
{
|
||||
return attachType == TransformInto;
|
||||
}
|
||||
QString getAttachTypeAsString() const
|
||||
{
|
||||
switch (attachType) {
|
||||
case AttachTo:
|
||||
return "attach";
|
||||
case TransformInto:
|
||||
return "transform";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
bool getCanCreateAnother() const
|
||||
{
|
||||
return !doesAttach;
|
||||
return !getDoesAttach();
|
||||
}
|
||||
bool getIsCreateAllExclusion() const
|
||||
{
|
||||
@@ -490,5 +519,9 @@ public:
|
||||
{
|
||||
return defaultCount;
|
||||
}
|
||||
bool getIsPersistent() const
|
||||
{
|
||||
return isPersistent;
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -326,12 +326,12 @@ void CardDatabaseDisplayModel::clearFilterAll()
|
||||
invalidateFilter();
|
||||
}
|
||||
|
||||
void CardDatabaseDisplayModel::setFilterTree(FilterTree *filterTree)
|
||||
void CardDatabaseDisplayModel::setFilterTree(FilterTree *_filterTree)
|
||||
{
|
||||
if (this->filterTree != nullptr)
|
||||
disconnect(this->filterTree, nullptr, this, nullptr);
|
||||
|
||||
this->filterTree = filterTree;
|
||||
this->filterTree = _filterTree;
|
||||
connect(this->filterTree, SIGNAL(changed()), this, SLOT(filterTreeChanged()));
|
||||
invalidate();
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@ private:
|
||||
|
||||
public:
|
||||
explicit CardDatabaseDisplayModel(QObject *parent = nullptr);
|
||||
void setFilterTree(FilterTree *filterTree);
|
||||
void setFilterTree(FilterTree *_filterTree);
|
||||
void setIsToken(FilterBool _isToken)
|
||||
{
|
||||
isToken = _isToken;
|
||||
|
||||
@@ -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,13 +148,14 @@ 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();
|
||||
QString colors = QString("");
|
||||
QList<CardRelation *> relatedCards, reverseRelatedCards;
|
||||
CardInfoPerSetMap sets = CardInfoPerSetMap();
|
||||
auto _sets = CardInfoPerSetMap();
|
||||
int tableRow = 0;
|
||||
bool cipt = false;
|
||||
bool isToken = false;
|
||||
@@ -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);
|
||||
@@ -216,10 +221,10 @@ void CockatriceXml3Parser::loadCardsFromXml(QXmlStreamReader &xml)
|
||||
if (attrs.hasAttribute("rarity")) {
|
||||
setInfo.setProperty("rarity", attrs.value("rarity").toString());
|
||||
}
|
||||
sets.insert(setName, setInfo);
|
||||
// relatd cards
|
||||
} else if (xml.name() == "related" || xml.name() == "reverse-related") {
|
||||
bool attach = false;
|
||||
_sets.insert(setName, setInfo);
|
||||
// related cards
|
||||
} else if (xmlName == "related" || xmlName == "reverse-related") {
|
||||
CardRelation::AttachType attach = CardRelation::DoesNotAttach;
|
||||
bool exclude = false;
|
||||
bool variable = false;
|
||||
int count = 1;
|
||||
@@ -241,7 +246,7 @@ void CockatriceXml3Parser::loadCardsFromXml(QXmlStreamReader &xml)
|
||||
}
|
||||
|
||||
if (attrs.hasAttribute("attach")) {
|
||||
attach = true;
|
||||
attach = CardRelation::AttachTo;
|
||||
}
|
||||
|
||||
if (attrs.hasAttribute("exclude")) {
|
||||
@@ -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();
|
||||
}
|
||||
@@ -263,7 +268,7 @@ void CockatriceXml3Parser::loadCardsFromXml(QXmlStreamReader &xml)
|
||||
|
||||
properties.insert("colors", colors);
|
||||
CardInfoPtr newCard = CardInfo::newInstance(name, text, isToken, properties, relatedCards,
|
||||
reverseRelatedCards, sets, cipt, tableRow, upsideDown);
|
||||
reverseRelatedCards, _sets, cipt, tableRow, upsideDown);
|
||||
emit addCard(newCard);
|
||||
}
|
||||
}
|
||||
@@ -407,7 +412,7 @@ static QXmlStreamWriter &operator<<(QXmlStreamWriter &xml, const CardInfoPtr &in
|
||||
return xml;
|
||||
}
|
||||
|
||||
bool CockatriceXml3Parser::saveToFile(SetNameMap sets,
|
||||
bool CockatriceXml3Parser::saveToFile(SetNameMap _sets,
|
||||
CardNameMap cards,
|
||||
const QString &fileName,
|
||||
const QString &sourceUrl,
|
||||
@@ -434,9 +439,9 @@ bool CockatriceXml3Parser::saveToFile(SetNameMap sets,
|
||||
xml.writeTextElement("sourceVersion", sourceVersion);
|
||||
xml.writeEndElement();
|
||||
|
||||
if (sets.count() > 0) {
|
||||
if (_sets.count() > 0) {
|
||||
xml.writeStartElement("sets");
|
||||
for (CardSetPtr set : sets) {
|
||||
for (CardSetPtr set : _sets) {
|
||||
xml << set;
|
||||
}
|
||||
xml.writeEndElement();
|
||||
@@ -454,4 +459,4 @@ bool CockatriceXml3Parser::saveToFile(SetNameMap sets,
|
||||
xml.writeEndDocument();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ public:
|
||||
~CockatriceXml3Parser() override = default;
|
||||
bool getCanParseFile(const QString &name, QIODevice &device) override;
|
||||
void parseFile(QIODevice &device) override;
|
||||
bool saveToFile(SetNameMap sets,
|
||||
bool saveToFile(SetNameMap _sets,
|
||||
CardNameMap cards,
|
||||
const QString &fileName,
|
||||
const QString &sourceUrl = "unknown",
|
||||
|
||||
@@ -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,12 +127,14 @@ 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();
|
||||
QList<CardRelation *> relatedCards, reverseRelatedCards;
|
||||
CardInfoPerSetMap sets = CardInfoPerSetMap();
|
||||
auto _sets = CardInfoPerSetMap();
|
||||
int tableRow = 0;
|
||||
bool cipt = false;
|
||||
bool isToken = false;
|
||||
@@ -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);
|
||||
@@ -169,13 +178,14 @@ void CockatriceXml4Parser::loadCardsFromXml(QXmlStreamReader &xml)
|
||||
attrName = "picurl";
|
||||
setInfo.setProperty(attrName, attr.value().toString());
|
||||
}
|
||||
sets.insert(setName, setInfo);
|
||||
_sets.insert(setName, setInfo);
|
||||
}
|
||||
// relatd cards
|
||||
} else if (xml.name() == "related" || xml.name() == "reverse-related") {
|
||||
bool attach = false;
|
||||
// related cards
|
||||
} else if (xmlName == "related" || xmlName == "reverse-related") {
|
||||
CardRelation::AttachType attachType = CardRelation::DoesNotAttach;
|
||||
bool exclude = false;
|
||||
bool variable = false;
|
||||
bool persistent = false;
|
||||
int count = 1;
|
||||
QXmlStreamAttributes attrs = xml.attributes();
|
||||
QString cardName = xml.readElementText(QXmlStreamReader::IncludeChildElements);
|
||||
@@ -195,28 +205,33 @@ void CockatriceXml4Parser::loadCardsFromXml(QXmlStreamReader &xml)
|
||||
}
|
||||
|
||||
if (attrs.hasAttribute("attach")) {
|
||||
attach = true;
|
||||
attachType = attrs.value("attach").toString() == "transform" ? CardRelation::TransformInto
|
||||
: CardRelation::AttachTo;
|
||||
}
|
||||
|
||||
if (attrs.hasAttribute("exclude")) {
|
||||
exclude = true;
|
||||
}
|
||||
|
||||
auto *relation = new CardRelation(cardName, attach, exclude, variable, count);
|
||||
if (xml.name() == "reverse-related") {
|
||||
if (attrs.hasAttribute("persistent")) {
|
||||
persistent = true;
|
||||
}
|
||||
|
||||
auto *relation = new CardRelation(cardName, attachType, exclude, variable, count, persistent);
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
CardInfoPtr newCard = CardInfo::newInstance(name, text, isToken, properties, relatedCards,
|
||||
reverseRelatedCards, sets, cipt, tableRow, upsideDown);
|
||||
reverseRelatedCards, _sets, cipt, tableRow, upsideDown);
|
||||
emit addCard(newCard);
|
||||
}
|
||||
}
|
||||
@@ -280,12 +295,14 @@ static QXmlStreamWriter &operator<<(QXmlStreamWriter &xml, const CardInfoPtr &in
|
||||
for (auto i : related) {
|
||||
xml.writeStartElement("related");
|
||||
if (i->getDoesAttach()) {
|
||||
xml.writeAttribute("attach", "attach");
|
||||
xml.writeAttribute("attach", i->getAttachTypeAsString());
|
||||
}
|
||||
if (i->getIsCreateAllExclusion()) {
|
||||
xml.writeAttribute("exclude", "exclude");
|
||||
}
|
||||
|
||||
if (i->getIsPersistent()) {
|
||||
xml.writeAttribute("persistent", "persistent");
|
||||
}
|
||||
if (i->getIsVariable()) {
|
||||
if (1 == i->getDefaultCount()) {
|
||||
xml.writeAttribute("count", "x");
|
||||
@@ -302,13 +319,16 @@ static QXmlStreamWriter &operator<<(QXmlStreamWriter &xml, const CardInfoPtr &in
|
||||
for (auto i : reverseRelated) {
|
||||
xml.writeStartElement("reverse-related");
|
||||
if (i->getDoesAttach()) {
|
||||
xml.writeAttribute("attach", "attach");
|
||||
xml.writeAttribute("attach", i->getAttachTypeAsString());
|
||||
}
|
||||
|
||||
if (i->getIsCreateAllExclusion()) {
|
||||
xml.writeAttribute("exclude", "exclude");
|
||||
}
|
||||
|
||||
if (i->getIsPersistent()) {
|
||||
xml.writeAttribute("persistent", "persistent");
|
||||
}
|
||||
if (i->getIsVariable()) {
|
||||
if (1 == i->getDefaultCount()) {
|
||||
xml.writeAttribute("count", "x");
|
||||
@@ -336,7 +356,7 @@ static QXmlStreamWriter &operator<<(QXmlStreamWriter &xml, const CardInfoPtr &in
|
||||
return xml;
|
||||
}
|
||||
|
||||
bool CockatriceXml4Parser::saveToFile(SetNameMap sets,
|
||||
bool CockatriceXml4Parser::saveToFile(SetNameMap _sets,
|
||||
CardNameMap cards,
|
||||
const QString &fileName,
|
||||
const QString &sourceUrl,
|
||||
@@ -363,9 +383,9 @@ bool CockatriceXml4Parser::saveToFile(SetNameMap sets,
|
||||
xml.writeTextElement("sourceVersion", sourceVersion);
|
||||
xml.writeEndElement();
|
||||
|
||||
if (sets.count() > 0) {
|
||||
if (_sets.count() > 0) {
|
||||
xml.writeStartElement("sets");
|
||||
for (CardSetPtr set : sets) {
|
||||
for (CardSetPtr set : _sets) {
|
||||
xml << set;
|
||||
}
|
||||
xml.writeEndElement();
|
||||
|
||||
@@ -14,7 +14,7 @@ public:
|
||||
~CockatriceXml4Parser() override = default;
|
||||
bool getCanParseFile(const QString &name, QIODevice &device) override;
|
||||
void parseFile(QIODevice &device) override;
|
||||
bool saveToFile(SetNameMap sets,
|
||||
bool saveToFile(SetNameMap _sets,
|
||||
CardNameMap cards,
|
||||
const QString &fileName,
|
||||
const QString &sourceUrl = "unknown",
|
||||
|
||||
@@ -24,7 +24,7 @@ void CardDragItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *opti
|
||||
AbstractCardDragItem::paint(painter, option, widget);
|
||||
|
||||
if (occupied)
|
||||
painter->fillRect(boundingRect(), QColor(200, 0, 0, 100));
|
||||
painter->fillPath(shape(), QColor(200, 0, 0, 100));
|
||||
}
|
||||
|
||||
void CardDragItem::updatePosition(const QPointF &cursorScenePos)
|
||||
@@ -53,8 +53,20 @@ void CardDragItem::updatePosition(const QPointF &cursorScenePos)
|
||||
|
||||
QPointF zonePos = currentZone->scenePos();
|
||||
QPointF cursorPosInZone = cursorScenePos - zonePos;
|
||||
QPointF cardTopLeft = cursorPosInZone - hotSpot;
|
||||
QPointF closestGridPoint = cursorZone->closestGridPoint(cardTopLeft);
|
||||
|
||||
// If we are on a Table, we center the card around the cursor, because we
|
||||
// snap it into place and no longer see it being dragged.
|
||||
//
|
||||
// For other zones (where we do display the card under the cursor), we use
|
||||
// the hotspot to feel like the card was dragged at the corresponding
|
||||
// position.
|
||||
TableZone *tableZone = qobject_cast<TableZone *>(cursorZone);
|
||||
QPointF closestGridPoint;
|
||||
if (tableZone)
|
||||
closestGridPoint = tableZone->closestGridPoint(cursorPosInZone);
|
||||
else
|
||||
closestGridPoint = cursorPosInZone - hotSpot;
|
||||
|
||||
QPointF newPos = zonePos + closestGridPoint;
|
||||
|
||||
if (newPos != pos()) {
|
||||
@@ -83,7 +95,7 @@ void CardDragItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
||||
|
||||
QList<CardDragItem *> dragItemList;
|
||||
CardZone *startZone = static_cast<CardItem *>(item)->getZone();
|
||||
if (currentZone && !(static_cast<CardItem *>(item)->getAttachedTo() && (startZone == currentZone))) {
|
||||
if (currentZone && !(static_cast<CardItem *>(item)->getAttachedTo() && (startZone == currentZone)) && !occupied) {
|
||||
dragItemList.append(this);
|
||||
for (int i = 0; i < childDrags.size(); i++) {
|
||||
CardDragItem *c = static_cast<CardDragItem *>(childDrags[i]);
|
||||
|
||||
@@ -4,8 +4,7 @@
|
||||
#include "main.h"
|
||||
#include "pictureloader.h"
|
||||
|
||||
#include <QPainter>
|
||||
#include <QStyle>
|
||||
#include <QStylePainter>
|
||||
#include <QWidget>
|
||||
|
||||
CardInfoPicture::CardInfoPicture(QWidget *parent) : QWidget(parent), info(nullptr), pixmapDirty(true)
|
||||
@@ -55,6 +54,13 @@ void CardInfoPicture::paintEvent(QPaintEvent *)
|
||||
if (pixmapDirty)
|
||||
loadPixmap();
|
||||
|
||||
QPainter painter(this);
|
||||
style()->drawItemPixmap(&painter, rect(), Qt::AlignHCenter, resizedPixmap);
|
||||
QSize scaledSize = resizedPixmap.size().scaled(size(), Qt::KeepAspectRatio);
|
||||
QPoint topLeft{(width() - scaledSize.width()) / 2, (height() - scaledSize.height()) / 2};
|
||||
qreal radius = 0.05 * scaledSize.width();
|
||||
|
||||
QStylePainter painter(this);
|
||||
QPainterPath shape;
|
||||
shape.addRoundedRect(QRect(topLeft, scaledSize), radius, radius);
|
||||
painter.setClipPath(shape);
|
||||
painter.drawItemPixmap(QRect(topLeft, scaledSize), Qt::AlignCenter, resizedPixmap);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -97,10 +97,10 @@ void CardItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
|
||||
QMapIterator<int, int> counterIterator(counters);
|
||||
while (counterIterator.hasNext()) {
|
||||
counterIterator.next();
|
||||
QColor color;
|
||||
color.setHsv(counterIterator.key() * 60, 150, 255);
|
||||
QColor _color;
|
||||
_color.setHsv(counterIterator.key() * 60, 150, 255);
|
||||
|
||||
paintNumberEllipse(counterIterator.value(), 14, color, i, counters.size(), painter);
|
||||
paintNumberEllipse(counterIterator.value(), 14, _color, i, counters.size(), painter);
|
||||
++i;
|
||||
}
|
||||
|
||||
@@ -141,21 +141,19 @@ void CardItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
|
||||
}
|
||||
|
||||
if (getBeingPointedAt()) {
|
||||
painter->fillRect(boundingRect(), QBrush(QColor(255, 0, 0, 100)));
|
||||
painter->fillPath(shape(), QBrush(QColor(255, 0, 0, 100)));
|
||||
}
|
||||
|
||||
if (doesntUntap) {
|
||||
painter->save();
|
||||
|
||||
painter->setRenderHint(QPainter::Antialiasing, false);
|
||||
transformPainter(painter, translatedSize, tapAngle);
|
||||
|
||||
QPen pen;
|
||||
pen.setColor(Qt::magenta);
|
||||
const int penWidth = 1;
|
||||
pen.setWidth(penWidth);
|
||||
pen.setWidth(0); // Cosmetic pen
|
||||
painter->setPen(pen);
|
||||
painter->drawRect(QRectF(0, 0, translatedSize.width() + penWidth, translatedSize.height() - penWidth));
|
||||
painter->drawPath(shape());
|
||||
|
||||
painter->restore();
|
||||
}
|
||||
@@ -235,25 +233,25 @@ void CardItem::resetState()
|
||||
update();
|
||||
}
|
||||
|
||||
void CardItem::processCardInfo(const ServerInfo_Card &info)
|
||||
void CardItem::processCardInfo(const ServerInfo_Card &_info)
|
||||
{
|
||||
counters.clear();
|
||||
const int counterListSize = info.counter_list_size();
|
||||
const int counterListSize = _info.counter_list_size();
|
||||
for (int i = 0; i < counterListSize; ++i) {
|
||||
const ServerInfo_CardCounter &counterInfo = info.counter_list(i);
|
||||
const ServerInfo_CardCounter &counterInfo = _info.counter_list(i);
|
||||
counters.insert(counterInfo.id(), counterInfo.value());
|
||||
}
|
||||
|
||||
setId(info.id());
|
||||
setName(QString::fromStdString(info.name()));
|
||||
setAttacking(info.attacking());
|
||||
setFaceDown(info.face_down());
|
||||
setPT(QString::fromStdString(info.pt()));
|
||||
setAnnotation(QString::fromStdString(info.annotation()));
|
||||
setColor(QString::fromStdString(info.color()));
|
||||
setTapped(info.tapped());
|
||||
setDestroyOnZoneChange(info.destroy_on_zone_change());
|
||||
setDoesntUntap(info.doesnt_untap());
|
||||
setId(_info.id());
|
||||
setName(QString::fromStdString(_info.name()));
|
||||
setAttacking(_info.attacking());
|
||||
setFaceDown(_info.face_down());
|
||||
setPT(QString::fromStdString(_info.pt()));
|
||||
setAnnotation(QString::fromStdString(_info.annotation()));
|
||||
setColor(QString::fromStdString(_info.color()));
|
||||
setTapped(_info.tapped());
|
||||
setDestroyOnZoneChange(_info.destroy_on_zone_change());
|
||||
setDoesntUntap(_info.doesnt_untap());
|
||||
}
|
||||
|
||||
CardDragItem *CardItem::createDragItem(int _id, const QPointF &_pos, const QPointF &_scenePos, bool faceDown)
|
||||
@@ -286,15 +284,36 @@ void CardItem::drawArrow(const QColor &arrowColor)
|
||||
scene()->addItem(arrow);
|
||||
arrow->grabMouse();
|
||||
|
||||
QListIterator<QGraphicsItem *> itemIterator(scene()->selectedItems());
|
||||
while (itemIterator.hasNext()) {
|
||||
CardItem *c = qgraphicsitem_cast<CardItem *>(itemIterator.next());
|
||||
if (!c || (c == this))
|
||||
for (const auto &item : scene()->selectedItems()) {
|
||||
CardItem *card = qgraphicsitem_cast<CardItem *>(item);
|
||||
if (card == nullptr || card == this)
|
||||
continue;
|
||||
if (c->getZone() != zone)
|
||||
if (card->getZone() != zone)
|
||||
continue;
|
||||
|
||||
ArrowDragItem *childArrow = new ArrowDragItem(arrowOwner, c, arrowColor);
|
||||
ArrowDragItem *childArrow = new ArrowDragItem(arrowOwner, card, arrowColor);
|
||||
scene()->addItem(childArrow);
|
||||
arrow->addChildArrow(childArrow);
|
||||
}
|
||||
}
|
||||
|
||||
void CardItem::drawAttachArrow()
|
||||
{
|
||||
if (static_cast<TabGame *>(owner->parent())->getSpectator())
|
||||
return;
|
||||
|
||||
auto *arrow = new ArrowAttachItem(this);
|
||||
scene()->addItem(arrow);
|
||||
arrow->grabMouse();
|
||||
|
||||
for (const auto &item : scene()->selectedItems()) {
|
||||
CardItem *card = qgraphicsitem_cast<CardItem *>(item);
|
||||
if (card == nullptr)
|
||||
continue;
|
||||
if (card->getZone() != zone)
|
||||
continue;
|
||||
|
||||
ArrowAttachItem *childArrow = new ArrowAttachItem(card);
|
||||
scene()->addItem(childArrow);
|
||||
arrow->addChildArrow(childArrow);
|
||||
}
|
||||
@@ -329,22 +348,24 @@ void CardItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
||||
|
||||
bool forceFaceDown = event->modifiers().testFlag(Qt::ShiftModifier);
|
||||
|
||||
createDragItem(id, event->pos(), event->scenePos(), facedown || forceFaceDown);
|
||||
// Use the buttonDownPos to align the hot spot with the position when
|
||||
// the user originally clicked
|
||||
createDragItem(id, event->buttonDownPos(Qt::LeftButton), event->scenePos(), facedown || forceFaceDown);
|
||||
dragItem->grabMouse();
|
||||
|
||||
QList<QGraphicsItem *> sel = scene()->selectedItems();
|
||||
int j = 0;
|
||||
for (int i = 0; i < sel.size(); i++) {
|
||||
CardItem *c = static_cast<CardItem *>(sel.at(i));
|
||||
if ((c == this) || (c->getZone() != zone))
|
||||
int childIndex = 0;
|
||||
for (const auto &item : scene()->selectedItems()) {
|
||||
CardItem *card = static_cast<CardItem *>(item);
|
||||
if ((card == this) || (card->getZone() != zone))
|
||||
continue;
|
||||
++j;
|
||||
++childIndex;
|
||||
QPointF childPos;
|
||||
if (zone->getHasCardAttr())
|
||||
childPos = c->pos() - pos();
|
||||
childPos = card->pos() - pos();
|
||||
else
|
||||
childPos = QPointF(j * CARD_WIDTH / 2, 0);
|
||||
CardDragItem *drag = new CardDragItem(c, c->getId(), childPos, c->getFaceDown() || forceFaceDown, dragItem);
|
||||
childPos = QPointF(childIndex * CARD_WIDTH / 2, 0);
|
||||
CardDragItem *drag =
|
||||
new CardDragItem(card, card->getId(), childPos, card->getFaceDown() || forceFaceDown, dragItem);
|
||||
drag->setPos(dragItem->pos() + childPos);
|
||||
scene()->addItem(drag);
|
||||
}
|
||||
@@ -369,7 +390,8 @@ void CardItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
if (event->button() == Qt::RightButton) {
|
||||
if (cardMenu != nullptr && !cardMenu->isEmpty() && owner != nullptr) {
|
||||
cardMenu->exec(event->screenPos());
|
||||
cardMenu->popup(event->screenPos());
|
||||
return;
|
||||
}
|
||||
} else if ((event->modifiers() != Qt::AltModifier) && (event->button() == Qt::LeftButton) &&
|
||||
(!SettingsCache::instance().getDoubleClickToPlay())) {
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#define CARDITEM_H
|
||||
|
||||
#include "abstractcarditem.h"
|
||||
#include "server_card.h"
|
||||
|
||||
class CardDatabase;
|
||||
class CardDragItem;
|
||||
@@ -130,14 +131,14 @@ public:
|
||||
}
|
||||
void removeAttachedCard(CardItem *card)
|
||||
{
|
||||
attachedCards.removeAt(attachedCards.indexOf(card));
|
||||
attachedCards.removeOne(card);
|
||||
}
|
||||
const QList<CardItem *> &getAttachedCards() const
|
||||
{
|
||||
return attachedCards;
|
||||
}
|
||||
void resetState();
|
||||
void processCardInfo(const ServerInfo_Card &info);
|
||||
void processCardInfo(const ServerInfo_Card &_info);
|
||||
|
||||
QMenu *getCardMenu() const
|
||||
{
|
||||
@@ -156,6 +157,7 @@ public:
|
||||
CardDragItem *createDragItem(int _id, const QPointF &_pos, const QPointF &_scenePos, bool faceDown);
|
||||
void deleteDragItem();
|
||||
void drawArrow(const QColor &arrowColor);
|
||||
void drawAttachArrow();
|
||||
void playCard(bool faceDown);
|
||||
|
||||
protected:
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -23,7 +21,7 @@ UserMessagePosition::UserMessagePosition(QTextCursor &cursor)
|
||||
relativePosition = cursor.position() - block.position();
|
||||
}
|
||||
|
||||
ChatView::ChatView(const TabSupervisor *_tabSupervisor,
|
||||
ChatView::ChatView(TabSupervisor *_tabSupervisor,
|
||||
const UserlistProxy *_userlistProxy,
|
||||
TabGame *_game,
|
||||
bool _showTimestamps,
|
||||
@@ -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);
|
||||
@@ -472,15 +470,23 @@ void ChatView::showSystemPopup(const QString &userName)
|
||||
|
||||
QColor ChatView::getCustomMentionColor()
|
||||
{
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 4, 0))
|
||||
QColor customColor = QColor::fromString("#" + SettingsCache::instance().getChatMentionColor());
|
||||
#else
|
||||
QColor customColor;
|
||||
customColor.setNamedColor("#" + SettingsCache::instance().getChatMentionColor());
|
||||
#endif
|
||||
return customColor.isValid() ? customColor : DEFAULT_MENTION_COLOR;
|
||||
}
|
||||
|
||||
QColor ChatView::getCustomHighlightColor()
|
||||
{
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 4, 0))
|
||||
QColor customColor = QColor::fromString("#" + SettingsCache::instance().getChatMentionColor());
|
||||
#else
|
||||
QColor customColor;
|
||||
customColor.setNamedColor("#" + SettingsCache::instance().getChatHighlightColor());
|
||||
customColor.setNamedColor("#" + SettingsCache::instance().getChatMentionColor());
|
||||
#endif
|
||||
return customColor.isValid() ? customColor : DEFAULT_MENTION_COLOR;
|
||||
}
|
||||
|
||||
@@ -512,7 +518,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 +578,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 +592,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: {
|
||||
|
||||
@@ -33,7 +33,7 @@ class ChatView : public QTextBrowser
|
||||
{
|
||||
Q_OBJECT
|
||||
protected:
|
||||
const TabSupervisor *const tabSupervisor;
|
||||
TabSupervisor *const tabSupervisor;
|
||||
TabGame *const game;
|
||||
|
||||
private:
|
||||
@@ -65,8 +65,8 @@ private:
|
||||
QTextCursor prepareBlock(bool same = false);
|
||||
void appendCardTag(QTextCursor &cursor, const QString &cardName);
|
||||
void appendUrlTag(QTextCursor &cursor, QString url);
|
||||
QColor getCustomMentionColor();
|
||||
QColor getCustomHighlightColor();
|
||||
static QColor getCustomMentionColor();
|
||||
static QColor getCustomHighlightColor();
|
||||
void showSystemPopup(const QString &userName);
|
||||
bool isModeratorSendingGlobal(QFlags<ServerInfo_User::UserLevelFlag> userLevelFlag, QString message);
|
||||
void checkTag(QTextCursor &cursor, QString &message);
|
||||
@@ -83,7 +83,7 @@ private slots:
|
||||
void actMessageClicked();
|
||||
|
||||
public:
|
||||
ChatView(const TabSupervisor *_tabSupervisor,
|
||||
ChatView(TabSupervisor *_tabSupervisor,
|
||||
const UserlistProxy *_userlistProxy,
|
||||
TabGame *_game,
|
||||
bool _showTimestamps,
|
||||
@@ -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,29 +0,0 @@
|
||||
#ifndef CLIENT_METATYPES_H
|
||||
#define CLIENT_METATYPES_H
|
||||
|
||||
#include <QMetaType>
|
||||
|
||||
Q_DECLARE_METATYPE(QVariant)
|
||||
Q_DECLARE_METATYPE(CommandContainer)
|
||||
Q_DECLARE_METATYPE(Response)
|
||||
Q_DECLARE_METATYPE(Response::ResponseCode)
|
||||
Q_DECLARE_METATYPE(ClientStatus)
|
||||
Q_DECLARE_METATYPE(RoomEvent)
|
||||
Q_DECLARE_METATYPE(GameEventContainer)
|
||||
Q_DECLARE_METATYPE(Event_ServerIdentification)
|
||||
Q_DECLARE_METATYPE(Event_ConnectionClosed)
|
||||
Q_DECLARE_METATYPE(Event_ServerShutdown)
|
||||
Q_DECLARE_METATYPE(Event_AddToList)
|
||||
Q_DECLARE_METATYPE(Event_RemoveFromList)
|
||||
Q_DECLARE_METATYPE(Event_UserJoined)
|
||||
Q_DECLARE_METATYPE(Event_UserLeft)
|
||||
Q_DECLARE_METATYPE(Event_ServerMessage)
|
||||
Q_DECLARE_METATYPE(Event_ListRooms)
|
||||
Q_DECLARE_METATYPE(Event_GameJoined)
|
||||
Q_DECLARE_METATYPE(Event_UserMessage)
|
||||
Q_DECLARE_METATYPE(ServerInfo_User)
|
||||
Q_DECLARE_METATYPE(QList<ServerInfo_User>)
|
||||
Q_DECLARE_METATYPE(Event_ReplayAdded)
|
||||
Q_DECLARE_METATYPE(QList<QString>)
|
||||
|
||||
#endif
|
||||
@@ -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";
|
||||
}
|
||||
@@ -288,7 +289,7 @@ QString DeckLoader::getCardZoneFromName(QString cardName, QString currentZoneNam
|
||||
return currentZoneName;
|
||||
}
|
||||
|
||||
QString DeckLoader::getCompleteCardName(const QString cardName) const
|
||||
QString DeckLoader::getCompleteCardName(const QString &cardName) const
|
||||
{
|
||||
if (db) {
|
||||
CardInfoPtr temp = db->guessCard(cardName);
|
||||
|
||||
@@ -57,8 +57,8 @@ protected:
|
||||
const InnerDecklistNode *zoneNode,
|
||||
QList<DecklistCardNode *> cards,
|
||||
bool addComments = true);
|
||||
virtual QString getCardZoneFromName(QString cardName, QString currentZoneName);
|
||||
virtual QString getCompleteCardName(const QString cardName) const;
|
||||
[[nodiscard]] QString getCardZoneFromName(QString cardName, QString currentZoneName) override;
|
||||
[[nodiscard]] QString getCompleteCardName(const QString &cardName) const override;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QNetworkReply>
|
||||
#include <QNetworkRequest>
|
||||
#include <QRegExp>
|
||||
#include <QRegularExpression>
|
||||
#include <QUrlQuery>
|
||||
|
||||
DeckStatsInterface::DeckStatsInterface(CardDatabase &_cardDatabase, QObject *parent)
|
||||
@@ -20,7 +20,7 @@ DeckStatsInterface::DeckStatsInterface(CardDatabase &_cardDatabase, QObject *par
|
||||
void DeckStatsInterface::queryFinished(QNetworkReply *reply)
|
||||
{
|
||||
if (reply->error() != QNetworkReply::NoError) {
|
||||
QMessageBox::critical(0, tr("Error"), reply->errorString());
|
||||
QMessageBox::critical(nullptr, tr("Error"), reply->errorString());
|
||||
reply->deleteLater();
|
||||
deleteLater();
|
||||
return;
|
||||
@@ -29,14 +29,15 @@ void DeckStatsInterface::queryFinished(QNetworkReply *reply)
|
||||
QString data(reply->readAll());
|
||||
reply->deleteLater();
|
||||
|
||||
QRegExp rx("<meta property=\"og:url\" content=\"([^\"]+)\"");
|
||||
if (-1 == rx.indexIn(data)) {
|
||||
QMessageBox::critical(0, tr("Error"), tr("The reply from the server could not be parsed."));
|
||||
static const QRegularExpression rx("<meta property=\"og:url\" content=\"([^\"]+)\"");
|
||||
auto match = rx.match(data);
|
||||
if (!match.hasMatch()) {
|
||||
QMessageBox::critical(nullptr, tr("Error"), tr("The reply from the server could not be parsed."));
|
||||
deleteLater();
|
||||
return;
|
||||
}
|
||||
|
||||
QString deckUrl = rx.cap(1);
|
||||
QString deckUrl = match.captured(1);
|
||||
QDesktopServices::openUrl(deckUrl);
|
||||
|
||||
deleteLater();
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
#include <QApplication>
|
||||
#include <QGraphicsSceneMouseEvent>
|
||||
#include <QMouseEvent>
|
||||
#include <QtMath>
|
||||
#include <algorithm>
|
||||
#include <math.h>
|
||||
|
||||
DeckViewCardDragItem::DeckViewCardDragItem(DeckViewCard *_item,
|
||||
const QPointF &_hotSpot,
|
||||
@@ -89,7 +89,8 @@ void DeckViewCard::paint(QPainter *painter, const QStyleOptionGraphicsItem *opti
|
||||
pen.setJoinStyle(Qt::MiterJoin);
|
||||
pen.setColor(originZone == DECK_ZONE_MAIN ? Qt::green : Qt::red);
|
||||
painter->setPen(pen);
|
||||
painter->drawRect(QRectF(1, 1, CARD_WIDTH - 2, CARD_HEIGHT - 2.5));
|
||||
qreal cardRadius = 0.05 * (CARD_WIDTH - 3);
|
||||
painter->drawRoundedRect(QRectF(1.5, 1.5, CARD_WIDTH - 3., CARD_HEIGHT - 3.), cardRadius, cardRadius);
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
@@ -216,7 +217,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 +239,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;
|
||||
@@ -274,16 +273,11 @@ void DeckViewCardContainer::rearrangeItems(const QList<QPair<int, int>> &rowsAnd
|
||||
{
|
||||
currentRowsAndCols = rowsAndCols;
|
||||
|
||||
int totalCols = 0, totalRows = 0;
|
||||
qreal yUntilNow = separatorY + paddingY;
|
||||
qreal x = (qreal)getCardTypeTextWidth();
|
||||
for (int i = 0; i < rowsAndCols.size(); ++i) {
|
||||
const int tempRows = rowsAndCols[i].first;
|
||||
const int tempCols = rowsAndCols[i].second;
|
||||
totalRows += tempRows;
|
||||
if (tempCols > totalCols)
|
||||
totalCols = tempCols;
|
||||
|
||||
QList<QString> cardTypeList = cardsByType.uniqueKeys();
|
||||
QList<DeckViewCard *> row = cardsByType.values(cardTypeList[i]);
|
||||
std::sort(row.begin(), row.end(), DeckViewCardContainer::sortCardsByName);
|
||||
@@ -340,12 +334,14 @@ void DeckViewScene::rebuildTree()
|
||||
{
|
||||
clearContents();
|
||||
|
||||
if (!deck)
|
||||
if (!deck) {
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned int cardsRenderedAlready = 0;
|
||||
InnerDecklistNode *listRoot = deck->getRoot();
|
||||
for (int i = 0; i < listRoot->size(); i++) {
|
||||
InnerDecklistNode *currentZone = dynamic_cast<InnerDecklistNode *>(listRoot->at(i));
|
||||
for (const auto innerDecklistNode : *listRoot) {
|
||||
auto *currentZone = dynamic_cast<InnerDecklistNode *>(innerDecklistNode);
|
||||
|
||||
DeckViewCardContainer *container = cardContainers.value(currentZone->getName(), 0);
|
||||
if (!container) {
|
||||
@@ -355,12 +351,15 @@ void DeckViewScene::rebuildTree()
|
||||
}
|
||||
|
||||
for (int j = 0; j < currentZone->size(); j++) {
|
||||
DecklistCardNode *currentCard = dynamic_cast<DecklistCardNode *>(currentZone->at(j));
|
||||
auto *currentCard = dynamic_cast<DecklistCardNode *>(currentZone->at(j));
|
||||
if (!currentCard)
|
||||
continue;
|
||||
|
||||
for (int k = 0; k < currentCard->getNumber(); ++k) {
|
||||
DeckViewCard *newCard = new DeckViewCard(currentCard->getName(), currentZone->getName(), container);
|
||||
if (++cardsRenderedAlready >= MAX_CARDS_TO_RENDER) {
|
||||
break; // We can't render anymore cards efficiently, evict early
|
||||
}
|
||||
auto *newCard = new DeckViewCard(currentCard->getName(), currentZone->getName(), container);
|
||||
container->addCard(newCard);
|
||||
emit newCardAdded(newCard);
|
||||
}
|
||||
@@ -440,7 +439,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;
|
||||
|
||||
@@ -104,6 +104,7 @@ signals:
|
||||
void sideboardPlanChanged();
|
||||
|
||||
private:
|
||||
static constexpr unsigned int MAX_CARDS_TO_RENDER = 300;
|
||||
bool locked;
|
||||
DeckList *deck;
|
||||
QMap<QString, DeckViewCardContainer *> cardContainers;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
@@ -240,22 +245,22 @@ void DlgConnect::updateDisplayInfo(const QString &saveName)
|
||||
}
|
||||
|
||||
UserConnection_Information uci;
|
||||
QStringList data = uci.getServerInfo(saveName);
|
||||
QStringList _data = uci.getServerInfo(saveName);
|
||||
|
||||
bool savePasswordStatus = (data.at(5) == "1");
|
||||
bool savePasswordStatus = (_data.at(5) == "1");
|
||||
|
||||
saveEdit->setText(data.at(0));
|
||||
hostEdit->setText(data.at(1));
|
||||
portEdit->setText(data.at(2));
|
||||
playernameEdit->setText(data.at(3));
|
||||
saveEdit->setText(_data.at(0));
|
||||
hostEdit->setText(_data.at(1));
|
||||
portEdit->setText(_data.at(2));
|
||||
playernameEdit->setText(_data.at(3));
|
||||
savePasswordCheckBox->setChecked(savePasswordStatus);
|
||||
|
||||
if (savePasswordStatus) {
|
||||
passwordEdit->setText(data.at(4));
|
||||
passwordEdit->setText(_data.at(4));
|
||||
}
|
||||
|
||||
if (!data.at(6).isEmpty()) {
|
||||
QString formattedLink = "<a href=\"" + data.at(6) + "\">" + data.at(6) + "</a>";
|
||||
if (!_data.at(6).isEmpty()) {
|
||||
QString formattedLink = "<a href=\"" + _data.at(6) + "\">" + _data.at(6) + "</a>";
|
||||
serverContactLabel->setText(tr("Webpage") + ":");
|
||||
serverContactLink->setText(formattedLink);
|
||||
} else {
|
||||
|
||||
@@ -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"));
|
||||
@@ -233,13 +235,13 @@ void DlgCreateGame::actOK()
|
||||
cmd.set_join_as_judge(QApplication::keyboardModifiers() & Qt::ShiftModifier);
|
||||
cmd.set_join_as_spectator(createGameAsSpectatorCheckBox->isChecked());
|
||||
|
||||
QString gameTypes = QString();
|
||||
QString _gameTypes = QString();
|
||||
QMapIterator<int, QRadioButton *> gameTypeCheckBoxIterator(gameTypeCheckBoxes);
|
||||
while (gameTypeCheckBoxIterator.hasNext()) {
|
||||
gameTypeCheckBoxIterator.next();
|
||||
if (gameTypeCheckBoxIterator.value()->isChecked()) {
|
||||
cmd.add_game_type_ids(gameTypeCheckBoxIterator.key());
|
||||
gameTypes += gameTypeCheckBoxIterator.value()->text() + ", ";
|
||||
_gameTypes += gameTypeCheckBoxIterator.value()->text() + ", ";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -254,7 +256,7 @@ void DlgCreateGame::actOK()
|
||||
SettingsCache::instance().setSpectatorsCanTalk(spectatorsCanTalkCheckBox->isChecked());
|
||||
SettingsCache::instance().setSpectatorsCanSeeEverything(spectatorsSeeEverythingCheckBox->isChecked());
|
||||
SettingsCache::instance().setCreateGameAsSpectator(createGameAsSpectatorCheckBox->isChecked());
|
||||
SettingsCache::instance().setGameTypes(gameTypes);
|
||||
SettingsCache::instance().setGameTypes(_gameTypes);
|
||||
}
|
||||
PendingCommand *pend = room->prepareRoomCommand(cmd);
|
||||
connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this, SLOT(checkResponse(Response)));
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user