-
-
Notifications
You must be signed in to change notification settings - Fork 417
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add AutoPlaceHack #1051
base: master
Are you sure you want to change the base?
Add AutoPlaceHack #1051
Conversation
📝 Walkthrough📝 WalkthroughWalkthroughThe changes introduce several new features and modifications across multiple classes in the WurstClient Minecraft mod. A new Changes
📜 Recent review detailsConfiguration used: CodeRabbit UI ⛔ Files ignored due to path filters (2)
📒 Files selected for processing (15)
🚧 Files skipped from review as they are similar to previous changes (1)
🧰 Additional context used🪛 ast-grep
🔇 Additional comments (23)
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
Update Fabric API
Add TeamEspHack & FilterNpcLikeSetting
Add AimAssistHack onlyHoldingWeapon option
Add TriggerBotHack blacklistedItems option
Add SafeWalkHack minDepth & motionPrediction options
Update to 7.46
Optional AutoReconnectHack death screen button
Update to v7.46.1
This pull request has been open for a while with no recent activity. If you're still working on this or waiting for a review, please add a comment or commit within the next 7 days to keep it open. Otherwise, the pull request will be automatically closed to free up time for other tasks. Pull requests should be closed if:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 8
🧹 Outside diff range and nitpick comments (3)
src/main/java/net/wurstclient/hacks/AutoPlaceHack.java (3)
98-101
: Ensure consistent handling ofActionResult
.Currently, you check if
actionResult.isAccepted()
before swinging the hand. For complete accuracy, you should also handle the case where the result is aSUCCESS
, which may not always equate toisAccepted()
.Consider updating the condition:
- if(actionResult.isAccepted()) + if(actionResult.isAccepted() && actionResult.shouldSwingHand())
29-35
: Clarify the description forfastPlace
setting.The description "Builds as if FastPlace was enabled, even if it's not." might be misleading. It could be rephrased for better clarity.
Update the setting description:
- "Builds as if FastPlace was enabled, even if it's not.", true); + "Allows block placement without the usual cooldown, even if FastPlace hack is disabled.", true);
70-72
: Optimize inventory slot retrieval.Accessing
player.getInventory().selectedSlot
directly can be replaced with a more direct method for readability and potential performance benefits.Simplify the code:
- if(!(player.getInventory().getStack(player.getInventory().selectedSlot) + if(!(player.getMainHandStack() .getItem() instanceof BlockItem))
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
⛔ Files ignored due to path filters (2)
src/main/resources/assets/wurst/translations/en_us.json
is excluded by!**/*.json
src/main/resources/assets/wurst/translations/zh_tw.json
is excluded by!**/*.json
📒 Files selected for processing (2)
- src/main/java/net/wurstclient/hack/HackList.java (1 hunks)
- src/main/java/net/wurstclient/hacks/AutoPlaceHack.java (1 hunks)
🧰 Additional context used
🔇 Additional comments (1)
src/main/java/net/wurstclient/hack/HackList.java (1)
52-52
: LGTM: AutoPlaceHack added correctlyThe addition of
AutoPlaceHack
is consistent with the existing pattern and placed in the correct alphabetical order. This aligns with the PR objective of introducing the newAutoPlace
feature.Consider potential interactions with other hacks, especially
ScaffoldWalk
as mentioned in the PR notes. It might be beneficial to review theAutoPlaceHack
implementation to ensure it doesn't conflict with existing functionalities. You can use the following script to check for any direct references betweenAutoPlaceHack
andScaffoldWalk
:✅ Verification successful
Verified: No interactions found between AutoPlaceHack and ScaffoldWalk
The search results indicate that there are no interactions between
AutoPlaceHack
andScaffoldWalk
. The addition ofAutoPlaceHack
does not conflict with existing functionalities.🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Search for any interactions between AutoPlaceHack and ScaffoldWalk rg -i "autoplacehack.*scaffoldwalk|scaffoldwalk.*autoplacehack" --type javaLength of output: 77
BlockHitResult blockHitResult = (BlockHitResult)hitResult; | ||
if(blockHitResult.getSide() == Direction.UP | ||
|| blockHitResult.getSide() == Direction.DOWN) | ||
return; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Consider allowing placement on the top and bottom faces.
Currently, the hack does not allow placing blocks when targeting the top or bottom face of a block. This might limit the usefulness of the hack in certain building scenarios.
Consider removing or adjusting this condition to allow more flexible block placement.
- if(blockHitResult.getSide() == Direction.UP
- || blockHitResult.getSide() == Direction.DOWN)
- return;
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
BlockHitResult blockHitResult = (BlockHitResult)hitResult; | |
if(blockHitResult.getSide() == Direction.UP | |
|| blockHitResult.getSide() == Direction.DOWN) | |
return; | |
BlockHitResult blockHitResult = (BlockHitResult)hitResult; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be made configurable in the settings. The PR author said they only want it to place blocks horizontally, but I agree this might limit its usefulness e.g. if you're trying to tower up.
Some different ideas for how the settings might work:
- a single checkbox "Allow vertical placement"
- an enum "Direction" ["Horizontal", "Vertical", "Both"]
- multiple checkboxes "Place up", "Place down", "Place horizontal"
- a long enum "Place directions" ["Horizontal", "Vertical", "Up only", "Down only", "Up/horizontal", "Down/horizontal", "All"]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great suggestion! Making the placement directions configurable would enhance the flexibility of the AutoPlace
hack.
You could implement this by adding an EnumSetting
to allow users to select their preferred placement directions. Here's how you might do it:
private final EnumSetting<PlacementDirection> placementDirection =
new EnumSetting<>("Placement Direction", PlacementDirection.values(), PlacementDirection.HORIZONTAL);
private enum PlacementDirection
{
HORIZONTAL("Horizontal"),
VERTICAL("Vertical"),
BOTH("Both");
private final String name;
private PlacementDirection(String name)
{
this.name = name;
}
@Override
public String toString()
{
return name;
}
}
Then, adjust the onUpdate
method to handle the selected option:
BlockHitResult blockHitResult = (BlockHitResult) hitResult;
Direction side = blockHitResult.getSide();
switch (placementDirection.getSelected())
{
case HORIZONTAL:
if (side == Direction.UP || side == Direction.DOWN)
return;
break;
case VERTICAL:
if (side.getAxis().isHorizontal())
return;
break;
case BOTH:
// Allow all directions
break;
}
Alternatively, if you prefer multiple checkboxes for more granular control, you could add:
private final CheckboxSetting placeUp =
new CheckboxSetting("Place Up", true);
private final CheckboxSetting placeDown =
new CheckboxSetting("Place Down", true);
private final CheckboxSetting placeHorizontal =
new CheckboxSetting("Place Horizontal", true);
And modify the onUpdate
method accordingly:
BlockHitResult blockHitResult = (BlockHitResult) hitResult;
Direction side = blockHitResult.getSide();
if ((side == Direction.UP && !placeUp.isChecked()) ||
(side == Direction.DOWN && !placeDown.isChecked()) ||
(side.getAxis().isHorizontal() && !placeHorizontal.isChecked()))
return;
This gives users the flexibility to enable or disable placement in specific directions based on their needs.
Let me know your thoughts on these options!
assert MC.interactionManager != null; | ||
MC.interactionManager.interactItem(player, Hand.MAIN_HAND); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Redundant call to interactItem
.
The call to MC.interactionManager.interactItem(player, Hand.MAIN_HAND);
is unnecessary in this context because you are already interacting with the block using interactBlock
. This might lead to unintended item interactions.
Remove the redundant method call:
- MC.interactionManager.interactItem(player, Hand.MAIN_HAND);
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
assert MC.interactionManager != null; | |
MC.interactionManager.interactItem(player, Hand.MAIN_HAND); | |
assert MC.interactionManager != null; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
interactBlock
and interactItem
work in complicated and confusing ways. Sometimes both need to be called and sometimes even twice to match vanilla Minecraft behavior. I'd recommend instead using Wurst's utility net.wurstclient.util.InteractionSimulator
whenever possible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Alexander01998, thank you for the clarification. Using InteractionSimulator
makes sense to ensure consistent behavior with vanilla Minecraft. I've updated the code to use InteractionSimulator
:
@Override
public void onUpdate()
{
if(MC.currentScreen instanceof HandledScreen)
return;
if(MC.itemUseCooldown != 0 && !fastPlace.isChecked())
return;
ClientPlayerEntity player = MC.player;
assert player != null;
// Item in hand is not a block
if(!(player.getInventory().getStack(player.getInventory().selectedSlot)
.getItem() instanceof BlockItem))
return;
HitResult hitResult = MC.crosshairTarget;
if(hitResult == null || hitResult.getType() != HitResult.Type.BLOCK)
return;
BlockHitResult blockHitResult = (BlockHitResult)hitResult;
if(blockHitResult.getSide() == Direction.UP
|| blockHitResult.getSide() == Direction.DOWN)
return;
if(!BlockUtils.canBeClicked(blockHitResult.getBlockPos()))
return;
BlockPos blockToPlacePos =
blockHitResult.getBlockPos().offset(blockHitResult.getSide());
if(!BlockUtils.getState(blockToPlacePos).isReplaceable())
return;
// Option: only below feet
if(blockToPlacePos.getY() != BlockPos.ofFloored(MC.player.getPos())
.down().getY() && onlyBelowFeet.isChecked())
return;
// Use InteractionSimulator to simulate block placement
InteractionSimulator.rightClickBlock(blockHitResult, Hand.MAIN_HAND);
}
(•ᴗ•) A curious rabbit tilts its head in understanding.
ClientPlayerEntity player = MC.player; | ||
assert player != null; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Avoid using assertions for null checks in production code.
Using assert
statements for null checks is not recommended in production code because assertions may be disabled at runtime. Instead, consider implementing explicit null checks to prevent NullPointerException
.
Apply this change:
- assert player != null;
+ if (player == null)
+ return;
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
ClientPlayerEntity player = MC.player; | |
assert player != null; | |
ClientPlayerEntity player = MC.player; | |
if (player == null) | |
return; |
// Option: only below feet | ||
if(blockToPlacePos.getY() != BlockPos.ofFloored(MC.player.getPos()) | ||
.down().getY() && onlyBelowFeet.isChecked()) | ||
return; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Simplify the condition for better readability.
The conditional statement can be simplified for clarity by checking onlyBelowFeet
first before comparing positions.
Refactor the condition:
- if(blockToPlacePos.getY() != BlockPos.ofFloored(MC.player.getPos())
- .down().getY() && onlyBelowFeet.isChecked())
+ if (onlyBelowFeet.isChecked() && blockToPlacePos.getY() != MC.player.getBlockPos().down().getY())
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
// Option: only below feet | |
if(blockToPlacePos.getY() != BlockPos.ofFloored(MC.player.getPos()) | |
.down().getY() && onlyBelowFeet.isChecked()) | |
return; | |
// Option: only below feet | |
if (onlyBelowFeet.isChecked() && blockToPlacePos.getY() != MC.player.getBlockPos().down().getY()) | |
return; |
ClientPlayerEntity player = MC.player; | ||
assert player != null; | ||
|
||
// Item in hand is not a block | ||
if(!(player.getInventory().getStack(player.getInventory().selectedSlot) | ||
.getItem() instanceof BlockItem)) | ||
return; | ||
|
||
HitResult hitResult = MC.crosshairTarget; | ||
if(hitResult == null || hitResult.getType() != HitResult.Type.BLOCK) | ||
return; | ||
|
||
BlockHitResult blockHitResult = (BlockHitResult)hitResult; | ||
if(blockHitResult.getSide() == Direction.UP | ||
|| blockHitResult.getSide() == Direction.DOWN) | ||
return; | ||
|
||
if(!BlockUtils.canBeClicked(blockHitResult.getBlockPos())) | ||
return; | ||
|
||
BlockPos blockToPlacePos = | ||
blockHitResult.getBlockPos().offset(blockHitResult.getSide()); | ||
if(!BlockUtils.getState(blockToPlacePos).isReplaceable()) | ||
return; | ||
|
||
// Option: only below feet | ||
if(blockToPlacePos.getY() != BlockPos.ofFloored(MC.player.getPos()) | ||
.down().getY() && onlyBelowFeet.isChecked()) | ||
return; | ||
|
||
assert MC.interactionManager != null; | ||
MC.interactionManager.interactItem(player, Hand.MAIN_HAND); | ||
ActionResult actionResult = MC.interactionManager.interactBlock(player, | ||
Hand.MAIN_HAND, blockHitResult); | ||
if(actionResult.isAccepted()) | ||
MC.player.swingHand(Hand.MAIN_HAND); | ||
|
||
MC.itemUseCooldown = 4; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Handle potential NullPointerException
for MC.interactionManager
.
Similar to the player entity, MC.interactionManager
could be null. Relying on assertions might not prevent exceptions in production.
Implement a null check:
- assert MC.interactionManager != null;
+ if (MC.interactionManager == null)
+ return;
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
ClientPlayerEntity player = MC.player; | |
assert player != null; | |
// Item in hand is not a block | |
if(!(player.getInventory().getStack(player.getInventory().selectedSlot) | |
.getItem() instanceof BlockItem)) | |
return; | |
HitResult hitResult = MC.crosshairTarget; | |
if(hitResult == null || hitResult.getType() != HitResult.Type.BLOCK) | |
return; | |
BlockHitResult blockHitResult = (BlockHitResult)hitResult; | |
if(blockHitResult.getSide() == Direction.UP | |
|| blockHitResult.getSide() == Direction.DOWN) | |
return; | |
if(!BlockUtils.canBeClicked(blockHitResult.getBlockPos())) | |
return; | |
BlockPos blockToPlacePos = | |
blockHitResult.getBlockPos().offset(blockHitResult.getSide()); | |
if(!BlockUtils.getState(blockToPlacePos).isReplaceable()) | |
return; | |
// Option: only below feet | |
if(blockToPlacePos.getY() != BlockPos.ofFloored(MC.player.getPos()) | |
.down().getY() && onlyBelowFeet.isChecked()) | |
return; | |
assert MC.interactionManager != null; | |
MC.interactionManager.interactItem(player, Hand.MAIN_HAND); | |
ActionResult actionResult = MC.interactionManager.interactBlock(player, | |
Hand.MAIN_HAND, blockHitResult); | |
if(actionResult.isAccepted()) | |
MC.player.swingHand(Hand.MAIN_HAND); | |
MC.itemUseCooldown = 4; | |
ClientPlayerEntity player = MC.player; | |
assert player != null; | |
// Item in hand is not a block | |
if(!(player.getInventory().getStack(player.getInventory().selectedSlot) | |
.getItem() instanceof BlockItem)) | |
return; | |
HitResult hitResult = MC.crosshairTarget; | |
if(hitResult == null || hitResult.getType() != HitResult.Type.BLOCK) | |
return; | |
BlockHitResult blockHitResult = (BlockHitResult)hitResult; | |
if(blockHitResult.getSide() == Direction.UP | |
|| blockHitResult.getSide() == Direction.DOWN) | |
return; | |
if(!BlockUtils.canBeClicked(blockHitResult.getBlockPos())) | |
return; | |
BlockPos blockToPlacePos = | |
blockHitResult.getBlockPos().offset(blockHitResult.getSide()); | |
if(!BlockUtils.getState(blockToPlacePos).isReplaceable()) | |
return; | |
// Option: only below feet | |
if(blockToPlacePos.getY() != BlockPos.ofFloored(MC.player.getPos()) | |
.down().getY() && onlyBelowFeet.isChecked()) | |
return; | |
if (MC.interactionManager == null) | |
return; | |
MC.interactionManager.interactItem(player, Hand.MAIN_HAND); | |
ActionResult actionResult = MC.interactionManager.interactBlock(player, | |
Hand.MAIN_HAND, blockHitResult); | |
if(actionResult.isAccepted()) | |
MC.player.swingHand(Hand.MAIN_HAND); | |
MC.itemUseCooldown = 4; |
d4b624e
to
40778be
Compare
wait a min did i just done something very stupid again |
40778be
to
41ab6d2
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Caution
Inline review comments failed to post. This is likely due to GitHub's limits when posting large numbers of comments.
Actionable comments posted: 11
🧹 Outside diff range and nitpick comments (14)
gradle.properties (1)
8-16
: Overall assessment of gradle.properties changesThe changes in this file are mostly consistent with the PR objectives to update the mod for Minecraft 1.21. However, the Fabric API version downgrade needs further investigation to ensure compatibility and explain the reason for the change.
Consider implementing a version compatibility check in your build process to ensure that all dependencies are at their latest compatible versions. This could help prevent potential issues with version mismatches in the future.
src/main/java/net/wurstclient/settings/filters/FilterTeammatesSetting.java (2)
10-13
: Consider using a constant for the filter name.The constructor looks good overall. However, the hardcoded string "Filter teammates" might be better as a constant or configurable value. This would make maintenance easier and potentially support localization in the future.
Consider refactoring like this:
+ private static final String FILTER_NAME = "Filter teammates"; public FilterTeammatesSetting(String description, boolean checked) { - super("Filter teammates", description, checked); + super(FILTER_NAME, description, checked); }
15-34
: LGTM: Thorough null checks and correct teammate identification logic.The
test
method is well-implemented with thorough null checks to prevent NullPointerExceptions. The logic for determining if an entity is a teammate based on name color is correct.Consider caching the player's display name color to potentially improve performance, especially if this method is called frequently:
public final class FilterTeammatesSetting extends EntityFilterCheckbox { + private TextColor cachedPlayerColor; // ... existing code ... @Override public boolean test(Entity e) { Text theirName = e.getDisplayName(); if(theirName == null) return false; TextColor theirColor = theirName.getStyle().getColor(); if(theirColor == null) return false; assert WurstClient.MC.player != null; + if (cachedPlayerColor == null) { Text myName = WurstClient.MC.player.getDisplayName(); if(myName == null) return false; - TextColor myColor = myName.getStyle().getColor(); - if(myColor == null) + cachedPlayerColor = myName.getStyle().getColor(); + if(cachedPlayerColor == null) return false; + } - return !theirColor.equals(myColor); + return !theirColor.equals(cachedPlayerColor); } // ... existing code ... }This change would cache the player's color, potentially reducing the number of object creations and method calls in scenarios where this method is called frequently.
src/main/java/net/wurstclient/hacks/AutoReconnectHack.java (2)
22-25
: LGTM: New CheckboxSetting added with clear description.The new
buttons
setting aligns well with the PR objectives, allowing users to control the visibility of the reconnect button. The description is informative, and the default value oftrue
ensures a good out-of-the-box experience.Consider adding "when disconnected" to the end of the description for extra clarity:
private final CheckboxSetting buttons = new CheckboxSetting( "Reconnect screen button", "Shows a button on the reconnect" - + " screen that lets you quickly enable AutoReconnect.", + + " screen that lets you quickly enable AutoReconnect when disconnected.", true);
38-41
: LGTM: New method added to check button visibility preference.The
shouldShowButtons()
method provides a clean interface for accessing the button visibility preference. The implementation is correct and the method name is descriptive.For a minor optimization, you could make this method a one-liner:
public boolean shouldShowButtons() { - return buttons.isChecked(); + return buttons.isChecked(); }This change doesn't affect functionality but makes the code slightly more concise.
src/main/java/net/wurstclient/settings/filterlists/EntityFilterList.java (1)
65-66
: LGTM! Consider grouping related filters for better readability.The addition of
FilterTeammatesSetting
andFilterNpcLikeSetting
enhances the entity filtering capabilities, which aligns well with the PR objectives. The placement and default values (false) are consistent with other filters.To improve code organization and readability, consider grouping related filters together. For example, you could move these new filters next to other player-related filters like
FilterSleepingSetting
orFilterInvisibleSetting
.src/main/java/net/wurstclient/mixin/DisconnectedScreenMixin.java (1)
73-74
: Approved: Improved control over reconnect button visibilityThe addition of the conditional check before calling
addReconnectButtons()
is a good improvement. It ensures that the reconnect buttons are only displayed when appropriate, based on the state of theautoReconnectHack
.Consider extracting the condition to a descriptive method name for improved readability:
-if(WurstClient.INSTANCE.getHax().autoReconnectHack.shouldShowButtons()) +if(shouldShowReconnectButtons()) addReconnectButtons(); +private boolean shouldShowReconnectButtons() { + return WurstClient.INSTANCE.getHax().autoReconnectHack.shouldShowButtons(); +}This change would make the code more self-documenting and easier to maintain.
src/main/java/net/wurstclient/hacks/AimAssistHack.java (2)
57-60
: LGTM: New setting added correctly.The
onlyHoldingWeapon
setting is well-implemented and aligns with the PR objectives. The description is clear and the default value is appropriate.Consider adding a comment explaining why sticks are considered weapons, as it might not be immediately obvious to other developers.
156-162
: LGTM: onUpdate method updated correctly.The new check for the
onlyHoldingWeapon
setting is well-implemented and correctly enforces the new functionality. The early return optimizes performance when the condition is not met.Consider extracting the weapon check into a separate method for better readability and potential reuse, e.g.:
private boolean isHoldingWeapon() { Item itemInHand = MC.player.getInventory().getMainHandStack().getItem(); return itemInHand instanceof SwordItem || itemInHand instanceof AxeItem || itemInHand == Items.STICK; }Then use it in the
onUpdate
method:if (onlyHoldingWeapon.isChecked() && !isHoldingWeapon()) { target = null; return; }src/main/java/net/wurstclient/settings/filters/FilterNpcLikeSetting.java (2)
23-43
: Optimize the loop by avoiding unnecessary array creationCreating an array with
.toArray()
can be inefficient. Iterate over the stream directly to improve performance.Apply this diff to optimize the loop:
-int letters = 0, digits = 0, maxLetters = 0, maxDigits = 0; -for(int c : name.chars().toArray()) +int letters = 0, digits = 0, maxLetters = 0, maxDigits = 0; +IntStream stream = name.codePoints(); +PrimitiveIterator.OfInt iterator = stream.iterator(); +while (iterator.hasNext()) { int c = iterator.nextInt();Alternatively, you can use a for-each loop over the stream:
-for(int c : name.chars().toArray()) +for(int c : name.codePoints().toArray())
55-67
: Consistent descriptions in factory methodsThe descriptions in
genericCombat
andgenericVision
methods are identical. If there are differences in how these settings are used, consider updating the descriptions to reflect their specific purposes.Apply this diff to clarify descriptions:
-return new FilterNpcLikeSetting( - "Won't attack NPC-like players (Sort by Hypixel NPC names.)", + "Won't attack NPC-like players (identifies NPCs by their names).",And
-return new FilterNpcLikeSetting( - "Won't show NPC-like players (Sort by Hypixel NPC names.)", + "Won't show NPC-like players (identifies NPCs by their names).",src/main/java/net/wurstclient/hacks/AutoPlaceHack.java (1)
38-42
: Add a description to the hack for better clarity.Including a description helps users understand the purpose and functionality of the
AutoPlace
hack within the client UI.You can set the description in the constructor:
super("AutoPlace"); setDescription("Automatically places blocks when aiming at block sides, assisting in bridging.");src/main/java/net/wurstclient/hacks/SafeWalkHack.java (1)
26-26
: Typo in description for 'minDepth' settingThe description contains a typo: "Increase to stop SafeWalk from stucking on stairs." It should be "from getting stuck on stairs."
Apply this diff to correct the typo:
-"Increase to stop SafeWalk from stucking on stairs.\n" +"Increase to stop SafeWalk from getting stuck on stairs.\n"src/main/java/net/wurstclient/hacks/TriggerBotHack.java (1)
72-76
: Consider renaming the setting for consistencyThe setting is named
"Black-listed Items"
with a hyphen. For consistency with other settings and standard terminology, consider renaming it to"Blacklisted Items"
without the hyphen.Apply this diff to rename the setting:
private final ItemListSetting blacklistedItems = new ItemListSetting( - "Black-listed Items", + "Blacklisted Items", "Will not trigger when these items are in your hand, so you will never mis-click when you are in the lobby.", "minecraft:compass", "minecraft:clock");
🛑 Comments failed to post (11)
gradle.properties (1)
13-13: 💡 Codebase verification
⚠️ Potential issueFabric API version downgraded below the latest version
The Fabric API version has been downgraded to
0.102.0+1.21
, which is below both the previous version0.105.0+1.21.1
and the latest version0.106.0+1.21.2
. This downgrade may introduce compatibility issues or omit important features and fixes.🔗 Analysis chain
Verify Fabric API version downgrade
The Fabric API version has been changed from 0.105.0+1.21.1 to 0.102.0+1.21. This is a version downgrade, which is unusual for an update.
Please verify that this older version of Fabric API is compatible with all features of the mod and Minecraft 1.21. Consider checking the Fabric API changelog to ensure no critical features or fixes are being missed. If possible, explain the reason for downgrading.
To verify the latest compatible version, you can run:
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Check latest Fabric API version for Minecraft 1.21 curl -s https://api.modrinth.com/v2/project/fabric-api/version | jq -r '.[] | select(.game_versions | contains(["1.21"])) | .version_number' | sort -V | tail -n 1Length of output: 179
src/main/java/net/wurstclient/settings/filters/FilterNpcLikeSetting.java (3)
45-51:
⚠️ Potential issueReevaluate the filtering conditions for better accuracy
The conditions at the end of the
test
method may not accurately classify NPC-like names. For example, names with certain patterns might bypass the filter unintentionally. Consider reviewing and refining these conditions to ensure they match the intended criteria for NPC-like player names.If possible, provide examples of player names that should be filtered and adjust the conditions accordingly.
24-43: 🛠️ Refactor suggestion
Use
codePoints()
instead ofchars()
to handle Unicode characters correctlyUsing
name.chars()
processes characters as UTF-16 code units, which may not correctly handle characters outside the Basic Multilingual Plane (BMP). Replacename.chars()
withname.codePoints()
to operate on Unicode code points and ensure accurate character processing.Apply this diff to use
codePoints()
:-for(int c : name.chars().toArray()) +for(int c : name.codePoints().toArray())📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.for(int c : name.codePoints().toArray()) { if(Character.isDigit(c)) { letters = 0; digits += 1; }else if(Character.isLetter(c) && Character.isLowerCase(c)) { digits = 0; letters += 1; }else { return true; } if(letters > maxLetters) maxLetters = letters; if(digits > maxDigits) maxDigits = digits; }
24-43:
⚠️ Potential issueHandle uppercase letters and special characters in player names
The
test
method only considers lowercase letters due to the conditionCharacter.isLowerCase(c)
. Player names with uppercase letters or special characters will result inreturn true
, possibly excluding legitimate players from the filter. Consider modifying the condition to include uppercase letters and handle special characters appropriately.Apply this diff to include uppercase letters:
-}else if(Character.isLetter(c) && Character.isLowerCase(c)) +}else if(Character.isLetter(c))Additionally, if special characters are allowed in player names, adjust the logic to account for them, or explicitly handle them based on your requirements.
Committable suggestion was skipped due to low confidence.
src/main/java/net/wurstclient/hacks/AutoPlaceHack.java (1)
70-72: 🛠️ Refactor suggestion
Simplify item in hand check for better readability.
You can use
player.getMainHandStack()
to retrieve the item in the player's main hand, making the code more concise.Refactor the code as follows:
-if(!(player.getInventory().getStack(player.getInventory().selectedSlot) - .getItem() instanceof BlockItem)) +if (!(player.getMainHandStack().getItem() instanceof BlockItem)) return;📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.if (!(player.getMainHandStack().getItem() instanceof BlockItem)) return;
src/main/java/net/wurstclient/hacks/SafeWalkHack.java (1)
71-82: 🛠️ Refactor suggestion
Refactor to eliminate code duplication between 'shouldClip()' and 'onClipAtLedge()'
Both methods
shouldClip()
andonClipAtLedge()
perform similar calculations foradjustedBox
and checkMC.world.isSpaceEmpty(player, adjustedBox)
. Consider refactoring to avoid code duplication by reusingshouldClip()
withinonClipAtLedge()
.Apply this diff to refactor the code:
public boolean shouldClip() { ClientPlayerEntity player = MC.player; Box box = player.getBoundingBox(); Box adjustedBox = box .offset(player.getVelocity().multiply(motionPrediction.getValue())) .stretch(0, -minDepth.getValue(), 0) .expand(-edgeDistance.getValue(), 0, -edgeDistance.getValue()); return MC.world.isSpaceEmpty(player, adjustedBox); } public void onClipAtLedge() { ClientPlayerEntity player = MC.player; if(!isEnabled() || !sneak.isChecked() || !player.isOnGround()) { if(sneaking) setSneaking(false); return; } setSneaking(shouldClip()); }This refactoring removes the duplicated code by utilizing
shouldClip()
withinonClipAtLedge()
, enhancing maintainability.Also applies to: 84-102
src/main/java/net/wurstclient/hacks/TriggerBotHack.java (3)
166-167: 🛠️ Refactor suggestion
Improve performance by using a
Set
for blacklist itemsIf
blacklistedItems.getItemNames()
returns aList
, thecontains
method has a linear time complexity. Converting the item names to aSet
will improve the performance of thecontains
checks, especially if the blacklist grows.Consider updating the
ItemListSetting
to use aSet
internally or cache theSet
representation:// In ItemListSetting class public Set<String> getItemNameSet() { return new HashSet<>(itemNames); }Then, use
getItemNameSet()
in your check:-if(blacklistedItems.getItemNames().contains(itemName)) +if(blacklistedItems.getItemNameSet().contains(itemName)) return;
72-76:
⚠️ Potential issueFix grammatical errors in the setting description
There are grammatical mistakes in the description of the
blacklistedItems
setting:
- "these item" should be "these items"
- "in lobby" should be "in the lobby"
Apply this diff to correct the description:
private final ItemListSetting blacklistedItems = new ItemListSetting( - "Black-listed Items", - "Will not trigger when these item are in your hand, so you will never mis-click when you are in lobby.", + "Blacklisted Items", + "Will not trigger when these items are in your hand, so you will never mis-click when you are in the lobby.", "minecraft:compass", "minecraft:clock");📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.private final ItemListSetting blacklistedItems = new ItemListSetting( "Blacklisted Items", "Will not trigger when these items are in your hand, so you will never mis-click when you are in the lobby.", "minecraft:compass", "minecraft:clock");
156-168: 🛠️ Refactor suggestion
Simplify the item blacklist checking logic
The current logic for checking the blacklisted items can be simplified to improve readability and maintainability. By assigning the item name in both cases (when the stack is empty or not), you can perform a single check against the blacklist.
Apply this diff to streamline the code:
ItemStack stack = MC.player.getInventory().getMainHandStack(); -if(stack.isEmpty()) -{ - if(blacklistedItems.getItemNames().contains("minecraft:air")) - return; -} -else -{ - Item item = stack.getItem(); - String itemName = Registries.ITEM.getId(item).toString(); - - if(blacklistedItems.getItemNames().contains(itemName)) - return; -} + +String itemName = stack.isEmpty() + ? "minecraft:air" + : Registries.ITEM.getId(stack.getItem()).toString(); + +if(blacklistedItems.getItemNames().contains(itemName)) + return;📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.ItemStack stack = MC.player.getInventory().getMainHandStack(); String itemName = stack.isEmpty() ? "minecraft:air" : Registries.ITEM.getId(stack.getItem()).toString(); if(blacklistedItems.getItemNames().contains(itemName)) return;
src/main/java/net/wurstclient/hacks/TeamEspHack.java (2)
46-47: 🛠️ Refactor suggestion
Consider refactoring to eliminate code duplication
The comment on line 46 indicates that this class is "pretty much just cloned from
PlayerEspHack.java
". To improve maintainability and adhere to the DRY (Don't Repeat Yourself) principle, consider abstracting shared functionality into a base class or utility methods. This would reduce code duplication and make it easier to implement future changes or fixes across both hacks.
168-177:
⚠️ Potential issueCorrect RGB color extraction for accurate team colors
The current method of extracting RGB components from
teamColor
may not produce the correct colors due to integer division and modulus operations. This can lead to incorrect coloring of the ESP boxes and tracers.Apply the following diff to correctly extract the RGB values using bitwise operations:
@@ -168,10 +168,7 @@ int teamColor = colorComponent.getRgb(); - b = (float)(teamColor % 256); - g = (float)(teamColor % 65536 / 256); - r = (float)(teamColor / 65536); - - b /= 256; - g /= 256; - r /= 256; + r = ((teamColor >> 16) & 0xFF) / 255.0f; + g = ((teamColor >> 8) & 0xFF) / 255.0f; + b = (teamColor & 0xFF) / 255.0f;Repeat the same correction in the
renderTracers
method at lines 218-227 to ensure consistency.Also applies to: 218-227
wait what i didn't do that merge |
bro no way, every time I think "oh I finally learned how to use git" it just slaps me in the face and says "no you don't" |
※ I recreated #1048 because I used the wrong branch, sorry.
Description
Added a simple but cool feature,
AutoPlace
. This hack allows you to free up your right middle finger when bridging, as it will place the blocks for you when you need to.When it's enabled, blocks will be placed as long as you aim at side faces of blocks.
Testing
It's working, here's the video
Don't complain about my aiming though, I'm using a very bad mouse right nowNotes
😎 I've applied
spotless
to match the original coding style.🤔 Not sure if I need to disable some other hacks like
ScaffoldWalk
when this hack is turned on?