Compare commits

...

47 Commits

Author SHA1 Message Date
Ray b8e2e14244 update taiwanese translation 2024-01-25 15:06:49 +01:00
Syping ce0721a6f4 update german translation 2023-10-08 18:45:08 +02:00
Syping 022a5045a3 update translations, RDR 2 detection in importFile 2023-10-08 18:40:34 +02:00
Syping 446f0b07b0 fix RDR 2 photo import, little code rework 2023-10-07 15:24:07 +02:00
Syping 61387ee711 completed RDR 2 game folder detection, some code rework 2023-10-06 18:52:50 +02:00
Syping 259e785165 more RDR 2-awareness, some code rework 2023-10-06 15:37:48 +02:00
Syping e7721404b6 more work towards supporting RDR 2, some export changes 2023-10-06 00:20:48 +02:00
Syping d6968792aa rework ImportDialog and remove ImageCropper 2023-10-05 17:31:41 +02:00
Syping 23663d389b distinguish more GTA V RDR 2 code, remove SidebarGenerator 2023-10-05 17:10:01 +02:00
Syping 51f9cffddf improvement for RDR 2 support, some code reworks 2023-10-05 16:39:10 +02:00
Syping 9c0cc39b4f add RDR 2 photo import and remove savegame import 2023-10-03 23:21:16 +02:00
Syping 8f8ef469d4 fix RDR2 fileFormat 2023-10-03 22:49:24 +02:00
Syping 4fdde8e485 improve format awareness, improve RNG 2023-10-03 22:47:11 +02:00
Syping 01424ef51f remove template and add initialise function 2023-10-02 19:21:36 +02:00
Syping 12c6b7425c libragephoto upstream (0.5.0, fix) 2023-06-11 23:31:18 +02:00
Syping c74e9a00d0 libragephoto upstream (0.5.0)
SnapmaticPicture.h: RagePhoto(A).h -> RagePhoto(A)
2023-06-11 22:50:44 +02:00
Syping 34bc0a5e3e libragephoto upstream 2023-06-07 06:14:00 +02:00
Syping 71b7b32f60 libragephoto upstream 2023-06-06 19:49:04 +02:00
Syping 0a812a977a libragephoto upstream (0.4.0) 2023-05-14 12:09:15 +02:00
Syping 40675f605d improve file dialog experience 2023-05-13 01:17:46 +02:00
Syping 09d79228a0 build fix for older Boost.JSON versions (2/2) 2023-05-11 21:54:13 +02:00
Syping 13fa4331fb build fix for older Boost.JSON versions 2023-05-11 21:51:51 +02:00
Syping 392f35a96d PictureDialog: fix window height 2023-05-10 18:02:07 +02:00
Syping bb06af8a79 add res cache, fix size bug, support 8K exports 2023-05-10 17:59:30 +02:00
Syping 0e6a6ae34a SnapmaticPicture: update size, width and height for RDR 2 2023-05-10 15:17:19 +02:00
Syping b19cfdee0f libragephoto upstream 2023-05-09 23:34:25 +02:00
Syping 7f7b202df9 add WITH_BOOST option to build with linked Boost 2023-04-09 21:45:58 +02:00
Syping 6e38894bcc improved RDR 2 support, libragephoto upstream 2023-04-05 22:26:57 +02:00
Syping a10d259db1 SnapmaticJson: fix indent of empty array and objects 2023-03-31 01:33:54 +02:00
Syping 7e13f01d6d add JPEG signatures to SnapmaticPicture 2023-03-30 18:41:55 +02:00
Syping 489bf531b8 fix Qt 5 build (force C++17), increase JsonEditorDialog height 2023-03-29 21:10:33 +02:00
Syping 7720fb2cac use boost.json standalone 2023-03-29 17:26:59 +02:00
Syping 557b999608 replace json serializer with boost, libragephoto upstream 2023-03-29 17:12:32 +02:00
Syping aa4b2fc080 fix directory scanner crash, libragephoto upstream 2023-03-27 15:07:12 +02:00
Syping 2d0830254b better RDR 2 support, bug fixes + optimisation, libragephoto upstream 2023-02-27 14:17:50 +01:00
Syping b19152fdae SnapmaticPicture: fix format detection and libragephoto update
- libragephoto: update to upstream
2023-02-23 09:23:09 +01:00
Syping dca2e9fe59 libragephoto: add option to enable ABI wrapper 2023-02-20 15:22:30 +01:00
Syping 4dceb52fe7 upstream libragephoto 2023-02-20 15:00:43 +01:00
Syping 83e133ddf2 SnapmaticPicture: add G5EX RagePhotoFormatParser 2023-02-20 14:04:17 +01:00
Syping bb62cc438d upstream libragephoto 2023-02-11 21:16:22 +01:00
Syping 1528879b42 removal and rework of legacy code 2023-02-09 20:42:05 +01:00
Syping a456b06ad3 libragephoto upstream, SnapmaticPicture readAll -> read(size) 2023-02-08 20:05:15 +01:00
Syping 3d87cebeac SnapmaticPicture: replace read() with readAll() 2023-01-27 23:27:57 +01:00
Syping 8d866cb44e replace free with std::free 2023-01-27 21:39:12 +01:00
Syping 487372f7ee translate libragephoto errors to gta5view errors 2023-01-27 21:10:17 +01:00
Syping 050a281be8 replace internal RagePhoto with libragephoto, few other changes
- remove more Qt4 compatibility stuff
- replaced internal RagePhoto with libragephoto 0.2
- some minor UI changes
- year 2023 updates
2023-01-27 20:09:43 +01:00
Syping e463d2d22c drop Qt4 support, move Source files and few other changes 2023-01-10 19:03:03 +01:00
185 changed files with 10037 additions and 16853 deletions

View File

@ -1,33 +0,0 @@
IDI_ICON1 ICON DISCARDABLE "5sync.ico"
#define RT_MANIFEST 24
#define CREATEPROCESS_MANIFEST_RESOURCE_ID 1
CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "gta5view.exe.manifest"
#include <windows.h>
VS_VERSION_INFO VERSIONINFO
FILEVERSION MAJOR_VER, MINOR_VER, PATCH_VER, INT_BUILD_VER
PRODUCTVERSION MAJOR_VER, MINOR_VER, PATCH_VER, INT_BUILD_VER
FILEFLAGSMASK 0x3fL
FILEFLAGS 0
FILEOS VOS_NT_WINDOWS32
FILETYPE VFT_APP
FILESUBTYPE VFT2_UNKNOWN
BEGIN
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x0809, 1200
END
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "CompanyName", "Syping"
VALUE "FileDescription", "gta5view"
VALUE "FileVersion", "MAJOR_VER.MINOR_VER.PATCH_VERSTR_BUILD_VER"
VALUE "InternalName", "gta5view"
VALUE "LegalCopyright", "Copyright © 2016-2022 Syping"
VALUE "OriginalFilename", "gta5view.exe"
VALUE "ProductName", "gta5view"
VALUE "ProductVersion", "MAJOR_VER.MINOR_VER.PATCH_VERSTR_BUILD_VER"
END
END
END

View File

@ -1,72 +0,0 @@
#!/usr/bin/env bash
if [ $(git name-rev --tags --name-only $(git rev-parse HEAD)) == "undefined" ]; then
export APPLICATION_VERSION=$(lua -e 'for line in io.lines("config.h") do local m = string.match(line, "#define GTA5SYNC_APPVER \"(.+)\"$"); if m then print(m); os.exit(0) end end')
else
export APPLICATION_VERSION=$(git name-rev --tags --name-only $(git rev-parse HEAD))
fi
export PACKAGE_VERSION=$(grep -oE '^[^\-]*' <<< $APPLICATION_VERSION)
export PACKAGE_BUILD=$(grep -oP '\-\K.+' <<< $APPLICATION_VERSION)
export EXECUTABLE_VERSION=${PACKAGE_VERSION}${PACKAGE_BUILD}${EXECUTABLE_TAG}
export APPLICATION_MAJOR_VERSION=$(cut -d. -f1 <<< $APPLICATION_VERSION)
export APPLICATION_MINOR_VERSION=$(cut -d. -f2 <<< $APPLICATION_VERSION)
export APPLICATION_PATCH_VERSION=$(cut -d. -f3 <<< $APPLICATION_VERSION)
if [ "${PACKAGE_BUILD}" == "" ]; then
export PACKAGE_BUILD=1
else
export APPLICATION_BUILD_INT_VERSION=$(grep -oE '[1-9]*$' <<< $PACKAGE_BUILD)
export APPLICATION_BUILD_STR_VERSION=-${PACKAGE_BUILD}
fi
cat ".ci/app.rc" | sed \
-e "s/MAJOR_VER/$APPLICATION_MAJOR_VERSION/g" \
-e "s/MINOR_VER/$APPLICATION_MINOR_VERSION/g" \
-e "s/PATCH_VER/$APPLICATION_PATCH_VERSION/g" \
-e "s/INT_BUILD_VER/0/g" \
-e "s/STR_BUILD_VER/$APPLICATION_BUILD_STR_VERSION/g" \
-e "s/STR_BUILD_VER/$APPLICATION_BUILD_STR_VERSION/g" \
> "res/app.rc"
if [ "${BUILD_TYPE}" == "ALPHA" ]; then
export CMAKE_BUILD_TYPE="-DGTA5VIEW_BUILDTYPE=Alpha"
export QMAKE_BUILD_TYPE="DEFINES+=GTA5SYNC_BUILDTYPE=\\\\\\\"Alpha\\\\\\\""
elif [ "${BUILD_TYPE}" == "Alpha" ]; then
export CMAKE_BUILD_TYPE="-DGTA5VIEW_BUILDTYPE=Alpha"
export QMAKE_BUILD_TYPE="DEFINES+=GTA5SYNC_BUILDTYPE=\\\\\\\"Alpha\\\\\\\""
elif [ "${BUILD_TYPE}" == "BETA" ]; then
export CMAKE_BUILD_TYPE="-DGTA5VIEW_BUILDTYPE=Beta"
export QMAKE_BUILD_TYPE="DEFINES+=GTA5SYNC_BUILDTYPE=\\\\\\\"Beta\\\\\\\""
elif [ "${BUILD_TYPE}" == "Beta" ]; then
export CMAKE_BUILD_TYPE="-DGTA5VIEW_BUILDTYPE=Beta"
export QMAKE_BUILD_TYPE="DEFINES+=GTA5SYNC_BUILDTYPE=\\\\\\\"Beta\\\\\\\""
elif [ "${BUILD_TYPE}" == "DEV" ]; then
export CMAKE_BUILD_TYPE="-DGTA5VIEW_BUILDTYPE=Developer"
export QMAKE_BUILD_TYPE="DEFINES+=GTA5SYNC_BUILDTYPE=\\\\\\\"Developer\\\\\\\""
elif [ "${BUILD_TYPE}" == "Development" ]; then
export CMAKE_BUILD_TYPE="-DGTA5VIEW_BUILDTYPE=Developer"
export QMAKE_BUILD_TYPE="DEFINES+=GTA5SYNC_BUILDTYPE=\\\\\\\"Developer\\\\\\\""
elif [ "${BUILD_TYPE}" == "DAILY" ]; then
export CMAKE_BUILD_TYPE="-DGTA5VIEW_BUILDTYPE=Daily Build"
export QMAKE_BUILD_TYPE="DEFINES+=GTA5SYNC_BUILDTYPE=\\\\\\\"Daily Build\\\\\\\""
elif [ "${BUILD_TYPE}" == "Daily" ]; then
export CMAKE_BUILD_TYPE="-DGTA5VIEW_BUILDTYPE=Daily Build"
export QMAKE_BUILD_TYPE="DEFINES+=GTA5SYNC_BUILDTYPE=\\\\\\\"Daily Build\\\\\\\""
elif [ "${BUILD_TYPE}" == "RC" ]; then
export CMAKE_BUILD_TYPE="-DGTA5VIEW_BUILDTYPE=Release Candidate"
export QMAKE_BUILD_TYPE="DEFINES+=GTA5SYNC_BUILDTYPE=\\\\\\\"Release Candidate\\\\\\\""
elif [ "${BUILD_TYPE}" == "Release Candidate" ]; then
export CMAKE_BUILD_TYPE="-DGTA5VIEW_BUILDTYPE=Release Candidate"
export QMAKE_BUILD_TYPE="DEFINES+=GTA5SYNC_BUILDTYPE=\\\\\\\"Release Candidate\\\\\\\""
elif [ "${BUILD_TYPE}" == "REL" ]; then
export CMAKE_BUILD_TYPE="-DGTA5VIEW_BUILDTYPE=Release"
export QMAKE_BUILD_TYPE="DEFINES+=GTA5SYNC_BUILDTYPE=\\\\\\\"Release\\\\\\\""
elif [ "${BUILD_TYPE}" == "Release" ]; then
export CMAKE_BUILD_TYPE="-DGTA5VIEW_BUILDTYPE=Release"
export QMAKE_BUILD_TYPE="DEFINES+=GTA5SYNC_BUILDTYPE=\\\\\\\"Release\\\\\\\""
fi
export PROJECT_DIR=$(pwd)
.ci/${BUILD_SCRIPT}

View File

