Skip to content

Commit

Permalink
[Savestates] Start rewriting player motion
Browse files Browse the repository at this point in the history
  • Loading branch information
ScribbleTAS committed Dec 12, 2024
1 parent 460a04d commit 7d6fe51
Show file tree
Hide file tree
Showing 5 changed files with 264 additions and 197 deletions.
1 change: 1 addition & 0 deletions src/main/java/com/minecrafttas/tasmod/TASmod.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import com.minecrafttas.tasmod.playback.metadata.integrated.StartpositionMetadataExtension;
import com.minecrafttas.tasmod.registries.TASmodPackets;
import com.minecrafttas.tasmod.savestates.SavestateHandlerServer;
import com.minecrafttas.tasmod.savestates.storage.SavestateMotionStorage;
import com.minecrafttas.tasmod.tickratechanger.TickrateChangerServer;
import com.minecrafttas.tasmod.ticksync.TickSyncServer;
import com.minecrafttas.tasmod.util.LoggerMarkers;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,61 +10,61 @@
import com.minecrafttas.mctcommon.networking.ByteBufferBuilder;
import com.minecrafttas.mctcommon.networking.interfaces.PacketID;
import com.minecrafttas.tasmod.playback.PlaybackControllerClient.TASstate;
import com.minecrafttas.tasmod.savestates.handlers.SavestatePlayerHandler.MotionData;
import com.minecrafttas.tasmod.savestates.storage.SavestateMotionStorage.MotionData;
import com.minecrafttas.tasmod.tickratechanger.TickrateChangerServer.TickratePauseState;

import net.minecraft.nbt.CompressedStreamTools;
import net.minecraft.nbt.NBTSizeTracker;
import net.minecraft.nbt.NBTTagCompound;

