├── .gitattributes ├── .github ├── ISSUE_TEMPLATE │ └── bug_report.md └── workflows │ ├── gradle-win.yml │ └── gradle.yml ├── .gitignore ├── .gitmodules ├── .idea ├── copyright │ ├── Emerson_Pinter.xml │ └── profiles_settings.xml ├── inspectionProfiles │ └── Project_Default.xml └── vcs.xml ├── CHANGELOG.md ├── LICENSE ├── README.md ├── assets ├── screenshot_archive.png ├── screenshot_attributes.png ├── screenshot_characters.png ├── screenshot_misc.png └── screenshot_skills.png ├── build.gradle ├── gradle ├── libs.versions.toml ├── patchModulesJar.gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle └── src ├── dist ├── TQRespec.sh ├── texconverter-cli.sh └── tqextract-cli.sh ├── images ├── about.xcf ├── about_character.xcf ├── icon.png ├── icon.xcf ├── icon2.xcf ├── topdecoration.xcf ├── window.xcf └── window2.xcf ├── main ├── java │ ├── br │ │ └── com │ │ │ └── pinter │ │ │ └── tqrespec │ │ │ ├── Main.java │ │ │ ├── Settings.java │ │ │ ├── core │ │ │ ├── ExceptionHandler.java │ │ │ ├── GameNotFoundException.java │ │ │ ├── GameProcessMonitor.java │ │ │ ├── GuiceModule.java │ │ │ ├── InjectionContext.java │ │ │ ├── MyEventHandler.java │ │ │ ├── MyTask.java │ │ │ ├── ResourceNotFoundException.java │ │ │ ├── SingleInstanceLock.java │ │ │ ├── State.java │ │ │ ├── UnhandledRuntimeException.java │ │ │ ├── WorkerThread.java │ │ │ └── package-info.java │ │ │ ├── gui │ │ │ ├── AboutController.java │ │ │ ├── AppPreloader.java │ │ │ ├── AttributesPaneController.java │ │ │ ├── CharacterListCell.java │ │ │ ├── CharactersViewController.java │ │ │ ├── CheckVersionService.java │ │ │ ├── CopyTarget.java │ │ │ ├── CustomMap.java │ │ │ ├── DifficultyItem.java │ │ │ ├── Icon.java │ │ │ ├── MainController.java │ │ │ ├── MiscPaneController.java │ │ │ ├── ResizeListener.java │ │ │ ├── ResourceHelper.java │ │ │ ├── SkillListCell.java │ │ │ ├── SkillListViewItem.java │ │ │ ├── SkillsPaneController.java │ │ │ ├── TeleportItem.java │ │ │ ├── Toast.java │ │ │ ├── UIUtils.java │ │ │ └── UiPlayerProperties.java │ │ │ ├── logging │ │ │ ├── JULLogger.java │ │ │ ├── JULLoggerFinder.java │ │ │ ├── Log.java │ │ │ └── OutputStreamLog.java │ │ │ ├── save │ │ │ ├── BlockInfo.java │ │ │ ├── BlockType.java │ │ │ ├── DataChange.java │ │ │ ├── DataChangeRaw.java │ │ │ ├── DataChangeVariable.java │ │ │ ├── DeepCloneable.java │ │ │ ├── FileBlockType.java │ │ │ ├── FileDataHolder.java │ │ │ ├── FileDataMap.java │ │ │ ├── FileParser.java │ │ │ ├── FileVariable.java │ │ │ ├── FileWriter.java │ │ │ ├── IncompatibleSavegameException.java │ │ │ ├── InvalidVariableException.java │ │ │ ├── Platform.java │ │ │ ├── SaveLocation.java │ │ │ ├── UID.java │ │ │ ├── VariableInfo.java │ │ │ ├── VariableType.java │ │ │ ├── exporter │ │ │ │ ├── Exporter.java │ │ │ │ ├── Node.java │ │ │ │ └── NodeSerializer.java │ │ │ ├── player │ │ │ │ ├── Archiver.java │ │ │ │ ├── CurrentPlayerData.java │ │ │ │ ├── Gender.java │ │ │ │ ├── HeaderInfo.java │ │ │ │ ├── Player.java │ │ │ │ ├── PlayerBlockType.java │ │ │ │ ├── PlayerFileVariable.java │ │ │ │ ├── PlayerLoader.java │ │ │ │ ├── PlayerParser.java │ │ │ │ ├── PlayerSkill.java │ │ │ │ ├── PlayerWriter.java │ │ │ │ └── TeleportDifficulty.java │ │ │ └── stash │ │ │ │ ├── StashBlockType.java │ │ │ │ ├── StashData.java │ │ │ │ ├── StashFileVariable.java │ │ │ │ ├── StashLoader.java │ │ │ │ ├── StashParser.java │ │ │ │ └── StashWriter.java │ │ │ ├── tqdata │ │ │ ├── Db.java │ │ │ ├── DefaultAct.java │ │ │ ├── DefaultMapTeleport.java │ │ │ ├── GameInfo.java │ │ │ ├── GameResources.java │ │ │ ├── GameVersion.java │ │ │ ├── InstallType.java │ │ │ ├── MapTeleport.java │ │ │ ├── Mastery.java │ │ │ ├── PlayerCharacter.java │ │ │ ├── PlayerCharacterFile.java │ │ │ └── Txt.java │ │ │ └── util │ │ │ ├── Build.java │ │ │ ├── Constants.java │ │ │ └── Version.java │ ├── dev │ │ └── pinter │ │ │ └── tqextract │ │ │ ├── Cli.java │ │ │ ├── Extract.java │ │ │ ├── README.md │ │ │ ├── TexConverterCli.java │ │ │ ├── decompiler │ │ │ ├── MapBlock.java │ │ │ ├── MapDecompiler.java │ │ │ ├── MapLevel.java │ │ │ └── MapTga.java │ │ │ └── image │ │ │ └── DDSReader.java │ └── module-info.java └── resources │ ├── fxml │ ├── about.css │ ├── about.fxml │ ├── about_bg.png │ ├── about_character.png │ ├── bg-button.png │ ├── bg-button_pressed.png │ ├── border.png │ ├── characters.fxml │ ├── close.png │ ├── close_pressed.png │ ├── decoleft.png │ ├── decoright.png │ ├── fa5-free-solid-900.ttf │ ├── font │ │ ├── Marcellus-Regular-license.txt │ │ ├── Marcellus-Regular.ttf │ │ ├── Roboto-Regular-license.txt │ │ ├── Roboto-Regular.ttf │ │ ├── font-albertus_mt.css │ │ ├── font-albertus_mt_light.css │ │ ├── font-default.css │ │ ├── font-nonlatin.css │ │ └── font-title-albertus_mt.css │ ├── main.css │ ├── main.fxml │ ├── preloader.css │ ├── preloader_bg.png │ ├── sv.png │ ├── tab_misc.fxml │ ├── tab_points.fxml │ ├── tab_skills.fxml │ ├── topbar_center.png │ ├── topbar_region.png │ ├── topdeco.png │ ├── topdecoration.png │ ├── window.png │ └── window_bg.png │ ├── i18n │ ├── UI.properties │ ├── UI_fr.properties │ ├── UI_it.properties │ ├── UI_pt_BR.properties │ ├── UI_ru.properties │ └── UI_uk.properties │ └── icon │ ├── icon128.ico │ ├── icon128.png │ ├── icon16.ico │ ├── icon16.png │ ├── icon256.ico │ ├── icon256.png │ ├── icon32.ico │ ├── icon32.png │ ├── icon64.ico │ └── icon64.png └── test ├── java └── br │ └── com │ └── pinter │ └── tqrespec │ ├── VersionTest.java │ └── save │ └── player │ ├── GuiceInjector.java │ ├── PlayerParserTest.java │ ├── PlayerTest.java │ └── PlayerWriterTest.java └── resources ├── _mobile └── Player.chr ├── _savegame ├── Player.chr ├── winsys.dxb └── winsys.dxg ├── _savegame2 ├── Player.chr ├── winsys.dxb └── winsys.dxg └── _savegame3 └── Player.chr /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | *.java text 3 | *.sh text eol=lf 4 | *.properties text 5 | *.gradle text 6 | gradlew text eol=lf 7 | gradlew.bat text eol=crlf 8 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: Bug 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | ***To Reproduce*** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | ***Expected behavior*** 21 | A clear and concise description of what you expected to happen. 22 | 23 | ***Error message (detail)*** 24 | - Paste the error message here 25 | 26 | ***TQRespec version (please complete the following information):*** 27 | - ? 28 | 29 | ***Operating System (please complete the following information):*** 30 | - Windows? 31 | 32 | ***Game version (please complete the following information):*** 33 | - Titan Quest? 34 | 35 | ***DLCs installed (please complete the following information):*** 36 | -Ragnarok? 37 | -Atlantis? 38 | 39 | ***Additional context*** 40 | Add any other context about the problem here. 41 | -------------------------------------------------------------------------------- /.github/workflows/gradle-win.yml: -------------------------------------------------------------------------------- 1 | # This workflow uses actions that are not certified by GitHub. 2 | # They are provided by a third-party and are governed by 3 | # separate terms of service, privacy policy, and support 4 | # documentation. 5 | # This workflow will build a Java project with Gradle and cache/restore any dependencies to improve the workflow execution time 6 | # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-gradle 7 | 8 | name: Java CI with Gradle 9 | 10 | on: 11 | push: 12 | branches: [ "master" ] 13 | pull_request: 14 | branches: [ "master" ] 15 | 16 | jobs: 17 | build: 18 | 19 | runs-on: windows-latest 20 | permissions: 21 | contents: read 22 | 23 | steps: 24 | - uses: actions/checkout@v4 25 | with: 26 | submodules: 'true' 27 | - name: Set up JDK 21 28 | uses: actions/setup-java@v4 29 | with: 30 | java-version: '21' 31 | distribution: 'temurin' 32 | 33 | # Configure Gradle for optimal use in GitHub Actions, including caching of downloaded dependencies. 34 | # See: https://github.com/gradle/actions/blob/main/setup-gradle/README.md 35 | - name: Setup Gradle 36 | uses: gradle/actions/setup-gradle@af1da67850ed9a4cedd57bfd976089dd991e2582 # v4.0.0 37 | 38 | - name: Build with Gradle Wrapper 39 | run: ./gradlew archiveAppimage 40 | 41 | - name: Set sha short 42 | id: myvars 43 | run: | 44 | "gitsha_short=$(git rev-parse --short HEAD)" >> $env:GITHUB_OUTPUT 45 | 46 | - name: Upload build artifacts 47 | uses: actions/upload-artifact@v4 48 | with: 49 | name: ${{ env.APP_BUILDPACKAGENAME }}-g${{ steps.myvars.outputs.gitsha_short }} 50 | path: build/app-image 51 | 52 | dependency-submission: 53 | 54 | runs-on: windows-latest 55 | permissions: 56 | contents: write 57 | 58 | steps: 59 | - uses: actions/checkout@v4 60 | with: 61 | submodules: 'true' 62 | - name: Set up JDK 21 63 | uses: actions/setup-java@v4 64 | with: 65 | java-version: '21' 66 | distribution: 'temurin' 67 | 68 | # Generates and submits a dependency graph, enabling Dependabot Alerts for all project dependencies. 69 | # See: https://github.com/gradle/actions/blob/main/dependency-submission/README.md 70 | - name: Generate and submit dependency graph 71 | uses: gradle/actions/dependency-submission@af1da67850ed9a4cedd57bfd976089dd991e2582 # v4.0.0 72 | -------------------------------------------------------------------------------- /.github/workflows/gradle.yml: -------------------------------------------------------------------------------- 1 | # This workflow uses actions that are not certified by GitHub. 2 | # They are provided by a third-party and are governed by 3 | # separate terms of service, privacy policy, and support 4 | # documentation. 5 | # This workflow will build a Java project with Gradle and cache/restore any dependencies to improve the workflow execution time 6 | # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-gradle 7 | 8 | name: Java CI with Gradle 9 | 10 | on: 11 | push: 12 | branches: [ "dev" ] 13 | pull_request: 14 | branches: [ "dev" ] 15 | 16 | jobs: 17 | build: 18 | 19 | runs-on: ubuntu-latest 20 | permissions: 21 | contents: read 22 | 23 | steps: 24 | - uses: actions/checkout@v4 25 | with: 26 | submodules: 'true' 27 | - name: Set up JDK 21 28 | uses: actions/setup-java@v4 29 | with: 30 | java-version: '21' 31 | distribution: 'temurin' 32 | 33 | # Configure Gradle for optimal use in GitHub Actions, including caching of downloaded dependencies. 34 | # See: https://github.com/gradle/actions/blob/main/setup-gradle/README.md 35 | - name: Setup Gradle 36 | uses: gradle/actions/setup-gradle@af1da67850ed9a4cedd57bfd976089dd991e2582 # v4.0.0 37 | 38 | - name: Build with Gradle Wrapper 39 | run: ./gradlew archiveAppimage 40 | 41 | # NOTE: The Gradle Wrapper is the default and recommended way to run Gradle (https://docs.gradle.org/current/userguide/gradle_wrapper.html). 42 | # If your project does not have the Gradle Wrapper configured, you can use the following configuration to run Gradle with a specified version. 43 | # 44 | # - name: Setup Gradle 45 | # uses: gradle/actions/setup-gradle@af1da67850ed9a4cedd57bfd976089dd991e2582 # v4.0.0 46 | # with: 47 | # gradle-version: '8.9' 48 | # 49 | # - name: Build with Gradle 8.9 50 | # run: gradle build 51 | 52 | dependency-submission: 53 | 54 | runs-on: ubuntu-latest 55 | permissions: 56 | contents: write 57 | 58 | steps: 59 | - uses: actions/checkout@v4 60 | with: 61 | submodules: 'true' 62 | - name: Set up JDK 21 63 | uses: actions/setup-java@v4 64 | with: 65 | java-version: '21' 66 | distribution: 'temurin' 67 | 68 | # Generates and submits a dependency graph, enabling Dependabot Alerts for all project dependencies. 69 | # See: https://github.com/gradle/actions/blob/main/dependency-submission/README.md 70 | - name: Generate and submit dependency graph 71 | uses: gradle/actions/dependency-submission@af1da67850ed9a4cedd57bfd976089dd991e2582 # v4.0.0 72 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | gamedata/ 2 | savedata/ 3 | libs/ 4 | src/test/resources/_testcopy/ 5 | src/test/resources/_testplayer/ 6 | *.arz 7 | *.arc 8 | hs_err_pid* 9 | .gradle 10 | 11 | ##Intellij 12 | .idea/** 13 | *.iml 14 | *.ipr 15 | !/.idea/copyright/** 16 | !/.idea/inspectionProfiles/Project_Default.xml 17 | !/.idea/vcs.xml 18 | 19 | # CMake 20 | cmake-build-debug/ 21 | cmake-build-release/ 22 | 23 | # Mongo Explorer plugin: 24 | .idea/**/mongoSettings.xml 25 | 26 | ## File-based project format: 27 | *.iws 28 | 29 | ## Plugin-specific files: 30 | 31 | # IntelliJ 32 | out/ 33 | build/ 34 | 35 | # mpeltonen/sbt-idea plugin 36 | .idea_modules/ 37 | 38 | # JIRA plugin 39 | atlassian-ide-plugin.xml 40 | 41 | # Cursive Clojure plugin 42 | .idea/replstate.xml 43 | 44 | # Crashlytics plugin (for Android Studio and IntelliJ) 45 | com_crashlytics_export_strings.xml 46 | crashlytics.properties 47 | crashlytics-build.properties 48 | fabric.properties 49 | 50 | 51 | #### https://github.com/github/gitignore/blob/master/Global/Eclipse.gitignore 52 | .metadata 53 | bin/ 54 | tmp/ 55 | *.tmp 56 | *.bak 57 | *.swp 58 | *~.nib 59 | local.properties 60 | .settings/ 61 | .loadpath 62 | .recommenders 63 | 64 | # External tool builders 65 | .externalToolBuilders/ 66 | 67 | # Locally stored "Eclipse launch configurations" 68 | *.launch 69 | 70 | # PyDev specific (Python IDE for Eclipse) 71 | *.pydevproject 72 | 73 | # CDT-specific (C/C++ Development Tooling) 74 | .cproject 75 | 76 | # CDT- autotools 77 | .autotools 78 | 79 | # Java annotation processor (APT) 80 | .factorypath 81 | 82 | # PDT-specific (PHP Development Tools) 83 | .buildpath 84 | 85 | # sbteclipse plugin 86 | .target 87 | 88 | # Tern plugin 89 | .tern-project 90 | 91 | # TeXlipse plugin 92 | .texlipse 93 | 94 | # STS (Spring Tool Suite) 95 | .springBeans 96 | 97 | # Code Recommenders 98 | .recommenders/ 99 | 100 | # Scala IDE specific (Scala & Java development for Eclipse) 101 | .cache-main 102 | .scala_dependencies 103 | .worksheet 104 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "sdk"] 2 | path = sdk 3 | url = https://github.com/epinter/openjfx-sdk 4 | branch = master 5 | [submodule "tqdatabase"] 6 | path = tqdatabase 7 | url = https://github.com/epinter/tqdatabase 8 | branch = master 9 | -------------------------------------------------------------------------------- /.idea/copyright/Emerson_Pinter.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 21 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /assets/screenshot_archive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epinter/tqrespec/d1b2afb03b6816af1a902e0065db15257c1e6368/assets/screenshot_archive.png -------------------------------------------------------------------------------- /assets/screenshot_attributes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epinter/tqrespec/d1b2afb03b6816af1a902e0065db15257c1e6368/assets/screenshot_attributes.png -------------------------------------------------------------------------------- /assets/screenshot_characters.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epinter/tqrespec/d1b2afb03b6816af1a902e0065db15257c1e6368/assets/screenshot_characters.png -------------------------------------------------------------------------------- /assets/screenshot_misc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epinter/tqrespec/d1b2afb03b6816af1a902e0065db15257c1e6368/assets/screenshot_misc.png -------------------------------------------------------------------------------- /assets/screenshot_skills.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epinter/tqrespec/d1b2afb03b6816af1a902e0065db15257c1e6368/assets/screenshot_skills.png -------------------------------------------------------------------------------- /gradle/libs.versions.toml: -------------------------------------------------------------------------------- 1 | [versions] 2 | junit = "5.13.0-M2" 3 | junit-launcher = "1.13.0-M2" 4 | mockito = "5.17.0" 5 | guava = { strictly = "32.0.1-jre" } 6 | guice = "7.0.0" 7 | commons-lang3 = "3.14.0" 8 | commons-text = "1.12.0" 9 | jna = "5.14.0" 10 | jackson = "2.17.1" 11 | picocli = "4.7.7" 12 | 13 | [libraries] 14 | junit = { module = "org.junit.jupiter:junit-jupiter", version.ref = "junit" } 15 | junit-engine = { module = "org.junit.jupiter:junit-jupiter-engine", version.ref = "junit" } 16 | junit-launcher = { module = "org.junit.platform:junit-platform-launcher", version.ref = "junit-launcher" } 17 | mockito-core = { module = "org.mockito:mockito-core", version.ref = "mockito" } 18 | mockito-junit-jupiter = { module = "org.mockito:mockito-junit-jupiter", version.ref = "mockito" } 19 | guava = { module = "com.google.guava:guava", version.ref = "guava" } 20 | guice = { module = "com.google.inject:guice", version.ref = "guice" } 21 | commons-lang3 = { module = "org.apache.commons:commons-lang3", version.ref = "commons-lang3" } 22 | commons-text = { module = "org.apache.commons:commons-text", version.ref = "commons-text" } 23 | jna = { module = "net.java.dev.jna:jna-platform-jpms", version.ref = "jna" } 24 | jackson-core = { module = "com.fasterxml.jackson.core:jackson-core", version.ref = "jackson" } 25 | jackson-annotations = { module = "com.fasterxml.jackson.core:jackson-annotations", version.ref = "jackson" } 26 | jackson-databind = { module = "com.fasterxml.jackson.core:jackson-databind", version.ref = "jackson" } 27 | picocli = {module = "info.picocli:picocli", version.ref = "picocli"} 28 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epinter/tqrespec/d1b2afb03b6816af1a902e0065db15257c1e6368/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.14-bin.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%"=="" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%"=="" set DIRNAME=. 29 | @rem This is normally unused 30 | set APP_BASE_NAME=%~n0 31 | set APP_HOME=%DIRNAME% 32 | 33 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 34 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 35 | 36 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 37 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 38 | 39 | @rem Find java.exe 40 | if defined JAVA_HOME goto findJavaFromJavaHome 41 | 42 | set JAVA_EXE=java.exe 43 | %JAVA_EXE% -version >NUL 2>&1 44 | if %ERRORLEVEL% equ 0 goto execute 45 | 46 | echo. 1>&2 47 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 48 | echo. 1>&2 49 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2 50 | echo location of your Java installation. 1>&2 51 | 52 | goto fail 53 | 54 | :findJavaFromJavaHome 55 | set JAVA_HOME=%JAVA_HOME:"=% 56 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 57 | 58 | if exist "%JAVA_EXE%" goto execute 59 | 60 | echo. 1>&2 61 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 62 | echo. 1>&2 63 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2 64 | echo location of your Java installation. 1>&2 65 | 66 | goto fail 67 | 68 | :execute 69 | @rem Setup the command line 70 | 71 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 72 | 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if %ERRORLEVEL% equ 0 goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | set EXIT_CODE=%ERRORLEVEL% 85 | if %EXIT_CODE% equ 0 set EXIT_CODE=1 86 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% 87 | exit /b %EXIT_CODE% 88 | 89 | :mainEnd 90 | if "%OS%"=="Windows_NT" endlocal 91 | 92 | :omega 93 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Emerson Pinter - All Rights Reserved 3 | */ 4 | 5 | rootProject.name = 'tqrespec' 6 | include ':tqdatabase' 7 | -------------------------------------------------------------------------------- /src/dist/TQRespec.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | MYDIR=$(realpath "${0%/*}") 3 | OLDLDLIB="" 4 | if [ -n "$LD_LIBRARY_PATH" ]; then 5 | OLDLDLIB=":${LD_LIBRARY_PATH}" 6 | fi 7 | export LD_LIBRARY_PATH=${MYDIR}/lib/runtime/lib${OLDLDLIB} 8 | cd "$MYDIR" 9 | if [ "Xinstall" = "X$1" ]; then 10 | cat < ~/.local/share/applications/TQRespec.desktop 11 | [Desktop Entry] 12 | Name=TQRespec 13 | Comment=The respec tool for Titan Quest 14 | GenericName=TQRespec 15 | Exec=${MYDIR}/TQRespec.sh 16 | Type=Application 17 | StartupNotify=true 18 | StartupWMClass=TQRespec 19 | Categories=Game; 20 | Keywords=TQRespec; 21 | Icon=${MYDIR}/lib/TQRespec.png 22 | Path=${MYDIR} 23 | EOF 24 | elif [ "Xuninstall" = "X$1" ]; then 25 | exec rm -f ~/.local/share/applications/TQRespec.desktop 26 | else 27 | exec ./bin/TQRespec $@ 28 | fi 29 | -------------------------------------------------------------------------------- /src/dist/texconverter-cli.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -e 2 | DIRNAME=$(dirname $0) 3 | resolvepath() { 4 | which realpath > /dev/null 2>&1 && realpath $1 || readlink -f $1 5 | } 6 | MYDIR=$(resolvepath $DIRNAME) 7 | 8 | cd "${MYDIR}" 9 | exec "${MYDIR}/bin/texconverter-cli" "$@" 10 | -------------------------------------------------------------------------------- /src/dist/tqextract-cli.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh -e 2 | DIRNAME=$(dirname $0) 3 | resolvepath() { 4 | which realpath > /dev/null 2>&1 && realpath $1 || readlink -f $1 5 | } 6 | MYDIR=$(resolvepath $DIRNAME) 7 | 8 | cd "${MYDIR}" 9 | exec "${MYDIR}/bin/tqextract-cli" "$@" 10 | -------------------------------------------------------------------------------- /src/images/about.xcf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epinter/tqrespec/d1b2afb03b6816af1a902e0065db15257c1e6368/src/images/about.xcf -------------------------------------------------------------------------------- /src/images/about_character.xcf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epinter/tqrespec/d1b2afb03b6816af1a902e0065db15257c1e6368/src/images/about_character.xcf -------------------------------------------------------------------------------- /src/images/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epinter/tqrespec/d1b2afb03b6816af1a902e0065db15257c1e6368/src/images/icon.png -------------------------------------------------------------------------------- /src/images/icon.xcf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epinter/tqrespec/d1b2afb03b6816af1a902e0065db15257c1e6368/src/images/icon.xcf -------------------------------------------------------------------------------- /src/images/icon2.xcf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epinter/tqrespec/d1b2afb03b6816af1a902e0065db15257c1e6368/src/images/icon2.xcf -------------------------------------------------------------------------------- /src/images/topdecoration.xcf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epinter/tqrespec/d1b2afb03b6816af1a902e0065db15257c1e6368/src/images/topdecoration.xcf -------------------------------------------------------------------------------- /src/images/window.xcf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epinter/tqrespec/d1b2afb03b6816af1a902e0065db15257c1e6368/src/images/window.xcf -------------------------------------------------------------------------------- /src/images/window2.xcf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epinter/tqrespec/d1b2afb03b6816af1a902e0065db15257c1e6368/src/images/window2.xcf -------------------------------------------------------------------------------- /src/main/java/br/com/pinter/tqrespec/core/ExceptionHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Emerson Pinter - All Rights Reserved 3 | */ 4 | 5 | /* This file is part of TQ Respec. 6 | 7 | TQ Respec is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | TQ Respec is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with TQ Respec. If not, see . 19 | */ 20 | 21 | package br.com.pinter.tqrespec.core; 22 | 23 | import br.com.pinter.tqrespec.logging.Log; 24 | import br.com.pinter.tqrespec.util.Build; 25 | import br.com.pinter.tqrespec.util.Constants; 26 | import javafx.application.Platform; 27 | import javafx.scene.control.Alert; 28 | import javafx.scene.control.ButtonType; 29 | import javafx.scene.control.TextArea; 30 | import javafx.scene.layout.GridPane; 31 | import javafx.scene.layout.Priority; 32 | import javafx.stage.Modality; 33 | import org.apache.commons.lang3.exception.ExceptionUtils; 34 | 35 | import java.util.Optional; 36 | 37 | import static java.lang.System.Logger.Level.ERROR; 38 | 39 | public class ExceptionHandler { 40 | private static final System.Logger logger = Log.getLogger(ExceptionHandler.class); 41 | 42 | private ExceptionHandler() { 43 | } 44 | 45 | public static void logAndShow(Throwable e) { 46 | logger.log(ERROR, Constants.ERROR_MSG_EXCEPTION, e); 47 | 48 | if (Platform.isFxApplicationThread()) { 49 | ExceptionHandler.showAlert(e); 50 | } 51 | } 52 | 53 | public static void unhandled(Thread t, Throwable e) { 54 | logAndShow(e); 55 | } 56 | 57 | private static void showAlert(Throwable e) { 58 | String header = ExceptionUtils.getRootCause(e).toString(); 59 | if (header == null) { 60 | header = e.toString(); 61 | } 62 | header = header.replaceAll("^java.lang.RuntimeException: (.*)", "$1"); 63 | header = header.replaceAll("^br.com.pinter.tqrespec.core.UnhandledRuntimeException: (.*)", "$1"); 64 | header = header.replaceAll("^br.com.pinter.tqrespec.(.*)", "$1"); 65 | 66 | Alert alert = new Alert(Alert.AlertType.ERROR); 67 | alert.initModality(Modality.APPLICATION_MODAL); 68 | alert.setTitle(Build.title()); 69 | alert.setHeaderText("An unhandled exception occurred"); 70 | alert.setContentText(header); 71 | 72 | TextArea textArea = new TextArea(ExceptionUtils.getStackTrace(e.getCause() != null ? e.getCause() : e)); 73 | textArea.setEditable(false); 74 | textArea.setWrapText(false); 75 | 76 | textArea.setMaxWidth(Double.MAX_VALUE); 77 | textArea.setMaxHeight(Double.MAX_VALUE); 78 | GridPane.setVgrow(textArea, Priority.ALWAYS); 79 | GridPane.setHgrow(textArea, Priority.ALWAYS); 80 | 81 | GridPane expContent = new GridPane(); 82 | expContent.setMaxWidth(Double.MAX_VALUE); 83 | expContent.add(textArea, 0, 1); 84 | 85 | alert.getDialogPane().setExpandableContent(expContent); 86 | 87 | ButtonType abort = new ButtonType("Abort"); 88 | alert.getButtonTypes().setAll(abort); 89 | 90 | Optional result = alert.showAndWait(); 91 | if (result.isPresent() && result.get() == abort) { 92 | Platform.exit(); 93 | System.exit(0); 94 | } 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /src/main/java/br/com/pinter/tqrespec/core/GameNotFoundException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Emerson Pinter - All Rights Reserved 3 | */ 4 | 5 | /* This file is part of TQ Respec. 6 | 7 | TQ Respec is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | TQ Respec is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with TQ Respec. If not, see . 19 | */ 20 | 21 | package br.com.pinter.tqrespec.core; 22 | 23 | public class GameNotFoundException extends Exception { 24 | public GameNotFoundException() { 25 | super(); 26 | } 27 | 28 | public GameNotFoundException(String message) { 29 | super(message); 30 | } 31 | 32 | public GameNotFoundException(String message, Throwable cause) { 33 | super(message, cause); 34 | } 35 | 36 | public GameNotFoundException(Throwable cause) { 37 | super(cause); 38 | } 39 | 40 | protected GameNotFoundException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { 41 | super(message, cause, enableSuppression, writableStackTrace); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/br/com/pinter/tqrespec/core/GameProcessMonitor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Emerson Pinter - All Rights Reserved 3 | */ 4 | 5 | /* This file is part of TQ Respec. 6 | 7 | TQ Respec is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | TQ Respec is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with TQ Respec. If not, see . 19 | */ 20 | 21 | package br.com.pinter.tqrespec.core; 22 | 23 | import org.apache.commons.lang3.SystemUtils; 24 | 25 | import java.nio.file.Path; 26 | import java.nio.file.Paths; 27 | import java.util.concurrent.atomic.AtomicBoolean; 28 | 29 | import static br.com.pinter.tqrespec.util.Constants.PROCESS_SCAN_INTERVAL_MS; 30 | 31 | public class GameProcessMonitor implements Runnable { 32 | private int interrupted = 0; 33 | private final String directory; 34 | 35 | public GameProcessMonitor(String directory) { 36 | this.directory = directory; 37 | } 38 | 39 | private void monitor() { 40 | AtomicBoolean foundRunning = new AtomicBoolean(false); 41 | while (true) { 42 | try { 43 | if (interrupted > 5000) { 44 | break; 45 | } 46 | 47 | foundRunning.set(false); 48 | if (SystemUtils.IS_OS_WINDOWS) { 49 | ProcessHandle.allProcesses().forEach(p -> { 50 | String command = p.info().command().orElse(null); 51 | if (command != null) { 52 | Path processCommand = Paths.get(command); 53 | Path gamePath = Paths.get(directory); 54 | if (processCommand.getFileName().toString().equalsIgnoreCase("tq.exe") 55 | || (processCommand.startsWith(gamePath) && 56 | processCommand.getFileName().toString().toLowerCase().endsWith(".exe") 57 | && !processCommand.getFileName().toString().equalsIgnoreCase("tqrespec.exe"))) { 58 | foundRunning.set(true); 59 | } 60 | } 61 | }); 62 | } else { 63 | ProcessHandle.allProcesses().forEach(p -> { 64 | String command = p.info().commandLine().orElse(null); 65 | Path gamePath = Paths.get(directory); 66 | if (command != null && command.matches("(?i).*" + gamePath.toAbsolutePath() + "\\b.*") 67 | && command.matches("(?i).*\\btq.exe\\b.*")) { 68 | foundRunning.set(true); 69 | } 70 | }); 71 | } 72 | State.get().setGameRunning(foundRunning.get()); 73 | //noinspection BusyWait 74 | Thread.sleep(PROCESS_SCAN_INTERVAL_MS); 75 | } catch (InterruptedException ignored) { 76 | //ignored 77 | interrupted++; 78 | Thread.currentThread().interrupt(); 79 | } 80 | } 81 | } 82 | 83 | @Override 84 | public void run() { 85 | monitor(); 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/main/java/br/com/pinter/tqrespec/core/GuiceModule.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Emerson Pinter - All Rights Reserved 3 | */ 4 | 5 | /* This file is part of TQ Respec. 6 | 7 | TQ Respec is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | TQ Respec is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with TQ Respec. If not, see . 19 | */ 20 | 21 | package br.com.pinter.tqrespec.core; 22 | 23 | import com.google.inject.AbstractModule; 24 | 25 | public class GuiceModule extends AbstractModule { 26 | @Override 27 | protected void configure() { 28 | //empty 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/br/com/pinter/tqrespec/core/InjectionContext.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Emerson Pinter - All Rights Reserved 3 | */ 4 | 5 | /* This file is part of TQ Respec. 6 | 7 | TQ Respec is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | TQ Respec is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with TQ Respec. If not, see . 19 | */ 20 | 21 | package br.com.pinter.tqrespec.core; 22 | 23 | import com.google.inject.AbstractModule; 24 | import com.google.inject.Guice; 25 | import com.google.inject.Injector; 26 | import com.google.inject.Module; 27 | import com.google.inject.Provides; 28 | import javafx.fxml.FXMLLoader; 29 | 30 | import java.util.ArrayList; 31 | import java.util.List; 32 | 33 | public class InjectionContext { 34 | private final Object context; 35 | private Injector guiceInjector; 36 | private final List modules; 37 | 38 | public InjectionContext(Object context, List modules) { 39 | this.context = context; 40 | this.modules = modules; 41 | } 42 | 43 | public void initialize() { 44 | List modulesList = new ArrayList<>(modules); 45 | modulesList.add(new FXMLProvider()); 46 | guiceInjector = Guice.createInjector(modulesList.toArray(new Module[0])); 47 | injectMembers(context); 48 | } 49 | 50 | public void injectMembers(Object instance) { 51 | guiceInjector.injectMembers(instance); 52 | } 53 | 54 | public T getInstance(Class type) { 55 | return guiceInjector.getInstance(type); 56 | } 57 | 58 | private class FXMLProvider extends AbstractModule { 59 | @Override 60 | protected void configure() { 61 | //ignored 62 | } 63 | 64 | @Provides 65 | FXMLLoader producer() { 66 | FXMLLoader fxmlLoader = new FXMLLoader(); 67 | fxmlLoader.setControllerFactory(InjectionContext.this::getInstance); 68 | return fxmlLoader; 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/main/java/br/com/pinter/tqrespec/core/MyEventHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Emerson Pinter - All Rights Reserved 3 | */ 4 | 5 | /* This file is part of TQ Respec. 6 | 7 | TQ Respec is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | TQ Respec is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with TQ Respec. If not, see . 19 | */ 20 | 21 | package br.com.pinter.tqrespec.core; 22 | 23 | import javafx.event.Event; 24 | import javafx.event.EventHandler; 25 | 26 | @FunctionalInterface 27 | public interface MyEventHandler extends EventHandler { 28 | @Override 29 | default void handle(T t) { 30 | try { 31 | handleEvent(t); 32 | } catch (Exception e) { 33 | throw new UnhandledRuntimeException(e); 34 | } 35 | } 36 | 37 | void handleEvent(T t); 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/br/com/pinter/tqrespec/core/MyTask.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Emerson Pinter - All Rights Reserved 3 | */ 4 | 5 | /* This file is part of TQ Respec. 6 | 7 | TQ Respec is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | TQ Respec is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with TQ Respec. If not, see . 19 | */ 20 | 21 | package br.com.pinter.tqrespec.core; 22 | 23 | import javafx.concurrent.Task; 24 | 25 | public abstract class MyTask extends Task { 26 | protected MyTask() { 27 | super(); 28 | setOnFailed(workerStateEvent -> { 29 | throw new UnhandledRuntimeException(getException()); 30 | }); 31 | } 32 | 33 | @Override 34 | protected abstract T call(); 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/br/com/pinter/tqrespec/core/ResourceNotFoundException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2022 Emerson Pinter - All Rights Reserved 3 | */ 4 | 5 | /* This file is part of TQ Respec. 6 | 7 | TQ Respec is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | TQ Respec is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with TQ Respec. If not, see . 19 | */ 20 | 21 | package br.com.pinter.tqrespec.core; 22 | 23 | public class ResourceNotFoundException extends RuntimeException { 24 | public ResourceNotFoundException() { 25 | } 26 | 27 | public ResourceNotFoundException(String message) { 28 | super(message); 29 | } 30 | 31 | public ResourceNotFoundException(String message, Throwable cause) { 32 | super(message, cause); 33 | } 34 | 35 | public ResourceNotFoundException(Throwable cause) { 36 | super(cause); 37 | } 38 | 39 | public ResourceNotFoundException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { 40 | super(message, cause, enableSuppression, writableStackTrace); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/br/com/pinter/tqrespec/core/SingleInstanceLock.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Emerson Pinter - All Rights Reserved 3 | */ 4 | 5 | /* This file is part of TQ Respec. 6 | 7 | TQ Respec is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | TQ Respec is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with TQ Respec. If not, see . 19 | */ 20 | 21 | package br.com.pinter.tqrespec.core; 22 | 23 | import br.com.pinter.tqrespec.logging.Log; 24 | 25 | import java.io.File; 26 | import java.io.IOException; 27 | import java.io.RandomAccessFile; 28 | import java.nio.ByteBuffer; 29 | import java.nio.channels.FileChannel; 30 | import java.nio.channels.FileLock; 31 | import java.nio.file.Files; 32 | 33 | import static java.lang.System.Logger.Level.ERROR; 34 | 35 | public class SingleInstanceLock { 36 | private static final System.Logger logger = Log.getLogger(SingleInstanceLock.class); 37 | private final File lockFile = new File(System.getProperty("java.io.tmpdir"), "tqrespec.pid"); 38 | private FileChannel fileChannel; 39 | private FileLock lock; 40 | 41 | public SingleInstanceLock() { 42 | if (lockFile.exists()) { 43 | deleteLock(); 44 | } 45 | } 46 | 47 | public void lock() throws IOException { 48 | //noinspection resource 49 | fileChannel = new RandomAccessFile(lockFile, "rw").getChannel(); 50 | lock = fileChannel.tryLock(); 51 | String pid = String.valueOf(ProcessHandle.current().pid()); 52 | //noinspection ResultOfMethodCallIgnored 53 | fileChannel.write(ByteBuffer.wrap(pid.getBytes())); 54 | 55 | if (lock == null) { 56 | fileChannel.close(); 57 | throw new IOException("Can't lock file"); 58 | } 59 | Runtime.getRuntime().addShutdownHook(new Thread(this::release)); 60 | } 61 | 62 | public void deleteLock() { 63 | try { 64 | Files.delete(lockFile.toPath()); 65 | } catch (IOException e) { 66 | logger.log(ERROR, "Error deleting lockfile ''{0}''", lockFile.getPath()); 67 | } 68 | } 69 | 70 | public void release() { 71 | if (lock != null) { 72 | try { 73 | lock.release(); 74 | fileChannel.close(); 75 | deleteLock(); 76 | } catch (IOException e) { 77 | logger.log(ERROR, "Error deleting lockfile ''{0}''", lockFile.getPath()); 78 | } 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/main/java/br/com/pinter/tqrespec/core/State.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Emerson Pinter - All Rights Reserved 3 | */ 4 | 5 | /* This file is part of TQ Respec. 6 | 7 | TQ Respec is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | TQ Respec is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with TQ Respec. If not, see . 19 | */ 20 | 21 | package br.com.pinter.tqrespec.core; 22 | 23 | import javafx.beans.property.SimpleBooleanProperty; 24 | import org.apache.commons.lang3.StringUtils; 25 | 26 | import java.util.HashMap; 27 | import java.util.Locale; 28 | import java.util.Map; 29 | import java.util.concurrent.atomic.AtomicBoolean; 30 | import java.util.concurrent.atomic.AtomicReference; 31 | import java.util.logging.Level; 32 | 33 | public class State { 34 | private static final Object lock = new Object(); 35 | private static State instance = null; 36 | private final SimpleBooleanProperty saveInProgress = new SimpleBooleanProperty(false); 37 | private final SimpleBooleanProperty gameRunning = new SimpleBooleanProperty(false); 38 | private final Map debugPrefix = new HashMap<>(); 39 | private final AtomicReference> lastCursorWaitTask = new AtomicReference<>(); 40 | private final AtomicBoolean gameFontFound = new AtomicBoolean(false); 41 | private Locale locale = Locale.of("en"); 42 | 43 | private State() { 44 | } 45 | 46 | public static State get() { 47 | State c = instance; 48 | if (c == null) { 49 | synchronized (lock) { 50 | c = instance; 51 | if (c == null) { 52 | c = new State(); 53 | instance = c; 54 | } 55 | } 56 | } 57 | return instance; 58 | } 59 | 60 | public boolean isSaveInProgress() { 61 | return saveInProgress.getValue(); 62 | } 63 | 64 | public void setSaveInProgress(Boolean saveInProgress) { 65 | this.saveInProgress.setValue(saveInProgress); 66 | } 67 | 68 | public boolean isGameRunning() { 69 | return gameRunning.getValue(); 70 | } 71 | 72 | public void setGameRunning(Boolean gameRunning) { 73 | this.gameRunning.setValue(gameRunning); 74 | } 75 | 76 | public SimpleBooleanProperty gameRunningProperty() { 77 | return gameRunning; 78 | } 79 | 80 | public Map getDebugPrefix() { 81 | return debugPrefix; 82 | } 83 | 84 | public void addDebugPrefix(String prefix, Level level) { 85 | getDebugPrefix().put(prefix, level); 86 | } 87 | 88 | public Locale getLocale() { 89 | if (locale == null) { 90 | locale = Locale.of("en"); 91 | } 92 | return locale; 93 | } 94 | 95 | public boolean isLocaleLatin() { 96 | if (locale == null) { 97 | return true; 98 | } 99 | return !StringUtils.equalsAnyIgnoreCase(locale.getLanguage(), "zh", "ja", "ko", "pl", "ru", "uk"); 100 | } 101 | 102 | public void setLocale(Locale locale) { 103 | this.locale = locale; 104 | } 105 | 106 | public MyTask getLastCursorWaitTask() { 107 | return lastCursorWaitTask.get(); 108 | } 109 | 110 | public void setLastCursorWaitTask(MyTask lastCursorWaitTask) { 111 | this.lastCursorWaitTask.set(lastCursorWaitTask); 112 | } 113 | 114 | public boolean isGameFontFound() { 115 | return gameFontFound.get(); 116 | } 117 | 118 | public void setGameFontFound(boolean gameFontFound) { 119 | this.gameFontFound.set(gameFontFound); 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /src/main/java/br/com/pinter/tqrespec/core/UnhandledRuntimeException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Emerson Pinter - All Rights Reserved 3 | */ 4 | 5 | /* This file is part of TQ Respec. 6 | 7 | TQ Respec is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | TQ Respec is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with TQ Respec. If not, see . 19 | */ 20 | 21 | package br.com.pinter.tqrespec.core; 22 | 23 | public class UnhandledRuntimeException extends RuntimeException { 24 | public UnhandledRuntimeException() { 25 | } 26 | 27 | public UnhandledRuntimeException(String message) { 28 | super(message); 29 | } 30 | 31 | public UnhandledRuntimeException(String message, Throwable cause) { 32 | super(message, cause); 33 | } 34 | 35 | public UnhandledRuntimeException(Throwable cause) { 36 | super(cause); 37 | } 38 | 39 | public UnhandledRuntimeException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { 40 | super(message, cause, enableSuppression, writableStackTrace); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/br/com/pinter/tqrespec/core/WorkerThread.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Emerson Pinter - All Rights Reserved 3 | */ 4 | 5 | /* This file is part of TQ Respec. 6 | 7 | TQ Respec is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | TQ Respec is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with TQ Respec. If not, see . 19 | */ 20 | 21 | package br.com.pinter.tqrespec.core; 22 | 23 | public class WorkerThread extends Thread { 24 | @SuppressWarnings("unused") 25 | public WorkerThread() { 26 | super(); 27 | setUncaughtExceptionHandler(ExceptionHandler::unhandled); 28 | } 29 | 30 | public WorkerThread(Runnable target) { 31 | super(target); 32 | setUncaughtExceptionHandler(ExceptionHandler::unhandled); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/br/com/pinter/tqrespec/core/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Emerson Pinter - All Rights Reserved 3 | */ 4 | 5 | /* This file is part of TQ Respec. 6 | 7 | TQ Respec is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | TQ Respec is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with TQ Respec. If not, see . 19 | */ 20 | 21 | package br.com.pinter.tqrespec.core; -------------------------------------------------------------------------------- /src/main/java/br/com/pinter/tqrespec/gui/AboutController.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Emerson Pinter - All Rights Reserved 3 | */ 4 | 5 | /* This file is part of TQ Respec. 6 | 7 | TQ Respec is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | TQ Respec is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with TQ Respec. If not, see . 19 | */ 20 | 21 | package br.com.pinter.tqrespec.gui; 22 | 23 | import br.com.pinter.tqrespec.util.Build; 24 | import javafx.fxml.FXML; 25 | import javafx.fxml.Initializable; 26 | import javafx.scene.Scene; 27 | import javafx.scene.control.Label; 28 | import javafx.scene.control.TextArea; 29 | import javafx.scene.input.KeyCode; 30 | import javafx.scene.input.KeyEvent; 31 | import javafx.scene.input.MouseEvent; 32 | import javafx.scene.layout.AnchorPane; 33 | import javafx.scene.paint.Color; 34 | import javafx.stage.Modality; 35 | import javafx.stage.Stage; 36 | import javafx.stage.StageStyle; 37 | import org.apache.commons.lang3.StringUtils; 38 | import org.apache.commons.lang3.SystemUtils; 39 | 40 | import java.net.URL; 41 | import java.util.ResourceBundle; 42 | 43 | public class AboutController implements Initializable { 44 | @FXML 45 | private AnchorPane rootelement; 46 | @FXML 47 | private Label aboutFormTitle; 48 | @FXML 49 | private Label aboutVersion; 50 | @FXML 51 | private TextArea aboutText; 52 | 53 | @Override 54 | public void initialize(URL location, ResourceBundle resources) { 55 | Scene scene = new Scene(rootelement); 56 | Stage stage = new Stage(); 57 | stage.setScene(scene); 58 | scene.setFill(Color.TRANSPARENT); 59 | stage.initModality(Modality.APPLICATION_MODAL); 60 | UIUtils.setStageFontCss(stage); 61 | 62 | stage.getIcons().addAll(ResourceHelper.getAppIcons()); 63 | 64 | //disable maximize 65 | stage.resizableProperty().setValue(Boolean.FALSE); 66 | 67 | // min* and max* set to -1 will force javafx to use values defined on root element 68 | stage.setMinHeight(rootelement.minHeight(-1)); 69 | stage.setMinWidth(rootelement.minWidth(-1)); 70 | stage.setMaxHeight(rootelement.maxHeight(-1)); 71 | stage.setMaxWidth(rootelement.maxWidth(-1)); 72 | 73 | //remove default window decoration 74 | if (SystemUtils.IS_OS_WINDOWS) { 75 | stage.initStyle(StageStyle.TRANSPARENT); 76 | } else { 77 | stage.initStyle(StageStyle.UNDECORATED); 78 | } 79 | 80 | stage.addEventHandler(KeyEvent.KEY_PRESSED, (event -> { 81 | if (event.getCode() == KeyCode.ESCAPE) { 82 | stage.close(); 83 | } 84 | })); 85 | stage.setTitle(ResourceHelper.getMessage("about.title", Build.title())); 86 | aboutFormTitle.setText(ResourceHelper.getMessage("about.title", Build.title())); 87 | aboutVersion.setText(ResourceHelper.getMessage("about.version", Build.version())); 88 | 89 | String translators = ResourceHelper.getMessage("main.translators"); 90 | if (StringUtils.isNotBlank(translators)) { 91 | aboutText.appendText("\n\n" + ResourceHelper.getMessage("main.translators")); 92 | } 93 | 94 | stage.show(); 95 | } 96 | 97 | @FXML 98 | public void closeAboutWindow(@SuppressWarnings("unused") MouseEvent evt) { 99 | Stage stage = (Stage) rootelement.getScene().getWindow(); 100 | stage.close(); 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /src/main/java/br/com/pinter/tqrespec/gui/AppPreloader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Emerson Pinter - All Rights Reserved 3 | */ 4 | 5 | /* This file is part of TQ Respec. 6 | 7 | TQ Respec is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | TQ Respec is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with TQ Respec. If not, see . 19 | */ 20 | 21 | package br.com.pinter.tqrespec.gui; 22 | 23 | import br.com.pinter.tqrespec.util.Build; 24 | import br.com.pinter.tqrespec.util.Constants; 25 | import javafx.application.Preloader; 26 | import javafx.geometry.Pos; 27 | import javafx.scene.Scene; 28 | import javafx.scene.control.Label; 29 | import javafx.scene.control.ProgressBar; 30 | import javafx.scene.layout.BorderPane; 31 | import javafx.scene.layout.StackPane; 32 | import javafx.stage.Stage; 33 | import javafx.stage.StageStyle; 34 | import org.apache.commons.lang3.SystemUtils; 35 | 36 | import java.io.IOException; 37 | 38 | public class AppPreloader extends Preloader { 39 | private ProgressBar bar; 40 | private Stage stage; 41 | 42 | private Scene createPreloaderScene() { 43 | ResourceHelper.loadFonts(); 44 | 45 | BorderPane pane = new BorderPane(); 46 | Scene scene = new Scene(pane, Constants.UI.PRELOADER_WIDTH, Constants.UI.PRELOADER_HEIGHT); 47 | scene.getStylesheets().add(ResourceHelper.getResource(Constants.UI.PRELOADER_CSS)); 48 | scene.getStylesheets().add(ResourceHelper.getResource(Constants.UI.DEFAULT_FONT_CSS)); 49 | pane.getStyleClass().add(Constants.UI.PRELOADER_PANE_STYLE); 50 | 51 | Label title = new Label(); 52 | title.setText(Constants.APPNAME); 53 | title.getStyleClass().add(Constants.UI.PRELOADER_TITLE_STYLE); 54 | StackPane topPane = new StackPane(title); 55 | topPane.getStyleClass().add(Constants.UI.PRELOADER_TOP_STYLE); 56 | StackPane.setAlignment(title, Pos.CENTER); 57 | pane.setTop(topPane); 58 | 59 | bar = new ProgressBar(0.1); 60 | bar.getStyleClass().add(Constants.UI.PRELOADER_BAR_STYLE); 61 | bar.setMaxWidth(Constants.UI.PRELOADER_WIDTH - 30d); 62 | pane.setCenter(bar); 63 | 64 | Label versionText = new Label(Build.version()); 65 | versionText.getStyleClass().add(Constants.UI.PRELOADER_VERSION_STYLE); 66 | StackPane bottomPane = new StackPane(versionText); 67 | bottomPane.getStyleClass().add(Constants.UI.PRELOADER_BOTTOM_STYLE); 68 | StackPane.setAlignment(versionText, Pos.BOTTOM_RIGHT); 69 | pane.setBottom(bottomPane); 70 | 71 | return scene; 72 | 73 | } 74 | 75 | @Override 76 | public void start(Stage stage) throws IOException { 77 | this.stage = stage; 78 | stage.getIcons().addAll(ResourceHelper.getAppIcons()); 79 | stage.setScene(createPreloaderScene()); 80 | stage.setTitle(Build.title()); 81 | 82 | if (SystemUtils.IS_OS_WINDOWS) { 83 | stage.initStyle(StageStyle.TRANSPARENT); 84 | } else { 85 | stage.initStyle(StageStyle.UNDECORATED); 86 | } 87 | 88 | stage.show(); 89 | } 90 | 91 | @Override 92 | public void handleApplicationNotification(PreloaderNotification pn) { 93 | if (pn instanceof ProgressNotification progressNotification) { 94 | bar.setProgress(progressNotification.getProgress()); 95 | } else if (pn instanceof StateChangeNotification) { 96 | //hide after get any state update from application 97 | stage.hide(); 98 | } 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /src/main/java/br/com/pinter/tqrespec/gui/CharacterListCell.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2025 Emerson Pinter - All Rights Reserved 3 | */ 4 | 5 | /* This file is part of TQ Respec. 6 | 7 | TQ Respec is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | TQ Respec is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with TQ Respec. If not, see . 19 | */ 20 | 21 | package br.com.pinter.tqrespec.gui; 22 | 23 | import br.com.pinter.tqrespec.save.SaveLocation; 24 | import br.com.pinter.tqrespec.tqdata.PlayerCharacterFile; 25 | import javafx.scene.control.Label; 26 | import javafx.scene.control.ListCell; 27 | import javafx.scene.layout.HBox; 28 | import javafx.scene.layout.Priority; 29 | 30 | import java.util.Locale; 31 | 32 | public class CharacterListCell extends ListCell { 33 | private final HBox container; 34 | private final Label characterName; 35 | private final Label characterType; 36 | 37 | public CharacterListCell() { 38 | super(); 39 | characterName = new Label(); 40 | characterType = new Label(); 41 | HBox containerName = new HBox(characterName); 42 | HBox containerType = new HBox(characterType); 43 | container = new HBox(containerName, containerType); 44 | HBox.setHgrow(containerName, Priority.ALWAYS); 45 | characterName.getStyleClass().add("character-combobox-name"); 46 | characterType.getStyleClass().add("character-combobox-type"); 47 | } 48 | 49 | @Override 50 | public void updateItem(PlayerCharacterFile character, boolean empty) { 51 | super.updateItem(character, empty); 52 | if (empty) { 53 | setGraphic(null); 54 | characterName.setText(null); 55 | characterType.setText(null); 56 | } else if (character != null) { 57 | characterName.setText(character.getPlayerName()); 58 | characterType.setText(null); 59 | String typeTag = switch (character.getLocation()) { 60 | case USER -> ResourceHelper.getMessage("characters.store.USER"); 61 | case EXTERNAL -> ResourceHelper.getMessage("characters.store.EXTERNAL"); 62 | default -> null; 63 | }; 64 | 65 | if (typeTag == null) { 66 | characterType.setText(null); 67 | setTooltip(null); 68 | } else { 69 | characterType.setText(String.format("[%s]", typeTag).toUpperCase(Locale.ROOT)); 70 | setTooltip(new UIUtils().simpleTooltip(typeTag)); 71 | } 72 | setGraphic(container); 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/main/java/br/com/pinter/tqrespec/gui/CheckVersionService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Emerson Pinter - All Rights Reserved 3 | */ 4 | 5 | package br.com.pinter.tqrespec.gui; 6 | 7 | import br.com.pinter.tqrespec.util.Build; 8 | import br.com.pinter.tqrespec.util.Constants; 9 | import br.com.pinter.tqrespec.util.Version; 10 | import com.google.inject.Inject; 11 | import javafx.application.HostServices; 12 | import javafx.concurrent.Service; 13 | import javafx.concurrent.Task; 14 | import javafx.concurrent.WorkerStateEvent; 15 | import javafx.scene.control.Control; 16 | import javafx.scene.control.Hyperlink; 17 | import org.apache.commons.lang3.StringUtils; 18 | 19 | import java.net.URI; 20 | import java.net.URISyntaxException; 21 | 22 | public class CheckVersionService extends Service { 23 | private Control control; 24 | 25 | @Inject 26 | private HostServices hostServices; 27 | 28 | public CheckVersionService withControl(Control control) { 29 | this.control = control; 30 | return this; 31 | } 32 | 33 | @Override 34 | protected Task createTask() { 35 | String url = Constants.VERSION_CHECK_URL; 36 | String currentVersion = Build.version(); 37 | if (control == null) { 38 | throw new IllegalArgumentException("null parameter received"); 39 | } 40 | 41 | Task task = new Task<>() { 42 | @Override 43 | protected Version call() { 44 | Version version = new Version(currentVersion); 45 | version.checkNewerVersion(url); 46 | //new version available (-1 our version is less than remote, 0 equal, 1 greater, -2 error checking 47 | return version; 48 | } 49 | }; 50 | 51 | task.addEventHandler(WorkerStateEvent.WORKER_STATE_SUCCEEDED, (WorkerStateEvent e) -> { 52 | Version version = (Version) e.getSource().getValue(); 53 | 54 | if (version == null || version.getLastCheck() != -1 || StringUtils.isEmpty(version.getUrlPage())) { 55 | control.setDisable(true); 56 | return; 57 | } 58 | ((Hyperlink) control).setOnAction(event -> { 59 | final Task openUrl = new Task<>() { 60 | @Override 61 | public Void call() { 62 | try { 63 | hostServices.showDocument(new URI(version.getUrlPage()).toString()); 64 | } catch (URISyntaxException ignored) { 65 | //ignored 66 | } 67 | return null; 68 | } 69 | }; 70 | new Thread(openUrl).start(); 71 | }); 72 | ((Hyperlink) control).setText(ResourceHelper.getMessage("about.newversion")); 73 | }); 74 | 75 | return task; 76 | } 77 | 78 | } 79 | -------------------------------------------------------------------------------- /src/main/java/br/com/pinter/tqrespec/gui/CopyTarget.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Emerson Pinter - All Rights Reserved 3 | */ 4 | 5 | package br.com.pinter.tqrespec.gui; 6 | 7 | import br.com.pinter.tqrespec.save.Platform; 8 | 9 | import java.util.Arrays; 10 | 11 | public enum CopyTarget { 12 | WINDOWS, 13 | MOBILE, 14 | BACKUP; 15 | 16 | public Platform getPlatform() { 17 | return Arrays.stream(Platform.values()).filter(p -> p.name().equals(name())).findFirst().orElse(null); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/br/com/pinter/tqrespec/gui/CustomMap.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2025 Emerson Pinter - All Rights Reserved 3 | */ 4 | 5 | /* This file is part of TQ Respec. 6 | 7 | TQ Respec is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | TQ Respec is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with TQ Respec. If not, see . 19 | */ 20 | 21 | package br.com.pinter.tqrespec.gui; 22 | 23 | import java.nio.file.Path; 24 | 25 | public class CustomMap { 26 | private String name; 27 | private Path path; 28 | 29 | public CustomMap(String name, Path path) { 30 | this.name = name; 31 | this.path = path; 32 | } 33 | 34 | public String getName() { 35 | return name; 36 | } 37 | 38 | public Path getPath() { 39 | return path; 40 | } 41 | 42 | @Override 43 | public String toString() { 44 | return name; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/br/com/pinter/tqrespec/gui/DifficultyItem.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2025 Emerson Pinter - All Rights Reserved 3 | */ 4 | 5 | /* This file is part of TQ Respec. 6 | 7 | TQ Respec is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | TQ Respec is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with TQ Respec. If not, see . 19 | */ 20 | 21 | package br.com.pinter.tqrespec.gui; 22 | 23 | public class DifficultyItem { 24 | private final int id; 25 | private final String name; 26 | 27 | public DifficultyItem(int id, String name) { 28 | this.id = id; 29 | this.name = name; 30 | if (id < 0 || id > 2) { 31 | throw new IllegalArgumentException("invalid difficulty id " + id); 32 | } 33 | } 34 | 35 | public int getId() { 36 | return id; 37 | } 38 | 39 | public String getName() { 40 | return name; 41 | } 42 | 43 | @Override 44 | public String toString() { 45 | return name; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/br/com/pinter/tqrespec/gui/SkillListCell.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Emerson Pinter - All Rights Reserved 3 | */ 4 | 5 | /* This file is part of TQ Respec. 6 | 7 | TQ Respec is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | TQ Respec is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with TQ Respec. If not, see . 19 | */ 20 | 21 | package br.com.pinter.tqrespec.gui; 22 | 23 | import br.com.pinter.tqrespec.tqdata.Txt; 24 | import com.google.inject.Inject; 25 | import javafx.scene.control.Label; 26 | import javafx.scene.control.ListCell; 27 | import javafx.scene.layout.HBox; 28 | import javafx.scene.layout.Priority; 29 | 30 | public class SkillListCell extends ListCell { 31 | private final HBox container; 32 | private final Label skillName; 33 | private final Label skillPoints; 34 | 35 | @Inject 36 | private Txt txt; 37 | 38 | SkillListCell() { 39 | super(); 40 | skillName = new Label(); 41 | skillPoints = new Label(); 42 | HBox containerName = new HBox(skillName); 43 | HBox containerPoints = new HBox(skillPoints); 44 | container = new HBox(containerName, containerPoints); 45 | HBox.setHgrow(containerName, Priority.ALWAYS); 46 | } 47 | 48 | @Override 49 | protected void updateItem(SkillListViewItem s, boolean empty) { 50 | super.updateItem(s, empty); 51 | if (empty) { 52 | setGraphic(null); 53 | skillName.setText(null); 54 | skillPoints.setText(null); 55 | } else if (s != null) { 56 | skillName.setText(s.getSkillNameText()); 57 | skillPoints.setText(String.valueOf(s.getSkillPoints())); 58 | setGraphic(container); 59 | } 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/br/com/pinter/tqrespec/gui/SkillListViewItem.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Emerson Pinter - All Rights Reserved 3 | */ 4 | 5 | /* This file is part of TQ Respec. 6 | 7 | TQ Respec is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | TQ Respec is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with TQ Respec. If not, see . 19 | */ 20 | 21 | package br.com.pinter.tqrespec.gui; 22 | 23 | public class SkillListViewItem { 24 | private final String skillName; 25 | private final int skillPoints; 26 | private final String skillNameText; 27 | 28 | SkillListViewItem(String skillName, int skillPoints, String skillNameText) { 29 | this.skillName = skillName; 30 | this.skillPoints = skillPoints; 31 | this.skillNameText = skillNameText; 32 | } 33 | 34 | String getSkillName() { 35 | return skillName; 36 | } 37 | 38 | int getSkillPoints() { 39 | return skillPoints; 40 | } 41 | 42 | public String getSkillNameText() { 43 | return skillNameText; 44 | } 45 | } -------------------------------------------------------------------------------- /src/main/java/br/com/pinter/tqrespec/gui/TeleportItem.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2025 Emerson Pinter - All Rights Reserved 3 | */ 4 | 5 | /* This file is part of TQ Respec. 6 | 7 | TQ Respec is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | TQ Respec is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with TQ Respec. If not, see . 19 | */ 20 | 21 | package br.com.pinter.tqrespec.gui; 22 | 23 | import br.com.pinter.tqrespec.tqdata.MapTeleport; 24 | 25 | import java.util.Objects; 26 | 27 | public class TeleportItem { 28 | private final int difficulty; 29 | private final MapTeleport teleport; 30 | 31 | public enum Ops { 32 | INSERT, 33 | REMOVE 34 | } 35 | 36 | public TeleportItem(MapTeleport teleport, int difficulty) { 37 | this.teleport = teleport; 38 | this.difficulty = difficulty; 39 | } 40 | 41 | public int getDifficulty() { 42 | return difficulty; 43 | } 44 | 45 | public MapTeleport getTeleport() { 46 | return teleport; 47 | } 48 | 49 | @Override 50 | public boolean equals(Object o) { 51 | if (o == null || getClass() != o.getClass()) return false; 52 | TeleportItem that = (TeleportItem) o; 53 | return difficulty == that.difficulty && teleport.getUid().equals(that.teleport.getUid()); 54 | } 55 | 56 | @Override 57 | public int hashCode() { 58 | return Objects.hash(difficulty, teleport); 59 | } 60 | 61 | @Override 62 | public String toString() { 63 | return "TeleportItem{" + 64 | "difficulty=" + difficulty + 65 | ", teleport=" + teleport + 66 | '}'; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/main/java/br/com/pinter/tqrespec/logging/JULLoggerFinder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Emerson Pinter - All Rights Reserved 3 | */ 4 | 5 | /* This file is part of TQ Respec. 6 | 7 | TQ Respec is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | TQ Respec is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with TQ Respec. If not, see . 19 | */ 20 | 21 | package br.com.pinter.tqrespec.logging; 22 | 23 | public class JULLoggerFinder extends System.LoggerFinder { 24 | @Override 25 | public System.Logger getLogger(String name, Module module) { 26 | return new JULLogger(name); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/br/com/pinter/tqrespec/logging/Log.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Emerson Pinter - All Rights Reserved 3 | */ 4 | 5 | /* This file is part of TQ Respec. 6 | 7 | TQ Respec is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | TQ Respec is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with TQ Respec. If not, see . 19 | */ 20 | 21 | package br.com.pinter.tqrespec.logging; 22 | 23 | import br.com.pinter.tqrespec.core.State; 24 | import br.com.pinter.tqrespec.core.UnhandledRuntimeException; 25 | import br.com.pinter.tqrespec.util.Constants; 26 | 27 | import java.io.IOException; 28 | import java.io.PrintStream; 29 | import java.nio.file.Path; 30 | import java.util.logging.ConsoleHandler; 31 | import java.util.logging.FileHandler; 32 | import java.util.logging.Handler; 33 | import java.util.logging.Level; 34 | import java.util.logging.LogManager; 35 | import java.util.logging.Logger; 36 | import java.util.logging.SimpleFormatter; 37 | 38 | public class Log { 39 | private Log() { 40 | } 41 | 42 | public static System.Logger getLogger(String name) { 43 | return System.getLogger(name); 44 | } 45 | 46 | public static System.Logger getLogger(Class cls) { 47 | return System.getLogger(cls.getName()); 48 | } 49 | 50 | private static FileHandler getLogFileHandler(Path logFile) { 51 | FileHandler fileHandler; 52 | try { 53 | System.setProperty("java.util.logging.SimpleFormatter.format", 54 | "%1$tb %1$td, %1$tY %1$tH:%1$tM:%1$tS.%1$tL %2$s%n\t%4$s: %5$s%6$s%n%n"); 55 | fileHandler = new FileHandler(logFile.toAbsolutePath().toString(), false); 56 | fileHandler.setFormatter(new SimpleFormatter()); 57 | 58 | } catch (IOException e) { 59 | throw new UnhandledRuntimeException(e); 60 | } 61 | return fileHandler; 62 | } 63 | 64 | public static void setupGlobalLogging() { 65 | setupGlobalLogging(Path.of(Constants.LOGFILE)); 66 | redirectStd(); 67 | } 68 | 69 | private static void redirectStd() { 70 | System.setOut(new PrintStream(new OutputStreamLog(Level.INFO))); 71 | System.setErr(new PrintStream(new OutputStreamLog(Level.SEVERE))); 72 | } 73 | 74 | public static void setupGlobalLogging(Path logFile) { 75 | Logger rootLogger = LogManager.getLogManager().getLogger(""); 76 | 77 | rootLogger.addHandler(getLogFileHandler(logFile)); 78 | for (Handler h : rootLogger.getHandlers()) { 79 | if (h instanceof ConsoleHandler) { 80 | rootLogger.removeHandler(h); 81 | } 82 | } 83 | 84 | if (State.get().getDebugPrefix().containsKey("*")) { 85 | Level level = State.get().getDebugPrefix().get("*"); 86 | if (level != null) { 87 | rootLogger.setLevel(level); 88 | } 89 | } 90 | } 91 | 92 | } 93 | -------------------------------------------------------------------------------- /src/main/java/br/com/pinter/tqrespec/logging/OutputStreamLog.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Emerson Pinter - All Rights Reserved 3 | */ 4 | 5 | /* This file is part of TQ Respec. 6 | 7 | TQ Respec is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | TQ Respec is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with TQ Respec. If not, see . 19 | */ 20 | 21 | package br.com.pinter.tqrespec.logging; 22 | 23 | import java.io.IOException; 24 | import java.io.OutputStream; 25 | import java.util.logging.Level; 26 | import java.util.logging.Logger; 27 | 28 | public class OutputStreamLog extends OutputStream { 29 | private StringBuilder stringBuilder = new StringBuilder(); 30 | private StringBuilder stringBuilderArray = new StringBuilder(); 31 | private final Level level; 32 | private final Logger logger = Logger.getLogger(OutputStreamLog.class.getName()); 33 | 34 | public OutputStreamLog(Level level) { 35 | this.level = level; 36 | } 37 | 38 | @Override 39 | public void write(byte[] b, int off, int len) throws IOException { 40 | int max = Math.min(b.length, off + len); 41 | 42 | for (int i = off; i < max; i++) { 43 | char c = (char) b[i]; 44 | 45 | if (c != '\r' && c != '\n') { 46 | stringBuilderArray.append(c); 47 | } 48 | 49 | if (c == '\r' || c == '\n' || i == max - 1) { 50 | logger.log(level, "{0}", stringBuilderArray); 51 | stringBuilderArray = new StringBuilder(); 52 | } 53 | } 54 | } 55 | 56 | @Override 57 | public void write(int b) { 58 | char c = (char) b; 59 | 60 | if (c == '\r' || c == '\n') { 61 | if (!stringBuilder.isEmpty()) { 62 | logger.log(level, "{0}", stringBuilder); 63 | stringBuilder = new StringBuilder(); 64 | } 65 | } else { 66 | stringBuilder.append(c); 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/main/java/br/com/pinter/tqrespec/save/BlockInfo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Emerson Pinter - All Rights Reserved 3 | */ 4 | 5 | /* This file is part of TQ Respec. 6 | 7 | TQ Respec is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | TQ Respec is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with TQ Respec. If not, see . 19 | */ 20 | 21 | package br.com.pinter.tqrespec.save; 22 | 23 | import com.fasterxml.jackson.annotation.JsonIgnore; 24 | import com.fasterxml.jackson.annotation.JsonProperty; 25 | import com.google.common.collect.ImmutableList; 26 | import com.google.common.collect.ImmutableListMultimap; 27 | import com.google.common.collect.Multimap; 28 | import com.google.common.collect.MultimapBuilder; 29 | 30 | import java.io.Serializable; 31 | import java.util.ArrayList; 32 | 33 | public class BlockInfo implements Serializable { 34 | private int start = -1; 35 | private int end = -1; 36 | private int size = -1; 37 | @JsonIgnore 38 | private ImmutableListMultimap variables = ImmutableListMultimap.of(); 39 | @JsonIgnore 40 | private transient Multimap stagingVariables = MultimapBuilder.hashKeys().arrayListValues().build(); 41 | @JsonIgnore 42 | private int parentOffset = -1; 43 | private BlockType blockType = FileBlockType.UNKNOWN; 44 | 45 | @JsonProperty("blockType") 46 | public String jsonBlockType() { 47 | return blockType.toString(); 48 | } 49 | 50 | public int getStart() { 51 | return start; 52 | } 53 | 54 | public void setStart(int start) { 55 | this.start = start; 56 | } 57 | 58 | public int getEnd() { 59 | return end; 60 | } 61 | 62 | public void setEnd(int end) { 63 | this.end = end; 64 | } 65 | 66 | public int getSize() { 67 | return size; 68 | } 69 | 70 | public void setSize(int size) { 71 | this.size = size; 72 | } 73 | 74 | public int getParentOffset() { 75 | return parentOffset; 76 | } 77 | 78 | public void setParentOffset(int parentOffset) { 79 | this.parentOffset = parentOffset; 80 | } 81 | 82 | public ImmutableListMultimap getVariables() { 83 | return variables; 84 | } 85 | 86 | public void setVariables(ImmutableListMultimap variables) { 87 | this.variables = variables; 88 | } 89 | 90 | public ImmutableList getVariableByAlias(String alias) { 91 | ArrayList ret = new ArrayList<>(); 92 | for (VariableInfo v : variables.values()) { 93 | if (v.getAlias().equals(alias)) { 94 | ret.add(v); 95 | } 96 | } 97 | return ImmutableList.copyOf(ret); 98 | } 99 | 100 | public BlockType getBlockType() { 101 | return blockType; 102 | } 103 | 104 | public void setBlockType(BlockType blockType) { 105 | this.blockType = blockType; 106 | } 107 | 108 | public Multimap getStagingVariables() { 109 | if (stagingVariables == null) { 110 | // stagingVariables content is lost during deepClone 111 | stagingVariables = MultimapBuilder.hashKeys().arrayListValues().build(); 112 | } 113 | return stagingVariables; 114 | } 115 | 116 | @Override 117 | public String toString() { 118 | return "BlockInfo{" + 119 | "start=" + start + 120 | ", end=" + end + 121 | ", size=" + size + 122 | ", variables=" + variables + 123 | ", stagingVariables=" + stagingVariables + 124 | ", parentOffset=" + parentOffset + 125 | ", blockType=" + blockType + 126 | '}'; 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /src/main/java/br/com/pinter/tqrespec/save/BlockType.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Emerson Pinter - All Rights Reserved 3 | */ 4 | 5 | /* This file is part of TQ Respec. 6 | 7 | TQ Respec is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | TQ Respec is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with TQ Respec. If not, see . 19 | */ 20 | 21 | package br.com.pinter.tqrespec.save; 22 | 23 | import java.io.Serializable; 24 | 25 | /** 26 | * Class to hold block types of the files parsed. (HEADER, BODY, etc..) 27 | */ 28 | public interface BlockType extends Serializable { 29 | int getValue(); 30 | 31 | String name(); 32 | 33 | BlockType getParent(); 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/br/com/pinter/tqrespec/save/DataChange.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Emerson Pinter - All Rights Reserved 3 | */ 4 | 5 | /* This file is part of TQ Respec. 6 | 7 | TQ Respec is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | TQ Respec is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with TQ Respec. If not, see . 19 | */ 20 | 21 | package br.com.pinter.tqrespec.save; 22 | 23 | import java.io.ByteArrayOutputStream; 24 | import java.io.IOException; 25 | import java.io.Serializable; 26 | 27 | abstract class DataChange implements Serializable { 28 | private byte[] padding = new byte[0]; 29 | private boolean paddingAfter = true; 30 | 31 | public boolean isRaw() { 32 | return !isVariable(); 33 | } 34 | 35 | public abstract boolean isVariable(); 36 | 37 | public abstract byte[] data(); 38 | 39 | public abstract int previousValueLength(); 40 | 41 | public abstract int offset(); 42 | 43 | public void insertPadding(byte[] data) { 44 | insertPadding(data, true); 45 | } 46 | 47 | public abstract boolean isEmpty(); 48 | 49 | public byte[] getPadding() { 50 | return padding; 51 | } 52 | 53 | public void setPadding(byte[] padding) { 54 | this.padding = padding; 55 | } 56 | 57 | public boolean isPaddingAfter() { 58 | return paddingAfter; 59 | } 60 | 61 | public void setPaddingAfter(boolean paddingAfter) { 62 | this.paddingAfter = paddingAfter; 63 | } 64 | 65 | public void insertPadding(byte[] data, boolean before) { 66 | try { 67 | ByteArrayOutputStream bos = new ByteArrayOutputStream(); 68 | if (before) { 69 | bos.write(data); 70 | bos.write(padding); 71 | } else { 72 | bos.write(padding); 73 | bos.write(data); 74 | } 75 | padding = bos.toByteArray(); 76 | } catch (IOException e) { 77 | throw new IllegalStateException("Error writing to buffer"); 78 | } 79 | } 80 | 81 | public abstract boolean isRemove(); 82 | 83 | public abstract void setRemove(boolean remove); 84 | } 85 | -------------------------------------------------------------------------------- /src/main/java/br/com/pinter/tqrespec/save/DataChangeRaw.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Emerson Pinter - All Rights Reserved 3 | */ 4 | 5 | /* This file is part of TQ Respec. 6 | 7 | TQ Respec is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | TQ Respec is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with TQ Respec. If not, see . 19 | */ 20 | 21 | package br.com.pinter.tqrespec.save; 22 | 23 | import org.apache.commons.lang3.NotImplementedException; 24 | 25 | import java.io.ByteArrayOutputStream; 26 | import java.io.IOException; 27 | import java.io.Serializable; 28 | import java.util.Arrays; 29 | import java.util.Objects; 30 | 31 | class DataChangeRaw extends DataChange implements Serializable { 32 | private final byte[] data; 33 | private final int previouslength; 34 | private final int offset; 35 | 36 | public DataChangeRaw(int offset, byte[] data, int previousLength) { 37 | this.offset = offset; 38 | this.data = data; 39 | this.previouslength = previousLength; 40 | } 41 | 42 | @Override 43 | public boolean equals(Object o) { 44 | if (this == o) return true; 45 | if (o == null || getClass() != o.getClass()) return false; 46 | DataChangeRaw changeRaw = (DataChangeRaw) o; 47 | return previouslength == changeRaw.previouslength && offset == changeRaw.offset && Arrays.equals(data, changeRaw.data); 48 | } 49 | 50 | @Override 51 | public int hashCode() { 52 | int result = Objects.hash(previouslength, offset); 53 | result = 31 * result + Arrays.hashCode(data); 54 | return result; 55 | } 56 | 57 | @Override 58 | public boolean isVariable() { 59 | return false; 60 | } 61 | 62 | @Override 63 | public boolean isEmpty() { 64 | return data.length == 0 && getPadding().length == 0; 65 | } 66 | 67 | @Override 68 | public byte[] data() { 69 | try { 70 | ByteArrayOutputStream bos = new ByteArrayOutputStream(); 71 | if (!isPaddingAfter()) 72 | bos.write(getPadding()); 73 | 74 | bos.write(data); 75 | 76 | if (isPaddingAfter()) 77 | bos.write(getPadding()); 78 | 79 | return bos.toByteArray(); 80 | } catch (IOException e) { 81 | throw new IllegalStateException("Error writing to buffer"); 82 | } 83 | } 84 | 85 | @Override 86 | public int previousValueLength() { 87 | return previouslength; 88 | } 89 | 90 | @Override 91 | public int offset() { 92 | return offset; 93 | } 94 | 95 | @Override 96 | public boolean isRemove() { 97 | return false; 98 | } 99 | 100 | @Override 101 | public void setRemove(boolean remove) { 102 | throw new NotImplementedException(); 103 | } 104 | 105 | @Override 106 | public String toString() { 107 | return "DataChangeRaw{" + 108 | "data=" + Arrays.toString(data) + 109 | ", previouslength=" + previouslength + 110 | ", offset=" + offset + 111 | "} " + super.toString(); 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /src/main/java/br/com/pinter/tqrespec/save/DeepCloneable.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Emerson Pinter - All Rights Reserved 3 | */ 4 | 5 | /* This file is part of TQ Respec. 6 | 7 | TQ Respec is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | TQ Respec is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with TQ Respec. If not, see . 19 | */ 20 | package br.com.pinter.tqrespec.save; 21 | 22 | import org.apache.commons.lang3.exception.CloneFailedException; 23 | 24 | import java.io.ByteArrayInputStream; 25 | import java.io.ByteArrayOutputStream; 26 | import java.io.IOException; 27 | import java.io.ObjectInputStream; 28 | import java.io.ObjectOutputStream; 29 | import java.io.Serializable; 30 | 31 | interface DeepCloneable extends Serializable { 32 | default Object deepClone() { 33 | try { 34 | ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); 35 | ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream); 36 | objectOutputStream.writeUnshared(this); 37 | 38 | ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray()); 39 | ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream); 40 | return objectInputStream.readUnshared(); 41 | } catch (IOException | ClassNotFoundException e) { 42 | throw new CloneFailedException("deep clone failed", e); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/br/com/pinter/tqrespec/save/FileBlockType.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Emerson Pinter - All Rights Reserved 3 | */ 4 | 5 | /* This file is part of TQ Respec. 6 | 7 | TQ Respec is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | TQ Respec is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with TQ Respec. If not, see . 19 | */ 20 | 21 | package br.com.pinter.tqrespec.save; 22 | 23 | import java.util.Objects; 24 | 25 | public class FileBlockType implements BlockType { 26 | public static final FileBlockType MULTIPLE = new FileBlockType(-3, "MULTIPLE"); 27 | public static final FileBlockType UNKNOWN = new FileBlockType(-1, "UNKNOWN"); 28 | 29 | private final String name; 30 | private final int value; 31 | private BlockType parent; 32 | 33 | public FileBlockType(int value, String name) { 34 | this.value = value; 35 | this.name = name; 36 | } 37 | 38 | public FileBlockType(int value, String name, BlockType parent) { 39 | this.value = value; 40 | this.name = name; 41 | this.parent = parent; 42 | } 43 | 44 | @Override 45 | public int getValue() { 46 | return value; 47 | } 48 | 49 | @Override 50 | public String name() { 51 | return name; 52 | } 53 | 54 | @Override 55 | public BlockType getParent() { 56 | return parent; 57 | } 58 | 59 | @Override 60 | public boolean equals(Object o) { 61 | if (this == o) return true; 62 | 63 | if (o == null || getClass() != o.getClass()) return false; 64 | FileBlockType that = (FileBlockType) o; 65 | return value == that.value && 66 | name.equals(that.name); 67 | } 68 | 69 | @Override 70 | public int hashCode() { 71 | return Objects.hash(name, value); 72 | } 73 | 74 | @Override 75 | public String toString() { 76 | return name(); 77 | } 78 | 79 | } 80 | -------------------------------------------------------------------------------- /src/main/java/br/com/pinter/tqrespec/save/FileDataHolder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Emerson Pinter - All Rights Reserved 3 | */ 4 | 5 | /* This file is part of TQ Respec. 6 | 7 | TQ Respec is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | TQ Respec is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with TQ Respec. If not, see . 19 | */ 20 | 21 | package br.com.pinter.tqrespec.save; 22 | 23 | import java.nio.ByteBuffer; 24 | import java.nio.file.Path; 25 | 26 | public interface FileDataHolder { 27 | ByteBuffer getBuffer(); 28 | 29 | void setBuffer(ByteBuffer buffer); 30 | 31 | FileDataMap getDataMap(); 32 | 33 | String getPlayerName(); 34 | 35 | void setPlayerName(String playerName); 36 | 37 | Path getPlayerPath(); 38 | 39 | void setPlayerPath(Path playerPath); 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/br/com/pinter/tqrespec/save/FileVariable.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Emerson Pinter - All Rights Reserved 3 | */ 4 | 5 | /* This file is part of TQ Respec. 6 | 7 | TQ Respec is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | TQ Respec is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with TQ Respec. If not, see . 19 | */ 20 | 21 | package br.com.pinter.tqrespec.save; 22 | 23 | public interface FileVariable { 24 | String variable(); 25 | 26 | VariableType type(); 27 | 28 | BlockType location(); 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/br/com/pinter/tqrespec/save/IncompatibleSavegameException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Emerson Pinter - All Rights Reserved 3 | */ 4 | 5 | /* This file is part of TQ Respec. 6 | 7 | TQ Respec is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | TQ Respec is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with TQ Respec. If not, see . 19 | */ 20 | 21 | package br.com.pinter.tqrespec.save; 22 | 23 | @SuppressWarnings("unused") 24 | public class IncompatibleSavegameException extends Exception { 25 | public IncompatibleSavegameException() { 26 | super(); 27 | } 28 | 29 | public IncompatibleSavegameException(String message) { 30 | super(message); 31 | } 32 | 33 | public IncompatibleSavegameException(String message, Throwable cause) { 34 | super(message, cause); 35 | } 36 | 37 | public IncompatibleSavegameException(Throwable cause) { 38 | super(cause); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/br/com/pinter/tqrespec/save/InvalidVariableException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Emerson Pinter - All Rights Reserved 3 | */ 4 | 5 | package br.com.pinter.tqrespec.save; 6 | 7 | public class InvalidVariableException extends RuntimeException { 8 | public InvalidVariableException() { 9 | super(); 10 | } 11 | 12 | public InvalidVariableException(String message) { 13 | super(message); 14 | } 15 | 16 | public InvalidVariableException(String message, Throwable cause) { 17 | super(message, cause); 18 | } 19 | 20 | public InvalidVariableException(Throwable cause) { 21 | super(cause); 22 | } 23 | 24 | protected InvalidVariableException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { 25 | super(message, cause, enableSuppression, writableStackTrace); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/br/com/pinter/tqrespec/save/Platform.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Emerson Pinter - All Rights Reserved 3 | */ 4 | 5 | package br.com.pinter.tqrespec.save; 6 | 7 | public enum Platform { 8 | WINDOWS, 9 | MOBILE, 10 | UNDEFINED 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/br/com/pinter/tqrespec/save/SaveLocation.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2022 Emerson Pinter - All Rights Reserved 3 | */ 4 | 5 | package br.com.pinter.tqrespec.save; 6 | 7 | public enum SaveLocation { 8 | MAIN, 9 | USER, 10 | EXTERNAL, 11 | ARCHIVEMAIN, 12 | ARCHIVEUSER 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/br/com/pinter/tqrespec/save/UID.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Emerson Pinter - All Rights Reserved 3 | */ 4 | 5 | /* This file is part of TQ Respec. 6 | 7 | TQ Respec is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | TQ Respec is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with TQ Respec. If not, see . 19 | */ 20 | 21 | package br.com.pinter.tqrespec.save; 22 | 23 | import org.apache.commons.lang3.StringUtils; 24 | 25 | import java.nio.ByteBuffer; 26 | import java.nio.ByteOrder; 27 | import java.util.Arrays; 28 | import java.util.Objects; 29 | 30 | public class UID { 31 | private final String value; 32 | 33 | public UID(String value) { 34 | if (value == null || value.isBlank() || value.replaceAll("-", "").matches("^0+$")) { 35 | throw new IllegalArgumentException("invalid uid"); 36 | } 37 | this.value = value; 38 | } 39 | 40 | public UID(byte[] value) { 41 | this.value = convertUidByteToString(value); 42 | if (this.value == null || this.value.isBlank() || this.value.replaceAll("-", "").matches("^0+$")) { 43 | throw new IllegalArgumentException("invalid uid"); 44 | } 45 | } 46 | 47 | public static String convertUidByteToString(byte[] uid) { 48 | ByteBuffer uidP1 = ByteBuffer.wrap(Arrays.copyOfRange(uid, 0, 4)).order(ByteOrder.LITTLE_ENDIAN); 49 | ByteBuffer uidP2 = ByteBuffer.wrap(Arrays.copyOfRange(uid, 4, 8)).order(ByteOrder.LITTLE_ENDIAN); 50 | ByteBuffer uidP3 = ByteBuffer.wrap(Arrays.copyOfRange(uid, 8, 12)).order(ByteOrder.LITTLE_ENDIAN); 51 | ByteBuffer uidP4 = ByteBuffer.wrap(Arrays.copyOfRange(uid, 12, 16)).order(ByteOrder.LITTLE_ENDIAN); 52 | 53 | int p4 = uidP4.getInt(); 54 | int p3 = uidP3.getInt(); 55 | int p2 = uidP2.getInt(); 56 | int p1 = uidP1.getInt(); 57 | 58 | String uidStr = String.format("%d-%d-%d-%d", 59 | p4 & 0xFFFFFFFFL, 60 | p3 & 0xFFFFFFFFL, 61 | p2 & 0xFFFFFFFFL, 62 | p1 & 0xFFFFFFFFL); 63 | 64 | if ("0-0-0-0".equals(uidStr) || StringUtils.isBlank(uidStr)) { 65 | return null; 66 | } 67 | return uidStr; 68 | } 69 | 70 | public static byte[] convertUidStringToByte(String uid) { 71 | if (StringUtils.isBlank(uid)) { 72 | return new byte[0]; 73 | } 74 | 75 | String[] p = StringUtils.split(uid, "-"); 76 | long p4 = Long.parseLong(p[3]); 77 | long p3 = Long.parseLong(p[2]); 78 | long p2 = Long.parseLong(p[1]); 79 | long p1 = Long.parseLong(p[0]); 80 | 81 | ByteBuffer uidP4 = ByteBuffer.allocate(4).order(ByteOrder.LITTLE_ENDIAN); 82 | ByteBuffer uidP3 = ByteBuffer.allocate(4).order(ByteOrder.LITTLE_ENDIAN); 83 | ByteBuffer uidP2 = ByteBuffer.allocate(4).order(ByteOrder.LITTLE_ENDIAN); 84 | ByteBuffer uidP1 = ByteBuffer.allocate(4).order(ByteOrder.LITTLE_ENDIAN); 85 | 86 | uidP4.putInt((int) (p4)); 87 | uidP3.putInt((int) p3); 88 | uidP2.putInt((int) p2); 89 | uidP1.putInt((int) p1); 90 | 91 | byte[] ret = new byte[16]; 92 | System.arraycopy(uidP4.array(), 0, ret, 0, 4); 93 | System.arraycopy(uidP3.array(), 0, ret, 4, 4); 94 | System.arraycopy(uidP2.array(), 0, ret, 8, 4); 95 | System.arraycopy(uidP1.array(), 0, ret, 12, 4); 96 | 97 | return ret; 98 | } 99 | 100 | public byte[] getBytes() { 101 | return convertUidStringToByte(value); 102 | } 103 | 104 | public String getUid() { 105 | return value; 106 | } 107 | 108 | @Override 109 | public boolean equals(Object o) { 110 | if (this == o) return true; 111 | if (o == null || getClass() != o.getClass()) return false; 112 | UID uid = (UID) o; 113 | return value.equals(uid.value); 114 | } 115 | 116 | @Override 117 | public int hashCode() { 118 | return Objects.hash(value); 119 | } 120 | 121 | @Override 122 | public String toString() { 123 | return "UID{" + 124 | "value='" + value + '\'' + 125 | '}'; 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /src/main/java/br/com/pinter/tqrespec/save/VariableType.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Emerson Pinter - All Rights Reserved 3 | */ 4 | 5 | /* This file is part of TQ Respec. 6 | 7 | TQ Respec is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | TQ Respec is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with TQ Respec. If not, see . 19 | */ 20 | 21 | package br.com.pinter.tqrespec.save; 22 | 23 | public enum VariableType { 24 | UNKNOWN, 25 | STRING, 26 | INTEGER, 27 | FLOAT, 28 | STRING_UTF_16_LE, 29 | STRING_UTF_32_LE, 30 | UID, 31 | STREAM; 32 | 33 | public int dataTypeSize() { 34 | if (equals(STRING_UTF_16_LE)) { 35 | return 2; 36 | } else if (equals(STRING_UTF_32_LE)) { 37 | return 4; 38 | } else if (equals(STRING)) { 39 | return 1; 40 | } else if (equals(FLOAT) || equals(INTEGER)) { 41 | return 4; 42 | } else if (equals(UID)) { 43 | return 16; 44 | } 45 | throw new IllegalStateException("illegal data type for this method"); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/br/com/pinter/tqrespec/save/exporter/Exporter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Emerson Pinter - All Rights Reserved 3 | */ 4 | 5 | /* This file is part of TQ Respec. 6 | 7 | TQ Respec is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | TQ Respec is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with TQ Respec. If not, see . 19 | */ 20 | 21 | package br.com.pinter.tqrespec.save.exporter; 22 | 23 | import br.com.pinter.tqrespec.save.BlockInfo; 24 | import br.com.pinter.tqrespec.save.FileDataMap; 25 | import br.com.pinter.tqrespec.save.VariableInfo; 26 | import com.fasterxml.jackson.databind.ObjectMapper; 27 | 28 | import java.io.File; 29 | import java.io.IOException; 30 | import java.util.ArrayList; 31 | import java.util.Collections; 32 | import java.util.Comparator; 33 | import java.util.HashMap; 34 | import java.util.List; 35 | import java.util.Map; 36 | 37 | 38 | public class Exporter { 39 | private final File filename; 40 | private final FileDataMap fileDataMap; 41 | private final Map> children; 42 | 43 | public Exporter(File filename, FileDataMap fileDataMap) { 44 | this.filename = filename; 45 | this.fileDataMap = fileDataMap; 46 | this.children = new HashMap<>(); 47 | } 48 | 49 | public void writeJson() throws IOException { 50 | Node tree = getTree(); 51 | ObjectMapper mapper = new ObjectMapper(); 52 | mapper.writerWithDefaultPrettyPrinter().writeValue(filename, tree); 53 | } 54 | 55 | public Node getTree() { 56 | List rootBlocks = fileDataMap.getBlockInfo().values() 57 | .stream().filter(f -> f.getParentOffset() == -1).sorted(Comparator.comparing(BlockInfo::getStart)).toList(); 58 | 59 | for (BlockInfo b : fileDataMap.getBlockInfo().values()) { 60 | children.computeIfAbsent(b.getParentOffset(), k -> new ArrayList<>()); 61 | children.get(b.getParentOffset()).add(b.getStart()); 62 | } 63 | 64 | Node root; 65 | if (fileDataMap.getBlockInfo().containsKey(0)) { 66 | root = new Node(fileDataMap.getBlockInfo().get(0)); 67 | for (VariableInfo v : fileDataMap.getBlockInfo().get(0).getVariables().values()) { 68 | root.getChildren().add(new Node(v)); 69 | } 70 | } else { 71 | root = new Node(); 72 | } 73 | 74 | for (BlockInfo levelZeroBlock : rootBlocks) { 75 | if (levelZeroBlock.getStart() == 0) { 76 | continue; 77 | } 78 | Node levelZeroNode = new Node(levelZeroBlock); 79 | levelZeroNode.getChildren().addAll(childNodes(levelZeroBlock)); 80 | root.getChildren().add(levelZeroNode); 81 | } 82 | 83 | return root; 84 | } 85 | 86 | private List childNodes(BlockInfo b) { 87 | List ret = new ArrayList<>(); 88 | for (VariableInfo v : b.getVariables().values()) { 89 | ret.add(new Node(v)); 90 | } 91 | 92 | if (children.containsKey(b.getStart())) { 93 | for (Integer c : children.get(b.getStart())) { 94 | BlockInfo currentBlock = fileDataMap.getBlockInfo().get(c); 95 | Node currentNode = new Node(currentBlock); 96 | currentNode.getChildren().addAll(childNodes(currentBlock)); 97 | Collections.sort(currentNode.getChildren()); 98 | ret.add(currentNode); 99 | 100 | } 101 | } 102 | return ret; 103 | } 104 | 105 | } 106 | -------------------------------------------------------------------------------- /src/main/java/br/com/pinter/tqrespec/save/exporter/Node.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Emerson Pinter - All Rights Reserved 3 | */ 4 | 5 | /* This file is part of TQ Respec. 6 | 7 | TQ Respec is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | TQ Respec is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with TQ Respec. If not, see . 19 | */ 20 | 21 | package br.com.pinter.tqrespec.save.exporter; 22 | 23 | import br.com.pinter.tqrespec.save.BlockInfo; 24 | import br.com.pinter.tqrespec.save.VariableInfo; 25 | import com.fasterxml.jackson.databind.annotation.JsonSerialize; 26 | 27 | import java.util.ArrayList; 28 | import java.util.List; 29 | import java.util.Objects; 30 | 31 | @JsonSerialize(using = NodeSerializer.class) 32 | public class Node implements Comparable { 33 | private int offset; 34 | private final List children = new ArrayList<>(); 35 | private BlockInfo block; 36 | private VariableInfo variable; 37 | private final Node.Type nodeType; 38 | 39 | @Override 40 | public int compareTo(Node o) { 41 | return Integer.compare(offset, o.offset); 42 | } 43 | 44 | public enum Type { 45 | BLOCK, 46 | VAR 47 | } 48 | 49 | @Override 50 | public boolean equals(Object o) { 51 | if (this == o) return true; 52 | if (o == null || getClass() != o.getClass()) return false; 53 | Node node = (Node) o; 54 | return offset == node.offset && Objects.equals(children, node.children) && Objects.equals(block, node.block) && Objects.equals(variable, node.variable) && nodeType == node.nodeType; 55 | } 56 | 57 | @Override 58 | public int hashCode() { 59 | return Objects.hash(offset, children, block, variable, nodeType); 60 | } 61 | 62 | public Node() { 63 | nodeType = Type.BLOCK; 64 | } 65 | 66 | public Node(BlockInfo block) { 67 | this.block = block; 68 | offset = block.getStart(); 69 | nodeType = Type.BLOCK; 70 | } 71 | 72 | public Node(VariableInfo variable) { 73 | this.variable = variable; 74 | offset = variable.getKeyOffset(); 75 | nodeType = Type.VAR; 76 | } 77 | 78 | public List getChildren() { 79 | return children; 80 | } 81 | 82 | public Type getNodeType() { 83 | return nodeType; 84 | } 85 | 86 | public BlockInfo getBlock() { 87 | return block; 88 | } 89 | 90 | public VariableInfo getVariable() { 91 | return variable; 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /src/main/java/br/com/pinter/tqrespec/save/exporter/NodeSerializer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Emerson Pinter - All Rights Reserved 3 | */ 4 | 5 | /* This file is part of TQ Respec. 6 | 7 | TQ Respec is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | TQ Respec is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with TQ Respec. If not, see . 19 | */ 20 | 21 | package br.com.pinter.tqrespec.save.exporter; 22 | 23 | import br.com.pinter.tqrespec.save.VariableInfo; 24 | import com.fasterxml.jackson.core.JsonGenerator; 25 | import com.fasterxml.jackson.databind.JsonSerializer; 26 | import com.fasterxml.jackson.databind.SerializerProvider; 27 | 28 | import java.io.IOException; 29 | import java.util.Collections; 30 | 31 | public class NodeSerializer extends JsonSerializer { 32 | private void writeField(JsonGenerator gen, VariableInfo v) throws IOException { 33 | if (v.isInt()) { 34 | gen.writeNumberField(v.getName(), (Integer) v.getValue()); 35 | } else if (v.isFloat()) { 36 | gen.writeNumberField(v.getName(), (Float) v.getValue()); 37 | } else if (v.isString() || v.isUid()) { 38 | gen.writeStringField(v.getName(), v.getValueString()); 39 | } else if (v.isStream()) { 40 | gen.writeBinaryField(v.getName(), (byte[]) v.getValue()); 41 | } 42 | } 43 | 44 | @Override 45 | public void serialize(Node node, JsonGenerator gen, SerializerProvider serializers) throws IOException { 46 | Collections.sort(node.getChildren()); 47 | 48 | if (node.getNodeType().equals(Node.Type.BLOCK)) { 49 | gen.writeStartObject(); 50 | if (node.getBlock() != null) { 51 | gen.writeFieldName("$metadata"); 52 | serializers.defaultSerializeValue(node.getBlock(), gen); 53 | } 54 | for (Node c : node.getChildren()) { 55 | if (c.getNodeType().equals(Node.Type.BLOCK)) { 56 | gen.writeFieldName("$block"); 57 | serialize(c, gen, serializers); 58 | } else { 59 | writeField(gen, c.getVariable()); 60 | } 61 | } 62 | gen.writeEndObject(); 63 | } else { 64 | writeField(gen, node.getVariable()); 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/br/com/pinter/tqrespec/save/player/Archiver.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2022 Emerson Pinter - All Rights Reserved 3 | */ 4 | 5 | package br.com.pinter.tqrespec.save.player; 6 | 7 | import br.com.pinter.tqrespec.save.SaveLocation; 8 | import br.com.pinter.tqrespec.tqdata.GameInfo; 9 | import br.com.pinter.tqrespec.tqdata.PlayerCharacter; 10 | import com.google.inject.Inject; 11 | 12 | import java.io.IOException; 13 | import java.nio.file.Files; 14 | import java.nio.file.Path; 15 | import java.nio.file.Paths; 16 | import java.nio.file.StandardCopyOption; 17 | 18 | public class Archiver { 19 | @Inject 20 | private GameInfo gameInfo; 21 | 22 | public void archive(PlayerCharacter playerCharacter) throws IOException { 23 | Path src = playerCharacter.getPath(); 24 | Path dst; 25 | 26 | Path main = Paths.get(gameInfo.getSaveDataMainPath()); 27 | Path mainArchive = Paths.get(gameInfo.getSaveDataMainArchivedPath()); 28 | if (main.toFile().exists() && !mainArchive.toFile().exists()) { 29 | Files.createDirectory(mainArchive); 30 | } 31 | 32 | Path user = Paths.get(gameInfo.getSaveDataUserPath()); 33 | Path userArchive = Paths.get(gameInfo.getSaveDataUserArchivedPath()); 34 | if (user.toFile().exists() && !userArchive.toFile().exists()) { 35 | Files.createDirectory(userArchive); 36 | } 37 | 38 | if (SaveLocation.MAIN.equals(playerCharacter.getLocation())) { 39 | dst = gameInfo.playerPath(playerCharacter.getName(), SaveLocation.ARCHIVEMAIN); 40 | } else if (SaveLocation.USER.equals(playerCharacter.getLocation())) { 41 | dst = gameInfo.playerPath(playerCharacter.getName(), SaveLocation.ARCHIVEUSER); 42 | } else { 43 | throw new IOException("Invalid savegame location"); 44 | } 45 | 46 | if (!dst.startsWith(src.getParent()) || !dst.startsWith(gameInfo.getSavePath())) { 47 | throw new IOException("Error archiving character, invalid path"); 48 | } 49 | 50 | Files.move(src, dst, StandardCopyOption.ATOMIC_MOVE); 51 | } 52 | 53 | public void unarchive(PlayerCharacter playerCharacter) throws IOException { 54 | Path src = playerCharacter.getPath(); 55 | Path dst; 56 | 57 | if (SaveLocation.ARCHIVEMAIN.equals(playerCharacter.getLocation())) { 58 | dst = gameInfo.playerPath(playerCharacter.getName(), SaveLocation.MAIN); 59 | } else if (SaveLocation.ARCHIVEUSER.equals(playerCharacter.getLocation())) { 60 | dst = gameInfo.playerPath(playerCharacter.getName(), SaveLocation.USER); 61 | } else { 62 | throw new IOException("Invalid savegame location"); 63 | } 64 | 65 | if (!src.startsWith(dst.getParent()) || !dst.startsWith(gameInfo.getSavePath())) { 66 | throw new IOException("Error unarchiving character, invalid path"); 67 | } 68 | 69 | Files.move(src, dst, StandardCopyOption.ATOMIC_MOVE); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/main/java/br/com/pinter/tqrespec/save/player/CurrentPlayerData.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Emerson Pinter - All Rights Reserved 3 | */ 4 | 5 | /* This file is part of TQ Respec. 6 | 7 | TQ Respec is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | TQ Respec is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with TQ Respec. If not, see . 19 | */ 20 | 21 | package br.com.pinter.tqrespec.save.player; 22 | 23 | import br.com.pinter.tqrespec.save.FileDataHolder; 24 | import br.com.pinter.tqrespec.save.FileDataMap; 25 | import br.com.pinter.tqrespec.save.Platform; 26 | import br.com.pinter.tqrespec.save.SaveLocation; 27 | import com.google.inject.Singleton; 28 | 29 | import java.nio.ByteBuffer; 30 | import java.nio.file.Path; 31 | import java.util.Collections; 32 | import java.util.LinkedHashMap; 33 | import java.util.Map; 34 | import java.util.concurrent.atomic.AtomicBoolean; 35 | 36 | @Singleton 37 | public class CurrentPlayerData implements FileDataHolder { 38 | private final Map playerSkills = Collections.synchronizedMap(new LinkedHashMap<>()); 39 | private final AtomicBoolean missingSkills = new AtomicBoolean(false); 40 | private String playerName = null; 41 | private Path playerChr = null; 42 | private FileDataMap dataMap = new FileDataMap(); 43 | private HeaderInfo headerInfo = new HeaderInfo(); 44 | private ByteBuffer buffer = null; 45 | private SaveLocation location; 46 | 47 | @Override 48 | public String getPlayerName() { 49 | return playerName; 50 | } 51 | 52 | @Override 53 | public void setPlayerName(String playerName) { 54 | this.playerName = playerName; 55 | } 56 | 57 | public void setLocation(SaveLocation location) { 58 | this.location = location; 59 | } 60 | 61 | public SaveLocation getLocation() { 62 | return location; 63 | } 64 | 65 | boolean isCustomQuest() { 66 | return SaveLocation.USER.equals(location); 67 | } 68 | 69 | String getPlayerClassTag() { 70 | if (getHeaderInfo() != null) { 71 | return getHeaderInfo().getPlayerClassTag(); 72 | } 73 | return null; 74 | } 75 | 76 | String getPlayerCharacterClass() { 77 | return getHeaderInfo().getPlayerCharacterClass(); 78 | } 79 | 80 | Map getPlayerSkills() { 81 | return playerSkills; 82 | } 83 | 84 | Path getPlayerChr() { 85 | return playerChr; 86 | } 87 | 88 | public void setPlayerChr(Path playerChr) { 89 | this.playerChr = playerChr; 90 | } 91 | 92 | HeaderInfo getHeaderInfo() { 93 | return headerInfo; 94 | } 95 | 96 | void setHeaderInfo(HeaderInfo headerInfo) { 97 | this.headerInfo = headerInfo; 98 | } 99 | 100 | @Override 101 | public Path getPlayerPath() { 102 | return playerChr.getParent(); 103 | } 104 | 105 | @Override 106 | public void setPlayerPath(Path playerPath) { 107 | //not implemented 108 | } 109 | 110 | @Override 111 | public ByteBuffer getBuffer() { 112 | return buffer; 113 | } 114 | 115 | @Override 116 | public void setBuffer(ByteBuffer buffer) { 117 | this.buffer = buffer; 118 | } 119 | 120 | @Override 121 | public FileDataMap getDataMap() { 122 | return dataMap; 123 | } 124 | 125 | public boolean isMissingSkills() { 126 | return missingSkills.get(); 127 | } 128 | 129 | public void setMissingSkills(boolean newValue) { 130 | missingSkills.set(newValue); 131 | } 132 | 133 | public Platform getPlatform() { 134 | return getDataMap().getPlatform(); 135 | } 136 | 137 | public void setPlatform(Platform platform) { 138 | getDataMap().setPlatform(platform); 139 | } 140 | 141 | void reset() { 142 | dataMap.clear(); 143 | buffer = null; 144 | headerInfo = new HeaderInfo(); 145 | dataMap = new FileDataMap(); 146 | playerName = null; 147 | location = SaveLocation.MAIN; 148 | playerSkills.clear(); 149 | missingSkills.set(false); 150 | } 151 | 152 | 153 | } 154 | -------------------------------------------------------------------------------- /src/main/java/br/com/pinter/tqrespec/save/player/Gender.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Emerson Pinter - All Rights Reserved 3 | */ 4 | 5 | /* This file is part of TQ Respec. 6 | 7 | TQ Respec is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | TQ Respec is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with TQ Respec. If not, see . 19 | */ 20 | 21 | package br.com.pinter.tqrespec.save.player; 22 | 23 | public enum Gender { 24 | MALE, 25 | FEMALE 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/br/com/pinter/tqrespec/save/player/HeaderInfo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Emerson Pinter - All Rights Reserved 3 | */ 4 | 5 | /* This file is part of TQ Respec. 6 | 7 | TQ Respec is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | TQ Respec is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with TQ Respec. If not, see . 19 | */ 20 | 21 | package br.com.pinter.tqrespec.save.player; 22 | 23 | import br.com.pinter.tqrespec.tqdata.GameVersion; 24 | 25 | import java.io.Serializable; 26 | 27 | @SuppressWarnings("unused") 28 | public class HeaderInfo implements Serializable { 29 | private GameVersion headerVersion = GameVersion.UNKNOWN; 30 | private String playerCharacterClass = null; 31 | private String playerClassTag = null; 32 | private int playerLevel = -1; 33 | private int playerVersion = -1; 34 | 35 | GameVersion getHeaderVersion() { 36 | return headerVersion; 37 | } 38 | 39 | void setHeaderVersion(GameVersion headerVersion) { 40 | this.headerVersion = headerVersion; 41 | } 42 | 43 | public String getPlayerCharacterClass() { 44 | return playerCharacterClass; 45 | } 46 | 47 | void setPlayerCharacterClass(String playerCharacterClass) { 48 | this.playerCharacterClass = playerCharacterClass; 49 | } 50 | 51 | String getPlayerClassTag() { 52 | return playerClassTag; 53 | } 54 | 55 | void setPlayerClassTag(String playerClassTag) { 56 | this.playerClassTag = playerClassTag; 57 | } 58 | 59 | int getPlayerLevel() { 60 | return playerLevel; 61 | } 62 | 63 | void setPlayerLevel(int playerLevel) { 64 | this.playerLevel = playerLevel; 65 | } 66 | 67 | int getPlayerVersion() { 68 | return playerVersion; 69 | } 70 | 71 | void setPlayerVersion(int playerVersion) { 72 | this.playerVersion = playerVersion; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/main/java/br/com/pinter/tqrespec/save/player/PlayerBlockType.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Emerson Pinter - All Rights Reserved 3 | */ 4 | 5 | /* This file is part of TQ Respec. 6 | 7 | TQ Respec is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | TQ Respec is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with TQ Respec. If not, see . 19 | */ 20 | 21 | package br.com.pinter.tqrespec.save.player; 22 | 23 | import br.com.pinter.tqrespec.save.FileBlockType; 24 | 25 | public class PlayerBlockType extends FileBlockType { 26 | public static final FileBlockType PLAYER_HEADER = new FileBlockType(0, "PLAYER_HEADER"); 27 | public static final FileBlockType PLAYER_MAIN = new FileBlockType(1, "PLAYER_MAIN"); 28 | public static final FileBlockType PLAYER_ATTRIBUTES = new FileBlockType(2, "PLAYER_ATTRIBUTES"); 29 | public static final FileBlockType PLAYER_STATS = new FileBlockType(3, "PLAYER_STATS"); 30 | public static final FileBlockType PLAYER_SKILLSLIST = new FileBlockType(4, "PLAYER_SKILLSLIST"); 31 | public static final FileBlockType PLAYER_INVENTORY = new FileBlockType(5, "PLAYER_INVENTORY"); 32 | public static final FileBlockType PLAYER_EQUIPMENT = new FileBlockType(7, "PLAYER_EQUIPMENT"); 33 | public static final FileBlockType PLAYER_HOT_SLOT = new FileBlockType(8, "PLAYER_HOT_SLOT"); 34 | public static final FileBlockType PLAYER_UI_SKILL = new FileBlockType(10, "PLAYER_UI_SKILL"); 35 | public static final FileBlockType PLAYER_LEVEL_POINTS = new FileBlockType(11, "PLAYER_LEVEL_POINTS"); 36 | public static final FileBlockType PLAYER_SKILL = new FileBlockType(9, "PLAYER_SKILL", PlayerBlockType.PLAYER_SKILLSLIST); 37 | public static final FileBlockType PLAYER_ITEM = new FileBlockType(6, "PLAYER_ITEM", PlayerBlockType.PLAYER_INVENTORY_ITEMCONTAINER); 38 | public static final FileBlockType PLAYER_INVENTORY_SACK = new FileBlockType(13, "PLAYER_INVENTORY_SACK", PlayerBlockType.PLAYER_INVENTORY); 39 | public static final FileBlockType PLAYER_INVENTORY_ITEMCONTAINER = new FileBlockType(14, "PLAYER_INVENTORY_ITEMCONTAINER", PlayerBlockType.PLAYER_INVENTORY_SACK); 40 | 41 | public PlayerBlockType(int value, String name) { 42 | super(value, name); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/br/com/pinter/tqrespec/save/player/PlayerLoader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Emerson Pinter - All Rights Reserved 3 | */ 4 | 5 | /* This file is part of TQ Respec. 6 | 7 | TQ Respec is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | TQ Respec is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with TQ Respec. If not, see . 19 | */ 20 | 21 | package br.com.pinter.tqrespec.save.player; 22 | 23 | public class PlayerLoader extends Player { 24 | private CurrentPlayerData saveDataPrivate; 25 | 26 | @Override 27 | protected void prepareSaveData() { 28 | saveDataPrivate = new CurrentPlayerData(); 29 | } 30 | 31 | @Override 32 | public CurrentPlayerData getSaveData() { 33 | return saveDataPrivate; 34 | } 35 | } -------------------------------------------------------------------------------- /src/main/java/br/com/pinter/tqrespec/save/player/PlayerSkill.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Emerson Pinter - All Rights Reserved 3 | */ 4 | 5 | /* This file is part of TQ Respec. 6 | 7 | TQ Respec is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | TQ Respec is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with TQ Respec. If not, see . 19 | */ 20 | 21 | package br.com.pinter.tqrespec.save.player; 22 | 23 | public class PlayerSkill { 24 | private String skillName; 25 | private Integer skillEnabled; 26 | private Integer skillActive; 27 | private Integer skillSubLevel; 28 | private Integer skillTransition; 29 | private Integer skillLevel; 30 | private int blockStart; 31 | 32 | public String getSkillName() { 33 | return skillName; 34 | } 35 | 36 | public void setSkillName(String skillName) { 37 | this.skillName = skillName; 38 | } 39 | 40 | public Integer getSkillEnabled() { 41 | return skillEnabled; 42 | } 43 | 44 | public void setSkillEnabled(Integer skillEnabled) { 45 | this.skillEnabled = skillEnabled; 46 | } 47 | 48 | public Integer getSkillActive() { 49 | return skillActive; 50 | } 51 | 52 | public void setSkillActive(Integer skillActive) { 53 | this.skillActive = skillActive; 54 | } 55 | 56 | public Integer getSkillSubLevel() { 57 | return skillSubLevel; 58 | } 59 | 60 | public void setSkillSubLevel(Integer skillSubLevel) { 61 | this.skillSubLevel = skillSubLevel; 62 | } 63 | 64 | public Integer getSkillTransition() { 65 | return skillTransition; 66 | } 67 | 68 | public void setSkillTransition(Integer skillTransition) { 69 | this.skillTransition = skillTransition; 70 | } 71 | 72 | public Integer getSkillLevel() { 73 | return skillLevel; 74 | } 75 | 76 | public void setSkillLevel(Integer skillLevel) { 77 | this.skillLevel = skillLevel; 78 | } 79 | 80 | public int getBlockStart() { 81 | return blockStart; 82 | } 83 | 84 | public void setBlockStart(int blockStart) { 85 | this.blockStart = blockStart; 86 | } 87 | 88 | @Override 89 | public String toString() { 90 | return "PlayerSkill{" + 91 | "skillName='" + skillName + '\'' + 92 | ", skillEnabled=" + skillEnabled + 93 | ", skillActive=" + skillActive + 94 | ", skillSubLevel=" + skillSubLevel + 95 | ", skillTransition=" + skillTransition + 96 | ", skillLevel=" + skillLevel + 97 | ", blockStart=" + blockStart + 98 | '}'; 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /src/main/java/br/com/pinter/tqrespec/save/player/TeleportDifficulty.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Emerson Pinter - All Rights Reserved 3 | */ 4 | 5 | /* This file is part of TQ Respec. 6 | 7 | TQ Respec is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | TQ Respec is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with TQ Respec. If not, see . 19 | */ 20 | 21 | package br.com.pinter.tqrespec.save.player; 22 | 23 | import br.com.pinter.tqrespec.save.BlockInfo; 24 | import br.com.pinter.tqrespec.save.UID; 25 | import br.com.pinter.tqrespec.save.VariableInfo; 26 | 27 | import java.util.ArrayList; 28 | import java.util.List; 29 | 30 | public class TeleportDifficulty { 31 | private final int difficulty; 32 | private final int size; 33 | private final int offset; 34 | private final BlockInfo blockInfo; 35 | private final List variables; 36 | private final List teleports = new ArrayList<>(); 37 | 38 | public TeleportDifficulty(int difficulty, int size, int offset, List variables, BlockInfo blockInfo) { 39 | this.difficulty = difficulty; 40 | this.size = size; 41 | this.offset = offset; 42 | this.variables = variables; 43 | this.blockInfo = blockInfo; 44 | for (VariableInfo v : variables) { 45 | if (v.isUid()) { 46 | teleports.add(new UID((byte[]) v.getValue())); 47 | } 48 | } 49 | } 50 | 51 | public int getDifficulty() { 52 | return difficulty; 53 | } 54 | 55 | public int getSize() { 56 | return size; 57 | } 58 | 59 | public int getOffset() { 60 | return offset; 61 | } 62 | 63 | public List getVariables() { 64 | return variables; 65 | } 66 | 67 | public List getTeleports() { 68 | return teleports; 69 | } 70 | 71 | public BlockInfo getBlockInfo() { 72 | return blockInfo; 73 | } 74 | 75 | @Override 76 | public String toString() { 77 | return "TeleportDifficulty{" + 78 | "difficulty=" + difficulty + 79 | ", size=" + size + 80 | ", offset=" + offset + 81 | ", teleportList=" + variables + 82 | '}'; 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/main/java/br/com/pinter/tqrespec/save/stash/StashBlockType.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Emerson Pinter - All Rights Reserved 3 | */ 4 | 5 | /* This file is part of TQ Respec. 6 | 7 | TQ Respec is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | TQ Respec is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with TQ Respec. If not, see . 19 | */ 20 | 21 | package br.com.pinter.tqrespec.save.stash; 22 | 23 | import br.com.pinter.tqrespec.save.FileBlockType; 24 | 25 | class StashBlockType extends FileBlockType { 26 | static final FileBlockType STASH_MAIN = new FileBlockType(0, "STASH_MAIN"); 27 | static final FileBlockType STASH_ITEM = new FileBlockType(1, "STASH_ITEM"); 28 | static final FileBlockType STASH_ITEM_PREFIX = new FileBlockType(2, "STASH_ITEM_PREFIX"); 29 | static final FileBlockType STASH_ITEM_SUFFIX = new FileBlockType(3, "STASH_ITEM_SUFFIX"); 30 | 31 | public StashBlockType(int value, String name) { 32 | super(value, name); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/br/com/pinter/tqrespec/save/stash/StashData.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Emerson Pinter - All Rights Reserved 3 | */ 4 | 5 | /* This file is part of TQ Respec. 6 | 7 | TQ Respec is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | TQ Respec is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with TQ Respec. If not, see . 19 | */ 20 | 21 | package br.com.pinter.tqrespec.save.stash; 22 | 23 | import br.com.pinter.tqrespec.save.FileDataHolder; 24 | import br.com.pinter.tqrespec.save.FileDataMap; 25 | 26 | import java.nio.ByteBuffer; 27 | import java.nio.file.Path; 28 | 29 | public class StashData implements FileDataHolder { 30 | private String playerName = null; 31 | private Path playerPath = null; 32 | private boolean customQuest = false; 33 | private FileDataMap dataMap = new FileDataMap(); 34 | private ByteBuffer buffer = null; 35 | 36 | @Override 37 | public String getPlayerName() { 38 | return playerName; 39 | } 40 | 41 | @Override 42 | public void setPlayerName(String playerName) { 43 | this.playerName = playerName; 44 | } 45 | 46 | @Override 47 | public Path getPlayerPath() { 48 | return playerPath; 49 | } 50 | 51 | @Override 52 | public void setPlayerPath(Path playerPath) { 53 | this.playerPath = playerPath; 54 | } 55 | 56 | public boolean isCustomQuest() { 57 | return customQuest; 58 | } 59 | 60 | public void setCustomQuest(boolean customQuest) { 61 | this.customQuest = customQuest; 62 | } 63 | 64 | @Override 65 | public FileDataMap getDataMap() { 66 | return dataMap; 67 | } 68 | 69 | @Override 70 | public ByteBuffer getBuffer() { 71 | return buffer; 72 | } 73 | 74 | @Override 75 | public void setBuffer(ByteBuffer buffer) { 76 | this.buffer = buffer; 77 | } 78 | 79 | void reset() { 80 | dataMap.clear(); 81 | this.buffer = null; 82 | this.dataMap = new FileDataMap(); 83 | this.playerName = null; 84 | this.customQuest = false; 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/main/java/br/com/pinter/tqrespec/save/stash/StashFileVariable.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Emerson Pinter - All Rights Reserved 3 | */ 4 | 5 | /* This file is part of TQ Respec. 6 | 7 | TQ Respec is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | TQ Respec is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with TQ Respec. If not, see . 19 | */ 20 | 21 | package br.com.pinter.tqrespec.save.stash; 22 | 23 | import br.com.pinter.tqrespec.save.BlockType; 24 | import br.com.pinter.tqrespec.save.FileVariable; 25 | import br.com.pinter.tqrespec.save.VariableType; 26 | 27 | import java.util.HashMap; 28 | 29 | class StashFileVariable implements FileVariable { 30 | private static final HashMap map = new HashMap<>(); 31 | 32 | static { 33 | map.put("stashVersion", new StashFileVariable("stashVersion", VariableType.INTEGER, StashBlockType.STASH_MAIN)); 34 | map.put("fName", new StashFileVariable("fName", VariableType.STRING, StashBlockType.STASH_MAIN)); 35 | map.put("sackWidth", new StashFileVariable("sackWidth", VariableType.INTEGER, StashBlockType.STASH_MAIN)); 36 | map.put("sackHeight", new StashFileVariable("sackHeight", VariableType.INTEGER, StashBlockType.STASH_MAIN)); 37 | map.put("numItems", new StashFileVariable("numItems", VariableType.INTEGER, StashBlockType.STASH_MAIN)); 38 | 39 | map.put("stackCount", new StashFileVariable("stackCount", VariableType.INTEGER, StashBlockType.STASH_MAIN)); 40 | map.put("baseName", new StashFileVariable("baseName", VariableType.STRING, StashBlockType.STASH_ITEM)); 41 | map.put("prefixName", new StashFileVariable("prefixName", VariableType.STRING, StashBlockType.STASH_ITEM)); 42 | map.put("suffixName", new StashFileVariable("suffixName", VariableType.STRING, StashBlockType.STASH_ITEM)); 43 | map.put("relicName", new StashFileVariable("relicName", VariableType.STRING, StashBlockType.STASH_ITEM)); 44 | map.put("relicBonus", new StashFileVariable("relicBonus", VariableType.STRING, StashBlockType.STASH_ITEM)); 45 | map.put("seed", new StashFileVariable("seed", VariableType.INTEGER, StashBlockType.STASH_ITEM)); 46 | map.put("var1", new StashFileVariable("var1", VariableType.INTEGER, StashBlockType.STASH_ITEM)); 47 | map.put("relicName2", new StashFileVariable("relicName2", VariableType.STRING, StashBlockType.STASH_ITEM)); 48 | map.put("relicBonus2", new StashFileVariable("relicBonus2", VariableType.STRING, StashBlockType.STASH_ITEM)); 49 | map.put("var2", new StashFileVariable("var2", VariableType.INTEGER, StashBlockType.STASH_ITEM)); 50 | map.put("xOffset", new StashFileVariable("xOffset", VariableType.INTEGER, StashBlockType.STASH_MAIN)); 51 | map.put("yOffset", new StashFileVariable("yOffset", VariableType.INTEGER, StashBlockType.STASH_MAIN)); 52 | } 53 | 54 | private final BlockType location; 55 | private final String variable; 56 | private final VariableType type; 57 | 58 | private StashFileVariable(String variable, VariableType type, BlockType location) { 59 | this.variable = variable; 60 | this.type = type; 61 | this.location = location; 62 | } 63 | 64 | static StashFileVariable valueOf(String variable) { 65 | return map.get(variable); 66 | } 67 | 68 | @Override 69 | public String variable() { 70 | return variable; 71 | } 72 | 73 | @Override 74 | public VariableType type() { 75 | return type; 76 | } 77 | 78 | @Override 79 | public BlockType location() { 80 | return location; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/main/java/br/com/pinter/tqrespec/save/stash/StashLoader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Emerson Pinter - All Rights Reserved 3 | */ 4 | 5 | /* This file is part of TQ Respec. 6 | 7 | TQ Respec is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | TQ Respec is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with TQ Respec. If not, see . 19 | */ 20 | 21 | package br.com.pinter.tqrespec.save.stash; 22 | 23 | import br.com.pinter.tqrespec.util.Constants; 24 | 25 | import java.nio.file.Files; 26 | import java.nio.file.Path; 27 | 28 | public class StashLoader { 29 | private StashData stashData; 30 | 31 | public StashData getSaveData() { 32 | return stashData; 33 | } 34 | 35 | public boolean loadStash(Path playerPath, String playerName) { 36 | if (!Files.exists(playerPath.resolve(Constants.STASH_FILE))) { 37 | return false; 38 | } 39 | StashParser stashParser = new StashParser(playerPath.toString()); 40 | stashData = new StashData(); 41 | stashData.setPlayerPath(playerPath); 42 | stashData.setBuffer(stashParser.load()); 43 | stashData.setPlayerName(playerName); 44 | stashData.setCustomQuest(false); 45 | stashData.getDataMap().setBlockInfo(stashParser.getBlockInfo()); 46 | stashData.getDataMap().setVariableLocation(stashParser.getVariableLocation()); 47 | return true; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/br/com/pinter/tqrespec/save/stash/StashParser.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Emerson Pinter - All Rights Reserved 3 | */ 4 | 5 | /* This file is part of TQ Respec. 6 | 7 | TQ Respec is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | TQ Respec is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with TQ Respec. If not, see . 19 | */ 20 | 21 | package br.com.pinter.tqrespec.save.stash; 22 | 23 | import br.com.pinter.tqrespec.logging.Log; 24 | import br.com.pinter.tqrespec.save.BlockInfo; 25 | import br.com.pinter.tqrespec.save.BlockType; 26 | import br.com.pinter.tqrespec.save.FileParser; 27 | import br.com.pinter.tqrespec.save.FileVariable; 28 | import br.com.pinter.tqrespec.save.Platform; 29 | import br.com.pinter.tqrespec.save.VariableInfo; 30 | import br.com.pinter.tqrespec.util.Constants; 31 | 32 | import java.io.FileInputStream; 33 | import java.io.IOException; 34 | import java.nio.ByteBuffer; 35 | import java.nio.ByteOrder; 36 | import java.nio.channels.FileChannel; 37 | import java.nio.file.Files; 38 | import java.nio.file.Paths; 39 | 40 | import static java.lang.System.Logger.Level.DEBUG; 41 | 42 | class StashParser extends FileParser { 43 | private static final System.Logger logger = Log.getLogger(StashParser.class); 44 | private final String playerPath; 45 | 46 | public StashParser(String playerPath) { 47 | this.playerPath = playerPath; 48 | } 49 | 50 | private String getStashFileName() { 51 | return Paths.get(playerPath, Constants.STASH_FILE).toString(); 52 | } 53 | 54 | @Override 55 | protected boolean readFile() throws IOException { 56 | if (!Files.exists(Paths.get(getStashFileName()))) { 57 | return false; 58 | } 59 | try (FileInputStream chr = new FileInputStream(getStashFileName())) { 60 | try (FileChannel in = chr.getChannel()) { 61 | setBuffer(ByteBuffer.allocate((int) in.size())); 62 | this.getBuffer().order(ByteOrder.LITTLE_ENDIAN); 63 | 64 | while (true) { 65 | if (in.read(this.getBuffer()) <= 0) break; 66 | } 67 | } 68 | } 69 | 70 | logger.log(DEBUG, "File ''{0}'' read to buffer: ''{1}''", getStashFileName(), this.getBuffer()); 71 | return this.getBuffer() != null; 72 | } 73 | 74 | @Override 75 | protected void preprocessVariable(String name, int keyOffset, BlockType block) { 76 | //not implemented 77 | } 78 | 79 | @Override 80 | protected void prepareForParse() throws IOException { 81 | if (this.getBuffer() == null || this.getBuffer().capacity() <= 50) { 82 | throw new IOException("Can't read stash from" + playerPath); 83 | } 84 | logger.log(DEBUG, "Stash ''{0}'' loaded, size=''{1}''", playerPath, this.getBuffer().capacity()); 85 | } 86 | 87 | @Override 88 | protected void prepareBlockSpecialVariable(VariableInfo variableInfo, String name) { 89 | //not implemented 90 | } 91 | 92 | @Override 93 | protected void processBlockSpecialVariable(BlockInfo block) { 94 | //not implemented 95 | } 96 | 97 | @Override 98 | protected FileVariable getFileVariable(String variable) { 99 | return StashFileVariable.valueOf(variable); 100 | } 101 | 102 | @Override 103 | protected FileVariable getPlatformFileVariable(Platform platform, String variable) { 104 | return getFileVariable(variable); 105 | } 106 | 107 | } 108 | -------------------------------------------------------------------------------- /src/main/java/br/com/pinter/tqrespec/save/stash/StashWriter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Emerson Pinter - All Rights Reserved 3 | */ 4 | 5 | /* This file is part of TQ Respec. 6 | 7 | TQ Respec is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | TQ Respec is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with TQ Respec. If not, see . 19 | */ 20 | 21 | package br.com.pinter.tqrespec.save.stash; 22 | 23 | import br.com.pinter.tqrespec.logging.Log; 24 | import br.com.pinter.tqrespec.save.FileDataHolder; 25 | import br.com.pinter.tqrespec.save.FileWriter; 26 | import br.com.pinter.tqrespec.util.Constants; 27 | 28 | import java.io.IOException; 29 | 30 | import static java.lang.System.Logger.Level.ERROR; 31 | 32 | public class StashWriter extends FileWriter { 33 | private static final System.Logger logger = Log.getLogger(StashWriter.class); 34 | 35 | private final StashData saveData; 36 | private final int crcOffset; 37 | private final boolean createCrc; 38 | 39 | public StashWriter(StashData saveData) { 40 | this.saveData = saveData; 41 | createCrc = true; 42 | crcOffset = 0; 43 | } 44 | 45 | public boolean save() { 46 | try { 47 | String fName = String.format("%s/winsys.dxb", saveData.getPlayerPath()); 48 | getSaveData().getDataMap().setString("fName", fName); 49 | writeBuffer(saveData.getPlayerPath().toString(), Constants.STASH_FILE); 50 | getSaveData().getDataMap().setString("fName", fName.replaceAll("\\.dxb$", ".dxg")); 51 | writeBuffer(saveData.getPlayerPath().toString(), Constants.STASH_FILE_BACKUP); 52 | return true; 53 | } catch (IOException e) { 54 | logger.log(ERROR, Constants.ERROR_MSG_EXCEPTION, e); 55 | } 56 | return false; 57 | } 58 | 59 | public int getCrcOffset() { 60 | return crcOffset; 61 | } 62 | 63 | public boolean isCreateCrc() { 64 | return createCrc; 65 | } 66 | 67 | @Override 68 | protected FileDataHolder getSaveData() { 69 | return saveData; 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /src/main/java/br/com/pinter/tqrespec/tqdata/Db.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Emerson Pinter - All Rights Reserved 3 | */ 4 | 5 | /* This file is part of TQ Respec. 6 | 7 | TQ Respec is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | TQ Respec is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with TQ Respec. If not, see . 19 | */ 20 | 21 | package br.com.pinter.tqrespec.tqdata; 22 | 23 | import br.com.pinter.tqdatabase.Database; 24 | import br.com.pinter.tqdatabase.Player; 25 | import br.com.pinter.tqdatabase.Skills; 26 | import br.com.pinter.tqdatabase.Teleports; 27 | import br.com.pinter.tqdatabase.models.DbRecord; 28 | import br.com.pinter.tqrespec.core.GameNotFoundException; 29 | import br.com.pinter.tqrespec.core.UnhandledRuntimeException; 30 | import br.com.pinter.tqrespec.logging.Log; 31 | import com.google.inject.Inject; 32 | import com.google.inject.Singleton; 33 | 34 | import java.io.IOException; 35 | import java.nio.file.Path; 36 | 37 | import static java.lang.System.Logger.Level.ERROR; 38 | import static java.lang.System.Logger.Level.INFO; 39 | 40 | @Singleton 41 | public class Db { 42 | private static final System.Logger logger = Log.getLogger(Db.class); 43 | private Database database; 44 | private Db.Platform platform = Db.Platform.WINDOWS; 45 | 46 | @Inject 47 | private GameInfo gameInfo; 48 | 49 | public Db.Platform getPlatform() { 50 | return platform; 51 | } 52 | 53 | public void initialize() { 54 | try { 55 | if (database == null) { 56 | database = new Database(gameInfo.getDatabasePath()); 57 | if (gameInfo.getInstallType().equals(InstallType.UNKNOWN) 58 | && !Path.of(gameInfo.getGamePath(), "FORCE_WINDOWS.txt").toFile().exists() 59 | && (recordExists("Records\\InGameUI\\Player Character\\Mobile\\CharStatsMobile.dbr") 60 | || recordExists("Records\\xpack\\ui\\hud\\hud_mobile.dbr"))) { 61 | logger.log(INFO, 62 | "Mobile database detected. If this database is from Windows version, create the file to force detection: " 63 | + Path.of(gameInfo.getGamePath(), "FORCE_WINDOWS.txt").toFile()); 64 | platform = Platform.MOBILE; 65 | } 66 | } 67 | } catch (IOException | GameNotFoundException e) { 68 | logger.log(ERROR, "", e); 69 | throw new UnhandledRuntimeException("Error loading database.", e); 70 | } 71 | } 72 | 73 | public Skills skills() { 74 | initialize(); 75 | return database.skills(); 76 | } 77 | 78 | public Player player() { 79 | initialize(); 80 | return database.player(); 81 | } 82 | 83 | public Teleports teleports() { 84 | initialize(); 85 | return database.teleports(); 86 | } 87 | 88 | public DbRecord getRecord(String recordPath) { 89 | return database.getRecord(recordPath); 90 | } 91 | 92 | public void loadMod(Path dbPath) throws IOException { 93 | database.loadMod(dbPath); 94 | } 95 | 96 | public void unloadMods() { 97 | database.unloadMods(); 98 | } 99 | 100 | public void preloadAll() { 101 | initialize(); 102 | database.preloadAll(); 103 | } 104 | 105 | public boolean recordExists(String recordId) { 106 | return database.recordExists(recordId); 107 | } 108 | 109 | public enum Platform { 110 | WINDOWS, 111 | MOBILE 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /src/main/java/br/com/pinter/tqrespec/tqdata/DefaultAct.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Emerson Pinter - All Rights Reserved 3 | */ 4 | 5 | /* This file is part of TQ Respec. 6 | 7 | TQ Respec is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | TQ Respec is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with TQ Respec. If not, see . 19 | */ 20 | 21 | package br.com.pinter.tqrespec.tqdata; 22 | 23 | import java.util.Arrays; 24 | import java.util.Optional; 25 | 26 | public enum DefaultAct { 27 | GREECE(1), 28 | EGYPT(2), 29 | ORIENT(3), 30 | HADES(4), 31 | NORTH(5), 32 | ATLANTIS(6), 33 | EAST(7); 34 | 35 | private final int value; 36 | 37 | DefaultAct(int value) { 38 | this.value = value; 39 | } 40 | 41 | public static int get(DefaultAct v) { 42 | Optional first = Arrays.stream(DefaultAct.values()).filter((f -> f.value == v.getValue())).findFirst(); 43 | if (first.isEmpty()) { 44 | throw new EnumConstantNotPresentException(DefaultAct.class, String.valueOf(v)); 45 | } 46 | return first.get().getValue(); 47 | } 48 | 49 | public String getTag() { 50 | switch (value) { 51 | case 1 -> { 52 | return "tagMGreece"; 53 | } 54 | case 2 -> { 55 | return "tagMEgypt"; 56 | } 57 | case 3 -> { 58 | return "tagMOrient"; 59 | } 60 | case 4 -> { 61 | return "xtagMHades"; 62 | } 63 | case 5 -> { 64 | return "x2tagMNorth"; 65 | } 66 | case 6 -> { 67 | return "x3tagQAct06"; 68 | } 69 | case 7 -> { 70 | return "x4tagMChina"; 71 | } 72 | default -> { 73 | return ""; 74 | } 75 | } 76 | } 77 | 78 | public int getValue() { 79 | return value; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/main/java/br/com/pinter/tqrespec/tqdata/GameResources.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Emerson Pinter - All Rights Reserved 3 | */ 4 | 5 | /* This file is part of TQ Respec. 6 | 7 | TQ Respec is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | TQ Respec is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with TQ Respec. If not, see . 19 | */ 20 | 21 | package br.com.pinter.tqrespec.tqdata; 22 | 23 | import br.com.pinter.tqdatabase.Resources; 24 | import br.com.pinter.tqrespec.logging.Log; 25 | import br.com.pinter.tqrespec.util.Constants; 26 | import com.google.inject.Inject; 27 | import com.google.inject.Singleton; 28 | 29 | import java.io.IOException; 30 | import java.nio.file.Path; 31 | import java.util.Collections; 32 | import java.util.Map; 33 | 34 | import static java.lang.System.Logger.Level.ERROR; 35 | 36 | @Singleton 37 | public class GameResources { 38 | private static final System.Logger logger = Log.getLogger(GameResources.class); 39 | 40 | @Inject 41 | private GameInfo gameInfo; 42 | 43 | public Map getAllFonts() { 44 | try { 45 | Resources fonts = new Resources(Path.of(gameInfo.getResourcesPath(), "Fonts.arc").toString()); 46 | return fonts.getAllFonts(); 47 | } catch (IOException e) { 48 | logger.log(ERROR, Constants.ERROR_MSG_EXCEPTION, e); 49 | return Collections.emptyMap(); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/br/com/pinter/tqrespec/tqdata/GameVersion.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Emerson Pinter - All Rights Reserved 3 | */ 4 | 5 | /* This file is part of TQ Respec. 6 | 7 | TQ Respec is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | TQ Respec is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with TQ Respec. If not, see . 19 | */ 20 | 21 | package br.com.pinter.tqrespec.tqdata; 22 | 23 | import java.util.Arrays; 24 | import java.util.Optional; 25 | 26 | public enum GameVersion { 27 | UNKNOWN(0), 28 | TQ(1), 29 | TQIT(2), 30 | TQAE(3), 31 | TQLE(4); 32 | 33 | private final int value; 34 | 35 | GameVersion(int value) { 36 | this.value = value; 37 | } 38 | 39 | public static GameVersion fromValue(int version) { 40 | Optional first = Arrays.stream(GameVersion.values()).filter(f -> f.value() == version).findFirst(); 41 | if (first.isEmpty()) { 42 | throw new EnumConstantNotPresentException(GameVersion.class, String.valueOf(version)); 43 | } 44 | return first.get(); 45 | } 46 | 47 | public int value() { 48 | return value; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/br/com/pinter/tqrespec/tqdata/InstallType.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Emerson Pinter - All Rights Reserved 3 | */ 4 | 5 | /* This file is part of TQ Respec. 6 | 7 | TQ Respec is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | TQ Respec is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with TQ Respec. If not, see . 19 | */ 20 | 21 | package br.com.pinter.tqrespec.tqdata; 22 | 23 | import java.util.Arrays; 24 | import java.util.Optional; 25 | 26 | public enum InstallType { 27 | UNKNOWN(0), 28 | WINDOWS(1), 29 | STEAM(2), 30 | GOG(3), 31 | MICROSOFT_STORE(4), 32 | LEGACY_DISC(5), 33 | ALTERNATIVE_STEAM_API(6), 34 | MANUAL(100); 35 | 36 | private final int value; 37 | 38 | InstallType(int value) { 39 | this.value = value; 40 | } 41 | 42 | public static InstallType fromValue(int version) { 43 | Optional first = Arrays.stream(InstallType.values()).filter(f -> f.value() == version).findFirst(); 44 | if (first.isEmpty()) { 45 | throw new EnumConstantNotPresentException(InstallType.class, String.valueOf(version)); 46 | } 47 | return first.get(); 48 | } 49 | 50 | public int value() { 51 | return value; 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/br/com/pinter/tqrespec/tqdata/MapTeleport.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Emerson Pinter - All Rights Reserved 3 | */ 4 | 5 | /* This file is part of TQ Respec. 6 | 7 | TQ Respec is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | TQ Respec is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with TQ Respec. If not, see . 19 | */ 20 | 21 | package br.com.pinter.tqrespec.tqdata; 22 | 23 | import br.com.pinter.tqrespec.save.UID; 24 | 25 | import java.util.Objects; 26 | 27 | public abstract class MapTeleport { 28 | private final int order; 29 | private final UID uid; 30 | private final String recordId; 31 | private final int act; 32 | private String name; 33 | private String tag; 34 | 35 | protected MapTeleport(int order, UID uid, int act, String recordId, String tag) { 36 | this.order = order; 37 | this.uid = uid; 38 | this.recordId = recordId; 39 | this.act = act; 40 | this.tag = tag; 41 | } 42 | 43 | protected MapTeleport(MapTeleport o) { 44 | this.order = o.order; 45 | this.uid = o.uid; 46 | this.recordId = o.recordId; 47 | this.act = o.act; 48 | this.name = o.name; 49 | this.tag = o.tag; 50 | } 51 | 52 | public int getOrder() { 53 | return order; 54 | } 55 | 56 | public UID getUid() { 57 | return uid; 58 | } 59 | 60 | public String getRecordId() { 61 | return recordId; 62 | } 63 | 64 | public int getAct() { 65 | return act; 66 | } 67 | 68 | public String getName() { 69 | return name; 70 | } 71 | 72 | public void setName(String name) { 73 | this.name = name; 74 | } 75 | 76 | public String getTag() { 77 | return tag; 78 | } 79 | 80 | public void setTag(String tag) { 81 | this.tag = tag; 82 | } 83 | 84 | @Override 85 | public boolean equals(Object o) { 86 | if (o == null || getClass() != o.getClass()) return false; 87 | MapTeleport that = (MapTeleport) o; 88 | return Objects.equals(uid, that.uid); 89 | } 90 | 91 | @Override 92 | public int hashCode() { 93 | return Objects.hashCode(uid); 94 | } 95 | 96 | @Override 97 | public String toString() { 98 | return "MapTeleport{" + 99 | "name='" + name + '\'' + 100 | ", order=" + order + 101 | ", uid=" + uid + 102 | ", recordId='" + recordId + '\'' + 103 | ", act=" + act + 104 | '}'; 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /src/main/java/br/com/pinter/tqrespec/tqdata/Mastery.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Emerson Pinter - All Rights Reserved 3 | */ 4 | 5 | /* This file is part of TQ Respec. 6 | 7 | TQ Respec is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | TQ Respec is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with TQ Respec. If not, see . 19 | */ 20 | 21 | package br.com.pinter.tqrespec.tqdata; 22 | 23 | import br.com.pinter.tqdatabase.models.Skill; 24 | 25 | public class Mastery { 26 | private String displayName; 27 | private int level; 28 | private Skill skill; 29 | 30 | public String getDisplayName() { 31 | return displayName; 32 | } 33 | 34 | public void setDisplayName(String displayName) { 35 | this.displayName = displayName; 36 | } 37 | 38 | public int getLevel() { 39 | return level; 40 | } 41 | 42 | public void setLevel(int level) { 43 | this.level = level; 44 | } 45 | 46 | public Skill getSkill() { 47 | return skill; 48 | } 49 | 50 | public void setSkill(Skill skill) { 51 | this.skill = skill; 52 | } 53 | 54 | @Override 55 | public String toString() { 56 | return "Mastery{" + 57 | "name='" + displayName + '\'' + 58 | ", level=" + level + 59 | ", mastery=" + skill + 60 | '}'; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/br/com/pinter/tqrespec/tqdata/PlayerCharacterFile.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Emerson Pinter - All Rights Reserved 3 | */ 4 | 5 | package br.com.pinter.tqrespec.tqdata; 6 | 7 | import br.com.pinter.tqrespec.save.SaveLocation; 8 | 9 | public class PlayerCharacterFile { 10 | private final String playerName; 11 | private final SaveLocation location; 12 | 13 | public PlayerCharacterFile(String playerName, SaveLocation location) { 14 | this.playerName = playerName; 15 | this.location = location; 16 | } 17 | 18 | public String getPlayerName() { 19 | return playerName; 20 | } 21 | 22 | public SaveLocation getLocation() { 23 | return location; 24 | } 25 | 26 | @Override 27 | public String toString() { 28 | return playerName; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/br/com/pinter/tqrespec/tqdata/Txt.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Emerson Pinter - All Rights Reserved 3 | */ 4 | 5 | /* This file is part of TQ Respec. 6 | 7 | TQ Respec is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | TQ Respec is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with TQ Respec. If not, see . 19 | */ 20 | 21 | package br.com.pinter.tqrespec.tqdata; 22 | 23 | import br.com.pinter.tqdatabase.Text; 24 | import br.com.pinter.tqrespec.core.State; 25 | import br.com.pinter.tqrespec.core.UnhandledRuntimeException; 26 | import br.com.pinter.tqrespec.logging.Log; 27 | import br.com.pinter.tqrespec.util.Constants; 28 | import com.google.inject.Inject; 29 | import com.google.inject.Singleton; 30 | import org.apache.commons.lang3.StringUtils; 31 | import org.apache.commons.text.WordUtils; 32 | 33 | import java.io.FileNotFoundException; 34 | import java.io.IOException; 35 | import java.nio.file.Path; 36 | import java.util.ArrayList; 37 | import java.util.List; 38 | import java.util.Locale; 39 | 40 | import static java.lang.System.Logger.Level.ERROR; 41 | import static java.lang.System.Logger.Level.INFO; 42 | 43 | @Singleton 44 | public class Txt { 45 | private static final System.Logger logger = Log.getLogger(Txt.class); 46 | private final List text = new ArrayList<>(); 47 | private final List textMod = new ArrayList<>(); 48 | 49 | @Inject 50 | private GameInfo gameInfo; 51 | 52 | public void initialize() { 53 | try { 54 | if (text.isEmpty()) { 55 | text.add(new Text(gameInfo.getTextPath(), Constants.LOCALE_TEXT.get(State.get().getLocale()))); 56 | if (!State.get().getLocale().equals(Locale.ENGLISH)) { 57 | text.add(new Text(gameInfo.getTextPath(), Constants.LOCALE_TEXT.get(Locale.ENGLISH), false)); 58 | } 59 | } 60 | } catch (FileNotFoundException e) { 61 | logger.log(ERROR, Constants.ERROR_MSG_EXCEPTION, e); 62 | throw new UnhandledRuntimeException("Error loading text resource."); 63 | } 64 | } 65 | 66 | public String getString(String tag) { 67 | initialize(); 68 | if (StringUtils.isBlank(tag)) { 69 | return tag; 70 | } 71 | try { 72 | for (Text t : textMod) { 73 | String str = t.getString(tag); 74 | if (!StringUtils.isBlank(str) && !tag.equals(str)) { 75 | return str; 76 | } 77 | } 78 | for (Text t : text) { 79 | String str = t.getString(tag); 80 | if (!StringUtils.isBlank(str) && !tag.equals(str)) { 81 | return str; 82 | } 83 | } 84 | 85 | } catch (IOException ignore) { 86 | return null; 87 | } 88 | return null; 89 | } 90 | 91 | public void preload() { 92 | initialize(); 93 | try { 94 | for (Text t : text) { 95 | t.preload(); 96 | } 97 | for (Text t : textMod) { 98 | t.preload(); 99 | } 100 | } catch (IOException e) { 101 | throw new UnhandledRuntimeException("Error loading text resource", e); 102 | } 103 | } 104 | 105 | public String getCapitalizedString(String tag) { 106 | return WordUtils.capitalize(getString(tag)); 107 | } 108 | 109 | public boolean isTagStringValid(String tag) { 110 | String str = getString(tag); 111 | return !StringUtils.isBlank(tag) && !StringUtils.isBlank(str) && !tag.equals(str); 112 | } 113 | 114 | public void loadMod(Path path) { 115 | String[] paths = new String[]{path.toAbsolutePath().toString()}; 116 | 117 | textMod.add(new Text(paths, Constants.LOCALE_TEXT.get(State.get().getLocale()), false)); 118 | text.getFirst().clearCache(); 119 | preload(); 120 | } 121 | 122 | public void unloadMods() { 123 | textMod.clear(); 124 | text.getFirst().clearCache(); 125 | preload(); 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /src/main/java/br/com/pinter/tqrespec/util/Build.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2022 Emerson Pinter - All Rights Reserved 3 | */ 4 | 5 | /* This file is part of TQ Respec. 6 | 7 | TQ Respec is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | TQ Respec is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with TQ Respec. If not, see . 19 | */ 20 | 21 | package br.com.pinter.tqrespec.util; 22 | 23 | import org.apache.commons.lang3.StringUtils; 24 | 25 | import java.io.IOException; 26 | import java.io.InputStream; 27 | import java.net.URI; 28 | import java.nio.file.FileSystem; 29 | import java.nio.file.FileSystems; 30 | import java.nio.file.Files; 31 | import java.util.Objects; 32 | import java.util.jar.Attributes; 33 | import java.util.jar.Manifest; 34 | 35 | public final class Build { 36 | private static String buildVersion; 37 | private static String buildTitle; 38 | 39 | private Build() { 40 | } 41 | 42 | public static String version() { 43 | if (StringUtils.isNotBlank(buildVersion)) { 44 | return buildVersion; 45 | } 46 | String implementationVersion = Build.class.getPackage().getImplementationVersion(); 47 | if (implementationVersion == null) { 48 | Attributes attr = readManifest(); 49 | if (!attr.isEmpty()) { 50 | implementationVersion = attr.getValue("Implementation-Version"); 51 | } 52 | } 53 | buildVersion = Objects.requireNonNullElse(implementationVersion, "0.0"); 54 | return buildVersion; 55 | } 56 | 57 | public static String title() { 58 | if (StringUtils.isNotBlank(buildTitle)) { 59 | return buildTitle; 60 | } 61 | String implementationTitle = Build.class.getPackage().getImplementationTitle(); 62 | if (implementationTitle == null) { 63 | Attributes attr = readManifest(); 64 | if (!attr.isEmpty()) { 65 | implementationTitle = attr.getValue("Implementation-Title"); 66 | } 67 | } 68 | buildTitle = Objects.requireNonNullElse(implementationTitle, "Development"); 69 | return buildTitle; 70 | } 71 | 72 | private static Attributes readManifest() { 73 | if (!Build.class.getModule().isNamed()) { 74 | return new Attributes(); 75 | } 76 | 77 | Manifest manifest; 78 | try { 79 | FileSystem fs = FileSystems.getFileSystem(URI.create("jrt:/")); 80 | InputStream stream = Files.newInputStream( 81 | fs.getPath("modules", Build.class.getModule().getName(), "META-INF/MANIFEST.MF")); 82 | manifest = new Manifest(stream); 83 | return manifest.getMainAttributes(); 84 | } catch (IOException ignored) { 85 | //ignored 86 | } 87 | return new Attributes(); 88 | } 89 | 90 | } 91 | -------------------------------------------------------------------------------- /src/main/java/dev/pinter/tqextract/README.md: -------------------------------------------------------------------------------- 1 | ## TEX Conversion 2 | 3 | The texconverter-cli can convert from TEX to DDS, TEX to PNG and DDS to TEX. 4 | You can specify a .TEX as input using the option `--input-file`, 5 | or pass the path of .ARC and the path of the TEX inside the .ARC using the `--input-arc`. 6 | When converting from TEX to DDS, the mipmaps order are reverted to normal order. 7 | Most game textures have mipmaps in reversed order (smaller first), the standard for DDS 8 | is bigger mipmap first. The game has textures with reversed mipmaps and textures that 9 | are not reversed, like `Creatures.arc/MONSTER/TIGERMAN/TIGERMAN01.TEX`. 10 | The current version doesn't invert the mipmaps order when converting DDS to TEX, 11 | the TEX will contain the mipmaps using the standard DDS order, 12 | like the `TIGERMAN01.TEX` uses. The game have 818 textures using the standard mipmaps order, 13 | of a total 25278 TEX files, so 24460 reversed. 14 | 15 | #### EXAMPLES 16 | 17 | Convert a TEX to PNG on Windows 18 | 19 | ~~~ 20 | ./texconverter-cli.exe -i x:/tmp/TIGERMAN01.TEX -o x:/tmp/tigerman.png 21 | ~~~ 22 | 23 | Convert a TEX to DDS on Linux 24 | 25 | ~~~ 26 | ./texconverter-cli.sh -i /tmp/TIGERMAN01.TEX -o /tmp/tigerman.dds 27 | ~~~ 28 | 29 | The example below converts all textures found in the directory specified, and a new directory "x:/tmp/output-texconvert/textures" will be 30 | created containing resulting textures. If no conversion type is specified with the command line options, 31 | ***all .TEX will be converted to .DDS, and all .DDS will be converted to .TEX.*** 32 | 33 | **If you drag-and-drop a directory to texconverter-cli.exe, the process will start in a console window, the log can be found in the default 34 | temporary directory, (%TEMP% on Windows, /tmp on Linux). The same can be done with a single file.** 35 | 36 | ~~~ 37 | ./texconverter-cli.exe -d x:/tmp/textures 38 | ~~~ 39 | 40 | ## Extract 41 | 42 | The tqextract-cli is a tool to extract all .ARC and .ARZ from the game. 43 | 44 | The command have some GLOBAL options, these options will be used by subcommands: all, arc and arz: 45 | 46 | ~~~ 47 | Usage: tqextract-cli [-hV] -o=directory [-l=file] [-t=] [COMMAND] 48 | -h, --help Show this help message and exit. 49 | -l, --logfile=file Logfile path 50 | -o, --output-dir=directory 51 | Output directory 52 | -t, --max-threads= 53 | Max threads, limits the parallel work when extracting 54 | ARC and ARZ. Higher the number, higher will be the 55 | memory usage. 56 | -V, --version Print version information and exit. 57 | ~~~ 58 | 59 | Calling the command with -h alone, or with -h after a subcommand will show a help for the specified subcommand. 60 | 61 | ### ALL 62 | 63 | The 'all' subcommand will extract all .ARC and .ARZ found in the game directory. 64 | It is possible to specify if the textures will be all converted to DDS, 65 | or if the MapDecompiler will be disabled. By default, all textures are extracted as .TEX, and the 66 | world map is decompiled, you will have the following path ready to be used with TQ Editor: 67 | 68 | ~~~ 69 | Resources/Levels.arc/WORLD/source.WORLD01.MAP/Levels/World/world01.wrl 70 | ~~~ 71 | 72 | Help of subcommand 'all': 73 | 74 | ~~~ 75 | ./tqextract-cli.exe --output-dir x:/tmp all -h 76 | ~~~ 77 | 78 | ### ARC 79 | 80 | The 'arc' subcommand can do the same operations as 'all' subcommand, or list the content of a .ARC. 81 | 82 | Help of the subcommand 'arc': 83 | 84 | ~~~ 85 | ./tqextract-cli.exe --output-dir x:/tmp arc -h 86 | ~~~ 87 | 88 | ### EXAMPLES 89 | 90 | Extract all game files to `x:/tmp/tq` on Windows, converting all TEX to DDS and decompiling the world map: 91 | 92 | ~~~ 93 | ./tqextract-cli.exe --output-dir=x:/tmp/dd -l x:/tmp/tqextract.log all --tex-todds 94 | ~~~ 95 | 96 | Same on Linux: 97 | 98 | ~~~ 99 | ./tqextract-cli.sh --output-dir=/tmp/dd -l /tmp/tqextract.log all --tex-todds 100 | ~~~ 101 | 102 | Extract all Text files to `x:/tmp/tqtext` on Windows: 103 | 104 | ~~~ 105 | ./tqextract-cli.exe --output-dir x:/tmp/tqtext --logfile x:/tmp/tqextract.log arc -d "d:/games/Titan Quest Anniversary Edition/Text" 106 | ~~~ 107 | 108 | Extract and decompile the world map: 109 | 110 | ~~~ 111 | ./tqextract-cli.exe --output-dir x:/tmp/tqmap --logfile x:/tmp/tqextract.log arc -f "d:/games/Titan Quest Anniversary Edition/Resources/Levels.arc" 112 | ~~~ 113 | 114 | 115 | -------------------------------------------------------------------------------- /src/main/java/dev/pinter/tqextract/decompiler/MapBlock.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2025 Emerson Pinter - All Rights Reserved 3 | */ 4 | 5 | /* This file is part of TQ Extract. 6 | 7 | TQ Extract is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | TQ Extract is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with TQ Extract. If not, see . 19 | */ 20 | 21 | package dev.pinter.tqextract.decompiler; 22 | 23 | import java.util.Arrays; 24 | 25 | record MapBlock(int id, int size, int start) { 26 | public enum Type { 27 | UNKNOWN(0xFF), 28 | LEVELS(0x01), 29 | LEVELDATA(0x02), 30 | IMAGES(0x1A), 31 | QUESTS(0x1B), 32 | INSTANCEDATA(0x11), 33 | SECTOR(0x18), 34 | MINIMAP(0x19); 35 | 36 | 37 | private final int value; 38 | 39 | Type(int value) { 40 | this.value = value; 41 | } 42 | 43 | public int value() { 44 | return value; 45 | } 46 | 47 | public static Type of(int value) { 48 | return Arrays.stream(values()).filter(f -> f.value == value).findFirst().orElse(UNKNOWN); 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/dev/pinter/tqextract/decompiler/MapLevel.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2025 Emerson Pinter - All Rights Reserved 3 | */ 4 | 5 | /* This file is part of TQ Extract. 6 | 7 | TQ Extract is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | TQ Extract is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with TQ Extract. If not, see . 19 | */ 20 | 21 | package dev.pinter.tqextract.decompiler; 22 | 23 | record MapLevel(int id, String fileName, String recordName, byte[] data, int offset, int length) { 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/dev/pinter/tqextract/decompiler/MapTga.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2025 Emerson Pinter - All Rights Reserved 3 | */ 4 | 5 | /* This file is part of TQ Extract. 6 | 7 | TQ Extract is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | TQ Extract is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with TQ Extract. If not, see . 19 | */ 20 | 21 | package dev.pinter.tqextract.decompiler; 22 | 23 | record MapTga(int id, int width, int height, int size, int srcOffset, int srcLength, int type, int bpp, short newWidth, short newHeight) { 24 | } -------------------------------------------------------------------------------- /src/main/java/module-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2020 Emerson Pinter - All Rights Reserved 3 | */ 4 | 5 | /* This file is part of TQ Respec. 6 | 7 | TQ Respec is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | TQ Respec is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with TQ Respec. If not, see . 19 | */ 20 | 21 | module br.com.pinter.tqrespec { 22 | requires javafx.base; 23 | requires javafx.fxml; 24 | requires javafx.graphics; 25 | requires javafx.controls; 26 | requires java.net.http; 27 | requires java.prefs; 28 | requires java.base; 29 | requires jdk.zipfs; 30 | requires java.desktop; 31 | requires java.logging; 32 | provides System.LoggerFinder with br.com.pinter.tqrespec.logging.JULLoggerFinder; 33 | requires org.apache.commons.lang3; 34 | requires aopalliance; 35 | requires org.checkerframework.checker.qual; 36 | requires com.google.errorprone.annotations; 37 | requires failureaccess; 38 | requires j2objc.annotations; 39 | requires jakarta.inject; 40 | requires jsr305; 41 | requires listenablefuture; 42 | requires org.apache.commons.text; 43 | requires com.google.guice; 44 | requires com.google.common; 45 | requires com.sun.jna.platform; 46 | requires com.fasterxml.jackson.core; 47 | requires com.fasterxml.jackson.databind; 48 | requires com.fasterxml.jackson.annotation; 49 | requires br.com.pinter.tqdatabase; 50 | requires info.picocli; 51 | exports br.com.pinter.tqrespec; 52 | exports br.com.pinter.tqrespec.core; 53 | exports br.com.pinter.tqrespec.gui; 54 | exports br.com.pinter.tqrespec.tqdata; 55 | exports br.com.pinter.tqrespec.save; 56 | exports br.com.pinter.tqrespec.util; 57 | opens br.com.pinter.tqrespec to com.google.guice, javafx.fxml; 58 | opens br.com.pinter.tqrespec.core to com.google.guice, javafx.fxml; 59 | opens br.com.pinter.tqrespec.gui to com.google.guice, javafx.fxml; 60 | opens br.com.pinter.tqrespec.save to com.google.guice, javafx.fxml; 61 | opens br.com.pinter.tqrespec.save.player to com.google.guice, javafx.fxml; 62 | opens br.com.pinter.tqrespec.save.stash to com.google.guice, javafx.fxml; 63 | opens br.com.pinter.tqrespec.tqdata to com.google.guice, javafx.fxml; 64 | opens br.com.pinter.tqrespec.util to com.google.guice, javafx.fxml; 65 | exports br.com.pinter.tqrespec.save.exporter; 66 | opens br.com.pinter.tqrespec.save.exporter to com.google.guice, javafx.fxml; 67 | opens dev.pinter.tqextract to com.google.guice, info.picocli; 68 | opens dev.pinter.tqextract.decompiler to com.google.guice; 69 | 70 | } -------------------------------------------------------------------------------- /src/main/resources/fxml/about.css: -------------------------------------------------------------------------------- 1 | .root { 2 | -fx-base: #443823; 3 | -fx-accent: #f6d35b; 4 | -fx-focus-color: #f6d35b; 5 | -fx-pressed-base: #f6d35b; 6 | -fx-text-box-border: #ffd993; 7 | -fx-control-inner-background: #443823; 8 | -fx-shadow-highlight-color: #ffd993; 9 | -fx-body-color: #443823; 10 | -fx-text-fill: white; 11 | -fx-mark-highlight-color: #ffd993; 12 | -fx-mark-color: #ffd993; 13 | /* will be overriden to 1em on runtime */ 14 | -fx-font-size: 1em; 15 | } 16 | 17 | .bg-container { 18 | -fx-background-image: url('about_bg.png'); 19 | -fx-background-size: contain; 20 | -fx-background-repeat: no-repeat; 21 | -fx-background-color: transparent; 22 | } 23 | .tq-title-label { 24 | -fx-text-fill: #000000; 25 | // px, do not scale 26 | -fx-font-size: 12px; 27 | -fx-background-image: url('topbar_center.png'); 28 | -fx-background-repeat: no-repeat; 29 | 30 | } 31 | .tq-bigtitle { 32 | -fx-font-size: 30px; 33 | -fx-font-weight: bold; 34 | -fx-font-style: italic; 35 | -fx-text-fill: #ffd993; 36 | -fx-effect: dropshadow( one-pass-box , #443823 , 5, 5.0 , 5 , 5 ); 37 | 38 | } 39 | 40 | .tq-splitpane, 41 | .tq-splitpane-left { 42 | -fx-background-color: transparent; 43 | } 44 | 45 | .tq-text-area:focused, 46 | .tq-textarea > .scroll-pane, 47 | .tq-textarea .content, 48 | .tq-textarea { 49 | -fx-background-color: transparent; 50 | -fx-border-color: transparent; 51 | -fx-prompt-text-fill: transparent; 52 | -fx-base: transparent; 53 | -fx-text-fill: #ffd993; 54 | } 55 | 56 | .tq-aboutversion { 57 | -fx-text-fill: #ffffff; 58 | -fx-font-size: 26px; 59 | } 60 | .tq-winclose { 61 | -fx-background-image: url('close.png'); 62 | -fx-background-size: stretch; 63 | -fx-background-color:transparent; 64 | } 65 | 66 | .tq-winclose:pressed { 67 | -fx-background-image: url('close_pressed.png'); 68 | -fx-background-size: stretch; 69 | -fx-background-color:transparent; 70 | } 71 | -------------------------------------------------------------------------------- /src/main/resources/fxml/about.fxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 25 | 26 | 27 | 28 | 33 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 47 | 48 | -------------------------------------------------------------------------------- /src/main/resources/fxml/about_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epinter/tqrespec/d1b2afb03b6816af1a902e0065db15257c1e6368/src/main/resources/fxml/about_bg.png -------------------------------------------------------------------------------- /src/main/resources/fxml/about_character.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epinter/tqrespec/d1b2afb03b6816af1a902e0065db15257c1e6368/src/main/resources/fxml/about_character.png -------------------------------------------------------------------------------- /src/main/resources/fxml/bg-button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epinter/tqrespec/d1b2afb03b6816af1a902e0065db15257c1e6368/src/main/resources/fxml/bg-button.png -------------------------------------------------------------------------------- /src/main/resources/fxml/bg-button_pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epinter/tqrespec/d1b2afb03b6816af1a902e0065db15257c1e6368/src/main/resources/fxml/bg-button_pressed.png -------------------------------------------------------------------------------- /src/main/resources/fxml/border.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epinter/tqrespec/d1b2afb03b6816af1a902e0065db15257c1e6368/src/main/resources/fxml/border.png -------------------------------------------------------------------------------- /src/main/resources/fxml/close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epinter/tqrespec/d1b2afb03b6816af1a902e0065db15257c1e6368/src/main/resources/fxml/close.png -------------------------------------------------------------------------------- /src/main/resources/fxml/close_pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epinter/tqrespec/d1b2afb03b6816af1a902e0065db15257c1e6368/src/main/resources/fxml/close_pressed.png -------------------------------------------------------------------------------- /src/main/resources/fxml/decoleft.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epinter/tqrespec/d1b2afb03b6816af1a902e0065db15257c1e6368/src/main/resources/fxml/decoleft.png -------------------------------------------------------------------------------- /src/main/resources/fxml/decoright.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epinter/tqrespec/d1b2afb03b6816af1a902e0065db15257c1e6368/src/main/resources/fxml/decoright.png -------------------------------------------------------------------------------- /src/main/resources/fxml/fa5-free-solid-900.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epinter/tqrespec/d1b2afb03b6816af1a902e0065db15257c1e6368/src/main/resources/fxml/fa5-free-solid-900.ttf -------------------------------------------------------------------------------- /src/main/resources/fxml/font/Marcellus-Regular-license.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012, Brian J. Bonislawsky DBA Astigmatic (AOETI) (astigma@astigmatic.com), with Reserved Font Names "Marcellus" 2 | 3 | This Font Software is licensed under the SIL Open Font License, Version 1.1. 4 | This license is copied below, and is also available with a FAQ at: 5 | http://scripts.sil.org/OFL 6 | 7 | 8 | ----------------------------------------------------------- 9 | SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 10 | ----------------------------------------------------------- 11 | 12 | PREAMBLE 13 | The goals of the Open Font License (OFL) are to stimulate worldwide 14 | development of collaborative font projects, to support the font creation 15 | efforts of academic and linguistic communities, and to provide a free and 16 | open framework in which fonts may be shared and improved in partnership 17 | with others. 18 | 19 | The OFL allows the licensed fonts to be used, studied, modified and 20 | redistributed freely as long as they are not sold by themselves. The 21 | fonts, including any derivative works, can be bundled, embedded, 22 | redistributed and/or sold with any software provided that any reserved 23 | names are not used by derivative works. The fonts and derivatives, 24 | however, cannot be released under any other type of license. The 25 | requirement for fonts to remain under this license does not apply 26 | to any document created using the fonts or their derivatives. 27 | 28 | DEFINITIONS 29 | "Font Software" refers to the set of files released by the Copyright 30 | Holder(s) under this license and clearly marked as such. This may 31 | include source files, build scripts and documentation. 32 | 33 | "Reserved Font Name" refers to any names specified as such after the 34 | copyright statement(s). 35 | 36 | "Original Version" refers to the collection of Font Software components as 37 | distributed by the Copyright Holder(s). 38 | 39 | "Modified Version" refers to any derivative made by adding to, deleting, 40 | or substituting -- in part or in whole -- any of the components of the 41 | Original Version, by changing formats or by porting the Font Software to a 42 | new environment. 43 | 44 | "Author" refers to any designer, engineer, programmer, technical 45 | writer or other person who contributed to the Font Software. 46 | 47 | PERMISSION & CONDITIONS 48 | Permission is hereby granted, free of charge, to any person obtaining 49 | a copy of the Font Software, to use, study, copy, merge, embed, modify, 50 | redistribute, and sell modified and unmodified copies of the Font 51 | Software, subject to the following conditions: 52 | 53 | 1) Neither the Font Software nor any of its individual components, 54 | in Original or Modified Versions, may be sold by itself. 55 | 56 | 2) Original or Modified Versions of the Font Software may be bundled, 57 | redistributed and/or sold with any software, provided that each copy 58 | contains the above copyright notice and this license. These can be 59 | included either as stand-alone text files, human-readable headers or 60 | in the appropriate machine-readable metadata fields within text or 61 | binary files as long as those fields can be easily viewed by the user. 62 | 63 | 3) No Modified Version of the Font Software may use the Reserved Font 64 | Name(s) unless explicit written permission is granted by the corresponding 65 | Copyright Holder. This restriction only applies to the primary font name as 66 | presented to the users. 67 | 68 | 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font 69 | Software shall not be used to promote, endorse or advertise any 70 | Modified Version, except to acknowledge the contribution(s) of the 71 | Copyright Holder(s) and the Author(s) or with their explicit written 72 | permission. 73 | 74 | 5) The Font Software, modified or unmodified, in part or in whole, 75 | must be distributed entirely under this license, and must not be 76 | distributed under any other license. The requirement for fonts to 77 | remain under this license does not apply to any document created 78 | using the Font Software. 79 | 80 | TERMINATION 81 | This license becomes null and void if any of the above conditions are 82 | not met. 83 | 84 | DISCLAIMER 85 | THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 86 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF 87 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT 88 | OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE 89 | COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 90 | INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL 91 | DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 92 | FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM 93 | OTHER DEALINGS IN THE FONT SOFTWARE. 94 | -------------------------------------------------------------------------------- /src/main/resources/fxml/font/Marcellus-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epinter/tqrespec/d1b2afb03b6816af1a902e0065db15257c1e6368/src/main/resources/fxml/font/Marcellus-Regular.ttf -------------------------------------------------------------------------------- /src/main/resources/fxml/font/Roboto-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epinter/tqrespec/d1b2afb03b6816af1a902e0065db15257c1e6368/src/main/resources/fxml/font/Roboto-Regular.ttf -------------------------------------------------------------------------------- /src/main/resources/fxml/font/font-albertus_mt.css: -------------------------------------------------------------------------------- 1 | .root { 2 | -fx-font-family: 'Albertus MT'; 3 | } -------------------------------------------------------------------------------- /src/main/resources/fxml/font/font-albertus_mt_light.css: -------------------------------------------------------------------------------- 1 | .root { 2 | -fx-font-family: 'Albertus MT Light'; 3 | } -------------------------------------------------------------------------------- /src/main/resources/fxml/font/font-default.css: -------------------------------------------------------------------------------- 1 | .root { 2 | -fx-font-family: 'Marcellus'; 3 | } -------------------------------------------------------------------------------- /src/main/resources/fxml/font/font-nonlatin.css: -------------------------------------------------------------------------------- 1 | .root { 2 | -fx-font-family: 'Roboto'; 3 | } -------------------------------------------------------------------------------- /src/main/resources/fxml/font/font-title-albertus_mt.css: -------------------------------------------------------------------------------- 1 | .tq-bigtitle { 2 | -fx-font-family: 'Albertus MT'; 3 | } -------------------------------------------------------------------------------- /src/main/resources/fxml/preloader.css: -------------------------------------------------------------------------------- 1 | .root { 2 | -fx-base: #443823; 3 | -fx-accent: #f6d35b; 4 | -fx-focus-color: #f6d35b; 5 | -fx-pressed-base: #f6d35b; 6 | -fx-text-box-border: #ffd993; 7 | -fx-control-inner-background: #443823; 8 | -fx-shadow-highlight-color: #ffd993; 9 | -fx-body-color: #443823; 10 | -fx-text-fill: white; 11 | -fx-mark-highlight-color: #ffd993; 12 | -fx-mark-color: #ffd993; 13 | /* will be overriden to 1em on runtime */ 14 | -fx-font-size: 1em; 15 | } 16 | 17 | .bg-container { 18 | -fx-background-color: #000000; 19 | -fx-padding: 0 0 0 0; 20 | -fx-border-image-source: url('border.png'); 21 | -fx-border-image-insets: 0; 22 | -fx-border-image-repeat: stretch; 23 | -fx-border-image-width: 3 3 3 3; 24 | -fx-border-image-slice: 3 3 3 3; 25 | -fx-background-image: url('window_bg.png'); 26 | -fx-background-size: cover; 27 | -fx-background-repeat: no-repeat; 28 | } 29 | 30 | .topContainer, 31 | .bottomContainer { 32 | -fx-min-height: 63px; 33 | -fx-pref-height: 63px; 34 | -fx-max-height: 63px; 35 | -fx-padding: 10px 10px 10px 10px; 36 | } 37 | 38 | .bar { 39 | -fx-min-height: 70px; 40 | -fx-pref-height: 70px; 41 | -fx-max-height: 70px; 42 | -fx-padding: 20px 0px 0px 0px; 43 | } 44 | 45 | .indicator { 46 | -fx-min-height: 35px; 47 | -fx-pref-height: 35px; 48 | -fx-max-height: 35px; 49 | -fx-min-width: 35px; 50 | -fx-pref-width: 35px; 51 | -fx-max-width: 35px; 52 | } 53 | 54 | .version { 55 | -fx-font-size: 1.3em; 56 | -fx-text-fill: #ffd993; 57 | -fx-padding: 0 0 0 0; 58 | -fx-effect: dropshadow( one-pass-box , black , 0, 0.0 , 0 , 2 ); 59 | } 60 | 61 | .tq-bigtitle { 62 | -fx-font-size: 5.0em; 63 | -fx-font-weight: bold; 64 | -fx-text-fill: #ffd993; 65 | -fx-effect: dropshadow( one-pass-box, black, 5, 5.0, 5, 5); 66 | -fx-padding: 20px 0px 0px 0px; 67 | } -------------------------------------------------------------------------------- /src/main/resources/fxml/preloader_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epinter/tqrespec/d1b2afb03b6816af1a902e0065db15257c1e6368/src/main/resources/fxml/preloader_bg.png -------------------------------------------------------------------------------- /src/main/resources/fxml/sv.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epinter/tqrespec/d1b2afb03b6816af1a902e0065db15257c1e6368/src/main/resources/fxml/sv.png -------------------------------------------------------------------------------- /src/main/resources/fxml/topbar_center.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epinter/tqrespec/d1b2afb03b6816af1a902e0065db15257c1e6368/src/main/resources/fxml/topbar_center.png -------------------------------------------------------------------------------- /src/main/resources/fxml/topbar_region.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epinter/tqrespec/d1b2afb03b6816af1a902e0065db15257c1e6368/src/main/resources/fxml/topbar_region.png -------------------------------------------------------------------------------- /src/main/resources/fxml/topdeco.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epinter/tqrespec/d1b2afb03b6816af1a902e0065db15257c1e6368/src/main/resources/fxml/topdeco.png -------------------------------------------------------------------------------- /src/main/resources/fxml/topdecoration.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epinter/tqrespec/d1b2afb03b6816af1a902e0065db15257c1e6368/src/main/resources/fxml/topdecoration.png -------------------------------------------------------------------------------- /src/main/resources/fxml/window.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epinter/tqrespec/d1b2afb03b6816af1a902e0065db15257c1e6368/src/main/resources/fxml/window.png -------------------------------------------------------------------------------- /src/main/resources/fxml/window_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epinter/tqrespec/d1b2afb03b6816af1a902e0065db15257c1e6368/src/main/resources/fxml/window_bg.png -------------------------------------------------------------------------------- /src/main/resources/icon/icon128.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epinter/tqrespec/d1b2afb03b6816af1a902e0065db15257c1e6368/src/main/resources/icon/icon128.ico -------------------------------------------------------------------------------- /src/main/resources/icon/icon128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epinter/tqrespec/d1b2afb03b6816af1a902e0065db15257c1e6368/src/main/resources/icon/icon128.png -------------------------------------------------------------------------------- /src/main/resources/icon/icon16.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epinter/tqrespec/d1b2afb03b6816af1a902e0065db15257c1e6368/src/main/resources/icon/icon16.ico -------------------------------------------------------------------------------- /src/main/resources/icon/icon16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epinter/tqrespec/d1b2afb03b6816af1a902e0065db15257c1e6368/src/main/resources/icon/icon16.png -------------------------------------------------------------------------------- /src/main/resources/icon/icon256.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epinter/tqrespec/d1b2afb03b6816af1a902e0065db15257c1e6368/src/main/resources/icon/icon256.ico -------------------------------------------------------------------------------- /src/main/resources/icon/icon256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epinter/tqrespec/d1b2afb03b6816af1a902e0065db15257c1e6368/src/main/resources/icon/icon256.png -------------------------------------------------------------------------------- /src/main/resources/icon/icon32.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epinter/tqrespec/d1b2afb03b6816af1a902e0065db15257c1e6368/src/main/resources/icon/icon32.ico -------------------------------------------------------------------------------- /src/main/resources/icon/icon32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epinter/tqrespec/d1b2afb03b6816af1a902e0065db15257c1e6368/src/main/resources/icon/icon32.png -------------------------------------------------------------------------------- /src/main/resources/icon/icon64.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epinter/tqrespec/d1b2afb03b6816af1a902e0065db15257c1e6368/src/main/resources/icon/icon64.ico -------------------------------------------------------------------------------- /src/main/resources/icon/icon64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epinter/tqrespec/d1b2afb03b6816af1a902e0065db15257c1e6368/src/main/resources/icon/icon64.png -------------------------------------------------------------------------------- /src/test/java/br/com/pinter/tqrespec/VersionTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2021 Emerson Pinter - All Rights Reserved 3 | */ 4 | 5 | /* This file is part of TQ Respec. 6 | 7 | TQ Respec is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | TQ Respec is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with TQ Respec. If not, see . 19 | */ 20 | 21 | package br.com.pinter.tqrespec; 22 | 23 | import br.com.pinter.tqrespec.util.Version; 24 | import org.junit.jupiter.api.BeforeEach; 25 | import org.junit.jupiter.api.Test; 26 | 27 | import static org.junit.jupiter.api.Assertions.assertEquals; 28 | 29 | class VersionTest { 30 | private Version version; 31 | 32 | @BeforeEach 33 | void setUp() { 34 | version = new Version("1.1.0"); 35 | } 36 | 37 | @Test 38 | void Given_smallerVersionNumber_Then_returnNegative() { 39 | assertEquals(-1, new Version("000001.00000.22222").compareTo(version)); 40 | assertEquals(-1, new Version("000000.5.999").compareTo(version)); 41 | assertEquals(-1, new Version("1.0.0.0.0.0.1").compareTo(version)); 42 | assertEquals(-1, new Version("1.0.0").compareTo(version)); 43 | assertEquals(-1, new Version("1.0").compareTo(version)); 44 | assertEquals(-1, new Version("0.1").compareTo(version)); 45 | } 46 | 47 | @Test 48 | void Given_greaterVersionNumber_Then_returnPositive() { 49 | assertEquals(1, new Version("1.1.0.0.0.1").compareTo(version)); 50 | assertEquals(1, new Version("000001.0001.00001").compareTo(version)); 51 | assertEquals(1, new Version("000002.00005.999").compareTo(version)); 52 | assertEquals(1, new Version("2000.1.1.0").compareTo(version)); 53 | assertEquals(1, new Version("2.0").compareTo(version)); 54 | assertEquals(1, new Version("2.0.0").compareTo(version)); 55 | assertEquals(1, new Version("1.2.0").compareTo(version)); 56 | } 57 | 58 | @Test 59 | void Given_equalVersionNumber_Then_returnZero() { 60 | assertEquals(0, new Version("1.1.0.0.0.0.0").compareTo(version)); 61 | assertEquals(0, new Version("00001.0000001.00000").compareTo(version)); 62 | assertEquals(0, new Version("1.1").compareTo(version)); 63 | } 64 | 65 | } -------------------------------------------------------------------------------- /src/test/java/br/com/pinter/tqrespec/save/player/GuiceInjector.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2025 Emerson Pinter - All Rights Reserved 3 | */ 4 | 5 | package br.com.pinter.tqrespec.save.player; 6 | 7 | import br.com.pinter.tqrespec.core.GuiceModule; 8 | import br.com.pinter.tqrespec.logging.Log; 9 | import com.google.inject.Guice; 10 | import com.google.inject.Injector; 11 | import com.google.inject.Module; 12 | 13 | import java.io.FileNotFoundException; 14 | import java.util.ArrayList; 15 | import java.util.List; 16 | 17 | import static java.lang.System.Logger.Level.INFO; 18 | 19 | public class GuiceInjector { 20 | private static final System.Logger logger = Log.getLogger(GuiceInjector.class); 21 | 22 | public static Injector init(Object object) throws FileNotFoundException { 23 | logger.log(INFO, "### Initializing Google Guice for ''{0}''", object.getClass().getSimpleName()); 24 | 25 | List modules = new ArrayList<>() {{ 26 | add(new GuiceModule()); 27 | }}; 28 | 29 | Injector injector = Guice.createInjector(modules); 30 | 31 | injector.injectMembers(object); 32 | 33 | logger.log(INFO, "################## Guice injector initialized for ''{0}'' ##################", object.getClass().getSimpleName()); 34 | return injector; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/test/resources/_mobile/Player.chr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epinter/tqrespec/d1b2afb03b6816af1a902e0065db15257c1e6368/src/test/resources/_mobile/Player.chr -------------------------------------------------------------------------------- /src/test/resources/_savegame/Player.chr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epinter/tqrespec/d1b2afb03b6816af1a902e0065db15257c1e6368/src/test/resources/_savegame/Player.chr -------------------------------------------------------------------------------- /src/test/resources/_savegame/winsys.dxb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epinter/tqrespec/d1b2afb03b6816af1a902e0065db15257c1e6368/src/test/resources/_savegame/winsys.dxb -------------------------------------------------------------------------------- /src/test/resources/_savegame/winsys.dxg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epinter/tqrespec/d1b2afb03b6816af1a902e0065db15257c1e6368/src/test/resources/_savegame/winsys.dxg -------------------------------------------------------------------------------- /src/test/resources/_savegame2/Player.chr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epinter/tqrespec/d1b2afb03b6816af1a902e0065db15257c1e6368/src/test/resources/_savegame2/Player.chr -------------------------------------------------------------------------------- /src/test/resources/_savegame2/winsys.dxb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epinter/tqrespec/d1b2afb03b6816af1a902e0065db15257c1e6368/src/test/resources/_savegame2/winsys.dxb -------------------------------------------------------------------------------- /src/test/resources/_savegame2/winsys.dxg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epinter/tqrespec/d1b2afb03b6816af1a902e0065db15257c1e6368/src/test/resources/_savegame2/winsys.dxg -------------------------------------------------------------------------------- /src/test/resources/_savegame3/Player.chr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epinter/tqrespec/d1b2afb03b6816af1a902e0065db15257c1e6368/src/test/resources/_savegame3/Player.chr --------------------------------------------------------------------------------