@ -1,38 +0,0 @@
#!/usr/bin/env bash
# Creating folders
cd ${PROJECT_DIR} && \
echo "gta5view build version is ${APPLICATION_VERSION}" && \
mkdir -p build && \
mkdir -p assets && \
chmod -x res/gta5sync_*.qm res/*.desktop res/*gta5view*.png && \
cd build && \
mkdir -p qt5 && \
cd qt5 && \
echo "Grand Theft Auto V Snapmatic and Savegame viewer/editor" > ./description-pak && \
cd .. && \
# Set compiler
export CC=clang && \
export CXX=clang++ && \
# Prepare checkinstall step
mkdir -p /usr/share/gta5view && \
# Starting build
cd qt5 && \
cmake \
"-DCMAKE_INSTALL_PREFIX=/usr" \
"${CMAKE_BUILD_TYPE}" \
"-DFORCE_QT_VERSION=5" \
"-DGTA5VIEW_BUILDCODE=${PACKAGE_CODE}" \
"-DGTA5VIEW_APPVER=${APPLICATION_VERSION}" \
"-DGTA5VIEW_COMMIT=${APPLICATION_COMMIT}" \
"-DWITH_DONATE=ON" \
"-DWITH_TELEMETRY=ON" \
"-DDONATE_ADDRESSES=$(cat ${PROJECT_DIR}/.ci/donate.txt)" \
"-DTELEMETRY_WEBURL=https://dev.syping.de/gta5view-userstats/" \
"-DQCONF_BUILD=ON" \
../../ && \
make -j 4 && \
checkinstall -D --default --nodoc --install=no --pkgname=gta5view --pkgversion=${PACKAGE_VERSION} --pkgrelease=${PACKAGE_BUILD} --pkggroup=utility --maintainer="Syping \<dpkg@syping.de\>" --requires=libqt5core5a,libqt5gui5,libqt5network5,libqt5svg5,libqt5widgets5,qttranslations5-l10n --conflicts=gta5view-qt4,gta5view-qt5 --replaces=gta5view-qt4,gta5view-qt5 --pakdir=${PROJECT_DIR}/assets

View File

@ -1,8 +0,0 @@
#!/usr/bin/env bash
# Install packages
.ci/debian_install.sh && \
# Build gta5view
.ci/debian_build.sh && \
cd ${PROJECT_DIR}

View File

@ -1,15 +0,0 @@
#!/usr/bin/env bash
if [ "${DOCKER_USER}" != "" ]; then
DOCKER_IMAGE=${DOCKER_USER}/debian:${DEBIAN_VERSION}
else
DOCKER_IMAGE=debian:${DEBIAN_VERSION}
fi
PROJECT_DIR_DOCKER=/gta5view
cd ${PROJECT_DIR} && \
docker pull ${DOCKER_IMAGE} && \
docker run --rm \
-v "${PROJECT_DIR}:${PROJECT_DIR_DOCKER}" \
${DOCKER_IMAGE} \
/bin/bash -c "export PROJECT_DIR=${PROJECT_DIR_DOCKER} && export QT_SELECT=${QT_SELECT} && export APPLICATION_VERSION=${APPLICATION_VERSION} && export APPLICATION_COMMIT=${APPLICATION_COMMIT} && export BUILD_TYPE=${BUILD_TYPE} && export APT_INSTALL=${APT_INSTALL} && export QMAKE_FLAGS_QT4=${QMAKE_FLAGS_QT4} && export QMAKE_FLAGS_QT5=${QMAKE_FLAGS_QT5} && export CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} && export QMAKE_BUILD_TYPE=${QMAKE_BUILD_TYPE} && export PACKAGE_VERSION=${PACKAGE_VERSION} && export PACKAGE_BUILD=${PACKAGE_BUILD} && export PACKAGE_CODE=${PACKAGE_CODE} && export EXECUTABLE_VERSION=${EXECUTABLE_VERSION} && export EXECUTABLE_ARCH=${EXECUTABLE_ARCH} && cd ${PROJECT_DIR_DOCKER} && .ci/debian_install.sh && .ci/debian_build.sh"

View File

@ -1,13 +0,0 @@
#!/usr/bin/env bash
# Source OS Release
source /etc/os-release
# When Debian add backports
if [ "${ID}" == "debian" ]; then
echo "deb http://deb.debian.org/debian ${VERSION_CODENAME}-backports main" >> /etc/apt/sources.list
fi
# Install packages
apt-get update -qq && \
apt-get install -qq ${APT_INSTALL} checkinstall cmake dpkg-dev fakeroot g++ gcc qtbase5-dev qt5-qmake qttranslations5-l10n libqt5svg5-dev

File diff suppressed because it is too large Load Diff

View File

@ -1,364 +0,0 @@
######################################################################
!define APP_NAME "gta5view"
!define APP_EXT ".g5e"
!define COMP_NAME "Syping"
!define WEB_SITE "https://gta5view.syping.de/"
!define VERSION "1.10.1.1"
!define COPYRIGHT "Copyright © 2016-2022 Syping"
!define DESCRIPTION "Open Source Snapmatic and Savegame viewer/editor for GTA V"
!define INSTALLER_NAME "gta5view_setup.exe"
!define MAIN_APP_EXE "gta5view.exe"
!define INSTALL_TYPE "SetShellVarContext all"
!define REG_ROOT "HKLM"
!define REG_APP_PATH "Software\Microsoft\Windows\CurrentVersion\App Paths\${MAIN_APP_EXE}"
!define UNINSTALL_PATH "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_NAME}"
!define LICENSE_TXT "../LICENSE"
######################################################################
VIProductVersion "${VERSION}"
VIAddVersionKey "ProductName" "${APP_NAME}"
VIAddVersionKey "ProductVersion" "${VERSION}"
VIAddVersionKey "CompanyName" "${COMP_NAME}"
VIAddVersionKey "LegalCopyright" "${COPYRIGHT}"
VIAddVersionKey "FileDescription" "${DESCRIPTION}"
VIAddVersionKey "FileVersion" "${VERSION}"
######################################################################
!include "x64.nsh"
SetCompressor LZMA
Name "${APP_NAME}"
Caption "${APP_NAME}"
OutFile "${INSTALLER_NAME}"
#BrandingText "${APP_NAME}"
XPStyle on
Unicode true
InstallDirRegKey "${REG_ROOT}" "${REG_APP_PATH}" ""
InstallDir "$PROGRAMFILES64\Syping\gta5view"
######################################################################
!include "MUI2.nsh"
!define MUI_ABORTWARNING
!define MUI_UNABORTWARNING
!define MUI_LANGDLL_REGISTRY_ROOT "${REG_ROOT}"
!define MUI_LANGDLL_REGISTRY_KEY "${UNINSTALL_PATH}"
!define MUI_LANGDLL_REGISTRY_VALUENAME "Installer Language"
!insertmacro MUI_PAGE_WELCOME
!ifdef LICENSE_TXT
!insertmacro MUI_PAGE_LICENSE "${LICENSE_TXT}"
!endif
!insertmacro MUI_PAGE_DIRECTORY
!ifdef REG_START_MENU
!define MUI_STARTMENUPAGE_NODISABLE
!define MUI_STARTMENUPAGE_DEFAULTFOLDER "gta5view"
!define MUI_STARTMENUPAGE_REGISTRY_ROOT "${REG_ROOT}"
!define MUI_STARTMENUPAGE_REGISTRY_KEY "${UNINSTALL_PATH}"
!define MUI_STARTMENUPAGE_REGISTRY_VALUENAME "${REG_START_MENU}"
!insertmacro MUI_PAGE_STARTMENU Application $SM_Folder
!endif
!insertmacro MUI_PAGE_INSTFILES
!define MUI_FINISHPAGE_RUN "$INSTDIR\${MAIN_APP_EXE}"
!insertmacro MUI_PAGE_FINISH
!insertmacro MUI_UNPAGE_CONFIRM
!insertmacro MUI_UNPAGE_INSTFILES
!insertmacro MUI_UNPAGE_FINISH
!insertmacro MUI_LANGUAGE "English"
!insertmacro MUI_LANGUAGE "French"
!insertmacro MUI_LANGUAGE "German"
!insertmacro MUI_LANGUAGE "Korean"
!insertmacro MUI_LANGUAGE "Russian"
!insertmacro MUI_LANGUAGE "Ukrainian"
!insertmacro MUI_LANGUAGE "TradChinese"
!insertmacro MUI_RESERVEFILE_LANGDLL
######################################################################
Function .onInit
!insertmacro MUI_LANGDLL_DISPLAY
!ifdef WIN32
MessageBox MB_OK|MB_ICONSTOP "Windows 32-Bit is not supported anymore!"
Quit
!endif
SetRegView 64
FunctionEnd
######################################################################
Section -MainProgram
${INSTALL_TYPE}
SetOverwrite ifnewer
SetOutPath "$INSTDIR"
File "../build/gta5view.exe"
File "/opt/llvm-mingw/x86_64-w64-mingw32/bin/libc++.dll"
File "/opt/llvm-mingw/x86_64-w64-mingw32/bin/libunwind.dll"
File "/usr/local/lib/x86_64-w64-mingw32/openssl/bin/libcrypto-1_1-x64.dll"
File "/usr/local/lib/x86_64-w64-mingw32/openssl/bin/libssl-1_1-x64.dll"
File "/usr/local/lib/x86_64-w64-mingw32/qt5/bin/Qt5Core.dll"
File "/usr/local/lib/x86_64-w64-mingw32/qt5/bin/Qt5Gui.dll"
File "/usr/local/lib/x86_64-w64-mingw32/qt5/bin/Qt5Network.dll"
File "/usr/local/lib/x86_64-w64-mingw32/qt5/bin/Qt5Svg.dll"
File "/usr/local/lib/x86_64-w64-mingw32/qt5/bin/Qt5Widgets.dll"
SetOutPath "$INSTDIR\lang"
File "../build/gta5sync_en_US.qm"
File "../build/gta5sync_de.qm"
File "../build/gta5sync_fr.qm"
File "../build/gta5sync_ko.qm"
File "../build/gta5sync_ru.qm"
File "../build/gta5sync_uk.qm"
File "../build/gta5sync_zh_TW.qm"
File "../build/qtbase_en_GB.qm"
File "../res/qt5/qtbase_de.qm"
File "../res/qt5/qtbase_fr.qm"
File "../res/qt5/qtbase_ko.qm"
File "../res/qt5/qtbase_ru.qm"
File "../res/qt5/qtbase_uk.qm"
File "../res/qt5/qtbase_zh_TW.qm"
SetOutPath "$INSTDIR\resources"
File "../res/add.svgz"
File "../res/avatararea.png"
File "../res/avatarareaimport.png"
File "../res/back.svgz"
File "../res/flag-de.png"
File "../res/flag-fr.png"
File "../res/flag-gb.png"
File "../res/flag-kr.png"
File "../res/flag-ru.png"
File "../res/flag-tw.png"
File "../res/flag-ua.png"
File "../res/flag-us.png"
File "../res/gta5view-16.png"
File "../res/gta5view-24.png"
File "../res/gta5view-32.png"
File "../res/gta5view-40.png"
File "../res/gta5view-48.png"
File "../res/gta5view-64.png"
File "../res/gta5view-96.png"
File "../res/gta5view-128.png"
File "../res/gta5view-256.png"
File "../res/mapcayoperico.jpg"
File "../res/mappreview.jpg"
File "../res/next.svgz"
File "../res/pointmaker-8.png"
File "../res/pointmaker-16.png"
File "../res/pointmaker-24.png"
File "../res/pointmaker-32.png"
File "../res/savegame.svgz"
File "../res/watermark_1b.png"
File "../res/watermark_2b.png"
File "../res/watermark_2r.png"
SetOutPath "$INSTDIR\imageformats"
File "/usr/local/lib/x86_64-w64-mingw32/qt5/plugins/imageformats/qgif.dll"
File "/usr/local/lib/x86_64-w64-mingw32/qt5/plugins/imageformats/qicns.dll"
File "/usr/local/lib/x86_64-w64-mingw32/qt5/plugins/imageformats/qico.dll"
File "/usr/local/lib/x86_64-w64-mingw32/qt5/plugins/imageformats/qjpeg.dll"
File "/usr/local/lib/x86_64-w64-mingw32/qt5/plugins/imageformats/qsvg.dll"
File "/usr/local/lib/x86_64-w64-mingw32/qt5/plugins/imageformats/qtga.dll"
File "/usr/local/lib/x86_64-w64-mingw32/qt5/plugins/imageformats/qtiff.dll"
File "/usr/local/lib/x86_64-w64-mingw32/qt5/plugins/imageformats/qwbmp.dll"
File "/usr/local/lib/x86_64-w64-mingw32/qt5/plugins/imageformats/qwebp.dll"
SetOutPath "$INSTDIR\platforms"
File "/usr/local/lib/x86_64-w64-mingw32/qt5/plugins/platforms/qwindows.dll"
SetOutPath "$INSTDIR\styles"
File "/usr/local/lib/x86_64-w64-mingw32/qt5/plugins/styles/qcleanlooksstyle.dll"
File "/usr/local/lib/x86_64-w64-mingw32/qt5/plugins/styles/qplastiquestyle.dll"
File "/usr/local/lib/x86_64-w64-mingw32/qt5/plugins/styles/qwindowsvistastyle.dll"
SectionEnd
######################################################################
Section -Icons_Reg
SetOutPath "$INSTDIR"
WriteUninstaller "$INSTDIR\uninstall.exe"
!ifdef REG_START_MENU
!insertmacro MUI_STARTMENU_WRITE_BEGIN Application
CreateDirectory "$SMPROGRAMS\$SM_Folder"
CreateShortCut "$SMPROGRAMS\$SM_Folder\${APP_NAME}.lnk" "$INSTDIR\${MAIN_APP_EXE}"
CreateShortCut "$SMPROGRAMS\$SM_Folder\Uninstall ${APP_NAME}.lnk" "$INSTDIR\uninstall.exe"
!ifdef WEB_SITE
WriteIniStr "$INSTDIR\${APP_NAME} website.url" "InternetShortcut" "URL" "${WEB_SITE}"
CreateShortCut "$SMPROGRAMS\$SM_Folder\gta5view Website.lnk" "$INSTDIR\${APP_NAME} website.url"
!endif
!insertmacro MUI_STARTMENU_WRITE_END
!endif
!ifndef REG_START_MENU
CreateDirectory "$SMPROGRAMS\gta5view"
CreateShortCut "$SMPROGRAMS\gta5view\${APP_NAME}.lnk" "$INSTDIR\${MAIN_APP_EXE}"
CreateShortCut "$SMPROGRAMS\gta5view\Uninstall ${APP_NAME}.lnk" "$INSTDIR\uninstall.exe"
!ifdef WEB_SITE
WriteIniStr "$INSTDIR\${APP_NAME} website.url" "InternetShortcut" "URL" "${WEB_SITE}"
CreateShortCut "$SMPROGRAMS\gta5view\gta5view Website.lnk" "$INSTDIR\${APP_NAME} website.url"
!endif
!endif
WriteRegStr ${REG_ROOT} "${REG_APP_PATH}" "" "$INSTDIR\${MAIN_APP_EXE}"
WriteRegStr ${REG_ROOT} "${UNINSTALL_PATH}" "DisplayName" "${APP_NAME}"
WriteRegStr ${REG_ROOT} "${UNINSTALL_PATH}" "UninstallString" "$INSTDIR\uninstall.exe"
WriteRegStr ${REG_ROOT} "${UNINSTALL_PATH}" "DisplayIcon" "$INSTDIR\${MAIN_APP_EXE}"
WriteRegStr ${REG_ROOT} "${UNINSTALL_PATH}" "DisplayVersion" "${VERSION}"
WriteRegStr ${REG_ROOT} "${UNINSTALL_PATH}" "Publisher" "${COMP_NAME}"
!ifdef WEB_SITE
WriteRegStr ${REG_ROOT} "${UNINSTALL_PATH}" "URLInfoAbout" "${WEB_SITE}"
!endif
SectionEnd
######################################################################
Section -ShellAssoc
WriteRegStr ${REG_ROOT} "Software\Classes\${APP_NAME}\DefaultIcon" "" "$INSTDIR\${MAIN_APP_EXE},0"
WriteRegStr ${REG_ROOT} "Software\Classes\${APP_NAME}\shell\open\command" "" '"$INSTDIR\${MAIN_APP_EXE}" "%1"'
WriteRegStr ${REG_ROOT} "Software\Classes\${APP_EXT}" "" "${APP_NAME}"
WriteRegStr ${REG_ROOT} "Software\Classes\${APP_EXT}" "Content Type" "application/x-gta5view-export"
System::Call 'SHELL32::SHChangeNotify(i0x8000000,i0,p0,p0)'
SectionEnd
######################################################################
Section -un.ShellAssoc
ClearErrors
ReadRegStr $0 ${REG_ROOT} "Software\Classes\${APP_EXT}" ""
DeleteRegKey ${REG_ROOT} "Software\Classes\${APP_NAME}"
${IfNot} ${Errors}
${AndIf} $0 == "${APP_NAME}"
DeleteRegValue ${REG_ROOT} "Software\Classes\${APP_EXT}" ""
DeleteRegKey /IfEmpty ${REG_ROOT} "Software\Classes\${APP_EXT}"
${EndIf}
System::Call 'SHELL32::SHChangeNotify(i0x8000000,i0,p0,p0)'
SectionEnd
######################################################################
Section Uninstall
${INSTALL_TYPE}
Delete "$INSTDIR\gta5view.exe"
Delete "$INSTDIR\libc++.dll"
Delete "$INSTDIR\libunwind.dll"
Delete "$INSTDIR\libcrypto-1_1-x64.dll"
Delete "$INSTDIR\libssl-1_1-x64.dll"
Delete "$INSTDIR\Qt5Core.dll"
Delete "$INSTDIR\Qt5Gui.dll"
Delete "$INSTDIR\Qt5Network.dll"
Delete "$INSTDIR\Qt5Svg.dll"
Delete "$INSTDIR\Qt5Widgets.dll"
Delete "$INSTDIR\lang\gta5sync_en_US.qm"
Delete "$INSTDIR\lang\gta5sync_de.qm"
Delete "$INSTDIR\lang\gta5sync_fr.qm"
Delete "$INSTDIR\lang\gta5sync_ko.qm"
Delete "$INSTDIR\lang\gta5sync_ru.qm"
Delete "$INSTDIR\lang\gta5sync_uk.qm"
Delete "$INSTDIR\lang\gta5sync_zh_TW.qm"
Delete "$INSTDIR\lang\qtbase_en_GB.qm"
Delete "$INSTDIR\lang\qtbase_de.qm"
Delete "$INSTDIR\lang\qtbase_fr.qm"
Delete "$INSTDIR\lang\qtbase_ko.qm"
Delete "$INSTDIR\lang\qtbase_ru.qm"
Delete "$INSTDIR\lang\qtbase_uk.qm"
Delete "$INSTDIR\lang\qtbase_zh_TW.qm"
Delete "$INSTDIR\resources\add.svgz"
Delete "$INSTDIR\resources\avatararea.png"
Delete "$INSTDIR\resources\avatarareaimport.png"
Delete "$INSTDIR\resources\back.svgz"
Delete "$INSTDIR\resources\flag-de.png"
Delete "$INSTDIR\resources\flag-fr.png"
Delete "$INSTDIR\resources\flag-gb.png"
Delete "$INSTDIR\resources\flag-kr.png"
Delete "$INSTDIR\resources\flag-ru.png"
Delete "$INSTDIR\resources\flag-tw.png"
Delete "$INSTDIR\resources\flag-ua.png"
Delete "$INSTDIR\resources\flag-us.png"
Delete "$INSTDIR\resources\gta5view-16.png"
Delete "$INSTDIR\resources\gta5view-24.png"
Delete "$INSTDIR\resources\gta5view-32.png"
Delete "$INSTDIR\resources\gta5view-40.png"
Delete "$INSTDIR\resources\gta5view-48.png"
Delete "$INSTDIR\resources\gta5view-64.png"
Delete "$INSTDIR\resources\gta5view-96.png"
Delete "$INSTDIR\resources\gta5view-128.png"
Delete "$INSTDIR\resources\gta5view-256.png"
Delete "$INSTDIR\resources\mapcayoperico.jpg"
Delete "$INSTDIR\resources\mappreview.jpg"
Delete "$INSTDIR\resources\next.svgz"
Delete "$INSTDIR\resources\pointmaker-8.png"
Delete "$INSTDIR\resources\pointmaker-16.png"
Delete "$INSTDIR\resources\pointmaker-24.png"
Delete "$INSTDIR\resources\pointmaker-32.png"
Delete "$INSTDIR\resources\savegame.svgz"
Delete "$INSTDIR\resources\watermark_1b.png"
Delete "$INSTDIR\resources\watermark_2b.png"
Delete "$INSTDIR\resources\watermark_2r.png"
Delete "$INSTDIR\imageformats\qgif.dll"
Delete "$INSTDIR\imageformats\qicns.dll"
Delete "$INSTDIR\imageformats\qico.dll"
Delete "$INSTDIR\imageformats\qjpeg.dll"
Delete "$INSTDIR\imageformats\qsvg.dll"
Delete "$INSTDIR\imageformats\qtga.dll"
Delete "$INSTDIR\imageformats\qtiff.dll"
Delete "$INSTDIR\imageformats\qwbmp.dll"
Delete "$INSTDIR\imageformats\qwebp.dll"
Delete "$INSTDIR\platforms\qwindows.dll"
Delete "$INSTDIR\styles\qcleanlooksstyle.dll"
Delete "$INSTDIR\styles\qplastiquestyle.dll"
Delete "$INSTDIR\styles\qwindowsvistastyle.dll"
RmDir "$INSTDIR\lang"
RmDir "$INSTDIR\imageformats"
RmDir "$INSTDIR\platforms"
RmDir "$INSTDIR\styles"
Delete "$INSTDIR\uninstall.exe"
!ifdef WEB_SITE
Delete "$INSTDIR\${APP_NAME} website.url"
!endif
RmDir "$INSTDIR"
!ifdef REG_START_MENU
!insertmacro MUI_STARTMENU_GETFOLDER "Application" $SM_Folder
Delete "$SMPROGRAMS\$SM_Folder\${APP_NAME}.lnk"
Delete "$SMPROGRAMS\$SM_Folder\Uninstall ${APP_NAME}.lnk"
!ifdef WEB_SITE
Delete "$SMPROGRAMS\$SM_Folder\gta5view Website.lnk"
!endif
RmDir "$SMPROGRAMS\$SM_Folder"
!endif
!ifndef REG_START_MENU
Delete "$SMPROGRAMS\gta5view\${APP_NAME}.lnk"
Delete "$SMPROGRAMS\gta5view\Uninstall ${APP_NAME}.lnk"
!ifdef WEB_SITE
Delete "$SMPROGRAMS\gta5view\gta5view Website.lnk"
!endif
RmDir "$SMPROGRAMS\gta5view"
!endif
DeleteRegKey ${REG_ROOT} "${REG_APP_PATH}"
DeleteRegKey ${REG_ROOT} "${UNINSTALL_PATH}"
SectionEnd
######################################################################
Function un.onInit
!insertmacro MUI_UNGETLANGUAGE
SetRegView 64
FunctionEnd
######################################################################

View File

@ -1,24 +0,0 @@
#!/usr/bin/env bash
# Creating folders
cd ${PROJECT_DIR} && \
echo "gta5view build version is ${APPLICATION_VERSION}" && \
echo "gta5view image name is gta5view-osx_${APPLICATION_VERSION}.dmg" && \
mkdir -p build && \
mkdir -p assets && \
cd build && \
/usr/local/bin/cmake \
"-DCMAKE_PREFIX_PATH=/usr/local/opt/qt" \
"${CMAKE_BUILD_TYPE}" \
"-DGTA5VIEW_BUILDCODE=${PACKAGE_CODE}" \
"-DGTA5VIEW_APPVER=${APPLICATION_VERSION}" \
"-DGTA5VIEW_COMMIT=${APPLICATION_COMMIT}" \
"-DWITH_DONATE=ON" \
"-DWITH_TELEMETRY=ON" \
"-DDONATE_ADDRESSES=$(cat ${PROJECT_DIR}/.ci/donate.txt)" \
"-DTELEMETRY_WEBURL=https://dev.syping.de/gta5view-userstats/" \
../ && \
make -j 4 && \
/usr/local/opt/qt/bin/macdeployqt gta5view.app -dmg && \
cp -Rf gta5view.dmg ../assets/gta5view-osx_${APPLICATION_VERSION}.dmg

View File

@ -1,8 +0,0 @@
#!/usr/bin/env bash
# Install packages
.ci/osx_install.sh && \
# Build gta5view
.ci/osx_build.sh && \
cd ${PROJECT_DIR}

View File

@ -1,4 +0,0 @@
#!/usr/bin/env bash
# Install packages
brew upgrade cmake qt

View File

@ -1,28 +0,0 @@
#!/usr/bin/env bash
# Prepare environment variable
export GTA5VIEW_EXECUTABLE=gta5view-${EXECUTABLE_VERSION}${EXECUTABLE_ARCH}.exe && \
# Creating folders
cd ${PROJECT_DIR} && \
echo "gta5view build version is ${APPLICATION_VERSION}" && \
echo "gta5view executable is ${GTA5VIEW_EXECUTABLE}" && \
mkdir -p build && \
mkdir -p assets && \
# Starting build
cd build && \
mingw64-qt-cmake \
"${CMAKE_BUILD_TYPE}" \
"-DGTA5VIEW_BUILDCODE=${PACKAGE_CODE}" \
"-DGTA5VIEW_APPVER=${APPLICATION_VERSION}" \
"-DGTA5VIEW_COMMIT=${APPLICATION_COMMIT}" \
"-DWITH_DONATE=ON" \
"-DWITH_TELEMETRY=ON" \
"-DDONATE_ADDRESSES=$(cat ${PROJECT_DIR}/.ci/donate.txt)" \
"-DTELEMETRY_WEBURL=https://dev.syping.de/gta5view-userstats/" \
.. && \
make -j 4 && \
x86_64-w64-mingw32-strip -s gta5view.exe && \
cp -Rf *.exe ${PROJECT_DIR}/assets/${GTA5VIEW_EXECUTABLE} && \
cd ${PROJECT_DIR}/assets

View File

@ -1,25 +0,0 @@
#!/usr/bin/env bash
DOCKER_IMAGE=sypingauto/gta5view-build:1.10-static
PROJECT_DIR_DOCKER=/gta5view
cd ${PROJECT_DIR} && \
docker pull ${DOCKER_IMAGE} && \
docker run --rm \
-v "${PROJECT_DIR}:${PROJECT_DIR_DOCKER}" \
${DOCKER_IMAGE} \
/bin/bash -c "export PROJECT_DIR=${PROJECT_DIR_DOCKER} && export QT_SELECT=${QT_SELECT} && export APPLICATION_VERSION=${APPLICATION_VERSION} && export APPLICATION_COMMIT=${APPLICATION_COMMIT} && export BUILD_TYPE=${BUILD_TYPE} && export QMAKE_FLAGS_QT4=${QMAKE_FLAGS_QT4} && export QMAKE_FLAGS_QT5=${QMAKE_FLAGS_QT5} && export CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} && export QMAKE_BUILD_TYPE=${QMAKE_BUILD_TYPE} && export PACKAGE_VERSION=${PACKAGE_VERSION} && export PACKAGE_BUILD=${PACKAGE_BUILD} && export PACKAGE_CODE=${PACKAGE_CODE} && export EXECUTABLE_VERSION=${EXECUTABLE_VERSION} && export EXECUTABLE_ARCH=${EXECUTABLE_ARCH} && cd ${PROJECT_DIR_DOCKER} && .ci/windows_build.sh" && \
# Prepare environment variable
export GTA5VIEW_EXECUTABLE=gta5view-${EXECUTABLE_VERSION}${EXECUTABLE_ARCH}.exe && \
# Upload Assets to Dropbox
if [ "${PACKAGE_CODE}" == "gta5-mods" ]; then
${PROJECT_DIR}/.ci/dropbox_uploader.sh mkdir gta5-mods/${PACKAGE_VERSION}
${PROJECT_DIR}/.ci/dropbox_uploader.sh upload ${PROJECT_DIR}/assets/${GTA5VIEW_EXECUTABLE} gta5-mods/${PACKAGE_VERSION}/${GTA5VIEW_EXECUTABLE} && \
rm -rf ${GTA5VIEW_EXECUTABLE}
elif [ "${PACKAGE_CODE}" == "gtainside" ]; then
${PROJECT_DIR}/.ci/dropbox_uploader.sh mkdir gtainside/${PACKAGE_VERSION}
${PROJECT_DIR}/.ci/dropbox_uploader.sh upload ${PROJECT_DIR}/assets/${GTA5VIEW_EXECUTABLE} gtainside/${PACKAGE_VERSION}/${GTA5VIEW_EXECUTABLE} && \
rm -rf ${GTA5VIEW_EXECUTABLE}
fi

View File

@ -1,29 +0,0 @@
#!/usr/bin/env bash
# Creating folders
cd ${PROJECT_DIR} && \
echo "gta5view build version is ${APPLICATION_VERSION}" && \
mkdir -p build && \
mkdir -p assets && \
# Starting build
cd build && \
mingw64-qt-cmake \
"${CMAKE_BUILD_TYPE}" \
"-DGTA5VIEW_BUILDCODE=${PACKAGE_CODE}" \
"-DGTA5VIEW_APPVER=${APPLICATION_VERSION}" \
"-DGTA5VIEW_COMMIT=${APPLICATION_COMMIT}" \
"-DWITH_DONATE=ON" \
"-DWITH_TELEMETRY=ON" \
"-DDONATE_ADDRESSES=$(cat ${PROJECT_DIR}/.ci/donate.txt)" \
"-DTELEMETRY_WEBURL=https://dev.syping.de/gta5view-userstats/" \
"-DQCONF_BUILD=ON" \
"-DGTA5VIEW_INLANG=RUNDIR:SEPARATOR:lang" \
"-DGTA5VIEW_LANG=RUNDIR:SEPARATOR:lang" \
"-DGTA5VIEW_PLUG=RUNDIR:SEPARATOR:plugins" \
.. && \
make -j 4 && \
x86_64-w64-mingw32-strip -s gta5view.exe && \
cd ${PROJECT_DIR}/assets && \
makensis "-XTarget amd64-unicode" -NOCD ${PROJECT_DIR}/.ci/gta5view.nsi && \
mv -f gta5view_setup.exe gta5view-${EXECUTABLE_VERSION}_setup.exe

View File

@ -1,11 +0,0 @@
#!/usr/bin/env bash
DOCKER_IMAGE=sypingauto/gta5view-build:1.10-shared
PROJECT_DIR_DOCKER=/gta5view
cd ${PROJECT_DIR} && \
docker pull ${DOCKER_IMAGE} && \
docker run --rm \
-v "${PROJECT_DIR}:${PROJECT_DIR_DOCKER}" \
${DOCKER_IMAGE} \
/bin/bash -c "export PROJECT_DIR=${PROJECT_DIR_DOCKER} && export QT_SELECT=${QT_SELECT} && export APPLICATION_VERSION=${APPLICATION_VERSION} && export APPLICATION_COMMIT=${APPLICATION_COMMIT} && export BUILD_TYPE=${BUILD_TYPE} && export QMAKE_FLAGS_QT4=${QMAKE_FLAGS_QT4} && export QMAKE_FLAGS_QT5=${QMAKE_FLAGS_QT5} && export CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} && export QMAKE_BUILD_TYPE=${QMAKE_BUILD_TYPE} && export PACKAGE_VERSION=${PACKAGE_VERSION} && export PACKAGE_BUILD=${PACKAGE_BUILD} && export PACKAGE_CODE=${PACKAGE_CODE} && export EXECUTABLE_VERSION=${EXECUTABLE_VERSION} && export EXECUTABLE_ARCH=${EXECUTABLE_ARCH} && cd ${PROJECT_DIR_DOCKER} && .ci/wininstall_build.sh"

View File

@ -1,36 +0,0 @@
kind: pipeline
type: docker
environment:
BUILD_TYPE: "REL"
steps:
- name: Windows Installer
image: sypingauto/gta5view-build:1.10-shared
environment:
BUILD_SCRIPT: "wininstall_build.sh"
QT_SELECT: "qt5-x86_64-w64-mingw32"
TCA_PASS:
from_secret: tca_pass
commands:
- .drone/drone.sh
volumes:
- name: gta5view
path: /srv/gta5view
- name: Windows Portable
image: sypingauto/gta5view-build:1.10-static
environment:
BUILD_SCRIPT: "windows_build.sh"
QT_SELECT: "qt5-x86_64-w64-mingw32"
TCA_PASS:
from_secret: tca_pass
commands:
- .drone/drone.sh
volumes:
- name: gta5view
path: /srv/gta5view
volumes:
- name: gta5view
host:
path: /srv/gta5view

View File

@ -1,33 +0,0 @@
#!/bin/bash
# Cleanup previous Drone build
if [ -d "assets" ]; then
rm -rf assets
fi
if [ -d "build" ]; then
rm -rf build
fi
# Decrypt Telemetry Authenticator
rm -rf tmext/TelemetryClassAuthenticator.cpp && \
openssl aes-256-cbc -k ${TCA_PASS} -in .drone/TelemetryClassAuthenticator.cpp.enc -out tmext/TelemetryClassAuthenticator.cpp -d -pbkdf2
# Check if build is not tagged
if [ "${DRONE_TAG}" == "" ]; then
export EXECUTABLE_TAG=-$(git rev-parse --short HEAD)
else
export EXECUTABLE_TAG=
fi
# Check if package code is not set
if [ "${PACKAGE_CODE}" == "" ]; then
export PACKAGE_CODE=Drone
fi
# Init Application Commit Hash
export APPLICATION_COMMIT=$(git rev-parse --short HEAD)
# Start CI script and copying assets into gta5view directory
.ci/ci.sh && \
mkdir -p /srv/gta5view/${APPLICATION_COMMIT} && \
cp -Rf assets/* /srv/gta5view/${APPLICATION_COMMIT}/

View File

@ -1,22 +0,0 @@
app-id: de.syping.gta5view
runtime: org.kde.Platform
runtime-version: '5.15-21.08'
sdk: org.kde.Sdk
command: gta5view
finish-args:
- --share=network
- --share=ipc
- --socket=fallback-x11
- --socket=wayland
- --device=dri
modules:
- name: gta5view
buildsystem: cmake-ninja
config-opts:
- -DFLATPAK_BUILD=ON
- -DQCONF_BUILD=ON
- -DGTA5VIEW_BUILDCODE=Flatpak
- -DGTA5VIEW_BUILDTYPE=Release
sources:
- type: dir
path: ../

3
.gitignore vendored
View File

@ -27,7 +27,8 @@
*.out
*.app
# Qt project user file
# Qt project user files
CMakeLists.txt.user
*.pro.user
# Gettext translation files

View File

@ -1,31 +0,0 @@
stages:
- build
variables:
BUILD_TYPE: "REL"
Windows Installer:
stage: build
image: sypingauto/gta5view-build:1.10-shared
variables:
BUILD_SCRIPT: "wininstall_build.sh"
QT_SELECT: "qt5-x86_64-w64-mingw32"
script:
- .gitlab/gitlab.sh
artifacts:
name: "gta5view-$CI_COMMIT_REF_NAME-${CI_COMMIT_SHA:0:8}_setup"
paths:
- "gta5view-*.exe"
Windows Portable:
stage: build
image: sypingauto/gta5view-build:1.10-static
variables:
BUILD_SCRIPT: "windows_build.sh"
QT_SELECT: "qt5-x86_64-w64-mingw32"
script:
- .gitlab/gitlab.sh
artifacts:
name: "gta5view-$CI_COMMIT_REF_NAME-${CI_COMMIT_SHA:0:8}_portable"
paths:
- "gta5view-*.exe"

View File

@ -1,24 +0,0 @@
#!/bin/bash
# Decrypt Telemetry Authenticator
rm -rf tmext/TelemetryClassAuthenticator.cpp && \
openssl aes-256-cbc -k ${tca_pass} -in .gitlab/TelemetryClassAuthenticator.cpp.enc -out tmext/TelemetryClassAuthenticator.cpp -d
# Check if build is not tagged
if [ "${CI_COMMIT_TAG}" == "" ]; then
export EXECUTABLE_TAG=-$(git rev-parse --short HEAD)
else
export EXECUTABLE_TAG=
fi
# Check if package code is not set
if [ "${PACKAGE_CODE}" == "" ]; then
export PACKAGE_CODE=GitLab
fi
# Init Application Commit Hash
export APPLICATION_COMMIT=$(git rev-parse --short HEAD)
# Start CI script and copying assets into base directory
.ci/ci.sh && \
cp -Rf assets/* ./

6
.gitmodules vendored Normal file
View File

@ -0,0 +1,6 @@
[submodule "src/libragephoto"]
path = src/libragephoto
url = https://github.com/Syping/libragephoto.git
[submodule "src/json"]
path = src/json
url = https://github.com/boostorg/json.git

View File

@ -1,50 +0,0 @@
dist: bionic
sudo: required
language: cpp
services:
- docker
env:
global:
- BUILD_TYPE=REL
matrix:
include:
- env:
- BUILD_SCRIPT=debian_docker.sh
- RELEASE_LABEL="Debian 64-Bit Package"
- DEBIAN_VERSION=buster
- DOCKER_USER=amd64
- APT_INSTALL=clang
- env:
- BUILD_SCRIPT=windows_docker.sh
- QT_SELECT=qt5-x86_64-w64-mingw32
- RELEASE_LABEL="Windows 64-Bit Portable"
- env:
- BUILD_SCRIPT=wininstall_docker.sh
- QT_SELECT=qt5-x86_64-w64-mingw32
- RELEASE_LABEL="Windows 64-Bit Installer"
- os: osx
osx_image: xcode12.2
env:
- BUILD_SCRIPT=osx_ci.sh
- RELEASE_LABEL="Mac OS X 64-Bit Disk Image"
before_install:
- ".travis/source.sh"
script:
- ".travis/travis.sh"
deploy:
provider: releases
api_key:
secure: o7VneEz1aHfdVwZvOZLfopf6uJWNrFsZaBvunTmXFzpmNFhlNS1qwqgMUkIA2yBRbZ3wIzVs4vfwIHv7W9yE/PqK+AYL+R8+AwKGrwlgT4HqJNuk6VM/LNJ6GwT/qkQuaoOVw29bUjmzzgIRdHmw53SlJv6Hh1VE8HphlTT//aex6nCfcFhUZ0BETdZDWz5FSHwL3NalUoqfKfQrJeky5RXzCyCANQC2tKt0bV46GaWIgWrDo2KCTNqPtRWWf5GDmnkXE5IYRMQ3mXvO9iYh0v5Y2jo4PiXGUiFUU6Z3aAWFAiPdGclrBO697cf3lCTzDMhuCETR153qFYsLShUlFf61ITAmCeHAWETjZDri0lmPONo3GoNB6alGfYEA51qw14kXakrTpICtTJj7gw/gtUYOabW6hrzmieNzMBIy62RikDPjyakFnuwW2qNHRlD65e0jYv+6nCpb6E+OV16Ysh1zhV2vTfpfzVmSuyu2J+ELqXD3OZCXRSPpDIih9UQ8335p8FBji6jHORcgym/TRgdgRmENibh8tLzWp+UjpWHuWfcpvZgOskjfwU0iDMCayMJ7tDpOhXHcAhDRnd6XRIiOJ5YZCzflj2nEwmt3YUd7DwXS/AU+WHOmcNQBjXBxF/FJa35XXcy3HKJM5TTKqtph3medo30us5yXHeG6NNg=
label: ${RELEASE_LABEL}
file_glob: true
file: assets/*
skip_cleanup: true
on:
tags: true

View File

@ -1 +0,0 @@
Poァ鏖<EFBFBD>劾ラ<作1x」%几<>ャネw|RtZv<>kホ銓顴Z肄2チ廁湮ォ`<1A>,4vヨマ・@€<>ヲeハ・~U$+<2B><>€<EFBFBD><1A><牾&蓬熙

View File

@ -1,5 +0,0 @@
#!/bin/bash
rm -rf tmext/TelemetryClassAuthenticator.cpp && \
openssl aes-256-cbc -K $encrypted_db000a5d87d6_key -iv $encrypted_db000a5d87d6_iv -in .travis/TelemetryClassAuthenticator.cpp.enc -out tmext/TelemetryClassAuthenticator.cpp -d && \
openssl aes-256-cbc -K $encrypted_d57e7d2f8877_key -iv $encrypted_d57e7d2f8877_iv -in .travis/dropbox_uploader.enc -out ~/.dropbox_uploader -d

View File

@ -1,27 +0,0 @@
#!/bin/bash
# Install lua
if [ "${TRAVIS_OS_NAME}" == "osx" ]; then
brew install lua
else
sudo apt-get update -qq && \
sudo apt-get install -qq lua5.2
fi
# Check if build is not tagged
if [ "${TRAVIS_TAG}" == "" ]; then
export EXECUTABLE_TAG=-$(git rev-parse --short HEAD)
else
export EXECUTABLE_TAG=
fi
# Check if package code is not set
if [ "${PACKAGE_CODE}" == "" ]; then
export PACKAGE_CODE=GitHub
fi
# Init Application Commit Hash
export APPLICATION_COMMIT=$(git rev-parse --short HEAD)
# Start CI script
.ci/ci.sh

View File

@ -1,8 +0,0 @@
#!/bin/bash
# Install packages
sudo .ci/debian_install.sh && \
# Build gta5view
sudo .ci/debian_build.sh && \
cd ${PROJECT_DIR}

View File

@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.7)
project(gta5view LANGUAGES C CXX)
project(gta5view VERSION 1.11.0 LANGUAGES C CXX)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
@ -8,7 +8,7 @@ set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD 17 CACHE STRING "gta5view C++ standard")
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(FORCE_QT_VERSION "" CACHE STRING "Force Qt Version")
@ -20,6 +20,9 @@ endif()
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Network Svg Widgets REQUIRED)
find_package(Qt${QT_VERSION_MAJOR} COMPONENTS LinguistTools QUIET)
set(RAGEPHOTO_STATIC ON CACHE BOOL "Build libragephoto as static library")
add_subdirectory(src/libragephoto)
if(WIN32)
list(APPEND GTA5VIEW_LIBS
dwmapi
@ -38,7 +41,7 @@ if(APPLE)
res/gta5view.icns
)
set(MACOSX_BUNDLE_BUNDLE_NAME gta5view)
set(MACOSX_BUNDLE_BUNDLE_VERSION 1.10.1)
set(MACOSX_BUNDLE_BUNDLE_VERSION ${gta5view_VERSION})
set(MACOSX_BUNDLE_ICON_FILE gta5view.icns)
set(MACOSX_BUNDLE_GUI_IDENTIFIER de.syping.gta5view)
set_source_files_properties(res/gta5view.icns PROPERTIES MACOSX_PACKAGE_LOCATION "Resources")
@ -50,111 +53,107 @@ list(APPEND GTA5VIEW_DEFINES
)
set(GTA5VIEW_SOURCES
main.cpp
AboutDialog.cpp
AppEnv.cpp
CrewDatabase.cpp
DatabaseThread.cpp
ExportDialog.cpp
ExportThread.cpp
GlobalString.cpp
IconLoader.cpp
ImportDialog.cpp
JsonEditorDialog.cpp
MapLocationDialog.cpp
OptionsDialog.cpp
PictureDialog.cpp
PictureExport.cpp
PictureWidget.cpp
PlayerListDialog.cpp
ProfileDatabase.cpp
ProfileInterface.cpp
ProfileLoader.cpp
ProfileWidget.cpp
RagePhoto.cpp
SavegameCopy.cpp
SavegameData.cpp
SavegameDialog.cpp
SavegameWidget.cpp
SidebarGenerator.cpp
SnapmaticEditor.cpp
SnapmaticPicture.cpp
SnapmaticWidget.cpp
StandardPaths.cpp
StringParser.cpp
TranslationClass.cpp
UserInterface.cpp
anpro/imagecropper.cpp
pcg/pcg_basic.c
uimod/JSHighlighter.cpp
uimod/UiModLabel.cpp
uimod/UiModWidget.cpp
src/main.cpp
src/AboutDialog.cpp
src/AppEnv.cpp
src/CrewDatabase.cpp
src/DatabaseThread.cpp
src/ExportDialog.cpp
src/ExportThread.cpp
src/GlobalString.cpp
src/IconLoader.cpp
src/ImportDialog.cpp
src/JsonEditorDialog.cpp
src/MapLocationDialog.cpp
src/OptionsDialog.cpp
src/PictureDialog.cpp
src/PictureExport.cpp
src/PictureWidget.cpp
src/PlayerListDialog.cpp
src/ProfileDatabase.cpp
src/ProfileInterface.cpp
src/ProfileLoader.cpp
src/ProfileWidget.cpp
src/SavegameCopy.cpp
src/SavegameData.cpp
src/SavegameDialog.cpp
src/SavegameWidget.cpp
src/SnapmaticEditor.cpp
src/SnapmaticJson.cpp
src/SnapmaticPicture.cpp
src/SnapmaticWidget.cpp
src/StandardPaths.cpp
src/StringParser.cpp
src/TranslationClass.cpp
src/UserInterface.cpp
src/pcg/pcg_basic.c
src/uimod/JSHighlighter.cpp
src/uimod/UiModLabel.cpp
src/uimod/UiModWidget.cpp
)
set(GTA5VIEW_HEADERS
config.h
wrapper.h
AboutDialog.h
AppEnv.h
CrewDatabase.h
DatabaseThread.h
ExportDialog.h
ExportThread.h
GlobalString.h
IconLoader.h
ImportDialog.h
JsonEditorDialog.h
MapLocationDialog.h
OptionsDialog.h
PictureDialog.h
PictureExport.h
PictureWidget.h
PlayerListDialog.h
ProfileDatabase.h
ProfileInterface.h
ProfileLoader.h
ProfileWidget.h
RagePhoto.h
SavegameCopy.h
SavegameData.h
SavegameDialog.h
SavegameWidget.h
SidebarGenerator.h
SnapmaticEditor.h
SnapmaticPicture.h
SnapmaticWidget.h
StandardPaths.h
StringParser.h
TranslationClass.h
UserInterface.h
anpro/imagecropper.h
pcg/pcg_basic.h
uimod/JSHighlighter.h
uimod/UiModLabel.h
uimod/UiModWidget.h
src/config.h
src/AboutDialog.h
src/AppEnv.h
src/CrewDatabase.h
src/DatabaseThread.h
src/ExportDialog.h
src/ExportThread.h
src/GlobalString.h
src/IconLoader.h
src/ImportDialog.h
src/JsonEditorDialog.h
src/MapLocationDialog.h
src/OptionsDialog.h
src/PictureDialog.h
src/PictureExport.h
src/PictureWidget.h
src/PlayerListDialog.h
src/ProfileDatabase.h
src/ProfileInterface.h
src/ProfileLoader.h
src/ProfileWidget.h
src/SavegameCopy.h
src/SavegameData.h
src/SavegameDialog.h
src/SavegameWidget.h
src/SnapmaticEditor.h
src/SnapmaticJson.h
src/SnapmaticPicture.h
src/SnapmaticWidget.h
src/StandardPaths.h
src/StringParser.h
src/TranslationClass.h
src/UserInterface.h
src/pcg/pcg_basic.h
src/uimod/JSHighlighter.h
src/uimod/UiModLabel.h
src/uimod/UiModWidget.h
)
set(GTA5VIEW_INCLUDEDIR
anpro
pcg
uimod
src
src/anpro
src/pcg
src/uimod
)
set(GTA5VIEW_FORMS
AboutDialog.ui
ExportDialog.ui
ImportDialog.ui
JsonEditorDialog.ui
MapLocationDialog.ui
OptionsDialog.ui
PictureDialog.ui
PlayerListDialog.ui
ProfileInterface.ui
SavegameDialog.ui
SavegameWidget.ui
SnapmaticEditor.ui
SnapmaticWidget.ui
UserInterface.ui
src/AboutDialog.ui
src/ExportDialog.ui
src/ImportDialog.ui
src/JsonEditorDialog.ui
src/MapLocationDialog.ui
src/OptionsDialog.ui
src/PictureDialog.ui
src/PlayerListDialog.ui
src/ProfileInterface.ui
src/SavegameDialog.ui
src/SavegameWidget.ui
src/SnapmaticEditor.ui
src/SnapmaticWidget.ui
src/UserInterface.ui
)
set(GTA5VIEW_TRANSLATIONS
@ -169,7 +168,6 @@ set(GTA5VIEW_TRANSLATIONS
list(APPEND GTA5VIEW_RESOURCES
res/global.qrc
res/template.qrc
)
set_property(SOURCE res/global.qrc PROPERTY AUTORCC_OPTIONS "-threshold;0;-compress;9")
@ -218,14 +216,45 @@ if(FLATPAK_BUILD)
)
endif()
option(RAGEPHOTO_ABI_WRAPPER "Use libragephoto's ABI wrapper" OFF)
if(RAGEPHOTO_ABI_WRAPPER)
set(RAGEPHOTO_C_API ON CACHE BOOL "Build libragephoto with C API support" FORCE)
list(APPEND GTA5VIEW_DEFINES
-DRAGEPHOTO_USE_ABI_WRAPPER
)
endif()
option(WITH_BOOST "Use linked Boost library" OFF)
if(WITH_BOOST)
find_package(Boost REQUIRED
COMPONENTS json
)
list(APPEND GTA5VIEW_LIBS
Boost::json
)
list(APPEND GTA5VIEW_DEFINES
-DGTA5SYNC_BOOST
)
list(APPEND GTA5VIEW_INCLUDEDIR
${Boost_INCLUDE_DIRS}
)
else()
list(APPEND GTA5VIEW_DEFINES
-DBOOST_JSON_STANDALONE
)
list(APPEND GTA5VIEW_INCLUDEDIR
src/json/include
)
endif()
option(WITH_DONATE "Donate menu option and donation dialog" OFF)
if(WITH_DONATE)
set(DONATE_ADDRESSES "" CACHE STRING "Donation addresses")
list(APPEND GTA5VIEW_HEADERS
anpro/QrCode.h
src/anpro/QrCode.h
)
list(APPEND GTA5VIEW_SOURCES
anpro/QrCode.cpp
src/anpro/QrCode.cpp
)
list(APPEND GTA5VIEW_DEFINES
-DGTA5SYNC_DONATE
@ -244,10 +273,10 @@ option(WITH_MOTD "Developer message system directed to users" OFF)
if(WITH_MOTD)
set(MOTD_WEBURL "" CACHE STRING "Messages WebURL")
list(APPEND GTA5VIEW_HEADERS
MessageThread.h
src/MessageThread.h
)
list(APPEND GTA5VIEW_SOURCES
MessageThread.cpp
src/MessageThread.cpp
)
list(APPEND GTA5VIEW_DEFINES
-DGTA5SYNC_MOTD
@ -267,15 +296,15 @@ if(WITH_TELEMETRY)
set(TELEMETRY_REGURL "" CACHE STRING "Telemetry RegURL")
set(TELEMETRY_WEBURL "" CACHE STRING "Telemetry WebURL")
list(APPEND GTA5VIEW_HEADERS
TelemetryClass.h
tmext/TelemetryClassAuthenticator.h
src/TelemetryClass.h
src/tmext/TelemetryClassAuthenticator.h
)
list(APPEND GTA5VIEW_SOURCES
TelemetryClass.cpp
tmext/TelemetryClassAuthenticator.cpp
src/TelemetryClass.cpp
src/tmext/TelemetryClassAuthenticator.cpp
)
list(APPEND GTA5VIEW_INCLUDEDIR
tmext
src/tmext
)
list(APPEND GTA5VIEW_DEFINES
-DGTA5SYNC_TELEMETRY
@ -351,7 +380,7 @@ if(LINGUIST_FOUND AND QCONF_BUILD)
endif()
if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.16.0")
target_precompile_headers(gta5view PRIVATE config.h)
target_precompile_headers(gta5view PRIVATE src/config.h)
endif()
if(Qt5Core_VERSION VERSION_GREATER_EQUAL "5.14.0")
@ -359,8 +388,8 @@ if(Qt5Core_VERSION VERSION_GREATER_EQUAL "5.14.0")
endif()
target_compile_definitions(gta5view PRIVATE ${GTA5VIEW_DEFINES})
target_include_directories(gta5view PRIVATE ${GTA5VIEW_INCLUDEDIR})
target_link_libraries(gta5view PRIVATE Qt${QT_VERSION_MAJOR}::Network Qt${QT_VERSION_MAJOR}::Svg Qt${QT_VERSION_MAJOR}::Widgets ${GTA5VIEW_LIBS})
target_include_directories(gta5view PRIVATE ${GTA5VIEW_INCLUDEDIR} ${RAGEPHOTO_INCLUDE_DIRS})
target_link_libraries(gta5view PRIVATE Qt${QT_VERSION_MAJOR}::Network Qt${QT_VERSION_MAJOR}::Svg Qt${QT_VERSION_MAJOR}::Widgets ragephoto ${GTA5VIEW_LIBS})
install(TARGETS gta5view DESTINATION bin)
install(FILES res/de.syping.gta5view.desktop DESTINATION share/applications)

View File

@ -15,7 +15,7 @@ Open Source Snapmatic and Savegame viewer/editor for GTA V
# Note: Install Docker Community Edition and Git before continuing
docker pull sypingauto/gta5view-build:1.10-static
git clone https://gitlab.com/Syping/gta5view
git clone --recurse-submodules https://gitlab.com/Syping/gta5view
docker run --rm -v "$PWD/gta5view:/gta5view" -it sypingauto/gta5view-build:1.10-static
mingw64-qt-cmake -B /gta5view/build /gta5view
cmake --build /gta5view/build
@ -23,7 +23,7 @@ Open Source Snapmatic and Savegame viewer/editor for GTA V
#### Build gta5view for Debian/Ubuntu
sudo apt-get install cmake git gcc g++ libqt5svg5-dev make qtbase5-dev qttranslations5-l10n
git clone https://gitlab.com/Syping/gta5view
git clone --recurse-submodules https://gitlab.com/Syping/gta5view
cmake -B gta5view-build gta5view
cmake --build gta5view-build
sudo cmake --install gta5view-build
@ -31,7 +31,7 @@ Open Source Snapmatic and Savegame viewer/editor for GTA V
#### Build gta5view for Arch/Manjaro
sudo pacman -S cmake gcc git make qt5-base qt5-svg qt5-tools qt5-translations
git clone https://gitlab.com/Syping/gta5view
git clone --recurse-submodules https://gitlab.com/Syping/gta5view
cmake -B gta5view-build gta5view
cmake --build gta5view-build
sudo cmake --install gta5view-build
@ -39,7 +39,7 @@ Open Source Snapmatic and Savegame viewer/editor for GTA V
#### Build gta5view for Fedora/RHEL
sudo dnf install cmake git gcc gcc-c++ make qt5-qtbase-devel qt5-qtsvg-devel qt5-qttranslations
git clone https://gitlab.com/Syping/gta5view
git clone --recurse-submodules https://gitlab.com/Syping/gta5view
cmake -B gta5view-build gta5view
cmake --build gta5view-build
sudo cmake --install gta5view-build

View File

@ -1,865 +0,0 @@
/*****************************************************************************
* gta5view Grand Theft Auto V Profile Viewer
* Copyright (C) 2020-2022 Syping
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*****************************************************************************/
#include "RagePhoto.h"
#include <QJsonDocument>
#include <QBuffer>
#include <QFile>
#if QT_VERSION < 0x060000
#include <QTextCodec>
#else
#include <QStringEncoder>
#include <QStringDecoder>
#endif
#ifdef RAGEPHOTO_BENCHMARK
#include <QFileInfo>
#include <chrono>
#endif
RagePhoto::RagePhoto()
{
p_photoFormat = PhotoFormat::Undefined;
p_isLoaded = false;
p_inputMode = -1;
}
RagePhoto::RagePhoto(const QByteArray &data) : p_fileData(data)
{
p_photoFormat = PhotoFormat::Undefined;
p_isLoaded = false;
p_inputMode = 0;
}
RagePhoto::RagePhoto(const QString &filePath) : p_filePath(filePath)
{
p_photoFormat = PhotoFormat::Undefined;
p_isLoaded = false;
p_inputMode = 1;
}
RagePhoto::RagePhoto(QIODevice *ioDevice) : p_ioDevice(ioDevice)
{
p_photoFormat = PhotoFormat::Undefined;
p_isLoaded = false;
p_inputMode = 2;
}
bool RagePhoto::isLoaded()
{
return p_isLoaded;
}
bool RagePhoto::load()
{
if (p_inputMode == -1)
return false;
if (p_isLoaded)
clear();
if (p_inputMode == 1) {
QFile pictureFile(p_filePath);
if (pictureFile.open(QIODevice::ReadOnly)) {
p_fileData = pictureFile.readAll();
}
pictureFile.close();
}
else if (p_inputMode == 2) {
if (!p_ioDevice->isOpen()) {
if (!p_ioDevice->open(QIODevice::ReadOnly))
return false;
}
p_fileData = p_ioDevice->readAll();
}
QBuffer dataBuffer(&p_fileData);
dataBuffer.open(QIODevice::ReadOnly);
#ifdef RAGEPHOTO_BENCHMARK
auto benchmark_parse_start = std::chrono::high_resolution_clock::now();
#endif
char uInt32Buffer[4];
qint64 size = dataBuffer.read(uInt32Buffer, 4);
if (size != 4)
return false;
quint32 format = charToUInt32LE(uInt32Buffer);
if (format == static_cast<quint32>(PhotoFormat::GTA5)) {
char photoHeader[256];
size = dataBuffer.read(photoHeader, 256);
if (size != 256) {
return false;
}
for (const QChar &photoChar : utf16LEToString(photoHeader, 256)) {
if (photoChar.isNull())
break;
p_photoString += photoChar;
}
size = dataBuffer.read(uInt32Buffer, 4);
if (size != 4)
return false;
p_headerSum = charToUInt32LE(uInt32Buffer);
size = dataBuffer.read(uInt32Buffer, 4);
if (size != 4)
return false;
p_endOfFile = charToUInt32LE(uInt32Buffer);
size = dataBuffer.read(uInt32Buffer, 4);
if (size != 4)
return false;
p_jsonOffset = charToUInt32LE(uInt32Buffer);
size = dataBuffer.read(uInt32Buffer, 4);
if (size != 4)
return false;
p_titlOffset = charToUInt32LE(uInt32Buffer);
size = dataBuffer.read(uInt32Buffer, 4);
if (size != 4)
return false;
p_descOffset = charToUInt32LE(uInt32Buffer);
char markerBuffer[4];
size = dataBuffer.read(markerBuffer, 4);
if (size != 4)
return false;
if (strncmp(markerBuffer, "JPEG", 4) != 0)
return false;
size = dataBuffer.read(uInt32Buffer, 4);
if (size != 4)
return false;
p_photoBuffer = charToUInt32LE(uInt32Buffer);
size = dataBuffer.read(uInt32Buffer, 4);
if (size != 4)
return false;
quint32 t_photoSize = charToUInt32LE(uInt32Buffer);
char *photoData = static_cast<char*>(malloc(t_photoSize));
if (!photoData)
return false;
size = dataBuffer.read(photoData, t_photoSize);
if (size != t_photoSize) {
free(photoData);
return false;
}
p_photoData = QByteArray(photoData, t_photoSize);
free(photoData);
dataBuffer.seek(p_jsonOffset + 264);
size = dataBuffer.read(markerBuffer, 4);
if (size != 4)
return false;
if (strncmp(markerBuffer, "JSON", 4) != 0)
return false;
size = dataBuffer.read(uInt32Buffer, 4);
if (size != 4)
return false;
p_jsonBuffer = charToUInt32LE(uInt32Buffer);
char *jsonBytes = static_cast<char*>(malloc(p_jsonBuffer));
if (!jsonBytes)
return false;
size = dataBuffer.read(jsonBytes, p_jsonBuffer);
if (size != p_jsonBuffer) {
free(jsonBytes);
return false;
}
quint32 i;
for (i = 0; i != p_jsonBuffer; i++) {
if (jsonBytes[i] == '\x00')
break;
}
p_jsonData = QByteArray(jsonBytes, i);
free(jsonBytes);
QJsonDocument t_jsonDocument = QJsonDocument::fromJson(p_jsonData);
if (t_jsonDocument.isNull())
return false;
p_jsonObject = t_jsonDocument.object();
dataBuffer.seek(p_titlOffset + 264);
size = dataBuffer.read(markerBuffer, 4);
if (size != 4)
return false;
if (strncmp(markerBuffer, "TITL", 4) != 0)
return false;
size = dataBuffer.read(uInt32Buffer, 4);
if (size != 4)
return false;
p_titlBuffer = charToUInt32LE(uInt32Buffer);
char *titlBytes = static_cast<char*>(malloc(p_titlBuffer));
if (!titlBytes)
return false;
size = dataBuffer.read(titlBytes, p_titlBuffer);
if (size != p_titlBuffer){
free(titlBytes);
return false;
}
for (i = 0; i != p_titlBuffer; i++) {
if (titlBytes[i] == '\x00')
break;
}
p_titleString = QString::fromUtf8(titlBytes, i);
free(titlBytes);
dataBuffer.seek(p_descOffset + 264);
size = dataBuffer.read(markerBuffer, 4);
if (size != 4)
return false;
if (strncmp(markerBuffer, "DESC", 4) != 0)
return false;
size = dataBuffer.read(uInt32Buffer, 4);
if (size != 4)
return false;
p_descBuffer = charToUInt32LE(uInt32Buffer);
char *descBytes = static_cast<char*>(malloc(p_descBuffer));
if (!descBytes)
return false;
size = dataBuffer.read(descBytes, p_descBuffer);
if (size != p_descBuffer) {
free(descBytes);
return false;
}
for (i = 0; i != p_descBuffer; i++) {
if (descBytes[i] == '\x00')
break;
}
p_descriptionString = QString::fromUtf8(descBytes, i);
free(descBytes);
dataBuffer.seek(p_endOfFile + 260);
size = dataBuffer.read(markerBuffer, 4);
if (size != 4)
return false;
if (strncmp(markerBuffer, "JEND", 4) != 0)
return false;
#ifdef RAGEPHOTO_BENCHMARK
auto benchmark_parse_end = std::chrono::high_resolution_clock::now();
auto benchmark_ns = std::chrono::duration_cast<std::chrono::nanoseconds>(benchmark_parse_end - benchmark_parse_start);
if (p_inputMode == 1) {
QTextStream(stdout) << QFileInfo(p_filePath).fileName() << ": " << benchmark_ns.count() << "ns" << Qt::endl;
}
else {
QTextStream(stdout) << "PGTA5" << p_jsonObject.value("uid").toInt() << ": " << benchmark_ns.count() << "ns" << Qt::endl;
}
#endif
if (p_photoFormat != PhotoFormat::G5EX)
p_photoFormat = PhotoFormat::GTA5;
p_fileData.clear();
p_isLoaded = true;
return true;
}
else if (format == static_cast<quint32>(PhotoFormat::G5EX)) {
size = dataBuffer.read(uInt32Buffer, 4);
if (size != 4)
return false;
format = charToUInt32LE(uInt32Buffer);
if (format == static_cast<quint32>(ExportFormat::G5E3P)) {
size = dataBuffer.read(uInt32Buffer, 4);
if (size != 4)
return false;
quint32 compressedSize = charToUInt32LE(uInt32Buffer);
char *compressedPhotoHeader = static_cast<char*>(malloc(compressedSize));
if (!compressedPhotoHeader)
return false;
size = dataBuffer.read(compressedPhotoHeader, compressedSize);
if (size != compressedSize) {
free(compressedPhotoHeader);
return false;
}
QByteArray t_photoHeader = QByteArray::fromRawData(compressedPhotoHeader, compressedSize);
t_photoHeader = qUncompress(t_photoHeader);
free(compressedPhotoHeader);
if (t_photoHeader.isEmpty())
return false;
p_photoString = QString::fromUtf8(t_photoHeader);
size = dataBuffer.read(uInt32Buffer, 4);
if (size != 4)
return false;
p_headerSum = charToUInt32LE(uInt32Buffer);
size = dataBuffer.read(uInt32Buffer, 4);
if (size != 4)
return false;
p_photoBuffer = charToUInt32LE(uInt32Buffer);
size = dataBuffer.read(uInt32Buffer, 4);
if (size != 4)
return false;
compressedSize = charToUInt32LE(uInt32Buffer);
char *compressedPhoto = static_cast<char*>(malloc(compressedSize));
if (!compressedPhoto)
return false;
size = dataBuffer.read(compressedPhoto, compressedSize);
if (size != compressedSize) {
free(compressedPhoto);
return false;
}
QByteArray t_photoData = QByteArray::fromRawData(compressedPhoto, compressedSize);
p_photoData = qUncompress(t_photoData);
free(compressedPhoto);
size = dataBuffer.read(uInt32Buffer, 4);
if (size != 4)
return false;
p_jsonOffset = charToUInt32LE(uInt32Buffer);
size = dataBuffer.read(uInt32Buffer, 4);
if (size != 4)
return false;
p_jsonBuffer = charToUInt32LE(uInt32Buffer);
size = dataBuffer.read(uInt32Buffer, 4);
if (size != 4)
return false;
compressedSize = charToUInt32LE(uInt32Buffer);
char *compressedJson = static_cast<char*>(malloc(compressedSize));
if (!compressedJson)
return false;
size = dataBuffer.read(compressedJson, compressedSize);
if (size != compressedSize) {
free(compressedJson);
return false;
}
QByteArray t_jsonBytes = QByteArray::fromRawData(compressedJson, compressedSize);
p_jsonData = qUncompress(t_jsonBytes);
free(compressedJson);
if (p_jsonData.isEmpty())
return false;
QJsonDocument t_jsonDocument = QJsonDocument::fromJson(p_jsonData);
if (t_jsonDocument.isNull())
return false;
p_jsonObject = t_jsonDocument.object();
size = dataBuffer.read(uInt32Buffer, 4);
if (size != 4)
return false;
p_titlOffset = charToUInt32LE(uInt32Buffer);
size = dataBuffer.read(uInt32Buffer, 4);
if (size != 4)
return false;
p_titlBuffer = charToUInt32LE(uInt32Buffer);
size = dataBuffer.read(uInt32Buffer, 4);
if (size != 4)
return false;
compressedSize = charToUInt32LE(uInt32Buffer);
char *compressedTitl = static_cast<char*>(malloc(compressedSize));
if (!compressedTitl)
return false;
size = dataBuffer.read(compressedTitl, compressedSize);
if (size != compressedSize) {
free(compressedTitl);
return false;
}
QByteArray t_titlBytes = QByteArray::fromRawData(compressedTitl, compressedSize);
t_titlBytes = qUncompress(t_titlBytes);
free(compressedTitl);
p_titleString = QString::fromUtf8(t_titlBytes);
size = dataBuffer.read(uInt32Buffer, 4);
if (size != 4)
return false;
p_descOffset = charToUInt32LE(uInt32Buffer);
size = dataBuffer.read(uInt32Buffer, 4);
if (size != 4)
return false;
p_descBuffer = charToUInt32LE(uInt32Buffer);
size = dataBuffer.read(uInt32Buffer, 4);
if (size != 4)
return false;
compressedSize = charToUInt32LE(uInt32Buffer);
char *compressedDesc = static_cast<char*>(malloc(compressedSize));
if (!compressedDesc)
return false;
size = dataBuffer.read(compressedDesc, compressedSize);
if (size != compressedSize) {
free(compressedDesc);
return false;
}
QByteArray t_descBytes = QByteArray::fromRawData(compressedDesc, compressedSize);
t_descBytes = qUncompress(t_descBytes);
free(compressedDesc);
p_descriptionString = QString::fromUtf8(t_descBytes);
size = dataBuffer.read(uInt32Buffer, 4);
if (size != 4)
return false;
p_endOfFile = charToUInt32LE(uInt32Buffer);
#ifdef RAGEPHOTO_BENCHMARK
auto benchmark_parse_end = std::chrono::high_resolution_clock::now();
auto benchmark_ns = std::chrono::duration_cast<std::chrono::nanoseconds>(benchmark_parse_end - benchmark_parse_start);
if (p_inputMode == 1) {
QTextStream(stdout) << QFileInfo(p_filePath).fileName() << ": " << benchmark_ns.count() << "ns" << Qt::endl;
}
else {
QTextStream(stdout) << "PGTA5" << p_jsonObject.value("uid").toInt() << ": " << benchmark_ns.count() << "ns" << Qt::endl;
}
#endif
p_photoFormat = PhotoFormat::G5EX;
p_fileData.clear();
p_isLoaded = true;
return true;
}
else if (format == static_cast<quint32>(ExportFormat::G5E2P)) {
p_photoFormat = PhotoFormat::G5EX;
p_fileData = qUncompress(dataBuffer.readAll());
if (p_fileData.isEmpty())
return false;
p_inputMode = 0;
return load();
}
else if (format == static_cast<quint32>(ExportFormat::G5E1P)) {
#if QT_VERSION >= 0x050A00
size = dataBuffer.skip(1);
if (size != 1)
return false;
#else
if (!dataBuffer.seek(dataBuffer.pos() + 1))
return false;
#endif
char length[1];
size = dataBuffer.read(length, 1);
if (size != 1)
return false;
int i_length = QByteArray::number(static_cast<int>(length[0]), 16).toInt() + 6;
#if QT_VERSION >= 0x050A00
size = dataBuffer.skip(i_length);
if (size != i_length)
return false;
#else
if (!dataBuffer.seek(dataBuffer.pos() + i_length))
return false;
#endif
p_photoFormat = PhotoFormat::G5EX;
p_fileData = qUncompress(dataBuffer.readAll());
if (p_fileData.isEmpty())
return false;
p_inputMode = 0;
return load();
}
else {
return false;
}
}
else {
return false;
}
}
void RagePhoto::clear()
{
p_photoFormat = PhotoFormat::Undefined;
p_jsonObject = QJsonObject();
p_descriptionString.clear();
p_jsonData.clear();
p_photoData.clear();
p_photoString.clear();
p_titleString.clear();
p_headerSum = 0;
p_isLoaded = false;
}
void RagePhoto::setDescription(const QString &description)
{
p_descriptionString = description;
}
void RagePhoto::setFileData(const QByteArray &data)
{
p_fileData = data;
p_inputMode = 0;
}
void RagePhoto::setFilePath(const QString &filePath)
{
p_filePath = filePath;
p_inputMode = 1;
}
void RagePhoto::setIODevice(QIODevice *ioDevice)
{
p_ioDevice = ioDevice;
p_inputMode = 2;
}
bool RagePhoto::setJsonData(const QByteArray &data)
{
QJsonDocument t_jsonDocument = QJsonDocument::fromJson(data);
if (t_jsonDocument.isNull())
return false;
p_jsonData = t_jsonDocument.toJson(QJsonDocument::Compact);
p_jsonObject = t_jsonDocument.object();
return true;
}
bool RagePhoto::setPhotoBuffer(quint32 size, bool moveOffsets)
{
if (size < static_cast<quint32>(p_photoData.size()))
return false;
p_photoBuffer = size;
if (moveOffsets) {
p_jsonOffset = size + 28;
p_titlOffset = p_jsonOffset + p_jsonBuffer + 8;
p_descOffset = p_titlOffset + p_titlBuffer + 8;
p_endOfFile = p_descOffset + p_descBuffer + 12;
}
return true;
}
bool RagePhoto::setPhotoData(const QByteArray &data)
{
quint32 size = data.size();
if (size > p_photoBuffer)
return false;
p_photoData = data;
return true;
}
bool RagePhoto::setPhotoData(const char *data, int size)
{
if (static_cast<quint32>(size) > p_photoBuffer)
return false;
p_photoData = QByteArray(data, size);
return true;
}
void RagePhoto::setPhotoFormat(PhotoFormat photoFormat)
{
p_photoFormat = photoFormat;
}
void RagePhoto::setTitle(const QString &title)
{
p_titleString = title;
}
const QByteArray RagePhoto::jsonData(JsonFormat jsonFormat)
{
if (jsonFormat == JsonFormat::Compact) {
return QJsonDocument(p_jsonObject).toJson(QJsonDocument::Compact);
}
else if (jsonFormat == JsonFormat::Indented) {
return QJsonDocument(p_jsonObject).toJson(QJsonDocument::Indented);
}
else {
return p_jsonData;
}
}
const QJsonObject RagePhoto::jsonObject()
{
return p_jsonObject;
}
const QByteArray RagePhoto::photoData()
{
return p_photoData;
}
const QString RagePhoto::description()
{
return p_descriptionString;
}
const QString RagePhoto::photoString()
{
return p_photoString;
}
const QString RagePhoto::title()
{
return p_titleString;
}
quint32 RagePhoto::photoBuffer()
{
return p_photoBuffer;
}
quint32 RagePhoto::photoSize()
{
return p_photoData.size();
}
RagePhoto::PhotoFormat RagePhoto::photoFormat()
{
return p_photoFormat;
}
QByteArray RagePhoto::save(PhotoFormat photoFormat)
{
QByteArray data;
QBuffer dataBuffer(&data);
dataBuffer.open(QIODevice::WriteOnly);
save(&dataBuffer, photoFormat);
return data;
}
void RagePhoto::save(QIODevice *ioDevice, PhotoFormat photoFormat)
{
if (photoFormat == PhotoFormat::G5EX) {
char uInt32Buffer[4];
quint32 format = static_cast<quint32>(PhotoFormat::G5EX);
uInt32ToCharLE(format, uInt32Buffer);
ioDevice->write(uInt32Buffer, 4);
format = static_cast<quint32>(ExportFormat::G5E3P);
uInt32ToCharLE(format, uInt32Buffer);
ioDevice->write(uInt32Buffer, 4);
QByteArray compressedData = qCompress(p_photoString.toUtf8(), 9);
quint32 compressedSize = compressedData.size();
uInt32ToCharLE(compressedSize, uInt32Buffer);
ioDevice->write(uInt32Buffer, 4);
ioDevice->write(compressedData);
uInt32ToCharLE(p_headerSum, uInt32Buffer);
ioDevice->write(uInt32Buffer, 4);
uInt32ToCharLE(p_photoBuffer, uInt32Buffer);
ioDevice->write(uInt32Buffer, 4);
compressedData = qCompress(p_photoData, 9);
compressedSize = compressedData.size();
uInt32ToCharLE(compressedSize, uInt32Buffer);
ioDevice->write(uInt32Buffer, 4);
ioDevice->write(compressedData);
uInt32ToCharLE(p_jsonOffset, uInt32Buffer);
ioDevice->write(uInt32Buffer, 4);
uInt32ToCharLE(p_jsonBuffer, uInt32Buffer);
ioDevice->write(uInt32Buffer, 4);
compressedData = qCompress(p_jsonData, 9);
compressedSize = compressedData.size();
uInt32ToCharLE(compressedSize, uInt32Buffer);
ioDevice->write(uInt32Buffer, 4);
ioDevice->write(compressedData);
uInt32ToCharLE(p_titlOffset, uInt32Buffer);
ioDevice->write(uInt32Buffer, 4);
uInt32ToCharLE(p_titlBuffer, uInt32Buffer);
ioDevice->write(uInt32Buffer, 4);
compressedData = qCompress(p_titleString.toUtf8(), 9);
compressedSize = compressedData.size();
uInt32ToCharLE(compressedSize, uInt32Buffer);
ioDevice->write(uInt32Buffer, 4);
ioDevice->write(compressedData);
uInt32ToCharLE(p_descOffset, uInt32Buffer);
ioDevice->write(uInt32Buffer, 4);
uInt32ToCharLE(p_descBuffer, uInt32Buffer);
ioDevice->write(uInt32Buffer, 4);
compressedData = qCompress(p_descriptionString.toUtf8(), 9);
compressedSize = compressedData.size();
uInt32ToCharLE(compressedSize, uInt32Buffer);
ioDevice->write(uInt32Buffer, 4);
ioDevice->write(compressedData);
uInt32ToCharLE(p_endOfFile, uInt32Buffer);
ioDevice->write(uInt32Buffer, 4);
}
else if (photoFormat == PhotoFormat::GTA5) {
char uInt32Buffer[4];
quint32 format = static_cast<quint32>(PhotoFormat::GTA5);
uInt32ToCharLE(format, uInt32Buffer);
ioDevice->write(uInt32Buffer, 4);
QByteArray photoHeader = stringToUtf16LE(p_photoString);
if (photoHeader.startsWith("\xFF\xFE")) {
photoHeader.remove(0, 2);
}
qint64 photoHeaderSize = photoHeader.size();
if (photoHeaderSize > 256) {
photoHeader = photoHeader.left(256);
photoHeaderSize = 256;
}
ioDevice->write(photoHeader);
for (qint64 size = photoHeaderSize; size < 256; size++) {
ioDevice->write("\x00", 1);
}
uInt32ToCharLE(p_headerSum, uInt32Buffer);
ioDevice->write(uInt32Buffer, 4);
uInt32ToCharLE(p_endOfFile, uInt32Buffer);
ioDevice->write(uInt32Buffer, 4);
uInt32ToCharLE(p_jsonOffset, uInt32Buffer);
ioDevice->write(uInt32Buffer, 4);
uInt32ToCharLE(p_titlOffset, uInt32Buffer);
ioDevice->write(uInt32Buffer, 4);
uInt32ToCharLE(p_descOffset, uInt32Buffer);
ioDevice->write(uInt32Buffer, 4);
ioDevice->write("JPEG", 4);
uInt32ToCharLE(p_photoBuffer, uInt32Buffer);
ioDevice->write(uInt32Buffer, 4);
quint32 t_photoSize = p_photoData.size();
uInt32ToCharLE(t_photoSize, uInt32Buffer);
ioDevice->write(uInt32Buffer, 4);
ioDevice->write(p_photoData);
for (qint64 size = t_photoSize; size < p_photoBuffer; size++) {
ioDevice->write("\x00", 1);
}
ioDevice->seek(p_jsonOffset + 264);
ioDevice->write("JSON", 4);
uInt32ToCharLE(p_jsonBuffer, uInt32Buffer);
ioDevice->write(uInt32Buffer, 4);
qint64 dataSize = p_jsonData.size();
ioDevice->write(p_jsonData);
for (qint64 size = dataSize; size < p_jsonBuffer; size++) {
ioDevice->write("\x00", 1);
}
ioDevice->seek(p_titlOffset + 264);
ioDevice->write("TITL", 4);
uInt32ToCharLE(p_titlBuffer, uInt32Buffer);
ioDevice->write(uInt32Buffer, 4);
QByteArray data = p_titleString.toUtf8();
dataSize = data.size();
ioDevice->write(data);
for (qint64 size = dataSize; size < p_titlBuffer; size++) {
ioDevice->write("\x00", 1);
}
ioDevice->seek(p_descOffset + 264);
ioDevice->write("DESC", 4);
uInt32ToCharLE(p_descBuffer, uInt32Buffer);
ioDevice->write(uInt32Buffer, 4);
data = p_descriptionString.toUtf8();
dataSize = data.size();
ioDevice->write(data);
for (qint64 size = dataSize; size < p_descBuffer; size++) {
ioDevice->write("\x00", 1);
}
ioDevice->seek(p_endOfFile + 260);
ioDevice->write("JEND", 4);
}
}
RagePhoto* RagePhoto::loadFile(const QString &filePath)
{
RagePhoto *ragePhoto = new RagePhoto(filePath);
ragePhoto->load();
return ragePhoto;
}
quint32 RagePhoto::charToUInt32BE(char *x)
{
return (static_cast<unsigned char>(x[0]) << 24 |
static_cast<unsigned char>(x[1]) << 16 |
static_cast<unsigned char>(x[2]) << 8 |
static_cast<unsigned char>(x[3]));
}
quint32 RagePhoto::charToUInt32LE(char *x)
{
return (static_cast<unsigned char>(x[3]) << 24 |
static_cast<unsigned char>(x[2]) << 16 |
static_cast<unsigned char>(x[1]) << 8 |
static_cast<unsigned char>(x[0]));
}
void RagePhoto::uInt32ToCharBE(quint32 x, char *y)
{
y[0] = x >> 24;
y[1] = x >> 16;
y[2] = x >> 8;
y[3] = x;
}
void RagePhoto::uInt32ToCharLE(quint32 x, char *y)
{
y[0] = x;
y[1] = x >> 8;
y[2] = x >> 16;
y[3] = x >> 24;
}
const QByteArray RagePhoto::stringToUtf16LE(const QString &string)
{
#if QT_VERSION >= 0x060000
return QStringEncoder(QStringEncoder::Utf16LE)(string);
#else
return QTextCodec::codecForName("UTF-16LE")->fromUnicode(string);
#endif
}
const QString RagePhoto::utf16LEToString(const QByteArray &data)
{
#if QT_VERSION >= 0x060000
return QStringDecoder(QStringDecoder::Utf16LE)(data);
#else
return QTextCodec::codecForName("UTF-16LE")->toUnicode(data);
#endif
}
const QString RagePhoto::utf16LEToString(const char *data, int size)
{
#if QT_VERSION >= 0x060000
return QStringDecoder(QStringDecoder::Utf16LE)(QByteArray::fromRawData(data, size));
#else
return QTextCodec::codecForName("UTF-16LE")->toUnicode(data, size);
#endif
}

