Skip to content

Commit

Permalink
Fix NullPointerException cause game crashed (#15)
Browse files Browse the repository at this point in the history
* Fix NullPointerException cause game crashed

Fixes #14

Fix the NullPointerException error caused by `stitchResults` being null during game initialization.

* Add a null check for `stitchResults` before attempting to read its length in the `loadCachedData` method.
* Return an empty `ConcurrentHashMap` if `stitchResults` is null in the `loadCachedData` method.

---

For more details, open the [Copilot Workspace session](https://copilot-workspace.githubnext.com/steves-underwater-paradise/blinkload/issues/14?shareId=XXXX-XXXX-XXXX-XXXX).

* The mod description supports localization

* upgrade gradle

* loom 1.9

* fix: 🐛 Catch `JsonSyntaxException` and log error instead of crashing on `IOException`

The cache is now re-created when an exception is thrown while loading the cache, instead of throwing the exception.

* docs: 📝 Update changelog

---------

Co-authored-by: Steveplays28 <[email protected]>
  • Loading branch information
Wulian233 and Steveplays28 authored Dec 28, 2024
1 parent 6068d5f commit 9a0474d
Show file tree
Hide file tree
Showing 9 changed files with 55 additions and 44 deletions.
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,17 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## `v1.2.0` - 28/12/2024

### Added

- Localization support for the mod description (by [Wulian233](https://github.com/Wulian233) in [#15](https://github.com/steves-underwater-paradise/blinkload/pull/15))
- `zh_cn` mod description translation

### Fixed

- Various crashes that could occur due to an invalid cache file or `IOException`s when reading from disk (by [Wulian233](https://github.com/Wulian233) in [#15](https://github.com/steves-underwater-paradise/blinkload/pull/15))

## `v1.1.0` - 08/09/2024

### Changed
Expand Down
8 changes: 4 additions & 4 deletions CHANGELOG_LATEST.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
### Changed
### Added

- The hash to use the list of enabled resource packs on top of the mod list
- Localization support for the mod description (by [Wulian233](https://github.com/Wulian233) in [#15](https://github.com/steves-underwater-paradise/blinkload/pull/15))
- `zh_cn` mod description translation

### Fixed

- Mipmap levels not being saved to the cache, causing broken mipmaps when loading atlas textures from the cache
- An occasional native crash when saving atlas textures to the cache
- Various crashes that could occur due to an invalid cache file or `IOException`s when reading from disk (by [Wulian233](https://github.com/Wulian233) in [#15](https://github.com/steves-underwater-paradise/blinkload/pull/15))
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.gson.JsonIOException;
import com.google.gson.JsonParseException;
import com.google.gson.JsonSyntaxException;
import java.io.*;
import java.nio.file.Files;
import java.util.Map;
Expand All @@ -28,8 +30,7 @@
@Environment(EnvType.CLIENT)
public class BlinkLoadCache {
private static final Logger LOGGER = LoggerFactory.getLogger(String.format("%s/cache", MOD_ID));
private static final @NotNull File CACHED_DATA_FILE = new File(
String.format("%s/atlas_textures_cache.json", CacheUtil.getCachePath()));
private static final @NotNull File CACHED_DATA_FILE = new File(String.format("%s/atlas_textures_cache.json", CacheUtil.getCachePath()));
private static final @NotNull String MOD_LIST_HASH = HashUtil.calculateHash(HashUtil.getModAndEnabledResourcePackListCommaSeparated());

private static @Nullable CompletableFuture<Map<AtlasTextureIdentifier, StitchResult>> cachedDataCompletableFuture = null;
Expand Down Expand Up @@ -74,20 +75,13 @@ public static void cacheData(@NotNull StitchResult stitchResult) {

private static @NotNull CompletableFuture<Map<AtlasTextureIdentifier, StitchResult>> loadCachedDataAsync() {
if (cachedDataCompletableFuture == null) {
cachedDataCompletableFuture = CompletableFuture.supplyAsync(
BlinkLoadCache::loadCachedData, ThreadUtil.getAtlasTextureIOThreadPoolExecutor()
).whenCompleteAsync(
(cachedData, throwable) -> {
if (throwable != null) {
LOGGER.error(
"Exception thrown while trying to load the atlas texture cache: ",
ExceptionUtils.getRootCause(throwable)
);
}

BlinkLoadCache.cachedData = cachedData;
}
);
cachedDataCompletableFuture = CompletableFuture.supplyAsync(BlinkLoadCache::loadCachedData, ThreadUtil.getAtlasTextureIOThreadPoolExecutor()).whenCompleteAsync((cachedData, throwable) -> {
if (throwable != null) {
LOGGER.error("Exception thrown while trying to load the atlas texture cache: ", ExceptionUtils.getRootCause(throwable));
}

BlinkLoadCache.cachedData = cachedData;
});
}

return cachedDataCompletableFuture;
Expand All @@ -100,22 +94,23 @@ public static void cacheData(@NotNull StitchResult stitchResult) {
}

var startTime = System.nanoTime();
@NotNull Map<AtlasTextureIdentifier, StitchResult> cachedData = new ConcurrentHashMap<>();
// Read JSON from the cached data file
try (@NotNull Reader reader = new FileReader(CACHED_DATA_FILE)) {
// Convert the JSON data to a Java object
@NotNull var stitchResults = JsonUtil.getGson().fromJson(reader, StitchResult[].class);
@Nullable var stitchResults = JsonUtil.getGson().fromJson(reader, StitchResult[].class);
if (stitchResults == null) {
return new ConcurrentHashMap<>();
}

@NotNull Map<AtlasTextureIdentifier, StitchResult> cachedData = new ConcurrentHashMap<>();
for (int stitchResultIndex = 0; stitchResultIndex < stitchResults.length; stitchResultIndex++) {
@NotNull var stitchResult = stitchResults[stitchResultIndex];
cachedData.put(new AtlasTextureIdentifier(stitchResult.getAtlasTextureId(), stitchResult.getMipLevel()), stitchResult);
}

LOGGER.info(
"Loaded atlas textures from cache (took {}ms).",
TimeUnit.MILLISECONDS.convert(System.nanoTime() - startTime, TimeUnit.NANOSECONDS)
);
} catch (IOException e) {
throw new RuntimeException(e);
LOGGER.info("Loaded atlas textures from cache (took {}ms).", TimeUnit.MILLISECONDS.convert(System.nanoTime() - startTime, TimeUnit.NANOSECONDS));
} catch (IOException | JsonSyntaxException e) {
LOGGER.error("Failed loading cached data, re-creating cache: ", e);
}

return cachedData;
Expand Down Expand Up @@ -148,10 +143,6 @@ private static void writeCacheDataToFile() {
}

isUpToDate = true;
LOGGER.info(
"Saved atlas textures to cache ({}; took {}ms).",
CACHED_DATA_FILE,
TimeUnit.MILLISECONDS.convert(System.nanoTime() - startTime, TimeUnit.NANOSECONDS)
);
LOGGER.info("Saved atlas textures to cache ({}; took {}ms).", CACHED_DATA_FILE, TimeUnit.MILLISECONDS.convert(System.nanoTime() - startTime, TimeUnit.NANOSECONDS));
}
}
4 changes: 4 additions & 0 deletions common/src/main/resources/assets/blinkload/lang/en_us.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"modmenu.nameTranslation.blinkload": "BlinkLoad",
"modmenu.descriptionTranslation.blinkload": "Caches assets to reduce game loading times."
}
4 changes: 4 additions & 0 deletions common/src/main/resources/assets/blinkload/lang/zh_cn.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"modmenu.nameTranslation.blinkload": "BlinkLoad",
"modmenu.descriptionTranslation.blinkload": "缓存资源,加载如眨眼般迅捷"
}
3 changes: 2 additions & 1 deletion fabric/src/main/resources/fabric.mod.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
"description": "${mod_description}",
"authors": [
"BartolJukica",
"Steveplays28"
"Steveplays28",
"Wulian233"
],
"contact": {
"homepage": "https://modrinth.com/mod/${mod_id}",
Expand Down
2 changes: 1 addition & 1 deletion forge/src/main/resources/META-INF/mods.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ issueTrackerURL = "https://github.com/steves-underwater-paradise/${mod_id}/issue
modId = "${mod_id}"
version = "${version}"
displayName = "${mod_name}"
authors = "BartolJukica, Steveplays28"
authors = "BartolJukica, Steveplays28, Wulian233"
description = '''
${mod_description}
'''
Expand Down
14 changes: 7 additions & 7 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@ mod_namespace=blinkload
mod_name=BlinkLoad
mod_description=Caches assets to reduce game loading times.
mod_license=LGPL-3.0
mod_version=1.1.0
mod_version=1.2.0
supported_minecraft_version=>=1.20 <=1.20.1
supported_minecraft_version_name=1.20-1.20.1

# Multiloader properties
architectury_plugin_version=3.4-SNAPSHOT
architectury_loom_version=1.6-SNAPSHOT
shadow_plugin_version=7.1.2
architectury_loom_version=1.9-SNAPSHOT
shadow_plugin_version=8.+
minecraft_version=1.20.1
java_version=17
enabled_platforms=fabric,forge
Expand All @@ -30,13 +30,13 @@ modrinth_project_id=2qcrCATG
# Fabric properties
# Check these on https://modmuss50.me/fabric.html
yarn_mappings=1.20.1+build.10
fabric_loader_version=0.14.25
fabric_loader_version=0.16.9

# (Neo)Forge properties
neoforge_version=47.1.100
neoforge_version=47.1.106

# Dependencies
mixin_extras_version=0.3.5
mixin_extras_version=0.4.1
architectury_api_version=9.2.14
fabric_api_version=0.90.7+1.20.1
fabric_api_version=0.92.2+1.20.1
mod_menu_version=7.2.2
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip
networkTimeout=10000
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

0 comments on commit 9a0474d

Please sign in to comment.