├── .github └── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── .gitignore ├── LICENSE.txt ├── README-developing.md ├── README.md ├── build.xml ├── lib ├── commonmark-0.21.0.jar ├── commons-lang3-3.13.0.jar ├── commons-text-1.10.0.jar ├── semver4j-3.1.0.jar └── sqlite-jdbc-3.42.0.0.jar ├── licenceHeader.txt ├── manifest.mf ├── nbproject ├── build-impl.xml ├── genfiles.properties ├── project.properties └── project.xml ├── openblcmm-latest.txt ├── release-processing ├── finish-release.py ├── launch_openblcmm.bat ├── launch_openblcmm.command └── launch_openblcmm.sh ├── resources └── icon │ ├── README.md │ ├── arch_reference.jpg │ ├── gen_icon.py │ ├── openblcmm_icon.svg │ └── splash.html ├── src ├── CHANGELOG.md ├── LICENSE.txt ├── META-INF │ └── native-image │ │ └── blcmm │ │ └── blcmm │ │ ├── README.md │ │ ├── jni-config.json │ │ ├── native-image.properties │ │ ├── predefined-classes-config.json │ │ ├── proxy-config.json │ │ ├── reflect-config.json │ │ ├── resource-config.json │ │ └── serialization-config.json ├── SteamVDF │ └── VDF │ │ ├── VDF.java │ │ ├── VDFBaseElement.java │ │ ├── VDFElement.java │ │ └── VDFKey.java ├── blcmm │ ├── Meta.java │ ├── Startup.java │ ├── data │ │ ├── BehaviorProviderDefinition.java │ │ └── lib │ │ │ ├── DataManager.java │ │ │ ├── DataManagerManager.java │ │ │ ├── DataStatusNotifier.java │ │ │ ├── UEClass.java │ │ │ └── UEObject.java │ ├── gui │ │ ├── FontInfo.java │ │ ├── GUI_IO_Handler.java │ │ ├── MainGUI.form │ │ ├── MainGUI.java │ │ ├── ObjectExplorer.form │ │ ├── ObjectExplorer.java │ │ ├── PopupType.java │ │ ├── components │ │ │ ├── AdHocDialog.java │ │ │ ├── BLCMM_FileChooser.java │ │ │ ├── BoldJTabbedPane.java │ │ │ ├── ButtonTabComponent.java │ │ │ ├── DefaultTextTextField.java │ │ │ ├── EnhancedFormattedTextField.java │ │ │ ├── FontInfoJButton.java │ │ │ ├── FontInfoJCheckBox.java │ │ │ ├── FontInfoJComboBox.java │ │ │ ├── FontInfoJLabel.java │ │ │ ├── FontInfoJMenuItem.java │ │ │ ├── FontInfoJToggleButton.java │ │ │ ├── ForceClosingJFrame.java │ │ │ ├── GUIDataStatusNotifier.java │ │ │ ├── GameSelectionPanel.java │ │ │ ├── InfoLabel.java │ │ │ ├── ProgressDialog.java │ │ │ ├── ScrollablePanel.java │ │ │ ├── SimpleGameSelectionComboBox.java │ │ │ ├── TimedLabel.java │ │ │ └── VariableTabsTabbedPane.java │ │ ├── panels │ │ │ ├── AboutPanel.java │ │ │ ├── BookmarkTable.java │ │ │ ├── EditPanel.form │ │ │ ├── EditPanel.java │ │ │ ├── GameTweaksPanel.java │ │ │ ├── HexEditPanel.form │ │ │ ├── HexEditPanel.java │ │ │ ├── IniTweaksPanel.form │ │ │ ├── IniTweaksPanel.java │ │ │ ├── IntegerConverter.form │ │ │ ├── IntegerConverter.java │ │ │ ├── MasterSettingsPanel.form │ │ │ ├── MasterSettingsPanel.java │ │ │ ├── ObjectExplorerPanel.form │ │ │ ├── ObjectExplorerPanel.java │ │ │ ├── SetupGameFilesPanel.java │ │ │ ├── TextSearchDialog.form │ │ │ ├── TextSearchDialog.java │ │ │ └── ToolSettingsPanel.java │ │ ├── text │ │ │ ├── AutoCompleteAttacher.java │ │ │ ├── AutoCompleteList.java │ │ │ ├── CustomComponentKeySelectionAction.java │ │ │ ├── CustomComponentMouseSelectionAction.java │ │ │ ├── CustomSelectionDefinition.java │ │ │ ├── HighlightedTextArea.java │ │ │ ├── UndoManager.java │ │ │ └── myStylizedDocument.java │ │ ├── theme │ │ │ ├── Theme.java │ │ │ └── ThemeManager.java │ │ └── tree │ │ │ ├── CheckBoxTree.java │ │ │ ├── CheckBoxTreeCellRenderer.java │ │ │ ├── ColorGiver.java │ │ │ ├── EasterEggs.java │ │ │ ├── OverwriteChecker.java │ │ │ ├── TreeTransferHandler.java │ │ │ ├── TristateCheckBox.java │ │ │ └── rightmouse │ │ │ ├── AbstractCopyAction.java │ │ │ ├── AddCategoryAction.java │ │ │ ├── CheckMarkRightMouseButtonAction.java │ │ │ ├── CollapseCategoryCompletelyAction.java │ │ │ ├── CopyAction.java │ │ │ ├── CopyModListAction.java │ │ │ ├── CutAction.java │ │ │ ├── DeleteAction.java │ │ │ ├── EditAction.java │ │ │ ├── EnableAction.java │ │ │ ├── ExpandCategoryCompletelyAction.java │ │ │ ├── ExportCategoryAsModAction.java │ │ │ ├── FlattenCategoryAction.java │ │ │ ├── GoToCompleteOverwrittenAction.java │ │ │ ├── GoToOverwriterAction.java │ │ │ ├── GoToPartialOverwrittenAction.java │ │ │ ├── ImportModAction.java │ │ │ ├── InsertAction.java │ │ │ ├── IntroduceCategoryAction.java │ │ │ ├── LockAction.java │ │ │ ├── MutuallyExclusiveAction.java │ │ │ ├── PasteAction.java │ │ │ ├── RemoveCategoryAction.java │ │ │ ├── RenameCategoryAction.java │ │ │ ├── RightMouseButtonAction.java │ │ │ └── SortCategoryAction.java │ ├── model │ │ ├── Category.java │ │ ├── Comment.java │ │ ├── CompletePatch.java │ │ ├── EnableableModelElement.java │ │ ├── HotfixCommand.java │ │ ├── HotfixConverter.java │ │ ├── HotfixType.java │ │ ├── HotfixWrapper.java │ │ ├── ModelElement.java │ │ ├── ModelElementContainer.java │ │ ├── PatchIO.java │ │ ├── PatchType.java │ │ ├── Profile.java │ │ ├── SetCMPCommand.java │ │ ├── SetCommand.java │ │ ├── TransientModelData.java │ │ ├── attrparser │ │ │ ├── LevelDepArray.java │ │ │ ├── LevelDepData.java │ │ │ ├── LevelDepParser.java │ │ │ ├── LevelDepString.java │ │ │ └── LevelDepStruct.java │ │ └── properties │ │ │ ├── GlobalListOfProperties.java │ │ │ └── PropertyChecker.java │ └── utilities │ │ ├── AutoBackupper.java │ │ ├── BLCMMImportOptions.java │ │ ├── CancelConfirmer.java │ │ ├── CodeFormatter.java │ │ ├── DateVersion.java │ │ ├── GameDetection.java │ │ ├── GlobalLogger.java │ │ ├── IconManager.java │ │ ├── ImportAnomalyLog.java │ │ ├── InputValidator.java │ │ ├── OSInfo.java │ │ ├── Options.java │ │ ├── OptionsBase.java │ │ ├── StringUtilities.java │ │ ├── Utilities.java │ │ ├── hex │ │ ├── AddressHexEdit.java │ │ ├── HexDictionary.java │ │ ├── HexEdit.java │ │ ├── HexEditor.java │ │ ├── HexInspectResult.java │ │ ├── HexUtilities.java │ │ ├── PatternHexEdit.java │ │ └── WildCardHexEdit.java │ │ ├── log │ │ ├── LogConsole.java │ │ ├── LogFile.java │ │ └── LogTarget.java │ │ └── options │ │ ├── BooleanOption.java │ │ ├── FilenameOption.java │ │ ├── IntOption.java │ │ ├── InverseBooleanOption.java │ │ ├── LongOption.java │ │ ├── MouseButtonOption.java │ │ ├── Option.java │ │ ├── OptionDataConverter.java │ │ ├── SectionHeaderOption.java │ │ ├── SelectionOption.java │ │ ├── SelectionOptionData.java │ │ └── StringListOption.java └── resources │ ├── AODK │ ├── GBX_hotfixes.blcm │ ├── Icon.png │ └── vanillaLevelLists.blcm │ ├── BL2 │ ├── GBX_hotfixes.blcm │ ├── Icon.png │ └── vanillaLevelLists.blcm │ ├── Icon.png │ ├── Qmark.png │ ├── README.md │ ├── TPS │ ├── GBX_hotfixes.blcm │ ├── Icon.png │ └── vanillaLevelLists.blcm │ ├── donate.png │ ├── exec.png │ ├── folder.png │ ├── padlock.png │ └── speaker.png ├── steamos-processing ├── README.md ├── native-agent.sh ├── native-compile.sh └── prepare-deck.sh ├── store └── .gitkeep ├── test └── blcmm │ ├── gui │ └── tree │ │ └── OverwriteCheckerNGTest.java │ └── utilities │ ├── CodeFormatterNGTest.java │ └── StringUtilitiesNGTest.java └── windows-processing ├── OpenBLCMM.exe.manifest ├── README.md ├── installer-pre-text.txt ├── native-agent-merge.bat ├── native-agent-new.bat ├── native-compile.bat ├── openblcmm.ico └── openblcmm.iss /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Doesn't start? Crashes? Generally weird behavior? 4 | title: '' 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | **System Info** 11 | **Operating System:** 12 | Also please paste in the info from `Help > About`, assuming you can launch the app. 13 | 14 | **Describe the bug** 15 | A clear and concise description of what the bug is. 16 | 17 | **To Reproduce** 18 | Steps to reproduce the behavior: 19 | 20 | **Screenshots** 21 | If applicable, add screenshots to help explain your problem. 22 | 23 | **Mod Files** 24 | If you're having a problem with a specific mod file or patch file, please upload it here. 25 | 26 | **Additional context** 27 | Add any other context about the problem here. 28 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for OpenBLCMM 4 | title: '' 5 | labels: enhancement 6 | assignees: '' 7 | 8 | --- 9 | 10 | 11 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Netbeans files 2 | /nbproject/private 3 | 4 | # Build files 5 | /build/ 6 | /dist/ 7 | /store/OpenBLCMM* 8 | /store/Output 9 | /store/compiled 10 | /store/steamos 11 | /store/*.dll 12 | /store/archive 13 | 14 | # OpenBLCMM user-data files 15 | /blcmm_logs/ 16 | /backups/ 17 | /extracted-data 18 | /general.options 19 | /crash.boom 20 | 21 | # OpenBLCMM Data 22 | blcmm_data_*.jar 23 | 24 | # OSX Packaging -- don't want to commit this just yet in case it ends up 25 | # changing a bunch before we're ready for release. 26 | /release-processing/osx-app 27 | 28 | # Windows Packaging -- we're including the VC++ Redist 29 | /windows-processing/VC_redist.x64.exe 30 | 31 | -------------------------------------------------------------------------------- /lib/commonmark-0.21.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BLCM/OpenBLCMM/ecee5cbfbdbf9fadd7d38d6b86f8b669cb0dd19e/lib/commonmark-0.21.0.jar -------------------------------------------------------------------------------- /lib/commons-lang3-3.13.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BLCM/OpenBLCMM/ecee5cbfbdbf9fadd7d38d6b86f8b669cb0dd19e/lib/commons-lang3-3.13.0.jar -------------------------------------------------------------------------------- /lib/commons-text-1.10.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BLCM/OpenBLCMM/ecee5cbfbdbf9fadd7d38d6b86f8b669cb0dd19e/lib/commons-text-1.10.0.jar -------------------------------------------------------------------------------- /lib/semver4j-3.1.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BLCM/OpenBLCMM/ecee5cbfbdbf9fadd7d38d6b86f8b669cb0dd19e/lib/semver4j-3.1.0.jar -------------------------------------------------------------------------------- /lib/sqlite-jdbc-3.42.0.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BLCM/OpenBLCMM/ecee5cbfbdbf9fadd7d38d6b86f8b669cb0dd19e/lib/sqlite-jdbc-3.42.0.0.jar -------------------------------------------------------------------------------- /licenceHeader.txt: -------------------------------------------------------------------------------- 1 | Copyright (C) 2018-2020 LightChaosman 2 | 3 | BLCMM is free software: you can redistribute it and/or modify 4 | it under the terms of the GNU General Public License as published by 5 | the Free Software Foundation, either version 3 of the License, or 6 | (at your option) any later version. 7 | 8 | This program is distributed in the hope that it will be useful, 9 | but WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 | GNU General Public License for more details. 12 | 13 | You should have received a copy of the GNU General Public License 14 | along with this program. If not, see 15 | -------------------------------------------------------------------------------- /manifest.mf: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | X-COMMENT: Main-Class will be added automatically by build 3 | 4 | -------------------------------------------------------------------------------- /nbproject/genfiles.properties: -------------------------------------------------------------------------------- 1 | build.xml.data.CRC32=cbb7ca1e 2 | build.xml.script.CRC32=833f0cdb 3 | build.xml.stylesheet.CRC32=8064a381@1.80.1.48 4 | # This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. 5 | # Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. 6 | nbproject/build-impl.xml.data.CRC32=84a478b9 7 | nbproject/build-impl.xml.script.CRC32=0b685688 8 | nbproject/build-impl.xml.stylesheet.CRC32=12e0a6c2@1.105.0.48 9 | -------------------------------------------------------------------------------- /nbproject/project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | org.netbeans.modules.java.j2seproject 4 | 5 | 6 | OpenBLCMM 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /openblcmm-latest.txt: -------------------------------------------------------------------------------- 1 | OpenBLCMM: 1.4.1 2 | BL2Data: 1,2023.04.20.01 3 | TPSData: 1,2023.04.21.01 4 | AODKData: 1,2023.04.21.01 5 | -------------------------------------------------------------------------------- /release-processing/launch_openblcmm.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | Rem To change how much RAM OpenBLCMM is using, change the -Xmx argument, or 4 | Rem create your own launch script with a different parameter. The default 5 | Rem in here allocates 2GB. You can also use "M" as a suffix to supply more 6 | Rem precise values. Note that due to some peculiarities of Java memory 7 | Rem allocation, setting this value too high might result in the app not 8 | Rem launching properly, even if you technically have enough RAM free. 9 | 10 | java -Xmx2G -jar OpenBLCMM.jar 11 | -------------------------------------------------------------------------------- /release-processing/launch_openblcmm.command: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # vim: set expandtab tabstop=4 shiftwidth=4: 3 | 4 | # Head into the dir containing the shell script (OSX will otherwise 5 | # start out in the user's homedir) 6 | cd -- "$(dirname "$BASH_SOURCE")" 7 | 8 | # To change how much RAM OpenBLCMM is using, change the -Xmx argument, or 9 | # create your own launch script with a different parameter. The default 10 | # in here allocates 2GB. You can also use "M" as a suffix to supply more 11 | # precise values. Note that due to some peculiarities of Java memory 12 | # allocation, setting this value too high might result in the app not 13 | # launching properly, even if you technically have enough RAM free. 14 | 15 | java -Xmx2G -jar OpenBLCMM.jar 16 | -------------------------------------------------------------------------------- /release-processing/launch_openblcmm.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # vim: set expandtab tabstop=4 shiftwidth=4: 3 | 4 | # To change how much RAM OpenBLCMM is using, change the -Xmx argument, or 5 | # create your own launch script with a different parameter. The default 6 | # in here allocates 2GB. You can also use "M" as a suffix to supply more 7 | # precise values. Note that due to some peculiarities of Java memory 8 | # allocation, setting this value too high might result in the app not 9 | # launching properly, even if you technically have enough RAM free. 10 | 11 | java -Xmx2G -jar OpenBLCMM.jar 12 | -------------------------------------------------------------------------------- /resources/icon/README.md: -------------------------------------------------------------------------------- 1 | OpenBLCMM app icon, created by Apocalyptech. 2 | 3 | This was originally created in [Gimp](https://www.gimp.org/), which really 4 | wasn't the right tool to use for this kind of vectorish-looking art. So, 5 | shortly prior to official release, I ended up rebuilding it in 6 | [Inkscape](https://inkscape.org/) as an SVG. Several orders of magnitude 7 | smaller! There were still various imperfections in the paths which were 8 | noticeable at high resolutions, so I eventually rebuilt it again using a 9 | generation script (`gen_icon.py`), so the current SVG icon should be 10 | perfectly symmetrical and have identically-built corners and all that. 11 | 12 | `arch_reference.jpg` is the screenshot I used to construct the path, 13 | originally. That's from BL3, actually -- the arch in BL2 has a pretty 14 | different-looking shape, as it turns out, but I like the look of BL3's 15 | better. 16 | 17 | Rendered versions in the github tree: 18 | - `src/resources/Icon.png` - 256x256, used inside OpenBLCMM itself 19 | - `windows-processing/openblcmm.ico` - 64x64, used for Windows installer 20 | and EXE. 21 | 22 | -------------------------------------------------------------------------------- /resources/icon/arch_reference.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BLCM/OpenBLCMM/ecee5cbfbdbf9fadd7d38d6b86f8b669cb0dd19e/resources/icon/arch_reference.jpg -------------------------------------------------------------------------------- /resources/icon/openblcmm_icon.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /resources/icon/splash.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | OpenBLCMM 4 | 29 | 30 | 31 | 32 | 33 | 36 | 40 | 41 |
34 | 35 | 37 |
OpenBLCMM
38 |
Version 1.3.0
39 |
42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /src/META-INF/native-image/blcmm/blcmm/README.md: -------------------------------------------------------------------------------- 1 | This directory contains the [GraalVM native image build configuration](https://www.graalvm.org/22.0/reference-manual/native-image/BuildConfiguration/) 2 | that is used for BLCMM. This is what turns the Java code into a fully-compiled 3 | EXE for use on Windows systems. 4 | 5 | At time of writing (April 2023), we're actually using [Liberica Native Image Kit](https://bell-sw.com/liberica-native-image-kit/) 6 | instead of GraalVM itself to do the build, because vanilla GraalVM doesn't 7 | actually support Swing/AWT apps yet, which is what BLCMM is. Liberica, however, 8 | does. 9 | 10 | See README-developing.md out in the repository root for more information on 11 | this process. 12 | -------------------------------------------------------------------------------- /src/META-INF/native-image/blcmm/blcmm/native-image.properties: -------------------------------------------------------------------------------- 1 | Args = -Djava.awt.headless=false --enable-url-protocols=https -H:IncludeResources=.*/default.css$ -H:ReflectionConfigurationResources=${.}/reflect-config.json -H:ResourceConfigurationResources=${.}/resource-config.json -H:JNIConfigurationResources=${.}/jni-config.json -H:SerializationConfigurationResources=${.}/serialization-config.json 2 | -------------------------------------------------------------------------------- /src/META-INF/native-image/blcmm/blcmm/predefined-classes-config.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "type": "agent-extracted", 4 | "classes": [] 5 | } 6 | ] 7 | -------------------------------------------------------------------------------- /src/META-INF/native-image/blcmm/blcmm/proxy-config.json: -------------------------------------------------------------------------------- 1 | [] 2 | -------------------------------------------------------------------------------- /src/META-INF/native-image/blcmm/blcmm/serialization-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "types": [ 3 | { 4 | "name": "java.lang.Object[]" 5 | }, 6 | { 7 | "name": "java.lang.String" 8 | }, 9 | { 10 | "name": "javax.swing.tree.DefaultMutableTreeNode" 11 | }, 12 | { 13 | "name": "javax.swing.tree.DefaultMutableTreeNode[]" 14 | } 15 | ], 16 | "lambdaCapturingTypes": [], 17 | "proxies": [] 18 | } 19 | -------------------------------------------------------------------------------- /src/SteamVDF/VDF/VDF.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Taken from StidOfficial's "SteamVDF" project and adapated a bit for our own 3 | * use. https://github.com/StidOfficial/SteamVDF 4 | * 5 | * SteamVDF is distributed under the GPLv3: 6 | * 7 | * SteamVDF 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 | * This program 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 this program. If not, see 19 | */ 20 | 21 | package SteamVDF.VDF; 22 | 23 | import java.io.BufferedReader; 24 | import java.io.BufferedWriter; 25 | import java.io.File; 26 | import java.io.FileReader; 27 | import java.io.FileWriter; 28 | import java.io.IOException; 29 | import java.util.ArrayList; 30 | 31 | public class VDF extends VDFBaseElement { 32 | 33 | private static File VDFFile; 34 | 35 | public VDF() { 36 | super(); 37 | } 38 | 39 | public VDF(String file) throws IOException { 40 | this(new File(file)); 41 | } 42 | 43 | public VDF(File file) throws IOException { 44 | this(fileToLine(file)); 45 | } 46 | 47 | public VDF(String[] VDFLine) { 48 | String ElementName = null; 49 | VDFElement Element = null; 50 | 51 | for (int i = 0; i < VDFLine.length; i++) { 52 | 53 | String[] Line = VDFLine[i].trim().split("\t\t"); 54 | // Added 2023-02-13 for OpenBLCMM by Apocalyptech -- some older libraryfolder VDFs, 55 | // at least, seem to use a different separator. This should let the library 56 | // support either. 57 | if (Line.length == 1) { 58 | Line = VDFLine[i].trim().split(" \t"); 59 | } 60 | 61 | if (Line[0].startsWith("\"") && Line[0].endsWith("\"")) { 62 | if (Line.length == 2) { 63 | if (Element == null) 64 | this.addKey(removeQuote(Line[0]), removeQuote(Line[1])); 65 | else 66 | Element.addKey(removeQuote(Line[0]), removeQuote(Line[1])); 67 | } else if(Line.length == 1) { 68 | ElementName = removeQuote(Line[0]); 69 | } 70 | } else if (Line[0].contains("{")) { 71 | if (Element == null) { 72 | Element = this.addParent(ElementName, null); 73 | } else { 74 | Element = Element.addParent(ElementName, Element); 75 | } 76 | } else if (Line[0].contains("}")) { 77 | if (Element.getBase() == null) 78 | Element = null; 79 | else 80 | Element = Element.getBase(); 81 | } 82 | } 83 | } 84 | 85 | private static String[] fileToLine(File file) throws IOException { 86 | VDFFile = file; 87 | 88 | ArrayList BufferLine = new ArrayList<>(); 89 | BufferedReader BufferReader = new BufferedReader(new FileReader(file)); 90 | String LineRead = null; 91 | while ((LineRead = BufferReader.readLine()) != null) { 92 | BufferLine.add(LineRead); 93 | } 94 | BufferReader.close(); 95 | 96 | String[] VDFLine = new String[BufferLine.size()]; 97 | 98 | return BufferLine.toArray(VDFLine); 99 | } 100 | 101 | private static String removeQuote(String str) { 102 | return str.replace("\"", ""); 103 | } 104 | 105 | public File getFile() { 106 | return VDFFile; 107 | } 108 | 109 | public void Save() throws IOException { 110 | this.Save(VDFFile); 111 | } 112 | 113 | public void Save(String file) throws IOException { 114 | this.Save(new File(file)); 115 | } 116 | 117 | public void Save(File file) throws IOException { 118 | BufferedWriter BufferWriter = new BufferedWriter(new FileWriter(file)); 119 | BufferWriter.write(this.toString()); 120 | BufferWriter.close(); 121 | } 122 | } -------------------------------------------------------------------------------- /src/SteamVDF/VDF/VDFElement.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Taken from StidOfficial's "SteamVDF" project and adapated a bit for our own 3 | * use. https://github.com/StidOfficial/SteamVDF 4 | * 5 | * SteamVDF is distributed under the GPLv3: 6 | * 7 | * SteamVDF 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 | * This program 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 this program. If not, see 19 | */ 20 | 21 | package SteamVDF.VDF; 22 | 23 | public class VDFElement extends VDFBaseElement { 24 | 25 | private String ElementName; 26 | private VDFElement BaseElement; 27 | 28 | public VDFElement(String Name, VDFElement BaseElement) { 29 | this.ElementName = Name; 30 | this.BaseElement = BaseElement; 31 | } 32 | 33 | public String getName() { 34 | return this.ElementName; 35 | } 36 | 37 | public VDFElement getBase() { 38 | return BaseElement; 39 | } 40 | } -------------------------------------------------------------------------------- /src/SteamVDF/VDF/VDFKey.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Taken from StidOfficial's "SteamVDF" project and adapated a bit for our own 3 | * use. https://github.com/StidOfficial/SteamVDF 4 | * 5 | * SteamVDF is distributed under the GPLv3: 6 | * 7 | * SteamVDF 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 | * This program 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 this program. If not, see 19 | */ 20 | 21 | package SteamVDF.VDF; 22 | 23 | public class VDFKey { 24 | 25 | private String Value; 26 | 27 | public VDFKey(String Value) { 28 | this.Value = Value; 29 | } 30 | 31 | @Override 32 | public String toString() { 33 | return this.Value; 34 | } 35 | 36 | public boolean toBoolean() { 37 | return (this.Value == null || this.Value.equals("0")) ? false : true; 38 | } 39 | 40 | public int toInt() { 41 | return Integer.parseInt(this.Value); 42 | } 43 | 44 | public long toLong() { 45 | return Long.parseLong(this.Value); 46 | } 47 | } -------------------------------------------------------------------------------- /src/blcmm/Meta.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2023 Christopher J. Kucera 3 | * 4 | * 5 | * 6 | * OpenBLCMM is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see 18 | * 19 | */ 20 | package blcmm; 21 | 22 | /** 23 | * Just some general application metadata -- ie: app name + version 24 | * 25 | * @author pez 26 | */ 27 | public class Meta { 28 | 29 | /** 30 | * The application name, used in text throughout the app. 31 | */ 32 | public static final String NAME = "OpenBLCMM"; 33 | 34 | /** 35 | * App version. Should follow https://semver.org/ conventions. 36 | */ 37 | public static final String VERSION = "1.4.1"; 38 | 39 | /** 40 | * User data directory for storing prefs, extracted data, etc. If NAME 41 | * ever acquires special characters or spaces or whatever, it might be nice 42 | * to use a "sanitized" version here. 43 | */ 44 | public static final String APP_DATA_DIR_NAME = NAME; 45 | 46 | /** 47 | * URL to the project source control. 48 | */ 49 | public static final String CODE_URL = "https://github.com/BLCM/OpenBLCMM"; 50 | 51 | /** 52 | * URL to the project releases. 53 | */ 54 | public static final String RELEASES_URL = CODE_URL + "/releases"; 55 | 56 | /** 57 | * URL to where to submit bugs, shown on the crash handler dialog. 58 | */ 59 | public static final String BUGREPORT_URL = CODE_URL + "/issues"; 60 | 61 | /** 62 | * URL to where the app can retrieve the latest version of OpenBLCMM (and 63 | * its datapacks) available. Has a colon-suffixed "key" to indicate the 64 | * component whose version is being reported (valid vlaues: OpenBLCMM, 65 | * BL2Data, TPSData, or AODKData), and the data to the right of the colon 66 | * is the version string. The *Data versions have two values separated 67 | * by a comma; the first is the database (schema) version, the second being 68 | * the data version. 69 | */ 70 | public static final String UPDATE_VERSION_URL = "https://raw.githubusercontent.com/BLCM/OpenBLCMM/main/openblcmm-latest.txt"; 71 | 72 | /** 73 | * URL where data pack downloads are available. 74 | */ 75 | public static final String DATA_DOWNLOAD_URL = "https://github.com/BLCM/OpenBLCMM-Data/releases"; 76 | 77 | } 78 | -------------------------------------------------------------------------------- /src/blcmm/data/BehaviorProviderDefinition.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2023 Christopher J. Kucera 3 | * 4 | * 5 | * 6 | * OpenBLCMM is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see 18 | * 19 | */ 20 | 21 | package blcmm.data; 22 | 23 | /** 24 | * Some custom processing methods for BehaviorProviderDefinitions. 25 | * 26 | * This is mainly just here to support conversion of ArrayIndexAndLength 27 | * and LinkIdAndLinkedBehavior values to more human-useful numbers, for 28 | * modders doing BPD modding. These are shown in the main OpenBLCMM window 29 | * when statements are specifically going after a single value, and also 30 | * available via a little calculator window. 31 | * 32 | * @author apocalyptech 33 | */ 34 | public class BehaviorProviderDefinition { 35 | 36 | public static int getIndexFromArrayIndexAndLength(int value) { 37 | return value >> 16; 38 | } 39 | 40 | public static int getLengthFromArrayIndexAndLength(int value) { 41 | return value & 0xFFFF; 42 | } 43 | 44 | public static int getArrayIndexAndLength(int index, int length) { 45 | return (index << 16) | (length & 0xFFFF); 46 | } 47 | 48 | public static int getLinkIdFromLinkIdAndLinkedBehavior(int value) { 49 | return value >> 24; 50 | } 51 | 52 | public static int getBehaviorFromLinkIdAndLinkedBehavior(int value) { 53 | return value & 0xFFFF; 54 | } 55 | 56 | public static int getLinkIdAndLinkedBehavior(int linkId, int behavior) { 57 | return (linkId << 24) | (behavior & 0xFFFF); 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /src/blcmm/data/lib/DataStatusNotifier.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2023 Christopher J. Kucera 3 | * 4 | * 5 | * 6 | * OpenBLCMM is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see 18 | * 19 | */ 20 | package blcmm.data.lib; 21 | 22 | import blcmm.model.PatchType; 23 | 24 | /** 25 | * An interface to allow arbitrary components to receive status updates from 26 | * the DataManager extraction/verification processes, so it can be shown to 27 | * the user if desired. 28 | * 29 | * Event messages are intended to be marked as major or minor, with "major" 30 | * ones intended to be steps that may take a noticeable amount of time to 31 | * complete. That way the app can decide whether or not to display the 32 | * messages. 33 | * 34 | * @author apocalyptech 35 | */ 36 | public interface DataStatusNotifier { 37 | 38 | /** 39 | * Sets the Game whose data is currently being processed. 40 | * 41 | * @param game The game being processed. 42 | */ 43 | public void setGame(PatchType game); 44 | 45 | /** 46 | * Respond to an event. Events may be major or minor. 47 | * 48 | * @param message The message to send. 49 | * @param major True if the event is major, or false if it's minor. 50 | */ 51 | public void event(String message, boolean major); 52 | 53 | /** 54 | * Used to indicate that data processing has finished. 55 | */ 56 | public void finish(); 57 | 58 | } 59 | -------------------------------------------------------------------------------- /src/blcmm/data/lib/UEClass.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2023 Christopher J. Kucera 3 | * 4 | * 5 | * 6 | * OpenBLCMM is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see 18 | * 19 | */ 20 | 21 | package blcmm.data.lib; 22 | 23 | import java.sql.ResultSet; 24 | import java.sql.SQLException; 25 | import java.util.ArrayList; 26 | import java.util.List; 27 | 28 | /** 29 | * Model for a single class entry. 30 | * 31 | * This is part of the new opensource data library, reimplemented without 32 | * reference to the original non-opensourced code. 33 | * 34 | * This is a pretty simple data container without much actual functionality. 35 | * The majority of the logic governing the interactions with the data 36 | * is handled by the main DataManager class. 37 | * 38 | * @author apocalyptech 39 | */ 40 | public class UEClass implements Comparable { 41 | 42 | private final int id; 43 | private final String name; 44 | private final int categoryId; 45 | private UEClass parent; 46 | private final int parentId; 47 | private final int numObjects; 48 | private final ArrayList children; 49 | private final int numDatafiles; 50 | 51 | public UEClass(int id, String name, int categoryId, Integer parentId, int numObjects, int numDatafiles) { 52 | this.id = id; 53 | this.name = name; 54 | this.categoryId = categoryId; 55 | this.parentId = parentId; 56 | this.parent = null; 57 | this.numObjects = numObjects; 58 | this.children = new ArrayList<>(); 59 | this.numDatafiles = numDatafiles; 60 | } 61 | 62 | public int getId() { 63 | return this.id; 64 | } 65 | 66 | public String getName() { 67 | return this.name; 68 | } 69 | 70 | public int getCategoryId() { 71 | return this.categoryId; 72 | } 73 | 74 | public int getParentId() { 75 | return this.parentId; 76 | } 77 | 78 | public void setParent(UEClass ueClass) { 79 | this.parent = ueClass; 80 | } 81 | 82 | public UEClass getParent() { 83 | return this.parent; 84 | } 85 | 86 | public boolean hasChildren() { 87 | return !this.children.isEmpty(); 88 | } 89 | 90 | public List getChildren() { 91 | return this.children; 92 | } 93 | 94 | public void addChild(UEClass ueClass) { 95 | this.children.add(ueClass); 96 | } 97 | 98 | public int getNumObjects() { 99 | return this.numObjects; 100 | } 101 | 102 | public int getNumDatafiles() { 103 | return this.numDatafiles; 104 | } 105 | 106 | @Override 107 | public String toString() { 108 | return this.name; 109 | } 110 | 111 | @Override 112 | public int compareTo(UEClass other) { 113 | return this.name.compareToIgnoreCase(other.name); 114 | } 115 | 116 | /** 117 | * Returns a new UEClass based on a database row ResultSet. 118 | * 119 | * @param rs The ResultSet with database data. 120 | * @return A new UEClass object 121 | * @throws SQLException 122 | */ 123 | public static UEClass getFromDbRow(ResultSet rs) throws SQLException { 124 | int id = rs.getInt("id"); 125 | String name = rs.getString("name"); 126 | int categoryId = rs.getInt("category"); 127 | int parentId = rs.getInt("parent"); 128 | int numObjects = rs.getInt("total_children"); 129 | int numDatafiles = rs.getInt("num_datafiles"); 130 | return new UEClass(id, name, categoryId, parentId, numObjects, numDatafiles); 131 | } 132 | 133 | } 134 | -------------------------------------------------------------------------------- /src/blcmm/gui/components/BoldJTabbedPane.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2022 Inteli9 3 | * 4 | * This code was made available under CC BY-SA 4.0 by the StackOverflow 5 | * Terms of Service. 6 | * 7 | * Original Post: https://stackoverflow.com/a/70621256/2013126 8 | * Author: https://stackoverflow.com/users/2807375/inteli9 9 | * 10 | */ 11 | package blcmm.gui.components; 12 | 13 | import java.awt.Component; 14 | import javax.swing.Icon; 15 | import javax.swing.JComponent; 16 | import javax.swing.JTabbedPane; 17 | 18 | /** 19 | * A JTabbedPane where the currently-active tab title is set to bold, for 20 | * enhanced readability. 21 | * 22 | * Lifted with very minimal changes from https://stackoverflow.com/a/70621256/2013126 23 | * 24 | * @author https://stackoverflow.com/users/2807375/inteli9 25 | */ 26 | public class BoldJTabbedPane extends JTabbedPane { 27 | 28 | @Override 29 | public void insertTab(String title, Icon icon, Component component, String tip, int index) { 30 | ((JComponent)component).putClientProperty("title", title); 31 | super.insertTab(title, icon, component, tip, index); 32 | } 33 | 34 | @Override 35 | public void setSelectedIndex(int index) { 36 | int currentIndex = getSelectedIndex(); 37 | if (currentIndex >= 0) { 38 | JComponent previous = (JComponent) getComponentAt(currentIndex); 39 | String title = (String) previous.getClientProperty("title"); 40 | setTitleAt(currentIndex, title); 41 | } 42 | super.setSelectedIndex(index); 43 | 44 | JComponent current = (JComponent)getSelectedComponent(); 45 | String title = (String) current.getClientProperty("title"); 46 | setTitleAt(index, "" + title + ""); 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /src/blcmm/gui/components/DefaultTextTextField.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2020 LightChaosman 3 | * 4 | * OpenBLCMM is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see 16 | * 17 | */ 18 | package blcmm.gui.components; 19 | 20 | import blcmm.gui.FontInfo; 21 | import blcmm.gui.theme.ThemeManager; 22 | import java.awt.event.FocusEvent; 23 | import java.awt.event.FocusListener; 24 | import javax.swing.JTextField; 25 | import javax.swing.JToolTip; 26 | 27 | /** 28 | * 29 | * @author LightChaosman 30 | */ 31 | @SuppressWarnings("serial") 32 | public class DefaultTextTextField extends JTextField { 33 | 34 | private final String hint; 35 | private boolean showingHint; 36 | private final FontInfo fontInfo; 37 | 38 | public DefaultTextTextField(final String hint, FontInfo fontInfo) { 39 | super(hint); 40 | this.hint = hint; 41 | this.showingHint = true; 42 | this.fontInfo = fontInfo; 43 | super.addFocusListener(new MyFocusListener()); 44 | super.setForeground(ThemeManager.getColor(ThemeManager.ColorType.UINimbusDisabledText)); 45 | } 46 | 47 | @Override 48 | public String getText() { 49 | return showingHint ? "" : super.getText(); 50 | } 51 | 52 | @Override 53 | public JToolTip createToolTip() { 54 | JToolTip tip = new JToolTip(); 55 | tip.setComponent(this); 56 | tip.setFont(this.fontInfo.getFont()); 57 | return tip; 58 | } 59 | 60 | private class MyFocusListener implements FocusListener { 61 | 62 | @Override 63 | public void focusGained(FocusEvent e) { 64 | if (getText().isEmpty()) { 65 | setText(""); 66 | setForeground(ThemeManager.getColor(ThemeManager.ColorType.UIText)); 67 | showingHint = false; 68 | } 69 | } 70 | 71 | @Override 72 | public void focusLost(FocusEvent e) { 73 | if (getText().isEmpty()) { 74 | setForeground(ThemeManager.getColor(ThemeManager.ColorType.UINimbusDisabledText)); 75 | setText(hint); 76 | showingHint = true; 77 | 78 | } 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/blcmm/gui/components/FontInfoJButton.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2023 Christopher J. Kucera 3 | * 4 | * OpenBLCMM is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see 16 | * 17 | */ 18 | package blcmm.gui.components; 19 | 20 | import blcmm.gui.FontInfo; 21 | import java.awt.Font; 22 | import javax.swing.Action; 23 | import javax.swing.Icon; 24 | import javax.swing.JButton; 25 | import javax.swing.JToolTip; 26 | 27 | /** 28 | * An extension to JButton which supports scaling the tooltip font based on 29 | * the user's font-size selection. (Only really needed for sessions in which 30 | * the user's changing the size dynamically.) 31 | * 32 | * This class also includes a single constructor which allows setting a font 33 | * style + size modifier which should be applied whenever the label's font 34 | * size changes. 35 | * 36 | * @author apocalyptech 37 | */ 38 | public class FontInfoJButton extends JButton { 39 | 40 | private final FontInfo fontInfo; 41 | private boolean doExtraStyle = false; 42 | private int extraStyle = Font.PLAIN; 43 | private float extraFontSize = 0; 44 | 45 | public FontInfoJButton(FontInfo fontInfo) { 46 | super(); 47 | this.fontInfo = fontInfo; 48 | // May as well do this too 49 | this.setFont(fontInfo.getFont()); 50 | } 51 | 52 | public FontInfoJButton(FontInfo fontInfo, int extraStyle, float extraFontSize) { 53 | super(); 54 | this.fontInfo = fontInfo; 55 | this.doExtraStyle = true; 56 | this.extraStyle = extraStyle; 57 | this.extraFontSize = extraFontSize; 58 | // May as well do this too 59 | this.setFont(fontInfo.getFont()); 60 | } 61 | 62 | public FontInfoJButton(Action a, FontInfo fontInfo) { 63 | super(a); 64 | this.fontInfo = fontInfo; 65 | // May as well do this too 66 | this.setFont(fontInfo.getFont()); 67 | } 68 | 69 | public FontInfoJButton(Icon icon, FontInfo fontInfo) { 70 | super(icon); 71 | this.fontInfo = fontInfo; 72 | // May as well do this too 73 | this.setFont(fontInfo.getFont()); 74 | } 75 | 76 | public FontInfoJButton(String text, FontInfo fontInfo) { 77 | super(text); 78 | this.fontInfo = fontInfo; 79 | // May as well do this too 80 | this.setFont(fontInfo.getFont()); 81 | } 82 | 83 | public FontInfoJButton(String text, Icon icon, FontInfo fontInfo) { 84 | super(text, icon); 85 | this.fontInfo = fontInfo; 86 | // May as well do this too 87 | this.setFont(fontInfo.getFont()); 88 | } 89 | 90 | @Override 91 | public JToolTip createToolTip() { 92 | JToolTip tip = new JToolTip(); 93 | tip.setComponent(this); 94 | tip.setFont(this.fontInfo.getFont()); 95 | return tip; 96 | } 97 | 98 | @Override 99 | public void setFont(Font f) { 100 | if (doExtraStyle) { 101 | super.setFont(f.deriveFont(this.extraStyle, f.getSize2D() + this.extraFontSize)); 102 | } else { 103 | super.setFont(f.deriveFont(f.getSize2D() + this.extraFontSize)); 104 | } 105 | } 106 | 107 | } 108 | -------------------------------------------------------------------------------- /src/blcmm/gui/components/FontInfoJCheckBox.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2023 Christopher J. Kucera 3 | * 4 | * OpenBLCMM is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see 16 | * 17 | */ 18 | package blcmm.gui.components; 19 | 20 | import blcmm.gui.FontInfo; 21 | import javax.swing.Action; 22 | import javax.swing.Icon; 23 | import javax.swing.JCheckBox; 24 | import javax.swing.JToolTip; 25 | 26 | /** 27 | * An extension to JCheckBox which supports scaling the tooltip font based on 28 | * the user's font-size selection. (Only really needed for sessions in which 29 | * the user's changing the size dynamically.) 30 | * 31 | * @author apocalyptech 32 | */ 33 | public class FontInfoJCheckBox extends JCheckBox { 34 | 35 | private final FontInfo fontInfo; 36 | 37 | public FontInfoJCheckBox(FontInfo fontInfo) { 38 | super(); 39 | this.fontInfo = fontInfo; 40 | } 41 | 42 | public FontInfoJCheckBox(Action a, FontInfo fontInfo) { 43 | super(a); 44 | this.fontInfo = fontInfo; 45 | } 46 | 47 | public FontInfoJCheckBox(Icon icon, FontInfo fontInfo) { 48 | super(icon); 49 | this.fontInfo = fontInfo; 50 | } 51 | 52 | public FontInfoJCheckBox(Icon icon, boolean selected, FontInfo fontInfo) { 53 | super(icon, selected); 54 | this.fontInfo = fontInfo; 55 | } 56 | 57 | public FontInfoJCheckBox(String text, FontInfo fontInfo) { 58 | super(text); 59 | this.fontInfo = fontInfo; 60 | } 61 | 62 | public FontInfoJCheckBox(String text, boolean selected, FontInfo fontInfo) { 63 | super(text, selected); 64 | this.fontInfo = fontInfo; 65 | } 66 | 67 | public FontInfoJCheckBox(String text, Icon icon, FontInfo fontInfo) { 68 | super(text, icon); 69 | this.fontInfo = fontInfo; 70 | } 71 | 72 | public FontInfoJCheckBox(String text, Icon icon, boolean selected, FontInfo fontInfo) { 73 | super(text, icon, selected); 74 | this.fontInfo = fontInfo; 75 | } 76 | 77 | @Override 78 | public JToolTip createToolTip() { 79 | JToolTip tip = new JToolTip(); 80 | tip.setComponent(this); 81 | tip.setFont(this.fontInfo.getFont()); 82 | return tip; 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/blcmm/gui/components/FontInfoJComboBox.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2023 Christopher J. Kucera 3 | * 4 | * OpenBLCMM is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see 16 | * 17 | */ 18 | package blcmm.gui.components; 19 | 20 | import blcmm.gui.FontInfo; 21 | import java.util.Vector; 22 | import javax.swing.ComboBoxModel; 23 | import javax.swing.JComboBox; 24 | import javax.swing.JToolTip; 25 | 26 | /** 27 | * An extension to JComboBox which supports scaling the tooltip font based on 28 | * the user's font-size selection. (Only really needed for sessions in which 29 | * the user's changing the size dynamically.) 30 | * 31 | * @author apocalyptech 32 | */ 33 | public class FontInfoJComboBox extends JComboBox { 34 | 35 | private final FontInfo fontInfo; 36 | 37 | public FontInfoJComboBox(FontInfo fontInfo) { 38 | super(); 39 | this.fontInfo = fontInfo; 40 | // May as well do this too 41 | this.setFont(fontInfo.getFont()); 42 | } 43 | 44 | public FontInfoJComboBox(ComboBoxModel aModel, FontInfo fontInfo) { 45 | super(aModel); 46 | this.fontInfo = fontInfo; 47 | // May as well do this too 48 | this.setFont(fontInfo.getFont()); 49 | } 50 | 51 | public FontInfoJComboBox(E[] items, FontInfo fontInfo) { 52 | super(items); 53 | this.fontInfo = fontInfo; 54 | // May as well do this too 55 | this.setFont(fontInfo.getFont()); 56 | } 57 | 58 | public FontInfoJComboBox(Vector items, FontInfo fontInfo) { 59 | super(items); 60 | this.fontInfo = fontInfo; 61 | // May as well do this too 62 | this.setFont(fontInfo.getFont()); 63 | } 64 | 65 | @Override 66 | public JToolTip createToolTip() { 67 | JToolTip tip = new JToolTip(); 68 | tip.setComponent(this); 69 | tip.setFont(this.fontInfo.getFont()); 70 | return tip; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/blcmm/gui/components/FontInfoJLabel.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2023 Christopher J. Kucera 3 | * 4 | * OpenBLCMM is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see 16 | * 17 | */ 18 | package blcmm.gui.components; 19 | 20 | import blcmm.gui.FontInfo; 21 | import java.awt.Font; 22 | import javax.swing.Icon; 23 | import javax.swing.JLabel; 24 | import javax.swing.JToolTip; 25 | 26 | /** 27 | * An extension to JButton which supports scaling the tooltip font based on 28 | * the user's font-size selection. (Only really needed for sessions in which 29 | * the user's changing the size dynamically.) 30 | * 31 | * This class also includes a single constructor which allows setting a font 32 | * size modifier which should be applied whenever the label's font size changes. 33 | * 34 | * @author apocalyptech 35 | */ 36 | public class FontInfoJLabel extends JLabel { 37 | 38 | private final FontInfo fontInfo; 39 | private float extraFontSize = 0; 40 | 41 | public FontInfoJLabel(FontInfo fontInfo) { 42 | super(); 43 | this.fontInfo = fontInfo; 44 | // May as well do this too 45 | this.setFont(fontInfo.getFont()); 46 | } 47 | 48 | public FontInfoJLabel(FontInfo fontInfo, float extraFontSize) { 49 | super(); 50 | this.fontInfo = fontInfo; 51 | this.extraFontSize = extraFontSize; 52 | // May as well do this too 53 | this.setFont(fontInfo.getFont()); 54 | } 55 | 56 | public FontInfoJLabel(Icon image, FontInfo fontInfo) { 57 | super(image); 58 | this.fontInfo = fontInfo; 59 | // May as well do this too 60 | this.setFont(fontInfo.getFont()); 61 | } 62 | 63 | public FontInfoJLabel(Icon image, int horizontalAlignment, FontInfo fontInfo) { 64 | super(image, horizontalAlignment); 65 | this.fontInfo = fontInfo; 66 | // May as well do this too 67 | this.setFont(fontInfo.getFont()); 68 | } 69 | 70 | public FontInfoJLabel(String text, FontInfo fontInfo) { 71 | super(text); 72 | this.fontInfo = fontInfo; 73 | // May as well do this too 74 | this.setFont(fontInfo.getFont()); 75 | } 76 | 77 | public FontInfoJLabel(String text, Icon icon, int horizontalAlignment, FontInfo fontInfo) { 78 | super(text, icon, horizontalAlignment); 79 | this.fontInfo = fontInfo; 80 | // May as well do this too 81 | this.setFont(fontInfo.getFont()); 82 | } 83 | 84 | public FontInfoJLabel(String text, int horizontalAlignment, FontInfo fontInfo) { 85 | super(text, horizontalAlignment); 86 | this.fontInfo = fontInfo; 87 | // May as well do this too 88 | this.setFont(fontInfo.getFont()); 89 | } 90 | 91 | @Override 92 | public JToolTip createToolTip() { 93 | JToolTip tip = new JToolTip(); 94 | tip.setComponent(this); 95 | tip.setFont(this.fontInfo.getFont()); 96 | return tip; 97 | } 98 | 99 | @Override 100 | public void setFont(Font f) { 101 | super.setFont(f.deriveFont(f.getSize2D() + this.extraFontSize)); 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /src/blcmm/gui/components/FontInfoJMenuItem.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2023 Christopher J. Kucera 3 | * 4 | * OpenBLCMM is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see 16 | * 17 | */ 18 | package blcmm.gui.components; 19 | 20 | import blcmm.gui.FontInfo; 21 | import javax.swing.Action; 22 | import javax.swing.Icon; 23 | import javax.swing.JMenuItem; 24 | import javax.swing.JToolTip; 25 | 26 | /** 27 | * An extension to JMenuItem which supports scaling the tooltip font based on 28 | * the user's font-size selection. (Only really needed for sessions in which 29 | * the user's changing the size dynamically.) 30 | * 31 | * @author apocalyptech 32 | */ 33 | public class FontInfoJMenuItem extends JMenuItem { 34 | 35 | private final FontInfo fontInfo; 36 | 37 | public FontInfoJMenuItem(FontInfo fontInfo) { 38 | super(); 39 | this.fontInfo = fontInfo; 40 | // May as well do this too 41 | this.setFont(fontInfo.getFont()); 42 | } 43 | 44 | public FontInfoJMenuItem(Action a, FontInfo fontInfo) { 45 | super(a); 46 | this.fontInfo = fontInfo; 47 | // May as well do this too 48 | this.setFont(fontInfo.getFont()); 49 | } 50 | 51 | public FontInfoJMenuItem(Icon icon, FontInfo fontInfo) { 52 | super(icon); 53 | this.fontInfo = fontInfo; 54 | // May as well do this too 55 | this.setFont(fontInfo.getFont()); 56 | } 57 | 58 | public FontInfoJMenuItem(String text, FontInfo fontInfo) { 59 | super(text); 60 | this.fontInfo = fontInfo; 61 | // May as well do this too 62 | this.setFont(fontInfo.getFont()); 63 | } 64 | 65 | public FontInfoJMenuItem(String text, Icon icon, FontInfo fontInfo) { 66 | super(text, icon); 67 | this.fontInfo = fontInfo; 68 | // May as well do this too 69 | this.setFont(fontInfo.getFont()); 70 | } 71 | 72 | public FontInfoJMenuItem(String text, int mnemonic, FontInfo fontInfo) { 73 | super(text, mnemonic); 74 | this.fontInfo = fontInfo; 75 | // May as well do this too 76 | this.setFont(fontInfo.getFont()); 77 | } 78 | 79 | @Override 80 | public JToolTip createToolTip() { 81 | JToolTip tip = new JToolTip(); 82 | tip.setComponent(this); 83 | tip.setFont(this.fontInfo.getFont()); 84 | return tip; 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/blcmm/gui/components/FontInfoJToggleButton.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2023 Christopher J. Kucera 3 | * 4 | * OpenBLCMM is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see 16 | * 17 | */ 18 | package blcmm.gui.components; 19 | 20 | import blcmm.gui.FontInfo; 21 | import javax.swing.Action; 22 | import javax.swing.Icon; 23 | import javax.swing.JToggleButton; 24 | import javax.swing.JToolTip; 25 | 26 | /** 27 | * An extension to JToggleButton which supports scaling the tooltip font based on 28 | * the user's font-size selection. (Only really needed for sessions in which 29 | * the user's changing the size dynamically.) 30 | * 31 | * @author apocalyptech 32 | */ 33 | public class FontInfoJToggleButton extends JToggleButton { 34 | 35 | private final FontInfo fontInfo; 36 | 37 | public FontInfoJToggleButton(FontInfo fontInfo) { 38 | super(); 39 | this.fontInfo = fontInfo; 40 | // May as well do this too 41 | this.setFont(fontInfo.getFont()); 42 | } 43 | 44 | public FontInfoJToggleButton(Action a, FontInfo fontInfo) { 45 | super(a); 46 | this.fontInfo = fontInfo; 47 | // May as well do this too 48 | this.setFont(fontInfo.getFont()); 49 | } 50 | 51 | public FontInfoJToggleButton(Icon icon, FontInfo fontInfo) { 52 | super(icon); 53 | this.fontInfo = fontInfo; 54 | // May as well do this too 55 | this.setFont(fontInfo.getFont()); 56 | } 57 | 58 | public FontInfoJToggleButton(Icon icon, boolean selected, FontInfo fontInfo) { 59 | super(icon, selected); 60 | this.fontInfo = fontInfo; 61 | // May as well do this too 62 | this.setFont(fontInfo.getFont()); 63 | } 64 | 65 | public FontInfoJToggleButton(String text, FontInfo fontInfo) { 66 | super(text); 67 | this.fontInfo = fontInfo; 68 | // May as well do this too 69 | this.setFont(fontInfo.getFont()); 70 | } 71 | 72 | public FontInfoJToggleButton(String text, boolean selected, FontInfo fontInfo) { 73 | super(text, selected); 74 | this.fontInfo = fontInfo; 75 | // May as well do this too 76 | this.setFont(fontInfo.getFont()); 77 | } 78 | 79 | public FontInfoJToggleButton(String text, Icon icon, FontInfo fontInfo) { 80 | super(text, icon); 81 | this.fontInfo = fontInfo; 82 | // May as well do this too 83 | this.setFont(fontInfo.getFont()); 84 | } 85 | 86 | public FontInfoJToggleButton(String text, Icon icon, boolean selected, FontInfo fontInfo) { 87 | super(text, icon, selected); 88 | this.fontInfo = fontInfo; 89 | // May as well do this too 90 | this.setFont(fontInfo.getFont()); 91 | } 92 | 93 | @Override 94 | public JToolTip createToolTip() { 95 | JToolTip tip = new JToolTip(); 96 | tip.setComponent(this); 97 | tip.setFont(this.fontInfo.getFont()); 98 | return tip; 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /src/blcmm/gui/components/ForceClosingJFrame.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2020 LightChaosman 3 | * 4 | * OpenBLCMM is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see 16 | * 17 | */ 18 | package blcmm.gui.components; 19 | 20 | import blcmm.utilities.GlobalLogger; 21 | import java.util.HashSet; 22 | import javax.swing.JFrame; 23 | 24 | /** 25 | * 26 | * @author LightChaosman 27 | */ 28 | public class ForceClosingJFrame extends JFrame { 29 | 30 | private final static HashSet INSTANCES = new HashSet<>(); 31 | 32 | public ForceClosingJFrame() { 33 | super(); 34 | super.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 35 | INSTANCES.add(this); 36 | } 37 | 38 | public ForceClosingJFrame(String name) { 39 | super(name); 40 | super.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 41 | GlobalLogger.log("Opening frame: " + name); 42 | INSTANCES.add(this); 43 | } 44 | 45 | @Override 46 | public void dispose() { 47 | GlobalLogger.log("Closing frame: " + getTitle()); 48 | super.dispose(); 49 | INSTANCES.remove(this); 50 | if (INSTANCES.isEmpty()) { 51 | GlobalLogger.deleteLog(); 52 | try { 53 | Thread.sleep(500); 54 | } catch (InterruptedException ex) { 55 | } 56 | System.exit(0); 57 | } 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /src/blcmm/gui/components/SimpleGameSelectionComboBox.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2020 LightChaosman 3 | * Copyright (C) 2023 Christopher J. Kucera 4 | * 5 | * OpenBLCMM is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see 17 | * 18 | */ 19 | package blcmm.gui.components; 20 | 21 | import blcmm.model.PatchType; 22 | import blcmm.utilities.Options; 23 | import java.awt.Component; 24 | import java.awt.event.ItemListener; 25 | import javax.swing.DefaultListCellRenderer; 26 | import javax.swing.ImageIcon; 27 | import javax.swing.JComboBox; 28 | import javax.swing.JLabel; 29 | import javax.swing.JList; 30 | 31 | /** 32 | * A "Simple" game selection combo box, intended for use in OE. 33 | * Basically just copied from GameSelectionPanel with all the cruft trimmed 34 | * out. 35 | * 36 | * @author LightChaosman 37 | */ 38 | public class SimpleGameSelectionComboBox extends JComboBox { 39 | 40 | private PatchType type = null; 41 | 42 | public SimpleGameSelectionComboBox() { 43 | super(PatchType.values()); 44 | this.setRenderer(new DefaultListCellRenderer() { 45 | @Override 46 | public Component getListCellRendererComponent(JList jlist, Object o, int i, boolean bln, boolean bln1) { 47 | JLabel l = (JLabel) super.getListCellRendererComponent(jlist, o, i, bln, bln1); 48 | l.setText(((PatchType) o).getGameName()); 49 | l.setIcon(new ImageIcon(((PatchType) o).getIcon(4 + Options.INSTANCE.getFontsize()))); 50 | return l; 51 | } 52 | }); 53 | this.addItemListener(e -> type = (PatchType) this.getSelectedItem()); 54 | this.setMode(type); 55 | } 56 | 57 | public final void setMode(PatchType type) { 58 | this.type = type; 59 | this.setSelectedItem(type); 60 | } 61 | 62 | public PatchType getNonNullGameType() { 63 | return type == null ? PatchType.BL2 : type; 64 | } 65 | 66 | public PatchType getGameType() { 67 | return type; 68 | } 69 | 70 | public void setType(PatchType type) { 71 | this.setMode(type); 72 | } 73 | 74 | public void addItemListenerToComboBox(ItemListener aListener) { 75 | this.addItemListener(aListener); 76 | } 77 | 78 | } 79 | -------------------------------------------------------------------------------- /src/blcmm/gui/panels/HexEditPanel.form: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 |
82 | -------------------------------------------------------------------------------- /src/blcmm/gui/panels/IniTweaksPanel.form: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 |
82 | -------------------------------------------------------------------------------- /src/blcmm/gui/panels/IntegerConverter.form: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 |
46 | -------------------------------------------------------------------------------- /src/blcmm/gui/panels/TextSearchDialog.form: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /src/blcmm/gui/text/CustomSelectionDefinition.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2023 Christopher J. Kucera 3 | * 4 | * 5 | * 6 | * OpenBLCMM is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see 18 | * 19 | */ 20 | package blcmm.gui.text; 21 | 22 | import java.util.HashSet; 23 | 24 | /** 25 | * Shared definitions for our custom selection handling which attempts to make 26 | * selecting object names in OpenBLCMM a bit easier. This will be used for 27 | * both double-click-to-select, and for Ctrl-Shift-Left/Right-to-select. Since 28 | * it's got to be available for both Mouse and Key listeners, it made sense to 29 | * at least pull this out here. The actual selection handling seems like it's 30 | * still best left to the individual handlers, since it can be subtly different. 31 | * Trying to abstract it in here would, IMO, make it a bit too complex. 32 | * 33 | * Regardless, at the moment this just defines the characters which we consider 34 | * to delimit a "word," when selecting. This is quite a bit less restrictive 35 | * than the default Java handling -- a single selection can easily select an 36 | * entire URL, for instance, now. 37 | * 38 | * A better way to implement this is probably to figure out how to override 39 | * the Document's sense of what a "word" is so that the default selection 40 | * behavior does the "right" thing. But, after a bit of searching I couldn't 41 | * even find a hint of where that was stored, and just did this instead. 42 | * 43 | * @author apocalyptech 44 | */ 45 | public class CustomSelectionDefinition { 46 | 47 | /** 48 | * The set of delimiters which are considered boundaries of a "word," in 49 | * terms of a double-click selection. 50 | */ 51 | public final static HashSet delimiters = new HashSet<> (); 52 | static { 53 | delimiters.add('='); 54 | delimiters.add(' '); 55 | delimiters.add(','); 56 | delimiters.add(';'); 57 | delimiters.add('('); 58 | delimiters.add(')'); 59 | // Originally we'd excluded square brakets because I thought it'd be 60 | // useful to be able to copy whole attributes (including array indexes) 61 | // but it's apparently too annoying in other contexts. So, square 62 | // brackets are in. 63 | delimiters.add('['); 64 | delimiters.add(']'); 65 | delimiters.add('\t'); 66 | delimiters.add('\n'); 67 | delimiters.add('\r'); 68 | // Note that we very explicitly *don't* want to add apostrophe to the 69 | // list of delimiters, because that's used by fully-formed object 70 | // references, and we want to select all of that, when we can. Double 71 | // quote marks will be useful to delimit, though, so add that in. 72 | delimiters.add('"'); 73 | } 74 | 75 | /** 76 | * Also, the set of delimiters which are specifically whitespace. For 77 | * our ctrl-shift-(left|right) handling, we want to handle these a bit 78 | * differently. This is intended to be a subset of `delimiters`. 79 | */ 80 | public final static HashSet whitespace = new HashSet<> (); 81 | static { 82 | whitespace.add(' '); 83 | whitespace.add('\t'); 84 | whitespace.add('\n'); 85 | whitespace.add('\r'); 86 | } 87 | 88 | } 89 | -------------------------------------------------------------------------------- /src/blcmm/gui/theme/Theme.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2020 LightChaosman 3 | * 4 | * OpenBLCMM is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see 16 | * 17 | */ 18 | package blcmm.gui.theme; 19 | 20 | import blcmm.utilities.options.SelectionOptionData; 21 | import java.awt.Color; 22 | import java.util.HashMap; 23 | import javax.swing.ImageIcon; 24 | 25 | /** 26 | * Small class for containing the available themes 27 | * 28 | * @author LightChaosman 29 | */ 30 | public class Theme implements SelectionOptionData { 31 | 32 | static { 33 | ThemeManager.getTheme();//Force the ThemeManager to initialize 34 | } 35 | 36 | //The names displayed in the UI 37 | private final String name; 38 | private final String displayName; 39 | 40 | //The hashmaps containing the colors and the icons of the theme. 41 | private final HashMap colorMap = new HashMap<>(); 42 | private final HashMap iconMap = new HashMap<>(); 43 | 44 | /** 45 | * The private constructor for this class 46 | * 47 | * @param name 48 | */ 49 | Theme(String name) { 50 | this(name, null); 51 | } 52 | 53 | Theme(String name, String displayName) { 54 | this.name = name; 55 | this.displayName = displayName; 56 | } 57 | 58 | @Override 59 | public String toString() { 60 | return displayName == null ? name + " mode" : displayName; 61 | } 62 | 63 | @Override 64 | public String toSaveString() { 65 | return this.name; 66 | } 67 | 68 | @Override 69 | public String toDropdownLabel() { 70 | return this.name; 71 | } 72 | 73 | public Color get(ThemeManager.ColorType colortype) { 74 | return colorMap.get(colortype); 75 | } 76 | 77 | void put(ThemeManager.ColorType colortype, Color color) { 78 | colorMap.put(colortype, color); 79 | } 80 | 81 | HashMap getColorMap() { 82 | return colorMap; 83 | } 84 | 85 | HashMap getIconMap() { 86 | return iconMap; 87 | } 88 | 89 | } 90 | -------------------------------------------------------------------------------- /src/blcmm/gui/tree/EasterEggs.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2020 LightChaosman 3 | * 4 | * OpenBLCMM is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see 16 | * 17 | */ 18 | package blcmm.gui.tree; 19 | 20 | import java.awt.Desktop; 21 | import java.awt.event.KeyEvent; 22 | import java.io.IOException; 23 | import java.net.URI; 24 | import java.net.URISyntaxException; 25 | import java.net.URL; 26 | 27 | /** 28 | * 29 | * @author FromDarkHell 30 | */ 31 | public class EasterEggs { 32 | 33 | public static class CheatCode { 34 | 35 | public static CheatCode KONAMI = new CheatCode( 36 | KeyEvent.VK_UP, KeyEvent.VK_UP, 37 | KeyEvent.VK_DOWN, KeyEvent.VK_DOWN, 38 | KeyEvent.VK_LEFT, KeyEvent.VK_RIGHT, 39 | KeyEvent.VK_LEFT, KeyEvent.VK_RIGHT, 40 | KeyEvent.VK_B, KeyEvent.VK_A); 41 | 42 | private final int[] sequenceOfKeyEvents; 43 | private transient int progress = 0; 44 | 45 | public CheatCode(int... sequenceOfKeyEvents) { 46 | this.sequenceOfKeyEvents = sequenceOfKeyEvents; 47 | } 48 | 49 | public boolean keyPressCompletedCode(int keyCode) { 50 | if (keyCode != sequenceOfKeyEvents[progress]) { 51 | // Reset our index since the code was wrong. 52 | progress = 0; 53 | return false; 54 | } 55 | 56 | // Increase our index by one 57 | progress++; 58 | 59 | // This happens when our final button is pressed, VK_B in this case. 60 | if (progress == sequenceOfKeyEvents.length) { 61 | // Reset our index since it was right to fix an array index out of bounds exception. 62 | progress = 0; 63 | return true; 64 | } 65 | return false; 66 | } 67 | 68 | } 69 | 70 | public void checkAllCodes(int keyPressed) { 71 | // You put all other input comparisons in this function. 72 | boolean keyPressCompletedCode = CheatCode.KONAMI.keyPressCompletedCode(keyPressed); 73 | if (keyPressCompletedCode) { 74 | try { 75 | // SkiFree bitches. (Not using Utilities.launchBrowser() here 76 | // because it'd be ridiculous to throw a modal dialog in the 77 | // event of error, for something like this. 78 | URL skiFree = new URI("https://basicallydan.github.io/skifree.js/").toURL(); 79 | Desktop.getDesktop().browse(skiFree.toURI()); 80 | } catch (URISyntaxException | IOException | UnsupportedOperationException ex) { 81 | } 82 | } 83 | } 84 | 85 | } 86 | -------------------------------------------------------------------------------- /src/blcmm/gui/tree/rightmouse/AbstractCopyAction.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2020 LightChaosman 3 | * 4 | * OpenBLCMM is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see 16 | * 17 | */ 18 | package blcmm.gui.tree.rightmouse; 19 | 20 | import blcmm.gui.tree.CheckBoxTree; 21 | import blcmm.model.Category; 22 | import blcmm.model.ModelElement; 23 | import javax.swing.tree.DefaultMutableTreeNode; 24 | import javax.swing.tree.TreePath; 25 | 26 | /** 27 | * 28 | * @author LightChaosman 29 | */ 30 | abstract class AbstractCopyAction extends RightMouseButtonAction { 31 | 32 | private static TreePath[] pointerToLastCopiedPaths; 33 | private static boolean copiedElementContainsMUTElements; 34 | private static boolean oneTimeCopy = false; 35 | 36 | public static boolean isCut() { 37 | return oneTimeCopy; 38 | } 39 | 40 | public static void removePointers() { 41 | pointerToLastCopiedPaths = null; 42 | } 43 | 44 | public static TreePath[] getPointerToLastCopiedPaths() { 45 | return pointerToLastCopiedPaths; 46 | } 47 | 48 | public static boolean doCopiedElementContainsMUTElements() { 49 | return copiedElementContainsMUTElements; 50 | } 51 | 52 | private final boolean cut; 53 | 54 | AbstractCopyAction(CheckBoxTree tree, int hotkey, boolean ctrl, String name, boolean cut) { 55 | super(tree, name, hotkey, ctrl, new Requirements(false, cut, false)); 56 | this.cut = cut; 57 | } 58 | 59 | @Override 60 | public boolean couldBeEnabled() { 61 | 62 | // Require a single valid path 63 | TreePath[] paths = tree.getSelectionPaths(); 64 | if (paths == null) { 65 | return false; 66 | } 67 | if (paths.length == 0) { 68 | return false; 69 | } 70 | if (paths.length > 1) { 71 | TreePath parentPath = paths[0].getParentPath(); 72 | for (int i = 1; i < paths.length; i++) { 73 | if (paths[i].getParentPath() != parentPath) { 74 | return false; 75 | } 76 | } 77 | } 78 | return true; 79 | } 80 | 81 | @Override 82 | public void action() { 83 | TreePath[] paths = tree.getSelectionPaths(); 84 | pointerToLastCopiedPaths = paths; 85 | oneTimeCopy = cut; 86 | copiedElementContainsMUTElements = false; 87 | for (TreePath path : paths) { 88 | Object userObject = ((DefaultMutableTreeNode) path.getLastPathComponent()).getUserObject(); 89 | if (userObject instanceof Category) { 90 | copiedElementContainsMUTElements = copiedElementContainsMUTElements || containsMUT((Category) userObject); 91 | } 92 | } 93 | } 94 | 95 | private boolean containsMUT(Category category) { 96 | if (category.isMutuallyExclusive()) { 97 | return true; 98 | } 99 | for (ModelElement el : category.getElements()) { 100 | if (el instanceof Category && containsMUT((Category) el)) { 101 | return true; 102 | } 103 | } 104 | return false; 105 | } 106 | 107 | } 108 | -------------------------------------------------------------------------------- /src/blcmm/gui/tree/rightmouse/AddCategoryAction.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2020 LightChaosman 3 | * 4 | * OpenBLCMM is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see 16 | * 17 | */ 18 | package blcmm.gui.tree.rightmouse; 19 | 20 | import blcmm.gui.MainGUI; 21 | import blcmm.gui.components.AdHocDialog; 22 | import blcmm.gui.tree.CheckBoxTree; 23 | import blcmm.model.Category; 24 | import blcmm.model.ModelElement; 25 | import java.awt.Dimension; 26 | import javax.swing.tree.DefaultMutableTreeNode; 27 | import javax.swing.tree.TreePath; 28 | 29 | /** 30 | * Action to handle adding a new Category to a tree (as opposed to "introducing" 31 | * a Category on an already-existing entry. 32 | * 33 | * @author apocalyptech 34 | */ 35 | public class AddCategoryAction extends RightMouseButtonAction { 36 | 37 | public AddCategoryAction(CheckBoxTree tree, int hotkey, boolean ctrl) { 38 | super(tree, "Create new empty category", hotkey, ctrl, new Requirements(false, true, false)); 39 | } 40 | 41 | /** 42 | * Specifies whether this action can be taken. We must be selecting a single 43 | * category and have structural edits enabled. 44 | * 45 | * @return Whether or not to enable the action 46 | */ 47 | @Override 48 | public boolean couldBeEnabled() { 49 | TreePath[] paths = tree.getSelectionPaths(); 50 | if (paths == null 51 | || paths.length != 1) { 52 | return false; 53 | } 54 | TreePath path = paths[0]; 55 | DefaultMutableTreeNode node = (DefaultMutableTreeNode) path.getLastPathComponent(); 56 | return (node.getUserObject() instanceof Category); 57 | } 58 | 59 | /** 60 | * Actually perform the action. Will prompt user for the name of the new 61 | * category. 62 | */ 63 | @Override 64 | public void action() { 65 | 66 | // Grab some objects we'll need 67 | TreePath[] paths = tree.getSelectionPaths(); 68 | DefaultMutableTreeNode node = (DefaultMutableTreeNode) paths[0].getLastPathComponent(); 69 | ModelElement el = (ModelElement) node.getUserObject(); 70 | 71 | // This shouldn't ever happen on acconut of couldBeEnabled(), but 72 | // paranoia is a virtue. 73 | if (!(el instanceof Category)) { 74 | return; 75 | } 76 | 77 | // Ask user for the new category name and validate it. 78 | String name = AdHocDialog.askForString(MainGUI.INSTANCE, 79 | this.tree.getFontInfo(), 80 | AdHocDialog.IconType.QUESTION, 81 | "New Category Name", 82 | "New Category Name:", 83 | new Dimension(325, 100)); 84 | if (name == null || !this.isInputCategoryNameValid(name)) { 85 | return; 86 | } 87 | 88 | // Create a new category, make sure it's in the patch properly. 89 | Category newCategory = new Category(name); 90 | tree.getPatch().insertElementInto(newCategory, (Category) el); 91 | 92 | // If we happen to have created a new "mods" category off of the root 93 | // category, disable its transient statuses. 94 | if (newCategory.getParent() != null 95 | && newCategory.getParent().getParent() == null 96 | && name.equals("mods")) { 97 | newCategory.getTransientData().disableStatuses(); 98 | } 99 | 100 | // Cleanup 101 | refreshNode(node); 102 | tree.setChanged(true); 103 | 104 | } 105 | } 106 | -------------------------------------------------------------------------------- /src/blcmm/gui/tree/rightmouse/CheckMarkRightMouseButtonAction.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2020 LightChaosman 3 | * 4 | * OpenBLCMM is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see 16 | * 17 | */ 18 | package blcmm.gui.tree.rightmouse; 19 | 20 | import blcmm.gui.tree.CheckBoxTree; 21 | import javax.swing.JCheckBoxMenuItem; 22 | 23 | /** 24 | * 25 | * @author LightChaosman 26 | */ 27 | public abstract class CheckMarkRightMouseButtonAction extends RightMouseButtonAction { 28 | 29 | public CheckMarkRightMouseButtonAction(CheckBoxTree tree, String buttonName, boolean requiresUnlocked) { 30 | super(tree, new JCheckBoxMenuItem(buttonName), new Requirements(true, requiresUnlocked, false)); 31 | super.getButton().addActionListener(e -> action()); 32 | } 33 | 34 | public abstract void update(); 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/blcmm/gui/tree/rightmouse/CollapseCategoryCompletelyAction.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2020 LightChaosman 3 | * 4 | * OpenBLCMM is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see 16 | * 17 | */ 18 | package blcmm.gui.tree.rightmouse; 19 | 20 | import blcmm.gui.tree.CheckBoxTree; 21 | import blcmm.model.Category; 22 | import javax.swing.tree.DefaultMutableTreeNode; 23 | import javax.swing.tree.TreePath; 24 | 25 | /** 26 | * 27 | * @author LightChaosman 28 | */ 29 | public class CollapseCategoryCompletelyAction extends RightMouseButtonAction { 30 | 31 | public CollapseCategoryCompletelyAction(CheckBoxTree tree) { 32 | super(tree, "Fully collapse category", Requirements.NO_REQUIREMENTS); 33 | } 34 | 35 | @Override 36 | public boolean couldBeEnabled() { 37 | TreePath[] paths = tree.getSelectionPaths(); 38 | if (paths == null || paths.length != 1) { 39 | return false; 40 | } 41 | TreePath path = paths[0]; 42 | DefaultMutableTreeNode node = (DefaultMutableTreeNode) path.getLastPathComponent(); 43 | return node.getUserObject() instanceof Category; 44 | } 45 | 46 | @Override 47 | public void action() { 48 | TreePath[] paths = tree.getSelectionPaths(); 49 | for (TreePath path : paths) { 50 | collapse(path); 51 | } 52 | } 53 | 54 | private void collapse(TreePath path) { 55 | DefaultMutableTreeNode node = (DefaultMutableTreeNode) path.getLastPathComponent(); 56 | for (int i = 0; i < node.getChildCount(); i++) { 57 | collapse(path.pathByAddingChild(node.getChildAt(i))); 58 | } 59 | tree.collapsePath(path); 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /src/blcmm/gui/tree/rightmouse/CopyAction.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2020 LightChaosman 3 | * 4 | * OpenBLCMM is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see 16 | * 17 | */ 18 | package blcmm.gui.tree.rightmouse; 19 | 20 | import blcmm.gui.tree.CheckBoxTree; 21 | 22 | /** 23 | * 24 | * @author LightChaosman 25 | */ 26 | public class CopyAction extends AbstractCopyAction { 27 | 28 | public CopyAction(CheckBoxTree tree, int hotkey, boolean ctrl) { 29 | super(tree, hotkey, ctrl, "Copy", false); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/blcmm/gui/tree/rightmouse/CopyModListAction.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2020 LightChaosman 3 | * 4 | * OpenBLCMM is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see 16 | * 17 | */ 18 | package blcmm.gui.tree.rightmouse; 19 | 20 | import blcmm.gui.tree.CheckBoxTree; 21 | import blcmm.model.Category; 22 | import blcmm.model.ModelElement; 23 | import java.awt.Toolkit; 24 | import java.awt.datatransfer.Clipboard; 25 | import java.awt.datatransfer.StringSelection; 26 | import javax.swing.tree.DefaultMutableTreeNode; 27 | import javax.swing.tree.TreePath; 28 | 29 | /** 30 | * 31 | * @author LightChaosman 32 | */ 33 | public class CopyModListAction extends RightMouseButtonAction { 34 | 35 | public CopyModListAction(CheckBoxTree tree) { 36 | super(tree, "Copy modlist to clipboard", new Requirements(false, false, false)); 37 | } 38 | 39 | @Override 40 | public boolean couldBeEnabled() { 41 | TreePath[] paths = tree.getSelectionPaths(); 42 | if (paths == null) { 43 | return false; 44 | } 45 | if (paths.length != 1) { 46 | return false; 47 | } 48 | DefaultMutableTreeNode node = (DefaultMutableTreeNode) paths[0].getLastPathComponent(); 49 | return node.getUserObject() instanceof Category; 50 | } 51 | 52 | @Override 53 | public void action() { 54 | Category cat = (Category) ((DefaultMutableTreeNode) tree.getSelectionPaths()[0].getLastPathComponent()).getUserObject(); 55 | boolean first = true; 56 | StringBuilder sb = new StringBuilder(); 57 | for (ModelElement c : cat.getElements()) { 58 | if (c instanceof Category) { 59 | if (!first) { 60 | sb.append(", "); 61 | } 62 | first = false; 63 | sb.append(((Category) c).getName()); 64 | } 65 | } 66 | 67 | String myString = sb.toString(); 68 | StringSelection stringSelection = new StringSelection(myString); 69 | Clipboard clpbrd = Toolkit.getDefaultToolkit().getSystemClipboard(); 70 | clpbrd.setContents(stringSelection, null); 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /src/blcmm/gui/tree/rightmouse/CutAction.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2020 LightChaosman 3 | * 4 | * OpenBLCMM is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see 16 | * 17 | */ 18 | package blcmm.gui.tree.rightmouse; 19 | 20 | import blcmm.gui.tree.CheckBoxTree; 21 | 22 | /** 23 | * 24 | * @author LightChaosman 25 | */ 26 | public class CutAction extends AbstractCopyAction { 27 | 28 | public CutAction(CheckBoxTree tree, int hotkey, boolean ctrl) { 29 | super(tree, hotkey, ctrl, "Cut", true); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/blcmm/gui/tree/rightmouse/ExpandCategoryCompletelyAction.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2020 LightChaosman 3 | * 4 | * OpenBLCMM is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see 16 | * 17 | */ 18 | package blcmm.gui.tree.rightmouse; 19 | 20 | import blcmm.gui.tree.CheckBoxTree; 21 | import blcmm.model.Category; 22 | import javax.swing.tree.DefaultMutableTreeNode; 23 | import javax.swing.tree.TreePath; 24 | 25 | /** 26 | * 27 | * @author LightChaosman 28 | */ 29 | public class ExpandCategoryCompletelyAction extends RightMouseButtonAction { 30 | 31 | public ExpandCategoryCompletelyAction(CheckBoxTree tree) { 32 | super(tree, "Fully expand category", Requirements.NO_REQUIREMENTS); 33 | } 34 | 35 | @Override 36 | public boolean couldBeEnabled() { 37 | TreePath[] paths = tree.getSelectionPaths(); 38 | if (paths == null || paths.length != 1) { 39 | return false; 40 | } 41 | TreePath path = paths[0]; 42 | DefaultMutableTreeNode node = (DefaultMutableTreeNode) path.getLastPathComponent(); 43 | return node.getUserObject() instanceof Category; 44 | } 45 | 46 | @Override 47 | public void action() { 48 | TreePath[] paths = tree.getSelectionPaths(); 49 | for (TreePath path : paths) { 50 | expand(path); 51 | } 52 | } 53 | 54 | private void expand(TreePath path) { 55 | DefaultMutableTreeNode node = (DefaultMutableTreeNode) path.getLastPathComponent(); 56 | tree.expandPath(path); 57 | for (int i = 0; i < node.getChildCount(); i++) { 58 | expand(path.pathByAddingChild(node.getChildAt(i))); 59 | } 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /src/blcmm/gui/tree/rightmouse/ExportCategoryAsModAction.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2020 LightChaosman 3 | * 4 | * OpenBLCMM is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see 16 | * 17 | */ 18 | package blcmm.gui.tree.rightmouse; 19 | 20 | import blcmm.gui.MainGUI; 21 | import blcmm.gui.components.BLCMM_FileChooser; 22 | import blcmm.gui.tree.CheckBoxTree; 23 | import blcmm.model.Category; 24 | import blcmm.model.CompletePatch; 25 | import java.io.File; 26 | import javax.swing.tree.DefaultMutableTreeNode; 27 | import javax.swing.tree.TreePath; 28 | 29 | /** 30 | * 31 | * @author LightChaosman 32 | */ 33 | public class ExportCategoryAsModAction extends RightMouseButtonAction { 34 | 35 | public ExportCategoryAsModAction(CheckBoxTree tree) { 36 | super(tree, "Export category as mod", Requirements.NO_REQUIREMENTS); 37 | } 38 | 39 | @Override 40 | public boolean couldBeEnabled() { 41 | TreePath[] paths = tree.getSelectionPaths(); 42 | if (paths == null || paths.length != 1) { 43 | return false; 44 | } 45 | TreePath path = paths[0]; 46 | DefaultMutableTreeNode node = (DefaultMutableTreeNode) path.getLastPathComponent(); 47 | return node.getUserObject() instanceof Category; 48 | } 49 | 50 | @Override 51 | public void action() { 52 | tree.resetCheckingState(); 53 | Category c = (Category) ((DefaultMutableTreeNode) tree.getSelectionPaths()[0].getLastPathComponent()).getUserObject(); 54 | BLCMM_FileChooser fc = new BLCMM_FileChooser(this.tree.getFontInfo(), MainGUI.INSTANCE.getExportDialogPath(), c.getName(), true, true); 55 | int returnVal = fc.showSaveDialog(MainGUI.INSTANCE); 56 | if (returnVal == BLCMM_FileChooser.APPROVE_OPTION) { 57 | File file = fc.getSelectedFile(); 58 | MainGUI.INSTANCE.setExportDialogPath(file.getAbsoluteFile().getParentFile()); 59 | CompletePatch completePatch = new CompletePatch(); 60 | completePatch.setRoot(c); 61 | completePatch.setType(tree.getPatch().getType()); 62 | MainGUI.INSTANCE.savePatch(completePatch, file, true); 63 | MainGUI.INSTANCE.getTimedLabel().showTemporary( 64 | "Exported category to " + file.getName() + ""); 65 | } 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /src/blcmm/gui/tree/rightmouse/GoToCompleteOverwrittenAction.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2020 LightChaosman 3 | * 4 | * OpenBLCMM is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see 16 | * 17 | */ 18 | package blcmm.gui.tree.rightmouse; 19 | 20 | import blcmm.gui.tree.CheckBoxTree; 21 | import blcmm.gui.tree.OverwriteChecker; 22 | import blcmm.model.ModelElement; 23 | import blcmm.model.SetCommand; 24 | import blcmm.model.TransientModelData; 25 | import blcmm.utilities.GlobalLogger; 26 | import java.util.List; 27 | import javax.swing.tree.DefaultMutableTreeNode; 28 | import javax.swing.tree.TreePath; 29 | 30 | /** 31 | * 32 | * @author LightChaosman 33 | */ 34 | public class GoToCompleteOverwrittenAction extends RightMouseButtonAction { 35 | 36 | public GoToCompleteOverwrittenAction(CheckBoxTree tree) { 37 | super(tree, "Go to overwritten statement", Requirements.NO_REQUIREMENTS); 38 | } 39 | 40 | @Override 41 | public boolean couldBeEnabled() { 42 | TreePath[] paths = tree.getSelectionPaths(); 43 | if (paths == null) { 44 | return false; 45 | } 46 | if (paths.length != 1) { 47 | return false; 48 | } 49 | TreePath path = paths[0]; 50 | DefaultMutableTreeNode node = (DefaultMutableTreeNode) path.getLastPathComponent(); 51 | ModelElement element = (ModelElement) node.getUserObject(); 52 | if (!(element instanceof SetCommand)) { 53 | return false; 54 | } 55 | if (element.getTransientData().getOverwriteState() != TransientModelData.OverwriteState.Overwriter) { 56 | return false; 57 | } 58 | return true; 59 | } 60 | 61 | @Override 62 | public void action() { 63 | TreePath[] paths = tree.getSelectionPaths(); 64 | TreePath firstPath = paths[0]; 65 | DefaultMutableTreeNode firstSelectedNode = (DefaultMutableTreeNode) firstPath.getLastPathComponent(); 66 | SetCommand command = (SetCommand) firstSelectedNode.getUserObject(); 67 | List completeOverwrittens = OverwriteChecker.getCompleteOverwrittens(command); 68 | if (completeOverwrittens.size() > 0) { 69 | SetCommand s = completeOverwrittens.get(completeOverwrittens.size() - 1); 70 | DefaultMutableTreeNode root = (DefaultMutableTreeNode) tree.getModel().getRoot(); 71 | DefaultMutableTreeNode nodeToExpand = scan(root, s); 72 | TreePath path = new TreePath(nodeToExpand.getPath()); 73 | tree.expandPath(path.getParentPath()); 74 | tree.setSelectionPath(path); 75 | tree.scrollPathToVisible(path); 76 | } else { 77 | GlobalLogger.log("ERROR: Could not find overwritten statement for: " + command.toString()); 78 | } 79 | } 80 | 81 | private DefaultMutableTreeNode scan(DefaultMutableTreeNode root, final SetCommand command) { 82 | if (root.getUserObject() == command) { 83 | return root; 84 | } 85 | for (int i = 0; i < root.getChildCount(); i++) { 86 | DefaultMutableTreeNode res = scan((DefaultMutableTreeNode) root.getChildAt(i), command); 87 | if (res != null) { 88 | return res; 89 | } 90 | } 91 | return null; 92 | } 93 | 94 | } 95 | -------------------------------------------------------------------------------- /src/blcmm/gui/tree/rightmouse/GoToOverwriterAction.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2020 LightChaosman 3 | * 4 | * OpenBLCMM is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see 16 | * 17 | */ 18 | package blcmm.gui.tree.rightmouse; 19 | 20 | import blcmm.gui.tree.CheckBoxTree; 21 | import blcmm.gui.tree.OverwriteChecker; 22 | import blcmm.model.ModelElement; 23 | import blcmm.model.SetCommand; 24 | import blcmm.model.TransientModelData; 25 | import blcmm.utilities.GlobalLogger; 26 | import java.util.List; 27 | import javax.swing.tree.DefaultMutableTreeNode; 28 | import javax.swing.tree.TreePath; 29 | 30 | /** 31 | * 32 | * @author LightChaosman 33 | */ 34 | public class GoToOverwriterAction extends RightMouseButtonAction { 35 | 36 | public GoToOverwriterAction(CheckBoxTree tree) { 37 | super(tree, "Go to overwriter", Requirements.NO_REQUIREMENTS); 38 | } 39 | 40 | @Override 41 | public boolean couldBeEnabled() { 42 | TreePath[] paths = tree.getSelectionPaths(); 43 | if (paths == null) { 44 | return false; 45 | } 46 | if (paths.length != 1) { 47 | return false; 48 | } 49 | TreePath path = paths[0]; 50 | DefaultMutableTreeNode node = (DefaultMutableTreeNode) path.getLastPathComponent(); 51 | ModelElement element = (ModelElement) node.getUserObject(); 52 | if (!(element instanceof SetCommand)) { 53 | return false; 54 | } 55 | if (element.getTransientData().getOverwriteState() != TransientModelData.OverwriteState.Overwritten) { 56 | return false; 57 | } 58 | return true; 59 | } 60 | 61 | @Override 62 | public void action() { 63 | TreePath[] paths = tree.getSelectionPaths(); 64 | TreePath firstPath = paths[0]; 65 | DefaultMutableTreeNode firstSelectedNode = (DefaultMutableTreeNode) firstPath.getLastPathComponent(); 66 | SetCommand command = (SetCommand) firstSelectedNode.getUserObject(); 67 | List completeOverwriters = OverwriteChecker.getCompleteOverwriters(command); 68 | if (completeOverwriters.size() > 0) { 69 | DefaultMutableTreeNode root = (DefaultMutableTreeNode) tree.getModel().getRoot(); 70 | SetCommand s = completeOverwriters.get(completeOverwriters.size() - 1); 71 | DefaultMutableTreeNode nodeToExpand = scan(root, s); 72 | TreePath path = new TreePath(nodeToExpand.getPath()); 73 | tree.expandPath(path.getParentPath()); 74 | tree.setSelectionPath(path); 75 | tree.scrollPathToVisible(path); 76 | } else { 77 | GlobalLogger.log("ERROR: Could not find overwriter statement for: " + command.toString()); 78 | } 79 | } 80 | 81 | private DefaultMutableTreeNode scan(DefaultMutableTreeNode root, final SetCommand command) { 82 | if (root.getUserObject() == command) { 83 | return root; 84 | } 85 | for (int i = 0; i < root.getChildCount(); i++) { 86 | DefaultMutableTreeNode res = scan((DefaultMutableTreeNode) root.getChildAt(i), command); 87 | if (res != null) { 88 | return res; 89 | } 90 | } 91 | return null; 92 | } 93 | 94 | } 95 | -------------------------------------------------------------------------------- /src/blcmm/gui/tree/rightmouse/GoToPartialOverwrittenAction.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2020 LightChaosman 3 | * 4 | * OpenBLCMM is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see 16 | * 17 | */ 18 | package blcmm.gui.tree.rightmouse; 19 | 20 | import blcmm.gui.tree.CheckBoxTree; 21 | import blcmm.gui.tree.OverwriteChecker; 22 | import blcmm.model.ModelElement; 23 | import blcmm.model.SetCommand; 24 | import blcmm.model.TransientModelData; 25 | import blcmm.utilities.GlobalLogger; 26 | import java.util.List; 27 | import javax.swing.tree.DefaultMutableTreeNode; 28 | import javax.swing.tree.TreePath; 29 | 30 | /** 31 | * 32 | * @author LightChaosman 33 | */ 34 | public class GoToPartialOverwrittenAction extends RightMouseButtonAction { 35 | 36 | public GoToPartialOverwrittenAction(CheckBoxTree tree) { 37 | super(tree, "Go to partially overwritten statement", Requirements.NO_REQUIREMENTS); 38 | } 39 | 40 | @Override 41 | public boolean couldBeEnabled() { 42 | TreePath[] paths = tree.getSelectionPaths(); 43 | if (paths == null) { 44 | return false; 45 | } 46 | if (paths.length != 1) { 47 | return false; 48 | } 49 | TreePath path = paths[0]; 50 | DefaultMutableTreeNode node = (DefaultMutableTreeNode) path.getLastPathComponent(); 51 | ModelElement element = (ModelElement) node.getUserObject(); 52 | if (!(element instanceof SetCommand)) { 53 | return false; 54 | } 55 | if (element.getTransientData().getOverwriteState() != TransientModelData.OverwriteState.PartialOverwriter) { 56 | return false; 57 | } 58 | return true; 59 | } 60 | 61 | @Override 62 | public void action() { 63 | TreePath[] paths = tree.getSelectionPaths(); 64 | TreePath firstPath = paths[0]; 65 | DefaultMutableTreeNode firstSelectedNode = (DefaultMutableTreeNode) firstPath.getLastPathComponent(); 66 | SetCommand command = (SetCommand) firstSelectedNode.getUserObject(); 67 | List partialOverwrittens = OverwriteChecker.getPartialOverwrittens(command); 68 | if (partialOverwrittens.size() > 0) { 69 | SetCommand s = partialOverwrittens.get(partialOverwrittens.size() - 1); 70 | DefaultMutableTreeNode root = (DefaultMutableTreeNode) tree.getModel().getRoot(); 71 | DefaultMutableTreeNode nodeToExpand = scan(root, s); 72 | TreePath path = new TreePath(nodeToExpand.getPath()); 73 | tree.expandPath(path.getParentPath()); 74 | tree.setSelectionPath(path); 75 | tree.scrollPathToVisible(path); 76 | } else { 77 | GlobalLogger.log("ERROR: Could not find partially-overwritten statement for: " + command.toString()); 78 | } 79 | } 80 | 81 | private DefaultMutableTreeNode scan(DefaultMutableTreeNode root, final SetCommand command) { 82 | if (root.getUserObject() == command) { 83 | return root; 84 | } 85 | for (int i = 0; i < root.getChildCount(); i++) { 86 | DefaultMutableTreeNode res = scan((DefaultMutableTreeNode) root.getChildAt(i), command); 87 | if (res != null) { 88 | return res; 89 | } 90 | } 91 | return null; 92 | } 93 | 94 | } 95 | -------------------------------------------------------------------------------- /src/blcmm/gui/tree/rightmouse/InsertAction.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2020 LightChaosman 3 | * 4 | * OpenBLCMM is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see 16 | * 17 | */ 18 | package blcmm.gui.tree.rightmouse; 19 | 20 | import blcmm.gui.MainGUI; 21 | import blcmm.gui.panels.EditPanel; 22 | import blcmm.gui.tree.CheckBoxTree; 23 | import blcmm.model.Category; 24 | import java.awt.Dimension; 25 | import java.awt.event.ActionEvent; 26 | import javax.swing.tree.DefaultMutableTreeNode; 27 | import javax.swing.tree.TreePath; 28 | 29 | /** 30 | * 31 | * @author LightChaosman 32 | */ 33 | public class InsertAction extends RightMouseButtonAction { 34 | 35 | public InsertAction(CheckBoxTree tree, int hotkey, boolean ctrl) { 36 | super(tree, "Insert", hotkey, ctrl, new Requirements(true, true, true)); 37 | } 38 | 39 | @Override 40 | public boolean couldBeEnabled() { 41 | TreePath[] paths = tree.getSelectionPaths(); 42 | if (paths == null || paths.length != 1) { 43 | return false; 44 | } 45 | TreePath path = paths[0]; 46 | DefaultMutableTreeNode node = (DefaultMutableTreeNode) path.getLastPathComponent(); 47 | 48 | // Disallow inserting commands directly into a MUT category 49 | if (node.getUserObject() instanceof Category 50 | && ((Category) node.getUserObject()).isMutuallyExclusive()) { 51 | return false; 52 | } 53 | 54 | return true; 55 | 56 | } 57 | 58 | @Override 59 | public void action() { 60 | TreePath[] paths = tree.getSelectionPaths(); 61 | DefaultMutableTreeNode selectednode = (DefaultMutableTreeNode) paths[0].getLastPathComponent(); 62 | int insertIndex; 63 | Category parentCategory; 64 | DefaultMutableTreeNode parentnode; 65 | if (selectednode.getUserObject() instanceof Category) { 66 | parentnode = selectednode; 67 | parentCategory = (Category) parentnode.getUserObject(); 68 | insertIndex = parentnode.getChildCount(); 69 | } else { 70 | parentnode = (DefaultMutableTreeNode) selectednode.getParent(); 71 | parentCategory = (Category) parentnode.getUserObject(); 72 | insertIndex = parentnode.getIndex(selectednode) + 1; 73 | } 74 | EditPanel panel = new EditPanel(tree.getPatch(), parentCategory, this.tree.getFontInfo()); 75 | // I'm actually *not* going to Utilities.scaleAndClampDialogSize() these 76 | // dimensions, since they're based on the main window size. Presumably 77 | // users would already have that sized appropriately to their font 78 | // scaling. 79 | panel.setPreferredSize(new Dimension(MainGUI.INSTANCE.getWidth() - 125, MainGUI.INSTANCE.getHeight() - 150)); 80 | 81 | showCustomDialog(panel, (ActionEvent e) -> { 82 | addNewElements(panel, 83 | parentCategory, 84 | insertIndex, 85 | parentnode, 86 | tree.isSelected(parentnode)); 87 | }, true); 88 | } 89 | 90 | } 91 | -------------------------------------------------------------------------------- /src/blcmm/gui/tree/rightmouse/IntroduceCategoryAction.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2020 LightChaosman 3 | * 4 | * OpenBLCMM is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see 16 | * 17 | */ 18 | package blcmm.gui.tree.rightmouse; 19 | 20 | import blcmm.gui.MainGUI; 21 | import blcmm.gui.components.AdHocDialog; 22 | import blcmm.gui.tree.CheckBoxTree; 23 | import blcmm.model.Category; 24 | import blcmm.model.ModelElement; 25 | import java.awt.Dimension; 26 | import java.util.ArrayList; 27 | import javax.swing.tree.DefaultMutableTreeNode; 28 | import javax.swing.tree.TreePath; 29 | 30 | /** 31 | * 32 | * @author LightChaosman 33 | */ 34 | public class IntroduceCategoryAction extends RightMouseButtonAction { 35 | 36 | public IntroduceCategoryAction(CheckBoxTree tree, int hotkey, boolean ctrl) { 37 | super(tree, "Wrap in new category", hotkey, ctrl, new Requirements(false, true, false)); 38 | } 39 | 40 | @Override 41 | public boolean couldBeEnabled() { 42 | TreePath[] paths = tree.getSelectionPaths(); 43 | if (paths == null) { 44 | return false; 45 | } 46 | boolean allSameLevel = true; 47 | int level1 = paths[0].getPathCount(); 48 | for (TreePath path : paths) { 49 | allSameLevel = allSameLevel && path.getPathCount() == level1; 50 | } 51 | return allSameLevel && level1 > 1; 52 | } 53 | 54 | @Override 55 | public void action() { 56 | String name = AdHocDialog.askForString(MainGUI.INSTANCE, 57 | this.tree.getFontInfo(), 58 | AdHocDialog.IconType.QUESTION, 59 | "Insert Category Name", 60 | "Category Name", 61 | new Dimension(325, 100)); 62 | if (name == null) { 63 | return; 64 | } 65 | if (!this.isInputCategoryNameValid(name)) { 66 | return; 67 | } 68 | TreePath[] paths = tree.getSelectionPaths(); 69 | DefaultMutableTreeNode parentNode = (DefaultMutableTreeNode) paths[0].getParentPath().getLastPathComponent(); 70 | 71 | //remove old tree nodes 72 | tree.removeNodesFromTheirParents(paths); 73 | 74 | //change it in the model 75 | ArrayList elements = new ArrayList<>(); 76 | for (TreePath path : paths) { 77 | elements.add((ModelElement) ((DefaultMutableTreeNode) path.getLastPathComponent()).getUserObject()); 78 | } 79 | Category newCategory = tree.getPatch().introduceCategoryAsParentOfElements(elements, name); 80 | 81 | // If we happen to have created a new "mods" category off of the root 82 | // category, disable its transient statuses. 83 | if (newCategory.getParent() != null 84 | && newCategory.getParent().getParent() == null 85 | && name.equals("mods")) { 86 | newCategory.getTransientData().disableStatuses(); 87 | } 88 | 89 | // Cleanup. 90 | refreshNode(parentNode); 91 | tree.setChanged(true); 92 | } 93 | 94 | } 95 | -------------------------------------------------------------------------------- /src/blcmm/gui/tree/rightmouse/LockAction.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2020 LightChaosman 3 | * 4 | * OpenBLCMM is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see 16 | * 17 | */ 18 | package blcmm.gui.tree.rightmouse; 19 | 20 | import blcmm.gui.tree.CheckBoxTree; 21 | import blcmm.model.Category; 22 | import blcmm.model.ModelElement; 23 | import blcmm.model.ModelElementContainer; 24 | import javax.swing.JCheckBoxMenuItem; 25 | import javax.swing.tree.DefaultMutableTreeNode; 26 | import javax.swing.tree.DefaultTreeModel; 27 | import javax.swing.tree.TreePath; 28 | 29 | /** 30 | * 31 | * @author LightChaosman 32 | */ 33 | public class LockAction extends CheckMarkRightMouseButtonAction { 34 | 35 | public LockAction(CheckBoxTree tree) { 36 | // We set false for requiresUnlocked because we're allowed to change 37 | // this when WE are locked, just not when ancestors are locked, so 38 | // we do so in a custom way in couldBeEnabled(), below. 39 | super(tree, "Lock category", false); 40 | } 41 | 42 | @Override 43 | public void update() { 44 | TreePath[] paths = tree.getSelectionPaths(); 45 | DefaultMutableTreeNode node = (DefaultMutableTreeNode) paths[0].getLastPathComponent(); 46 | Category cat = (Category) node.getUserObject(); 47 | ((JCheckBoxMenuItem) getButton()).setSelected(cat.isLocked()); 48 | } 49 | 50 | @Override 51 | public boolean couldBeEnabled() { 52 | TreePath[] paths = tree.getSelectionPaths(); 53 | if (paths == null || paths.length != 1) { 54 | return false; 55 | } 56 | DefaultMutableTreeNode node = (DefaultMutableTreeNode) paths[0].getLastPathComponent(); 57 | if (!(node.getUserObject() instanceof Category)) { 58 | return false; 59 | } 60 | 61 | // It's okay to activate if WE are the locked element, but not if any 62 | // ancestor is locked. 63 | ModelElementContainer parent = ((ModelElement) node.getUserObject()).getParent(); 64 | if (parent != null && parent.hasLockedAncestor()) { 65 | return false; 66 | } 67 | 68 | return true; 69 | } 70 | 71 | @Override 72 | public void action() { 73 | TreePath[] paths = tree.getSelectionPaths(); 74 | TreePath path = paths[0]; 75 | DefaultMutableTreeNode node = (DefaultMutableTreeNode) path.getLastPathComponent(); 76 | Category cat = (Category) node.getUserObject(); 77 | boolean newMode = ((JCheckBoxMenuItem) getButton()).isSelected(); 78 | cat.setLocked(newMode); 79 | ((DefaultTreeModel) tree.getModel()).nodeStructureChanged(node); 80 | tree.setChanged(true); 81 | } 82 | 83 | } 84 | -------------------------------------------------------------------------------- /src/blcmm/gui/tree/rightmouse/RenameCategoryAction.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2020 LightChaosman 3 | * 4 | * OpenBLCMM is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see 16 | * 17 | */ 18 | package blcmm.gui.tree.rightmouse; 19 | 20 | import blcmm.gui.MainGUI; 21 | import blcmm.gui.components.AdHocDialog; 22 | import blcmm.gui.tree.CheckBoxTree; 23 | import blcmm.model.Category; 24 | import java.awt.Dimension; 25 | import javax.swing.tree.DefaultMutableTreeNode; 26 | import javax.swing.tree.DefaultTreeModel; 27 | import javax.swing.tree.TreePath; 28 | 29 | /** 30 | * 31 | * @author LightChaosman 32 | */ 33 | public class RenameCategoryAction extends RightMouseButtonAction { 34 | 35 | public RenameCategoryAction(CheckBoxTree tree, int hotkey, boolean ctrl) { 36 | super(tree, "Rename category", hotkey, ctrl, new Requirements(false, true, false)); 37 | 38 | } 39 | 40 | @Override 41 | public boolean couldBeEnabled() { 42 | TreePath[] paths = tree.getSelectionPaths(); 43 | if (paths == null) { 44 | return false; 45 | } 46 | return paths.length == 1 && ((DefaultMutableTreeNode) paths[0].getLastPathComponent()).getUserObject() instanceof Category; 47 | } 48 | 49 | @Override 50 | public void action() { 51 | TreePath[] paths = tree.getSelectionPaths(); 52 | TreePath path = paths[0]; 53 | DefaultMutableTreeNode node = (DefaultMutableTreeNode) path.getLastPathComponent(); 54 | String name = AdHocDialog.askForString(MainGUI.INSTANCE, 55 | this.tree.getFontInfo(), 56 | AdHocDialog.IconType.QUESTION, 57 | "New Category Name", 58 | "New Category Name", 59 | new Dimension(325, 100), 60 | node.toString()); 61 | if (name == null) { 62 | return; 63 | } 64 | if (!this.isInputCategoryNameValid(name)) { 65 | return; 66 | } 67 | Category cat = (Category) node.getUserObject(); 68 | cat.setName(name); 69 | ((DefaultTreeModel) tree.getModel()).nodeChanged(node); 70 | tree.setChanged(true); 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /src/blcmm/gui/tree/rightmouse/SortCategoryAction.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2020 LightChaosman 3 | * 4 | * OpenBLCMM is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see 16 | * 17 | */ 18 | package blcmm.gui.tree.rightmouse; 19 | 20 | import blcmm.gui.tree.CheckBoxTree; 21 | import blcmm.model.Category; 22 | import java.util.ArrayList; 23 | import java.util.List; 24 | import javax.swing.tree.DefaultMutableTreeNode; 25 | import javax.swing.tree.DefaultTreeModel; 26 | import javax.swing.tree.TreePath; 27 | 28 | /** 29 | * 30 | * @author LightChaosman 31 | */ 32 | public class SortCategoryAction extends RightMouseButtonAction { 33 | 34 | public SortCategoryAction(CheckBoxTree tree) { 35 | super(tree, "Sort", new Requirements(false, true, false)); 36 | } 37 | 38 | @Override 39 | public boolean couldBeEnabled() { 40 | TreePath[] paths = tree.getSelectionPaths(); 41 | if (paths == null) { 42 | return false; 43 | } 44 | if (paths.length != 1) { 45 | return false; 46 | } 47 | TreePath path = paths[0]; 48 | DefaultMutableTreeNode node = (DefaultMutableTreeNode) path.getLastPathComponent(); 49 | return node.getUserObject() instanceof Category; 50 | } 51 | 52 | @Override 53 | public void action() { 54 | TreePath[] paths = tree.getSelectionPaths(); 55 | TreePath path = paths[0]; 56 | DefaultMutableTreeNode node = (DefaultMutableTreeNode) path.getLastPathComponent(); 57 | List children = new ArrayList<>(); 58 | for (int i = 0; i < node.getChildCount(); i++) { 59 | children.add((DefaultMutableTreeNode) node.getChildAt(i)); 60 | } 61 | Category cat = (Category) node.getUserObject(); 62 | cat.sort(); 63 | DefaultMutableTreeNode clone = CheckBoxTree.createTree(cat); 64 | node.removeAllChildren(); 65 | for (int i = 0; i < children.size(); i++) { 66 | node.insert((DefaultMutableTreeNode) clone.getChildAt(0), i); 67 | } 68 | DefaultTreeModel model = (DefaultTreeModel) tree.getModel(); 69 | model.nodeStructureChanged(node); 70 | tree.setChanged(true); 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /src/blcmm/model/Comment.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2020 LightChaosman 3 | * 4 | * OpenBLCMM is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see 16 | * 17 | */ 18 | package blcmm.model; 19 | 20 | /** 21 | * 22 | * @author LightChaosman 23 | */ 24 | public class Comment extends ModelElement { 25 | 26 | private final String comment; 27 | 28 | public Comment(String comment) { 29 | assert !SetCommand.isValidCommand(comment); 30 | this.comment = comment; 31 | this.transientData = new TransientModelData(this); 32 | } 33 | 34 | @Override 35 | public Category getParent() { 36 | return (Category) super.getParent(); 37 | } 38 | 39 | @Override 40 | protected String toXMLString() { 41 | return String.format("%s", comment); 42 | } 43 | 44 | @Override 45 | public String toString() { 46 | return comment; 47 | } 48 | 49 | @Override 50 | public Comment copy() { 51 | Comment copy = new Comment(comment); 52 | return copy; 53 | } 54 | 55 | public String getComment() { 56 | return comment; 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /src/blcmm/model/EnableableModelElement.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2020 LightChaosman 3 | * 4 | * OpenBLCMM is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see 16 | * 17 | */ 18 | package blcmm.model; 19 | 20 | import blcmm.model.properties.GlobalListOfProperties; 21 | import java.util.Collection; 22 | import java.util.HashSet; 23 | 24 | /** 25 | * 26 | * @author LightChaosman 27 | */ 28 | abstract class EnableableModelElement extends ModelElement { 29 | 30 | private final HashSet onInProfiles = new HashSet<>(); 31 | private boolean selected = false; 32 | 33 | /** 34 | * Returns whether this code is selected. 35 | * 36 | * @return 37 | */ 38 | public boolean isSelected() { 39 | return selected; 40 | } 41 | 42 | final void turnOnInProfile(Profile p) { 43 | if (p == null) { 44 | throw new NullPointerException(); 45 | } 46 | this.onInProfiles.add(p); 47 | } 48 | 49 | final void turnOffInProfile(Profile p) { 50 | if (p == null) { 51 | throw new NullPointerException(); 52 | } 53 | this.onInProfiles.remove(p); 54 | } 55 | 56 | protected final void copyProfilesAndSelectedFrom(EnableableModelElement el) { 57 | onInProfiles.clear(); 58 | onInProfiles.addAll(el.onInProfiles); 59 | selected = el.selected; 60 | transientData.updateByChangingOwnProperty(GlobalListOfProperties.CLASS_TO_INSTANCE_MAP.get(GlobalListOfProperties.LeafSelectedChecker.class).get(0)); 61 | } 62 | 63 | final void profileChanged(Profile p) { 64 | if (p == null) { 65 | throw new NullPointerException(); 66 | } 67 | this.selected = onInProfiles.contains(p); 68 | transientData.updateByChangingOwnProperty(GlobalListOfProperties.CLASS_TO_INSTANCE_MAP.get(GlobalListOfProperties.LeafSelectedChecker.class).get(0)); 69 | } 70 | 71 | protected final String getProfileString() { 72 | StringBuilder sb = new StringBuilder(); 73 | sb.append("profiles=\""); 74 | boolean first = true; 75 | for (Profile prof : onInProfiles) { 76 | if (!first) { 77 | sb.append(","); 78 | } 79 | sb.append(prof.getName()); 80 | first = false; 81 | } 82 | sb.append("\""); 83 | return sb.toString(); 84 | } 85 | 86 | final Collection getProfiles() { 87 | return onInProfiles; 88 | } 89 | 90 | } 91 | -------------------------------------------------------------------------------- /src/blcmm/model/HotfixCommand.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2020 LightChaosman 3 | * Copyright (C) 2023 Christopher J. Kucera 4 | * 5 | * OpenBLCMM is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see 17 | * 18 | */ 19 | package blcmm.model; 20 | 21 | /** 22 | * Instead of putting a boolean inside the setCommand class, we use a subclass 23 | * with no added functionality. This has the benefit of compile-time error 24 | * detection. 25 | * 26 | * Marking set commands as hotfix themselves, rather than inferring that from 27 | * their parent, makes the transient data management significantly easier, since 28 | * we don't need to update when switching parents, and then keep that in mind 29 | * when we add the current element to a new container, usually as the very next 30 | * model change. Now we can simply update everything when a child array changes, 31 | * at which point we already have a guaranteed correct parent. 32 | * 33 | * @author LightChaosman 34 | */ 35 | public class HotfixCommand extends SetCommand { 36 | 37 | public HotfixCommand(String object, String field, String value) { 38 | super(object, field, value); 39 | } 40 | 41 | public HotfixCommand(String command) { 42 | super(command); 43 | } 44 | 45 | protected HotfixCommand(String object, String field, String value, boolean initTransient) { 46 | super(object, field, value, initTransient); 47 | } 48 | 49 | public HotfixCommand(SetCommand command) { 50 | super(command.getCode()); 51 | } 52 | 53 | @Override 54 | protected HotfixCommand getBaseCopy() { 55 | return new HotfixCommand(object, field, value); 56 | } 57 | 58 | @Override 59 | void setParent(ModelElementContainer newParent) { 60 | if (newParent != null && !(newParent instanceof HotfixWrapper)) { 61 | throw new IllegalArgumentException(); 62 | } 63 | super.setParent(newParent); 64 | } 65 | 66 | @Override 67 | public HotfixWrapper getParent() { 68 | return (HotfixWrapper) super.getParent(); 69 | } 70 | 71 | /** 72 | * Returns the "raw" hotfix format actually used by Gearbox hotfixes. 73 | * @return The raw hotfix format 74 | */ 75 | public String toRawHotfixFormat() { 76 | return this.toRawHotfixFormat(""); 77 | } 78 | 79 | /** 80 | * Returns the "raw" hotfix format actually used by Gearbox hotfixes, 81 | * with support for a previous value (used by our `set_cmp` syntax). 82 | * 83 | * @param previous The previous value, for set_cmp hotfixes 84 | * @return The raw hotfix format 85 | */ 86 | public String toRawHotfixFormat(String previous) { 87 | HotfixWrapper wrapper = (HotfixWrapper)this.getParent(); 88 | switch (wrapper.getType()) { 89 | case PATCH: 90 | return this.object 91 | + "," + this.field 92 | + "," + previous 93 | + "," + this.value; 94 | 95 | default: 96 | return wrapper.getRawParameter() 97 | + "," + this.object 98 | + "," + this.field 99 | + "," + previous 100 | + "," + this.value; 101 | } 102 | } 103 | 104 | } 105 | -------------------------------------------------------------------------------- /src/blcmm/model/HotfixType.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2023 Christopher J. Kucera 3 | * 4 | * 5 | * 6 | * OpenBLCMM is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see 18 | * 19 | */ 20 | 21 | package blcmm.model; 22 | 23 | import java.util.HashMap; 24 | 25 | /** 26 | * Enum to describe the hotfix types available for OpenBLCMM. This class was 27 | * reimplemented based on the calls BLCMM made into BLCMM_Utilities.jar, 28 | * without reference to the original sourcecode. 29 | * 30 | * @author apocalyptech 31 | */ 32 | public enum HotfixType { 33 | 34 | // Enum members 35 | PATCH("SparkPatchEntry"), 36 | LEVEL("SparkLevelPatchEntry"), 37 | ONDEMAND("SparkOnDemandPatchEntry"); 38 | 39 | /** 40 | * Convenience var to provide a mapping of hotfix prefixes to type 41 | */ 42 | private static final HashMap PREFIX_MAP; 43 | 44 | static { 45 | PREFIX_MAP = new HashMap<>(); 46 | for (HotfixType type : HotfixType.values()) { 47 | PREFIX_MAP.put(type.getPrefix().toLowerCase(), type); 48 | } 49 | } 50 | 51 | private final String hotfixPrefix; 52 | 53 | private HotfixType(String hotfixPrefix) { 54 | this.hotfixPrefix = hotfixPrefix; 55 | } 56 | 57 | public String getPrefix() { 58 | return this.hotfixPrefix; 59 | } 60 | 61 | /** 62 | * Given a hotfix key prefix, return the correct HotfixType if possible. 63 | * 64 | * @param prefix The key prefix 65 | * @return The HotfixType matching that prefix 66 | */ 67 | public static HotfixType getByPrefix(String prefix) { 68 | String prefix_lower = prefix.toLowerCase(); 69 | if (PREFIX_MAP.containsKey(prefix_lower)) { 70 | return PREFIX_MAP.get(prefix_lower); 71 | } else { 72 | return null; 73 | } 74 | } 75 | 76 | } 77 | -------------------------------------------------------------------------------- /src/blcmm/model/Profile.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2020 LightChaosman 3 | * 4 | * OpenBLCMM is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see 16 | * 17 | */ 18 | package blcmm.model; 19 | 20 | /** 21 | * 22 | * @author LightChaosman 23 | */ 24 | public class Profile { 25 | 26 | private String name; 27 | 28 | Profile(String name) { 29 | this.name = name; 30 | } 31 | 32 | void setName(String newName) { 33 | this.name = newName; 34 | } 35 | 36 | public String getName() { 37 | return name; 38 | } 39 | 40 | @Override 41 | public String toString() { 42 | return ""; 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /src/blcmm/model/SetCMPCommand.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2020 LightChaosman 3 | * Copyright (C) 2023 Christopher J. Kucera 4 | * 5 | * OpenBLCMM is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see 17 | * 18 | */ 19 | package blcmm.model; 20 | 21 | import blcmm.utilities.Options; 22 | 23 | /** 24 | * 25 | * @author LightChaosman 26 | */ 27 | public class SetCMPCommand extends HotfixCommand { 28 | 29 | private final String cmpValue; 30 | 31 | public SetCMPCommand(String object, String field, String cmpValue, String value) { 32 | this(new String[]{object, field, cmpValue, value}); 33 | } 34 | 35 | public SetCMPCommand(String command) { 36 | this(split(command, 4)); 37 | if (!(command.substring(0, 7).equalsIgnoreCase("set_cmp") && Character.isWhitespace(command.charAt(7)))) { 38 | throw new IllegalArgumentException(command); 39 | } 40 | } 41 | 42 | private SetCMPCommand(String[] args) { 43 | super(args[0], args[1], args[3], false); 44 | this.cmpValue = args[2]; 45 | if (args.length != 4) { 46 | throw new IllegalArgumentException(); 47 | } 48 | this.transientData = new TransientModelData(this); 49 | } 50 | 51 | @Override 52 | public String getCode() { 53 | return String.format("set_cmp %s %s %s %s", object, field, cmpValue, value); 54 | } 55 | 56 | public String getCmpValue() { 57 | return cmpValue; 58 | } 59 | 60 | @Override 61 | protected String getPrefix() { 62 | ModelElementContainer parent = getParent(); 63 | if (parent instanceof HotfixWrapper) { 64 | return String.format("%s set_cmp", ((HotfixWrapper) parent).getPrefix()); 65 | } else { 66 | return "set_cmp"; 67 | } 68 | } 69 | 70 | @Override 71 | protected SetCMPCommand getBaseCopy() { 72 | return new SetCMPCommand(object, field, cmpValue, value); 73 | } 74 | 75 | @Override 76 | String[] getSplit() { 77 | String val; 78 | String cmpval; 79 | if (Options.INSTANCE.getTruncateCommands() 80 | && value.length() > Options.INSTANCE.getTruncateCommandLength()) { 81 | val = String.format("%s...", 82 | value.substring(0, Options.INSTANCE.getTruncateCommandLength() - 3)); 83 | } else { 84 | val = value; 85 | } 86 | if (Options.INSTANCE.getTruncateCommands() 87 | && cmpValue.length() > Options.INSTANCE.getTruncateCommandLength()) { 88 | cmpval = String.format("%s...", 89 | cmpValue.substring(0, Options.INSTANCE.getTruncateCommandLength() - 3)); 90 | } else { 91 | cmpval = cmpValue; 92 | } 93 | return new String[]{getPrefix(), object, field, cmpval, val}; 94 | 95 | } 96 | 97 | /** 98 | * Returns the "raw" hotfix format actually used by Gearbox hotfixes. 99 | * @return The raw hotfix format 100 | */ 101 | @Override 102 | public String toRawHotfixFormat() { 103 | return this.toRawHotfixFormat(this.cmpValue); 104 | } 105 | 106 | } 107 | -------------------------------------------------------------------------------- /src/blcmm/model/attrparser/LevelDepArray.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2023 Christopher J. Kucera 3 | * 4 | * 5 | * 6 | * OpenBLCMM is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see 18 | * 19 | */ 20 | 21 | package blcmm.model.attrparser; 22 | 23 | import java.util.ArrayList; 24 | 25 | /** 26 | * Simple data class to hold a parsed array inside an attribute. See the 27 | * LevelDepParser docs for more info on the whole process. This class was 28 | * reimplemented based on the calls BLCMM made into BLCMM_Data_Interaction_Library.jar, 29 | * without reference to the original sourcecode. 30 | * 31 | * @param The type of data this array holds 32 | * @author apocalyptech 33 | */ 34 | public class LevelDepArray extends LevelDepData { 35 | 36 | private final ArrayList list; 37 | 38 | public LevelDepArray() { 39 | this.list = new ArrayList<>(); 40 | } 41 | 42 | public void add(T newElement) { 43 | this.list.add(newElement); 44 | } 45 | 46 | public int size() { 47 | return this.list.size(); 48 | } 49 | 50 | public T get(int index) { 51 | return this.list.get(index); 52 | } 53 | 54 | @Override 55 | public String toString() { 56 | ArrayList newList = new ArrayList<>(); 57 | for (Object o : this.list) { 58 | if (o == null) { 59 | newList.add(""); 60 | } else { 61 | newList.add(o.toString()); 62 | } 63 | } 64 | return "(" + String.join(",", newList) + ")"; 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /src/blcmm/model/attrparser/LevelDepData.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2023 Christopher J. Kucera 3 | * 4 | * 5 | * 6 | * OpenBLCMM is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see 18 | * 19 | */ 20 | 21 | package blcmm.model.attrparser; 22 | 23 | /** 24 | * Ridiculous little base class just used so I don't have to specify "Object" 25 | * for the various generic methods in the rest of the level dependency 26 | * attribute parsing. Provides no actual functionality of its own. 27 | * 28 | * @author apocalyptech 29 | */ 30 | public class LevelDepData { 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/blcmm/model/attrparser/LevelDepString.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2023 Christopher J. Kucera 3 | * 4 | * 5 | * 6 | * OpenBLCMM is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see 18 | * 19 | */ 20 | 21 | package blcmm.model.attrparser; 22 | 23 | /** 24 | * Simple class to hold a parsed string from inside an attribute. This class 25 | * was added during the reimplementation of the datalib, based on the calls 26 | * BLCMM made into BLCMM_Data_Interaction_Library.jar, but I don't think 27 | * the original implementation did anything like this. Judging from the 28 | * code in PatchIO, I think it just used regular Strings. 29 | * 30 | * @author apocalyptech 31 | */ 32 | public class LevelDepString extends LevelDepData { 33 | 34 | private String value; 35 | private boolean quoted; 36 | 37 | /** 38 | * Create a new, unquoted String object 39 | * 40 | * @param value The value of the string 41 | */ 42 | public LevelDepString(String value) { 43 | this(value, false); 44 | } 45 | 46 | /** 47 | * Create a new String object, optionally specifying that it should be 48 | * quoted when serialized back into a string. 49 | * 50 | * @param value The value of the string 51 | * @param quoted Whether or not the string should be quoted 52 | */ 53 | public LevelDepString(String value, boolean quoted) { 54 | this.value = value; 55 | this.quoted = quoted; 56 | } 57 | 58 | public String getValue() { 59 | return value; 60 | } 61 | 62 | public boolean isQuoted() { 63 | return quoted; 64 | } 65 | 66 | public boolean equals(LevelDepString other) { 67 | return this.value.equals(other.value); 68 | } 69 | 70 | public boolean equalsIgnoreCase(LevelDepString other) { 71 | if (other == null) { 72 | return false; 73 | } 74 | return this.value.equalsIgnoreCase(other.value); 75 | } 76 | 77 | @Override 78 | public String toString() { 79 | if (this.quoted) { 80 | return '"' + value.replace("\"", "\\\"") + '"'; 81 | } else { 82 | return value; 83 | } 84 | } 85 | 86 | } 87 | -------------------------------------------------------------------------------- /src/blcmm/model/properties/PropertyChecker.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2020 LightChaosman 3 | * 4 | * OpenBLCMM is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see 16 | * 17 | */ 18 | package blcmm.model.properties; 19 | 20 | import blcmm.model.ModelElement; 21 | 22 | /** 23 | * 24 | * @author LightChaosman 25 | */ 26 | public abstract class PropertyChecker { 27 | 28 | private final boolean propagatingToAncestors; 29 | private final boolean dependantOnChildren; 30 | 31 | /** 32 | * For generating tooltips, we want to know what "type" of description is 33 | * being given, to know what do report on containers. 34 | */ 35 | public enum DescType { 36 | SyntaxError, 37 | ContentError, 38 | Warning, 39 | Informational, 40 | Invisible 41 | } 42 | 43 | public PropertyChecker(boolean propagatingToAncestors, boolean dependantOnChildren) { 44 | this.propagatingToAncestors = propagatingToAncestors; 45 | this.dependantOnChildren = dependantOnChildren; 46 | } 47 | 48 | public abstract boolean checkProperty(ModelElement element); 49 | 50 | /** 51 | * Some checkers might have a better performance when given pre-computed 52 | * hints, like lower-case versions of the element. These can override this 53 | * method. 54 | * 55 | * @param element 56 | * @param hints 57 | * @return 58 | */ 59 | public boolean checkProperty(ModelElement element, Hints hints) { 60 | return checkProperty(element);//Default implementation 61 | } 62 | 63 | public abstract DescType getPropertyDescriptionType(); 64 | 65 | public abstract String getPropertyDescription(); 66 | 67 | public boolean isDependantOnChildren() { 68 | return dependantOnChildren; 69 | } 70 | 71 | public boolean isPropagatingToAncestors() { 72 | return propagatingToAncestors; 73 | } 74 | 75 | @Override 76 | public String toString() { 77 | return getClass().getSimpleName(); 78 | } 79 | 80 | public static class Hints { 81 | 82 | String lowerCaseObject; 83 | String lowerCaseField; 84 | String lowerCaseValue; 85 | 86 | public Hints() { 87 | } 88 | 89 | public Hints(String lowerCaseObject, String lowerCaseField, String lowerCaseValue) { 90 | this.lowerCaseObject = lowerCaseObject; 91 | this.lowerCaseField = lowerCaseField; 92 | this.lowerCaseValue = lowerCaseValue; 93 | } 94 | 95 | } 96 | 97 | } 98 | -------------------------------------------------------------------------------- /src/blcmm/utilities/CancelConfirmer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2020 LightChaosman 3 | * 4 | * OpenBLCMM is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see 16 | * 17 | */ 18 | package blcmm.utilities; 19 | 20 | /** 21 | * Used to confirm with the user that cancellation should happen. 22 | */ 23 | public interface CancelConfirmer { 24 | 25 | /** 26 | * Used to confirm with the user that cancellation should happen. 27 | * 28 | * @return True if the dialog can be canceled, False otherwise. 29 | */ 30 | public boolean userConfirmCancel(); 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/blcmm/utilities/DateVersion.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2023 Christopher J. Kucera 3 | * 4 | * 5 | * 6 | * OpenBLCMM is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see 18 | * 19 | */ 20 | package blcmm.utilities; 21 | 22 | /** 23 | * A class to handle the date-versioned version numbers that our OE Datapacks 24 | * use. They're in the form YYYY.MM.DD.NN, with the date as the first 25 | * components, and then a raw number just in case we end up releasing more 26 | * than once per day. 27 | * 28 | * This class blindly assumes that the year is four digits and the rest of 29 | * the "fields" are two digits, for purposes of comparing versions. That's 30 | * obviously quite naive, but I'm honestly not concerned about edge cases, since 31 | * the only places we get these version strings from are from "official" 32 | * sources, and the only failure condition is related to new-version 33 | * notifications. 34 | * 35 | * @author apocalyptech 36 | */ 37 | public class DateVersion { 38 | 39 | private final String rawVersion; 40 | private int year; 41 | private int month; 42 | private int day; 43 | private int num; 44 | private int compareNumber; 45 | 46 | public DateVersion(String rawVersion) { 47 | this.rawVersion = rawVersion; 48 | String[] parts = rawVersion.split("\\.", 4); 49 | if (parts.length != 4) { 50 | throw new RuntimeException("Invalid number of integer parts for raw string: " + rawVersion); 51 | } 52 | this.year = Integer.parseInt(parts[0]); 53 | this.month = Integer.parseInt(parts[1]); 54 | this.day = Integer.parseInt(parts[2]); 55 | this.num = Integer.parseInt(parts[3]); 56 | this.compareNumber = this.year*1000000 + this.month*10000 + this.day*100 + this.num; 57 | } 58 | 59 | @Override 60 | public String toString() { 61 | return this.rawVersion; 62 | } 63 | 64 | public boolean isGreaterThan(DateVersion other) { 65 | return this.compareNumber > other.compareNumber; 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /src/blcmm/utilities/ImportAnomalyLog.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2020 LightChaosman 3 | * 4 | * OpenBLCMM is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see 16 | * 17 | */ 18 | package blcmm.utilities; 19 | 20 | import blcmm.model.CompletePatch; 21 | import java.util.ArrayList; 22 | import java.util.Iterator; 23 | 24 | /** 25 | * 26 | * @author LightChaosman 27 | */ 28 | public class ImportAnomalyLog implements Iterable { 29 | 30 | public static final ImportAnomalyLog INSTANCE = new ImportAnomalyLog(); 31 | 32 | // Var to keep track of errors while importing mods, for reporting to 33 | // the user. 34 | private final ArrayList anomalies = new ArrayList<>(); 35 | 36 | /** 37 | * Error types which we may encounter while trying to import mods. 38 | */ 39 | public static enum ImportAnomalyType implements Comparable { 40 | ParseError(true), 41 | AlreadyExists(true), 42 | NotFound(true), 43 | HTMLFile(false), 44 | EmptyFile(false), 45 | DifferentType(false), 46 | RARfile(true), 47 | NoCommands(true), 48 | IncorrectType(true), 49 | PythonFile(true); 50 | 51 | public final boolean error; 52 | 53 | private ImportAnomalyType(boolean error) { 54 | this.error = error; 55 | } 56 | 57 | } 58 | 59 | /** 60 | * Tiny little class to hold information about an import error. It's a shame 61 | * Java doesn't just have a native Tuple type (though Apache Commons 62 | * apparently does). 63 | */ 64 | public static class importAnomaly implements Comparable { 65 | 66 | public final String modName; 67 | public final ImportAnomalyType anomalyType; 68 | public final String anomalyString; 69 | public final CompletePatch patch; 70 | 71 | public importAnomaly(String modName, ImportAnomalyType errorType, String errorString, CompletePatch patch) { 72 | this.modName = modName; 73 | this.anomalyType = errorType; 74 | this.anomalyString = errorString; 75 | this.patch = patch; 76 | } 77 | 78 | @Override 79 | public int compareTo(importAnomaly t) { 80 | return anomalyType.compareTo(t.anomalyType); 81 | } 82 | } 83 | 84 | public void add(importAnomaly anomaly) { 85 | int i = anomalies.size(); 86 | while (i > 0 && anomaly.compareTo(anomalies.get(i - 1)) < 0) { 87 | i--; 88 | } 89 | anomalies.add(i, anomaly); 90 | } 91 | 92 | public void clear() { 93 | anomalies.clear(); 94 | } 95 | 96 | public int size() { 97 | return anomalies.size(); 98 | } 99 | 100 | @Override 101 | public Iterator iterator() { 102 | return anomalies.iterator(); 103 | } 104 | 105 | } 106 | -------------------------------------------------------------------------------- /src/blcmm/utilities/InputValidator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2020 LightChaosman 3 | * 4 | * OpenBLCMM is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see 16 | * 17 | */ 18 | package blcmm.utilities; 19 | 20 | /** 21 | * 22 | * @author LightChaosman 23 | */ 24 | public interface InputValidator { 25 | 26 | /** 27 | * Used to fix any issues with the provided data which can be easily correct 28 | * automatically. Arguably this should maybe just happen inside 29 | * hasValidInput(), but it seems more proper to have it separate. 30 | */ 31 | public void fixFixableInputs(); 32 | 33 | /** 34 | * Used to check whether the dialog has valid input. 35 | * 36 | * @return True if the dialog should be accepted, False otherwise 37 | */ 38 | public boolean hasValidInput(); 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/blcmm/utilities/OSInfo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2023 Christopher J. Kucera 3 | * 4 | * 5 | * 6 | * OpenBLCMM is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see 18 | * 19 | */ 20 | 21 | package blcmm.utilities; 22 | 23 | import org.apache.commons.lang3.SystemUtils; 24 | 25 | /** 26 | * OS Info class for OpenBLCMM. This class was reimplemented based on the 27 | * calls BLCMM made into BLCMM_Utilities.jar, without reference to the original 28 | * sourcecode. This calls out to Apache Commons Lang to do the actual work. 29 | * 30 | * This class used to live under general.utilities, but it's been moved 31 | * under blcmm.utilities as part of its opensourcing. 32 | * 33 | * @author apocalyptech 34 | */ 35 | public class OSInfo { 36 | 37 | public enum OS { 38 | WINDOWS, 39 | MAC, 40 | UNIX, 41 | UNKNOWN 42 | } 43 | 44 | public static final OS CURRENT_OS; 45 | 46 | static { 47 | if (SystemUtils.IS_OS_WINDOWS) { 48 | CURRENT_OS = OS.WINDOWS; 49 | } else if (SystemUtils.IS_OS_MAC) { 50 | CURRENT_OS = OS.MAC; 51 | } else if (SystemUtils.IS_OS_UNIX) { 52 | CURRENT_OS = OS.UNIX; 53 | } else { 54 | CURRENT_OS = OS.UNKNOWN; 55 | } 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /src/blcmm/utilities/StringUtilities.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2023 Christopher J. Kucera 3 | * 4 | * 5 | * 6 | * OpenBLCMM is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see 18 | * 19 | */ 20 | 21 | package blcmm.utilities; 22 | 23 | /** 24 | * Miscellaneous string utilities for OpenBLCMM. This class was reimplemented based 25 | * on the calls BLCMM made into BLCMM_Utilities.jar, without reference to the 26 | * original sourcecode. 27 | * 28 | * This class used to live under general.utilities, but it's been moved 29 | * under blcmm.utilities as part of its opensourcing. 30 | * 31 | * @author apocalyptech 32 | */ 33 | public class StringUtilities { 34 | 35 | /** 36 | * Returns whether or not a substring of the given CharSequence `s` is equal 37 | * to `searchString`. Really this is checking for substring *equality* but 38 | * with an assumed substring length. 39 | * 40 | * OpenBLCMM v1.3.0 had some performance issues related to this method when 41 | * doing code formatting, though some v1.4.0 changes bypassed this method 42 | * as a bottleneck entirely, prior to discovering that problem. A couple 43 | * of things were done to address it, regardless: 44 | * 45 | * 1. This originally did a naive `s.substring(startIndex).startsWith(searchString)`, 46 | * which is slower than what we're now doing (potentially as much 47 | * as 2x slower). In the end, that wasn't the biggest deal, though. 48 | * 49 | * 2. OpenBLCMM originally had two functions -- one that took a String, 50 | * and another which took a StringBuilder (which did a .toString() to 51 | * pass through to the String version). *This* is what was being super 52 | * slow, in the end. The right thing to do is to just use a 53 | * CharSequence instead, which lets us get right to charAt. To do 54 | * that, we did need to do #1 as well, so at least that wasn't wasted 55 | * effort. 56 | * 57 | * @param s The charsequence in which to search 58 | * @param startIndex The start index where we expect to find our search 59 | * @param searchString The string we're searching for 60 | * @return Whether or not the search string is found at the specified index 61 | */ 62 | public static boolean substringStartsWith(CharSequence s, int startIndex, String searchString) { 63 | int endIndex = startIndex + searchString.length(); 64 | if (endIndex > s.length()) { 65 | return false; 66 | } 67 | int searchLength = searchString.length(); 68 | for (int i=0; i 16 | * 17 | */ 18 | package blcmm.utilities.hex; 19 | 20 | import java.util.Arrays; 21 | 22 | /** 23 | * 24 | * @author LightChaosman 25 | */ 26 | class AddressHexEdit extends HexEdit { 27 | 28 | public final int adress; 29 | 30 | AddressHexEdit(int hardCodedAdress, String original, String replacement) { 31 | this(hardCodedAdress, HexUtilities.convertToByteArray(original), HexUtilities.convertToByteArray(replacement)); 32 | } 33 | 34 | AddressHexEdit(int hardCodedAdress, byte[] original, byte[] replacement) { 35 | super(original, replacement); 36 | this.adress = hardCodedAdress; 37 | } 38 | 39 | public int getAdress() { 40 | return adress; 41 | } 42 | 43 | @Override 44 | public int requiredBufferSize() { 45 | return original.length; 46 | } 47 | 48 | @Override 49 | public boolean match(byte[] bytes, int startIndexInArray, int globalOffset) { 50 | return globalOffset + startIndexInArray == adress; 51 | } 52 | 53 | @Override 54 | public HexEditor.HexResultStatus replace(byte[] bytes, int startIndexInArray, int globalOffset, boolean force) { 55 | if (!match(bytes, startIndexInArray, globalOffset)) { 56 | return null; 57 | } else if (force) { 58 | HexUtilities.replace(bytes, startIndexInArray, replacement); 59 | return HexEditor.HexResultStatus.HEXEDIT_SUCCESFUL; 60 | } else if (HexUtilities.matches(bytes, startIndexInArray, replacement)) { 61 | return HexEditor.HexResultStatus.HEXEDIT_ALREADY_DONE; 62 | } else if (HexUtilities.matches(bytes, startIndexInArray, original)) { 63 | HexUtilities.replace(bytes, startIndexInArray, replacement); 64 | return HexEditor.HexResultStatus.HEXEDIT_SUCCESFUL; 65 | } else { 66 | System.out.println(Arrays.toString(original) + Arrays.toString(replacement)); 67 | for (int i = -1; i < original.length + 2; i++) { 68 | System.out.print(bytes[i + startIndexInArray] + " "); 69 | } 70 | System.out.println(); 71 | return HexEditor.HexResultStatus.ERROR_UNKNOWN_BYTE_PATTERN_FOUND; 72 | } 73 | } 74 | 75 | @Override 76 | public int requiredNegativeBufferSize() { 77 | return 0; 78 | } 79 | 80 | @Override 81 | public HexInspectResult inspect(byte[] bytes, int startIndexInArray, int globalOffset) { 82 | byte[] bts = new byte[replacement.length]; 83 | System.arraycopy(bytes, startIndexInArray, bts, 0, bts.length); 84 | return new HexInspectResult(this, globalOffset + startIndexInArray, bts); 85 | } 86 | 87 | @Override 88 | public HexEdit getInvertedCopy() { 89 | return new AddressHexEdit(adress, replacement, original); 90 | } 91 | 92 | } 93 | -------------------------------------------------------------------------------- /src/blcmm/utilities/hex/HexEdit.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2020 LightChaosman 3 | * 4 | * BLCMM is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see 16 | * 17 | */ 18 | package blcmm.utilities.hex; 19 | 20 | /** 21 | * 22 | * @author LightChaosman 23 | */ 24 | public abstract class HexEdit { 25 | 26 | public static final int NO_MATCH = 4729; 27 | public static final int SUCCESFULLY_REPLACED = 43849; 28 | public static final int WAS_ALREADY_REPLACED = 347983; 29 | public static final int UNKNOWN_PATTERN_FOUND = 349; 30 | 31 | //The pattern that's originally found 'offset' bytes after 'searchPattern' 32 | public final byte[] original; 33 | //The pattern that we replace orginal with if we find it 34 | public final byte[] replacement; 35 | 36 | protected HexEdit(String original, String replacement) { 37 | this(HexUtilities.convertToByteArray(original), HexUtilities.convertToByteArray(replacement)); 38 | } 39 | 40 | protected HexEdit(String[] original, String[] replacement) { 41 | this(HexUtilities.convertToByteArray(original), HexUtilities.convertToByteArray(replacement)); 42 | } 43 | 44 | protected HexEdit(byte[] original, byte[] replacement) { 45 | this.original = original; 46 | this.replacement = replacement; 47 | if (this.original.length != this.replacement.length) { 48 | throw new IllegalArgumentException("replacement and original must be equal length: "); 49 | } 50 | } 51 | 52 | public byte[] getOriginal() { 53 | return original; 54 | } 55 | 56 | public byte[] getReplacement() { 57 | return replacement; 58 | } 59 | 60 | public abstract int requiredBufferSize(); 61 | 62 | public abstract boolean match(byte[] bytes, int startIndexInArray, int globalOffset); 63 | 64 | public abstract HexEditor.HexResultStatus replace(byte[] bytes, int startIndexInArray, int globalOffset, boolean force); 65 | 66 | public abstract HexInspectResult inspect(byte[] bytes, int startIndexInArray, int globalOffset); 67 | 68 | public abstract int requiredNegativeBufferSize(); 69 | 70 | public abstract HexEdit getInvertedCopy(); 71 | 72 | } 73 | -------------------------------------------------------------------------------- /src/blcmm/utilities/hex/HexInspectResult.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2020 LightChaosman 3 | * 4 | * BLCMM is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see 16 | * 17 | */ 18 | package blcmm.utilities.hex; 19 | 20 | /** 21 | * 22 | * @author LightChaosman 23 | */ 24 | public class HexInspectResult { 25 | 26 | public final HexEdit orginialHexEdit; 27 | public final byte[] found; 28 | public final int adress; 29 | 30 | HexInspectResult(HexEdit orginialHexEdit, int adress, byte[] found) { 31 | this.adress = adress; 32 | this.orginialHexEdit = orginialHexEdit; 33 | this.found = found; 34 | } 35 | 36 | public HexEdit getOrginialHexEdit() { 37 | return orginialHexEdit; 38 | } 39 | 40 | public byte[] getFound() { 41 | return found; 42 | } 43 | 44 | public int getAdress() { 45 | return adress; 46 | } 47 | 48 | public boolean matchesOriginal() { 49 | return HexUtilities.matches(found, 0, orginialHexEdit.original); 50 | } 51 | 52 | public boolean matchesEdited() { 53 | return HexUtilities.matches(found, 0, orginialHexEdit.replacement); 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /src/blcmm/utilities/hex/HexUtilities.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2020 LightChaosman 3 | * 4 | * BLCMM is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see 16 | * 17 | */ 18 | package blcmm.utilities.hex; 19 | 20 | /** 21 | * 22 | * @author LightChaosman 23 | */ 24 | public class HexUtilities { 25 | 26 | public final static short WILDCARD = '?' + 1024; 27 | 28 | private HexUtilities() { 29 | } 30 | 31 | protected static final byte[] convertToByteArray(String stringVersion) throws NumberFormatException { 32 | return convertToByteArray(convertStringToArray(stringVersion)); 33 | } 34 | 35 | protected static final byte[] convertToByteArray(String[] stringVersion) throws NumberFormatException { 36 | byte[] bts = new byte[stringVersion.length]; 37 | for (int i = 0; i < stringVersion.length; i++) { 38 | bts[i] = (byte) Integer.parseInt(stringVersion[i], 16); 39 | } 40 | return bts; 41 | } 42 | 43 | protected static final short[] convertToShortArray(byte[] byteVersion) { 44 | short[] res = new short[byteVersion.length]; 45 | for (int i = 0; i < res.length; i++) { 46 | res[i] = byteVersion[i]; 47 | } 48 | return res; 49 | } 50 | 51 | /** 52 | * Use this method if wildcards should be accepted 53 | * 54 | * @param stringVersion 55 | * @return 56 | * @throws NumberFormatException 57 | */ 58 | static short[] convertToShortArray(String stringVersion) throws NumberFormatException { 59 | return convertToShortArray(HexUtilities.convertStringToArray(stringVersion)); 60 | } 61 | 62 | /** 63 | * Use this method if wildcards should be accepted 64 | * 65 | * @param stringVersion 66 | * @return 67 | * @throws NumberFormatException 68 | */ 69 | protected static short[] convertToShortArray(String[] stringVersion) throws NumberFormatException { 70 | short[] bts = new short[stringVersion.length]; 71 | for (int i = 0; i < stringVersion.length; i++) { 72 | if (stringVersion[i].startsWith("?")) { 73 | bts[i] = WILDCARD; 74 | } else { 75 | bts[i] = (byte) Integer.parseInt(stringVersion[i], 16); 76 | } 77 | } 78 | return bts; 79 | } 80 | 81 | protected static final String[] convertStringToArray(String base) { 82 | return base.replaceAll("0x", "").split("[\\s,]+"); 83 | } 84 | 85 | protected static boolean matches(byte[] bytes, int offset, byte[] toMatch) { 86 | for (int i = 0; i < toMatch.length; i++) { 87 | if (bytes[offset + i] != toMatch[i]) { 88 | return false; 89 | } 90 | } 91 | return true; 92 | } 93 | 94 | protected static boolean matches(byte[] bytes, int offset, short[] toMatch) { 95 | for (int i = 0; i < toMatch.length; i++) { 96 | if (toMatch[i] != HexUtilities.WILDCARD && bytes[offset + i] != ((byte) toMatch[i])) { 97 | return false; 98 | } 99 | } 100 | return true; 101 | } 102 | 103 | protected static final void replace(byte[] bytes, int offset, byte[] replacement) { 104 | System.arraycopy(replacement, 0, bytes, offset, replacement.length); 105 | } 106 | 107 | } 108 | -------------------------------------------------------------------------------- /src/blcmm/utilities/log/LogConsole.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2023 Christopher J. Kucera 3 | * 4 | * 5 | * 6 | * OpenBLCMM is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see 18 | * 19 | */ 20 | 21 | package blcmm.utilities.log; 22 | 23 | /** 24 | * Console logging for GlobalLogger. Just a straightforward wrapper around 25 | * some basic System.out.println(), basically. 26 | * 27 | * @author apocalyptech 28 | */ 29 | 30 | public class LogConsole implements LogTarget { 31 | 32 | /** 33 | * Has no effect. 34 | * 35 | * @param newLogFolder The folder to use. 36 | */ 37 | @Override 38 | public void setLogFolder(String newLogFolder) { 39 | } 40 | 41 | /** 42 | * Logs a single line. 43 | * 44 | * @param line The message to log 45 | */ 46 | @Override 47 | public void singleLine(String line) { 48 | System.out.println(line); 49 | } 50 | 51 | /** 52 | * Flush the console. 53 | */ 54 | @Override 55 | public void flush() { 56 | System.out.flush(); 57 | } 58 | 59 | /** 60 | * Has no effect. 61 | */ 62 | @Override 63 | public void close() { 64 | } 65 | 66 | /** 67 | * Has no effect. 68 | */ 69 | @Override 70 | public void delete() { 71 | } 72 | 73 | /** 74 | * Has no effect. 75 | */ 76 | @Override 77 | public void markAsPermanentLog() { 78 | } 79 | 80 | } 81 | -------------------------------------------------------------------------------- /src/blcmm/utilities/log/LogTarget.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2023 Christopher J. Kucera 3 | * 4 | * 5 | * 6 | * OpenBLCMM is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see 18 | * 19 | */ 20 | 21 | package blcmm.utilities.log; 22 | 23 | /** 24 | * Interface defining a logging target, used by blcmm.utilities.GlobalLogger. 25 | * This is kind of stupidly overengineered, but whatever. Note that the 26 | * majority of these functions don't really apply to console logging. Other 27 | * potential log targets like databases or whatever wouldn't fit neatly in 28 | * here either. 29 | * 30 | * @author apocalyptech 31 | */ 32 | 33 | public interface LogTarget { 34 | 35 | /** 36 | * Sets the log folder to send logs to. Obviously only has an effect for 37 | * file-based targets. 38 | * 39 | * @param newLogFolder The folder to use. 40 | */ 41 | public void setLogFolder(String newLogFolder); 42 | 43 | /** 44 | * Logs a single line to the target. 45 | * 46 | * @param line The message to log 47 | */ 48 | public void singleLine(String line); 49 | 50 | /** 51 | * Flush the target, if appropriate. 52 | */ 53 | public void flush(); 54 | 55 | /** 56 | * Close any open filehandles-or-whatever, if appropriate. 57 | */ 58 | public void close(); 59 | 60 | /** 61 | * Mark the target as permanent -- do not delete on application close. 62 | */ 63 | public void markAsPermanentLog(); 64 | 65 | /** 66 | * Delete the file-or-whatever, if appropriate. Will not have any effect 67 | * if markAsPermanentLog has been called, or if the target is otherwise 68 | * ensuring its permanence. 69 | */ 70 | public void delete(); 71 | } 72 | -------------------------------------------------------------------------------- /src/blcmm/utilities/options/InverseBooleanOption.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2023 Christopher J. Kucera 3 | * 4 | * 5 | * 6 | * OpenBLCMM is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see 18 | * 19 | */ 20 | package blcmm.utilities.options; 21 | 22 | import blcmm.gui.FontInfo; 23 | import blcmm.gui.components.FontInfoJCheckBox; 24 | import blcmm.gui.panels.ToolSettingsPanel; 25 | import blcmm.utilities.OptionsBase; 26 | import javax.swing.JComponent; 27 | import javax.swing.SwingConstants; 28 | 29 | /** 30 | * Boolean option whose GUI checkbox should actually store/display the *inverse* 31 | * of the on-disk value. 32 | * 33 | * @author apocalyptech 34 | */ 35 | public class InverseBooleanOption extends BooleanOption { 36 | 37 | /** 38 | * Constructor for a boolean option which will not be displayed on the 39 | * settings panel. 40 | * 41 | * @param optionsObj The Options that this Option is a part of 42 | * @param name Key for the option 43 | * @param fontInfo Font information to use on the option 44 | * @param defaultData Default value for the option 45 | */ 46 | public InverseBooleanOption(OptionsBase optionsObj, String name, FontInfo fontInfo, boolean defaultData) { 47 | super(optionsObj, name, fontInfo, defaultData); 48 | } 49 | 50 | /** 51 | * Constructor for a boolean option. If displayDesc is null, the option will 52 | * not be shown on the settings panel. 53 | * 54 | * @param optionsObj The Options that this Option is a part of 55 | * @param name Key for the option 56 | * @param fontInfo Font information to use on the option 57 | * @param defaultData Default value for the option 58 | * @param shownPanel The panel on which to show this option 59 | * @param displayDesc Display description on the settings panel 60 | * @param callback Callback to use when the option is changed 61 | * @param tooltip Tooltip to show on the control 62 | */ 63 | public InverseBooleanOption(OptionsBase optionsObj, 64 | String name, 65 | FontInfo fontInfo, 66 | boolean defaultData, 67 | Option.Shown shownPanel, 68 | String displayDesc, 69 | String callback, 70 | String tooltip) { 71 | super(optionsObj, name, fontInfo, defaultData, shownPanel, displayDesc, callback, tooltip); 72 | } 73 | 74 | /** 75 | * Return a JComponent for this option, for use in the settings panel. 76 | * 77 | * @param panel The ToolSettingsPanel object we are being added to 78 | * @return A suitable JComponent 79 | */ 80 | @Override 81 | public JComponent getGUIComponent(ToolSettingsPanel panel) { 82 | BooleanOption option = this; 83 | FontInfoJCheckBox check = new FontInfoJCheckBox(this.fontInfo); 84 | check.setSelected(!this.getData()); 85 | check.setHorizontalAlignment(SwingConstants.RIGHT); 86 | check.addActionListener(ae -> { 87 | setData(!check.isSelected()); 88 | panel.callBack(option, check); 89 | optionsObj.save(); 90 | }); 91 | return check; 92 | } 93 | 94 | } 95 | -------------------------------------------------------------------------------- /src/blcmm/utilities/options/MouseButtonOption.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2023 Christopher J. Kucera 3 | * 4 | * 5 | * 6 | * OpenBLCMM is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see 18 | * 19 | */ 20 | package blcmm.utilities.options; 21 | 22 | import blcmm.gui.FontInfo; 23 | import blcmm.gui.components.FontInfoJButton; 24 | import blcmm.gui.panels.ToolSettingsPanel; 25 | import blcmm.utilities.OptionsBase; 26 | import java.awt.event.MouseAdapter; 27 | import java.awt.event.MouseEvent; 28 | import javax.swing.JButton; 29 | import javax.swing.JComponent; 30 | 31 | /** 32 | * An integer-based option to store the selected mouse button based on the 33 | * user clicking on a JButton. The MouseEvent generated by the JButton click 34 | * will be used as the new value of the option. 35 | * 36 | * @author apocalyptech 37 | */ 38 | public class MouseButtonOption extends Option { 39 | 40 | /** 41 | * Constructor for a new Mouse-Button option. 42 | * 43 | * @param optionsObj The Options that this Option is a part of 44 | * @param name Key for the option 45 | * @param fontInfo Font information to use on the option 46 | * @param defaultData Default value for the option 47 | * @param shownPanel The panel on which to show this option 48 | * @param displayDesc Display description on the settings panel 49 | * @param callback Callback to use when the option is changed 50 | * @param tooltip Tooltip to show on the control 51 | */ 52 | public MouseButtonOption(OptionsBase optionsObj, 53 | String name, 54 | FontInfo fontInfo, 55 | int defaultData, 56 | Option.Shown shownPanel, 57 | String displayDesc, 58 | String callback, 59 | String tooltip) { 60 | super(optionsObj, name, fontInfo, defaultData, shownPanel, displayDesc, callback, tooltip); 61 | } 62 | 63 | /** 64 | * Converts the given string (read from a config file) into the correct data 65 | * type for this Option. 66 | * 67 | * @param stringData The string data to convert 68 | * @return The data in its proper format 69 | */ 70 | @Override 71 | public Integer stringToData(String stringData) { 72 | return Integer.parseInt(stringData); 73 | } 74 | 75 | /** 76 | * Converts the current data for this option into a String suitable for 77 | * saving to a text-based options file. 78 | * 79 | * @return A string representation of our data 80 | */ 81 | @Override 82 | public String dataToString() { 83 | return Integer.toString(this.getData()); 84 | } 85 | 86 | /** 87 | * Update our button label with our current data 88 | */ 89 | private void updateLabel(JButton button) { 90 | button.setText("" + this.dataToString() + " (Click to Change)"); 91 | } 92 | 93 | /** 94 | * Return a JComponent for this option, for use in the settings panel. 95 | * 96 | * @param panel The ToolSettingsPanel object we are being added to 97 | * @return A suitable JComponent 98 | */ 99 | @Override 100 | public JComponent getGUIComponent(ToolSettingsPanel panel) { 101 | FontInfoJButton button = new FontInfoJButton(this.fontInfo); 102 | this.updateLabel(button); 103 | button.addMouseListener(new MouseAdapter() { 104 | @Override 105 | public void mousePressed(MouseEvent e) { 106 | setData(e.getButton()); 107 | updateLabel(button); 108 | } 109 | }); 110 | return button; 111 | } 112 | 113 | } 114 | -------------------------------------------------------------------------------- /src/blcmm/utilities/options/OptionDataConverter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2020 LightChaosman 3 | * 4 | * OpenBLCMM is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see 16 | * 17 | */ 18 | package blcmm.utilities.options; 19 | 20 | /** 21 | * 22 | * @author LightChaosman 23 | * @param The class to convert to. 24 | */ 25 | public interface OptionDataConverter { 26 | 27 | public O convert(String s); 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/blcmm/utilities/options/SectionHeaderOption.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2023 Christopher J. Kucera 3 | * 4 | * 5 | * 6 | * OpenBLCMM is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program. If not, see 18 | * 19 | */ 20 | package blcmm.utilities.options; 21 | 22 | import blcmm.gui.FontInfo; 23 | import blcmm.gui.components.FontInfoJLabel; 24 | import blcmm.gui.panels.ToolSettingsPanel; 25 | import blcmm.utilities.OptionsBase; 26 | import javax.swing.JComponent; 27 | import javax.swing.SwingConstants; 28 | 29 | /** 30 | * A fake "Option" to display a section header on our Options screen, which 31 | * isn't *really* an option. 32 | * 33 | * @author apocalyptech 34 | */ 35 | public class SectionHeaderOption extends Option { 36 | 37 | private static int num_headers = 0; 38 | private String headerText; 39 | 40 | /** 41 | * Creates a new section header. 42 | * 43 | * @param optionsObj The Options object we're contained within 44 | * @param shownPanel The panel in which we appear 45 | * @param headerText The header text to display 46 | * @param fontInfo Font information to use on the option 47 | */ 48 | public SectionHeaderOption(OptionsBase optionsObj, Option.Shown shownPanel, String headerText, FontInfo fontInfo) { 49 | super(optionsObj, "_sectionheaderoption_header_" + Integer.toString(SectionHeaderOption.num_headers), fontInfo, shownPanel); 50 | SectionHeaderOption.num_headers++; 51 | this.headerText = headerText; 52 | } 53 | 54 | @Override 55 | public void setData(Integer newData) { 56 | } 57 | 58 | @Override 59 | public Integer stringToData(String stringData) { 60 | return 1; 61 | } 62 | 63 | @Override 64 | public String dataToString() { 65 | return ""; 66 | } 67 | 68 | @Override 69 | public JComponent getGUIComponent(ToolSettingsPanel panel) { 70 | FontInfoJLabel label = new FontInfoJLabel("" + this.headerText + "
", this.fontInfo); 71 | label.setHorizontalAlignment(SwingConstants.CENTER); 72 | return label; 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /src/blcmm/utilities/options/SelectionOptionData.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2020 LightChaosman 3 | * 4 | * OpenBLCMM is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see 16 | * 17 | */ 18 | package blcmm.utilities.options; 19 | 20 | /** 21 | * Simple interface for any data type used in a SelectionOption. 22 | * 23 | * @author apocalyptech 24 | */ 25 | public interface SelectionOptionData { 26 | 27 | /** 28 | * Returns a string suitable for saving this object into a text-based 29 | * preference file. Needed because .toString() might be something sent to 30 | * the user. 31 | * 32 | * @return A string identifying this option 33 | */ 34 | public String toSaveString(); 35 | 36 | /** 37 | * Returns a string suitable for showing in the user-facing dropdown 38 | * entry. 39 | * 40 | * @return A human-suitable string representing the data 41 | */ 42 | public String toDropdownLabel(); 43 | 44 | } 45 | -------------------------------------------------------------------------------- /src/blcmm/utilities/options/StringListOption.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2020 LightChaosman 3 | * 4 | * OpenBLCMM is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see 16 | * 17 | */ 18 | package blcmm.utilities.options; 19 | 20 | import blcmm.gui.FontInfo; 21 | import blcmm.gui.panels.ToolSettingsPanel; 22 | import blcmm.model.PatchIO; 23 | import blcmm.utilities.OptionsBase; 24 | import javax.swing.JComponent; 25 | 26 | /** 27 | * 28 | * @author LightChaosman 29 | */ 30 | public class StringListOption extends Option { 31 | 32 | public StringListOption(OptionsBase optionsObj, String name, FontInfo fontInfo, String[] defaultData) { 33 | super(optionsObj, name, fontInfo, defaultData); 34 | } 35 | 36 | @Override 37 | public String[] stringToData(String stringData) { 38 | //Remove the square braces *and* the opening quote for the first entry, and the closing quote for the last entry 39 | if (stringData.equals("[]")) { 40 | return new String[0]; 41 | } 42 | String nobrackets = stringData.substring(2, stringData.length() - 2); 43 | String[] split = nobrackets.split("\",\""); 44 | for (int i = 0; i < split.length; i++) { 45 | split[i] = PatchIO.unescape(split[i]); 46 | } 47 | return split; 48 | } 49 | 50 | @Override 51 | public String dataToString() { 52 | if (getData().length == 0) { 53 | return "[]"; 54 | } 55 | StringBuilder sb = new StringBuilder(); 56 | sb.append("[\"" + PatchIO.escape(getData()[0]) + "\""); 57 | for (int i = 1; i < getData().length; i++) { 58 | sb.append(",\"" + PatchIO.escape(getData()[i]) + "\""); 59 | } 60 | sb.append("]"); 61 | return sb.toString(); 62 | } 63 | 64 | @Override 65 | public JComponent getGUIComponent(ToolSettingsPanel panel) { 66 | return null; 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /src/resources/AODK/Icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BLCM/OpenBLCMM/ecee5cbfbdbf9fadd7d38d6b86f8b669cb0dd19e/src/resources/AODK/Icon.png -------------------------------------------------------------------------------- /src/resources/BL2/Icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BLCM/OpenBLCMM/ecee5cbfbdbf9fadd7d38d6b86f8b669cb0dd19e/src/resources/BL2/Icon.png -------------------------------------------------------------------------------- /src/resources/Icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BLCM/OpenBLCMM/ecee5cbfbdbf9fadd7d38d6b86f8b669cb0dd19e/src/resources/Icon.png -------------------------------------------------------------------------------- /src/resources/Qmark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BLCM/OpenBLCMM/ecee5cbfbdbf9fadd7d38d6b86f8b669cb0dd19e/src/resources/Qmark.png -------------------------------------------------------------------------------- /src/resources/README.md: -------------------------------------------------------------------------------- 1 | Provenance of the various resources in here 2 | =========================================== 3 | 4 | **Note:** Any new resources added here will also need to be added into 5 | the `META-INF/native-image/blcmm/blcmm/resource-config.json` registry, 6 | for the compiled Windows EXE version to Not Crash when the resources 7 | are requested. 8 | 9 | * `donate.png` - This was just taken from a screenshot at paypal.com from 10 | their set-up-a-donation-link page, with the HTML/CSS fiddled a little 11 | bit to just say "Donate" and to make the button less wide. (Then edited 12 | in Gimp to make the background transparent.) 13 | 14 | * `Icon.png` - OpenBLCMM's app icon, unless someone is willing to create 15 | and submit something better. Constructed by apocalyptech in Gimp in a 16 | rather crude fashion. The source Gimp files (and a couple of gradients 17 | used while playing with it) can be found in the top-level `resources/icon` 18 | directory. 19 | 20 | * `Qmark.png` - Free-to-use icon from [Fathema Khanom](https://www.flaticon.com/authors/fathema-khanom)'s 21 | [User Interface set](https://www.flaticon.com/packs/user-interface-2899), available 22 | under [Flaticon's Free License](https://www.flaticon.com/free-icons/ui). 23 | (Though not with the filename used here.) 24 | 25 | * `exec.png` / `padlock.png` / `speaker.png` - Some icons from 26 | [Dave Gandy](http://www.flaticon.com/authors/dave-gandy)'s 27 | [Font Awesome set](http://www.flaticon.com/packs/font-awesome), available under 28 | CC BY 3.0. (Though not with the filenames used here.) 29 | 30 | * `folder.png` - [Free-to-use icon](https://www.flaticon.com/free-icon/folder_148955) 31 | from [Smashicons](https://www.flaticon.com/authors/smashicons)' 32 | [Essential Collection set](https://www.flaticon.com/packs/essential-collection), 33 | available under [Flaticon's Free License](https://www.flaticon.com/free-icons/ui). 34 | (Though not with the filename used here.) 35 | 36 | * `/GBX_hotfixes.blcm` - BLCM-formatted mod file containing the 37 | vanilla hotfixes still provided by GBX at time of writing. This is the 38 | same version as was present in the original BLCMM versions, since it's 39 | just the raw data. 40 | 41 | * `/vanillaLevelLists.blcm` - BLCM-formatted mod file containing 42 | the vanilla `LevelList` attributes for all `LevelDependencyList` objects. 43 | Used by BLCMM for handling map merges. This is the same version as was 44 | present in the original BLCMM versions, since it's just the raw data. 45 | 46 | * `/Icon.png` - For BL2 and TPS, these are the official game icons, 47 | though the official icons you can currently get from Steam are only 64x64. 48 | I'm pretty sure that that Steam originally provided 256x256 versions of the 49 | icons, though, which is where these had come from. The AoDK icon was created 50 | by [Julia @ steamgriddb.com](https://www.steamgriddb.com/icon/10266), and is 51 | used here by their kind permission! 52 | -------------------------------------------------------------------------------- /src/resources/TPS/Icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BLCM/OpenBLCMM/ecee5cbfbdbf9fadd7d38d6b86f8b669cb0dd19e/src/resources/TPS/Icon.png -------------------------------------------------------------------------------- /src/resources/donate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BLCM/OpenBLCMM/ecee5cbfbdbf9fadd7d38d6b86f8b669cb0dd19e/src/resources/donate.png -------------------------------------------------------------------------------- /src/resources/exec.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BLCM/OpenBLCMM/ecee5cbfbdbf9fadd7d38d6b86f8b669cb0dd19e/src/resources/exec.png -------------------------------------------------------------------------------- /src/resources/folder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BLCM/OpenBLCMM/ecee5cbfbdbf9fadd7d38d6b86f8b669cb0dd19e/src/resources/folder.png -------------------------------------------------------------------------------- /src/resources/padlock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BLCM/OpenBLCMM/ecee5cbfbdbf9fadd7d38d6b86f8b669cb0dd19e/src/resources/padlock.png -------------------------------------------------------------------------------- /src/resources/speaker.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BLCM/OpenBLCMM/ecee5cbfbdbf9fadd7d38d6b86f8b669cb0dd19e/src/resources/speaker.png -------------------------------------------------------------------------------- /steamos-processing/native-agent.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # vim: set expandtab tabstop=4 shiftwidth=4: 3 | 4 | export JAVA_HOME="/home/deck/bellsoft-liberica-vm-core-openjdk17-23.0.1" 5 | export PATH="${JAVA_HOME}/bin:${PATH}" 6 | 7 | # This can help fonts look better while running, though it does *not* actually 8 | # help anything on the Steam Deck. 9 | export FREETYPE_PROPERTIES="truetype:interpreter-version=35" 10 | 11 | # Check for dependencies 12 | for COMMAND in jq unix2dos java native-image 13 | do 14 | if [ ! -x "$(command -v ${COMMAND})" ]; then 15 | echo "JAVA_HOME was set to: ${JAVA_HOME}" 16 | echo "${COMMAND} not found on path, exiting..." 17 | exit 1 18 | fi 19 | done 20 | 21 | # Get into the correct dir 22 | cd ../store 23 | 24 | # Run the agent 25 | echo "Running Native Image Agent..." 26 | echo 27 | java -agentlib:native-image-agent=config-merge-dir=../src/META-INF/native-image/blcmm/blcmm -jar OpenBLCMM.jar 28 | echo 29 | 30 | # Normalize JSON (w/ compat for Windows-generated JSON) 31 | echo "Running JSON through jq..." 32 | echo 33 | cd ../src/META-INF/native-image/blcmm/blcmm 34 | for file in *.json 35 | do 36 | jq . < ${file} | unix2dos > ${file}.new 37 | mv ${file}.new ${file} 38 | done 39 | 40 | # ... and we're out! 41 | echo "Done!" 42 | echo 43 | 44 | -------------------------------------------------------------------------------- /steamos-processing/native-compile.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # vim: set expandtab tabstop=4 shiftwidth=4: 3 | 4 | export JAVA_HOME="/home/deck/bellsoft-liberica-vm-core-openjdk17-23.0.1" 5 | export PATH="${JAVA_HOME}/bin:${PATH}" 6 | 7 | # The default when compiling on AMD, and the one we'll be using 8 | export NIKARCH="x86-64-v3" 9 | # Compatibility; works on the widest possible range of CPUs 10 | #export NIKARCH="compatibility" 11 | # Native -- use anything useful found on the compiling CPU 12 | #export NIKARCH="native" 13 | 14 | # Check for dependencies 15 | for COMMAND in native-image 16 | do 17 | if [ ! -x "$(command -v ${COMMAND})" ]; then 18 | echo "JAVA_HOME was set to: ${JAVA_HOME}" 19 | echo "${COMMAND} not found on path, exiting..." 20 | exit 1 21 | fi 22 | done 23 | 24 | # Get into the correct dir 25 | cd ../store 26 | 27 | # Compile! 28 | echo "Compiling..." 29 | echo 30 | native-image -march=${NIKARCH} -jar OpenBLCMM.jar 31 | echo 32 | 33 | # Move stuff into its own dir 34 | echo "Collecting into subdir" 35 | echo 36 | rm -rf steamos 37 | mkdir steamos 38 | mv *.so OpenBLCMM steamos/ 39 | echo 40 | 41 | # ... and we're out! 42 | echo "Done!" 43 | echo 44 | 45 | # Display the results 46 | ls -l steamos/ 47 | 48 | -------------------------------------------------------------------------------- /steamos-processing/prepare-deck.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # vim: set expandtab tabstop=4 shiftwidth=4: 3 | 4 | echo 5 | echo "This script will (theoretically) prepare a SteamOS installation to be" 6 | echo "able to compile OpenBLCMM using GraalVM / Liberica NIK, at least from" 7 | echo "an OS level. It will *not* actually install Liberica NIK itself, but" 8 | echo "it should be good to go otherwise. There's a couple of steps to this:" 9 | echo 10 | echo " 1) Disabling readonly mode" 11 | echo " 2) Initializing the Arch Linux keyring" 12 | echo " 3) Installing development tools, plus reinstalling a few Arch" 13 | echo " packages whose contents have been intentionally trimmed on" 14 | echo " SteamOS" 15 | echo " 4) Re-enabling readonly mode" 16 | echo 17 | 18 | if [ ${UID} -ne 0 ]; then 19 | echo "ERROR:" 20 | echo 21 | echo "This script must be run as root! Obvs. look it over first to make" 22 | echo "sure you understand what it's doing." 23 | echo 24 | exit 1 25 | fi 26 | 27 | echo "If you don't want to do that, or have already done it, hit Ctrl-C" 28 | echo "now. Otherwise, hit enter to proceed!" 29 | echo 30 | read omg 31 | 32 | echo "Here we go!" 33 | echo 34 | steamos-readonly disable 35 | pacman-key --init 36 | pacman -S archlinux-keyring 37 | pacman -S base-devel glibc linux-api-headers 38 | steamos-readonly enable 39 | echo 40 | 41 | echo "Done! If you haven't already, download the Liberica NIK tgz from:" 42 | echo 43 | echo " https://bell-sw.com/pages/downloads/native-image-kit/#downloads" 44 | echo 45 | echo "... and unpack it in ~deck. You may need to check the paths given in" 46 | echo "native-agent.sh and native-compile.sh to ensure they match." 47 | echo 48 | 49 | -------------------------------------------------------------------------------- /store/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BLCM/OpenBLCMM/ecee5cbfbdbf9fadd7d38d6b86f8b669cb0dd19e/store/.gitkeep -------------------------------------------------------------------------------- /windows-processing/OpenBLCMM.exe.manifest: -------------------------------------------------------------------------------- 1 | 2 | 3 | 25 | 26 | 27 | true/pm 28 | PerMonitorV2, PerMonitor, system 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /windows-processing/installer-pre-text.txt: -------------------------------------------------------------------------------- 1 | The Borderlands Community Mod Manager was developed by LightChaosman, with assistance from apocalyptech, Bugworm, c0dycode, and FromDarkHell. 2 | 3 | OpenBLCMM is a fully-opensourced version of BLCMM maintained by the BLCMods community (with apocalyptech as the current lead). Thanks to LightChaosman for opensourcing the BLCMM core! Other OpenBLCMM contributions have come from apple1417 and ZetaDæmon. 4 | 5 | Thanks, too, to the countless members of the community who have contributed by testing, providing support, and spreading the word. Apologies to anyone we've missed! 6 | -------------------------------------------------------------------------------- /windows-processing/native-agent-merge.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | Rem Make sure we have jq-win64, for postprocessing 4 | where /q jq-win64 5 | if ERRORLEVEL 1 ( 6 | echo jq-win64 not found! 7 | echo install it with 'winget install jqlang.jq', and restart your 8 | echo shell to make sure it's in your path. Aborting agent run... 9 | exit /B 10 | ) 11 | 12 | Rem Now get to it. 13 | pushd ..\store 14 | echo Running Native Image Agent... 15 | echo. 16 | java -agentlib:native-image-agent=config-merge-dir=../src/META-INF/native-image/blcmm/blcmm -jar OpenBLCMM.jar 17 | echo. 18 | 19 | echo Running JSON through jq... 20 | echo. 21 | cd ..\src\META-INF\native-image\blcmm\blcmm 22 | for %%f in (*.json) do ( 23 | echo %%f 24 | jq-win64 . %%f > %%f.new 25 | move /Y %%f.new %%f 26 | ) 27 | echo. 28 | 29 | echo Done! 30 | echo. 31 | 32 | popd 33 | 34 | -------------------------------------------------------------------------------- /windows-processing/native-agent-new.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | Rem Make sure we have jq-win64, for postprocessing 4 | where /q jq-win64 5 | if ERRORLEVEL 1 ( 6 | echo jq-win64 not found! 7 | echo install it with 'winget install jqlang.jq', and restart your 8 | echo shell to make sure it's in your path. Aborting agent run... 9 | exit /B 10 | ) 11 | 12 | Rem Now get to it. 13 | pushd ..\store 14 | echo Running Native Image Agent... 15 | echo. 16 | java -agentlib:native-image-agent=config-output-dir=../src/META-INF/native-image/blcmm/blcmm -jar OpenBLCMM.jar 17 | echo. 18 | 19 | echo Running JSON through jq... 20 | echo. 21 | cd ..\src\META-INF\native-image\blcmm\blcmm 22 | for %%f in (*.json) do ( 23 | echo %%f 24 | jq-win64 . %%f > %%f.new 25 | move /Y %%f.new %%f 26 | ) 27 | echo. 28 | 29 | echo Done! 30 | echo. 31 | 32 | popd 33 | 34 | -------------------------------------------------------------------------------- /windows-processing/native-compile.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | Rem Original commandline, prior to pulling that config into the jarfile 4 | Rem native-image -Djava.awt.headless=false -H:ReflectionConfigurationFiles=conf-dir/reflect-config.json -H:ResourceConfigurationFiles=conf-dir/resource-config.json -H:JNIConfigurationFiles=conf-dir/jni-config.json -jar OpenBLCMM.jar 5 | 6 | echo Compiling using native-image 7 | echo ---------------------------- 8 | echo. 9 | pushd ..\store 10 | call native-image -march=compatibility -jar OpenBLCMM.jar 11 | echo. 12 | 13 | echo Setting icon on EXE 14 | echo ------------------- 15 | echo. 16 | RCEDIT64.exe /I OpenBLCMM.exe ..\windows-processing\openblcmm.ico 17 | echo. 18 | 19 | echo Setting to Windows Subsystem (avoids cmd.exe-window spawning) 20 | echo ------------------------------------------------------------- 21 | echo. 22 | Rem See https://github.com/oracle/graal/issues/2256 23 | EDITBIN /SUBSYSTEM:WINDOWS OpenBLCMM.exe 24 | echo. 25 | 26 | echo Setting the app as High-DPI Capable 27 | echo ----------------------------------- 28 | echo. 29 | MT.exe -manifest ..\windows-processing\OpenBLCMM.exe.manifest -outputresource:OpenBLCMM.exe;#1 30 | echo. 31 | 32 | echo Collecting into subdir 33 | echo ---------------------- 34 | echo. 35 | rd compiled /s /q 36 | md compiled 37 | copy *.dll compiled 38 | copy OpenBLCMM.exe compiled 39 | echo. 40 | 41 | echo Reporting 42 | echo --------- 43 | echo. 44 | dir compiled 45 | echo. 46 | 47 | popd 48 | 49 | -------------------------------------------------------------------------------- /windows-processing/openblcmm.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BLCM/OpenBLCMM/ecee5cbfbdbf9fadd7d38d6b86f8b669cb0dd19e/windows-processing/openblcmm.ico --------------------------------------------------------------------------------