View File

@ -1,110 +0,0 @@
/*****************************************************************************
* gta5view Grand Theft Auto V Profile Viewer
* Copyright (C) 2020 Syping
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*****************************************************************************/
#ifndef RAGEPHOTO_H
#define RAGEPHOTO_H
#include <QJsonObject>
#include <QIODevice>
#include <QObject>
class RagePhoto : public QObject
{
Q_OBJECT
public:
enum class JsonFormat : quint8 {
Original = 0,
Compact = 1,
Indented = 2,
};
enum class ExportFormat : quint32 {
G5E1P = 0x454C0010U,
G5E2P = 0x01000032U,
G5E2S = 0x02000032U,
G5E3P = 0x01000033U,
G5E3S = 0x02000033U,
Undefined = 0,
};
enum class PhotoFormat : quint32 {
G5EX = 0x45354700U,
GTA5 = 0x01000000U,
RDR2 = 0x04000000U,
Undefined = 0,
};
explicit RagePhoto();
explicit RagePhoto(const QByteArray &data);
explicit RagePhoto(const QString &filePath);
explicit RagePhoto(QIODevice *ioDevice);
bool isLoaded();
bool load();
void clear();
void setDescription(const QString &description);
void setFileData(const QByteArray &data);
void setFilePath(const QString &filePath);
void setIODevice(QIODevice *ioDevice);
bool setJsonData(const QByteArray &data);
bool setPhotoBuffer(quint32 size, bool moveOffsets = true);
bool setPhotoData(const QByteArray &data);
bool setPhotoData(const char *data, int size);
void setPhotoFormat(PhotoFormat photoFormat);
void setTitle(const QString &title);
const QJsonObject jsonObject();
const QByteArray jsonData(JsonFormat jsonFormat = JsonFormat::Original);
const QByteArray photoData();
const QString description();
const QString photoString();
const QString title();
quint32 photoBuffer();
quint32 photoSize();
PhotoFormat photoFormat();
QByteArray save(PhotoFormat photoFormat);
void save(QIODevice *ioDevice, PhotoFormat photoFormat);
static RagePhoto* loadFile(const QString &filePath);
private:
inline quint32 charToUInt32BE(char *x);
inline quint32 charToUInt32LE(char *x);
inline void uInt32ToCharBE(quint32 x, char *y);
inline void uInt32ToCharLE(quint32 x, char *y);
inline const QByteArray stringToUtf16LE(const QString &string);
inline const QString utf16LEToString(const QByteArray &data);
inline const QString utf16LEToString(const char *data, int size);
PhotoFormat p_photoFormat;
QJsonObject p_jsonObject;
QByteArray p_fileData;
QByteArray p_jsonData;
QByteArray p_photoData;
QIODevice *p_ioDevice;
QString p_descriptionString;
QString p_filePath;
QString p_photoString;
QString p_titleString;
quint32 p_descBuffer;
quint32 p_descOffset;
quint32 p_endOfFile;
quint32 p_headerSum;
quint32 p_jsonBuffer;
quint32 p_jsonOffset;
quint32 p_photoBuffer;
quint32 p_titlBuffer;
quint32 p_titlOffset;
bool p_isLoaded;
int p_inputMode;
};
#endif // RAGEPHOTO_H

