events refactor + mixin testing

This commit is contained in:
MeexReay 2024-04-23 19:18:22 +03:00
parent e76c3dfccf
commit f38629a294
13 changed files with 300 additions and 139 deletions

View File

@ -15,10 +15,10 @@ import net.minecraft.util.math.Vec3d;
import org.lwjgl.glfw.GLFW;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import themixray.repeating.mod.event.RecordDelayEvent;
import themixray.repeating.mod.event.events.DelayEvent;
import themixray.repeating.mod.event.RecordEvent;
import themixray.repeating.mod.event.RecordInputEvent;
import themixray.repeating.mod.event.RecordMoveEvent;
import themixray.repeating.mod.event.events.InputEvent;
import themixray.repeating.mod.event.events.MoveEvent;
import themixray.repeating.mod.render.RenderHelper;
import themixray.repeating.mod.render.RenderSystem;
import themixray.repeating.mod.render.buffer.WorldBuffer;
@ -45,7 +45,7 @@ public class Main implements ClientModInitializer {
public TickTask replay_tick = null;
public boolean is_replaying = false;
public boolean loop_replay = false;
public static RecordInputEvent input_replay = null;
public static InputEvent input_replay = null;
public long living_ticks = 0;
@ -169,7 +169,7 @@ public class Main implements ClientModInitializer {
now_record = record_list.newRecord();
Vec3d start_pos = client.player.getPos();
now_record.addEvent(new RecordMoveEvent(start_pos,client.player.getHeadYaw(),client.player.getPitch()));
now_record.addEvent(new MoveEvent(start_pos,client.player.getHeadYaw(),client.player.getPitch()));
now_record.setStartRecordPos(start_pos);
if (record_pos_delay > 0) {
@ -178,7 +178,7 @@ public class Main implements ClientModInitializer {
record_pos_delay) {
@Override
public void run() {
now_record.addEvent(new RecordMoveEvent(client.player.getPos(),
now_record.addEvent(new MoveEvent(client.player.getPos(),
client.player.getHeadYaw(), client.player.getPitch()));
}
};
@ -192,7 +192,7 @@ public class Main implements ClientModInitializer {
long now = living_ticks;
if (last_record != -1) {
long diff = now - last_record - 2;
if (diff > 0) now_record.addEvent(new RecordDelayEvent(diff));
if (diff > 0) now_record.addEvent(new DelayEvent(diff));
}
now_record.addEvent(e);
last_record = now;
@ -205,9 +205,9 @@ public class Main implements ClientModInitializer {
return;
}
RecordInputEvent l = ((RecordInputEvent) now_record.getLastEvent("input"));
InputEvent l = ((InputEvent) now_record.getLastEvent("input"));
if (l == null) {
RecordInputEvent e = new RecordInputEvent(
InputEvent e = new InputEvent(
client.player.input.sneaking,
client.player.input.jumping,
client.player.input.movementSideways,
@ -224,7 +224,7 @@ public class Main implements ClientModInitializer {
client.player.getMovementSpeed());
recordTick(e);
} else {
RecordInputEvent e = new RecordInputEvent(
InputEvent e = new InputEvent(
((Boolean) client.player.input.sneaking == l.sneaking) ? null : client.player.input.sneaking,
((Boolean) client.player.input.jumping == l.jumping) ? null : client.player.input.jumping,
(((Float) client.player.input.movementSideways).equals(l.movementSideways)) ? null : client.player.input.movementSideways,
@ -280,8 +280,8 @@ public class Main implements ClientModInitializer {
public void run() {
if (!is_replaying) cancel();
RecordEvent e = events.get(replay_index);
if (e instanceof RecordDelayEvent) {
setDelay(((RecordDelayEvent) e).delay);
if (e instanceof DelayEvent) {
setDelay(((DelayEvent) e).delay);
} else {
e.replay();
}

View File

@ -101,7 +101,7 @@ public class RecordState {
public RecordEvent getLastEvent(String type) {
for (RecordEvent r: Lists.reverse(new ArrayList<>(events))) {
if (r.getType().equals(type)) {
if (r.getType().getName().equals(type)) {
return r;
}
}

View File

@ -1,28 +1,22 @@
package themixray.repeating.mod.event;
import themixray.repeating.mod.event.events.*;
public abstract class RecordEvent {
public abstract void replay();
public abstract String serialize();
public abstract String getType();
public static RecordEvent deserialize(String t) {
try {
String type = String.valueOf(t.charAt(0));
String[] args = t.substring(2).split("&");
if (type.equals("d")) {
return RecordDelayEvent.fromArgs(args);
} else if (type.equals("m")) {
return RecordMoveEvent.fromArgs(args);
} else if (type.equals("p")) {
return RecordInputEvent.fromArgs(args);
} else if (type.equals("b")) {
return RecordBlockBreakEvent.fromArgs(args);
} else if (type.equals("i")) {
return RecordBlockInteractEvent.fromArgs(args);
public RecordEventType getType() {
for (RecordEventType ev : RecordEventType.values()) {
if (ev.getEventClass().equals(this.getClass())) {
return ev;
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
protected abstract String[] serializeArgs();
public String serialize() {
return getType().getChar() + "=" + String.join("&", serializeArgs());
}
public static RecordEvent deserialize(String t) {
return RecordEventType.getByChar(t.charAt(0)).deserialize(t.substring(2).split("&"));
}
}

View File

@ -0,0 +1,71 @@
package themixray.repeating.mod.event;
import themixray.repeating.mod.event.events.*;
import java.lang.reflect.InvocationTargetException;
import java.util.function.Consumer;
public enum RecordEventType {
BLOCK_BREAK('b',"block_break",BlockBreakEvent.class),
BLOCK_INTERACT('i',"block_interact",BlockInteractEvent.class),
DELAY('d',"delay",DelayEvent.class),
INPUT('p',"input",InputEvent.class),
MOVE('m',"move",MoveEvent.class),
GUI_KEY_PRESS('r',"key_press",BlockBreakEvent.class),
GUI_KEY_RELEASE('s',"key_release",BlockBreakEvent.class),
GUI_CHAR_TYPE('h',"char_type",BlockBreakEvent.class),
GUI_MOUSE_CLICK('c',"mouse_click",BlockBreakEvent.class),
GUI_MOUSE_RELEASE('l',"mouse_release",BlockBreakEvent.class),
GUI_MOUSE_DRAG('g',"mouse_drag",BlockBreakEvent.class),
GUI_MOUSE_SCROLL('o',"mouse_scroll",BlockBreakEvent.class),
GUI_CLOSE('e',"close",BlockBreakEvent.class);
private Class<? extends RecordEvent> ev;
private char ch;
private String name;
RecordEventType(char ch, String name, Class<? extends RecordEvent> ev) {
this.ev = ev;
this.ch = ch;
this.name = name;
}
public Class<? extends RecordEvent> getEventClass() {
return ev;
}
public char getChar() {
return ch;
}
public String getName() {
return name;
}
public RecordEvent deserialize(String[] args) {
try {
return (RecordEvent) ev
.getMethod("deserialize", String[].class)
.invoke(null, (Object) args);
} catch (Throwable e) {
return null;
}
}
public String serialize(RecordEvent event) {
return event.serialize();
}
public static RecordEventType getByChar(String type) {
return getByChar(type.charAt(0));
}
public static RecordEventType getByChar(char ch) {
for (RecordEventType t : values()) {
if (t.getChar() == ch) {
return t;
}
}
return null;
}
}

View File

@ -1,32 +1,33 @@
package themixray.repeating.mod.event;
package themixray.repeating.mod.event.events;
import net.minecraft.util.math.BlockPos;
import themixray.repeating.mod.Main;
import themixray.repeating.mod.event.RecordEvent;
public class RecordBlockBreakEvent extends RecordEvent {
public class BlockBreakEvent extends RecordEvent {
public BlockPos pos;
public static RecordBlockBreakEvent fromArgs(String[] a) {
return new RecordBlockBreakEvent(new BlockPos(
public BlockBreakEvent(
BlockPos pos) {
this.pos = pos;
}
public static BlockBreakEvent deserialize(String[] a) {
return new BlockBreakEvent(new BlockPos(
Integer.parseInt(a[0]),
Integer.parseInt(a[1]),
Integer.parseInt(a[2])));
}
public RecordBlockBreakEvent(
BlockPos pos) {
this.pos = pos;
protected String[] serializeArgs() {
return new String[]{
String.valueOf(pos.getX()),
String.valueOf(pos.getY()),
String.valueOf(pos.getZ())
};
}
public void replay() {
Main.client.interactionManager.breakBlock(pos);
}
public String serialize() {
return "b=" + pos.getX() + "&" + pos.getY() + "&" + pos.getZ();
}
public String getType() {
return "block_break";
}
}

View File

@ -1,4 +1,4 @@
package themixray.repeating.mod.event;
package themixray.repeating.mod.event.events;
import net.minecraft.util.Hand;
import net.minecraft.util.hit.BlockHitResult;
@ -6,13 +6,14 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.util.math.Vec3d;
import themixray.repeating.mod.Main;
import themixray.repeating.mod.event.RecordEvent;
public class RecordBlockInteractEvent extends RecordEvent {
public class BlockInteractEvent extends RecordEvent {
public Hand hand;
public BlockHitResult hitResult;
public static RecordBlockInteractEvent fromArgs(String[] a) {
return new RecordBlockInteractEvent(
public static BlockInteractEvent deserialize(String[] a) {
return new BlockInteractEvent(
Hand.valueOf(a[5]),
new BlockHitResult(new Vec3d(
Double.parseDouble(a[0]),
@ -26,7 +27,7 @@ public class RecordBlockInteractEvent extends RecordEvent {
a[3].equals("1")));
}
public RecordBlockInteractEvent(Hand hand, BlockHitResult hitResult) {
public BlockInteractEvent(Hand hand, BlockHitResult hitResult) {
this.hand = hand;
this.hitResult = hitResult;
}
@ -35,12 +36,14 @@ public class RecordBlockInteractEvent extends RecordEvent {
Main.client.interactionManager.interactBlock(Main.client.player, hand, hitResult);
}
public String serialize() {
return "i=" + hitResult.getBlockPos().getX() + "&" + hitResult.getBlockPos().getY() + "&" + hitResult.getBlockPos().getZ() +
"&" + (hitResult.isInsideBlock() ? "1" : "0") + "&" + hitResult.getSide().getId() + "&" + hand.name();
}
public String getType() {
return "block_interact";
protected String[] serializeArgs() {
return new String[]{
String.valueOf(hitResult.getBlockPos().getX()),
String.valueOf(hitResult.getBlockPos().getY()),
String.valueOf(hitResult.getBlockPos().getZ()),
(hitResult.isInsideBlock() ? "1" : "0"),
String.valueOf(hitResult.getSide().getId()),
hand.name()
};
}
}

View File

@ -1,13 +1,15 @@
package themixray.repeating.mod.event;
package themixray.repeating.mod.event.events;
public class RecordDelayEvent extends RecordEvent {
import themixray.repeating.mod.event.RecordEvent;
public class DelayEvent extends RecordEvent {
public long delay;
public static RecordDelayEvent fromArgs(String[] a) {
return new RecordDelayEvent(Long.parseLong(a[0]));
public static DelayEvent deserialize(String[] a) {
return new DelayEvent(Long.parseLong(a[0]));
}
public RecordDelayEvent(long delay) {
public DelayEvent(long delay) {
this.delay = delay;
}
@ -19,11 +21,9 @@ public class RecordDelayEvent extends RecordEvent {
}
}
public String serialize() {
return "d=" + delay;
}
public String getType() {
return "delay";
protected String[] serializeArgs() {
return new String[]{
String.valueOf(delay)
};
}
}

View File

@ -1,8 +1,9 @@
package themixray.repeating.mod.event;
package themixray.repeating.mod.event.events;
import themixray.repeating.mod.Main;
import themixray.repeating.mod.event.RecordEvent;
public class RecordInputEvent extends RecordEvent {
public class InputEvent extends RecordEvent {
public Boolean sneaking;
public Boolean jumping;
public Boolean pressingForward;
@ -20,37 +21,20 @@ public class RecordInputEvent extends RecordEvent {
public float pitch;
public float speed;
public static RecordInputEvent fromArgs(String[] a) {
return new RecordInputEvent(
(a[0].equals("n") ? null : a[0].equals("1")),
(a[1].equals("n") ? null : a[1].equals("1")),
(a[2].equals("n") ? null : Float.parseFloat(a[2])),
(a[3].equals("n") ? null : Float.parseFloat(a[3])),
(a[4].equals("n") ? null : a[4].equals("1")),
(a[5].equals("n") ? null : a[5].equals("1")),
(a[6].equals("n") ? null : a[6].equals("1")),
(a[7].equals("n") ? null : a[7].equals("1")),
Float.parseFloat(a[8]), Float.parseFloat(a[9]),
Float.parseFloat(a[10]),
(a[11].equals("n") ? null : a[11].equals("1")),
Float.parseFloat(a[12]),
Float.parseFloat(a[13]));
}
public RecordInputEvent(Boolean sneaking,
Boolean jumping,
Float movementSideways,
Float movementForward,
Boolean pressingForward,
Boolean pressingBack,
Boolean pressingLeft,
Boolean pressingRight,
float head_yaw,
float body_yaw,
float head_pitch,
Boolean sprinting,
float yaw,
float speed) {
public InputEvent(Boolean sneaking,
Boolean jumping,
Float movementSideways,
Float movementForward,
Boolean pressingForward,
Boolean pressingBack,
Boolean pressingLeft,
Boolean pressingRight,
float head_yaw,
float body_yaw,
float head_pitch,
Boolean sprinting,
float yaw,
float speed) {
this.sneaking = sneaking;
this.jumping = jumping;
this.movementSideways = movementSideways;
@ -67,7 +51,43 @@ public class RecordInputEvent extends RecordEvent {
this.speed = speed;
}
public void fillEmpty(RecordInputEvent e) {
public static InputEvent deserialize(String[] a) {
return new InputEvent(
(a[0].equals("n") ? null : a[0].equals("1")),
(a[1].equals("n") ? null : a[1].equals("1")),
(a[2].equals("n") ? null : Float.parseFloat(a[2])),
(a[3].equals("n") ? null : Float.parseFloat(a[3])),
(a[4].equals("n") ? null : a[4].equals("1")),
(a[5].equals("n") ? null : a[5].equals("1")),
(a[6].equals("n") ? null : a[6].equals("1")),
(a[7].equals("n") ? null : a[7].equals("1")),
Float.parseFloat(a[8]), Float.parseFloat(a[9]),
Float.parseFloat(a[10]),
(a[11].equals("n") ? null : a[11].equals("1")),
Float.parseFloat(a[12]),
Float.parseFloat(a[13]));
}
protected String[] serializeArgs() {
return new String[] {
((sneaking == null) ? "n" : (sneaking ? "1" : "0")), // sneaking
((jumping == null) ? "n" : (jumping ? "1" : "0")), // jumping
((movementSideways == null) ? "n" : String.valueOf(movementSideways)), // movement sideways
((movementForward == null) ? "n" : String.valueOf(movementForward)), // movement forward
((pressingForward == null) ? "n" : (pressingForward ? "1" : "0")), // pressing forward
((pressingBack == null) ? "n" : (pressingBack ? "1" : "0")), // pressing back
((pressingLeft == null) ? "n" : (pressingLeft ? "1" : "0")), // pressing left
((pressingRight == null) ? "n" : (pressingRight ? "1" : "0")), // pressing right
String.valueOf(head_yaw), // head yaw
String.valueOf(body_yaw), // body yaw
String.valueOf(pitch), // pitch
((sprinting == null) ? "n" : (sprinting ? "1" : "0")), // sprinting
String.valueOf(yaw), // yaw
String.valueOf(speed) // speed
};
}
public void fillEmpty(InputEvent e) {
if (sneaking == null) sneaking = e.sneaking;
if (jumping == null) jumping = e.jumping;
if (movementSideways == null) movementSideways = e.movementSideways;
@ -125,23 +145,4 @@ public class RecordInputEvent extends RecordEvent {
if (pressingRight != null && Main.client.player.input.pressingRight != pressingRight)
Main.client.player.input.pressingRight = pressingRight;
}
public String serialize() {
return "p=" +
((sneaking == null) ? "n" : (sneaking ? "1" : "0")) + "&" +
((jumping == null) ? "n" : (jumping ? "1" : "0")) + "&" +
((movementSideways == null) ? "n" : movementSideways) + "&" +
((movementForward == null) ? "n" : movementForward) + "&" +
((pressingForward == null) ? "n" : (pressingForward ? "1" : "0")) + "&" +
((pressingBack == null) ? "n" : (pressingBack ? "1" : "0")) + "&" +
((pressingLeft == null) ? "n" : (pressingLeft ? "1" : "0")) + "&" +
((pressingRight == null) ? "n" : (pressingRight ? "1" : "0")) + "&" +
head_yaw + "&" + body_yaw + "&" + pitch + "&" +
((sprinting == null) ? "n" : (sprinting ? "1" : "0") +
"&" + yaw + "&" + speed);
}
public String getType() {
return "input";
}
}

View File

@ -1,16 +1,17 @@
package themixray.repeating.mod.event;
package themixray.repeating.mod.event.events;
import net.minecraft.entity.MovementType;
import net.minecraft.util.math.Vec3d;
import themixray.repeating.mod.Main;
import themixray.repeating.mod.event.RecordEvent;
public class RecordMoveEvent extends RecordEvent {
public class MoveEvent extends RecordEvent {
public Vec3d vec;
public float yaw;
public float pitch;
public static RecordMoveEvent fromArgs(String[] a) {
return new RecordMoveEvent(new Vec3d(
public static MoveEvent deserialize(String[] a) {
return new MoveEvent(new Vec3d(
Double.parseDouble(a[0]),
Double.parseDouble(a[1]),
Double.parseDouble(a[2])),
@ -18,7 +19,7 @@ public class RecordMoveEvent extends RecordEvent {
Float.parseFloat(a[4]));
}
public RecordMoveEvent(Vec3d vec, float yaw, float pitch) {
public MoveEvent(Vec3d vec, float yaw, float pitch) {
this.vec = vec;
this.yaw = yaw;
this.pitch = pitch;
@ -32,11 +33,12 @@ public class RecordMoveEvent extends RecordEvent {
Main.client.player.setPitch(pitch);
}
public String serialize() {
return "m=" + vec.getX() + "&" + vec.getY() + "&" + vec.getZ() + "&" + yaw + "&" + pitch;
}
public String getType() {
return "move";
protected String[] serializeArgs() {
return new String[]{
String.valueOf(vec.getX()),
String.valueOf(vec.getZ()),
String.valueOf(yaw),
String.valueOf(pitch)
};
}
}

View File

@ -10,8 +10,8 @@ import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import themixray.repeating.mod.Main;
import themixray.repeating.mod.event.RecordBlockBreakEvent;
import themixray.repeating.mod.event.RecordBlockInteractEvent;
import themixray.repeating.mod.event.events.BlockBreakEvent;
import themixray.repeating.mod.event.events.BlockInteractEvent;
import themixray.repeating.mod.TickTask;
@Mixin(ClientPlayerEntity.class)
@ -21,13 +21,13 @@ public abstract class MovementMixin {
private void init(CallbackInfo ci) {
PlayerBlockBreakEvents.AFTER.register((world, player, pos, blockState, blockEntity) -> {
if (Main.me.is_recording)
Main.me.recordTick(new RecordBlockBreakEvent(pos));
Main.me.recordTick(new BlockBreakEvent(pos));
});
UseBlockCallback.EVENT.register((player, world, hand, hitResult) -> {
if (hitResult.getType().equals(HitResult.Type.BLOCK))
if (Main.me.is_recording)
Main.me.recordTick(new RecordBlockInteractEvent(hand,hitResult));
Main.me.recordTick(new BlockInteractEvent(hand,hitResult));
return ActionResult.PASS;
});
}

View File

@ -0,0 +1,23 @@
package themixray.repeating.mod.mixin;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientEntityEvents;
import net.minecraft.client.network.ClientPlayerEntity;
import net.minecraft.entity.Entity;
import net.minecraft.network.ClientConnection;
import net.minecraft.text.Text;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import themixray.repeating.mod.Main;
import java.util.UUID;
@Mixin(ClientConnection.class)
public abstract class PlayerMixin {
@Inject(at = @At(value = "HEAD"), method = "disconnect")
private void disconnect(Text disconnectReason, CallbackInfo ci) {
System.out.println("on client close");
}
}

View File

@ -0,0 +1,64 @@
package themixray.repeating.mod.mixin;
import net.minecraft.client.gui.AbstractParentElement;
import net.minecraft.client.gui.Drawable;
import net.minecraft.client.gui.Element;
import net.minecraft.client.gui.ParentElement;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.render.GameRenderer;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import themixray.repeating.mod.TickTask;
@Mixin(Screen.class)
public abstract class ScreenMixin extends AbstractParentElement implements Drawable {
@Inject(at = @At(value = "HEAD"), method = "close")
private void close(CallbackInfo ci) {
System.out.println("on screen close");
}
@Inject(at = @At(value = "HEAD"), method = "keyPressed")
private void keyPressed(int keyCode, int scanCode, int modifiers, CallbackInfoReturnable<Boolean> cir) {
System.out.println("on screen keyPressed");
}
@Override
public boolean charTyped(char chr, int modifiers) {
System.out.println("on screen charTyped");
return super.charTyped(chr, modifiers);
}
@Override
public boolean keyReleased(int keyCode, int scanCode, int modifiers) {
System.out.println("on screen keyReleased");
return super.keyReleased(keyCode, scanCode, modifiers);
}
@Override
public boolean mouseClicked(double mouseX, double mouseY, int button) {
System.out.println("on screen mouseClicked");
return super.mouseClicked(mouseX, mouseY, button);
}
@Override
public boolean mouseDragged(double mouseX, double mouseY, int button, double deltaX, double deltaY) {
System.out.println("on screen mouseDragged");
return super.mouseDragged(mouseX, mouseY, button, deltaX, deltaY);
}
@Override
public boolean mouseReleased(double mouseX, double mouseY, int button) {
System.out.println("on screen mouseReleased");
return super.mouseReleased(mouseX, mouseY, button);
}
@Override
public boolean mouseScrolled(double mouseX, double mouseY, double amount) {
System.out.println("on screen mouseScrolled");
return super.mouseScrolled(mouseX, mouseY, amount);
}
}

View File

@ -10,7 +10,9 @@
"InputMixin",
"RendererMixin",
"EntityMixin",
"ClientMixin"
"ClientMixin",
"ScreenMixin",
"PlayerMixin"
],
"injectors": {
"defaultRequire": 1