Skip to content

Commit 7ef4b43

Browse files
Merge branch '1.21.4' into 1.21.1
2 parents 2e3987b + b747119 commit 7ef4b43

File tree

8 files changed

+80
-92
lines changed

8 files changed

+80
-92
lines changed

.github/workflows/publish.yml

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -82,26 +82,29 @@ jobs:
8282
GITHUB_TOKEN: ${{ github.token }}
8383
run: ./gradlew closeMilestone --stacktrace --no-configuration-cache
8484

85+
- name: Build website update inputs
86+
id: website_inputs
87+
if: ${{ inputs.update_website }}
88+
run: |
89+
echo "wurst_version=$(grep '^mod_version=' gradle.properties | cut -d'=' -f2 | tr -d ' \r' | sed 's/^v//' | sed 's/-MC.*$//')" >> "$GITHUB_OUTPUT"
90+
echo "mc_version=$(grep '^minecraft_version=' gradle.properties | cut -d'=' -f2 | tr -d ' \r')" >> "$GITHUB_OUTPUT"
91+
echo "fapi_version=$(grep '^fabric_version=' gradle.properties | cut -d'=' -f2 | tr -d ' \r')" >> "$GITHUB_OUTPUT"
92+
8593
- name: Upload backups
8694
if: ${{ inputs.upload_backups }}
87-
env:
88-
WI_BACKUPS_API_KEY: ${{ secrets.WI_BACKUPS_API_KEY }}
89-
run: ./gradlew uploadBackups --stacktrace --no-configuration-cache
95+
uses: Wurst-Imperium/upload-backups@v1
96+
with:
97+
api_key: ${{ secrets.WI_BACKUPS_API_KEY }}
98+
project: Wurst
99+
version: ${{ steps.website_inputs.outputs.wurst_version }}
100+
path: build/libs/*.jar
90101

91102
- name: Publish to GitHub
92103
if: ${{ inputs.publish_github }}
93104
env:
94105
GITHUB_TOKEN: ${{ secrets.OLD_MCX_PUBLISH_TOKEN }}
95106
run: ./gradlew github --stacktrace --no-configuration-cache
96107

97-
- name: Build website update inputs
98-
id: website_inputs
99-
if: ${{ inputs.update_website }}
100-
run: |
101-
echo "wurst_version=$(grep '^mod_version=' gradle.properties | cut -d'=' -f2 | tr -d ' \r' | sed 's/^v//' | sed 's/-MC.*$//')" >> "$GITHUB_OUTPUT"
102-
echo "mc_version=$(grep '^minecraft_version=' gradle.properties | cut -d'=' -f2 | tr -d ' \r')" >> "$GITHUB_OUTPUT"
103-
echo "fapi_version=$(grep '^fabric_version=' gradle.properties | cut -d'=' -f2 | tr -d ' \r')" >> "$GITHUB_OUTPUT"
104-
105108
- name: Trigger website update
106109
if: ${{ inputs.update_website }}
107110
uses: Wurst-Imperium/dispatch-and-wait@v1

build.gradle

Lines changed: 1 addition & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ buildscript {
66

77
plugins {
88
id "fabric-loom" version "${loom_version}"
9-
id "com.diffplug.spotless" version "8.0.0"
9+
id "com.diffplug.spotless" version "8.1.0"
1010
}
1111

1212
def ENV = System.getenv()
@@ -236,60 +236,3 @@ task closeMilestone {
236236
}
237237
}
238238
}
239-
240-
task uploadBackups {
241-
dependsOn build
242-
243-
onlyIf {
244-
ENV.WI_BACKUPS_API_KEY
245-
}
246-
247-
doLast {
248-
def shortVersion = getGhVersion().substring(1)
249-
def backupUrl = "https://api.wurstclient.net/artifact-backups/Wurst/${shortVersion}"
250-
251-
def maxRetries = 3
252-
def retryCount = 0
253-
def success = false
254-
255-
while (!success && retryCount < maxRetries) {
256-
try {
257-
def connection = new URL(backupUrl).openConnection() as HttpURLConnection
258-
def boundary = UUID.randomUUID().toString()
259-
connection.setRequestMethod("POST")
260-
connection.setRequestProperty("X-API-Key", ENV.WI_BACKUPS_API_KEY)
261-
connection.setRequestProperty("Accept", "application/json")
262-
connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=$boundary")
263-
connection.doOutput = true
264-
265-
def output = connection.outputStream
266-
[remapJar, remapSourcesJar].each { jarTask ->
267-
def file = jarTask.archiveFile.get().asFile
268-
output << "--${boundary}\r\n"
269-
output << "Content-Disposition: form-data; name=\"files\"; filename=\"${file.name}\"\r\n"
270-
output << "Content-Type: application/java-archive\r\n\r\n"
271-
file.withInputStream { input ->
272-
output << input
273-
}
274-
output << "\r\n"
275-
}
276-
output << "--${boundary}--\r\n"
277-
output.flush()
278-
279-
if(connection.responseCode != 200) {
280-
throw new IOException("HTTP ${connection.responseCode}: ${connection.responseMessage}")
281-
}
282-
283-
success = true
284-
285-
} catch (Exception e) {
286-
retryCount++
287-
if (retryCount >= maxRetries) {
288-
throw new GradleException("Failed to upload backups after ${maxRetries} attempts: ${e.message}")
289-
}
290-
println "Upload attempt ${retryCount} failed: ${e.message}. Retrying in 5 seconds..."
291-
Thread.sleep(5000)
292-
}
293-
}
294-
}
295-
}

gradle.properties

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,14 @@ org.gradle.configuration-cache=true
88
# https://modrinth.com/mod/fabric-api/versions
99
minecraft_version=1.21.1
1010
yarn_mappings=1.21.1+build.3
11-
loader_version=0.17.3
11+
loader_version=0.18.1
1212
loom_version=1.13-SNAPSHOT
1313

1414
# Fabric API
1515
fabric_version=0.116.7+1.21.1
1616

1717
# Mod Properties
18-
mod_version=v7.51.1-MC1.21.1
18+
mod_version=v7.51.2-MC1.21.1
1919
maven_group=net.wurstclient
2020
archives_base_name=Wurst-Client
2121
mod_loader=Fabric

src/main/java/net/wurstclient/WurstClient.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ public enum WurstClient
5050
public static Minecraft MC;
5151
public static IMinecraftClient IMC;
5252

53-
public static final String VERSION = "7.51.1";
53+
public static final String VERSION = "7.51.2";
5454
public static final String MC_VERSION = "1.21.1";
5555

5656
private PlausibleAnalytics plausible;

src/main/java/net/wurstclient/WurstTranslator.java

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,18 @@
1515
import java.util.IllegalFormatException;
1616
import java.util.List;
1717
import java.util.Map;
18+
import java.util.Optional;
1819
import java.util.function.BiConsumer;
1920

2021
import com.google.common.collect.Lists;
22+
import com.google.gson.JsonParseException;
2123

2224
import net.minecraft.client.Minecraft;
2325
import net.minecraft.client.resources.language.ClientLanguage;
2426
import net.minecraft.client.resources.language.I18n;
2527
import net.minecraft.locale.Language;
2628
import net.minecraft.resources.ResourceLocation;
29+
import net.minecraft.server.packs.repository.KnownPack;
2730
import net.minecraft.server.packs.resources.Resource;
2831
import net.minecraft.server.packs.resources.ResourceManager;
2932
import net.minecraft.server.packs.resources.ResourceManagerReloadListener;
@@ -187,17 +190,50 @@ private void loadTranslations(ResourceManager manager,
187190
ResourceLocation langId =
188191
ResourceLocation.fromNamespaceAndPath("wurst", langFilePath);
189192

193+
// IMPORTANT: Exceptions thrown by Language.loadFromJson() must
194+
// be caught to prevent mod detection vulnerabilities using
195+
// intentionally corrupted resource packs.
190196
for(Resource resource : manager.getResourceStack(langId))
197+
{
191198
try(InputStream stream = resource.open())
192199
{
193-
Language.loadFromJson(stream, entryConsumer);
200+
if(isBuiltInWurstResourcePack(resource))
201+
Language.loadFromJson(stream, entryConsumer);
202+
203+
}catch(IOException | JsonParseException e)
204+
{
205+
System.out.println(
206+
"Failed to load Wurst translations for " + langCode);
207+
e.printStackTrace();
194208

195-
}catch(IOException e)
209+
}catch(Exception e)
196210
{
197-
System.out.println("Failed to load translations for "
198-
+ langCode + " from pack " + resource.sourcePackId());
211+
System.out.println(
212+
"Unexpected exception while loading Wurst translations for "
213+
+ langCode);
199214
e.printStackTrace();
200215
}
216+
}
201217
}
202218
}
219+
220+
/**
221+
* Ensures that the given resource is from Wurst's built-in resource pack,
222+
* or at least from another client-side mod pretending to be Wurst, as it
223+
* should be impossible for server-provided resource packs to obtain a
224+
* KnownPack of <code>fabric:wurst</code>.
225+
*
226+
* <p>
227+
* ASSUME THEY CAN BYPASS THIS. CATCH EXCEPTIONS ANYWAY.
228+
*/
229+
private boolean isBuiltInWurstResourcePack(Resource resource)
230+
{
231+
KnownPack knownPack = Optional.ofNullable(resource)
232+
.flatMap(Resource::knownPackInfo).orElse(null);
233+
if(knownPack == null)
234+
return false;
235+
236+
return "fabric".equals(knownPack.namespace())
237+
&& "wurst".equals(knownPack.id());
238+
}
203239
}