View File

@ -1,61 +0,0 @@
/*****************************************************************************
* gta5view Grand Theft Auto V Profile Viewer
* Copyright (C) 2016-2017 Syping
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*****************************************************************************/
#include "SidebarGenerator.h"
#include "StandardPaths.h"
#include "AppEnv.h"
#include <QList>
#include <QUrl>
#include <QDir>
SidebarGenerator::SidebarGenerator()
{
}
QList<QUrl> SidebarGenerator::generateSidebarUrls(QList<QUrl> sidebarUrls)
{
QDir dir;
dir.setPath(StandardPaths::picturesLocation());
if (dir.exists())
{
sidebarUrls += QUrl::fromLocalFile(dir.absolutePath());
}
dir.setPath(StandardPaths::documentsLocation());
if (dir.exists())
{
sidebarUrls += QUrl::fromLocalFile(dir.absolutePath());
}
bool gameFolderExists;
QString gameFolder = AppEnv::getGameFolder(&gameFolderExists);
if (gameFolderExists)
{
sidebarUrls += QUrl::fromLocalFile(gameFolder);
}
dir.setPath(StandardPaths::desktopLocation());
if (dir.exists())
{
sidebarUrls += QUrl::fromLocalFile(dir.absolutePath());
}
return sidebarUrls;
}

View File

@ -1,836 +0,0 @@
/*****************************************************************************
* gta5spv Grand Theft Auto Snapmatic Picture Viewer
* Copyright (C) 2016-2021 Syping
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*****************************************************************************/
#include "SnapmaticPicture.h"
#include <QStringBuilder>
#include <QJsonDocument>
#include <QJsonObject>
#include <QStringList>
#include <QVariantMap>
#include <QJsonArray>
#include <QFileInfo>
#include <QPainter>
#include <QString>
#include <QBuffer>
#include <QDebug>
#include <QImage>
#include <QSize>
#include <QFile>
#if QT_VERSION < 0x060000
#include <QTextCodec>
#else
#include <QStringDecoder>
#endif
#if QT_VERSION >= 0x050000
#include <QSaveFile>
#else
#include "StandardPaths.h"
#endif
// IMAGES VALUES
#define snapmaticResolutionW 960
#define snapmaticResolutionH 536
#define snapmaticResolution QSize(snapmaticResolutionW, snapmaticResolutionH)
SnapmaticPicture::SnapmaticPicture(const QString &fileName, QObject *parent) : QObject(parent), picFilePath(fileName)
{
reset();
}
SnapmaticPicture::~SnapmaticPicture()
{
}
void SnapmaticPicture::reset()
{
// INIT PIC
p_ragePhoto.clear();
cachePicture = QImage();
picExportFileName = QString();
pictureStr = QString();
lastStep = QString();
sortStr = QString();
// INIT PIC BOOLS
isFormatSwitch = false;
picOk = false;
// INIT JSON
jsonOk = false;
// SNAPMATIC PROPERTIES
localProperties = {};
}
bool SnapmaticPicture::preloadFile()
{
QFile *picFile = new QFile(picFilePath);
picFileName = QFileInfo(picFilePath).fileName();
isFormatSwitch = false;
if (!picFile->open(QFile::ReadOnly)) {
lastStep = "1;/1,OpenFile," % convertDrawStringForLog(picFilePath);
delete picFile;
return false;
}
p_ragePhoto.setIODevice(picFile);
bool ok = p_ragePhoto.load();
picFile->close();
delete picFile;
if (!ok)
return false;
if (picFilePath.right(4) != QLatin1String(".g5e")) {
if (p_ragePhoto.photoFormat() == RagePhoto::PhotoFormat::G5EX)
isFormatSwitch = true;
}
emit preloaded();
return ok;
}
bool SnapmaticPicture::readingPicture(bool cacheEnabled_)
{
// Start opening file
// lastStep is like currentStep
// Set boolean values
cacheEnabled = cacheEnabled_;
bool ok = true;
if (!p_ragePhoto.isLoaded())
ok = preloadFile();
if (!ok)
return false;
if (cacheEnabled)
picOk = cachePicture.loadFromData(p_ragePhoto.photoData(), "JPEG");
if (!cacheEnabled) {
QImage tempPicture;
picOk = tempPicture.loadFromData(p_ragePhoto.photoData(), "JPEG");
}
parseJsonContent(); // JSON parsing is own function
updateStrings();
emit loaded();
return picOk;
}
void SnapmaticPicture::updateStrings()
{
QString cmpPicTitl = p_ragePhoto.title();
cmpPicTitl.replace('\"', "''");
cmpPicTitl.replace(' ', '_');
cmpPicTitl.replace(':', '-');
cmpPicTitl.remove('\\');
cmpPicTitl.remove('{');
cmpPicTitl.remove('}');
cmpPicTitl.remove('/');
cmpPicTitl.remove('<');
cmpPicTitl.remove('>');
cmpPicTitl.remove('*');
cmpPicTitl.remove('?');
cmpPicTitl.remove('.');
pictureStr = tr("PHOTO - %1").arg(localProperties.createdDateTime.toString("MM/dd/yy HH:mm:ss"));
sortStr = localProperties.createdDateTime.toString("yyMMddHHmmss") % QString::number(localProperties.uid);
QString exportStr = localProperties.createdDateTime.toString("yyyyMMdd") % "-" % QString::number(localProperties.uid);
if (getSnapmaticFormat() == SnapmaticFormat::G5E_Format)
picFileName = "PGTA5" % QString::number(localProperties.uid);
picExportFileName = exportStr % "_" % cmpPicTitl;
}
bool SnapmaticPicture::readingPictureFromFile(const QString &fileName, bool cacheEnabled_)
{
if (!fileName.isEmpty()) {
picFilePath = fileName;
return readingPicture(cacheEnabled_);
}
else {
return false;
}
}
bool SnapmaticPicture::setImage(const QImage &picture, bool eXtendMode)
{
#ifdef GTA5SYNC_DYNAMIC_PHOTOBUFFER
quint32 jpegPicStreamLength = p_ragePhoto.photoBuffer();
#else
quint32 jpegPicStreamLength = 524288U;
#endif
QByteArray picByteArray;
int comLvl = 100;
bool saveSuccess = false;
while (comLvl != 0 && !saveSuccess) {
QByteArray picByteArrayT;
QBuffer picStreamT(&picByteArrayT);
picStreamT.open(QIODevice::WriteOnly);
saveSuccess = picture.save(&picStreamT, "JPEG", comLvl);
picStreamT.close();
if (saveSuccess) {
quint32 size = picByteArrayT.length();
if (size > jpegPicStreamLength) {
if (!eXtendMode) {
comLvl--;
saveSuccess = false;
}
else {
p_ragePhoto.setPhotoBuffer(size, true);
picByteArray = picByteArrayT;
}
}
else {
#ifndef GTA5SYNC_DYNAMIC_PHOTOBUFFER
if (p_ragePhoto.photoBuffer() != jpegPicStreamLength)
p_ragePhoto.setPhotoData(QByteArray()); // avoid buffer set fail
p_ragePhoto.setPhotoBuffer(jpegPicStreamLength, true);
#endif
picByteArray = picByteArrayT;
}
}
}
if (saveSuccess)
return setPictureStream(picByteArray);
return false;
}
bool SnapmaticPicture::setPictureStream(const QByteArray &streamArray) // clean method
{
bool success = p_ragePhoto.setPhotoData(streamArray);
if (success) {
if (cacheEnabled) {
QImage replacedPicture;
replacedPicture.loadFromData(streamArray);
cachePicture = replacedPicture;
}
return true;
}
else {
return false;
}
}
bool SnapmaticPicture::setPictureTitl(const QString &newTitle_)
{
QString newTitle = newTitle_;
if (newTitle.length() > 39) {
newTitle = newTitle.left(39);
}
p_ragePhoto.setTitle(newTitle);
return true;
}
int SnapmaticPicture::getContentMaxLength()
{
return p_ragePhoto.photoBuffer();
}
QString SnapmaticPicture::getExportPictureFileName()
{
return picExportFileName;
}
QString SnapmaticPicture::getOriginalPictureFileName()
{
QString newPicFileName = picFileName;
if (picFileName.right(4) == ".bak") {
newPicFileName = QString(picFileName).remove(picFileName.length() - 4, 4);
}
if (picFileName.right(7) == ".hidden") {
newPicFileName = QString(picFileName).remove(picFileName.length() - 7, 7);
}
return newPicFileName;
}
QString SnapmaticPicture::getOriginalPictureFilePath()
{
QString newPicFilePath = picFilePath;
if (picFilePath.right(4) == ".bak") {
newPicFilePath = QString(picFilePath).remove(picFilePath.length() - 4, 4);
}
if (picFilePath.right(7) == ".hidden") {
newPicFilePath = QString(picFilePath).remove(picFilePath.length() - 7, 7);
}
return newPicFilePath;
}
QString SnapmaticPicture::getPictureFileName()
{
return picFileName;
}
QString SnapmaticPicture::getPictureFilePath()
{
return picFilePath;
}
QString SnapmaticPicture::getPictureSortStr()
{
return sortStr;
}
QString SnapmaticPicture::getPictureTitl()
{
return p_ragePhoto.title();
}
QString SnapmaticPicture::getPictureStr()
{
return pictureStr;
}
QString SnapmaticPicture::getLastStep(bool readable)
{
if (readable) {
QStringList lastStepList = lastStep.split(";/");
if (lastStepList.length() < 2)
return lastStep;
bool intOk;
QStringList descStepList = lastStepList.at(1).split(",");
if (descStepList.length() < 1)
return lastStep;
int argsCount = descStepList.at(0).toInt(&intOk);
if (!intOk) { return lastStep; }
if (argsCount == 1) {
QString currentAction = descStepList.at(1);
QString actionFile = descStepList.at(2);
if (currentAction == "OpenFile") {
return tr("open file %1").arg(actionFile);
}
}
else if (argsCount == 3 || argsCount == 4) {
QString currentAction = descStepList.at(1);
QString actionFile = descStepList.at(2);
QString actionError = descStepList.at(4);
QString actionError2;
if (argsCount == 4) { actionError2 = descStepList.at(5); }
if (currentAction == "ReadingFile") {
QString readableError = actionError;
if (actionError == "NOHEADER") {
readableError = tr("header not exists");
}
else if (actionError == "MALFORMEDHEADER") {
readableError = tr("header is malformed");
}
else if (actionError == "NOJPEG" || actionError == "NOPIC") {
readableError = tr("picture not exists (%1)").arg(actionError);
}
else if (actionError == "NOJSON" || actionError == "CTJSON") {
readableError = tr("JSON not exists (%1)").arg(actionError);
}
else if (actionError == "NOTITL" || actionError == "CTTITL") {
readableError = tr("title not exists (%1)").arg(actionError);
}
else if (actionError == "NODESC" || actionError == "CTDESC") {
readableError = tr("description not exists (%1)").arg(actionError);
}
else if (actionError == "JSONINCOMPLETE" && actionError2 == "JSONERROR") {
readableError = tr("JSON is incomplete and malformed");
}
else if (actionError == "JSONINCOMPLETE") {
readableError = tr("JSON is incomplete");
}
else if (actionError == "JSONERROR") {
readableError = tr("JSON is malformed");
}
return tr("reading file %1 because of %2", "Example for %2: JSON is malformed error").arg(actionFile, readableError);
}
else {
return lastStep;
}
}
else {
return lastStep;
}
}
return lastStep;
}
QImage SnapmaticPicture::getImage()
{
if (cacheEnabled) {
return cachePicture;
}
else {
return QImage::fromData(p_ragePhoto.photoData(), "JPEG");
}
return QImage();
}
QByteArray SnapmaticPicture::getPictureStream()
{
return p_ragePhoto.photoData();
}
bool SnapmaticPicture::isPicOk()
{
return picOk;
}
void SnapmaticPicture::clearCache()
{
cacheEnabled = false;
cachePicture = QImage();
}
void SnapmaticPicture::emitUpdate()
{
emit updated();
}
void SnapmaticPicture::emitCustomSignal(const QString &signal)
{
emit customSignal(signal);
}
// JSON part
bool SnapmaticPicture::isJsonOk()
{
return jsonOk;
}
QString SnapmaticPicture::getJsonStr()
{
return QString::fromUtf8(p_ragePhoto.jsonData());
}
SnapmaticProperties SnapmaticPicture::getSnapmaticProperties()
{
return localProperties;
}
void SnapmaticPicture::parseJsonContent()
{
QJsonObject jsonObject = p_ragePhoto.jsonObject();
QVariantMap jsonMap = jsonObject.toVariantMap();
bool jsonIncomplete = false;
bool jsonError = false;
if (jsonObject.contains("loc")) {
if (jsonObject["loc"].isObject()) {
QJsonObject locObject = jsonObject["loc"].toObject();
if (locObject.contains("x")) {
if (locObject["x"].isDouble()) { localProperties.location.x = locObject["x"].toDouble(); }
else { jsonError = true; }
}
else { jsonIncomplete = true; }
if (locObject.contains("y")) {
if (locObject["y"].isDouble()) { localProperties.location.y = locObject["y"].toDouble(); }
else { jsonError = true; }
}
else { jsonIncomplete = true; }
if (locObject.contains("z")) {
if (locObject["z"].isDouble()) { localProperties.location.z = locObject["z"].toDouble(); }
else { jsonError = true; }
}
else { jsonIncomplete = true; }
}
else { jsonError = true; }
}
else { jsonIncomplete = true; }
if (jsonObject.contains("uid")) {
bool uidOk;
localProperties.uid = jsonMap["uid"].toInt(&uidOk);
if (!uidOk) { jsonError = true; }
}
else { jsonIncomplete = true; }
if (jsonObject.contains("area")) {
if (jsonObject["area"].isString()) { localProperties.location.area = jsonObject["area"].toString(); }
else { jsonError = true; }
}
else { jsonIncomplete = true; }
if (jsonObject.contains("crewid")) {
bool crewIDOk;
localProperties.crewID = jsonMap["crewid"].toInt(&crewIDOk);
if (!crewIDOk) { jsonError = true; }
}
else { jsonIncomplete = true; }
if (jsonObject.contains("street")) {
bool streetIDOk;
localProperties.streetID = jsonMap["street"].toInt(&streetIDOk);
if (!streetIDOk) { jsonError = true; }
}
else { jsonIncomplete = true; }
if (jsonObject.contains("creat")) {
bool timestampOk;
QDateTime createdTimestamp;
localProperties.createdTimestamp = jsonMap["creat"].toUInt(&timestampOk);
#if QT_VERSION >= 0x060000
createdTimestamp.setSecsSinceEpoch(localProperties.createdTimestamp);
#else
createdTimestamp.setTime_t(localProperties.createdTimestamp);
#endif
localProperties.createdDateTime = createdTimestamp;
if (!timestampOk) { jsonError = true; }
}
else { jsonIncomplete = true; }
if (jsonObject.contains("plyrs")) {
if (jsonObject["plyrs"].isArray()) { localProperties.playersList = jsonMap["plyrs"].toStringList(); }
else { jsonError = true; }
}
// else { jsonIncomplete = true; } // 2016 Snapmatic pictures left out plyrs when none are captured, so don't force exists on that one
if (jsonObject.contains("meme")) {
if (jsonObject["meme"].isBool()) { localProperties.isMeme = jsonObject["meme"].toBool(); }
else { jsonError = true; }
}
else { jsonIncomplete = true; }
if (jsonObject.contains("mug")) {
if (jsonObject["mug"].isBool()) { localProperties.isMug = jsonObject["mug"].toBool(); }
else { jsonError = true; }
}
else { jsonIncomplete = true; }
if (jsonObject.contains("slf")) {
if (jsonObject["slf"].isBool()) { localProperties.isSelfie = jsonObject["slf"].toBool(); }
else { jsonError = true; }
}
else { jsonIncomplete = true; }
if (jsonObject.contains("drctr")) {
if (jsonObject["drctr"].isBool()) { localProperties.isFromDirector = jsonObject["drctr"].toBool(); }
else { jsonError = true; }
}
else { jsonIncomplete = true; }
if (jsonObject.contains("rsedtr")) {
if (jsonObject["rsedtr"].isBool()) { localProperties.isFromRSEditor = jsonObject["rsedtr"].toBool(); }
else { jsonError = true; }
}
else { localProperties.isFromRSEditor = false; }
if (jsonObject.contains("onislandx")) {
if (jsonObject["onislandx"].isBool()) { localProperties.location.isCayoPerico = jsonObject["onislandx"].toBool(); }
else { jsonError = true; }
}
else { localProperties.location.isCayoPerico = false; }
if (!jsonIncomplete && !jsonError) {
jsonOk = true;
}
else {
if (jsonIncomplete && jsonError) {
lastStep = "2;/4,ReadingFile," % convertDrawStringForLog(picFilePath) % ",3,JSONINCOMPLETE,JSONERROR";
}
else if (jsonIncomplete) {
lastStep = "2;/3,ReadingFile," % convertDrawStringForLog(picFilePath) % ",3,JSONINCOMPLETE";
}
else if (jsonError) {
lastStep = "2;/3,ReadingFile," % convertDrawStringForLog(picFilePath) % ",3,JSONERROR";
}
jsonOk = false;
}
}
bool SnapmaticPicture::setSnapmaticProperties(SnapmaticProperties properties)
{
QJsonObject jsonObject = p_ragePhoto.jsonObject();
QJsonObject locObject;
locObject["x"] = properties.location.x;
locObject["y"] = properties.location.y;
locObject["z"] = properties.location.z;
jsonObject["loc"] = locObject;
jsonObject["uid"] = properties.uid;
jsonObject["area"] = properties.location.area;
jsonObject["crewid"] = properties.crewID;
jsonObject["street"] = properties.streetID;
jsonObject["creat"] = QJsonValue::fromVariant(properties.createdTimestamp);
jsonObject["plyrs"] = QJsonValue::fromVariant(properties.playersList);
jsonObject["meme"] = properties.isMeme;
jsonObject["mug"] = properties.isMug;
jsonObject["slf"] = properties.isSelfie;
jsonObject["drctr"] = properties.isFromDirector;
jsonObject["rsedtr"] = properties.isFromRSEditor;
jsonObject["onislandx"] = properties.location.isCayoPerico;
QJsonDocument jsonDocument(jsonObject);
if (setJsonStr(QString::fromUtf8(jsonDocument.toJson(QJsonDocument::Compact)))) {
localProperties = properties;
return true;
}
return false;
}
bool SnapmaticPicture::setJsonStr(const QString &newJsonStr, bool updateProperties)
{
if (p_ragePhoto.setJsonData(newJsonStr.toUtf8())) {
if (updateProperties)
parseJsonContent();
return true;
}
else {
return false;
}
}
// FILE MANAGEMENT
bool SnapmaticPicture::exportPicture(const QString &fileName, SnapmaticFormat format_)
{
// Keep current format when Auto_Format is used
SnapmaticFormat format = format_;
if (format_ == SnapmaticFormat::Auto_Format) {
if (p_ragePhoto.photoFormat() == RagePhoto::PhotoFormat::G5EX) {
format = SnapmaticFormat::G5E_Format;
}
else {
format = SnapmaticFormat::PGTA_Format;
}
}
bool saveSuccess = false;
#if QT_VERSION >= 0x050000
QSaveFile *picFile = new QSaveFile(fileName);
#else
QFile *picFile = new QFile(StandardPaths::tempLocation() % "/" % QFileInfo(fileName).fileName() % ".tmp");
#endif
if (picFile->open(QIODevice::WriteOnly)) {
if (format == SnapmaticFormat::G5E_Format) {
p_ragePhoto.save(picFile, RagePhoto::PhotoFormat::G5EX);
#if QT_VERSION >= 0x050000
saveSuccess = picFile->commit();
#else
saveSuccess = true;
picFile->close();
#endif
delete picFile;
}
else if (format == SnapmaticFormat::JPEG_Format) {
picFile->write(p_ragePhoto.photoData());
#if QT_VERSION >= 0x050000
saveSuccess = picFile->commit();
#else
saveSuccess = true;
picFile->close();
#endif
delete picFile;
}
else {
p_ragePhoto.save(picFile, RagePhoto::PhotoFormat::GTA5);
#if QT_VERSION >= 0x050000
saveSuccess = picFile->commit();
#else
saveSuccess = true;
picFile->close();
#endif
delete picFile;
}
#if QT_VERSION <= 0x050000
if (saveSuccess) {
bool tempBakCreated = false;
if (QFile::exists(fileName)) {
if (!QFile::rename(fileName, fileName % ".tmp")) {
QFile::remove(StandardPaths::tempLocation() % "/" % QFileInfo(fileName).fileName() % ".tmp");
return false;
}
tempBakCreated = true;
}
if (!QFile::rename(StandardPaths::tempLocation() % "/" % QFileInfo(fileName).fileName() % ".tmp", fileName)) {
QFile::remove(StandardPaths::tempLocation() % "/" % QFileInfo(fileName).fileName() % ".tmp");
if (tempBakCreated)
QFile::rename(fileName % ".tmp", fileName);
return false;
}
if (tempBakCreated)
QFile::remove(fileName % ".tmp");
}
#endif
return saveSuccess;
}
else {
delete picFile;
return saveSuccess;
}
}
void SnapmaticPicture::setPicFileName(const QString &picFileName_)
{
picFileName = picFileName_;
}
void SnapmaticPicture::setPicFilePath(const QString &picFilePath_)
{
picFilePath = picFilePath_;
}
bool SnapmaticPicture::deletePicFile()
{
bool success = false;
if (!QFile::exists(picFilePath)) {
success = true;
}
else if (QFile::remove(picFilePath)) {
success = true;
}
if (isHidden()) {
const QString picBakPath = QString(picFilePath).remove(picFilePath.length() - 7, 7) % ".bak";
if (QFile::exists(picBakPath)) QFile::remove(picBakPath);
}
else {
const QString picBakPath = picFilePath % ".bak";
if (QFile::exists(picBakPath)) QFile::remove(picBakPath);
}
return success;
}
// VISIBILITY
bool SnapmaticPicture::isHidden()
{
if (picFilePath.right(7) == QLatin1String(".hidden")) {
return true;
}
return false;
}
bool SnapmaticPicture::isVisible()
{
if (picFilePath.right(7) == QLatin1String(".hidden")) {
return false;
}
return true;
}
bool SnapmaticPicture::setPictureHidden()
{
if (p_ragePhoto.photoFormat() == RagePhoto::PhotoFormat::G5EX) {
return false;
}
if (!isHidden()) {
QString newPicFilePath = QString(picFilePath % ".hidden");
if (QFile::rename(picFilePath, newPicFilePath)) {
picFilePath = newPicFilePath;
return true;
}
return false;
}
return true;
}
bool SnapmaticPicture::setPictureVisible()
{
if (p_ragePhoto.photoFormat() == RagePhoto::PhotoFormat::G5EX) {
return false;
}
if (isHidden()) {
QString newPicFilePath = QString(picFilePath).remove(picFilePath.length() - 7, 7);
if (QFile::rename(picFilePath, newPicFilePath)) {
picFilePath = newPicFilePath;
return true;
}
return false;
}
return true;
}
// PREDEFINED PROPERTIES
QSize SnapmaticPicture::getSnapmaticResolution()
{
return snapmaticResolution;
}
// SNAPMATIC FORMAT
SnapmaticFormat SnapmaticPicture::getSnapmaticFormat()
{
if (p_ragePhoto.photoFormat() == RagePhoto::PhotoFormat::G5EX) {
return SnapmaticFormat::G5E_Format;
}
return SnapmaticFormat::PGTA_Format;
}
void SnapmaticPicture::setSnapmaticFormat(SnapmaticFormat format)
{
if (format == SnapmaticFormat::G5E_Format) {
p_ragePhoto.setPhotoFormat(RagePhoto::PhotoFormat::G5EX);
return;
}
else if (format == SnapmaticFormat::PGTA_Format) {
p_ragePhoto.setPhotoFormat(RagePhoto::PhotoFormat::GTA5);
return;
}
qDebug() << "setSnapmaticFormat: Invalid SnapmaticFormat defined, valid SnapmaticFormats are G5E_Format and PGTA_Format";
}
bool SnapmaticPicture::isFormatSwitched()
{
return isFormatSwitch;
}
// VERIFY CONTENT
bool SnapmaticPicture::verifyTitle(const QString &title)
{
// VERIFY TITLE FOR BE A VALID SNAPMATIC TITLE
if (title.length() <= 39 && title.length() > 0) {
for (const QChar &titleChar : title) {
if (!verifyTitleChar(titleChar)) return false;
}
return true;
}
return false;
}
bool SnapmaticPicture::verifyTitleChar(const QChar &titleChar)
{
// VERIFY CHAR FOR BE A VALID SNAPMATIC CHARACTER
if (titleChar.isLetterOrNumber() || titleChar.isPrint()) {
if (titleChar == '<' || titleChar == '>' || titleChar == '\\') return false;
return true;
}
return false;
}
// STRING OPERATIONS
QString SnapmaticPicture::parseTitleString(const QByteArray &commitBytes, int maxLength)
{
Q_UNUSED(maxLength)
#if QT_VERSION >= 0x060000
QStringDecoder strDecoder = QStringDecoder(QStringDecoder::Utf16LE);
QString retStr = strDecoder(commitBytes);
retStr = retStr.trimmed();
#else
QString retStr = QTextCodec::codecForName("UTF-16LE")->toUnicode(commitBytes).trimmed();
#endif
retStr.remove(QChar('\x00'));
return retStr;
}
QString SnapmaticPicture::convertDrawStringForLog(const QString &inputStr)
{
QString outputStr = inputStr;
return outputStr.replace("&","&u;").replace(",", "&c;");
}
QString SnapmaticPicture::convertLogStringForDraw(const QString &inputStr)
{
QString outputStr = inputStr;
return outputStr.replace("&c;",",").replace("&u;", "&");
}
// RAGEPHOTO
RagePhoto* SnapmaticPicture::ragePhoto()
{
return &p_ragePhoto;
}

View File

