Skip to content

Commit 5ecc66a

Browse files
committed
Add Minecraft 1.7.10 Forge support
- Add mod/1.7.10/forge-1.7.10 module with source code - Create custom userdev3.jar with converted binpatches - Add mavenLocal() to repositories for custom forge artifacts - Include all platform implementations and transformers
1 parent d038ad8 commit 5ecc66a

62 files changed

Lines changed: 3586 additions & 1 deletion

File tree

Some content is hidden

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

build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ subprojects {
2121
group = "top.fifthlight.touchcontroller"
2222

2323
repositories {
24+
mavenLocal()
2425
mavenCentral()
2526
google()
2627
maven {
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
plugins {
2+
alias(libs.plugins.jetbrains.kotlin.jvm)
3+
alias(libs.plugins.jetbrains.kotlin.serialization)
4+
alias(libs.plugins.compose.compiler)
5+
id("TouchController.toolchain-conventions")
6+
id("TouchController.forge-conventions")
7+
id("TouchController.about-libraries-conventions")
8+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
gameVersion=1.7.10
2+
forgeVersion=10.13.4.1614
3+
mappingType=mcp-snapshot
4+
mcpVersion=20140925-1.7.10
5+
javaVersion=8
6+
useMixin=false
7+
remapOutput=true
8+
useAccessTransformer=true
9+
useCoreMod=true
10+
bridgeSlf4j=true
11+
legacyLanguageFormat=true
12+
excludeR8=org.scala-lang,com.mojang:patchy,net.minecraftforge:mergetool
13+
excludeR8Jar=
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package top.fifthlight.touchcontroller;
2+
3+
import cpw.mods.fml.relauncher.IFMLLoadingPlugin;
4+
import top.fifthlight.touchcontroller.buildinfo.BuildInfo;
5+
6+
import java.util.Map;
7+
8+
@IFMLLoadingPlugin.MCVersion("1.7.10")
9+
@IFMLLoadingPlugin.Name(BuildInfo.MOD_NAME)
10+
public class TouchControllerCorePlugin implements IFMLLoadingPlugin {
11+
@Override
12+
public String[] getASMTransformerClass() {
13+
return new String[]{
14+
TouchControllerTransformer.class.getName(),
15+
};
16+
}
17+
18+
@Override
19+
public String getModContainerClass() {
20+
return null;
21+
}
22+
23+
@Override
24+
public String getSetupClass() {
25+
return null;
26+
}
27+
28+
@Override
29+
public void injectData(Map<String, Object> data) {
30+
}
31+
32+
@Override
33+
public String getAccessTransformerClass() {
34+
return null;
35+
}
36+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package top.fifthlight.touchcontroller;
2+
3+
import net.minecraft.launchwrapper.IClassTransformer;
4+
import org.objectweb.asm.ClassReader;
5+
import org.objectweb.asm.ClassVisitor;
6+
import org.objectweb.asm.ClassWriter;
7+
import top.fifthlight.touchcontroller.transformer.*;
8+
9+
import java.util.function.Function;
10+
11+
public class TouchControllerTransformer implements IClassTransformer {
12+
@Override
13+
public byte[] transform(String name, String transformedName, byte[] basicClass) {
14+
Function<ClassVisitor, ClassVisitor> visitorFactory;
15+
switch (transformedName) {
16+
case "net.minecraft.util.MouseHelper":
17+
visitorFactory = MouseHelperTransformer::new;
18+
break;
19+
case "net.minecraft.client.settings.KeyBinding":
20+
visitorFactory = KeyBindingTransformer::new;
21+
break;
22+
case "net.minecraft.client.entity.EntityPlayerSP":
23+
visitorFactory = EntityPlayerSPTransformer::new;
24+
break;
25+
case "net.minecraft.client.renderer.EntityRenderer":
26+
visitorFactory = EntityRendererTransformer::new;
27+
break;
28+
case "net.minecraft.util.MovementInputFromOptions":
29+
visitorFactory = MovementInputFromOptionsTransformer::new;
30+
break;
31+
case "net.minecraft.client.gui.GuiIngame":
32+
visitorFactory = GuiIngameTransformer::new;
33+
break;
34+
case "net.minecraft.client.multiplayer.PlayerControllerMP":
35+
visitorFactory = PlayerControllerMPTransformer::new;
36+
break;
37+
case "net.minecraft.client.Minecraft":
38+
visitorFactory = MinecraftTransformer::new;
39+
break;
40+
default:
41+
return basicClass;
42+
}
43+
ClassReader classReader = new ClassReader(basicClass);
44+
ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
45+
ClassVisitor visitor = visitorFactory.apply(classWriter);
46+
classReader.accept(visitor, 0);
47+
return classWriter.toByteArray();
48+
}
49+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package top.fifthlight.touchcontroller.transformer;
2+
3+
import org.objectweb.asm.ClassVisitor;
4+
import org.objectweb.asm.MethodVisitor;
5+
import org.objectweb.asm.Opcodes;
6+
7+
public class EntityPlayerSPTransformer extends TouchControllerClassVisitor {
8+
public EntityPlayerSPTransformer(ClassVisitor classVisitor) {
9+
super(Opcodes.ASM5, classVisitor);
10+
}
11+
12+
@Override
13+
public String getClassName() {
14+
return "net.minecraft.client.entity.EntityPlayerSP";
15+
}
16+
17+
@Override
18+
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
19+
if ("onLivingUpdate".equals(name) || "func_70636_d".equals(mapSelfMethodName(name, desc))) {
20+
String selfClassName = unmapClassName(getClassName());
21+
return new MethodVisitor(Opcodes.ASM5, super.visitMethod(access, name, desc, signature, exceptions)) {
22+
private boolean isFirst = true;
23+
24+
// replace this.onGround to EntityPlayerSPHelper.shouldReturnOnGround(this.onGround) when first access
25+
@Override
26+
public void visitFieldInsn(int opcode, String owner, String name, String desc) {
27+
if (opcode != Opcodes.GETFIELD) {
28+
super.visitFieldInsn(opcode, owner, name, desc);
29+
return;
30+
}
31+
if (!selfClassName.equals(owner)) {
32+
super.visitFieldInsn(opcode, owner, name, desc);
33+
return;
34+
}
35+
if (!"onGround".equals(name) && !"field_70122_E".equals(mapSelfFieldName(name, desc))) {
36+
super.visitFieldInsn(opcode, owner, name, desc);
37+
return;
38+
}
39+
if (isFirst) {
40+
isFirst = false;
41+
super.visitFieldInsn(opcode, owner, name, desc);
42+
visitMethodInsn(Opcodes.INVOKESTATIC, "top/fifthlight/touchcontroller/helper/EntityPlayerSPHelper", "shouldReturnOnGround", "(Z)Z", false);
43+
return;
44+
}
45+
super.visitFieldInsn(opcode, owner, name, desc);
46+
}
47+
};
48+
} else {
49+
return super.visitMethod(access, name, desc, signature, exceptions);
50+
}
51+
}
52+
}
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
package top.fifthlight.touchcontroller.transformer;
2+
3+
import org.objectweb.asm.ClassVisitor;
4+
import org.objectweb.asm.Label;
5+
import org.objectweb.asm.MethodVisitor;
6+
import org.objectweb.asm.Opcodes;
7+
8+
public class EntityRendererTransformer extends TouchControllerClassVisitor {
9+
public EntityRendererTransformer(ClassVisitor classVisitor) {
10+
super(Opcodes.ASM5, classVisitor);
11+
}
12+
13+
@Override
14+
public String getClassName() {
15+
return "net.minecraft.client.renderer.EntityRenderer";
16+
}
17+
18+
@Override
19+
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
20+
if ("updateCameraAndRender".equals(name) || "func_181560_a".equals(mapSelfMethodName(name, desc))) {
21+
String entityPlayerSPName = "net.minecraft.client.entity.EntityPlayerSP";
22+
String unmappedEntityPlayerSPName = unmapClassName(entityPlayerSPName);
23+
return new MethodVisitor(Opcodes.ASM5, super.visitMethod(access, name, desc, signature, exceptions)) {
24+
// method: updateCameraAndRender
25+
// insert in every EntityPlayerSP#turn(FF)V:
26+
// if (!EntityRendererHelper.doDisableMouseDirection()) {
27+
// this.mc.player.turn(float, float);
28+
// }
29+
@Override
30+
public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {
31+
if (opcode != Opcodes.INVOKEVIRTUAL) {
32+
super.visitMethodInsn(opcode, owner, name, desc, itf);
33+
return;
34+
}
35+
if (!unmappedEntityPlayerSPName.equals(owner)) {
36+
super.visitMethodInsn(opcode, owner, name, desc, itf);
37+
return;
38+
}
39+
String mappedMethodName = mapMethodName(entityPlayerSPName, name, desc);
40+
if (!"turn".equals(name) && !"func_70082_c".equals(mappedMethodName)) {
41+
super.visitMethodInsn(opcode, owner, name, desc, itf);
42+
return;
43+
}
44+
super.visitMethodInsn(Opcodes.INVOKESTATIC, "top/fifthlight/touchcontroller/helper/EntityRendererHelper", "doDisableMouseDirection", "()Z", false);
45+
Label turn = new Label();
46+
Label skip = new Label();
47+
visitJumpInsn(Opcodes.IFEQ, turn);
48+
visitInsn(Opcodes.POP);
49+
visitInsn(Opcodes.POP);
50+
visitInsn(Opcodes.POP);
51+
visitJumpInsn(Opcodes.GOTO, skip);
52+
visitLabel(turn);
53+
super.visitMethodInsn(opcode, owner, name, desc, itf);
54+
visitLabel(skip);
55+
}
56+
};
57+
} else if ("getMouseOver".equals(name) || "func_78473_a".equals(mapSelfMethodName(name, desc))) {
58+
String entityName = "net.minecraft.entity.Entity";
59+
String unmappedEntityName = unmapClassName(entityName);
60+
return new MethodVisitor(Opcodes.ASM5, super.visitMethod(access, name, desc, signature, exceptions)) {
61+
// method: getMouseOver
62+
// replace entity.getLook(1.0F) to EntityRendererHelper.getLook()
63+
// replace entity.rayTrace(DF) to EntityRendererHelper.rayTrace()
64+
@Override
65+
public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {
66+
if (opcode != Opcodes.INVOKEVIRTUAL) {
67+
super.visitMethodInsn(opcode, owner, name, desc, itf);
68+
return;
69+
}
70+
if (!unmappedEntityName.equals(owner)) {
71+
super.visitMethodInsn(opcode, owner, name, desc, itf);
72+
return;
73+
}
74+
String mappedMethodName = mapMethodName(unmappedEntityName, name, desc);
75+
if ("getLook".equals(name) || "func_70676_i".equals(mappedMethodName)) {
76+
visitInsn(Opcodes.POP);
77+
visitVarInsn(Opcodes.ALOAD, 0);
78+
visitVarInsn(Opcodes.FLOAD, 1);
79+
super.visitMethodInsn(Opcodes.INVOKESTATIC, "top/fifthlight/touchcontroller/helper/EntityRendererHelper", "getLook", "(Lnet/minecraft/entity/Entity;Lnet/minecraft/client/renderer/EntityRenderer;F)Lnet/minecraft/util/math/Vec3d;", false);
80+
return;
81+
} else if ("rayTrace".equals(name) || "func_174822_a".equals(mappedMethodName)) {
82+
visitVarInsn(Opcodes.ALOAD, 0);
83+
super.visitMethodInsn(Opcodes.INVOKESTATIC, "top/fifthlight/touchcontroller/helper/EntityRendererHelper", "rayTrace", "(Lnet/minecraft/entity/Entity;DFLnet/minecraft/client/renderer/EntityRenderer;)Lnet/minecraft/util/math/RayTraceResult;", false);
84+
return;
85+
}
86+
super.visitMethodInsn(opcode, owner, name, desc, itf);
87+
}
88+
};
89+
} else if ("isDrawBlockOutline".equals(name) || "func_175070_n".equals(mapSelfMethodName(name, desc))) {
90+
return new MethodVisitor(Opcodes.ASM5, super.visitMethod(access, name, desc, signature, exceptions)) {
91+
// Add code to isDrawBlockOutline:
92+
// if (EntityRendererHelper.doDisableBlockOutline()) {
93+
// return;
94+
// }
95+
@Override
96+
public void visitCode() {
97+
visitMethodInsn(Opcodes.INVOKESTATIC, "top/fifthlight/touchcontroller/helper/EntityRendererHelper", "doDisableBlockOutline", "()Z", false);
98+
Label skip = new Label();
99+
visitJumpInsn(Opcodes.IFEQ, skip);
100+
visitInsn(Opcodes.ICONST_0);
101+
visitInsn(Opcodes.IRETURN);
102+
visitLabel(skip);
103+
super.visitCode();
104+
}
105+
};
106+
} else {
107+
return super.visitMethod(access, name, desc, signature, exceptions);
108+
}
109+
}
110+
}
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
package top.fifthlight.touchcontroller.transformer;
2+
3+
import org.objectweb.asm.ClassVisitor;
4+
import org.objectweb.asm.MethodVisitor;
5+
import org.objectweb.asm.Opcodes;
6+
7+
public class GuiIngameTransformer extends TouchControllerClassVisitor {
8+
public GuiIngameTransformer(ClassVisitor classVisitor) {
9+
super(Opcodes.ASM5, classVisitor);
10+
}
11+
12+
@Override
13+
public String getClassName() {
14+
return "net.minecraft.client.gui.GuiIngame";
15+
}
16+
17+
@Override
18+
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
19+
if ("renderHotbar".equals(name) || "func_180479_a".equals(mapSelfMethodName(name, desc))) {
20+
String renderHelperName = "net.minecraft.client.renderer.RenderHelper";
21+
String unmappedRenderHelperName = unmapClassName(renderHelperName);
22+
return new MethodVisitor(Opcodes.ASM5, super.visitMethod(access, name, desc, signature, exceptions)) {
23+
// Call GuiIngameHelper.renderHotbar before every RenderHelper.enableGUIStandardItemLighting();
24+
@Override
25+
public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {
26+
if (opcode != Opcodes.INVOKESTATIC) {
27+
super.visitMethodInsn(opcode, owner, name, desc, itf);
28+
return;
29+
}
30+
if (!unmappedRenderHelperName.equals(owner)) {
31+
super.visitMethodInsn(opcode, owner, name, desc, itf);
32+
return;
33+
}
34+
String mappedMethodName = mapMethodName(renderHelperName, name, desc);
35+
if (!"enableGUIStandardItemLighting".equals(name) && !"func_74520_c".equals(mappedMethodName)) {
36+
super.visitMethodInsn(opcode, owner, name, desc, itf);
37+
return;
38+
}
39+
visitVarInsn(Opcodes.ALOAD, 1);
40+
super.visitMethodInsn(Opcodes.INVOKESTATIC, "top/fifthlight/touchcontroller/helper/GuiIngameHelper", "renderHotbar", "(Lnet/minecraft/client/gui/ScaledResolution;)V", false);
41+
super.visitMethodInsn(opcode, owner, name, desc, itf);
42+
}
43+
};
44+
} else if ("renderAttackIndicator".equals(name) || "func_184045_a".equals(mapSelfMethodName(name, desc))) {
45+
String selfClassName = unmapClassName(getClassName());
46+
// Redirect all drawTexturedModalRectWrapper to GuiIngameHelper.drawTexturedModalRectWrapper
47+
return new MethodVisitor(Opcodes.ASM5, super.visitMethod(access, name, desc, signature, exceptions)) {
48+
private int times = 0;
49+
@Override
50+
public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {
51+
if (opcode != Opcodes.INVOKEVIRTUAL) {
52+
super.visitMethodInsn(opcode, owner, name, desc, itf);
53+
return;
54+
}
55+
if (!selfClassName.equals(owner)) {
56+
super.visitMethodInsn(opcode, owner, name, desc, itf);
57+
return;
58+
}
59+
String mappedMethodName = mapSelfMethodName(name, desc);
60+
if (!"drawTexturedModalRectWrapper".equals(name) && !"func_73729_b".equals(mappedMethodName)) {
61+
super.visitMethodInsn(opcode, owner, name, desc, itf);
62+
return;
63+
}
64+
switch (times) {
65+
case 0:
66+
visitInsn(Opcodes.ICONST_0);
67+
break;
68+
case 1:
69+
visitInsn(Opcodes.ICONST_1);
70+
break;
71+
case 2:
72+
visitInsn(Opcodes.ICONST_2);
73+
break;
74+
case 3:
75+
visitInsn(Opcodes.ICONST_3);
76+
break;
77+
case 4:
78+
visitInsn(Opcodes.ICONST_4);
79+
break;
80+
case 5:
81+
visitInsn(Opcodes.ICONST_5);
82+
break;
83+
default:
84+
visitLdcInsn(times);
85+
break;
86+
}
87+
times++;
88+
super.visitMethodInsn(Opcodes.INVOKESTATIC, "top/fifthlight/touchcontroller/helper/GuiIngameHelper", "drawTexturedModalRectWrapper", "(Lnet/minecraft/client/gui/GuiIngame;IIIIIII)V", false);
89+
}
90+
};
91+
} else {
92+
return super.visitMethod(access, name, desc, signature, exceptions);
93+
}
94+
}
95+
}

0 commit comments

Comments
 (0)