Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
346 commits
Select commit Hold shift + click to select a range
67191aa
Add inheritable text field binding to GameSettingPage for advanced se…
Glavo May 18, 2026
1adb2ed
Refactor radio button selection in GlobalGameSettingListPage to use T…
Glavo May 18, 2026
17fbe26
Add pause transition before navigating to GlobalGameSettingListPage
Glavo May 18, 2026
5f2a8d1
Remove inheritance button and related logic from GameSettingPage
Glavo May 18, 2026
2f2e726
Refactor ComponentSublist to extend Control and implement custom skin
Glavo May 19, 2026
0458088
Enhance ComponentSublist with leading, trailing, and description prop…
Glavo May 19, 2026
b20f15e
Add headerLeft property to ComponentSublist and update header handlin…
Glavo May 19, 2026
cf27f61
Make titleContainer mouse transparent and adjust pickability settings
Glavo May 19, 2026
95666f6
Rename subtitle properties to description in various settings pages
Glavo May 19, 2026
3af078c
Remove dynamic backend handling from graphics settings
Glavo May 19, 2026
81ba8e8
Move overflow hidden from header to LineButtonBase
Glavo May 19, 2026
96c730d
Implement legacy game setting migration and JSON handling
Glavo May 19, 2026
6ec9d19
Refactor game setting file reading and improve JSON parsing methods
Glavo May 20, 2026
340806c
Migrate legacy game settings to new GameSetting model and remove Vers…
Glavo May 20, 2026
45d195c
Replace empty utility method with Objects.requireNonNullElse for bett…
Glavo May 20, 2026
81401ae
Refactor generics in setting property classes to improve nullability …
Glavo May 20, 2026
661d667
Enhance nullability handling in GameSetting and ModpackHelper by usin…
Glavo May 20, 2026
19ed585
Refactor GameSetting and GameSettingPage to improve null handling and…
Glavo May 20, 2026
d4bc37e
Update GameSettingPage to improve nullability handling for Global set…
Glavo May 20, 2026
c8e0b48
Refactor GameSettingPage to replace boolean array with Holder for bet…
Glavo May 20, 2026
15432a0
Refactor GameSettingPage and IndependentSettingBinder to enhance null…
Glavo May 20, 2026
ecfc6bc
Refactor GameSettingPage to improve code readability and simplify con…
Glavo May 20, 2026
8f5d2ed
Refactor GameSettingPage and IndependentSettingBinder to simplify int…
Glavo May 20, 2026
f017a9b
Refactor IndependentSettingBinder to simplify property initialization…
Glavo May 20, 2026
8dd4e9d
Refactor GameSettingPage to enhance nullability handling for active w…
Glavo May 20, 2026
7041b89
Refactor GameSettingPage to enhance nullability handling for active w…
Glavo May 20, 2026
8d8dc40
Refactor IndependentSettingBinder to enhance nullability handling for…
Glavo May 20, 2026
7909105
update
Glavo May 21, 2026
e5b6cb7
Use deterministic UUIDs for migrated global settings
Glavo May 21, 2026
a3778e0
Add instance isolation toggle and update game directory handling
Glavo May 21, 2026
00952a7
Remove game directory handling from GameSetting and GameSettingPage
Glavo May 21, 2026
d6b2509
Add running directory configuration to advanced launch settings
Glavo May 21, 2026
635405e
Refactor inherited property retrieval in GameSetting
Glavo May 21, 2026
88bfb28
Enhance type safety in inherited and inheritable property methods
Glavo May 21, 2026
258d24e
Revise GameSetting migration plan
Glavo May 22, 2026
d60d6db
Clarify game setting migration and override rules
Glavo May 22, 2026
526f021
Refine game running directory isolation handling
Glavo May 22, 2026
4139861
Use overrideProperties for game setting inheritance
Glavo May 22, 2026
7accedf
Refine type safety in property interfaces with UnknownNullability ann…
Glavo May 22, 2026
be1c84c
Remove legacy game setting override migration
Glavo May 22, 2026
68e2ba9
Remove legacy renderer migration from GameSetting
Glavo May 22, 2026
0d8dcbb
Stop pruning game setting properties on save
Glavo May 22, 2026
80cce9b
Merge remote-tracking branch 'upstream/main' into instance-setting2
Glavo May 22, 2026
90e3dba
Remove legacy profile markers from game setting migration
Glavo May 22, 2026
12bcab5
Add running directory inherit toggle
Glavo May 22, 2026
4e8fb08
refactor: remove unused local game settings collections
Glavo May 22, 2026
59601a8
refactor: remove unused bindInstanceSettingBidirectional method
Glavo May 22, 2026
15ff69c
feat: add parent property listener updates for inheritable settings
Glavo May 22, 2026
83a61e0
refactor: simplify game directory type handling and improve run direc…
Glavo May 22, 2026
652f7b3
refactor: update defaultGameSetting to support nullable UUID and simp…
Glavo May 23, 2026
f681a1b
refactor: streamline navigation button logic and remove legacy game s…
Glavo May 23, 2026
5bd9c3a
refactor: update title key retrieval to use direct string reference
Glavo May 23, 2026
214858a
refactor: enhance global setting navigation with TransitionPane for s…
Glavo May 23, 2026
c4129eb
refactor: remove unnecessary listView refresh call in setting selector
Glavo May 23, 2026
aa17fb8
refactor: implement global game setting management with radio button …
Glavo May 23, 2026
1fedda8
refactor: simplify global setting management by replacing radio butto…
Glavo May 23, 2026
34d38c7
refactor: update global settings label from 'Manage All Global Settin…
Glavo May 23, 2026
dbae962
refactor: update global settings to use 'Preset' terminology and enha…
Glavo May 23, 2026
b820fe5
refactor: enhance dynamic height management for expanded sublist content
Glavo May 23, 2026
14afbc6
refactor: update global settings terminology to use 'Preset' for cons…
Glavo May 23, 2026
d00fdc0
refactor: reorganize global settings layout to include preset setting…
Glavo May 23, 2026
68db17e
refactor: move GameDirectoryType enum definition into LegacyGameSetti…
Glavo May 23, 2026
cd4492d
Fix legacy game setting migration and checkstyle issues
Glavo May 23, 2026
05cf489
Preserve legacy game directory semantics during migration
Glavo May 23, 2026
f0bd0e1
Refine game setting inheritance handling
Glavo May 23, 2026
2f64b65
Rename global game settings to presets
Glavo May 23, 2026
a45c942
Rename legacy game setting helpers to preset
Glavo May 23, 2026
3e859e2
Move preset i18n keys under global preset
Glavo May 23, 2026
8efd1d9
Add preset deletion controls
Glavo May 24, 2026
ff20f1e
Move preset delete action to top level
Glavo May 24, 2026
49117f1
Refactor preset removal into a pane
Glavo May 24, 2026
dc5d3c7
Move preset delete action into each list item
Glavo May 24, 2026
d19d19c
Move preset delete action into preset list items
Glavo May 24, 2026
7097b4b
Add numbered preset defaults and inline rename actions
Glavo May 24, 2026
216e597
Migrate config loading to settings.json
Glavo May 24, 2026
72a337f
Refactor config migration loading
Glavo May 24, 2026
09ebb3e
update
Glavo May 24, 2026
9a9eed3
Read config JSON as JsonObject
Glavo May 24, 2026
a724b6e
Restore legacy config migration comments
Glavo May 24, 2026
36fa9b3
Document legacy config migration
Glavo May 24, 2026
d57f1fe
Remove obsolete UI version from Config
Glavo May 24, 2026
9be02c7
Move legacy preset migration into LegacyConfigMigrator
Glavo May 24, 2026
91a517e
Refine legacy config migration records
Glavo May 24, 2026
e033f03
Annotate nullable profile entries in legacy migration
Glavo May 24, 2026
5ad36b9
Move legacy preset migration into LegacyConfigMigrator
Glavo May 24, 2026
f77b8f2
Refine SchemaVersion parsing and documentation
Glavo May 24, 2026
a305841
Document SchemaVersion compatibility policy
Glavo May 24, 2026
eb36a66
Add schema version to config
Glavo May 24, 2026
99197b9
Document ConfigHolder config loading
Glavo May 25, 2026
89ae935
Extract game setting presets into separate file
Glavo May 25, 2026
4c053cc
Move game setting preset loading out of ConfigHolder
Glavo May 25, 2026
fc12ad9
Rename GameSetting model to GameSettings
Glavo May 25, 2026
78a92e4
Rename GameSetting model to GameSettings
Glavo May 25, 2026
eda775d
Migrate embedded game settings presets to detached file
Glavo May 25, 2026
147774a
Remove embedded game settings presets deserialization and migration code
Glavo May 25, 2026
46f3bbb
Merge remote-tracking branch 'upstream/main' into instance-setting2
Glavo May 25, 2026
81b15f0
Improve logging for malformed config file in ConfigHolder
Glavo May 25, 2026
c00892c
Refactor legacy config migration logic and enhance JSON handling
Glavo May 25, 2026
f6a4a10
Refactor legacy config version handling and streamline account migrat…
Glavo May 25, 2026
06b9148
Refactor legacy config loading to use JsonUtils and improve logging m…
Glavo May 25, 2026
4ca6025
Merge remote-tracking branch 'upstream/main' into instance-setting2
Glavo May 25, 2026
2b81f7f
Refactor legacy config migration logic to streamline processing and e…
Glavo May 25, 2026
f8306f6
Refactor ConfigHolder to utilize JsonUtils for JSON file reading
Glavo May 25, 2026
c2744a5
Refactor legacy config migration to remove unsupported version check …
Glavo May 25, 2026
9bf2815
Implement Comparable interface for SchemaVersion to enable version co…
Glavo May 25, 2026
9c8b22d
update
Glavo May 26, 2026
7fc57a0
Enhance SchemaVersion with detailed Javadoc comments for constructors…
Glavo May 26, 2026
d33b7ad
Update ConfigHolder to handle null settings and ensure schema version…
Glavo May 26, 2026
4a34367
Remove unused import and clean up migration logic in ConfigHolder
Glavo May 26, 2026
f70157d
Add backup mechanism for invalid config files in ConfigHolder
Glavo May 26, 2026
8249dac
Implement backup mechanism for invalid config files in ConfigHolder
Glavo May 26, 2026
3adc005
Refactor GameSettingsPresetsHolder to use JsonUtils for JSON file rea…
Glavo May 26, 2026
5b658c8
Move game settings presets init into ConfigHolder
Glavo May 26, 2026
0f6c0fe
Detach game settings presets from Config
Glavo May 26, 2026
bff3c97
Add JsonSerializable annotation to GameSettingsPresets class
Glavo May 26, 2026
3fc0f9c
Remove checkWritable method from GameSettingsPresetsHolder to simplif…
Glavo May 26, 2026
032c4f3
Extract schema version checks into SchemaVersion
Glavo May 26, 2026
e87e0ae
Handle missing schema version in config loading
Glavo May 26, 2026
d83934f
Handle invalid schema versions in config loading
Glavo May 26, 2026
2c5c69f
Validate game settings preset schema version
Glavo May 26, 2026
f30903b
Refactor Renderer JSON serialization to use a dedicated TypeAdapter
Glavo May 26, 2026
4d2bf00
Migrate instance settings to .hmcl metadata
Glavo May 26, 2026
05add14
Move instance game settings under .hmcl and update migration docs
Glavo May 26, 2026
cf5267d
Use format identifiers for serialized settings
Glavo May 26, 2026
9aca4ee
Switch file format metadata to structured JSON objects
Glavo May 26, 2026
4dce8a0
Rename file format type to JsonFileFormat
Glavo May 26, 2026
983e82f
Simplify validity check for format ID in JsonFileFormat
Glavo May 26, 2026
620c5b3
Use $format for file format metadata
Glavo May 26, 2026
a4d6333
Rename file format parsing and update config format id
Glavo May 26, 2026
4c825c6
Update file format references from 'hmcl.config' to 'hmcl.settings' i…
Glavo May 26, 2026
e7f15d2
Reorder game settings presets declaration and getter methods
Glavo May 26, 2026
a9f830d
Refactor legacy game settings migration and remove unused methods
Glavo May 26, 2026
20f39e6
Rename legacy version settings filename and simplify JSON parsing
Glavo May 26, 2026
9e7281e
Refactor legacy game settings migration to simplify parent setting ch…
Glavo May 26, 2026
d38ef3a
Update legacy config migrator version comments to reflect HMCL 3.15.0…
Glavo May 26, 2026
5ca517f
Refactor profile model: replace configuration map with profile list a…
Glavo May 26, 2026
cf68d85
Fix profile deserialization: throw exception for null profile ID and …
Glavo May 26, 2026
c0892c8
Refactor profile management: streamline profile list handling and rem…
Glavo May 26, 2026
e1206e0
Refactor profile access: replace local profiles method with direct co…
Glavo May 26, 2026
53933cc
Refactor profile access: replace local profiles method with direct co…
Glavo May 26, 2026
dc67cb6
Refactor profile access: update ProfileVersion to use record and simp…
Glavo May 26, 2026
6cacf60
Refactor Profile constructor: remove redundant single-argument constr…
Glavo May 26, 2026
ead16f6
Add GUID class for immutable UUID representation and JSON serialization
Glavo May 26, 2026
6241e72
Refactor profile ID handling: replace UUID with GUID for improved typ…
Glavo May 26, 2026
ddd4aea
update
Glavo May 26, 2026
20cd374
Extract profiles into game-directories storage
Glavo May 26, 2026
8ae3482
Refactor detached JSON settings loading
Glavo May 26, 2026
becc6c3
Simplify detached setting file serialization
Glavo May 26, 2026
15c015f
Rename game settings presets file to game-settings
Glavo May 26, 2026
b0c5e73
Merge workspace setting holders into ConfigHolder
Glavo May 26, 2026
0053ad6
Move default game settings into Config
Glavo May 26, 2026
8284fd7
Reset game setting format versions to 1.0
Glavo May 26, 2026
7f3903c
Rename game settings preset collection to presets
Glavo May 26, 2026
853800f
已把 `defaultGameSettings` 统一改成 `defaultGameSettingsPreset`,包括 `Config` 的序
Glavo May 27, 2026
c2208a2
Move selected game directory into Config
Glavo May 27, 2026
fe95f49
Move selected game directory into config
Glavo May 27, 2026
e3e86ab
Refine PortablePath absolute path normalization
Glavo May 27, 2026
c045a62
Fix PortablePath Windows absolute path detection
Glavo May 27, 2026
39d134d
Simplify PortablePath to store raw path strings
Glavo May 27, 2026
0dad55f
Add methods for converting between PortablePath and java.nio.file.Path
Glavo May 27, 2026
21bb25c
Simplify PortablePath handling
Glavo May 27, 2026
fd8291a
Add uuid creator dependency
Glavo May 27, 2026
7c3afaf
Add uuid-creator dependency
Glavo May 27, 2026
8119855
Require explicit GUIDs for profiles and presets
Glavo May 27, 2026
00e9a9c
Use GUID v7 for new profiles
Glavo May 27, 2026
a7df3ae
Use GUID v7 for new profile IDs
Glavo May 27, 2026
35dedb5
Migrate legacy selected versions to the current configuration format
Glavo May 27, 2026
3ea5cd9
Refactor: move legacy config migration methods to LegacyConfigMigrator
Glavo May 27, 2026
cc43943
Refactor: rename selectedVersion to selectedInstance
Glavo May 27, 2026
169ae54
Remove redundant Path constructor for Profile
Glavo May 27, 2026
659c1ba
Remove unused legacy profile-level setting conversion method
Glavo May 27, 2026
3399c07
Refactor: make observableHelper final for better immutability
Glavo May 27, 2026
a19665b
Refactor: make profile ID final and remove property wrapper
Glavo May 27, 2026
91b8bbc
Refactor: update legacy profile ID generation to use GUID v5 for impr…
Glavo May 27, 2026
6d667bb
Refactor: migrate game directory extraction to LegacyConfigMigrator f…
Glavo May 27, 2026
81688b7
Refactor: make profile name nullable for built-in profiles and update…
Glavo May 27, 2026
8417ce2
Refactor: enhance profile display name logic to prioritize explicit n…
Glavo May 27, 2026
62fed11
Refactor: optimize profile ID retrieval by storing it in a variable f…
Glavo May 27, 2026
795c571
Refactor: simplify legacy game directory migration by removing unnece…
Glavo May 27, 2026
cf9f7a3
Refactor: remove unused legacy profile ID method and simplify migrati…
Glavo May 27, 2026
c0657b4
Refactor: use collision-safe ID generation for presets and profiles
Glavo May 27, 2026
20e8b31
Refactor: update default preset labels for clarity in multiple languages
Glavo May 27, 2026
e1d72c1
Refactor: update newSettingProperty method to use nullable type param…
Glavo May 27, 2026
110f02f
Refactor: remove redundant parent property setting in game instance i…
Glavo May 27, 2026
553c776
Refactor: remove redundant parent property setting in game settings i…
Glavo May 27, 2026
940e4ce
Merge remote-tracking branch 'upstream/main' into instance-setting2
Glavo May 28, 2026
a0b6a1a
feat: introduce launcher state management and migrate legacy settings
Glavo May 28, 2026
d2156a1
feat: add logLines property to Config and update related components
Glavo May 28, 2026
be3cbc7
feat: refactor authlib injector server management to use dedicated class
Glavo May 28, 2026
8992d60
feat: enhance legacy config migration to conditionally add LittleSkin…
Glavo May 28, 2026
797b11d
feat: migrate legacy localization field to language and update relate…
Glavo May 28, 2026
e697557
feat: update default locale name from "def" to "default"
Glavo May 28, 2026
a4afb07
feat: migrate legacy allowAutoAgent setting to game settings presets
Glavo May 28, 2026
97c55a8
Merge remote-tracking branch 'upstream/main' into instance-setting2
Glavo May 28, 2026
2b9996c
feat: implement detached account storage management with JSON support
Glavo May 28, 2026
956ce7f
refactor: update game settings migration plan and storage layout docu…
Glavo May 28, 2026
b372906
docs: update compatibility constraints in PLANS.md for active develop…
Glavo May 28, 2026
c08af89
refactor: replace JSON file format with schema in account storage and…
Glavo May 28, 2026
edab3a3
refactor: update JsonSchema to handle raw schema strings and improve …
Glavo May 28, 2026
ddc8255
refactor: update JSON schema URLs to remove version from path structure
Glavo May 29, 2026
e487253
refactor: simplify URL handling in JsonSchema by consolidating schema…
Glavo May 29, 2026
ae0c215
refactor: update schema URLs to remove file suffix and simplify struc…
Glavo May 29, 2026
8399e4d
refactor: update JSON schema versions to include patch version
Glavo May 29, 2026
7f55743
refactor: clarify version handling in JsonSchema and related classes
Glavo May 29, 2026
52095ec
refactor: enhance version parsing to support patchless schema URLs
Glavo May 29, 2026
f0107b2
refactor: improve clarity of version support rejection criteria in Js…
Glavo May 29, 2026
2a1d097
refactor: simplify deep cloning of GameSettings.Instance using JsonUtils
Glavo May 29, 2026
660468d
refactor: update comment style for preferredLoginType in Config.java
Glavo May 29, 2026
279cda4
refactor: migrate legacy disableAutoGameOptions to game settings
Glavo May 29, 2026
b6487fd
refactor: enhance documentation and structure of Config.java
Glavo May 29, 2026
d7cc36d
refactor: update config accessors to use property methods
Glavo May 29, 2026
8088213
refactor: rename Config to LauncherSettings and update related refere…
Glavo May 29, 2026
70a20b9
refactor: update Gson references to use SETTINGS_GSON in multiple cla…
Glavo May 29, 2026
d05fee7
refactor: rename GlobalConfig to UserSettings and update related refe…
Glavo May 29, 2026
9329742
refactor: update fromJson method to use JsonUtils for JSON parsing
Glavo May 29, 2026
ae85a7f
refactor: update userSettings access to use ConfigHolder for property…
Glavo May 29, 2026
d75bd12
refactor: update ConfigHolder references to use settings() instead of…
Glavo May 29, 2026
a962c98
refactor: update references from ConfigHolder to SettingsManager acro…
Glavo May 29, 2026
28e069f
refactor: update init methods to public and improve documentation acr…
Glavo May 29, 2026
2143d04
refactor: remove unused serialization and deserialization methods in …
Glavo May 29, 2026
53b2604
refactor: update user settings file structure and implement legacy mi…
Glavo May 29, 2026
dc98358
refactor: improve legacy account migration logic and add correspondin…
Glavo May 29, 2026
a4b8287
refactor: streamline async method chaining in DownloadPage and clean …
Glavo May 29, 2026
f897b9e
Rename game directories JSON field to directories
Glavo May 29, 2026
9bd107d
refactor: initialize commonDirectory property and simplify getResolve…
Glavo May 29, 2026
5524783
refactor: rename commonpath to commonDirectory and implement migratio…
Glavo May 29, 2026
905e0a8
refactor: rename commonDirType to commonDirectoryType and update rela…
Glavo May 29, 2026
d718dfd
test: add migration test for legacy commonDirType to commonDirectoryType
Glavo May 29, 2026
4cda7a7
refactor: migrate legacy download source fields to new structure and …
Glavo May 29, 2026
facff96
refactor: rename proxyPass to proxyPassword and update related logic
Glavo May 29, 2026
d65aa5b
refactor: rename DEFAULT_MEMBER_NAME to PROPERTY_SCHEMA in JSON schem…
Glavo May 29, 2026
4b3d2b3
refactor: migrate legacy enum ordinal fields for backgroundType and p…
Glavo May 29, 2026
deffd8a
refactor: separate local and global game directories handling and upd…
Glavo May 29, 2026
9648d23
refactor: update paths to use user home and local home directories in…
Glavo May 29, 2026
e56fa1a
refactor: update log messages and paths to use user home instead of g…
Glavo May 29, 2026
87fe7d0
refactor: update global game accounts references to user game accounts
Glavo May 29, 2026
c2f026d
refactor: migrate legacy game settings to stable IDs and update relat…
Glavo May 29, 2026
9919b93
refactor: update JSON adapter to allow nullable GameDirectories
Glavo Jun 1, 2026
32052cd
Clean up migration notes
Glavo Jun 1, 2026
525bb90
Refactor legacy config migration into LegacyConfigMigrator
Glavo Jun 1, 2026
8211a01
Rename launcher state storage to launcher-state.json
Glavo Jun 1, 2026
8682e80
Fix line component subtitle layout
Glavo Jun 1, 2026
2be0a7f
Fix sublist height animation layout jump
Glavo Jun 1, 2026
c923e7d
Implement structured account reference migration and update account i…
Glavo Jun 1, 2026
dd2ebfe
Remove getIdentifier method from account classes
Glavo Jun 1, 2026
7ed156b
Refactor JSON utility methods for improved readability and consistency
Glavo Jun 1, 2026
09cd66f
Refactor legacy user accounts loading to use utility method for impro…
Glavo Jun 2, 2026
0b824cf
Remove unused import statement from LegacyConfigMigrator.java
Glavo Jun 2, 2026
f4c7bd9
Refactor game settings loading to use utility method for improved rea…
Glavo Jun 2, 2026
69b9df6
Refactor LineComponent and ComponentList to improve layout handling a…
Glavo Jun 2, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions HMCL/src/main/java/org/jackhuang/hmcl/EntryPoint.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public static void main(String[] args) {
System.getProperties().putIfAbsent("http.agent", "HMCL/" + Metadata.VERSION);

createHMCLDirectories();
LOG.start(Metadata.HMCL_CURRENT_DIRECTORY.resolve("logs"));
LOG.start(Metadata.HMCL_LOCAL_HOME.resolve("logs"));

checkWine();

Expand Down Expand Up @@ -140,29 +140,29 @@ private static void setupJavaFXVMOptions() {
}

private static void createHMCLDirectories() {
if (!Files.isDirectory(Metadata.HMCL_CURRENT_DIRECTORY)) {
if (!Files.isDirectory(Metadata.HMCL_LOCAL_HOME)) {
try {
Files.createDirectories(Metadata.HMCL_CURRENT_DIRECTORY);
Files.createDirectories(Metadata.HMCL_LOCAL_HOME);
if (OperatingSystem.CURRENT_OS == OperatingSystem.WINDOWS) {
try {
Files.setAttribute(Metadata.HMCL_CURRENT_DIRECTORY, "dos:hidden", true);
Files.setAttribute(Metadata.HMCL_LOCAL_HOME, "dos:hidden", true);
} catch (IOException e) {
LOG.warning("Failed to set hidden attribute of " + Metadata.HMCL_CURRENT_DIRECTORY, e);
LOG.warning("Failed to set hidden attribute of " + Metadata.HMCL_LOCAL_HOME, e);
}
}
} catch (IOException e) {
// Logger has not been started yet, so print directly to System.err
System.err.println("Failed to create HMCL directory: " + Metadata.HMCL_CURRENT_DIRECTORY);
System.err.println("Failed to create HMCL directory: " + Metadata.HMCL_LOCAL_HOME);
e.printStackTrace(System.err);
showErrorAndExit(i18n("fatal.create_hmcl_current_directory_failure", Metadata.HMCL_CURRENT_DIRECTORY));
showErrorAndExit(i18n("fatal.create_hmcl_current_directory_failure", Metadata.HMCL_LOCAL_HOME));
}
}

if (!Files.isDirectory(Metadata.HMCL_GLOBAL_DIRECTORY)) {
if (!Files.isDirectory(Metadata.HMCL_USER_HOME)) {
try {
Files.createDirectories(Metadata.HMCL_GLOBAL_DIRECTORY);
Files.createDirectories(Metadata.HMCL_USER_HOME);
} catch (IOException e) {
LOG.warning("Failed to create HMCL global directory " + Metadata.HMCL_GLOBAL_DIRECTORY, e);
LOG.warning("Failed to create HMCL user home " + Metadata.HMCL_USER_HOME, e);
}
}
}
Expand Down
69 changes: 50 additions & 19 deletions HMCL/src/main/java/org/jackhuang/hmcl/Launcher.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.beans.binding.Bindings;
import javafx.beans.value.ObservableBooleanValue;
import javafx.geometry.Rectangle2D;
import javafx.scene.control.Alert;
Expand All @@ -33,16 +34,25 @@
import javafx.stage.Screen;
import javafx.stage.Stage;
import javafx.util.Duration;
import org.jackhuang.hmcl.setting.ConfigHolder;
import org.jackhuang.hmcl.game.HMCLCacheRepository;
import org.jackhuang.hmcl.setting.Accounts;
import org.jackhuang.hmcl.setting.AuthlibInjectorServers;
import org.jackhuang.hmcl.setting.DownloadProviders;
import org.jackhuang.hmcl.setting.LauncherSettings;
import org.jackhuang.hmcl.setting.Profiles;
import org.jackhuang.hmcl.setting.ProxyManager;
import org.jackhuang.hmcl.setting.SettingsManager;
import org.jackhuang.hmcl.setting.SambaException;
import org.jackhuang.hmcl.task.AsyncTaskExecutor;
import org.jackhuang.hmcl.task.Schedulers;
import org.jackhuang.hmcl.ui.Controllers;
import org.jackhuang.hmcl.ui.FXUtils;
import org.jackhuang.hmcl.ui.animation.AnimationUtils;
import org.jackhuang.hmcl.theme.Themes;
import org.jackhuang.hmcl.upgrade.UpdateChecker;
import org.jackhuang.hmcl.upgrade.UpdateHandler;
import org.jackhuang.hmcl.util.*;
import org.jackhuang.hmcl.util.io.FileUtils;
import org.jackhuang.hmcl.util.io.JarUtils;
import org.jackhuang.hmcl.util.platform.*;

Expand Down Expand Up @@ -95,41 +105,42 @@ public void start(Stage primaryStage) {

try {
try {
ConfigHolder.init();
SettingsManager.init();
initializeSettingsRuntime();
} catch (SambaException e) {
showAlert(AlertType.WARNING, i18n("fatal.samba"));
} catch (IOException e) {
LOG.error("Failed to load config", e);
checkConfigInTempDir();
checkConfigOwner();
showAlert(AlertType.ERROR, i18n("fatal.config_loading_failure", ConfigHolder.configLocation().getParent()));
showAlert(AlertType.ERROR, i18n("fatal.config_loading_failure", SettingsManager.configLocation().getParent()));
EntryPoint.exit(1);
}

// https://lapcatsoftware.com/articles/app-translocation.html
if (OperatingSystem.CURRENT_OS == OperatingSystem.MACOS
&& ConfigHolder.isNewlyCreated()
&& SettingsManager.isNewlyCreated()
&& System.getProperty("user.dir").startsWith("/private/var/folders/")) {
if (!confirmWithCountdown(AlertType.WARNING, i18n("fatal.mac_app_translocation"), 5))
return;
} else {
checkConfigInTempDir();
}

if (ConfigHolder.isOwnerChanged()) {
if (SettingsManager.isOwnerChanged()) {
if (showAlert(AlertType.WARNING, i18n("fatal.config_change_owner_root"), ButtonType.YES, ButtonType.NO) == ButtonType.NO)
return;
}

if (ConfigHolder.isUnsupportedVersion()) {
if (SettingsManager.isUnsupportedVersion()) {
showAlert(AlertType.WARNING, i18n("fatal.config_unsupported_version"));
}

if (Metadata.HMCL_CURRENT_DIRECTORY.toString().indexOf('=') >= 0) {
if (Metadata.HMCL_LOCAL_HOME.toString().indexOf('=') >= 0) {
showAlert(AlertType.WARNING, i18n("fatal.illegal_char"));
}

// runLater to ensure ConfigHolder.init() finished initialization
// runLater to ensure SettingsManager.init() finished initialization
Platform.runLater(() -> {
// When launcher visibility is set to "hide and reopen" without Platform.implicitExit = false,
// Stage.show() cannot work again because JavaFX Toolkit have already shut down.
Expand All @@ -148,6 +159,26 @@ public void start(Stage primaryStage) {
}
}

/// Initializes modules and runtime services that depend on loaded settings.
private static void initializeSettingsRuntime() {
DownloadProviders.init();
ProxyManager.init();
Accounts.init();
Profiles.init();
AuthlibInjectorServers.init();
AnimationUtils.init();

CacheRepository.setInstance(HMCLCacheRepository.REPOSITORY);
HMCLCacheRepository.REPOSITORY.directoryProperty().bind(Bindings.createStringBinding(() -> {
String commonDirectory = SettingsManager.settings().getResolvedCommonDirectory();
if (commonDirectory != null && FileUtils.canCreateDirectory(commonDirectory)) {
return commonDirectory;
} else {
return LauncherSettings.getDefaultCommonDirectory();
}
}, SettingsManager.settings().commonDirectoryProperty(), SettingsManager.settings().commonDirectoryTypeProperty()));
}

private static void appendScreen(StringBuilder builder, Screen screen) {
Rectangle2D bounds = screen.getBounds();
double scale = screen.getOutputScaleX();
Expand Down Expand Up @@ -206,7 +237,7 @@ private static boolean confirmWithCountdown(Alert.AlertType alertType, String co
}

private static boolean isConfigInTempDir() {
String configPath = ConfigHolder.configLocation().toString();
String configPath = SettingsManager.configLocation().toString();

String tmpdir = System.getProperty("java.io.tmpdir");
if (StringUtils.isNotBlank(tmpdir) && configPath.startsWith(tmpdir))
Expand Down Expand Up @@ -243,7 +274,7 @@ private static boolean isConfigInTempDir() {
}

private static void checkConfigInTempDir() {
if (ConfigHolder.isNewlyCreated() && isConfigInTempDir()
if (SettingsManager.isNewlyCreated() && isConfigInTempDir()
&& !confirmWithCountdown(AlertType.WARNING, i18n("fatal.config_in_temp_dir"), 5)) {
EntryPoint.exit(0);
}
Expand All @@ -256,21 +287,21 @@ private static void checkConfigOwner() {
String userName = System.getProperty("user.name");
String owner;
try {
owner = Files.getOwner(ConfigHolder.configLocation()).getName();
owner = Files.getOwner(SettingsManager.configLocation()).getName();
} catch (IOException ioe) {
LOG.warning("Failed to get file owner", ioe);
return;
}

if (Files.isWritable(ConfigHolder.configLocation()) || userName.equals("root") || userName.equals(owner))
if (Files.isWritable(SettingsManager.configLocation()) || userName.equals("root") || userName.equals(owner))
return;

ArrayList<String> files = new ArrayList<>();
files.add(ConfigHolder.configLocation().toString());
if (Files.exists(Metadata.HMCL_GLOBAL_DIRECTORY))
files.add(Metadata.HMCL_GLOBAL_DIRECTORY.toString());
if (Files.exists(Metadata.HMCL_CURRENT_DIRECTORY))
files.add(Metadata.HMCL_CURRENT_DIRECTORY.toString());
files.add(SettingsManager.configLocation().toString());
if (Files.exists(Metadata.HMCL_USER_HOME))
files.add(Metadata.HMCL_USER_HOME.toString());
if (Files.exists(Metadata.HMCL_LOCAL_HOME))
files.add(Metadata.HMCL_LOCAL_HOME.toString());

Path mcDir = Paths.get(".minecraft").toAbsolutePath().normalize();
if (Files.exists(mcDir))
Expand Down Expand Up @@ -323,8 +354,8 @@ public static void main(String[] args) {
LOG.info("Java VM Version: " + System.getProperty("java.vm.name") + " (" + System.getProperty("java.vm.info") + "), " + System.getProperty("java.vm.vendor"));
LOG.info("Java Home: " + System.getProperty("java.home"));
LOG.info("Current Directory: " + Metadata.CURRENT_DIRECTORY);
LOG.info("HMCL Global Directory: " + Metadata.HMCL_GLOBAL_DIRECTORY);
LOG.info("HMCL Current Directory: " + Metadata.HMCL_CURRENT_DIRECTORY);
LOG.info("HMCL User Home: " + Metadata.HMCL_USER_HOME);
LOG.info("HMCL Local Home: " + Metadata.HMCL_LOCAL_HOME);
LOG.info("HMCL Jar Path: " + Lang.requireNonNullElse(JarUtils.thisJarPath(), "Not Found"));
LOG.info("HMCL Log File: " + Lang.requireNonNullElse(LOG.getLogFile(), "In Memory"));
LOG.info("JVM Max Memory: " + MEGABYTES.formatBytes(Runtime.getRuntime().maxMemory()));
Expand Down
16 changes: 8 additions & 8 deletions HMCL/src/main/java/org/jackhuang/hmcl/Metadata.java
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ private Metadata() {

public static final Path CURRENT_DIRECTORY = Path.of(System.getProperty("user.dir")).toAbsolutePath().normalize();
public static final Path MINECRAFT_DIRECTORY = OperatingSystem.getWorkingDirectory("minecraft");
public static final Path HMCL_GLOBAL_DIRECTORY;
public static final Path HMCL_CURRENT_DIRECTORY;
public static final Path HMCL_USER_HOME;
public static final Path HMCL_LOCAL_HOME;
public static final Path DEPENDENCIES_DIRECTORY;

static {
Expand All @@ -70,26 +70,26 @@ private Metadata() {
if (OperatingSystem.CURRENT_OS.isLinuxOrBSD()) {
String xdgData = System.getenv("XDG_DATA_HOME");
if (StringUtils.isNotBlank(xdgData)) {
HMCL_GLOBAL_DIRECTORY = Path.of(xdgData, "hmcl").toAbsolutePath().normalize();
HMCL_USER_HOME = Path.of(xdgData, "hmcl").toAbsolutePath().normalize();
} else {
HMCL_GLOBAL_DIRECTORY = Path.of(System.getProperty("user.home"), ".local", "share", "hmcl").toAbsolutePath().normalize();
HMCL_USER_HOME = Path.of(System.getProperty("user.home"), ".local", "share", "hmcl").toAbsolutePath().normalize();
}
} else {
HMCL_GLOBAL_DIRECTORY = OperatingSystem.getWorkingDirectory("hmcl");
HMCL_USER_HOME = OperatingSystem.getWorkingDirectory("hmcl");
}
} else {
HMCL_GLOBAL_DIRECTORY = Path.of(hmclHome).toAbsolutePath().normalize();
HMCL_USER_HOME = Path.of(hmclHome).toAbsolutePath().normalize();
}

String hmclCurrentDir = System.getProperty("hmcl.dir", System.getenv("HMCL_LOCAL_HOME"));
HMCL_CURRENT_DIRECTORY = StringUtils.isNotBlank(hmclCurrentDir)
HMCL_LOCAL_HOME = StringUtils.isNotBlank(hmclCurrentDir)
? Path.of(hmclCurrentDir).toAbsolutePath().normalize()
: CURRENT_DIRECTORY.resolve(".hmcl");

String hmclDependencies = System.getProperty("hmcl.dependencies.dir", System.getenv("HMCL_DEPENDENCIES_DIR"));
DEPENDENCIES_DIRECTORY = StringUtils.isNotBlank(hmclDependencies)
? Path.of(hmclDependencies).toAbsolutePath().normalize()
: HMCL_CURRENT_DIRECTORY.resolve("dependencies");
: HMCL_LOCAL_HOME.resolve("dependencies");
}

public static boolean isStable() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@
import java.util.*;
import java.util.stream.Stream;

import static org.jackhuang.hmcl.setting.ConfigHolder.config;
import static org.jackhuang.hmcl.util.logging.Logger.LOG;

/**
Expand Down Expand Up @@ -64,7 +63,7 @@ protected Map<String, String> getConfigurations() {
}

private void generateOptionsTxt() {
if (config().isDisableAutoGameOptions())
if (options.isDisableAutoGameOptions())
return;

Path runDir = repository.getRunDirectory(version.getId());
Expand Down Expand Up @@ -159,7 +158,7 @@ public void makeLaunchScript(Path scriptFile) throws IOException {
protected void appendJvmArgs(CommandBuilder result) {
super.appendJvmArgs(result);

if (config().getAllowAutoAgent()
if (options.isAllowAutoAgent()
&& !options.isNoGeneratedJVMArgs()
&& !options.isNoGeneratedOptimizingJVMArgs()
&& NativePatcher.needPatchMemoryUtil(version, options.getJava().getParsedVersion())) {
Expand Down
Loading
Loading