@ -1,537 +0,0 @@
/*****************************************************************************
* ImageCropper Qt Widget for cropping images
* Copyright (C) 2013 Dimka Novikov, to@dimkanovikov.pro
* Copyright (C) 2020 Syping
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*****************************************************************************/
#include "imagecropper.h"
#include "AppEnv.h"
#include <QPainterPath>
#include <QMouseEvent>
#include <QPainter>
namespace {
static const QSize WIDGET_MINIMUM_SIZE(470, 470);
}
ImageCropper::ImageCropper(QWidget* parent) :
QWidget(parent),
pimpl(new ImageCropperPrivate)
{
setMinimumSize(WIDGET_MINIMUM_SIZE);
setMouseTracking(true);
}
ImageCropper::~ImageCropper()
{
delete pimpl;
}
void ImageCropper::setImage(const QPixmap& _image)
{
pimpl->imageForCropping = _image;
update();
}
void ImageCropper::setBackgroundColor(const QColor& _backgroundColor)
{
pimpl->backgroundColor = _backgroundColor;
update();
}
void ImageCropper::setCroppingRectBorderColor(const QColor& _borderColor)
{
pimpl->croppingRectBorderColor = _borderColor;
update();
}
void ImageCropper::setProportion(const QSizeF& _proportion)
{
// Пропорции хранятся в коэффициентах приращения сторон
// Таким образом, при изменении размера области выделения,
// размеры сторон изменяются на размер зависящий от
// коэффициентов приращения.
// Сохраним пропорциональную зависимость области выделения в коэффициентах приращения сторон
if (pimpl->proportion != _proportion) {
pimpl->proportion = _proportion;
// ... расчитаем коэффициенты
float heightDelta = (float)_proportion.height() / _proportion.width();
float widthDelta = (float)_proportion.width() / _proportion.height();
// ... сохраним коэффициенты
pimpl->deltas.setHeight(heightDelta);
pimpl->deltas.setWidth(widthDelta);
}
// Обновим пропорции области выделения
if ( pimpl->isProportionFixed ) {
float croppintRectSideRelation =
(float)pimpl->croppingRect.width() / pimpl->croppingRect.height();
float proportionSideRelation =
(float)pimpl->proportion.width() / pimpl->proportion.height();
// Если область выделения не соответствует необходимым пропорциям обновим её
if (croppintRectSideRelation != proportionSideRelation) {
bool widthShotrerThenHeight =
pimpl->croppingRect.width() < pimpl->croppingRect.height();
// ... установим размер той стороны, что длиннее
if (widthShotrerThenHeight) {
pimpl->croppingRect.setHeight(
pimpl->croppingRect.width() * pimpl->deltas.height());
} else {
pimpl->croppingRect.setWidth(
pimpl->croppingRect.height() * pimpl->deltas.width());
}
// ... перерисуем виджет
update();
}
}
}
void ImageCropper::setProportionFixed(const bool _isFixed)
{
if (pimpl->isProportionFixed != _isFixed) {
pimpl->isProportionFixed = _isFixed;
setProportion(pimpl->proportion);
}
}
const QPixmap ImageCropper::cropImage()
{
// Получим размер отображаемого изображения
QSize scaledImageSize =
pimpl->imageForCropping.scaled(
size(), Qt::KeepAspectRatio, Qt::SmoothTransformation
).size();
// Определим расстояние от левого и верхнего краёв
float leftDelta = 0;
float topDelta = 0;
const float HALF_COUNT = 2;
if (size().height() == scaledImageSize.height()) {
leftDelta = (width() - scaledImageSize.width()) / HALF_COUNT;
} else {
topDelta = (height() - scaledImageSize.height()) / HALF_COUNT;
}
// Определим пропорцию области обрезки по отношению к исходному изображению
float xScale = (float)pimpl->imageForCropping.width() / scaledImageSize.width();
float yScale = (float)pimpl->imageForCropping.height() / scaledImageSize.height();
// Расчитаем область обрезки с учётом коррекции размеров исходного изображения
QRectF realSizeRect(
QPointF(pimpl->croppingRect.left() - leftDelta, pimpl->croppingRect.top() - topDelta),
pimpl->croppingRect.size());
// ... корректируем левый и верхний края
realSizeRect.setLeft((pimpl->croppingRect.left() - leftDelta) * xScale);
realSizeRect.setTop ((pimpl->croppingRect.top() - topDelta) * yScale);
// ... корректируем размер
realSizeRect.setWidth(pimpl->croppingRect.width() * xScale);
realSizeRect.setHeight(pimpl->croppingRect.height() * yScale);
// Получаем обрезанное изображение
return pimpl->imageForCropping.copy(realSizeRect.toRect());
}
// ********
// Protected section
void ImageCropper::paintEvent(QPaintEvent* _event)
{
QWidget::paintEvent(_event);
//
QPainter widgetPainter(this);
// Рисуем изображение по центру виджета
{
#if QT_VERSION >= 0x050600
qreal screenRatioPR = AppEnv::screenRatioPR();
// ... подгоним изображение для отображения по размеру виджета
QPixmap scaledImage =
pimpl->imageForCropping.scaled(qRound((double)width() * screenRatioPR), qRound((double)height() * screenRatioPR), Qt::KeepAspectRatio, Qt::SmoothTransformation);
scaledImage.setDevicePixelRatio(screenRatioPR);
#else
QPixmap scaledImage =
pimpl->imageForCropping.scaled(size(), Qt::KeepAspectRatio, Qt::SmoothTransformation);
#endif
// ... заливаем фон
widgetPainter.fillRect(rect(), pimpl->backgroundColor);
// ... рисуем изображение по центру виджета
#if QT_VERSION >= 0x050600
if (qRound((double)height() * screenRatioPR) == scaledImage.height()) {
widgetPainter.drawPixmap( ( qRound((double)width() * screenRatioPR) - scaledImage.width() ) / 2, 0, scaledImage );
} else {
widgetPainter.drawPixmap( 0, ( qRound((double)height() * screenRatioPR) - scaledImage.height() ) / 2, scaledImage );
}
#else
if (height() == scaledImage.height()) {
widgetPainter.drawPixmap( ( width()- scaledImage.width() ) / 2, 0, scaledImage );
} else {
widgetPainter.drawPixmap( 0, ( height() - scaledImage.height() ) / 2, scaledImage );
}
#endif
}
// Рисуем область обрезки
{
// ... если это первое отображение после инициилизации, то центруем областо обрезки
if (pimpl->croppingRect.isNull()) {
const int cwidth = WIDGET_MINIMUM_SIZE.width()/2;
const int cheight = WIDGET_MINIMUM_SIZE.height()/2;
pimpl->croppingRect.setSize(QSize(cwidth, cheight));
float x = (width() - pimpl->croppingRect.width())/2;
float y = (height() - pimpl->croppingRect.height())/2;
pimpl->croppingRect.moveTo(x, y);
}
// ... рисуем затемненную область
QPainterPath p;
p.addRect(pimpl->croppingRect);
p.addRect(rect());
widgetPainter.setBrush(QBrush(QColor(0,0,0,120)));
widgetPainter.setPen(Qt::transparent);
widgetPainter.drawPath(p);
// Рамка и контрольные точки
widgetPainter.setPen(pimpl->croppingRectBorderColor);
// ... рисуем прямоугольник области обрезки
{
widgetPainter.setBrush(QBrush(Qt::transparent));
widgetPainter.drawRect(pimpl->croppingRect);
}
// ... рисуем контрольные точки
{
widgetPainter.setBrush(QBrush(pimpl->croppingRectBorderColor));
// Вспомогательные X координаты
int leftXCoord = pimpl->croppingRect.left() - 2;
int centerXCoord = pimpl->croppingRect.center().x() - 3;
int rightXCoord = pimpl->croppingRect.right() - 2;
// Вспомогательные Y координаты
int topYCoord = pimpl->croppingRect.top() - 2;
int middleYCoord = pimpl->croppingRect.center().y() - 3;
int bottomYCoord = pimpl->croppingRect.bottom() - 2;
//
const QSize pointSize(6, 6);
//
QVector<QRect> points;
points
// левая сторона
<< QRect( QPoint(leftXCoord, topYCoord), pointSize )
<< QRect( QPoint(leftXCoord, middleYCoord), pointSize )
<< QRect( QPoint(leftXCoord, bottomYCoord), pointSize )
// центр
<< QRect( QPoint(centerXCoord, topYCoord), pointSize )
<< QRect( QPoint(centerXCoord, middleYCoord), pointSize )
<< QRect( QPoint(centerXCoord, bottomYCoord), pointSize )
// правая сторона
<< QRect( QPoint(rightXCoord, topYCoord), pointSize )
<< QRect( QPoint(rightXCoord, middleYCoord), pointSize )
<< QRect( QPoint(rightXCoord, bottomYCoord), pointSize );
//
widgetPainter.drawRects( points );
}
// ... рисуем пунктирные линии
{
QPen dashPen(pimpl->croppingRectBorderColor);
dashPen.setStyle(Qt::DashLine);
widgetPainter.setPen(dashPen);
// ... вертикальная
widgetPainter.drawLine(
QPoint(pimpl->croppingRect.center().x(), pimpl->croppingRect.top()),
QPoint(pimpl->croppingRect.center().x(), pimpl->croppingRect.bottom()) );
// ... горизонтальная
widgetPainter.drawLine(
QPoint(pimpl->croppingRect.left(), pimpl->croppingRect.center().y()),
QPoint(pimpl->croppingRect.right(), pimpl->croppingRect.center().y()) );
}
}
//
widgetPainter.end();
}
void ImageCropper::mousePressEvent(QMouseEvent* _event)
{
if (_event->button() == Qt::LeftButton) {
pimpl->isMousePressed = true;
pimpl->startMousePos = _event->pos();
pimpl->lastStaticCroppingRect = pimpl->croppingRect;
}
//
updateCursorIcon(_event->pos());
}
void ImageCropper::mouseMoveEvent(QMouseEvent* _event)
{
QPointF mousePos = _event->pos(); // относительно себя (виджета)
//
if (!pimpl->isMousePressed) {
// Обработка обычного состояния, т.е. не изменяется размер
// области обрезки, и она не перемещается по виджету
pimpl->cursorPosition = cursorPosition(pimpl->croppingRect, mousePos);
updateCursorIcon(mousePos);
} else if (pimpl->cursorPosition != CursorPositionUndefined) {
// Обработка действий над областью обрезки
// ... определим смещение курсора мышки
QPointF mouseDelta;
mouseDelta.setX( mousePos.x() - pimpl->startMousePos.x() );
mouseDelta.setY( mousePos.y() - pimpl->startMousePos.y() );
//
if (pimpl->cursorPosition != CursorPositionMiddle) {
// ... изменяем размер области обрезки
QRectF newGeometry =
calculateGeometry(
pimpl->lastStaticCroppingRect,
pimpl->cursorPosition,
mouseDelta);
// ... пользователь пытается вывернуть область обрезки наизнанку
if (!newGeometry.isNull()) {
pimpl->croppingRect = newGeometry;
}
} else {
// ... перемещаем область обрезки
pimpl->croppingRect.moveTo( pimpl->lastStaticCroppingRect.topLeft() + mouseDelta );
}
// Перерисуем виджет
update();
}
}
void ImageCropper::mouseReleaseEvent(QMouseEvent* _event)
{
pimpl->isMousePressed = false;
updateCursorIcon(_event->pos());
}
// ********
// Private section
namespace {
// Находится ли точка рядом с координатой стороны
static bool isPointNearSide (const int _sideCoordinate, const int _pointCoordinate)
{
static const int indent = 10;
return (_sideCoordinate - indent) < _pointCoordinate && _pointCoordinate < (_sideCoordinate + indent);
}
}
CursorPosition ImageCropper::cursorPosition(const QRectF& _cropRect, const QPointF& _mousePosition)
{
CursorPosition cursorPosition = CursorPositionUndefined;
//
if ( _cropRect.contains( _mousePosition ) ) {
// Двухстороннее направление
if (isPointNearSide(_cropRect.top(), _mousePosition.y()) &&
isPointNearSide(_cropRect.left(), _mousePosition.x())) {
cursorPosition = CursorPositionTopLeft;
} else if (isPointNearSide(_cropRect.bottom(), _mousePosition.y()) &&
isPointNearSide(_cropRect.left(), _mousePosition.x())) {
cursorPosition = CursorPositionBottomLeft;
} else if (isPointNearSide(_cropRect.top(), _mousePosition.y()) &&
isPointNearSide(_cropRect.right(), _mousePosition.x())) {
cursorPosition = CursorPositionTopRight;
} else if (isPointNearSide(_cropRect.bottom(), _mousePosition.y()) &&
isPointNearSide(_cropRect.right(), _mousePosition.x())) {
cursorPosition = CursorPositionBottomRight;
// Одностороннее направление
} else if (isPointNearSide(_cropRect.left(), _mousePosition.x())) {
cursorPosition = CursorPositionLeft;
} else if (isPointNearSide(_cropRect.right(), _mousePosition.x())) {
cursorPosition = CursorPositionRight;
} else if (isPointNearSide(_cropRect.top(), _mousePosition.y())) {
cursorPosition = CursorPositionTop;
} else if (isPointNearSide(_cropRect.bottom(), _mousePosition.y())) {
cursorPosition = CursorPositionBottom;
// Без направления
} else {
cursorPosition = CursorPositionMiddle;
}
}
//
return cursorPosition;
}
void ImageCropper::updateCursorIcon(const QPointF& _mousePosition)
{
QCursor cursorIcon;
//
switch (cursorPosition(pimpl->croppingRect, _mousePosition))
{
case CursorPositionTopRight:
case CursorPositionBottomLeft:
cursorIcon = QCursor(Qt::SizeBDiagCursor);
break;
case CursorPositionTopLeft:
case CursorPositionBottomRight:
cursorIcon = QCursor(Qt::SizeFDiagCursor);
break;
case CursorPositionTop:
case CursorPositionBottom:
cursorIcon = QCursor(Qt::SizeVerCursor);
break;
case CursorPositionLeft:
case CursorPositionRight:
cursorIcon = QCursor(Qt::SizeHorCursor);
break;
case CursorPositionMiddle:
cursorIcon = pimpl->isMousePressed ?
QCursor(Qt::ClosedHandCursor) :
QCursor(Qt::OpenHandCursor);
break;
case CursorPositionUndefined:
default:
cursorIcon = QCursor(Qt::ArrowCursor);
break;
}
//
this->setCursor(cursorIcon);
}
const QRectF ImageCropper::calculateGeometry(
const QRectF& _sourceGeometry,
const CursorPosition _cursorPosition,
const QPointF& _mouseDelta
)
{
QRectF resultGeometry;
//
if ( pimpl->isProportionFixed ) {
resultGeometry =
calculateGeometryWithFixedProportions(
_sourceGeometry, _cursorPosition, _mouseDelta, pimpl->deltas);
} else {
resultGeometry =
calculateGeometryWithCustomProportions(
_sourceGeometry, _cursorPosition, _mouseDelta);
}
// Если пользователь пытается вывернуть область обрезки наизнанку,
// возвращаем null-прямоугольник
if ((resultGeometry.left() >= resultGeometry.right()) ||
(resultGeometry.top() >= resultGeometry.bottom())) {
resultGeometry = QRect();
}
//
return resultGeometry;
}
const QRectF ImageCropper::calculateGeometryWithCustomProportions(
const QRectF& _sourceGeometry,
const CursorPosition _cursorPosition,
const QPointF& _mouseDelta
)
{
QRectF resultGeometry = _sourceGeometry;
//
switch ( _cursorPosition )
{
case CursorPositionTopLeft:
resultGeometry.setLeft( _sourceGeometry.left() + _mouseDelta.x() );
resultGeometry.setTop ( _sourceGeometry.top() + _mouseDelta.y() );
break;
case CursorPositionTopRight:
resultGeometry.setTop ( _sourceGeometry.top() + _mouseDelta.y() );
resultGeometry.setRight( _sourceGeometry.right() + _mouseDelta.x() );
break;
case CursorPositionBottomLeft:
resultGeometry.setBottom( _sourceGeometry.bottom() + _mouseDelta.y() );
resultGeometry.setLeft ( _sourceGeometry.left() + _mouseDelta.x() );
break;
case CursorPositionBottomRight:
resultGeometry.setBottom( _sourceGeometry.bottom() + _mouseDelta.y() );
resultGeometry.setRight ( _sourceGeometry.right() + _mouseDelta.x() );
break;
case CursorPositionTop:
resultGeometry.setTop( _sourceGeometry.top() + _mouseDelta.y() );
break;
case CursorPositionBottom:
resultGeometry.setBottom( _sourceGeometry.bottom() + _mouseDelta.y() );
break;
case CursorPositionLeft:
resultGeometry.setLeft( _sourceGeometry.left() + _mouseDelta.x() );
break;
case CursorPositionRight:
resultGeometry.setRight( _sourceGeometry.right() + _mouseDelta.x() );
break;
default:
break;
}
//
return resultGeometry;
}
const QRectF ImageCropper::calculateGeometryWithFixedProportions(
const QRectF& _sourceGeometry,
const CursorPosition _cursorPosition,
const QPointF& _mouseDelta,
const QSizeF& _deltas
)
{
QRectF resultGeometry = _sourceGeometry;
//
switch (_cursorPosition)
{
case CursorPositionLeft:
resultGeometry.setTop(_sourceGeometry.top() + _mouseDelta.x() * _deltas.height());
resultGeometry.setLeft(_sourceGeometry.left() + _mouseDelta.x());
break;
case CursorPositionRight:
resultGeometry.setTop(_sourceGeometry.top() - _mouseDelta.x() * _deltas.height());
resultGeometry.setRight(_sourceGeometry.right() + _mouseDelta.x());
break;
case CursorPositionTop:
resultGeometry.setTop(_sourceGeometry.top() + _mouseDelta.y());
resultGeometry.setRight(_sourceGeometry.right() - _mouseDelta.y() * _deltas.width());
break;
case CursorPositionBottom:
resultGeometry.setBottom(_sourceGeometry.bottom() + _mouseDelta.y());
resultGeometry.setRight(_sourceGeometry.right() + _mouseDelta.y() * _deltas.width());
break;
case CursorPositionTopLeft:
if ((_mouseDelta.x() * _deltas.height()) < (_mouseDelta.y())) {
resultGeometry.setTop(_sourceGeometry.top() + _mouseDelta.x() * _deltas.height());
resultGeometry.setLeft(_sourceGeometry.left() + _mouseDelta.x());
} else {
resultGeometry.setTop(_sourceGeometry.top() + _mouseDelta.y());
resultGeometry.setLeft(_sourceGeometry.left() + _mouseDelta.y() * _deltas.width());
}
break;
case CursorPositionTopRight:
if ((_mouseDelta.x() * _deltas.height() * -1) < (_mouseDelta.y())) {
resultGeometry.setTop(_sourceGeometry.top() - _mouseDelta.x() * _deltas.height());
resultGeometry.setRight(_sourceGeometry.right() + _mouseDelta.x() );
} else {
resultGeometry.setTop(_sourceGeometry.top() + _mouseDelta.y());
resultGeometry.setRight(_sourceGeometry.right() - _mouseDelta.y() * _deltas.width());
}
break;
case CursorPositionBottomLeft:
if ((_mouseDelta.x() * _deltas.height()) < (_mouseDelta.y() * -1)) {
resultGeometry.setBottom(_sourceGeometry.bottom() - _mouseDelta.x() * _deltas.height());
resultGeometry.setLeft(_sourceGeometry.left() + _mouseDelta.x());
} else {
resultGeometry.setBottom(_sourceGeometry.bottom() + _mouseDelta.y());
resultGeometry.setLeft(_sourceGeometry.left() - _mouseDelta.y() * _deltas.width());
}
break;
case CursorPositionBottomRight:
if ((_mouseDelta.x() * _deltas.height()) > (_mouseDelta.y())) {
resultGeometry.setBottom(_sourceGeometry.bottom() + _mouseDelta.x() * _deltas.height());
resultGeometry.setRight(_sourceGeometry.right() + _mouseDelta.x());
} else {
resultGeometry.setBottom(_sourceGeometry.bottom() + _mouseDelta.y());
resultGeometry.setRight(_sourceGeometry.right() + _mouseDelta.y() * _deltas.width());
}
break;
default:
break;
}
//
return resultGeometry;
}

View File

@ -1,103 +0,0 @@
/*****************************************************************************
* ImageCropper Qt Widget for cropping images
* Copyright (C) 2013 Dimka Novikov, to@dimkanovikov.pro
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*****************************************************************************/
#ifndef IMAGECROPPER_H
#define IMAGECROPPER_H
#include "imagecropper_p.h"
#include "imagecropper_e.h"
#include <QWidget>
class ImageCropper : public QWidget
{
Q_OBJECT
public:
ImageCropper(QWidget *parent = 0);
~ImageCropper();
public slots:
// Установить изображение для обрезки
void setImage(const QPixmap& _image);
// Установить цвет фона виджета обрезки
void setBackgroundColor(const QColor& _backgroundColor);
// Установить цвет рамки области обрезки
void setCroppingRectBorderColor(const QColor& _borderColor);
// Установить пропорции области выделения
void setProportion(const QSizeF& _proportion);
// Использовать фиксированные пропорции области виделения
void setProportionFixed(const bool _isFixed);
public:
// Обрезать изображение
const QPixmap cropImage();
protected:
virtual void paintEvent(QPaintEvent* _event);
virtual void mousePressEvent(QMouseEvent* _event);
virtual void mouseMoveEvent(QMouseEvent* _event);
virtual void mouseReleaseEvent(QMouseEvent* _event);
private:
// Определение местоположения курсора над виджетом
CursorPosition cursorPosition(const QRectF& _cropRect, const QPointF& _mousePosition);
// Обновить иконку курсора соответствующую местоположению мыши
void updateCursorIcon(const QPointF& _mousePosition);
// Получить размер виджета после его изменения мышью
// --------
// Контракты:
// 1. Метод должен вызываться, только при зажатой кнопке мыши
// (т.е. при перемещении или изменении размера виджета)
// --------
// В случае неудачи возвращает null-прямоугольник
const QRectF calculateGeometry(
const QRectF& _sourceGeometry,
const CursorPosition _cursorPosition,
const QPointF& _mouseDelta
);
// Получить размер виджета после его изменения мышью
// Метод изменяет виджет не сохраняя начальных пропорций сторон
// ------
// Контракты:
// 1. Метод должен вызываться, только при зажатой кнопке мыши
// (т.е. при перемещении или изменении размера виджета)
const QRectF calculateGeometryWithCustomProportions(
const QRectF& _sourceGeometry,
const CursorPosition _cursorPosition,
const QPointF& _mouseDelta
);
// Получить размер виджета после его изменения мышью
// Метод изменяет виджет сохраняя начальные пропорции сторон
// ------
// Контракты:
// 1. Метод должен вызываться, только при зажатой кнопке мыши
// (т.е. при перемещении или изменении размера виджета)
const QRectF calculateGeometryWithFixedProportions(const QRectF &_sourceGeometry,
const CursorPosition _cursorPosition,
const QPointF &_mouseDelta,
const QSizeF &_deltas
);
private:
// Private data implementation
ImageCropperPrivate* pimpl;
};
#endif // IMAGECROPPER_H

View File

@ -1,36 +0,0 @@
/*****************************************************************************
* ImageCropper Qt Widget for cropping images
* Copyright (C) 2013 Dimka Novikov, to@dimkanovikov.pro
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*****************************************************************************/
#ifndef IMAGECROPPER_E_H
#define IMAGECROPPER_E_H
enum CursorPosition
{
CursorPositionUndefined,
CursorPositionMiddle,
CursorPositionTop,
CursorPositionBottom,
CursorPositionLeft,
CursorPositionRight,
CursorPositionTopLeft,
CursorPositionTopRight,
CursorPositionBottomLeft,
CursorPositionBottomRight
};
#endif // IMAGECROPPER_E_H

View File

@ -1,76 +0,0 @@
/*****************************************************************************
* ImageCropper Qt Widget for cropping images
* Copyright (C) 2013 Dimka Novikov, to@dimkanovikov.pro
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*****************************************************************************/
#ifndef IMAGECROPPER_P_H
#define IMAGECROPPER_P_H
#include "imagecropper_e.h"
#include <QtCore/QRect>
#include <QtGui/QPixmap>
#include <QtGui/QColor>
namespace {
const QRect INIT_CROPPING_RECT = QRect();
const QSizeF INIT_PROPORTION = QSizeF(1.0, 1.0);
}
class ImageCropperPrivate {
public:
ImageCropperPrivate() :
imageForCropping(QPixmap()),
croppingRect(INIT_CROPPING_RECT),
lastStaticCroppingRect(QRect()),
cursorPosition(CursorPositionUndefined),
isMousePressed(false),
isProportionFixed(false),
startMousePos(QPoint()),
proportion(INIT_PROPORTION),
deltas(INIT_PROPORTION),
backgroundColor(Qt::black),
croppingRectBorderColor(Qt::white)
{}
public:
// Изображение для обрезки
QPixmap imageForCropping;
// Область обрезки
QRectF croppingRect;
// Последняя фиксированная область обрезки
QRectF lastStaticCroppingRect;
// Позиция курсора относительно области обрезки
CursorPosition cursorPosition;
// Зажата ли левая кнопка мыши
bool isMousePressed;
// Фиксировать пропорции области обрезки
bool isProportionFixed;
// Начальная позиция курсора при изменении размера области обрезки
QPointF startMousePos;
// Пропорции
QSizeF proportion;
// Приращения
// width - приращение по x
// height - приращение по y
QSizeF deltas;
// Цвет заливки фона под изображением
QColor backgroundColor;
// Цвет рамки области обрезки
QColor croppingRectBorderColor;
};
#endif // IMAGECROPPER_P_H

View File

@ -1,285 +0,0 @@
#/*****************************************************************************
#* gta5view Grand Theft Auto V Profile Viewer
#* Copyright (C) 2015-2021 Syping
#*
#* This program is free software: you can redistribute it and/or modify
#* it under the terms of the GNU General Public License as published by
#* the Free Software Foundation, either version 3 of the License, or
#* (at your option) any later version.
#*
#* This program is distributed in the hope that it will be useful,
#* but WITHOUT ANY WARRANTY; without even the implied warranty of
#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
#* GNU General Public License for more details.
#*
#* You should have received a copy of the GNU General Public License
#* along with this program. If not, see <http://www.gnu.org/licenses/>.
#*****************************************************************************/
QT += core gui network svg
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
greaterThan(QT_MAJOR_VERSION, 4): win32: LIBS += -ldwmapi
DEPLOYMENT.display_name = gta5view
TARGET = gta5view
TEMPLATE = app
HEADERS += config.h \
wrapper.h
PRECOMPILED_HEADER += config.h
SOURCES += main.cpp \
AboutDialog.cpp \
AppEnv.cpp \
CrewDatabase.cpp \
DatabaseThread.cpp \
ExportDialog.cpp \
ExportThread.cpp \
GlobalString.cpp \
IconLoader.cpp \
ImportDialog.cpp \
JsonEditorDialog.cpp \
MapLocationDialog.cpp \
MessageThread.cpp \
OptionsDialog.cpp \
PictureDialog.cpp \
PictureExport.cpp \
PictureWidget.cpp \
PlayerListDialog.cpp \
ProfileDatabase.cpp \
ProfileInterface.cpp \
ProfileLoader.cpp \
ProfileWidget.cpp \
RagePhoto.cpp \
SavegameCopy.cpp \
SavegameData.cpp \
SavegameDialog.cpp \
SavegameWidget.cpp \
SidebarGenerator.cpp \
SnapmaticEditor.cpp \
SnapmaticPicture.cpp \
SnapmaticWidget.cpp \
StandardPaths.cpp \
StringParser.cpp \
TelemetryClass.cpp \
TranslationClass.cpp \
UserInterface.cpp \
anpro/imagecropper.cpp \
pcg/pcg_basic.c \
tmext/TelemetryClassAuthenticator.cpp \
uimod/JSHighlighter.cpp \
uimod/UiModLabel.cpp \
uimod/UiModWidget.cpp
HEADERS += \
AboutDialog.h \
AppEnv.h \
CrewDatabase.h \
DatabaseThread.h \
ExportDialog.h \
ExportThread.h \
GlobalString.h \
IconLoader.h \
ImportDialog.h \
JsonEditorDialog.h \
MapLocationDialog.h \
MessageThread.h \
OptionsDialog.h \
PictureDialog.h \
PictureExport.h \
PictureWidget.h \
PlayerListDialog.h \
ProfileDatabase.h \
ProfileInterface.h \
ProfileLoader.h \
ProfileWidget.h \
RagePhoto.h \
SavegameCopy.h \
SavegameData.h \
SavegameDialog.h \
SavegameWidget.h \
SidebarGenerator.h \
SnapmaticEditor.h \
SnapmaticPicture.h \
SnapmaticWidget.h \
StandardPaths.h \
StringParser.h \
TelemetryClass.h \
TranslationClass.h \
UserInterface.h \
anpro/imagecropper.h \
anpro/imagecropper_e.h \
anpro/imagecropper_p.h \
pcg/pcg_basic.h \
tmext/TelemetryClassAuthenticator.h \
uimod/JSHighlighter.h \
uimod/UiModLabel.h \
uimod/UiModWidget.h
FORMS += \
AboutDialog.ui \
ExportDialog.ui \
ImportDialog.ui \
JsonEditorDialog.ui \
MapLocationDialog.ui \
OptionsDialog.ui \
PictureDialog.ui \
PlayerListDialog.ui \
ProfileInterface.ui \
SavegameDialog.ui \
SavegameWidget.ui \
SnapmaticEditor.ui \
SnapmaticWidget.ui \
UserInterface.ui
TRANSLATIONS += \
res/gta5sync.ts \
res/gta5sync_de.ts \
res/gta5sync_en_US.ts \
res/gta5sync_fr.ts \
res/gta5sync_ko.ts \
res/gta5sync_ru.ts \
res/gta5sync_uk.ts \
res/gta5sync_zh_TW.ts
RESOURCES += \
res/img.qrc \
res/template.qrc \
res/tr_g5p.qrc
DISTFILES += \
res/gta5view-16.png \
res/gta5view-24.png \
res/gta5view-32.png \
res/gta5view-40.png \
res/gta5view-48.png \
res/gta5view-64.png \
res/gta5view-96.png \
res/gta5view-128.png \
res/gta5view-256.png \
res/gta5view-512.png \
res/app.rc \
res/de.syping.gta5view.desktop \
res/de.syping.gta5view.png \
res/gta5sync_de.ts \
res/gta5sync_en_US.ts \
res/gta5sync_fr.ts \
res/gta5sync_ko.ts \
res/gta5sync_ru.ts \
res/gta5sync_uk.ts \
res/gta5sync_zh_TW.ts \
res/gta5view.exe.manifest \
res/gta5view.png \
lang/README.txt
INCLUDEPATH += ./anpro ./pcg ./tmext ./uimod
# GTA5SYNC/GTA5VIEW ONLY
DEFINES += GTA5SYNC_QMAKE # We using qmake do we?
DEFINES += GTA5SYNC_PROJECT # Enable exclusive gta5sync/gta5view functions
# WINDOWS ONLY
win32: RC_FILE += res/app.rc
win32: CONFIG -= embed_manifest_exe
contains(DEFINES, GTA5SYNC_TELEMETRY): win32: LIBS += -ld3d9 # Required for getting information about GPU
# MAC OS X ONLY
macx: ICON = res/gta5view.icns
# QT4 ONLY STUFF
isEqual(QT_MAJOR_VERSION, 4): INCLUDEPATH += ./qjson4
isEqual(QT_MAJOR_VERSION, 4): HEADERS += qjson4/QJsonArray.h \
qjson4/QJsonDocument.h \
qjson4/QJsonObject.h \
qjson4/QJsonParseError.h \
qjson4/QJsonValue.h \
qjson4/QJsonValueRef.h \
qjson4/QJsonParser.h \
qjson4/QJsonRoot.h
isEqual(QT_MAJOR_VERSION, 4): SOURCES += qjson4/QJsonArray.cpp \
qjson4/QJsonDocument.cpp \
qjson4/QJsonObject.cpp \
qjson4/QJsonParseError.cpp \
qjson4/QJsonValue.cpp \
qjson4/QJsonValueRef.cpp \
qjson4/QJsonParser.cpp
isEqual(QT_MAJOR_VERSION, 4): RESOURCES += res/qt4/tr_qt.qrc
isEqual(QT_MAJOR_VERSION, 4): GTA5SYNC_RCC = $$[QT_INSTALL_BINS]/rcc
# QT5 ONLY STUFF
isEqual(QT_MAJOR_VERSION, 5): RESOURCES += res/qt5/tr_qt.qrc
# QT5+ ONLY STUFF
greaterThan(QT_MAJOR_VERSION, 4): GTA5SYNC_RCC = $$[QT_HOST_BINS]/rcc
# QT6 ONLY STUFF
isEqual(QT_MAJOR_VERSION, 6): RESOURCES += res/qt6/tr_qt.qrc
# RESOURCE COMPILATION
system($$GTA5SYNC_RCC -threshold 0 -compress 9 $$PWD/res/global.qrc -o $$OUT_PWD/qrc_global.cpp) {
SOURCES += $$OUT_PWD/qrc_global.cpp
} else {
message("Failed to generate qrc_global.cpp")
}
# PROJECT INSTALLATION
isEmpty(GTA5SYNC_PREFIX): GTA5SYNC_PREFIX = /usr/local
appfiles.path = $$GTA5SYNC_PREFIX/share/applications
appfiles.files = $$PWD/res/de.syping.gta5view.desktop
pixmaps.path = $$GTA5SYNC_PREFIX/share/pixmaps
pixmaps.files = $$PWD/res/de.syping.gta5view.png
target.path = $$GTA5SYNC_PREFIX/bin
INSTALLS += target pixmaps appfiles
# QCONF BASED BUILD STUFF
contains(DEFINES, GTA5SYNC_QCONF) {
isEqual(QT_MAJOR_VERSION, 4): RESOURCES -= res/qt4/tr_qt.qrc
isEqual(QT_MAJOR_VERSION, 5): RESOURCES -= res/qt5/tr_qt.qrc
isEqual(QT_MAJOR_VERSION, 6): RESOURCES -= res/qt6/tr_qt.qrc
!contains(DEFINES, GTA5SYNC_QCONF_IN) {
RESOURCES -= res/tr_g5p.qrc
langfiles.path = $$GTA5SYNC_PREFIX/share/gta5view/translations
langfiles.files = $$PWD/res/gta5sync_en_US.qm $$PWD/res/gta5sync_de.qm $$PWD/res/gta5sync_fr.qm $$PWD/res/gta5sync_ko.qm $$PWD/res/gta5sync_ru.qm $$PWD/res/gta5sync_uk.qm $$PWD/res/gta5sync_zh_TW.qm $$PWD/res/qtbase_en_GB.qm
INSTALLS += langfiles
}
}
# TELEMETRY BASED STUFF
!contains(DEFINES, GTA5SYNC_TELEMETRY) {
SOURCES -= TelemetryClass.cpp \
tmext/TelemetryClassAuthenticator.cpp
HEADERS -= TelemetryClass.h \
tmext/TelemetryClassAuthenticator.h
}
!contains(DEFINES, GTA5SYNC_MOTD) {
SOURCES -= MessageThread.cpp
HEADERS -= MessageThread.h
} else {
lessThan(QT_MAJOR_VERSION, 5) {
SOURCES -= MessageThread.cpp
HEADERS -= MessageThread.h
DEFINES -= GTA5SYNC_MOTD
message("Messages require Qt5 or newer!")
}
}
# CMAKE BASED STUFF
greaterThan(QT_MAJOR_VERSION, 4) {
message("Building gta5view with QMake is deprecated, please use CMake instead!")
}

