Skip to content

Commit b441c1f

Browse files
committed
initial commit
0 parents  commit b441c1f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+3224
-0
lines changed

.github/workflows/build.yml

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
name: Build
2+
3+
on:
4+
push:
5+
tags:
6+
- 'v*'
7+
8+
jobs:
9+
build:
10+
runs-on: ubuntu-latest
11+
12+
steps:
13+
- uses: actions/checkout@v4
14+
15+
- name: Set up JDK 21
16+
uses: actions/setup-java@v4
17+
with:
18+
java-version: '21'
19+
distribution: 'temurin'
20+
21+
- name: Setup Gradle
22+
uses: gradle/actions/setup-gradle@v3
23+
24+
- name: Make gradlew executable
25+
run: chmod +x ./gradlew
26+
27+
- name: Build with Gradle
28+
run: |
29+
VERSION=${GITHUB_REF_NAME#v}
30+
./gradlew collectJars -Pversion=$VERSION
31+
32+
- name: Upload Artifacts
33+
uses: actions/upload-artifact@v4
34+
with:
35+
name: netutils-jars
36+
path: build/libs/*.jar

.gitignore

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# Gradle
2+
.gradle/
3+
build/
4+
out/
5+
6+
# IDE
7+
.idea/
8+
*.iml
9+
*.ipr
10+
*.iws
11+
.vscode/
12+
*.code-workspace
13+
14+
# Fabric/Loom
15+
run/
16+
*.log
17+
remappedSrc/
18+
19+
# Build artifacts
20+
build_log.txt
21+
*.jar
22+
!gradle/wrapper/gradle-wrapper.jar
23+
24+
# OS
25+
.DS_Store
26+
Thumbs.db
27+
28+
# Misc
29+
*.bak
30+
*.tmp
31+
32+
# Eclipse
33+
.settings/
34+
.classpath
35+
.project
36+
eclipse/
37+
bin/
38+
39+
.loom-cache/
40+
.qmap/
41+
.kotlin/

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2025 mishl
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# NetUtils
2+
3+
A Network utility mod for dupe hunting and packet manipulation.
4+
5+
## Features
6+
- **Packet Control**: Delay or toggle outgoing packets.
7+
- **De-sync**: Intentionally desynchronize your client from the server (Ghost Mode).
8+
- **Inventory Control**: Close inventory screens without sending packets to the server.
9+
- **Resource Pack Control**: Bypass or force-deny server resource packs.
10+
11+
## Usage
12+
Press **V** to restore the last closed screen.
13+
14+
## Building
15+
Run the following command to build for both Fabric and NeoForge:
16+
```bash
17+
./gradlew collectJars
18+
```
19+
The output jars will be in `build/libs/`.
20+
21+
## License
22+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.

build.gradle.kts

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
plugins {
2+
id("architectury-plugin") version "3.4.161"
3+
id("dev.architectury.loom") version "1.13.467" apply false
4+
kotlin("jvm") version "2.3.0" apply false
5+
}
6+
7+
architectury {
8+
minecraft = "1.21.11"
9+
}
10+
11+
subprojects {
12+
apply(plugin = "dev.architectury.loom")
13+
apply(plugin = "org.jetbrains.kotlin.jvm")
14+
15+
repositories {
16+
mavenCentral()
17+
maven("https://maven.fabricmc.net/")
18+
maven("https://maven.architectury.dev/")
19+
maven("https://maven.minecraftforge.net/")
20+
maven("https://maven.neoforged.net/releases/")
21+
maven("https://maven.terraformersmc.com/releases/")
22+
}
23+
}
24+
25+
allprojects {
26+
group = "org.netutils"
27+
version = "1.0.0"
28+
}
29+
30+
tasks.register("collectJars", Copy::class) {
31+
dependsOn(subprojects.map { it.tasks.named("build") })
32+
33+
from(project(":fabric").tasks.named("remapJar").map { (it as org.gradle.jvm.tasks.Jar).archiveFile })
34+
from(project(":forge").tasks.named("remapJar").map { (it as org.gradle.jvm.tasks.Jar).archiveFile })
35+
36+
into(layout.buildDirectory.dir("libs"))
37+
38+
rename { "netutils-${it}" }
39+
40+
doLast {
41+
println("Universal compilation complete. Jars collected in: ${layout.buildDirectory.dir("libs").get()}")
42+
}
43+
}

common/build.gradle.kts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
plugins {
2+
id("dev.architectury.loom")
3+
id("architectury-plugin")
4+
kotlin("jvm")
5+
}
6+
7+
architectury {
8+
common("fabric", "forge")
9+
}
10+
11+
loom {
12+
silentMojangMappingsLicense()
13+
}
14+
15+
dependencies {
16+
minecraft("com.mojang:minecraft:1.21.11")
17+
mappings(loom.officialMojangMappings())
18+
modImplementation("dev.architectury:architectury:${rootProject.property("architectury_version")}")
19+
20+
implementation(kotlin("stdlib"))
21+
}
22+
23+
kotlin {
24+
jvmToolchain(21)
25+
}
26+
27+
sourceSets {
28+
main {
29+
java.srcDirs("src/main/java", "src/main/kotlin")
30+
}
31+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package org.netutils.mixin;
2+
3+
import net.minecraft.client.Minecraft;
4+
import net.minecraft.client.gui.screens.Screen;
5+
import net.minecraft.client.gui.screens.inventory.BookEditScreen;
6+
import net.minecraft.network.chat.Component;
7+
import org.spongepowered.asm.mixin.Mixin;
8+
import org.spongepowered.asm.mixin.injection.At;
9+
import org.spongepowered.asm.mixin.injection.Inject;
10+
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
11+
import org.netutils.SharedVariables;
12+
import org.netutils.gui.WidgetUtils;
13+
14+
@Mixin(BookEditScreen.class)
15+
public abstract class BookEditScreenMixin extends Screen {
16+
17+
protected BookEditScreenMixin(Component component) {
18+
super(component);
19+
}
20+
21+
@Inject(at = @At("TAIL"), method = "init")
22+
public void init(CallbackInfo ci) {
23+
if (SharedVariables.enabled) {
24+
WidgetUtils.INSTANCE.createWidgets(Minecraft.getInstance(), this);
25+
}
26+
}
27+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package org.netutils.mixin;
2+
3+
import net.minecraft.client.Minecraft;
4+
import net.minecraft.client.gui.screens.Screen;
5+
import net.minecraft.client.gui.screens.inventory.BookViewScreen;
6+
import net.minecraft.network.chat.Component;
7+
import org.spongepowered.asm.mixin.Mixin;
8+
import org.spongepowered.asm.mixin.injection.At;
9+
import org.spongepowered.asm.mixin.injection.Inject;
10+
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
11+
import org.netutils.SharedVariables;
12+
import org.netutils.gui.WidgetUtils;
13+
14+
@Mixin(BookViewScreen.class)
15+
public abstract class BookScreenMixin extends Screen {
16+
17+
protected BookScreenMixin(Component component) {
18+
super(component);
19+
}
20+
21+
@Inject(at = @At("TAIL"), method = "init")
22+
public void init(CallbackInfo ci) {
23+
if (SharedVariables.enabled) {
24+
WidgetUtils.INSTANCE.createWidgets(Minecraft.getInstance(), this);
25+
}
26+
}
27+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package org.netutils.mixin;
2+
3+
import net.minecraft.client.gui.screens.ChatScreen;
4+
import org.netutils.command.ClientCommands;
5+
import org.spongepowered.asm.mixin.Mixin;
6+
import org.spongepowered.asm.mixin.injection.At;
7+
import org.spongepowered.asm.mixin.injection.Inject;
8+
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
9+
10+
/**
11+
* Mixin to intercept chat messages and handle client-side commands.
12+
*/
13+
@Mixin(ChatScreen.class)
14+
public class ChatScreenMixin {
15+
16+
/**
17+
* Intercept the handleChatInput method to handle client commands.
18+
* This method is called when the user presses Enter in the chat.
19+
* In 1.21.11, handleChatInput returns void, so we use CallbackInfo.
20+
*/
21+
@Inject(at = @At("HEAD"), method = "handleChatInput", cancellable = true)
22+
private void netutils$onHandleChatInput(String message, boolean addToHistory, CallbackInfo ci) {
23+
// Check if this is a NetUtils command
24+
if (message.startsWith(ClientCommands.PREFIX)) {
25+
// Try to execute the command
26+
boolean handled = ClientCommands.INSTANCE.tryExecute(message);
27+
if (handled) {
28+
// Cancel the original method - command was handled
29+
ci.cancel();
30+
}
31+
}
32+
}
33+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package org.netutils.mixin;
2+
3+
import net.minecraft.network.protocol.common.ClientboundResourcePackPushPacket;
4+
import net.minecraft.client.multiplayer.ClientCommonPacketListenerImpl;
5+
import net.minecraft.network.protocol.common.ServerboundResourcePackPacket;
6+
import org.spongepowered.asm.mixin.Mixin;
7+
import org.spongepowered.asm.mixin.injection.At;
8+
import org.spongepowered.asm.mixin.injection.Inject;
9+
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
10+
import org.netutils.SharedVariables;
11+
import org.netutils.NetUtilsCommon;
12+
/**
13+
* Mixin for resource pack handling.
14+
* Allows bypassing or denying server resource packs.
15+
*/
16+
@Mixin(ClientCommonPacketListenerImpl.class)
17+
public class ClientCommonNetworkHandlerMixin {
18+
19+
@Inject(method = "handleResourcePackPush", at = @At("HEAD"), cancellable = true)
20+
private void onResourcePackSend(ClientboundResourcePackPushPacket packet, CallbackInfo ci) {
21+
if (SharedVariables.bypassResourcePack) {
22+
// Pretend we accepted and loaded the pack
23+
NetUtilsCommon.LOGGER.info("Resource pack bypassed: {}", packet.url());
24+
ci.cancel();
25+
} else if (SharedVariables.resourcePackForceDeny) {
26+
// Decline the resource pack
27+
NetUtilsCommon.LOGGER.info("Resource pack denied: {}", packet.url());
28+
ci.cancel();
29+
}
30+
}
31+
}
32+

0 commit comments

Comments
 (0)