public class TASmodBufferBuilder extends ByteBufferBuilder{
public class TASmodBufferBuilder extends ByteBufferBuilder {

public TASmodBufferBuilder(int id) {
super(id);
}

public TASmodBufferBuilder(PacketID packet) {
super(packet);
}

public TASmodBufferBuilder(ByteBuffer buf) {
super(buf);
}

public TASmodBufferBuilder writeTASState(TASstate state) {
this.writeShort((short)state.ordinal());
this.writeShort((short) state.ordinal());
return this;
}

public TASmodBufferBuilder writeNBTTagCompound(NBTTagCompound compound) {

ByteArrayOutputStream out = new ByteArrayOutputStream();

DataOutputStream dataout = new DataOutputStream(out);

try {
CompressedStreamTools.write(compound, dataout);
} catch (IOException e) {
e.printStackTrace();
}

this.writeByteArray(out.toByteArray());

try {
out.close();
dataout.close();
} catch (IOException e) {
e.printStackTrace();
}

return this;
}

public TASmodBufferBuilder writeTickratePauseState(TickratePauseState state) {
writeShort((short) state.ordinal());
return this;
}

public TASmodBufferBuilder writeMotionData(MotionData data) {
writeDouble(data.getClientX());
writeDouble(data.getClientY());
Expand All @@ -76,28 +76,28 @@ public TASmodBufferBuilder writeMotionData(MotionData data) {
writeBoolean(data.isSprinting());
return this;
}

public static TASstate readTASState(ByteBuffer buf) {
return TASstate.values()[buf.getShort()];
}

public static NBTTagCompound readNBTTagCompound(ByteBuffer buf) throws IOException {
ByteArrayInputStream input = new ByteArrayInputStream(readByteArray(buf));

DataInputStream datain = new DataInputStream(input);

NBTTagCompound compound = CompressedStreamTools.read(datain, NBTSizeTracker.INFINITE);

input.close();
datain.close();

return compound;
}

public static TickratePauseState readTickratePauseState(ByteBuffer buf) {
return TickratePauseState.values()[buf.getShort()];
}

public static MotionData readMotionData(ByteBuffer buf) {
double x = TASmodBufferBuilder.readDouble(buf);
double y = TASmodBufferBuilder.readDouble(buf);
Expand All @@ -107,8 +107,8 @@ public static MotionData readMotionData(ByteBuffer buf) {
float rz = TASmodBufferBuilder.readFloat(buf);
float jumpMovementVector = TASmodBufferBuilder.readFloat(buf);
boolean sprinting = TASmodBufferBuilder.readBoolean(buf);

return new MotionData(x, y, z, rx, ry, rz, sprinting, jumpMovementVector);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import com.minecrafttas.tasmod.playback.PlaybackControllerClient.TASstate;
import com.minecrafttas.tasmod.playback.filecommands.PlaybackFileCommand.PlaybackFileCommandExtension;
import com.minecrafttas.tasmod.playback.tasfile.flavor.SerialiserFlavorBase;
import com.minecrafttas.tasmod.savestates.handlers.SavestatePlayerHandler.MotionData;
import com.minecrafttas.tasmod.savestates.storage.SavestateMotionStorage.MotionData;
import com.minecrafttas.tasmod.tickratechanger.TickrateChangerServer.TickratePauseState;
import com.minecrafttas.tasmod.util.Ducks.ScoreboardDuck;

Expand Down Expand Up @@ -83,6 +83,13 @@ public enum TASmodPackets implements PacketID {
* <strong>Client->Server</strong> {@link MotionData} motionData An Object containing all necessary motion data<br>
*/
SAVESTATE_REQUEST_MOTION,
/**
* <p>Used for setting the client motion data after it was loaded from a savestate
* <p>Side: Client<br>
* ARGS: <br>
* <strong>Server->Client</strong> {@link MotionData} motionData An Object containing all necessary motion data<br>
*/
SAVESTATE_SET_MOTION,
/**
* <p>Unloads the chunks on the client side
* <p>SIDE: Client<br>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,11 @@

import static com.minecrafttas.tasmod.TASmod.LOGGER;
import static com.minecrafttas.tasmod.registries.TASmodPackets.SAVESTATE_PLAYER;
import static com.minecrafttas.tasmod.registries.TASmodPackets.SAVESTATE_REQUEST_MOTION;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import com.minecrafttas.mctcommon.networking.Client.Side;
import com.minecrafttas.mctcommon.networking.exception.PacketNotImplementedException;
Expand All @@ -22,19 +15,14 @@
import com.minecrafttas.mctcommon.networking.interfaces.PacketID;
import com.minecrafttas.mctcommon.networking.interfaces.ServerPacketHandler;
import com.minecrafttas.tasmod.TASmod;
import com.minecrafttas.tasmod.TASmodClient;
import com.minecrafttas.tasmod.events.EventNBT;
import com.minecrafttas.tasmod.networking.TASmodBufferBuilder;
import com.minecrafttas.tasmod.registries.TASmodPackets;
import com.minecrafttas.tasmod.savestates.SavestateHandlerClient;
import com.minecrafttas.tasmod.savestates.exceptions.SavestateException;
import com.minecrafttas.tasmod.savestates.gui.GuiSavestateSavingScreen;
import com.minecrafttas.tasmod.util.LoggerMarkers;

import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.nbt.NBTTagCompound;
Expand All @@ -48,18 +36,12 @@
/**
* Handles player related savestating methods
*/
public class SavestatePlayerHandler implements ClientPacketHandler, ServerPacketHandler, EventNBT.EventPlayerRead, EventNBT.EventPlayerWrite {
public class SavestatePlayerHandler implements ClientPacketHandler, ServerPacketHandler {

private final MinecraftServer server;

private final Map<EntityPlayerMP, CompletableFuture<MotionData>> futures;

private final Map<EntityPlayerMP, MotionData> motionData;

public SavestatePlayerHandler(MinecraftServer server) {
this.server = server;
this.futures = new HashMap<>();
this.motionData = new HashMap<>();
}

/**
Expand Down Expand Up @@ -195,39 +177,10 @@ public void clearScoreboard() {
}
}

public void requestMotionFromClient() {
LOGGER.trace(LoggerMarkers.Savestate, "Request motion from client");

this.futures.clear();

List<EntityPlayerMP> playerList = server.getPlayerList().getPlayers();
playerList.forEach(player -> {
futures.put(player, new CompletableFuture<>());
});

try {
// request client motion
TASmod.server.sendToAll(new TASmodBufferBuilder(SAVESTATE_REQUEST_MOTION));
} catch (Exception e) {
e.printStackTrace();
}

futures.forEach((player, future) -> {
try {
this.motionData.put(player, future.get(5, TimeUnit.SECONDS));
} catch (TimeoutException e) {
throw new SavestateException(e, "Writing client motion for %s timed out!", player.getName());
} catch (ExecutionException | InterruptedException e) {
throw new SavestateException(e, "Writing client motion for %s", player.getName());
}
});
}

@Override
public PacketID[] getAcceptedPacketIDs() {
return new PacketID[] {
//@formatter:off
SAVESTATE_REQUEST_MOTION,
SAVESTATE_PLAYER
//@formatter:on
};
Expand All @@ -239,11 +192,6 @@ public void onServerPacket(PacketID id, ByteBuffer buf, String username) throws
EntityPlayerMP player = TASmod.getServerInstance().getPlayerList().getPlayerByUsername(username);

switch (packet) {
case SAVESTATE_REQUEST_MOTION:
MotionData data = TASmodBufferBuilder.readMotionData(buf);
CompletableFuture<MotionData> future = this.futures.get(player);
future.complete(data);
break;
case SAVESTATE_PLAYER:
throw new WrongSideException(packet, Side.SERVER);
default:
Expand Down Expand Up @@ -275,126 +223,8 @@ public void onClientPacket(PacketID id, ByteBuffer buf, String username) throws
});
break;

case SAVESTATE_REQUEST_MOTION:
EntityPlayerSP player = Minecraft.getMinecraft().player;
if (player != null) {
if (!(Minecraft.getMinecraft().currentScreen instanceof GuiSavestateSavingScreen)) {
Minecraft.getMinecraft().displayGuiScreen(new GuiSavestateSavingScreen());
}
//@formatter:off
MotionData motionData = new MotionData(
player.motionX,
player.motionY,
player.motionZ,
player.moveForward,
player.moveVertical,
player.moveStrafing,
player.isSprinting(),
player.jumpMovementFactor
);
//@formatter:on
TASmodClient.client.send(new TASmodBufferBuilder(TASmodPackets.SAVESTATE_REQUEST_MOTION).writeMotionData(motionData));
}
break;

default:
break;
}
}

public static class MotionData {

private double clientX;
private double clientY;
private double clientZ;
private float clientrX;
private float clientrY;
private float clientrZ;
private boolean sprinting;
private float jumpMovementVector;

public MotionData(double x, double y, double z, float rx, float ry, float rz, boolean sprinting, float jumpMovementVector) {
clientX = x;
clientY = y;
clientZ = z;
clientrX = rx;
clientrY = ry;
clientrZ = rz;
this.sprinting = sprinting;
this.jumpMovementVector = jumpMovementVector;
}

public MotionData() {
this(0D, 0D, 0D, 0f, 0f, 0f, false, 0f);
}

public double getClientX() {
return clientX;
}

public double getClientY() {
return clientY;
}

public double getClientZ() {
return clientZ;
}

public float getClientrX() {
return clientrX;
}

public float getClientrY() {
return clientrY;
}

public float getClientrZ() {
return clientrZ;
}

public boolean isSprinting() {
return sprinting;
}

public float getJumpMovementVector() {
return jumpMovementVector;
}
}

@Override
public void onPlayerWriteNBT(NBTTagCompound compound, EntityPlayerMP player) {
NBTTagCompound nbttagcompound = new NBTTagCompound();

MotionData saver = new MotionData();
if (motionData.containsKey(player)) {
saver = motionData.get(player);
}

nbttagcompound.setDouble("x", saver.getClientX());
nbttagcompound.setDouble("y", saver.getClientY());
nbttagcompound.setDouble("z", saver.getClientZ());
nbttagcompound.setFloat("RelativeX", saver.getClientrX());
nbttagcompound.setFloat("RelativeY", saver.getClientrY());
nbttagcompound.setFloat("RelativeZ", saver.getClientrZ());
nbttagcompound.setBoolean("Sprinting", saver.isSprinting());
nbttagcompound.setFloat("JumpFactor", saver.getJumpMovementVector());
compound.setTag("clientMotion", nbttagcompound);
}

@Override
public void onPlayerReadNBT(NBTTagCompound compound, EntityPlayerMP player) {
NBTTagCompound nbttagcompound = compound.getCompoundTag("clientMotion");

double clientmotionX = nbttagcompound.getDouble("x");
double clientmotionY = nbttagcompound.getDouble("y");
double clientmotionZ = nbttagcompound.getDouble("z");
float clientmotionrX = nbttagcompound.getFloat("RelativeX");
float clientmotionrY = nbttagcompound.getFloat("RelativeY");
float clientmotionrZ = nbttagcompound.getFloat("RelativeZ");
boolean sprinting = nbttagcompound.getBoolean("Sprinting");
float jumpVector = nbttagcompound.getFloat("JumpFactor");

MotionData motion = new MotionData(clientmotionX, clientmotionY, clientmotionZ, clientmotionrX, clientmotionrY, clientmotionrZ, sprinting, jumpVector);
motionData.put(player, motion);
}
}
Loading

0 comments on commit 7d6fe51

Please sign in to comment.