View File

@ -1,5 +0,0 @@
Community translation files
They get loaded in ApplicationPathExecFileFolder/lang
You can help translate with using Qt Linguist, after you've translated you'll need to send me a pull request on https://github.com/SyDevTeam/gta5view

View File

@ -1 +0,0 @@
#include "QJsonArray.h"

View File

@ -1,410 +0,0 @@
/*****************************************************************************
* gta5view Grand Theft Auto V Profile Viewer
* Copyright (C) 2016 Syping
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*****************************************************************************/
#include "QJsonArray.h"
#include "QJsonValueRef.h"
#include "QJsonValue.h"
#include <QtCore/QStringList>
#if QT_VERSION < 0x050000
//------------------------------------------------------------------------------
// Name: QJsonArray
// Desc: default constructor
//------------------------------------------------------------------------------
QJsonArray::QJsonArray() {
}
//------------------------------------------------------------------------------
// Name: QJsonArray
// Desc: copy constructor
//------------------------------------------------------------------------------
QJsonArray::QJsonArray(const QJsonArray &other) : values_(other.values_) {
}
#if __cplusplus >= 201103L
//------------------------------------------------------------------------------
// Name: QJsonArray
// Desc: Creates an array initialized from args initialization list.
//------------------------------------------------------------------------------
QJsonArray::QJsonArray(std::initializer_list<QJsonValue> args) {
for(const QJsonValue &arg : args) {
values_.append(arg);
}
}
#endif
//------------------------------------------------------------------------------
// Name: ~QJsonArray
// Desc: destructor
//------------------------------------------------------------------------------
QJsonArray::~QJsonArray() {
}
//------------------------------------------------------------------------------
// Name: operator=
// Desc: assignment operator
//------------------------------------------------------------------------------
QJsonArray &QJsonArray::operator=(const QJsonArray &other) {
QJsonArray(other).swap(*this);
return *this;
}
//------------------------------------------------------------------------------
// Name: operator+=
// Desc:
//------------------------------------------------------------------------------
QJsonArray &QJsonArray::operator+=(const QJsonValue &value) {
values_.append(value);
return *this;
}
//------------------------------------------------------------------------------
// Name: operator<<
// Desc:
//------------------------------------------------------------------------------
QJsonArray &QJsonArray::operator<<(const QJsonValue &value) {
values_.append(value);
return *this;
}
//------------------------------------------------------------------------------
// Name: operator+
// Desc:
//------------------------------------------------------------------------------
QJsonArray QJsonArray::operator+(const QJsonValue &value) const {
QJsonArray arr(*this);
arr.append(value);
return arr;
}
//------------------------------------------------------------------------------
// Name: operator!=
// Desc: returns true if the compared array IS NOT equal to this
//------------------------------------------------------------------------------
bool QJsonArray::operator!=(const QJsonArray &other) const {
return values_ != other.values_;
}
//------------------------------------------------------------------------------
// Name: operator==
// Desc: returns true if the compared array IS equal to this
//------------------------------------------------------------------------------
bool QJsonArray::operator==(const QJsonArray &other) const {
return values_ == other.values_;
}
//------------------------------------------------------------------------------
// Name: begin
// Desc: returns an iterator to the first contained element
//------------------------------------------------------------------------------
QJsonArray::const_iterator QJsonArray::begin() const {
return values_.begin();
}
//------------------------------------------------------------------------------
// Name: end
// Desc: returns an iterator to one past the last contained element
//------------------------------------------------------------------------------
QJsonArray::const_iterator QJsonArray::end() const {
return values_.end();
}
//------------------------------------------------------------------------------
// Name: begin
// Desc: returns an iterator to the first contained element
//------------------------------------------------------------------------------
QJsonArray::iterator QJsonArray::begin() {
return values_.begin();
}
//------------------------------------------------------------------------------
// Name: end
// Desc: returns an iterator to one past the last contained element
//------------------------------------------------------------------------------
QJsonArray::iterator QJsonArray::end() {
return values_.end();
}
//------------------------------------------------------------------------------
// Name: constBegin
// Desc: returns an iterator to the first contained element
//------------------------------------------------------------------------------
QJsonArray::const_iterator QJsonArray::constBegin() const {
return begin();
}
//------------------------------------------------------------------------------
// Name: constEnd
// Desc: returns an iterator to one past the last contained element
//------------------------------------------------------------------------------
QJsonArray::const_iterator QJsonArray::constEnd() const {
return end();
}
//------------------------------------------------------------------------------
// Name: first
// Desc: returns the first element by value
//------------------------------------------------------------------------------
QJsonValue QJsonArray::first() const {
Q_ASSERT(!empty());
return values_.first();
}
//------------------------------------------------------------------------------
// Name: last
// Desc: returns the last element by value
//------------------------------------------------------------------------------
QJsonValue QJsonArray::last() const {
Q_ASSERT(!empty());
return values_.last();
}
//------------------------------------------------------------------------------
// Name: operator[]
//------------------------------------------------------------------------------
QJsonValueRef QJsonArray::operator[](int i) {
return QJsonValueRef(this, i);
}
//------------------------------------------------------------------------------
// Name: operator[]
//------------------------------------------------------------------------------
QJsonValue QJsonArray::operator[](int i) const {
return values_[i];
}
//------------------------------------------------------------------------------
// Name: at
//------------------------------------------------------------------------------
QJsonValue QJsonArray::at(int i) const {
return values_.at(i);
}
//------------------------------------------------------------------------------
// Name: size
//------------------------------------------------------------------------------
int QJsonArray::size() const {
return values_.size();
}
//------------------------------------------------------------------------------
// Name: count
//------------------------------------------------------------------------------
int QJsonArray::count() const {
return size();
}
//------------------------------------------------------------------------------
// Name: empty
//------------------------------------------------------------------------------
bool QJsonArray::empty() const {
return values_.empty();
}
//------------------------------------------------------------------------------
// Name: isEmpty
//------------------------------------------------------------------------------
bool QJsonArray::isEmpty() const {
return empty();
}
//------------------------------------------------------------------------------
// Name: pop_back
//------------------------------------------------------------------------------
void QJsonArray::pop_back() {
values_.pop_back();
}
//------------------------------------------------------------------------------
// Name: pop_front
//------------------------------------------------------------------------------
void QJsonArray::pop_front() {
values_.pop_front();
}
//------------------------------------------------------------------------------
// Name: push_back
//------------------------------------------------------------------------------
void QJsonArray::push_back(const QJsonValue &value) {
values_.push_back(value);
}
//------------------------------------------------------------------------------
// Name: push_front
//------------------------------------------------------------------------------
void QJsonArray::push_front(const QJsonValue &value) {
values_.push_front(value);
}
//------------------------------------------------------------------------------
// Name:
//------------------------------------------------------------------------------
void QJsonArray::append(const QJsonValue &value) {
values_.append(value);
}
//------------------------------------------------------------------------------
// Name:
//------------------------------------------------------------------------------
bool QJsonArray::contains(const QJsonValue &value) const {
return values_.contains(value);
}
//------------------------------------------------------------------------------
// Name:
//------------------------------------------------------------------------------
QJsonArray::iterator QJsonArray::erase(iterator it) {
return values_.erase(it);
}
//------------------------------------------------------------------------------
// Name:
//------------------------------------------------------------------------------
void QJsonArray::insert(int i, const QJsonValue &value) {
values_.insert(i, value);
}
//------------------------------------------------------------------------------
// Name:
//------------------------------------------------------------------------------
QJsonArray::iterator QJsonArray::insert(iterator before, const QJsonValue &value) {
return values_.insert(before, value);
}
//------------------------------------------------------------------------------
// Name:
//------------------------------------------------------------------------------
void QJsonArray::prepend(const QJsonValue &value) {
values_.prepend(value);
}
//------------------------------------------------------------------------------
// Name:
//------------------------------------------------------------------------------
void QJsonArray::removeAt(int i) {
values_.removeAt(i);
}
//------------------------------------------------------------------------------
// Name:
//------------------------------------------------------------------------------
void QJsonArray::removeFirst() {
values_.removeFirst();
}
//------------------------------------------------------------------------------
// Name:
//------------------------------------------------------------------------------
void QJsonArray::removeLast() {
values_.removeLast();
}
//------------------------------------------------------------------------------
// Name:
//------------------------------------------------------------------------------
void QJsonArray::replace(int i, const QJsonValue &value) {
values_.replace(i, value);
}
//------------------------------------------------------------------------------
// Name:
//------------------------------------------------------------------------------
QJsonValue QJsonArray::takeAt(int i) {
return values_.takeAt(i);
}
//------------------------------------------------------------------------------
// Name: toVariantList
//------------------------------------------------------------------------------
QVariantList QJsonArray::toVariantList() const {
QVariantList a;
Q_FOREACH(const QJsonValue &v, *this) {
a.push_back(v.toVariant());
}
return a;
}
//------------------------------------------------------------------------------
// Name:
//------------------------------------------------------------------------------
QJsonArray QJsonArray::fromStringList(const QStringList &list) {
QJsonArray a;
Q_FOREACH(const QString &s, list) {
a.push_back(QJsonValue(s));
}
return a;
}
//------------------------------------------------------------------------------
// Name:
//------------------------------------------------------------------------------
QJsonArray QJsonArray::fromVariantList(const QVariantList &list) {
QJsonArray a;
Q_FOREACH(const QVariant &v, list) {
a.push_back(QJsonValue::fromVariant(v));
}
return a;
}
//------------------------------------------------------------------------------
// Name:
//------------------------------------------------------------------------------
QJsonRoot *QJsonArray::clone() const {
return new QJsonArray(*this);
}
//------------------------------------------------------------------------------
// Name:
//------------------------------------------------------------------------------
const QJsonObject *QJsonArray::toObject() const {
return 0;
}
//------------------------------------------------------------------------------
// Name:
//------------------------------------------------------------------------------
QJsonObject *QJsonArray::toObject() {
return 0;
}
//------------------------------------------------------------------------------
// Name:
//------------------------------------------------------------------------------
QJsonArray *QJsonArray::toArray() {
return this;
}
//------------------------------------------------------------------------------
// Name:
//------------------------------------------------------------------------------
const QJsonArray *QJsonArray::toArray() const {
return this;
}
//------------------------------------------------------------------------------
// Name:
//------------------------------------------------------------------------------
void QJsonArray::swap(QJsonArray &other) {
qSwap(values_, other.values_);
}
#endif

View File

@ -1,139 +0,0 @@
/*****************************************************************************
* gta5view Grand Theft Auto V Profile Viewer
* Copyright (C) 2016 Syping
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*****************************************************************************/
#ifndef QJSON_ARRAY_H_
#define QJSON_ARRAY_H_
#include <QtCore/QtGlobal>
#if QT_VERSION >= 0x050000
#include <QtCore/QJsonArray>
#else
#include "QJsonRoot.h"
#include <QtCore/QList>
#include <QtCore/QVariantList>
class QJsonValue;
class QJsonValueRef;
class QJsonArray : public QJsonRoot {
friend class QJsonDocument;
friend class QJsonValue;
friend class QJsonValueRef;
friend class QJsonParser;
public:
// TODO(eteran): manually implement the array, for now we use QList
// but the real thing has a custom implementation
// I guess for the purposes of less interdependancies?
// maybe so it's easier to forward declare the iterators?
typedef QList<QJsonValue>::const_iterator const_iterator;
typedef QList<QJsonValue>::iterator iterator;
typedef const_iterator ConstIterator;
typedef iterator Iterator;
typedef QList<QJsonValue>::const_pointer const_pointer;
typedef QList<QJsonValue>::const_reference const_reference;
typedef QList<QJsonValue>::difference_type difference_type;
typedef QList<QJsonValue>::pointer pointer;
typedef QList<QJsonValue>::reference reference;
typedef QList<QJsonValue>::size_type size_type;
typedef QList<QJsonValue>::value_type value_type;
public:
QJsonArray();
QJsonArray(const QJsonArray &other);
#if __cplusplus >= 201103L
QJsonArray(std::initializer_list<QJsonValue> args);
#endif
~QJsonArray();
public:
QJsonArray &operator=(const QJsonArray &other);
public:
bool operator!=(const QJsonArray &other) const;
bool operator==(const QJsonArray &other) const;
QJsonArray operator+(const QJsonValue &value) const;
QJsonArray &operator+=(const QJsonValue &value);
QJsonArray &operator<<(const QJsonValue &value);
public:
const_iterator begin() const;
const_iterator end() const;
iterator begin();
iterator end();
const_iterator constBegin() const;
const_iterator constEnd() const;
public:
QJsonValueRef operator[](int i);
QJsonValue operator[](int i) const;
QJsonValue at(int i) const;
QJsonValue first() const;
QJsonValue last() const;
public:
int size() const;
int count() const;
bool empty() const;
bool isEmpty() const;
public:
void pop_back();
void pop_front();
void push_back(const QJsonValue &value);
void push_front(const QJsonValue &value);
public:
void append(const QJsonValue &value);
bool contains(const QJsonValue &value) const;
iterator erase(iterator it);
void insert(int i, const QJsonValue &value);
iterator insert(iterator before, const QJsonValue &value);
void prepend(const QJsonValue &value);
void removeAt(int i);
void removeFirst();
void removeLast();
void replace(int i, const QJsonValue &value);
QJsonValue takeAt(int i);
public:
QVariantList toVariantList() const;
public:
static QJsonArray fromStringList(const QStringList &list);
static QJsonArray fromVariantList(const QVariantList &list);
private:
virtual QJsonRoot *clone() const;
virtual QJsonArray *toArray();
virtual QJsonObject *toObject();
virtual const QJsonArray *toArray() const;
virtual const QJsonObject *toObject() const;
private:
void swap(QJsonArray &other);
private:
QList<QJsonValue> values_;
};
#endif
#endif

View File

@ -1 +0,0 @@
#include "QJsonDocument.h"

View File

@ -1,424 +0,0 @@
/*****************************************************************************
* gta5view Grand Theft Auto V Profile Viewer
* Copyright (C) 2016 Syping
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*****************************************************************************/
#include "QJsonDocument.h"
#include "QJsonObject.h"
#include "QJsonArray.h"
#include "QJsonParser.h"
#include <QtCore/QStringList>
#include <QtCore/QByteArray>
#include <QtCore/QTextStream>
#include <QtCore/QTextCodec>
#include <QtCore/QtCore>
#if QT_VERSION < 0x050000
//------------------------------------------------------------------------------
// Name: QJsonDocument
//------------------------------------------------------------------------------
QJsonDocument::QJsonDocument() : root_(0) {
}
//------------------------------------------------------------------------------
// Name: QJsonDocument
//------------------------------------------------------------------------------
QJsonDocument::QJsonDocument(const QJsonObject &object) : root_(0) {
setObject(object);
}
//------------------------------------------------------------------------------
// Name: QJsonDocument
//------------------------------------------------------------------------------
QJsonDocument::QJsonDocument(const QJsonArray &array) : root_(0) {
setArray(array);
}
//------------------------------------------------------------------------------
// Name: QJsonDocument
//------------------------------------------------------------------------------
QJsonDocument::QJsonDocument(const QJsonDocument &other) : root_(0) {
if(other.root_) {
root_ = other.root_->clone();
}
}
//------------------------------------------------------------------------------
// Name: ~QJsonDocument
//------------------------------------------------------------------------------
QJsonDocument::~QJsonDocument() {
delete root_;
}
//------------------------------------------------------------------------------
// Name: operator=
//------------------------------------------------------------------------------
QJsonDocument &QJsonDocument::operator=(const QJsonDocument &other) {
QJsonDocument(other).swap(*this);
return *this;
}
//------------------------------------------------------------------------------
// Name: operator!=
//------------------------------------------------------------------------------
bool QJsonDocument::operator!=(const QJsonDocument &other) const {
return !(*this == other);
}
//------------------------------------------------------------------------------
// Name: operator==
//------------------------------------------------------------------------------
bool QJsonDocument::operator==(const QJsonDocument &other) const {
if(isArray() && other.isArray()) {
return array() == other.array();
}
if(isObject() && other.isObject()) {
return object() == other.object();
}
if(isEmpty() && other.isEmpty()) {
return true;
}
if(isNull() && other.isNull()) {
return true;
}
return false;
}
//------------------------------------------------------------------------------
// Name: isArray
//------------------------------------------------------------------------------
bool QJsonDocument::isArray() const {
return root_ && root_->toArray();
}
//------------------------------------------------------------------------------
// Name: isEmpty
//------------------------------------------------------------------------------
bool QJsonDocument::isEmpty() const {
// TODO(eteran): figure out the rules here that Qt5 uses
// it *looks* like they define empty as being NULL
// which is obviously different than this
return !root_;
}
//------------------------------------------------------------------------------
// Name: isNull
//------------------------------------------------------------------------------
bool QJsonDocument::isNull() const {
return !root_;
}
//------------------------------------------------------------------------------
// Name: isObject
//------------------------------------------------------------------------------
bool QJsonDocument::isObject() const {
return root_ && root_->toObject();
}
//------------------------------------------------------------------------------
// Name: setArray
//------------------------------------------------------------------------------
void QJsonDocument::setArray(const QJsonArray &array) {
setRoot(array);
}
//------------------------------------------------------------------------------
// Name: setObject
//------------------------------------------------------------------------------
void QJsonDocument::setObject(const QJsonObject &object) {
setRoot(object);
}
//------------------------------------------------------------------------------
// Name: setRoot
//------------------------------------------------------------------------------
void QJsonDocument::setRoot(const QJsonRoot &root) {
delete root_;
root_ = root.clone();
}
//------------------------------------------------------------------------------
// Name: toBinaryData
//------------------------------------------------------------------------------
QByteArray QJsonDocument::toBinaryData() const {
QByteArray r;
// TODO(eteran): implement this
return r;
}
//------------------------------------------------------------------------------
// Name: escapeString
//------------------------------------------------------------------------------
QString QJsonDocument::escapeString(const QString &s) const {
QString r;
Q_FOREACH(QChar ch, s) {
switch(ch.toLatin1()) {
case '\"': r.append("\\\""); break;
case '\\': r.append("\\\\"); break;
#if 0
case '/': r.append("\\/"); break;
#endif
case '\b': r.append("\\b"); break;
case '\f': r.append("\\f"); break;
case '\n': r.append("\\n"); break;
case '\r': r.append("\\r"); break;
case '\t': r.append("\\t"); break;
default:
r += ch;
break;
}
}
return r;
}
//------------------------------------------------------------------------------
// Name: toJson
//------------------------------------------------------------------------------
QString QJsonDocument::toJson(const QJsonValue &v, JsonFormat format, int indent) const {
QString b;
QTextStream ss(&b, QIODevice::WriteOnly | QIODevice::Text);
bool compact = (format == JsonFormat::Compact);
switch(v.type()) {
case QJsonValue::Null:
ss << "null";
break;
case QJsonValue::Bool:
ss << (v.toBool() ? "true" : "false");
break;
case QJsonValue::Double:
{
double d = v.toDouble ();
if (qIsFinite(d)) {
// +2 to format to ensure the expected precision
ss << QByteArray::number(d, 'g', 15 + 2); // ::digits10 is 15
} else {
ss << "null"; // +INF || -INF || NaN (see RFC4627#section2.4)
}
}
break;
case QJsonValue::String:
ss << '"' << escapeString(v.toString()) << '"';
break;
case QJsonValue::Array:
{
const QJsonArray a = v.toArray();
ss << (compact ? "[" : "[\n");
if(!a.empty()) {
QJsonArray::const_iterator it = a.begin();
QJsonArray::const_iterator e = a.end();
if (!compact) ss << QByteArray(4*indent, ' ');
ss << toJson(*it++, format, indent+1);
for(;it != e; ++it) {
ss << (compact ? "," : ",\n");
if (!compact) ss << QByteArray(4*indent, ' ');
ss << toJson(*it, format, indent+1);
}
}
indent--;
ss << (compact ? "]" : QString("\n%1]").arg(QString(4*indent, ' ')));
}
break;
case QJsonValue::Object:
{
const QJsonObject o = v.toObject();
ss << (compact ? "{" : "{\n");
if(!o.empty()) {
QJsonObject::const_iterator it = o.begin();
QJsonObject::const_iterator e = o.end();
if (!compact) ss << QByteArray(4*indent, ' ');
ss << '"' << escapeString(it.key()) << (compact ? "\":" : "\": ") << toJson(it.value(), format, indent+1);
++it;
for(;it != e; ++it) {
ss << (compact ? "," : ",\n");
if (!compact) ss << QByteArray(4*indent, ' ');
ss << '"' << escapeString(it.key()) << (compact ? "\":" : "\": ") << toJson(it.value(), format, indent+1);
}
}
indent--;
ss << (compact ? "}" : QString("\n%1}").arg(QString(4*indent, ' ')));
}
break;
case QJsonValue::Undefined:
Q_ASSERT(0);
break;
}
return b;
}
//------------------------------------------------------------------------------
// Name: toJson
//------------------------------------------------------------------------------
QByteArray QJsonDocument::toJson(JsonFormat format) const {
Q_UNUSED(format);
if(isArray()) {
QString s = toJson(array(), format);
return s.toUtf8();
}
if(isObject()) {
QString s = toJson(object(), format);
return s.toUtf8();
}
return QByteArray();
}
//------------------------------------------------------------------------------
// Name: toVariant
//------------------------------------------------------------------------------
QVariant QJsonDocument::toVariant() const {
if(!isEmpty()) {
if(QJsonObject *const object = root_->toObject()) {
return object->toVariantMap();
}
if(QJsonArray *const array = root_->toArray()) {
return array->toVariantList();
}
}
return QVariant();
}
//------------------------------------------------------------------------------
// Name: array
//------------------------------------------------------------------------------
QJsonArray QJsonDocument::array() const {
if(!isEmpty()) {
if(QJsonArray *const array = root_->toArray()) {
return *array;
}
}
return QJsonArray();
}
//------------------------------------------------------------------------------
// Name: object
//------------------------------------------------------------------------------
QJsonObject QJsonDocument::object() const {
if(!isEmpty()) {
if(QJsonObject *const object = root_->toObject()) {
return *object;
}
}
return QJsonObject();
}
//------------------------------------------------------------------------------
// Name: rawData
//------------------------------------------------------------------------------
const char *QJsonDocument::rawData(int *size) const {
Q_UNUSED(size);
// TODO(eteran): implement this
return 0;
}
//------------------------------------------------------------------------------
// Name: fromBinaryData
//------------------------------------------------------------------------------
QJsonDocument QJsonDocument::fromBinaryData(const QByteArray &data, DataValidation validation) {
Q_UNUSED(data);
Q_UNUSED(validation);
QJsonDocument doc;
// TODO(eteran): implement this
return doc;
}
//------------------------------------------------------------------------------
// Name: fromJson
//------------------------------------------------------------------------------
QJsonDocument QJsonDocument::fromJson(const QByteArray &json, QJsonParseError *error) {
QJsonDocument doc;
const char *const begin = json.constData();
const char *const end = begin + json.size();
QJsonParser parser(begin, end);
doc.root_ = parser.parse();
if(error) {
*error = parser.state();
}
return doc;
}
//------------------------------------------------------------------------------
// Name: fromRawData
//------------------------------------------------------------------------------
QJsonDocument QJsonDocument::fromRawData(const char *data, int size, DataValidation validation) {
// data has to be aligned to a 4 byte boundary.
Q_ASSERT(!(reinterpret_cast<quintptr>(data) % 3));
return fromBinaryData(QByteArray::fromRawData(data, size), validation);
}
//------------------------------------------------------------------------------
// Name: fromVariant
//------------------------------------------------------------------------------
QJsonDocument QJsonDocument::fromVariant(const QVariant &variant) {
QJsonDocument doc;
if (variant.type() == QVariant::Map) {
doc.setObject(QJsonObject::fromVariantMap(variant.toMap()));
} else if (variant.type() == QVariant::Hash) {
doc.setObject(QJsonObject::fromVariantHash(variant.toHash()));
} else if (variant.type() == QVariant::List) {
doc.setArray(QJsonArray::fromVariantList(variant.toList()));
} else if (variant.type() == QVariant::StringList) {
doc.setArray(QJsonArray::fromStringList(variant.toStringList()));
}
return doc;
}
//------------------------------------------------------------------------------
// Name: swap
//------------------------------------------------------------------------------
void QJsonDocument::swap(QJsonDocument &other) {
qSwap(root_, other.root_);
}
#endif

View File

@ -1,103 +0,0 @@
/*****************************************************************************
* gta5view Grand Theft Auto V Profile Viewer
* Copyright (C) 2016 Syping
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*****************************************************************************/
#ifndef QJSON_DOCUMENT_H_
#define QJSON_DOCUMENT_H_
#include <QtCore/QtGlobal>
#if QT_VERSION >= 0x050000
#include <QtCore/QJsonDocument>
#else
class QVariant;
class QByteArray;
class QTextStream;
class QJsonObject;
class QJsonValue;
class QJsonArray;
class QJsonParseError;
class QJsonRoot;
class QJsonDocument {
public:
enum DataValidation {
Validate = 0,
BypassValidation = 1
};
enum JsonFormat {
Indented,
Compact
};
public:
QJsonDocument();
QJsonDocument(const QJsonObject &object);
QJsonDocument(const QJsonArray &array);
QJsonDocument(const QJsonDocument &other);
~QJsonDocument();
public:
QJsonDocument &operator=(const QJsonDocument &other);
public:
bool operator!=(const QJsonDocument &other) const;
bool operator==(const QJsonDocument &other) const;
public:
bool isArray() const;
bool isEmpty() const;
bool isNull() const;
bool isObject() const;
public:
QByteArray toBinaryData() const;
QByteArray toJson(JsonFormat format = Indented) const;
QVariant toVariant() const;
public:
QJsonArray array() const;
QJsonObject object() const;
const char *rawData(int *size) const;
public:
void setArray(const QJsonArray &array);
void setObject(const QJsonObject &object);
public:
static QJsonDocument fromBinaryData(const QByteArray &data, DataValidation validation = Validate);
static QJsonDocument fromJson(const QByteArray &json, QJsonParseError *error = 0);
static QJsonDocument fromRawData(const char *data, int size, DataValidation validation = Validate);
static QJsonDocument fromVariant(const QVariant &variant);
private:
void setRoot(const QJsonRoot &root);
QString toJson(const QJsonValue &v, JsonFormat format, int indent = 1) const;
QString escapeString(const QString &s) const;
private:
void swap(QJsonDocument &other);
private:
QJsonRoot *root_;
};
#endif
#endif

View File

@ -1 +0,0 @@
#include "QJsonObject.h"

View File

