Skip to content

Commit 68de289

Browse files
Merge branch 'master' into 1.21.11
2 parents 0726483 + 95cd145 commit 68de289

9 files changed

Lines changed: 95 additions & 67 deletions

File tree

.github/workflows/publish.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,14 @@ on:
1616
description: "Publish to GitHub"
1717
type: boolean
1818
default: true
19+
publish_curseforge:
20+
description: "Dummy input. Does nothing."
21+
type: boolean
22+
default: false
23+
publish_modrinth:
24+
description: "Dummy input. Does nothing."
25+
type: boolean
26+
default: false
1927
update_website:
2028
description: "Update WurstClient.net post (only works if there already is one)"
2129
type: boolean

.github/workflows/update_modrinth_deps.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ jobs:
1212
strategy:
1313
fail-fast: false
1414
matrix:
15-
branch: ["master", "1.21.11"]
15+
branch: ["26.2", "master", "1.21.11"]
1616
steps:
1717
- name: Update Modrinth Dependencies
1818
uses: Wurst-Imperium/update-modrinth-deps@v1

gradle/wrapper/gradle-wrapper.jar

-504 Bytes
Binary file not shown.
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
distributionBase=GRADLE_USER_HOME
22
distributionPath=wrapper/dists
3-
distributionUrl=https\://services.gradle.org/distributions/gradle-9.4.1-bin.zip
3+
distributionUrl=https\://services.gradle.org/distributions/gradle-9.5.0-bin.zip
44
networkTimeout=10000
5+
retries=0
6+
retryBackOffMs=500
57
validateDistributionUrl=true
68
zipStoreBase=GRADLE_USER_HOME
79
zipStorePath=wrapper/dists

gradlew

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

gradlew.bat

