Include FML handshake in recording
This commit is contained in:
@@ -5,6 +5,7 @@ import com.replaymod.core.utils.Restrictions;
|
|||||||
import com.replaymod.recording.handler.ConnectionEventHandler;
|
import com.replaymod.recording.handler.ConnectionEventHandler;
|
||||||
import com.replaymod.recording.packet.PacketListener;
|
import com.replaymod.recording.packet.PacketListener;
|
||||||
import net.minecraftforge.fml.common.FMLCommonHandler;
|
import net.minecraftforge.fml.common.FMLCommonHandler;
|
||||||
|
import net.minecraft.network.NetworkManager;
|
||||||
import net.minecraftforge.fml.common.Mod;
|
import net.minecraftforge.fml.common.Mod;
|
||||||
import net.minecraftforge.fml.common.event.FMLInitializationEvent;
|
import net.minecraftforge.fml.common.event.FMLInitializationEvent;
|
||||||
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
|
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
|
||||||
@@ -17,6 +18,9 @@ import org.lwjgl.input.Keyboard;
|
|||||||
public class ReplayModRecording {
|
public class ReplayModRecording {
|
||||||
public static final String MOD_ID = "replaymod-recording";
|
public static final String MOD_ID = "replaymod-recording";
|
||||||
|
|
||||||
|
@Mod.Instance(MOD_ID)
|
||||||
|
public static ReplayModRecording instance;
|
||||||
|
|
||||||
@Mod.Instance(ReplayMod.MOD_ID)
|
@Mod.Instance(ReplayMod.MOD_ID)
|
||||||
private static ReplayMod core;
|
private static ReplayMod core;
|
||||||
|
|
||||||
@@ -49,4 +53,8 @@ public class ReplayModRecording {
|
|||||||
|
|
||||||
NetworkRegistry.INSTANCE.newSimpleChannel(Restrictions.PLUGIN_CHANNEL);
|
NetworkRegistry.INSTANCE.newSimpleChannel(Restrictions.PLUGIN_CHANNEL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void initiateRecording(NetworkManager networkManager) {
|
||||||
|
connectionEventHandler.onConnectedToServerEvent(networkManager);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,14 +9,10 @@ import com.replaymod.replaystudio.replay.ReplayFile;
|
|||||||
import com.replaymod.replaystudio.replay.ReplayMetaData;
|
import com.replaymod.replaystudio.replay.ReplayMetaData;
|
||||||
import com.replaymod.replaystudio.replay.ZipReplayFile;
|
import com.replaymod.replaystudio.replay.ZipReplayFile;
|
||||||
import com.replaymod.replaystudio.studio.ReplayStudio;
|
import com.replaymod.replaystudio.studio.ReplayStudio;
|
||||||
import io.netty.channel.Channel;
|
|
||||||
import io.netty.channel.ChannelPipeline;
|
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.network.NetworkManager;
|
import net.minecraft.network.NetworkManager;
|
||||||
import net.minecraft.server.MinecraftServer;
|
|
||||||
import net.minecraft.world.WorldType;
|
import net.minecraft.world.WorldType;
|
||||||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||||
import net.minecraftforge.fml.common.network.FMLNetworkEvent.ClientConnectedToServerEvent;
|
|
||||||
import net.minecraftforge.fml.common.network.FMLNetworkEvent.ClientDisconnectionFromServerEvent;
|
import net.minecraftforge.fml.common.network.FMLNetworkEvent.ClientDisconnectionFromServerEvent;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
@@ -46,11 +42,11 @@ public class ConnectionEventHandler {
|
|||||||
this.core = core;
|
this.core = core;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
public void onConnectedToServerEvent(NetworkManager networkManager) {
|
||||||
public void onConnectedToServerEvent(ClientConnectedToServerEvent event) {
|
|
||||||
try {
|
try {
|
||||||
if(event.isLocal) {
|
boolean local = networkManager.isLocalChannel();
|
||||||
if (MinecraftServer.getServer().getEntityWorld().getWorldType() == WorldType.DEBUG_WORLD) {
|
if (local) {
|
||||||
|
if (mc.getIntegratedServer().getEntityWorld().getWorldType() == WorldType.DEBUG_WORLD) {
|
||||||
logger.info("Debug World recording is not supported.");
|
logger.info("Debug World recording is not supported.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -65,18 +61,15 @@ public class ConnectionEventHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NetworkManager nm = event.manager;
|
|
||||||
String worldName;
|
String worldName;
|
||||||
if(event.isLocal) {
|
if (local) {
|
||||||
worldName = MinecraftServer.getServer().getWorldName();
|
worldName = mc.getIntegratedServer().getWorldName();
|
||||||
} else if (Minecraft.getMinecraft().getCurrentServerData() != null) {
|
} else if (Minecraft.getMinecraft().getCurrentServerData() != null) {
|
||||||
worldName = Minecraft.getMinecraft().getCurrentServerData().serverIP;
|
worldName = Minecraft.getMinecraft().getCurrentServerData().serverIP;
|
||||||
} else {
|
} else {
|
||||||
logger.info("Recording not started as the world is neither local nor remote (probably a replay).");
|
logger.info("Recording not started as the world is neither local nor remote (probably a replay).");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Channel channel = nm.channel();
|
|
||||||
ChannelPipeline pipeline = channel.pipeline();
|
|
||||||
|
|
||||||
File folder = core.getReplayFolder();
|
File folder = core.getReplayFolder();
|
||||||
|
|
||||||
@@ -87,13 +80,13 @@ public class ConnectionEventHandler {
|
|||||||
replayFile.writeModInfo(ModCompat.getInstalledNetworkMods());
|
replayFile.writeModInfo(ModCompat.getInstalledNetworkMods());
|
||||||
|
|
||||||
ReplayMetaData metaData = new ReplayMetaData();
|
ReplayMetaData metaData = new ReplayMetaData();
|
||||||
metaData.setSingleplayer(event.isLocal);
|
metaData.setSingleplayer(local);
|
||||||
metaData.setServerName(worldName);
|
metaData.setServerName(worldName);
|
||||||
metaData.setGenerator("ReplayMod v" + ReplayMod.getContainer().getVersion());
|
metaData.setGenerator("ReplayMod v" + ReplayMod.getContainer().getVersion());
|
||||||
metaData.setDate(System.currentTimeMillis());
|
metaData.setDate(System.currentTimeMillis());
|
||||||
metaData.setMcVersion(ReplayMod.getMinecraftVersion());
|
metaData.setMcVersion(ReplayMod.getMinecraftVersion());
|
||||||
packetListener = new PacketListener(replayFile, metaData);
|
packetListener = new PacketListener(replayFile, metaData);
|
||||||
pipeline.addBefore(packetHandlerKey, "replay_recorder", packetListener);
|
networkManager.channel().pipeline().addBefore(packetHandlerKey, "replay_recorder", packetListener);
|
||||||
|
|
||||||
recordingEventHandler = new RecordingEventHandler(packetListener);
|
recordingEventHandler = new RecordingEventHandler(packetListener);
|
||||||
recordingEventHandler.register();
|
recordingEventHandler.register();
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package com.replaymod.recording.mixin;
|
||||||
|
|
||||||
|
import com.replaymod.recording.ReplayModRecording;
|
||||||
|
import net.minecraft.client.network.NetHandlerLoginClient;
|
||||||
|
import net.minecraft.network.NetworkManager;
|
||||||
|
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;
|
||||||
|
|
||||||
|
@Mixin(NetHandlerLoginClient.class)
|
||||||
|
public abstract class MixinNetHandlerLoginClient {
|
||||||
|
|
||||||
|
@Shadow
|
||||||
|
private NetworkManager networkManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts the recording right before switching into PLAY state.
|
||||||
|
* We cannot use the {@link net.minecraftforge.fml.common.network.FMLNetworkEvent.ClientConnectedToServerEvent}
|
||||||
|
* as it only fires after the forge handshake.
|
||||||
|
*/
|
||||||
|
@Inject(method = "handleLoginSuccess", at=@At("HEAD"))
|
||||||
|
public void replayModRecording_initiateRecording(CallbackInfo cb) {
|
||||||
|
ReplayModRecording.instance.initiateRecording(networkManager);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package com.replaymod.recording.mixin;
|
||||||
|
|
||||||
|
import io.netty.channel.embedded.EmbeddedChannel;
|
||||||
|
import net.minecraftforge.fml.common.network.handshake.NetworkDispatcher;
|
||||||
|
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;
|
||||||
|
|
||||||
|
@Mixin(value = NetworkDispatcher.class, remap = false)
|
||||||
|
public abstract class MixinNetworkDispatcher {
|
||||||
|
|
||||||
|
@Shadow
|
||||||
|
private EmbeddedChannel handshakeChannel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Always sets fml:isLocal to false.
|
||||||
|
* This effectively removes the difference in the FML handshake between SP and MP
|
||||||
|
* and forces the block/item ids, etc. to always be send.
|
||||||
|
* This might have undesired side effects but at least it works at all.
|
||||||
|
*/
|
||||||
|
@Inject(method = "insertIntoChannel", at=@At("HEAD"))
|
||||||
|
public void replayModRecording_forceIsLocalToFalse(CallbackInfo cb) {
|
||||||
|
handshakeChannel.attr(NetworkDispatcher.IS_LOCAL).set(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,7 +4,9 @@
|
|||||||
"mixins": [],
|
"mixins": [],
|
||||||
"server": [],
|
"server": [],
|
||||||
"client": [
|
"client": [
|
||||||
|
"MixinNetHandlerLoginClient",
|
||||||
"MixinNetHandlerPlayClient",
|
"MixinNetHandlerPlayClient",
|
||||||
|
"MixinNetworkDispatcher",
|
||||||
"MixinRenderGlobal"
|
"MixinRenderGlobal"
|
||||||
],
|
],
|
||||||
"refmap": "mixins.replaymod.refmap.json"
|
"refmap": "mixins.replaymod.refmap.json"
|
||||||
|
|||||||
Reference in New Issue
Block a user