@ -1,322 +0,0 @@
/*****************************************************************************
* gta5view Grand Theft Auto V Profile Viewer
* Copyright (C) 2016 Syping
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*****************************************************************************/
#include "QJsonObject.h"
#if QT_VERSION < 0x050000
//------------------------------------------------------------------------------
// Name: QJsonObject
//------------------------------------------------------------------------------
QJsonObject::QJsonObject() {
}
//------------------------------------------------------------------------------
// Name: QJsonObject
//------------------------------------------------------------------------------
QJsonObject::QJsonObject(const QJsonObject &other) : values_(other.values_) {
}
#if __cplusplus >= 201103L
//------------------------------------------------------------------------------
// Name: QJsonObject
//------------------------------------------------------------------------------
QJsonObject::QJsonObject(std::initializer_list<QPair<QString, QJsonValue> > args) {
for(const QPair<QString, QJsonValue> &arg : args) {
values_.insert(arg.first, arg.second);
}
}
#endif
//------------------------------------------------------------------------------
// Name: ~QJsonObject
//------------------------------------------------------------------------------
QJsonObject::~QJsonObject() {
}
//------------------------------------------------------------------------------
// Name:
//------------------------------------------------------------------------------
QJsonObject &QJsonObject::operator=(const QJsonObject &other) {
QJsonObject(other).swap(*this);
return *this;
}
//------------------------------------------------------------------------------
// Name:
//------------------------------------------------------------------------------
QJsonObject::iterator QJsonObject::begin() {
return values_.begin();
}
//------------------------------------------------------------------------------
// Name:
//------------------------------------------------------------------------------
QJsonObject::const_iterator QJsonObject::begin() const {
return values_.begin();
}
//------------------------------------------------------------------------------
// Name:
//------------------------------------------------------------------------------
QJsonObject::iterator QJsonObject::end() {
return values_.end();
}
//------------------------------------------------------------------------------
// Name:
//------------------------------------------------------------------------------
QJsonObject::const_iterator QJsonObject::end() const {
return values_.end();
}
//------------------------------------------------------------------------------
// Name:
//------------------------------------------------------------------------------
QJsonObject::const_iterator QJsonObject::constBegin() const {
return begin();
}
//------------------------------------------------------------------------------
// Name:
//------------------------------------------------------------------------------
QJsonObject::const_iterator QJsonObject::constEnd() const {
return end();
}
//------------------------------------------------------------------------------
// Name:
//------------------------------------------------------------------------------
int QJsonObject::count() const {
return size();
}
//------------------------------------------------------------------------------
// Name:
//------------------------------------------------------------------------------
int QJsonObject::length() const {
return size();
}
//------------------------------------------------------------------------------
// Name:
//------------------------------------------------------------------------------
int QJsonObject::size() const {
return values_.size();
}
//------------------------------------------------------------------------------
// Name:
//------------------------------------------------------------------------------
bool QJsonObject::empty() const {
return values_.empty();
}
//------------------------------------------------------------------------------
// Name:
//------------------------------------------------------------------------------
bool QJsonObject::isEmpty() const {
return empty();
}
//------------------------------------------------------------------------------
// Name:
//------------------------------------------------------------------------------
QJsonObject::const_iterator QJsonObject::constFind(const QString &key) const {
return values_.find(key);
}
//------------------------------------------------------------------------------
// Name:
//------------------------------------------------------------------------------
bool QJsonObject::contains(const QString &key) const {
return values_.contains(key);
}
//------------------------------------------------------------------------------
// Name:
//------------------------------------------------------------------------------
QJsonObject::iterator QJsonObject::find(const QString &key) {
return values_.find(key);
}
//------------------------------------------------------------------------------
// Name:
//------------------------------------------------------------------------------
QJsonObject::const_iterator QJsonObject::find(const QString &key) const {
return values_.find(key);
}
//------------------------------------------------------------------------------
// Name:
//------------------------------------------------------------------------------
QJsonObject::iterator QJsonObject::erase(iterator it) {
return values_.erase(it);
}
//------------------------------------------------------------------------------
// Name:
//------------------------------------------------------------------------------
QJsonObject::iterator QJsonObject::insert(const QString &key, const QJsonValue &value) {
return values_.insert(key, value);
}
//------------------------------------------------------------------------------
// Name:
//------------------------------------------------------------------------------
QStringList QJsonObject::keys() const {
return values_.keys();
}
//------------------------------------------------------------------------------
// Name:
//------------------------------------------------------------------------------
void QJsonObject::remove(const QString &key) {
values_.remove(key);
}
//------------------------------------------------------------------------------
// Name:
//------------------------------------------------------------------------------
QJsonValue QJsonObject::take(const QString &key) {
return values_.take(key);
}
//------------------------------------------------------------------------------
// Name:
//------------------------------------------------------------------------------
QJsonValue QJsonObject::value(const QString &key) const {
return values_.value(key);
}
//------------------------------------------------------------------------------
// Name:
//------------------------------------------------------------------------------
bool QJsonObject::operator!=(const QJsonObject &other) const {
return values_ != other.values_;
}
//------------------------------------------------------------------------------
// Name:
//------------------------------------------------------------------------------
bool QJsonObject::operator==(const QJsonObject &other) const {
return values_ != other.values_;
}
//------------------------------------------------------------------------------
// Name:
//------------------------------------------------------------------------------
QJsonValue QJsonObject::operator[](const QString &key) const {
return values_[key];
}
//------------------------------------------------------------------------------
// Name:
//------------------------------------------------------------------------------
QJsonValueRef QJsonObject::operator[](const QString &key) {
return QJsonValueRef(this, key);
}
//------------------------------------------------------------------------------
// Name:
//------------------------------------------------------------------------------
QVariantMap QJsonObject::toVariantMap() const {
QVariantMap a;
for(const_iterator it = begin(); it != end(); ++it) {
a.insert(it.key(), it.value().toVariant());
}
return a;
}
//------------------------------------------------------------------------------
// Name:
//------------------------------------------------------------------------------
QVariantHash QJsonObject::toVariantHash() const {
QVariantHash a;
for(const_iterator it = begin(); it != end(); ++it) {
a.insert(it.key(), it.value().toVariant());
}
return a;
}
//------------------------------------------------------------------------------
// Name:
//------------------------------------------------------------------------------
QJsonObject QJsonObject::fromVariantMap(const QVariantMap &map) {
QJsonObject o;
for(QVariantMap::const_iterator it = map.begin(); it != map.end(); ++it) {
o.insert(it.key(), QJsonValue::fromVariant(it.value()));
}
return o;
}
//------------------------------------------------------------------------------
// Name:
//------------------------------------------------------------------------------
QJsonObject QJsonObject::fromVariantHash(const QVariantHash &hash) {
QJsonObject o;
for(QVariantHash::const_iterator it = hash.begin(); it != hash.end(); ++it) {
o.insert(it.key(), QJsonValue::fromVariant(it.value()));
}
return o;
}
//------------------------------------------------------------------------------
// Name:
//------------------------------------------------------------------------------
QJsonRoot *QJsonObject::clone() const {
return new QJsonObject(*this);
}
//------------------------------------------------------------------------------
// Name:
//------------------------------------------------------------------------------
const QJsonObject *QJsonObject::toObject() const {
return this;
}
//------------------------------------------------------------------------------
// Name:
//------------------------------------------------------------------------------
QJsonObject *QJsonObject::toObject() {
return this;
}
//------------------------------------------------------------------------------
// Name:
//------------------------------------------------------------------------------
QJsonArray *QJsonObject::toArray() {
return 0;
}
//------------------------------------------------------------------------------
// Name:
//------------------------------------------------------------------------------
const QJsonArray *QJsonObject::toArray() const {
return 0;
}
//------------------------------------------------------------------------------
// Name: swap
//------------------------------------------------------------------------------
void QJsonObject::swap(QJsonObject &other) {
qSwap(values_, other.values_);
}
#endif

View File

@ -1,121 +0,0 @@
/*****************************************************************************
* gta5view Grand Theft Auto V Profile Viewer
* Copyright (C) 2016 Syping
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*****************************************************************************/
#ifndef QJSON_OBJECT_H_
#define QJSON_OBJECT_H_
#include <QtCore/QtGlobal>
#if QT_VERSION >= 0x050000
#include <QtCore/QJsonObject>
#else
#include "QJsonRoot.h"
#include "QJsonValueRef.h"
#include "QJsonValue.h"
#include <QtCore/QString>
#include <QtCore/QStringList>
#include <QtCore/QVariantMap>
#include <QtCore/QMap>
class QJsonObject : public QJsonRoot {
friend class QJsonDocument;
friend class QJsonValue;
friend class QJsonValueRef;
friend class QJsonParser;
public:
// TODO(eteran): manually implement the map, for now we use QMap
// but the real thing has a custom implementation
// I guess for the purposes of less interdependancies?
// maybe so it's easier to forward declare the iterators?
typedef QMap<QString, QJsonValue>::const_iterator const_iterator;
typedef QMap<QString, QJsonValue>::iterator iterator;
typedef const_iterator ConstIterator;
typedef iterator Iterator;
typedef QMap<QString, QJsonValue>::key_type key_type;
typedef QMap<QString, QJsonValue>::mapped_type mapped_type;
typedef QMap<QString, QJsonValue>::size_type size_type;
public:
QJsonObject();
#if __cplusplus >= 201103L
QJsonObject(std::initializer_list<QPair<QString, QJsonValue> > args);
#endif
QJsonObject(const QJsonObject &other);
~QJsonObject();
QJsonObject &operator=(const QJsonObject &other);
public:
iterator begin();
const_iterator begin() const;
iterator end();
const_iterator end() const;
const_iterator constBegin() const;
const_iterator constEnd() const;
public:
int count() const;
int length() const;
int size() const;
bool empty() const;
bool isEmpty() const;
public:
const_iterator constFind(const QString &key) const;
bool contains(const QString &key) const;
iterator find(const QString &key);
const_iterator find(const QString &key) const;
public:
iterator erase(iterator it);
iterator insert(const QString &key, const QJsonValue &value);
QStringList keys() const;
void remove(const QString &key);
QJsonValue take(const QString &key);
QJsonValue value(const QString &key) const;
bool operator!=(const QJsonObject &other) const;
bool operator==(const QJsonObject &other) const;
QJsonValue operator[](const QString &key) const;
QJsonValueRef operator[](const QString &key);
public:
QVariantMap toVariantMap() const;
QVariantHash toVariantHash() const;
public:
static QJsonObject fromVariantMap(const QVariantMap &map);
static QJsonObject fromVariantHash(const QVariantHash &hash);
private:
virtual QJsonRoot *clone() const;
virtual QJsonArray *toArray();
virtual QJsonObject *toObject();
virtual const QJsonArray *toArray() const;
virtual const QJsonObject *toObject() const;
private:
void swap(QJsonObject &other);
private:
QMap<QString, QJsonValue> values_;
};
#endif
#endif

View File

@ -1 +0,0 @@
#include "QJsonParseError.h"

View File

@ -1,64 +0,0 @@
/*****************************************************************************
* gta5view Grand Theft Auto V Profile Viewer
* Copyright (C) 2016 Syping
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*****************************************************************************/
#include "QJsonParseError.h"
#if QT_VERSION < 0x050000
//------------------------------------------------------------------------------
// Name: errorString
// Desc: The QJsonParseError class is used to report errors during JSON parsing.
//------------------------------------------------------------------------------
QString QJsonParseError::errorString() const {
switch(error) {
case NoError:
return "No error occurred";
case UnterminatedObject:
return "unterminated object";
case MissingNameSeparator:
return "missing name separator";
case UnterminatedArray:
return "unterminated array";
case MissingValueSeparator:
return "missing value separator";
case IllegalValue:
return "illegal value";
case TerminationByNumber:
return "invalid termination by number";
case IllegalNumber:
return "illegal number";
case IllegalEscapeSequence:
return "illegal escape sequence";
case IllegalUTF8String:
return "invalid UTF8 string";
case UnterminatedString:
return "unterminated string";
case MissingObject:
return "object is missing after a comma";
case DeepNesting:
return "too deeply nested document";
case DocumentTooLarge:
return "too large document";
case GarbageAtEnd:
return "garbage at the end of the document";
}
return QString();
}
#endif

View File

@ -1,60 +0,0 @@
/*****************************************************************************
* gta5view Grand Theft Auto V Profile Viewer
* Copyright (C) 2016 Syping
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*****************************************************************************/
#ifndef QJSON_PARSE_ERROR_H_
#define QJSON_PARSE_ERROR_H_
#include <QtCore/QtGlobal>
#if QT_VERSION >= 0x050000
#include <QtCore/QJsonParseError>
#else
#include <QtCore/QString>
class QJsonParseError {
public:
enum ParseError {
NoError = 0,
UnterminatedObject = 1,
MissingNameSeparator = 2,
UnterminatedArray = 3,
MissingValueSeparator = 4,
IllegalValue = 5,
TerminationByNumber = 6,
IllegalNumber = 7,
IllegalEscapeSequence = 8,
IllegalUTF8String = 9,
UnterminatedString = 10,
MissingObject = 11,
DeepNesting = 12,
DocumentTooLarge = 13,
GarbageAtEnd = 14
};
public:
QString errorString() const;
public:
ParseError error;
int offset;
};
#endif
#endif

View File

@ -1,455 +0,0 @@
/*****************************************************************************
* gta5view Grand Theft Auto V Profile Viewer
* Copyright (C) 2016 Syping
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*****************************************************************************/
#include "QJsonParser.h"
#include "QJsonArray.h"
#include "QJsonObject.h"
#include "QJsonValue.h"
#if QT_VERSION < 0x050000
#include <cctype>
#include <QScopedPointer>
#include <QVector>
namespace {
unsigned int to_hex(int ch) {
static const int hexval[256] = {
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
0x0, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
};
if(static_cast<unsigned int>(ch) < 256) {
return hexval[static_cast<unsigned int>(ch)];
} else {
return 0;
}
}
}
//------------------------------------------------------------------------------
// Name: QJsonParser
//------------------------------------------------------------------------------
QJsonParser::QJsonParser(const char *begin, const char *end) : begin_(begin), end_(end), p_(begin) {
state_.error = QJsonParseError::NoError;
state_.offset = 0;
}
//------------------------------------------------------------------------------
// Name: parse
//------------------------------------------------------------------------------
QJsonRoot *QJsonParser::parse() {
if(begin_ == end_) {
return 0;
}
QJsonRoot *ret = 0;
try {
const char ch = peek();
switch(ch) {
case ArrayBegin:
ret = getArray();
break;
case ObjectBegin:
ret = getObject();
break;
default:
state_.error = QJsonParseError::IllegalValue;
state_.offset = p_ - begin_;
break;
}
} catch(const QJsonParseError &e) {
state_ = e;
}
if(ret) {
// eat up trailing white space...
while(p_ != end_ && std::isspace(*p_)) {
++p_;
}
//detect trailing garbage
if(p_ != end_) {
state_.error = QJsonParseError::GarbageAtEnd;
state_.offset = p_ - begin_;
}
}
return ret;
}
//------------------------------------------------------------------------------
// Name: peek
//------------------------------------------------------------------------------
char QJsonParser::peek() {
// first eat up some whitespace
while(p_ != end_ && std::isspace(*p_)) {
++p_;
}
return *p_;
}
//------------------------------------------------------------------------------
// Name: getValue
//------------------------------------------------------------------------------
QJsonValue QJsonParser::getValue() {
switch(peek()) {
case ObjectBegin:
{
QScopedPointer<QJsonObject> obj(getObject());
return QJsonValue(*obj);
}
case ArrayBegin:
{
QScopedPointer<QJsonArray> arr(getArray());
return QJsonValue(*arr);
}
case Quote:
return QJsonValue(getString());
case 't':
return getTrue();
case 'f':
return getFalse();
case 'n':
return getNull();
default:
return getNumber();
}
throwError(QJsonParseError::MissingObject);
return QJsonValue();
}
//------------------------------------------------------------------------------
// Name: getObject
//------------------------------------------------------------------------------
QJsonObject *QJsonParser::getObject() {
QScopedPointer<QJsonObject> obj(new QJsonObject);
char tok = peek();
if(tok != ObjectBegin) {
throwError(QJsonParseError::IllegalValue);
}
++p_;
// handle empty object
tok = peek();
if(peek() == ObjectEnd) {
++p_;
} else {
do {
QPair<QString, QJsonValue> p = getPair();
obj->values_.insert(p.first, p.second);
tok = peek();
++p_;
} while(tok == ValueSeparator);
}
if(tok != ObjectEnd) {
throwError(QJsonParseError::UnterminatedObject);
}
return obj.take();
}
//------------------------------------------------------------------------------
// Name: getArray
//------------------------------------------------------------------------------
QJsonArray *QJsonParser::getArray() {
QScopedPointer<QJsonArray> arr(new QJsonArray);
char tok = peek();
if(tok != ArrayBegin) {
throwError(QJsonParseError::IllegalValue);
}
++p_;
// handle empty object
tok = peek();
if(tok == ArrayEnd) {
++p_;
} else {
do {
arr->values_.push_back(getValue());
tok = peek();
++p_;
} while(tok == ValueSeparator);
}
if(tok != ArrayEnd) {
throwError(QJsonParseError::MissingValueSeparator);
}
return arr.take();
}
//------------------------------------------------------------------------------
// Name: getPair
//------------------------------------------------------------------------------
QPair<QString, QJsonValue> QJsonParser::getPair() {
QString key = getString();
if(peek() != NameSeparator) {
throwError(QJsonParseError::MissingNameSeparator);
}
++p_;
return qMakePair(key, getValue());
}
//------------------------------------------------------------------------------
// Name: getString
//------------------------------------------------------------------------------
QString QJsonParser::getString() {
if(peek() != Quote) {
throwError(QJsonParseError::IllegalUTF8String);
}
++p_;
QByteArray s;
while(p_ != end_ && *p_ != Quote && *p_ != '\n') {
if(*p_ == '\\') {
++p_;
if(p_ != end_) {
switch(*p_) {
case '"': s.append('"'); break;
case '\\': s.append('\\'); break;
case '/': s.append('/'); break;
case 'b': s.append('\b'); break;
case 'f': s.append('\f'); break;
case 'n': s.append('\n'); break;
case 'r': s.append('\r'); break;
case 't': s.append('\t'); break;
case 'u':
{
QString hexChar;
// convert \uXXXX escape sequences to UTF-8
char hex[4];
if(p_ == end_) { throwError(QJsonParseError::IllegalEscapeSequence); } hex[0] = *++p_;
if(p_ == end_) { throwError(QJsonParseError::IllegalEscapeSequence); } hex[1] = *++p_;
if(p_ == end_) { throwError(QJsonParseError::IllegalEscapeSequence); } hex[2] = *++p_;
if(p_ == end_) { throwError(QJsonParseError::IllegalEscapeSequence); } hex[3] = *++p_;
if(!std::isxdigit(hex[0])) throwError(QJsonParseError::IllegalUTF8String);
if(!std::isxdigit(hex[1])) throwError(QJsonParseError::IllegalUTF8String);
if(!std::isxdigit(hex[2])) throwError(QJsonParseError::IllegalUTF8String);
if(!std::isxdigit(hex[3])) throwError(QJsonParseError::IllegalUTF8String);
quint16 w1 = 0;
quint16 w2 = 0;
w1 |= (to_hex(hex[0]) << 12);
w1 |= (to_hex(hex[1]) << 8);
w1 |= (to_hex(hex[2]) << 4);
w1 |= (to_hex(hex[3]));
hexChar.append(QChar(w1));
if((w1 & 0xfc00) == 0xdc00) {
throwError(QJsonParseError::IllegalUTF8String);
}
if((w1 & 0xfc00) == 0xd800) {
// part of a surrogate pair
if(p_ == end_ || *++p_ != '\\') { throwError(QJsonParseError::IllegalEscapeSequence); }
if(p_ == end_ || *++p_ != 'u') { throwError(QJsonParseError::IllegalEscapeSequence); }
// convert \uXXXX escape sequences to UTF-8
if(p_ == end_) { throwError(QJsonParseError::IllegalEscapeSequence); } hex[0] = *++p_;
if(p_ == end_) { throwError(QJsonParseError::IllegalEscapeSequence); } hex[1] = *++p_;
if(p_ == end_) { throwError(QJsonParseError::IllegalEscapeSequence); } hex[2] = *++p_;
if(p_ == end_) { throwError(QJsonParseError::IllegalEscapeSequence); } hex[3] = *++p_;
if(!std::isxdigit(hex[0])) throwError(QJsonParseError::IllegalUTF8String);
if(!std::isxdigit(hex[1])) throwError(QJsonParseError::IllegalUTF8String);
if(!std::isxdigit(hex[2])) throwError(QJsonParseError::IllegalUTF8String);
if(!std::isxdigit(hex[3])) throwError(QJsonParseError::IllegalUTF8String);
w2 |= (to_hex(hex[0]) << 12);
w2 |= (to_hex(hex[1]) << 8);
w2 |= (to_hex(hex[2]) << 4);
w2 |= (to_hex(hex[3]));
hexChar.append(QChar(w2));
}
s.append(hexChar.toUtf8());
}
break;
default:
s.append('\\');
break;
}
}
} else {
s.append(*p_);
}
++p_;
}
if(*p_ != Quote || p_ == end_) {
throwError(QJsonParseError::UnterminatedString);
}
++p_;
return QString::fromUtf8(s, s.size());
}
//------------------------------------------------------------------------------
// Name: getNull
//------------------------------------------------------------------------------
QJsonValue QJsonParser::getNull() {
if(p_ == end_ || *p_++ != 'n') { throwError(QJsonParseError::IllegalValue); }
if(p_ == end_ || *p_++ != 'u') { throwError(QJsonParseError::IllegalValue); }
if(p_ == end_ || *p_++ != 'l') { throwError(QJsonParseError::IllegalValue); }
if(p_ == end_ || *p_++ != 'l') { throwError(QJsonParseError::IllegalValue); }
return QJsonValue();
}
//------------------------------------------------------------------------------
// Name: getTrue
//------------------------------------------------------------------------------
QJsonValue QJsonParser::getTrue() {
if(p_ == end_ || *p_++ != 't') { throwError(QJsonParseError::IllegalValue); }
if(p_ == end_ || *p_++ != 'r') { throwError(QJsonParseError::IllegalValue); }
if(p_ == end_ || *p_++ != 'u') { throwError(QJsonParseError::IllegalValue); }
if(p_ == end_ || *p_++ != 'e') { throwError(QJsonParseError::IllegalValue); }
return QJsonValue(true);
}
//------------------------------------------------------------------------------
// Name: getFalse
//------------------------------------------------------------------------------
QJsonValue QJsonParser::getFalse() {
if(p_ == end_ || *p_++ != 'f') { throwError(QJsonParseError::IllegalValue); }
if(p_ == end_ || *p_++ != 'a') { throwError(QJsonParseError::IllegalValue); }
if(p_ == end_ || *p_++ != 'l') { throwError(QJsonParseError::IllegalValue); }
if(p_ == end_ || *p_++ != 's') { throwError(QJsonParseError::IllegalValue); }
if(p_ == end_ || *p_++ != 'e') { throwError(QJsonParseError::IllegalValue); }
return QJsonValue(false);
}
//------------------------------------------------------------------------------
// Name: getNumber
//------------------------------------------------------------------------------
QJsonValue QJsonParser::getNumber() {
// JSON numbers fit the regex: -?(0|[1-9][0-9]*)(\.[0-9]+)?([eE][+-]?[0-9]+)?
const char *const first = p_;
// -?
if(p_ != end_ && *p_ == '-') {
++p_;
}
// (0|[1-9][0-9]*)
if(p_ != end_) {
if(*p_ >= '1' && *p_ <= '9') {
while(p_ != end_ && std::isdigit(*p_)) {
++p_;
}
} else if(*p_ == '0') {
++p_;
} else {
throwError(QJsonParseError::IllegalNumber);
}
}
// (\.[0-9]+)?
if(p_ != end_ && *p_ == '.') {
++p_;
if(!std::isdigit(*p_)) {
throwError(QJsonParseError::IllegalNumber);
}
while(p_ != end_ && std::isdigit(*p_)) {
++p_;
}
}
// ([eE][+-]?[0-9]+)?
if(p_ != end_ && (*p_ == 'e' || *p_ == 'E')) {
++p_;
if(p_ != end_ && (*p_ == '+' || *p_ == '-')) {
++p_;
}
if(!std::isdigit(*p_)) {
throwError(QJsonParseError::IllegalNumber);
}
while(p_ != end_ && std::isdigit(*p_)) {
++p_;
}
}
if(p_ == end_) {
throwError(QJsonParseError::TerminationByNumber);
}
return QJsonValue(QByteArray::fromRawData(first, p_ - first).toDouble());
}
//------------------------------------------------------------------------------
// Name: state
//------------------------------------------------------------------------------
QJsonParseError QJsonParser::state() const {
return state_;
}
//------------------------------------------------------------------------------
// Name: throwError
//------------------------------------------------------------------------------
void QJsonParser::throwError(QJsonParseError::ParseError e) {
QJsonParseError err;
err.error = e;
err.offset = p_ - begin_;
throw err;
}
#endif

View File

@ -1,81 +0,0 @@
/*****************************************************************************
* gta5view Grand Theft Auto V Profile Viewer
* Copyright (C) 2016 Syping
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*****************************************************************************/
// NOTE: this is not part of the "public" Qt API, so using this class directly
// is not recomended
#ifndef QJSON_PARSER_H_
#define QJSON_PARSER_H_
#include <QtCore/QtGlobal>
#if QT_VERSION < 0x050000
#include "QJsonParseError.h"
#include <QPair>
class QJsonRoot;
class QJsonObject;
class QJsonArray;
class QJsonValue;
class QJsonParser {
friend class QJsonDocument;
public:
QJsonParser(const char *begin, const char *end);
public:
QJsonRoot *parse();
public:
QJsonParseError state() const;
private:
static const char ArrayBegin = '[';
static const char ArrayEnd = ']';
static const char NameSeparator = ':';
static const char ValueSeparator = ',';
static const char ObjectBegin = '{';
static const char ObjectEnd = '}';
static const char Quote = '"';
private:
char peek();
QJsonObject *getObject();
QJsonArray *getArray();
QJsonValue getValue();
QString getString();
QJsonValue getTrue();
QJsonValue getFalse();
QJsonValue getNull();
QJsonValue getNumber();
QPair<QString, QJsonValue> getPair();
private:
void throwError(QJsonParseError::ParseError e);
private:
QJsonParseError state_;
const char *const begin_;
const char *const end_;
const char * p_;
};
#endif
#endif

View File

@ -1 +0,0 @@
#include "QJsonRoot.h"

View File

@ -1,45 +0,0 @@
/*****************************************************************************
* gta5view Grand Theft Auto V Profile Viewer
* Copyright (C) 2016 Syping
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*****************************************************************************/
#ifndef QJSON_ROOT_H_
#define QJSON_ROOT_H_
#include <QtCore/QtGlobal>
#if QT_VERSION < 0x050000
class QJsonObject;
class QJsonArray;
class QJsonRoot {
public:
virtual ~QJsonRoot() {};
public:
virtual QJsonRoot *clone() const = 0;
public:
virtual QJsonArray *toArray() = 0;
virtual QJsonObject *toObject() = 0;
virtual const QJsonArray *toArray() const = 0;
virtual const QJsonObject *toObject() const = 0;
};
#endif
#endif

View File

@ -1 +0,0 @@
#include "QJsonValue.h"

View File

@ -1,391 +0,0 @@
/*****************************************************************************
* gta5view Grand Theft Auto V Profile Viewer
* Copyright (C) 2016 Syping
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*****************************************************************************/
#include "QJsonValue.h"
#include "QJsonArray.h"
#include "QJsonObject.h"
#if QT_VERSION < 0x050000
#include <QtCore/QtAlgorithms>
#include <QtCore/qmath.h>
//------------------------------------------------------------------------------
// Name: QJsonValue
//------------------------------------------------------------------------------
QJsonValue::QJsonValue(Type type) : type_(type) {
}
//------------------------------------------------------------------------------
// Name: QJsonValue
//------------------------------------------------------------------------------
QJsonValue::QJsonValue(bool b) : type_(Bool) {
value_.b = b;
}
//------------------------------------------------------------------------------
// Name: QJsonValue
//------------------------------------------------------------------------------
QJsonValue::QJsonValue(double n) : type_(Double) {
value_.n = n;
}
//------------------------------------------------------------------------------
// Name: QJsonValue
//------------------------------------------------------------------------------
QJsonValue::QJsonValue(const QString &s) : type_(String) {
value_.s = new QString(s);
}
//------------------------------------------------------------------------------
// Name: QJsonValue
//------------------------------------------------------------------------------
QJsonValue::QJsonValue(QLatin1String s) : type_(String) {
value_.s = new QString(s);
}
#ifndef QT_NO_CAST_FROM_ASCII
//------------------------------------------------------------------------------
// Name: QJsonValue
//------------------------------------------------------------------------------
QJsonValue::QJsonValue(const char *s) : type_(String) {
value_.s = new QString(QString::fromUtf8(s));
}
#endif
//------------------------------------------------------------------------------
// Name: QJsonValue
//------------------------------------------------------------------------------
QJsonValue::QJsonValue(const QJsonArray &a) : type_(Array) {
value_.r = a.clone();
}
//------------------------------------------------------------------------------
// Name: QJsonValue
//------------------------------------------------------------------------------
QJsonValue::QJsonValue(const QJsonObject &o) : type_(Object) {
value_.r = o.clone();
}
//------------------------------------------------------------------------------
// Name: QJsonValue
//------------------------------------------------------------------------------
QJsonValue::QJsonValue(int n) : type_(Double) {
value_.n = n;
}
//------------------------------------------------------------------------------
// Name: QJsonValue
//------------------------------------------------------------------------------
QJsonValue::QJsonValue(qint64 n) : type_(Double) {
value_.n = n;
}
//------------------------------------------------------------------------------
// Name: QJsonValue
//------------------------------------------------------------------------------
QJsonValue::QJsonValue(const QJsonValue &other) : type_(other.type_) {
switch(other.type_) {
case Bool:
value_.b = other.value_.b;
break;
case Double:
value_.n = other.value_.n;
break;
case String:
value_.s = new QString(*other.value_.s);
break;
case Array:
case Object:
value_.r = other.value_.r->clone();
break;
case Undefined:
case Null:
value_ = other.value_;
break;
}
}
//------------------------------------------------------------------------------
// Name: ~QJsonValue
//------------------------------------------------------------------------------
QJsonValue::~QJsonValue() {
switch(type_) {
case Null:
case Bool:
case Double:
case Undefined:
break;
case String:
delete value_.s;
break;
case Object:
case Array:
delete value_.r;
break;
}
}
//------------------------------------------------------------------------------
// Name: operator=
//------------------------------------------------------------------------------
QJsonValue &QJsonValue::operator=(const QJsonValue &other) {
QJsonValue(other).swap(*this);
return *this;
}
//------------------------------------------------------------------------------
// Name: operator!=
//------------------------------------------------------------------------------
bool QJsonValue::operator!=(const QJsonValue &other) const {
return !(*this == other);
}
//------------------------------------------------------------------------------
// Name: operator==
//------------------------------------------------------------------------------
bool QJsonValue::operator==(const QJsonValue &other) const {
if(type_ == other.type_) {
switch(type_) {
case Null:
return true;
case Bool:
return value_.b == other.value_.b;
case Double:
return value_.n == other.value_.n;
case Undefined:
return true;
case String:
return *value_.s == *other.value_.s;
case Array:
return *(value_.r->toArray()) == *(other.value_.r->toArray());
case Object:
return *(value_.r->toObject()) == *(other.value_.r->toObject());
}
}
return false;
}
//------------------------------------------------------------------------------
// Name: isArray
//------------------------------------------------------------------------------
bool QJsonValue::isArray() const {
return type_ == Array;
}
//------------------------------------------------------------------------------
// Name: isBool
//------------------------------------------------------------------------------
bool QJsonValue::isBool() const {
return type_ == Bool;
}
//------------------------------------------------------------------------------
// Name: isDouble
//------------------------------------------------------------------------------
bool QJsonValue::isDouble() const {
return type_ == Double;
}
//------------------------------------------------------------------------------
// Name: isNull
//------------------------------------------------------------------------------
bool QJsonValue::isNull() const {
return type_ == Null;
}
//------------------------------------------------------------------------------
// Name: isObject
//------------------------------------------------------------------------------
bool QJsonValue::isObject() const {
return type_ == Object;
}
//------------------------------------------------------------------------------
// Name: isString
//------------------------------------------------------------------------------
bool QJsonValue::isString() const {
return type_ == String;
}
//------------------------------------------------------------------------------
// Name: isUndefined
//------------------------------------------------------------------------------
bool QJsonValue::isUndefined() const {
return type_ == Undefined;
}
//------------------------------------------------------------------------------
// Name: type
//------------------------------------------------------------------------------
QJsonValue::Type QJsonValue::type() const {
return type_;
}
//------------------------------------------------------------------------------
// Name: toArray
//------------------------------------------------------------------------------
QJsonArray QJsonValue::toArray(const QJsonArray &defaultValue) const {
if(isArray()) {
return *(value_.r->toArray());
}
return defaultValue;
}
//------------------------------------------------------------------------------
// Name: toArray
//------------------------------------------------------------------------------
QJsonArray QJsonValue::toArray() const {
return toArray(QJsonArray());
}
//------------------------------------------------------------------------------
// Name: toBool
//------------------------------------------------------------------------------
bool QJsonValue::toBool(bool defaultValue) const {
if(isBool()) {
return value_.b;
}
return defaultValue;
}
//------------------------------------------------------------------------------
// Name: toDouble
//------------------------------------------------------------------------------
double QJsonValue::toDouble(double defaultValue) const {
if(isDouble()) {
return value_.n;
}
return defaultValue;
}
//------------------------------------------------------------------------------
// Name: toInt
//------------------------------------------------------------------------------
int QJsonValue::toInt(int defaultValue) const {
if(isDouble() && qFloor(value_.n) == value_.n) {
return value_.n;
}
return defaultValue;
}
//------------------------------------------------------------------------------
// Name: toObject
//------------------------------------------------------------------------------
QJsonObject QJsonValue::toObject(const QJsonObject &defaultValue) const {
if(isObject()) {
return *(value_.r->toObject());
}
return defaultValue;
}
//------------------------------------------------------------------------------
// Name: toObject
//------------------------------------------------------------------------------
QJsonObject QJsonValue::toObject() const {
return toObject(QJsonObject());
}
//------------------------------------------------------------------------------
// Name: toString
//------------------------------------------------------------------------------
QString QJsonValue::toString(const QString &defaultValue) const {
if(isString()) {
return *value_.s;
}
return defaultValue;
}
//------------------------------------------------------------------------------
// Name: toVariant
//------------------------------------------------------------------------------
QVariant QJsonValue::toVariant() const {
switch(type_) {
case Null:
return QVariant();
case Bool:
return QVariant::fromValue(value_.b);
case Double:
return QVariant::fromValue(value_.n);
case String:
return QVariant::fromValue(*value_.s);
case Array:
return value_.r->toArray()->toVariantList();
case Object:
return value_.r->toObject()->toVariantMap();
case Undefined:
return QVariant();
}
return QVariant();
}
//------------------------------------------------------------------------------
// Name: fromVariant
//------------------------------------------------------------------------------
QJsonValue QJsonValue::fromVariant(const QVariant &variant) {
if(variant.isNull()) {
return QJsonValue(Null);
}
switch(variant.type()) {
case QVariant::Bool:
return QJsonValue(variant.toBool());
case QVariant::Int:
return QJsonValue(variant.toInt());
case QVariant::Double:
case QVariant::LongLong:
case QVariant::ULongLong:
case QVariant::UInt:
return QJsonValue(variant.toDouble());
case QVariant::String:
return QJsonValue(variant.toString());
case QVariant::List:
return QJsonArray::fromVariantList(variant.toList());
case QVariant::StringList:
return QJsonArray::fromStringList(variant.toStringList());
case QVariant::Map:
return QJsonObject::fromVariantMap(variant.toMap());
default:
const QString s = variant.toString();
if(!s.isEmpty()) {
return QJsonValue(s);
}
break;
}
return QJsonValue(Null);
}
//------------------------------------------------------------------------------
// Name: swap
//------------------------------------------------------------------------------
void QJsonValue::swap(QJsonValue &other) {
qSwap(type_, other.type_);
qSwap(value_, other.value_);
}
#endif