Lines changed: 10 additions & 21 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/gametest/java/net/wurstclient/gametest/SingleplayerTest.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ public SingleplayerTest(ClientGameTestContext context,
4646
public final void run()
4747
{
4848
runImpl();
49-
assertScreenshotEquals(
49+
waitForScreenshotMatch(
5050
getClass().getSimpleName().toLowerCase() + "_cleanup",
5151
"https://i.imgur.com/i2Nr9is.png");
5252
}
@@ -131,6 +131,13 @@ protected final void assertScreenshotEquals(String fileName,
131131
templateUrl);
132132
}
133133

134+
protected final void waitForScreenshotMatch(String fileName,
135+
String templateUrl)
136+
{
137+
WurstClientTestHelper.waitForScreenshotMatch(context, fileName,
138+
templateUrl);
139+
}
140+
134141
protected final void failWithScreenshot(String fileName, String title,
135142
String errorMessage)
136143
{

src/gametest/java/net/wurstclient/gametest/WurstClientTestHelper.java

Lines changed: 55 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -53,31 +53,62 @@ public static void assertScreenshotEquals(ClientGameTestContext context,
5353
String fileName, String templateUrl)
5454
{
5555
ThreadingImpl.checkOnGametestThread("assertScreenshotEquals");
56+
waitForScreenshotMatchImpl(context, fileName, templateUrl, 1);
57+
}
58+
59+
/**
60+
* Same as
61+
* {@link #assertScreenshotEquals(ClientGameTestContext, String, String)},
62+
* but retries for up to 10 seconds to get a matching screenshot.
63+
*
64+
* <p>
65+
* Useful for cases where you're waiting for recent movements to settle
66+
* (e.g. chunk reloads, hand animation), where it can otherwise be tricky to
67+
* get the timing right. Not useful for anything that's still in motion,
68+
* where delaying the screenshot would only cause it to drift further away
69+
* from the expected image.
70+
*/
71+
public static void waitForScreenshotMatch(ClientGameTestContext context,
72+
String fileName, String templateUrl)
73+
{
74+
ThreadingImpl.checkOnGametestThread("waitForScreenshotMatch");
75+
waitForScreenshotMatchImpl(context, fileName, templateUrl,
76+
ClientGameTestContext.DEFAULT_TIMEOUT);
77+
}
78+
79+
private static void waitForScreenshotMatchImpl(
80+
ClientGameTestContext context, String fileName, String templateUrl,
81+
int maxAttempts)
82+
{
83+
NativeImage nativeImageTemplate = downloadImage(templateUrl);
84+
boolean[][] mask = alphaChannelToMask(nativeImageTemplate);
85+
RawImage<int[]> rawTemplate =
86+
RawImageImpl.fromColorNativeImage(nativeImageTemplate);
87+
RawImage<int[]> maskedTemplate = applyMask(rawTemplate, mask);
5688

57-
NativeImage nativeTemplateImage = downloadImage(templateUrl);
58-
boolean[][] mask = alphaChannelToMask(nativeTemplateImage);
59-
RawImage<int[]> rawTemplateImage =
60-
RawImageImpl.fromColorNativeImage(nativeTemplateImage);
61-
RawImage<int[]> maskedTemplateImage = applyMask(rawTemplateImage, mask);
62-
63-
Path screenshotPath = context.takeScreenshot(fileName);
64-
RawImage<int[]> rawScreenshotImage =
65-
RawImageImpl.fromColorNativeImage(loadImageFile(screenshotPath));
66-
RawImage<int[]> maskedScreenshotImage =
67-
applyMask(rawScreenshotImage, mask);
68-
69-
if(maskedScreenshotImage.width() != maskedTemplateImage.width()
70-
|| maskedScreenshotImage.height() != maskedTemplateImage.height())
71-
throw new AssertionError(
72-
"Screenshot and template dimensions do not match");
73-
74-
TestScreenshotComparisonAlgorithm algo =
75-
TestScreenshotComparisonAlgorithm.meanSquaredDifference(3e-4F);
76-
77-
Vector2i result =
78-
algo.findColor(maskedScreenshotImage, maskedTemplateImage);
79-
if(result != null)
80-
return;
89+
Path screenshotPath = null;
90+
for(int i = 0; i < maxAttempts; i++)
91+
{
92+
if(i > 0)
93+
context.waitTick();
94+
95+
screenshotPath = context.takeScreenshot(fileName);
96+
RawImage<int[]> rawScreenshot = RawImageImpl
97+
.fromColorNativeImage(loadImageFile(screenshotPath));
98+
RawImage<int[]> maskedScreenshot = applyMask(rawScreenshot, mask);
99+
100+
if(maskedScreenshot.width() != maskedTemplate.width()
101+
|| maskedScreenshot.height() != maskedTemplate.height())
102+
throw new AssertionError(
103+
"Screenshot and template dimensions do not match");
104+
105+
TestScreenshotComparisonAlgorithm algo =
106+
TestScreenshotComparisonAlgorithm.meanSquaredDifference(3e-4F);
107+
108+
Vector2i result = algo.findColor(maskedScreenshot, maskedTemplate);
109+
if(result != null)
110+
return;
111+
}
81112

82113
ghSummary("### Screenshot " + fileName + " does not match template");
83114
ghSummary("Expected:");

src/gametest/java/net/wurstclient/gametest/tests/XRayHackTest.java

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -33,26 +33,26 @@ protected void runImpl()
3333
runWurstCommand("setcheckbox X-Ray only_show_exposed off");
3434
runWurstCommand("setslider X-Ray opacity 0");
3535
input.pressKey(GLFW.GLFW_KEY_X);
36-
waitForChunkReloading();
37-
assertScreenshotEquals("xray_default",
36+
world.waitForChunksRender();
37+
waitForScreenshotMatch("xray_default",
3838
"https://i.imgur.com/Dftamqv.png");
3939

4040
// Exposed only
4141
runWurstCommand("setcheckbox X-Ray only_show_exposed on");
4242
runWurstCommand("setslider X-Ray opacity 0");
4343
input.pressKey(GLFW.GLFW_KEY_X);
4444
input.pressKey(GLFW.GLFW_KEY_X);
45-
waitForChunkReloading();
46-
assertScreenshotEquals("xray_exposed_only",
45+
world.waitForChunksRender();
46+
waitForScreenshotMatch("xray_exposed_only",
4747
"https://i.imgur.com/QlEpQTu.png");
4848

4949
// Opacity mode
5050
runWurstCommand("setcheckbox X-Ray only_show_exposed off");
5151
runWurstCommand("setslider X-Ray opacity 0.5");
5252
input.pressKey(GLFW.GLFW_KEY_X);
5353
input.pressKey(GLFW.GLFW_KEY_X);
54-
waitForChunkReloading();
55-
assertScreenshotEquals("xray_opacity",
54+
world.waitForChunksRender();
55+
waitForScreenshotMatch("xray_opacity",
5656
WurstTest.IS_MOD_COMPAT_TEST ? "https://i.imgur.com/hXdzoDB.png"
5757
: "https://i.imgur.com/oZqevTx.png");
5858

@@ -61,8 +61,8 @@ protected void runImpl()
6161
runWurstCommand("setslider X-Ray opacity 0.5");
6262
input.pressKey(GLFW.GLFW_KEY_X);
6363
input.pressKey(GLFW.GLFW_KEY_X);
64-
waitForChunkReloading();
65-
assertScreenshotEquals("xray_exposed_only_opacity",
64+
world.waitForChunksRender();
65+
waitForScreenshotMatch("xray_exposed_only_opacity",
6666
WurstTest.IS_MOD_COMPAT_TEST ? "https://i.imgur.com/ZwIARSr.png"
6767
: "https://i.imgur.com/3DLxNuS.png");
6868

@@ -72,7 +72,7 @@ protected void runImpl()
7272
runWurstCommand("setcheckbox X-Ray only_show_exposed off");
7373
runWurstCommand("setslider X-Ray opacity 0");
7474
input.pressKey(GLFW.GLFW_KEY_X);
75-
waitForChunkReloading();
75+
world.waitForChunksRender();
7676
clearChat();
7777
}
7878

@@ -103,15 +103,6 @@ private void buildTestRig()
103103

104104
// Wait for blocks to appear
105105
waitForBlock(-1, 0, 6, Blocks.LAVA);
106-
waitForChunkReloading();
107106
clearChat();
108107
}
109-
110-
private void waitForChunkReloading()
111-
{
112-
// Wait longer if testing with Sodium, since we can't rely on
113-
// waitForChunksRender() to track when Sodium finishes loading chunks
114-
context.waitTicks(WurstTest.IS_MOD_COMPAT_TEST ? 5 : 1);
115-
world.waitForChunksRender();
116-
}
117108
}

0 commit comments

Comments
 (0)