Skip to content

Commit 0516e30

Browse files
committed
NiceWurst
1 parent a83a9f8 commit 0516e30

File tree

13 files changed

+517
-54
lines changed

13 files changed

+517
-54
lines changed

README.md

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,18 @@ This project is a friendly, independent fork of Wurst 7. I originally proposed t
1919

2020
All credit for the original client goes to Wurst-Imperium and its contributors. This fork is not affiliated with or endorsed by Wurst-Imperium. This fork maintains the original GPLv3 licensing.
2121

22-
## Other Projects
22+
## NiceWurst Variant (Cheat-Reduced Build)
2323

24-
I felt I should also make a more publicly accessible version of this fork via [NiceWurst](https://github.com/cev-api/NiceWurst), which is a **cheat-free** version of this very fork. This means, for example, that all ESPs that haven't been trimmed aren't visible through walls. Almost all combat-based hacks have been removed, except for AutoTotem and AutoLeave, which are questionable but are more about breaking server rules rather than any universal definition of cheating. Check out the page, see the list of what has been kept, and give it a go!
24+
This fork now ships with NiceWurst, a non-cheating configuration you can build from the same source by passing ```-Pnicewurst=1``` (or setting NICEWURST=1 as an env var).
2525

26-
## My Goals and Experience
26+
### The NiceWurst profile:
2727

28-
I have no other experience in the field of Minecraft and have never used any other hack except Wurst and Meteor. I ended up liking the UI and features of Wurst more, but I found there were some things that needed tweaking. This is why I made this fork. I don't play on anarchy servers and I don't grief or do anything dramatic. I just wanted a client that would make my survival Minecraft games a bit more enjoyable and personalised. While I don't actively test or use other cheats, I still come up with new ideas constantly and I'm often surprised that I'm the first to implement some of the things below. Maybe they're too superfluous or stupid, but I definitely like them.
28+
- Keeps only the utility/survival hacks listed in ```src/main/java/net/wurstclient/nicewurst/NiceWurstModule.java``` (edit the allowlist there if you want to add or remove features);
29+
- Removes combat/duplication/exploit hacks entirely and forces all ESP overlays to respect walls, so you can’t see entities through blocks;
30+
hides the Alt Manager, Anti-Fingerprint UI, X-Ray block editor, and other “grey-area” tools;
31+
- Rebrands the mod (jar name, mod id, HUD, links) to “NiceWurst 7” and stores data in .minecraft/nicewurst/ so it never touches your regular Wurst profile.
32+
33+
Build without the flag to get the full CevAPI experience; build with the flag for a genuinely cheat-free alternative.
2934

3035
---
3136

build.gradle

Lines changed: 77 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,33 @@ plugins {
1111

1212
def ENV = System.getenv()
1313

14-
version = project.mod_version
14+
def niceWurstRaw =
15+
(project.findProperty("nicewurst") ?: ENV.NICEWURST ?: "0").toString()
16+
def niceWurstEnabled = !["0", "false", "off", "no", ""]
17+
.contains(niceWurstRaw.toLowerCase(Locale.ROOT))
18+
19+
def effectiveVersion = niceWurstEnabled
20+
? project.mod_version.replace("-Cevapi", "")
21+
: project.mod_version
22+
def effectiveArchiveName =
23+
niceWurstEnabled ? "NiceWurst" : project.archives_base_name
24+
def modId = niceWurstEnabled ? "nicewurst" : "wurst"
25+
def modName = niceWurstEnabled ? "NiceWurst 7"
26+
: "Wurst Client - Modified by CevAPI"
27+
def modDescription = niceWurstEnabled
28+
? "NiceWurst is a curated, cheat-free build of this fork."
29+
: "Cevapi Cevapi Cevapi!"
30+
def homepageUrl = niceWurstEnabled ? "https://github.com/cev-api/NiceWurst"
31+
: "https://github.com/cev-api/Wurst7-CevAPI/"
32+
def sourcesUrl = homepageUrl
33+
def issuesUrl =
34+
homepageUrl + (homepageUrl.endsWith("/") ? "issues" : "/issues")
35+
36+
version = effectiveVersion
1537
group = project.maven_group
1638

1739
base {
18-
archivesName = project.archives_base_name
40+
archivesName = effectiveArchiveName
1941
}
2042

2143
repositories {
@@ -81,6 +103,7 @@ dependencies {
81103
}
82104

83105
import net.fabricmc.loom.util.Platform
106+
import java.util.Locale
84107
tasks.register('runEndToEndTest', JavaExec) {
85108
dependsOn remapJar, downloadAssets
86109
classpath.from configurations.productionRuntime
@@ -115,12 +138,62 @@ tasks.register('runEndToEndTest', JavaExec) {
115138
processResources {
116139
def modVersion = project.version.substring(1)
117140
inputs.property("version", modVersion)
141+
inputs.property("modName", modName)
142+
inputs.property("modDescription", modDescription)
143+
inputs.property("homepageUrl", homepageUrl)
144+
inputs.property("sourcesUrl", sourcesUrl)
145+
inputs.property("issuesUrl", issuesUrl)
146+
inputs.property("modId", modId)
118147

119148
filesMatching("fabric.mod.json") {
120-
expand(version: modVersion)
149+
expand([
150+
modId: modId,
151+
version: modVersion,
152+
modName: modName,
153+
modDescription: modDescription,
154+
homepage: homepageUrl,
155+
sources: sourcesUrl,
156+
issues: issuesUrl
157+
])
158+
}
159+
}
160+
161+
def buildConfigOutput =
162+
layout.buildDirectory.dir("generated/sources/buildConfig/java")
163+
164+
tasks.register("generateBuildConfig") {
165+
def template =
166+
file("src/main/templates/net/wurstclient/config/BuildConfig.java.in")
167+
168+
inputs.file(template)
169+
inputs.property("niceWurstEnabled", niceWurstEnabled)
170+
outputs.dir(buildConfigOutput)
171+
172+
doLast {
173+
def targetDir =
174+
buildConfigOutput.get().dir("net/wurstclient/config").asFile
175+
if(!targetDir.exists())
176+
targetDir.mkdirs()
177+
178+
def content = template.getText("UTF-8")
179+
.replace('${NICE_WURST}', String.valueOf(niceWurstEnabled))
180+
181+
def targetFile = new File(targetDir, "BuildConfig.java")
182+
targetFile.setText(content, "UTF-8")
121183
}
122184
}
123185

186+
sourceSets.main.java.srcDir(buildConfigOutput)
187+
188+
tasks.named("compileJava").configure {
189+
dependsOn(tasks.named("generateBuildConfig"))
190+
}
191+
192+
tasks.configureEach {
193+
if(name == "sourcesJar" || name == "spotlessJava")
194+
dependsOn(tasks.named("generateBuildConfig"))
195+
}
196+
124197
tasks.withType(JavaCompile).configureEach {
125198
// Minecraft 1.20.5 (24w14a) upwards uses Java 21.
126199
it.options.release = 21
@@ -151,6 +224,7 @@ import com.diffplug.spotless.generic.LicenseHeaderStep
151224
spotless {
152225
lineEndings = "WINDOWS"
153226
java {
227+
targetExclude("build/generated/sources/buildConfig/java/**/*.java")
154228
removeUnusedImports()
155229
leadingSpacesToTabs()
156230
trimTrailingWhitespace()

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@
4242
import net.wurstclient.update.ProblematicResourcePackDetector;
4343
import net.wurstclient.update.WurstUpdater;
4444
import net.wurstclient.util.json.JsonException;
45+
import net.wurstclient.nicewurst.NiceWurstModule;
46+
import net.wurstclient.config.BuildConfig;
4547

4648
public enum WurstClient
4749
{
@@ -142,12 +144,15 @@ public void initialize()
142144
Path altsFile = wurstFolder.resolve("alts.encrypted_json");
143145
Path encFolder = Encryption.chooseEncryptionFolder();
144146
altManager = new AltManager(altsFile, encFolder);
147+
148+
NiceWurstModule.apply(this);
145149
}
146150

147151
private Path createWurstFolder()
148152
{
149153
Path dotMinecraftFolder = MC.runDirectory.toPath().normalize();
150-
Path wurstFolder = dotMinecraftFolder.resolve("wurst");
154+
String folderName = BuildConfig.NICE_WURST ? "nicewurst" : "wurst";
155+
Path wurstFolder = dotMinecraftFolder.resolve(folderName);
151156

152157
try
153158
{

src/main/java/net/wurstclient/hud/WurstLogo.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import net.wurstclient.WurstClient;
1313
import net.wurstclient.other_features.WurstLogoOtf;
1414
import net.wurstclient.util.RenderUtils;
15+
import net.wurstclient.nicewurst.NiceWurstModule;
1516

1617
public final class WurstLogo
1718
{
@@ -24,7 +25,7 @@ public void render(DrawContext context)
2425
return;
2526

2627
String version = getVersionString();
27-
String brand = "Wurst 7 CevAPI";
28+
String brand = NiceWurstModule.getBrandLabel("Wurst 7 CevAPI");
2829
TextRenderer tr = WurstClient.MC.textRenderer;
2930

3031
// Measure and layout

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import net.minecraft.text.Text;
2828
import net.wurstclient.WurstClient;
2929
import net.wurstclient.options.WurstOptionsScreen;
30+
import net.wurstclient.nicewurst.NiceWurstModule;
3031

3132
@Mixin(GameMenuScreen.class)
3233
public abstract class GameMenuScreenMixin extends Screen
@@ -91,7 +92,9 @@ private void addWurstOptionsButton()
9192
ensureSpaceAvailable(buttonX, buttonY, buttonWidth, buttonHeight);
9293

9394
// Create Wurst Options button with full label instead of padded spaces
94-
MutableText buttonText = Text.literal("Wurst 7 CevAPI Options");
95+
String label =
96+
NiceWurstModule.getOptionsLabel("Wurst 7 CevAPI Options");
97+
MutableText buttonText = Text.literal(label);
9598
wurstOptionsButton = ButtonWidget
9699
.builder(buttonText, b -> openWurstOptions())
97100
.dimensions(buttonX, buttonY, buttonWidth, buttonHeight).build();

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

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import net.wurstclient.serverfinder.ServerFinderScreen;
2727
import net.wurstclient.util.LastServerRememberer;
2828
import net.cevapi.config.AntiFingerprintConfigScreen;
29+
import net.wurstclient.nicewurst.NiceWurstModule;
2930

3031
@Mixin(MultiplayerScreen.class)
3132
public class MultiplayerScreenMixin extends Screen
@@ -100,16 +101,27 @@ private void onRefreshWidgetPositions(CallbackInfo ci)
100101

101102
if(antiFingerprintButton == null)
102103
{
103-
antiFingerprintButton = ButtonWidget
104-
.builder(Text.literal("Anti-Fingerprint"),
105-
b -> client.setScreen(new AntiFingerprintConfigScreen(
106-
(MultiplayerScreen)(Object)this)))
107-
.dimensions(0, 0, 100, 20).build();
108-
addDrawableChild(antiFingerprintButton);
104+
if(!NiceWurstModule.showAntiFingerprintControls())
105+
{
106+
antiFingerprintButton = null;
107+
}else
108+
{
109+
antiFingerprintButton = ButtonWidget
110+
.builder(Text.literal("Anti-Fingerprint"),
111+
b -> client.setScreen(new AntiFingerprintConfigScreen(
112+
(MultiplayerScreen)(Object)this)))
113+
.dimensions(0, 0, 100, 20).build();
114+
addDrawableChild(antiFingerprintButton);
115+
}
116+
}
117+
118+
if(antiFingerprintButton != null)
119+
{
120+
antiFingerprintButton.setX(width / 2 + 54);
121+
antiFingerprintButton.setY(10);
122+
antiFingerprintButton.setWidth(100);
123+
antiFingerprintButton.visible = true;
109124
}
110-
antiFingerprintButton.setX(width / 2 + 54);
111-
antiFingerprintButton.setY(10);
112-
antiFingerprintButton.setWidth(100);
113125

114126
if(cornerServerFinderButton == null)
115127
{

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

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import net.minecraft.text.Text;
2323
import net.wurstclient.WurstClient;
2424
import net.wurstclient.altmanager.screens.AltManagerScreen;
25+
import net.wurstclient.nicewurst.NiceWurstModule;
2526

2627
@Mixin(TitleScreen.class)
2728
public abstract class TitleScreenMixin extends Screen
@@ -58,15 +59,20 @@ private void onAddNormalWidgets(int y, int spacingY,
5859
if(realmsButton == null)
5960
throw new IllegalStateException("Couldn't find realms button!");
6061

61-
// make Realms button smaller
62-
realmsButton.setWidth(98);
63-
64-
// add AltManager button
65-
addDrawableChild(altsButton = ButtonWidget
66-
.builder(Text.literal("Alt Manager"),
67-
b -> client.setScreen(new AltManagerScreen(this,
68-
WurstClient.INSTANCE.getAltManager())))
69-
.dimensions(width / 2 + 2, realmsButton.getY(), 98, 20).build());
62+
if(NiceWurstModule.showAltManager())
63+
{
64+
// make Realms button smaller
65+
realmsButton.setWidth(98);
66+
67+
// add AltManager button
68+
addDrawableChild(altsButton = ButtonWidget
69+
.builder(Text.literal("Alt Manager"),
70+
b -> client.setScreen(new AltManagerScreen(this,
71+
WurstClient.INSTANCE.getAltManager())))
72+
.dimensions(width / 2 + 2, realmsButton.getY(), 98, 20)
73+
.build());
74+
}else
75+
altsButton = null;
7076
}
7177

7278
@Inject(at = @At("RETURN"), method = "tick()V")

0 commit comments

Comments
 (0)