View File

@ -1,120 +0,0 @@
/*****************************************************************************
* gta5view Grand Theft Auto V Profile Viewer
* Copyright (C) 2016 Syping
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*****************************************************************************/
#ifndef QJSON_VALUE_H_
#define QJSON_VALUE_H_
#include <QtCore/QtGlobal>
#if QT_VERSION >= 0x050000
#include <QtCore/QJsonValue>
#else
class QString;
#include <QtCore/QVariant>
class QJsonRoot;
class QJsonArray;
class QJsonObject;
class QJsonValue {
public:
enum Type {
Null = 0x0,
Bool = 0x1,
Double = 0x2,
String = 0x3,
Array = 0x4,
Object = 0x5,
Undefined = 0x80
};
public:
QJsonValue(Type type = Null);
QJsonValue(bool b);
QJsonValue(double n);
QJsonValue(int n);
QJsonValue(qint64 n);
QJsonValue(const QString &s);
QJsonValue(QLatin1String s);
#ifndef QT_NO_CAST_FROM_ASCII
QJsonValue(const char *s);
#endif
QJsonValue(const QJsonArray &a);
QJsonValue(const QJsonObject &o);
QJsonValue(const QJsonValue &other);
~QJsonValue();
private:
// to protect against incorrect usage due to passing a const char *
QJsonValue(const void *);
public:
QJsonValue &operator=(const QJsonValue &other);
public:
bool operator!=(const QJsonValue &other) const;
bool operator==(const QJsonValue &other) const;
public:
bool isArray() const;
bool isBool() const;
bool isDouble() const;
bool isNull() const;
bool isObject() const;
bool isString() const;
bool isUndefined() const;
public:
QJsonArray toArray(const QJsonArray &defaultValue) const;
QJsonArray toArray() const;
bool toBool(bool defaultValue = false) const;
double toDouble(double defaultValue = 0) const;
int toInt(int defaultValue = 0) const;
QJsonObject toObject(const QJsonObject &defaultValue) const;
QJsonObject toObject() const;
QString toString(const QString &defaultValue = QString()) const;
QVariant toVariant() const;
public:
Type type() const;
public:
static QJsonValue fromVariant(const QVariant &variant);
private:
void swap(QJsonValue &other);
private:
Type type_;
union ValueType {
bool b;
double n;
QString *s;
QJsonRoot *r; // OJsonObject or QJsonArray
};
ValueType value_;
};
#endif
#endif

View File

@ -1 +0,0 @@
#include "QJsonValueRef.h"

View File

@ -1,228 +0,0 @@
/*****************************************************************************
* gta5view Grand Theft Auto V Profile Viewer
* Copyright (C) 2016 Syping
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*****************************************************************************/
#include "QJsonValueRef.h"
#if QT_VERSION < 0x050000
#include "QJsonArray.h"
#include "QJsonObject.h"
//------------------------------------------------------------------------------
// Name:
// Desc:
//------------------------------------------------------------------------------
QJsonValueRef::QJsonValueRef(QJsonArray *array, int idx) : p_(array), index_(idx) {
}
//------------------------------------------------------------------------------
// Name:
// Desc:
//------------------------------------------------------------------------------
QJsonValueRef::QJsonValueRef(QJsonObject *object, const QString &key) : p_(object), index_(0), key_(key) {
}
//------------------------------------------------------------------------------
// Name:
// Desc:
//------------------------------------------------------------------------------
QJsonValueRef::operator QJsonValue() const {
return toValue();
}
//------------------------------------------------------------------------------
// Name:
// Desc:
//------------------------------------------------------------------------------
QJsonValueRef &QJsonValueRef::operator=(const QJsonValue &val) {
if(QJsonObject *const o = p_->toObject()) {
o->values_[key_] = val;
} else if(QJsonArray *const a = p_->toArray()) {
a->values_[index_] = val;
}
return *this;
}
//------------------------------------------------------------------------------
// Name:
// Desc:
//------------------------------------------------------------------------------
QJsonValueRef &QJsonValueRef::operator=(const QJsonValueRef &ref) {
if(QJsonObject *const o = p_->toObject()) {
o->values_[key_] = ref;
} else if(QJsonArray *const a = p_->toArray()) {
a->values_[index_] = ref;
}
return *this;
}
//------------------------------------------------------------------------------
// Name: type
// Desc:
//------------------------------------------------------------------------------
QJsonValue::Type QJsonValueRef::type() const {
return toValue().type();
}
//------------------------------------------------------------------------------
// Name: isNull
// Desc:
//------------------------------------------------------------------------------
bool QJsonValueRef::isNull() const {
return toValue().isNull();
}
//------------------------------------------------------------------------------
// Name: isBool
// Desc:
//------------------------------------------------------------------------------
bool QJsonValueRef::isBool() const {
return toValue().isBool();
}
//------------------------------------------------------------------------------
// Name: isDouble
// Desc:
//------------------------------------------------------------------------------
bool QJsonValueRef::isDouble() const {
return toValue().isDouble();
}
//------------------------------------------------------------------------------
// Name: isString
// Desc:
//------------------------------------------------------------------------------
bool QJsonValueRef::isString() const {
return toValue().isString();
}
//------------------------------------------------------------------------------
// Name: isArray
// Desc:
//------------------------------------------------------------------------------
bool QJsonValueRef::isArray() const {
return toValue().isArray();
}
//------------------------------------------------------------------------------
// Name: isObject
// Desc:
//------------------------------------------------------------------------------
bool QJsonValueRef::isObject() const {
return toValue().isObject();
}
//------------------------------------------------------------------------------
// Name: isUndefined
// Desc:
//------------------------------------------------------------------------------
bool QJsonValueRef::isUndefined() const {
return toValue().isUndefined();
}
//------------------------------------------------------------------------------
// Name: toBool
// Desc:
//------------------------------------------------------------------------------
bool QJsonValueRef::toBool() const {
return toValue().toBool();
}
//------------------------------------------------------------------------------
// Name: toDouble
// Desc:
//------------------------------------------------------------------------------
double QJsonValueRef::toDouble() const {
return toValue().toDouble();
}
//------------------------------------------------------------------------------
// Name: toInt
// Desc:
//------------------------------------------------------------------------------
int QJsonValueRef::toInt(int defaultValue) const {
return toValue().toInt(defaultValue);
}
//------------------------------------------------------------------------------
// Name: toString
// Desc:
//------------------------------------------------------------------------------
QString QJsonValueRef::toString() const {
return toValue().toString();
}
//------------------------------------------------------------------------------
// Name: toArray
// Desc:
//------------------------------------------------------------------------------
QJsonArray QJsonValueRef::toArray() const {
return toValue().toArray();
}
//------------------------------------------------------------------------------
// Name: toObject
// Desc:
//------------------------------------------------------------------------------
QJsonObject QJsonValueRef::toObject() const {
return toValue().toObject();
}
//------------------------------------------------------------------------------
// Name: operator==
// Desc:
//------------------------------------------------------------------------------
bool QJsonValueRef::operator==(const QJsonValue &other) const {
return toValue() == other;
}
//------------------------------------------------------------------------------
// Name: operator!=
// Desc:
//------------------------------------------------------------------------------
bool QJsonValueRef::operator!=(const QJsonValue &other) const {
return toValue() != other;
}
//------------------------------------------------------------------------------
// Name: toValue
// Desc:
//------------------------------------------------------------------------------
QJsonValue QJsonValueRef::toValue() const {
if(QJsonObject *const o = p_->toObject()) {
return o->values_[key_];
} else if(QJsonArray *const a = p_->toArray()) {
return a->values_[index_];
}
return QJsonValue();
}
//------------------------------------------------------------------------------
// Name: swap
// Desc:
//------------------------------------------------------------------------------
void QJsonValueRef::swap(QJsonValueRef &other) {
qSwap(p_, other.p_);
qSwap(key_, other.key_);
qSwap(index_, other.index_);
}
#endif

View File

@ -1,79 +0,0 @@
/*****************************************************************************
* gta5view Grand Theft Auto V Profile Viewer
* Copyright (C) 2016 Syping
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*****************************************************************************/
#ifndef QJSON_VALUEREF_H_
#define QJSON_VALUEREF_H_
#include <QtCore/QtGlobal>
#if QT_VERSION >= 0x050000
#include <QtCore/QJsonValueRef>
#else
#include "QJsonValue.h"
class QJsonRoot;
class QJsonValueRef {
public:
QJsonValueRef(QJsonArray *array, int idx);
// slight variant from official APIs implementation
QJsonValueRef(QJsonObject *object, const QString &key);
public:
operator QJsonValue() const;
public:
QJsonValueRef &operator=(const QJsonValue &val);
QJsonValueRef &operator=(const QJsonValueRef &val);
public:
QJsonValue::Type type() const;
bool isNull() const;
bool isBool() const;
bool isDouble() const;
bool isString() const;
bool isArray() const;
bool isObject() const;
bool isUndefined() const;
public:
bool toBool() const;
double toDouble() const;
QString toString() const;
QJsonArray toArray() const;
QJsonObject toObject() const;
int toInt(int defaultValue = 0) const;
public:
bool operator==(const QJsonValue &other) const;
bool operator!=(const QJsonValue &other) const;
private:
QJsonValue toValue() const;
void swap(QJsonValueRef &other);
private:
QJsonRoot *p_;
int index_;
QString key_;
};
#endif
#endif

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,10 +0,0 @@
<RCC>
<qresource prefix="/tr">
<file>qt_de.qm</file>
<file>qt_fr.qm</file>
<file>qt_ko.qm</file>
<file>qt_ru.qm</file>
<file>qt_uk.qm</file>
<file>qt_zh_TW.qm</file>
</qresource>
</RCC>

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,5 +0,0 @@
<RCC>
<qresource prefix="/template">
<file>template.g5e</file>
</qresource>
</RCC>

View File

@ -1,6 +1,6 @@
/*****************************************************************************
* gta5view Grand Theft Auto V Profile Viewer
* Copyright (C) 2016-2021 Syping
* Copyright (C) 2016-2023 Syping
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -29,11 +29,7 @@ AboutDialog::AboutDialog(QWidget *parent) :
ui(new Ui::AboutDialog)
{
// Set Window Flags
#if QT_VERSION >= 0x050900
setWindowFlag(Qt::WindowContextHelpButtonHint, false);
#else
setWindowFlags(windowFlags()^Qt::WindowContextHelpButtonHint);
#endif
// Build Strings
QString appVersion = QApplication::applicationVersion();

View File

@ -1,6 +1,6 @@
/*****************************************************************************
* gta5view Grand Theft Auto V Profile Viewer
* Copyright (C) 2016-2021 Syping
* Copyright (C) 2016-2023 Syping
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -51,21 +51,25 @@ QString AppEnv::getBuildCode()
// Folder Stuff
QString AppEnv::getGameFolder(bool *ok)
QString AppEnv::getGTAVFolder(bool *ok)
{
QDir dir;
QString GTAV_FOLDER = QString::fromUtf8(qgetenv("GTAV_FOLDER"));
if (GTAV_FOLDER != "") {
if (!GTAV_FOLDER.isEmpty()) {
dir.setPath(GTAV_FOLDER);
if (dir.exists()) {
if (ok != NULL)
if (ok)
*ok = true;
qputenv("GTAV_FOLDER", dir.absolutePath().toUtf8());
return dir.absolutePath();
}
}
#ifdef Q_OS_UNIX
// TODO: Try to locate the Steam Proton GTA V folder
const QString GTAV_defaultFolder = StandardPaths::documentsLocation() % "/Rockstar Games/GTA V";
#else
const QString GTAV_defaultFolder = StandardPaths::documentsLocation() % "/Rockstar Games/GTA V";
#endif
QString GTAV_returnFolder = GTAV_defaultFolder;
QSettings settings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR);
@ -74,48 +78,100 @@ QString AppEnv::getGameFolder(bool *ok)
GTAV_returnFolder = settings.value("dir", GTAV_defaultFolder).toString();
settings.endGroup();
settings.beginGroup("GameDirectory");
settings.beginGroup("GTA V");
forceDir = settings.value("ForceCustom", forceDir).toBool();
GTAV_returnFolder = settings.value("Directory", GTAV_returnFolder).toString();
settings.endGroup();
settings.endGroup();
if (forceDir) {
dir.setPath(GTAV_returnFolder);
if (dir.exists()) {
if (ok != 0)
if (ok)
*ok = true;
qputenv("GTAV_FOLDER", dir.absolutePath().toUtf8());
return dir.absolutePath();
}
}
dir.setPath(GTAV_defaultFolder);
if (dir.exists()) {
if (ok != 0)
if (ok)
*ok = true;
qputenv("GTAV_FOLDER", dir.absolutePath().toUtf8());
return dir.absolutePath();
}
if (!forceDir) {
dir.setPath(GTAV_returnFolder);
if (dir.exists()) {
if (ok != 0)
if (ok)
*ok = true;
qputenv("GTAV_FOLDER", dir.absolutePath().toUtf8());
return dir.absolutePath();
}
}
if (ok != 0)
if (ok)
*ok = false;
return QString();
}
bool AppEnv::setGameFolder(QString gameFolder)
QString AppEnv::getRDR2Folder(bool *ok)
{
QDir dir;
dir.setPath(gameFolder);
if (dir.exists()) {
qputenv("GTAV_FOLDER", dir.absolutePath().toUtf8());
return true;
QString RDR2_FOLDER = QString::fromUtf8(qgetenv("RDR2_FOLDER"));
if (!RDR2_FOLDER.isEmpty()) {
dir.setPath(RDR2_FOLDER);
if (dir.exists()) {
if (ok)
*ok = true;
return dir.absolutePath();
}
}
return false;
#ifdef Q_OS_UNIX
// TODO: Try to locate the Steam Proton RDR 2 folder
const QString RDR2_defaultFolder = StandardPaths::documentsLocation() % "/Rockstar Games/Red Dead Redemption 2";
#else
const QString RDR2_defaultFolder = StandardPaths::documentsLocation() % "/Rockstar Games/Red Dead Redemption 2";
#endif
QString RDR2_returnFolder = RDR2_defaultFolder;
QSettings settings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR);
settings.beginGroup("GameDirectory");
settings.beginGroup("RDR 2");
bool forceDir = settings.value("ForceCustom", false).toBool();
RDR2_returnFolder = settings.value("Directory", RDR2_defaultFolder).toString();
settings.endGroup();
settings.endGroup();
if (forceDir) {
dir.setPath(RDR2_returnFolder);
if (dir.exists()) {
if (ok)
*ok = true;
return dir.absolutePath();
}
}
dir.setPath(RDR2_defaultFolder);
if (dir.exists()) {
if (ok)
*ok = true;
return dir.absolutePath();
}
if (!forceDir) {
dir.setPath(RDR2_returnFolder);
if (dir.exists()) {
if (ok)
*ok = true;
return dir.absolutePath();
}
}
if (ok)
*ok = false;
return QString();
}
QString AppEnv::getExLangFolder()
@ -167,33 +223,7 @@ QString AppEnv::getShareFolder()
QByteArray AppEnv::getUserAgent()
{
#if QT_VERSION >= 0x050400
#ifdef Q_OS_WIN
QString kernelVersion = QSysInfo::kernelVersion();
const QStringList &kernelVersionList = kernelVersion.split(".");
if (kernelVersionList.length() > 2) {
kernelVersion = kernelVersionList.at(0) % "." % kernelVersionList.at(1);
}
QString runArch = QSysInfo::buildCpuArchitecture();
if (runArch == "x86_64") {
runArch = "Win64; x64";
}
else if (runArch == "i686") {
const QString &curArch = QSysInfo::currentCpuArchitecture();
if (curArch == "x86_64") {
runArch = "WOW64";
}
else if (curArch == "i686") {
runArch = "Win32; x86";
}
}
return QString("Mozilla/5.0 (Windows NT %1; %2) %3/%4").arg(kernelVersion, runArch, GTA5SYNC_APPSTR, GTA5SYNC_APPVER).toUtf8();
#else
return QString("Mozilla/5.0 (%1; %2) %3/%4").arg(QSysInfo::kernelType(), QSysInfo::kernelVersion(), GTA5SYNC_APPSTR, GTA5SYNC_APPVER).toUtf8();
#endif
#else
return QString("Mozilla/5.0 %1/%2").arg(GTA5SYNC_APPSTR, GTA5SYNC_APPVER).toUtf8();
#endif
}
QUrl AppEnv::getCrewFetchingUrl(QString crewID)
@ -213,7 +243,7 @@ QUrl AppEnv::getPlayerFetchingUrl(QString crewID, int pageNumber)
// Game Stuff
GameVersion AppEnv::getGameVersion()
GameVersion AppEnv::getGTAVVersion()
{
#ifdef Q_OS_WIN
QString argumentValue;
@ -262,7 +292,7 @@ GameVersion AppEnv::getGameVersion()
#endif
}
GameLanguage AppEnv::getGameLanguage(GameVersion gameVersion)
GameLanguage AppEnv::getGTAVLanguage(GameVersion gameVersion)
{
if (gameVersion == GameVersion::SocialClubVersion) {
#ifdef Q_OS_WIN
@ -369,77 +399,11 @@ QString AppEnv::gameLanguageToString(GameLanguage gameLanguage)
}
}
bool AppEnv::setGameLanguage(GameVersion gameVersion, GameLanguage gameLanguage)
{
bool socialClubVersion = false;
bool steamVersion = false;
if (gameVersion == GameVersion::SocialClubVersion) {
socialClubVersion = true;
}
else if (gameVersion == GameVersion::SteamVersion) {
steamVersion = true;
}
else if (gameVersion == GameVersion::BothVersions) {
socialClubVersion = true;
steamVersion = true;
}
else {
return false;
}
if (socialClubVersion) {
#ifdef Q_OS_WIN
QString argumentValue;
#ifdef _WIN64
argumentValue = "\\WOW6432Node";
#endif
QSettings registrySettingsSc(QString("HKEY_LOCAL_MACHINE\\SOFTWARE%1\\Rockstar Games\\Grand Theft Auto V").arg(argumentValue), QSettings::NativeFormat);
if (gameLanguage != GameLanguage::Undefined) {
registrySettingsSc.setValue("Language", gameLanguageToString(gameLanguage));
}
else {
registrySettingsSc.remove("Language");
}
registrySettingsSc.sync();
if (registrySettingsSc.status() != QSettings::NoError) {
return false;
}
#else
Q_UNUSED(gameLanguage)
#endif
}
if (steamVersion) {
#ifdef Q_OS_WIN
QString argumentValue;
#ifdef _WIN64
argumentValue = "\\WOW6432Node";
#endif
QSettings registrySettingsSteam(QString("HKEY_LOCAL_MACHINE\\SOFTWARE%1\\Rockstar Games\\Grand Theft Auto V Steam").arg(argumentValue), QSettings::NativeFormat);
if (gameLanguage != GameLanguage::Undefined) {
registrySettingsSteam.setValue("Language", gameLanguageToString(gameLanguage));
}
else {
registrySettingsSteam.remove("Language");
}
registrySettingsSteam.sync();
if (registrySettingsSteam.status() != QSettings::NoError) {
return false;
}
#else
Q_UNUSED(gameLanguage)
#endif
}
return true;
}
// Screen Stuff
qreal AppEnv::screenRatio()
{
#if QT_VERSION >= 0x050000
qreal dpi = QApplication::primaryScreen()->logicalDotsPerInch();
#else
qreal dpi = QApplication::desktop()->logicalDpiX();
#endif
#ifdef Q_OS_MAC
return (dpi / 72);
#else
@ -449,9 +413,5 @@ qreal AppEnv::screenRatio()
qreal AppEnv::screenRatioPR()
{
#if QT_VERSION >= 0x050600
return QApplication::primaryScreen()->devicePixelRatio();
#else
return 1;
#endif
}

View File

@ -1,6 +1,6 @@
/*****************************************************************************
* gta5view Grand Theft Auto V Profile Viewer
* Copyright (C) 2016-2021 Syping
* Copyright (C) 2016-2023 Syping
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -35,8 +35,8 @@ public:
static QString getBuildCode();
// Folder Stuff
static QString getGameFolder(bool *ok = 0);
static bool setGameFolder(QString gameFolder);
static QString getGTAVFolder(bool *ok = 0);
static QString getRDR2Folder(bool *ok = 0);
static QString getExLangFolder();
static QString getInLangFolder();
static QString getImagesFolder();
@ -50,11 +50,10 @@ public:
static QUrl getPlayerFetchingUrl(QString crewID, int pageNumber);
// Game Stuff
static GameVersion getGameVersion();
static GameLanguage getGameLanguage(GameVersion gameVersion);
static GameVersion getGTAVVersion();
static GameLanguage getGTAVLanguage(GameVersion gameVersion);
static GameLanguage gameLanguageFromString(QString gameLanguage);
static QString gameLanguageToString(GameLanguage gameLanguage);
static bool setGameLanguage(GameVersion gameVersion, GameLanguage gameLanguage);
// Screen Stuff
static qreal screenRatio();

View File

@ -26,6 +26,7 @@
#include "config.h"
#include <QStringBuilder>
#include <QApplication>
#include <QSaveFile>
#include <QFileInfo>
#include <QFile>
@ -35,131 +36,56 @@
#include <QDesktopWidget>
#endif
ExportThread::ExportThread(QMap<ProfileWidget*,QString> profileMap, QString exportDirectory, bool pictureCopyEnabled, bool pictureExportEnabled, int exportCount, QObject *parent) : QThread(parent),
ExportThread::ExportThread(QHash<ProfileWidget*,QString> profileMap, QString exportDirectory, bool pictureCopyEnabled, bool pictureExportEnabled, int exportCount, QObject *parent) : QThread(parent),
profileMap(profileMap), exportDirectory(exportDirectory), pictureCopyEnabled(pictureCopyEnabled), pictureExportEnabled(pictureExportEnabled), exportCount(exportCount)
{
}
void ExportThread::run()
{
QSettings settings(GTA5SYNC_APPVENDOR, GTA5SYNC_APPSTR);
// Picture Settings
// Quality Settings
settings.beginGroup("Pictures");
int defaultQuality = 100;
QSize defExportSize = SnapmaticPicture::getSnapmaticResolution();
int customQuality = settings.value("CustomQuality", defaultQuality).toInt();
if (customQuality < 1 || customQuality > 100)
{
customQuality = 100;
}
bool useCustomQuality = settings.value("CustomQualityEnabled", false).toBool();
// Size Settings
QSize cusExportSize = settings.value("CustomSize", defExportSize).toSize();
if (cusExportSize.width() > 3840)
{
cusExportSize.setWidth(3840);
}
else if (cusExportSize.height() > 2160)
{
cusExportSize.setHeight(2160);
}
if (cusExportSize.width() < 1)
{
cusExportSize.setWidth(1);
}
else if (cusExportSize.height() < 1)
{
cusExportSize.setHeight(1);
}
QString sizeMode = settings.value("ExportSizeMode", "Default").toString();
Qt::AspectRatioMode aspectRatio = (Qt::AspectRatioMode)settings.value("AspectRatio", Qt::KeepAspectRatio).toInt();
settings.endGroup();
// End Picture Settings
int intExportProgress = 0;
for (ProfileWidget *widget : profileMap.keys())
{
if (widget->isSelected())
{
if (widget->getWidgetType() == "SnapmaticWidget")
{
size_t intExportProgress = 0;
for (ProfileWidget *widget : profileMap.keys()) {
if (widget->isSelected()) {
if (widget->getWidgetType() == "SnapmaticWidget") {
SnapmaticWidget *picWidget = qobject_cast<SnapmaticWidget*>(widget);
SnapmaticPicture *picture = picWidget->getPicture();
if (pictureExportEnabled)
{
if (pictureExportEnabled) {
QString exportFileName = PictureExport::getPictureFileName(picture);
if (exportFileName.right(4) != ".jpg" && exportFileName.right(4) != ".png")
{
if (!exportFileName.endsWith(".jpg"))
exportFileName += ".jpg";
}
intExportProgress++;
emit exportStringUpdate(ProfileInterface::tr("Export file %1 of %2 files").arg(QString::number(intExportProgress), QString::number(exportCount)));
emit exportProgressUpdate(intExportProgress);
// Scale Picture
QImage exportPicture = picture->getImage();
if (sizeMode == "Desktop")
{
#if QT_VERSION >= 0x050000
qreal screenRatioPR = AppEnv::screenRatioPR();
QRect desktopResolution = QApplication::primaryScreen()->geometry();
int desktopSizeWidth = qRound((double)desktopResolution.width() * screenRatioPR);
int desktopSizeHeight = qRound((double)desktopResolution.height() * screenRatioPR);
#else
QRect desktopResolution = QApplication::desktop()->screenGeometry();
int desktopSizeWidth = desktopResolution.width();
int desktopSizeHeight = desktopResolution.height();
#endif
exportPicture = exportPicture.scaled(desktopSizeWidth, desktopSizeHeight, aspectRatio, Qt::SmoothTransformation);
}
else if (sizeMode == "Custom")
{
exportPicture = exportPicture.scaled(cusExportSize, aspectRatio, Qt::SmoothTransformation);
}
bool isSaved;
if (useCustomQuality)
{
isSaved = exportPicture.save(exportDirectory % "/" % exportFileName, "JPEG", customQuality);
}
else
{
isSaved = exportPicture.save(exportDirectory % "/" % exportFileName, "JPEG", 100);
bool isSaved = false;
QSaveFile exportFile(exportDirectory % "/" % exportFileName);
if (exportFile.open(QIODevice::WriteOnly)) {
exportFile.write(picture->getPictureStream());
isSaved = exportFile.commit();
}
if (!isSaved)
{
failedExportPictures += exportFileName;
}
}
if (pictureCopyEnabled)
{
if (pictureCopyEnabled) {
QString exportFileName = PictureExport::getPictureFileName(picture);
if (exportFileName.right(4) != ".g5e")
{
if (!exportFileName.endsWith(".g5e"))
exportFileName += ".g5e";
}
intExportProgress++;
emit exportStringUpdate(ProfileInterface::tr("Export file %1 of %2 files").arg(QString::number(intExportProgress), QString::number(exportCount)));
emit exportProgressUpdate(intExportProgress);
QString exportFilePath = exportDirectory % "/" % exportFileName;
if (QFile::exists(exportFilePath)) {QFile::remove(exportFilePath);}
if (QFile::exists(exportFilePath))
QFile::remove(exportFilePath);
if (!picture->exportPicture(exportDirectory % "/" % exportFileName, SnapmaticFormat::G5E_Format))
{
failedCopyPictures += exportFileName;
}
}
}
else if (widget->getWidgetType() == "SavegameWidget")
{
else if (widget->getWidgetType() == "SavegameWidget") {
SavegameWidget *sgdWidget = qobject_cast<SavegameWidget*>(widget);
SavegameData *savegame = sgdWidget->getSavegame();
@ -172,11 +98,10 @@ void ExportThread::run()
emit exportProgressUpdate(intExportProgress);
QString exportFilePath = exportDirectory % "/" % exportFileName;
if (QFile::exists(exportFilePath)) {QFile::remove(exportFilePath);}
if (QFile::exists(exportFilePath))
QFile::remove(exportFilePath);
if (!QFile::copy(originalFileName, exportFilePath))
{
failedSavegames += exportFileName;
}
}
}
}

View File

@ -1,6 +1,6 @@
/*****************************************************************************
* gta5view Grand Theft Auto V Profile Viewer
* Copyright (C) 2016-2017 Syping
* Copyright (C) 2016-2023 Syping
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -29,7 +29,7 @@ class ExportThread : public QThread
{
Q_OBJECT
public:
explicit ExportThread(QMap<ProfileWidget*,QString> profileMap, QString exportDirectory, bool pictureCopyEnabled, bool pictureExportEnabled, int exportCount, QObject *parent = 0);
explicit ExportThread(QHash<ProfileWidget*,QString> profileMap, QString exportDirectory, bool pictureCopyEnabled, bool pictureExportEnabled, int exportCount, QObject *parent = 0);
QStringList getFailedSavegames();
QStringList getFailedCopyPictures();
QStringList getFailedExportPictures();
@ -38,7 +38,7 @@ protected:
void run();
private:
QMap <ProfileWidget*, QString> profileMap;
QHash<ProfileWidget*,QString> profileMap;
QString exportDirectory;
bool pictureCopyEnabled;
bool pictureExportEnabled;

Some files were not shown because too many files have changed in this diff Show More