src/main/java/net/wurstclient/mixin/FluidRendererMixin.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ private static void onIsSideCovered(BlockGetter world, BlockPos pos,
3434
CallbackInfoReturnable<Boolean> cir)
3535
{
3636
BlockState state = world.getBlockState(pos);
37-
ShouldDrawSideEvent event = new ShouldDrawSideEvent(state, pos);
37+
// Note: the null BlockPos is here to skip the "exposed only" check
38+
ShouldDrawSideEvent event = new ShouldDrawSideEvent(state, null);
3839
EventManager.fire(event);
3940

4041
if(event.isRendered() != null)

src/main/java/net/wurstclient/mixin/sodium/DefaultFluidRendererMixin.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ private void onIsFluidOccludedInSodium060(BlockAndTintGetter world, int x,
5555
{
5656
BlockPos.MutableBlockPos pos = mutablePosForExposedCheck.get();
5757
pos.set(x, y, z);
58-
ShouldDrawSideEvent event = new ShouldDrawSideEvent(state, pos);
58+
ShouldDrawSideEvent event = new ShouldDrawSideEvent(state, null);
5959
EventManager.fire(event);
6060

6161
if(event.isRendered() != null)
@@ -79,7 +79,7 @@ private void onIsFluidOccluded(BlockAndTintGetter world, int x, int y,
7979
{
8080
BlockPos.MutableBlockPos pos = mutablePosForExposedCheck.get();
8181
pos.set(x, y, z);
82-
ShouldDrawSideEvent event = new ShouldDrawSideEvent(state, pos);
82+
ShouldDrawSideEvent event = new ShouldDrawSideEvent(state, null);
8383
EventManager.fire(event);
8484

8585
if(event.isRendered() != null)
@@ -101,7 +101,8 @@ private void onIsFullBlockFluidOccluded(BlockAndTintGetter world,
101101
BlockPos pos, Direction dir, BlockState state, FluidState fluid,
102102
CallbackInfoReturnable<Boolean> cir)
103103
{
104-
ShouldDrawSideEvent event = new ShouldDrawSideEvent(state, pos);
104+
// Note: the null BlockPos is here to skip the "exposed only" check
105+
ShouldDrawSideEvent event = new ShouldDrawSideEvent(state, null);
105106
EventManager.fire(event);
106107

107108
if(event.isRendered() != null)
@@ -117,8 +118,8 @@ private void onIsFullBlockFluidOccluded(BlockAndTintGetter world,
117118
@ModifyExpressionValue(at = @At(value = "INVOKE",
118119
target = "Lnet/caffeinemc/mods/sodium/api/util/ColorARGB;toABGR(I)I"),
119120
method = "updateQuad",
120-
require = 0,
121-
remap = false)
121+
remap = false,
122+
require = 0)
122123
private int onUpdateQuad(int original, @Local(argsOnly = true) BlockPos pos,
123124
@Local(argsOnly = true) FluidState state)
124125
{

src/main/resources/assets/wurst/translations/pl_pl.json

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010
"description.wurst.hack.anchoraura": "Automatycznie umieszcza (opcjonalnie), ładuje i wysadza kotwice odrodzenia, aby zabijać otaczające cię istoty.",
1111
"description.wurst.setting.anchoraura.range": "Określa, jak daleko AnchorAura sięgnie, aby umieścić, naładować i zdetonować kotwice.",
1212
"description.wurst.setting.anchoraura.auto-place_anchors": "Gdy włączony, AnchorAura automatycznie umieszcza kotwice w pobliżu prawidłowych bytów.\nGdy wyłączony, AnchorAura będzie tylko ładować i detonować ręcznie umieszczone kotwice.",
13-
"description.wurst.setting.anchoraura.face_target": "Jak AnchorAura powinien być skierowany na kotwice odrodzenia.",
14-
"description.wurst.setting.anchoraura.check_line_of_sight": "Zabezpiecza przed sięganiem przez bloki podczas umieszczania lub klikania prawym przyciskiem kotwic odrodzenia.\n\nWolniejsze, ale może pomóc z pluginami antycheatowymi.",
13+
"description.wurst.setting.anchoraura.face_target": "Jak AnchorAura powinna być skierowana na kotwice odrodzenia.",
14+
"description.wurst.setting.anchoraura.check_line_of_sight": "Zabezpiecza przed sięganiem przez bloki podczas umieszczania lub klikania prawym przyciskiem kotwic odrodzenia.\n\nWolniejsze, ale może pomóc z pluginami anty-cheat.",
1515
"description.wurst.setting.anchoraura.swing_hand": "Jak AnchorAura powininna machać ręką podczas umieszczania, ładowania i detonacji kotwic odrodzenia.",
1616
"description.wurst.setting.anchoraura.take_items_from": "Gdzie szukać kotwic odrodzenia i jasnogłazu.",
1717
"description.wurst.hack.antiafk": "Spaceruje losowo dookoła, aby ukryć cię przed wykrywaczami AFK.",
@@ -38,8 +38,8 @@
3838
"description.wurst.hack.autodrop": "Automatycznie wyrzuca niechciane przedmioty.",
3939
"description.wurst.hack.autoleave": "Automatycznie opuszcza serwer, gdy masz mało życia.",
4040
"description.wurst.hack.autolibrarian": "Automatycznie szkoli osadnika, aby stał się bibliotekarzem sprzedającym określoną zaklętą książkę. Możesz błyskawicznie stworzyć całą halę handlową, korzystając z tego hacka.",
41-
"description.wurst.setting.autolibrarian.face_target": "Jak AutoLibrarian powinien być skierowany na wieśniaka i miejsce pracy.",
42-
"description.wurst.setting.autolibrarian.swing_hand": "Jak AutoLibrarian powinien machać ręką podczas interakcji z wieśniakiem i miejscem pracy.",
41+
"description.wurst.setting.autolibrarian.face_target": "Jak AutoLibrarian powinien być skierowany na osadnika i miejsce pracy.",
42+
"description.wurst.setting.autolibrarian.swing_hand": "Jak AutoLibrarian powinien machać ręką podczas interakcji z osadnikiem i miejscem pracy.",
4343
"description.wurst.hack.autoeat": "Automatycznie zjada coś, gdy jest to konieczne.",
4444
"description.wurst.setting.autoeat.target_hunger": "Stara się utrzymać pasek głodu na tym lub wyższym poziomie, jednak tylko, gdy nie zmarnuje to punktów głodu.",
4545
"description.wurst.setting.autoeat.min_hunger": "Zawsze utrzymuje pasek głodu na tym lub wyższym poziomie, nawet jeśli zmarnuje to kilka punktów głodu.\n6.5 - Nie zmarnuje punktów jedząc \"vanilla\" jedzenie.\n10.0 - Całkowicie ignoruje straty i po prostu utrzymuje pełny pasek głodu.",
@@ -51,6 +51,8 @@
5151
"description.wurst.setting.autoeat.allow_poison": "Trujące jedzenie zadaje z czasem obrażenia.\nNiepolecane.",
5252
"description.wurst.setting.autoeat.allow_chorus": "Zjedzenie owoców refrenusu teleportuje cię w losowe miejsce.\nNiepolecane.",
5353
"description.wurst.hack.autofarm": "Automatycznie zbiera i przesadza plony.",
54+
"description.wurst.setting.autofarm.check_line_of_sight": "Zabezpiecza przed sięganiem przez bloki podczas sadzenia i zbierania plonów.",
55+
"description.wurst.setting.autofarm.face_target": "Jak AutoFarm powinien być skierowany na uprawy podczas sadzenia i zbierania plonów.",
5456
"description.wurst.setting.autofarm.swing_hand": "Jak AutoFarm powinien machać twoją ręką podczas sadzenia i zbierania plonów.",
5557
"description.wurst.hack.autofish": "Automatycznie łowi ryby, korzystając z twojej najlepszej wędki. Jeśli podczas łowienia znajdzie lepszą wędkę, automatycznie się na nią przełączy.",
5658
"description.wurst.hack.automine": "Automatycznie wykopuje każdy blok, na który patrzysz.",
@@ -93,8 +95,8 @@
9395
"description.wurst.hack.creativeflight": "Pozwala latać, tak jak w trybie kreatywnym.\n\n§c§lOSTRZEŻENIE:§r Odniesiesz obrażenia od upadku, jeśli nie użyjesz NoFall.",
9496
"description.wurst.hack.criticals": "Zmienia wszystkie twoje uderzenia w uderzenia krytyczne.",
9597
"description.wurst.hack.crystalaura": "Automatycznie umieszcza (opcjonalnie) i wysadza kryształy Endu, aby zabijać otaczające cię istoty.",
96-
"description.wurst.setting.crystalaura.face_target": "Jak CrystalAura powinien być skierowany na kryształy Endu.",
97-
"description.wurst.setting.crystalaura.swing_hand": "Jak CrystalAura powinien machać ręką podczas umieszczania i detonacji kryształów Endu.",
98+
"description.wurst.setting.crystalaura.face_target": "Jak CrystalAura powinna być skierowana na kryształy Endu.",
99+
"description.wurst.setting.crystalaura.swing_hand": "Jak CrystalAura powinna machać ręką podczas umieszczania i detonacji kryształów Endu.",
98100
"description.wurst.hack.derp": "Losowo porusza twoją głową.\nWidoczne tylko dla innych graczy.",
99101
"description.wurst.hack.dolphin": "Sprawia, że automatycznie podskakujesz w wodzie.\n(tak jak delfin)",
100102
"description.wurst.hack.excavator": "Automatycznie niszczy wszystkie bloki w wybranym obszarze.",
@@ -133,6 +135,7 @@
133135
"description.wurst.hack.healthtags": "Pokazuje punkty życia graczy przy ich nazwach.",
134136
"description.wurst.hack.highjump": "Pozwala skakać wyżej.\n\n§c§lOSTRZEŻENIE:§r Odniesiesz obrażenia od upadku, jeśli nie użyjesz NoFall.",
135137
"description.wurst.hack.infinichat": "Usuwa limit 256 znaków z czatu.\nPrzydatne w przypadku długich poleceń modyfikujących dane NBT.\n\n§6§lUWAGA:§r Nie polecane do rozmów z ludźmi. Większość serwerów obcina wiadomości do 256 znaków.",
138+
"description.wurst.hack.instabuild": "Podobny do AutoBuild, z tym że próbuje zbudować cały szablon naraz.\nDziała tylko z bardzo prostymi szablonami.",
136139
"description.wurst.hack.instantbunker": "Buduje wokół ciebie mały bunkier. Wymaga 57 bloków.",
137140
"description.wurst.hack.invwalk": "Pozwala poruszać się z otwartym ekwipunkiem.",
138141
"description.wurst.setting.invwalk.allow_clickgui": "Pozwala poruszać się z otwartym ClickGUI Wursta.",
@@ -180,6 +183,7 @@
180183
"description.wurst.hack.nopumpkin": "Blokuje nakładkę podczas noszenia dyni na głowie.",
181184
"description.wurst.hack.noshieldoverlay": "Obniża tarczę, aby zakrywała mniejszą część ekranu.",
182185
"description.wurst.hack.noslowdown": "Anuluje efekty spowolnienia wywołane przez miód, piasek dusz i używanie przedmiotów.",
186+
"description.wurst.hack.novignette": "Usuwa efekt winiety (przyciemnienie krawędzi ekranu).",
183187
"description.wurst.hack.noweather": "Umożliwia zmianę pogody, czasu i fazy księżyca po stronie klienta.",
184188
"description.wurst.hack.noweb": "Zapobiega spowolnieniu przez pajęczyny.",
185189
"description.wurst.hack.nuker": "Automatycznie niszczy bloki wokół ciebie.",
@@ -246,10 +250,10 @@
246250
"button.wurst.nochatreports.disable_signatures": "Wyłącz Sygnatury",
247251
"button.wurst.nochatreports.re-enable_signatures": "Ponownie Włącz Sygnatury",
248252
"description.wurst.setting.generic.attack_speed": "Szybkość ataku w kliknięciach na sekundę.\n0 = dynamicznie dostosowuje szybkość do długości odnowienia ataku.",
249-
"description.wurst.setting.generic.face_target.off": "Nie kieruj się na cel w ogóle. Zostanie wykryte przez wtyczki anty-cheat.",
250-
"description.wurst.setting.generic.face_target.server": "Kieruj się na cel po stronie serwera, jednocześnie pozwalając swobodnie poruszać kamerą po stronie klienta.",
251-
"description.wurst.setting.generic.face_target.client": "Kieruj się na cel poprzez poruszanie kamerą po stronie klienta. To najbardziej wiarygodna opcja, ale może być dezorientująca do patrzenia.",
252-
"description.wurst.setting.generic.face_target.spam": "Kieruj się na cel po stronie serwera i wysyłaj oddzielny pakiet za każdym razem. Może pomóc z niektórymi (zepsutymi) wtyczkami anty-cheat, ale bardziej prawdopodobne jest, że po prostu zostaniesz wyrzucony.",
253+
"description.wurst.setting.generic.face_target.off": "W ogóle nie patrz w stronę celu. Zostanie wykryte przez wtyczki anty-cheat.",
254+
"description.wurst.setting.generic.face_target.server": "Obróć się w stronę celu po stronie serwera, jednocześnie pozwalając swobodnie poruszać kamerą po stronie klienta.",
255+
"description.wurst.setting.generic.face_target.client": "Obróć się w stronę celu, przesuwając kamerę po stronie klienta. To najbardziej wiarygodna opcja, jednak może być nieco myląca dla wzroku.",
256+
"description.wurst.setting.generic.face_target.spam": "Obróć się w stronę celu po stronie serwera i za każdym razem wysyłaj osobny pakiet. Może pomóc z niektórymi (uszkodzonymi) wtyczkami anty-cheat, lecz zwiększa szanse na wyrzucenie cię z gry.",
253257
"description.wurst.setting.generic.filter_allays_combat": "Nie będzie atakować otuszków.",
254258
"description.wurst.setting.generic.filter_allays_vision": "Nie będzie pokazywać otuszków.",
255259
"description.wurst.setting.generic.filter_armor_stands_combat": "Nie będzie atakować stojaków na zbroję.",

0 commit comments

Comments
 (0)