Skip to content

Commit e3bce5c

Browse files
authored
Merge pull request #4 from GTModpackTeam/tier-fix-npe
2 parents 22907cc + 3a8b2a3 commit e3bce5c

7 files changed

Lines changed: 118 additions & 29 deletions

File tree

.github/workflows/build_and_test.yml

Lines changed: 2 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -42,46 +42,22 @@ jobs:
4242
- name: Upload Jars
4343
uses: actions/upload-artifact@v7
4444
with:
45-
name: GTExpert-Core
45+
name: AdvancedBackups-Patch
4646
path: build/libs/*.jar
4747
retention-days: 31
4848

4949
- name: Run post-build checks
5050
id: build_mod
5151
run: ./gradlew --info build
5252

53-
- name: Attempt to make a PR fixing spotless errors
54-
if: ${{ failure() && steps.build_mod.conclusion == 'failure' && github.event_name == 'pull_request' && !github.event.pull_request.draft }}
55-
run: |
56-
git reset --hard
57-
git checkout "${github.ref_name}"
58-
./gradlew --info spotlessApply || exit 1
59-
git diff --exit-code && exit 1
60-
git config user.name "GitHub Actions"
61-
git config user.email "<>"
62-
git switch -c "${FIXED_BRANCH}"
63-
git commit -am "spotlessApply"
64-
git push --force-with-lease origin "${FIXED_BRANCH}"
65-
gh pr create \
66-
--head "${FIXED_BRANCH}" \
67-
--base "${github.ref_name}" \
68-
--title "Spotless apply for branch ${{ github.event.pull_request.head.ref }} for #${{ github.event.pull_request.number }}" \
69-
--body "Automatic spotless apply to fix formatting errors, applies to PR #${{ github.event.pull_request.number }}" \
70-
2>&1 | tee pr-message.log || true
71-
gh pr comment "${github.ref_name}" -F pr-message.log || true
72-
shell: bash # ensures set -eo pipefail
73-
env:
74-
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
75-
FIXED_BRANCH: ${{ github.head_ref }}-spotless-fixes
76-
7753
- name: Run server for ${{ inputs.timeout }} seconds
7854
if: ${{ !inputs.client-only }}
7955
run: |
8056
mkdir -p run/server/
8157
echo "eula=true" > run/server/eula.txt
8258
# Set a constant seed with a village at spawn
8359
echo "stop" > run/server/stop.txt
84-
timeout ${{ inputs.timeout }} ./gradlew runServer 2>&1 < run/stop.txt | tee -a server.log || true
60+
timeout ${{ inputs.timeout }} ./gradlew runServer 2>&1 < run/server/stop.txt | tee -a server.log || true
8561
8662
- name: Test no errors reported during server run
8763
if: ${{ !inputs.client-only }}

.github/workflows/publish.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,8 @@ jobs:
4949

5050
- name: Check if tag already exists
5151
run: |
52-
if git rev-parse --verify --quiet "v${{ github.event.inputs.version }}"; then
53-
echo "Version ${{ github.event.inputs.version }} already exists, aborting workflow."
52+
if git rev-parse --verify --quiet "v${{ env.FULL_VERSION }}"; then
53+
echo "Version ${{ env.FULL_VERSION }} already exists, aborting workflow."
5454
exit 1
5555
fi
5656

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
# 1.0.5
2+
- Fix a rare crash when entering a singleplayer world. ([HeatherComputer/AdvancedBackups#110](https://github.com/HeatherComputer/AdvancedBackups/issues/110))
3+
- Fix a potential crash during backup when a backup directory is missing.
4+
- Fix a potential crash when cleaning up old backup files.
5+
6+
* * *
7+
18
# 1.0.4
29
- Fix mod info.
310

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package com.github.gtexpert.advancedbackupspatch.mixin;
2+
3+
import java.io.File;
4+
5+
import computer.heather.advancedbackups.core.backups.BackupWrapper;
6+
7+
import org.spongepowered.asm.mixin.Mixin;
8+
import org.spongepowered.asm.mixin.injection.At;
9+
import org.spongepowered.asm.mixin.injection.Redirect;
10+
11+
@Mixin(value = BackupWrapper.class, remap = false)
12+
public abstract class BackupWrapperMixin {
13+
14+
/**
15+
* Prevent NPE when File.listFiles() returns null in deleteDirectoryContents.
16+
* This happens when the path is not a directory or an I/O error occurs.
17+
*/
18+
@Redirect(method = "deleteDirectoryContents",
19+
at = @At(value = "INVOKE",
20+
target = "Ljava/io/File;listFiles()[Ljava/io/File;"))
21+
private static File[] safeListFiles(File directory) {
22+
File[] result = directory.listFiles();
23+
return result != null ? result : new File[0];
24+
}
25+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package com.github.gtexpert.advancedbackupspatch.mixin;
2+
3+
import computer.heather.advancedbackups.core.ABCore;
4+
import computer.heather.advancedbackups.core.config.ClientConfigManager;
5+
6+
import org.apache.logging.log4j.LogManager;
7+
import org.apache.logging.log4j.Logger;
8+
9+
import org.spongepowered.asm.mixin.Mixin;
10+
import org.spongepowered.asm.mixin.Unique;
11+
import org.spongepowered.asm.mixin.injection.At;
12+
import org.spongepowered.asm.mixin.injection.Inject;
13+
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
14+
15+
@Mixin(value = ClientConfigManager.class, remap = false)
16+
public abstract class ClientConfigManagerMixin {
17+
18+
@Unique
19+
private static final Logger advancedbackupspatch$LOGGER = LogManager.getLogger("advancedbackups");
20+
21+
/**
22+
* Ensure ABCore loggers are non-null before ClientConfigManager uses them.
23+
* <p>
24+
* In singleplayer, PacketToastTest is handled on the Netty thread,
25+
* which may not see logger writes from the IntegratedServer thread
26+
* due to the Java Memory Model (non-volatile fields).
27+
* This provides a fallback to prevent NPE.
28+
*/
29+
@Inject(method = "loadOrCreateConfig", at = @At("HEAD"))
30+
private static void ensureLoggers(CallbackInfo ci) {
31+
if (ABCore.infoLogger == null) {
32+
ABCore.infoLogger = advancedbackupspatch$LOGGER::info;
33+
}
34+
if (ABCore.warningLogger == null) {
35+
ABCore.warningLogger = advancedbackupspatch$LOGGER::warn;
36+
}
37+
if (ABCore.errorLogger == null) {
38+
ABCore.errorLogger = advancedbackupspatch$LOGGER::error;
39+
}
40+
}
41+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package com.github.gtexpert.advancedbackupspatch.mixin;
2+
3+
import java.io.File;
4+
5+
import computer.heather.advancedbackups.core.backups.ThreadedBackup;
6+
7+
import org.spongepowered.asm.mixin.Mixin;
8+
import org.spongepowered.asm.mixin.injection.At;
9+
import org.spongepowered.asm.mixin.injection.Redirect;
10+
11+
@Mixin(value = ThreadedBackup.class, remap = false)
12+
public abstract class ThreadedBackupMixin {
13+
14+
/**
15+
* Prevent NPE when File.list() returns null in performRename.
16+
* This happens when the directory does not exist or an I/O error occurs.
17+
*/
18+
@Redirect(method = "performRename",
19+
at = @At(value = "INVOKE",
20+
target = "Ljava/io/File;list()[Ljava/lang/String;"))
21+
private String[] safeListInRename(File file) {
22+
String[] result = file.list();
23+
return result != null ? result : new String[0];
24+
}
25+
26+
/**
27+
* Prevent NPE when File.list() returns null in performDelete.
28+
* This happens when the directory does not exist or an I/O error occurs.
29+
*/
30+
@Redirect(method = "performDelete",
31+
at = @At(value = "INVOKE",
32+
target = "Ljava/io/File;list()[Ljava/lang/String;"))
33+
private String[] safeListInDelete(File file) {
34+
String[] result = file.list();
35+
return result != null ? result : new String[0];
36+
}
37+
}

src/main/resources/mixins.advancedbackupspatch.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
"package": "com.github.gtexpert.advancedbackupspatch.mixin",
44
"compatibilityLevel": "JAVA_8",
55
"mixins": [
6-
"AdvancedBackupsMixin"
6+
"AdvancedBackupsMixin",
7+
"BackupWrapperMixin",
8+
"ClientConfigManagerMixin",
9+
"ThreadedBackupMixin"
710
]
811
}

0 commit comments

Comments
 (0)