Add basic replay restriction system (no restrictions yet)
This commit is contained in:
@@ -8,8 +8,6 @@ import eu.crushedpixel.replaymod.gui.online.GuiReplayCenter;
|
|||||||
import eu.crushedpixel.replaymod.gui.replayeditor.GuiReplayEditor;
|
import eu.crushedpixel.replaymod.gui.replayeditor.GuiReplayEditor;
|
||||||
import eu.crushedpixel.replaymod.gui.replayviewer.GuiReplayViewer;
|
import eu.crushedpixel.replaymod.gui.replayviewer.GuiReplayViewer;
|
||||||
import eu.crushedpixel.replaymod.online.authentication.AuthenticationHandler;
|
import eu.crushedpixel.replaymod.online.authentication.AuthenticationHandler;
|
||||||
import eu.crushedpixel.replaymod.registry.LightingHandler;
|
|
||||||
import eu.crushedpixel.replaymod.registry.ReplayGuiRegistry;
|
|
||||||
import eu.crushedpixel.replaymod.replay.ReplayHandler;
|
import eu.crushedpixel.replaymod.replay.ReplayHandler;
|
||||||
import eu.crushedpixel.replaymod.replay.ReplayProcess;
|
import eu.crushedpixel.replaymod.replay.ReplayProcess;
|
||||||
import eu.crushedpixel.replaymod.studio.VersionValidator;
|
import eu.crushedpixel.replaymod.studio.VersionValidator;
|
||||||
@@ -193,16 +191,8 @@ public class GuiEventHandler {
|
|||||||
|
|
||||||
event.button.enabled = false;
|
event.button.enabled = false;
|
||||||
|
|
||||||
LightingHandler.setLighting(false);
|
|
||||||
|
|
||||||
ReplayHandler.lastExit = System.currentTimeMillis();
|
|
||||||
|
|
||||||
mc.theWorld.sendQuittingDisconnectingPacket();
|
|
||||||
mc.loadWorld(null);
|
|
||||||
mc.displayGuiScreen(new GuiMainMenu());
|
mc.displayGuiScreen(new GuiMainMenu());
|
||||||
|
|
||||||
ReplayGuiRegistry.show();
|
|
||||||
|
|
||||||
ReplayHandler.endReplay();
|
ReplayHandler.endReplay();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import eu.crushedpixel.replaymod.chat.ChatMessageHandler;
|
|||||||
import eu.crushedpixel.replaymod.holders.AdvancedPosition;
|
import eu.crushedpixel.replaymod.holders.AdvancedPosition;
|
||||||
import eu.crushedpixel.replaymod.holders.Keyframe;
|
import eu.crushedpixel.replaymod.holders.Keyframe;
|
||||||
import eu.crushedpixel.replaymod.holders.Marker;
|
import eu.crushedpixel.replaymod.holders.Marker;
|
||||||
|
import eu.crushedpixel.replaymod.replay.Restrictions;
|
||||||
import eu.crushedpixel.replaymod.utils.ReplayFileIO;
|
import eu.crushedpixel.replaymod.utils.ReplayFileIO;
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
@@ -25,10 +26,8 @@ import net.minecraft.entity.DataWatcher;
|
|||||||
import net.minecraft.network.NetworkManager;
|
import net.minecraft.network.NetworkManager;
|
||||||
import net.minecraft.network.Packet;
|
import net.minecraft.network.Packet;
|
||||||
import net.minecraft.network.play.client.C19PacketResourcePackStatus;
|
import net.minecraft.network.play.client.C19PacketResourcePackStatus;
|
||||||
import net.minecraft.network.play.server.S0CPacketSpawnPlayer;
|
import net.minecraft.network.play.server.*;
|
||||||
import net.minecraft.network.play.server.S0DPacketCollectItem;
|
import net.minecraft.util.ChatComponentText;
|
||||||
import net.minecraft.network.play.server.S0FPacketSpawnMob;
|
|
||||||
import net.minecraft.network.play.server.S48PacketResourcePackSend;
|
|
||||||
import net.minecraft.util.HttpUtil;
|
import net.minecraft.util.HttpUtil;
|
||||||
import org.apache.commons.io.FileUtils;
|
import org.apache.commons.io.FileUtils;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
@@ -106,6 +105,14 @@ public class PacketListener extends DataListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dataWriter.writePacket(getPacketData(packet));
|
dataWriter.writePacket(getPacketData(packet));
|
||||||
|
|
||||||
|
if (packet instanceof S3FPacketCustomPayload) {
|
||||||
|
S3FPacketCustomPayload p = (S3FPacketCustomPayload) packet;
|
||||||
|
if (Restrictions.PLUGIN_CHANNEL.equals(p.getChannelName())) {
|
||||||
|
packet = new S40PacketDisconnect(new ChatComponentText("Please update to view this replay."));
|
||||||
|
dataWriter.writePacket(getPacketData(packet));
|
||||||
|
}
|
||||||
|
}
|
||||||
} catch(Exception e) {
|
} catch(Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,9 @@ import eu.crushedpixel.replaymod.events.ReplayExitEvent;
|
|||||||
import eu.crushedpixel.replaymod.gui.overlay.GuiReplayOverlay;
|
import eu.crushedpixel.replaymod.gui.overlay.GuiReplayOverlay;
|
||||||
import eu.crushedpixel.replaymod.holders.*;
|
import eu.crushedpixel.replaymod.holders.*;
|
||||||
import eu.crushedpixel.replaymod.interpolation.KeyframeList;
|
import eu.crushedpixel.replaymod.interpolation.KeyframeList;
|
||||||
|
import eu.crushedpixel.replaymod.registry.LightingHandler;
|
||||||
import eu.crushedpixel.replaymod.registry.PlayerHandler;
|
import eu.crushedpixel.replaymod.registry.PlayerHandler;
|
||||||
|
import eu.crushedpixel.replaymod.registry.ReplayGuiRegistry;
|
||||||
import eu.crushedpixel.replaymod.settings.RenderOptions;
|
import eu.crushedpixel.replaymod.settings.RenderOptions;
|
||||||
import eu.crushedpixel.replaymod.utils.ReplayFile;
|
import eu.crushedpixel.replaymod.utils.ReplayFile;
|
||||||
import eu.crushedpixel.replaymod.utils.ReplayFileIO;
|
import eu.crushedpixel.replaymod.utils.ReplayFileIO;
|
||||||
@@ -74,6 +76,11 @@ public class ReplayHandler {
|
|||||||
*/
|
*/
|
||||||
private static ReplayFile currentReplayFile;
|
private static ReplayFile currentReplayFile;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Currently active replay restrictions.
|
||||||
|
*/
|
||||||
|
private static Restrictions restrictions;
|
||||||
|
|
||||||
public static KeyframeSet[] getKeyframeRepository() {
|
public static KeyframeSet[] getKeyframeRepository() {
|
||||||
return keyframeRepository;
|
return keyframeRepository;
|
||||||
}
|
}
|
||||||
@@ -335,6 +342,8 @@ public class ReplayHandler {
|
|||||||
|
|
||||||
setCameraTilt(0);
|
setCameraTilt(0);
|
||||||
|
|
||||||
|
restrictions = new Restrictions();
|
||||||
|
|
||||||
networkManager = new NetworkManager(EnumPacketDirection.CLIENTBOUND) {
|
networkManager = new NetworkManager(EnumPacketDirection.CLIENTBOUND) {
|
||||||
@Override
|
@Override
|
||||||
public void exceptionCaught(ChannelHandlerContext ctx, Throwable t) {
|
public void exceptionCaught(ChannelHandlerContext ctx, Throwable t) {
|
||||||
@@ -399,6 +408,8 @@ public class ReplayHandler {
|
|||||||
channel.close();
|
channel.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
restrictions = new Restrictions();
|
||||||
|
|
||||||
networkManager = new NetworkManager(EnumPacketDirection.CLIENTBOUND) {
|
networkManager = new NetworkManager(EnumPacketDirection.CLIENTBOUND) {
|
||||||
@Override
|
@Override
|
||||||
public void exceptionCaught(ChannelHandlerContext ctx, Throwable t) {
|
public void exceptionCaught(ChannelHandlerContext ctx, Throwable t) {
|
||||||
@@ -459,8 +470,16 @@ public class ReplayHandler {
|
|||||||
resetKeyframes(true);
|
resetKeyframes(true);
|
||||||
|
|
||||||
PlayerHandler.resetHiddenPlayers();
|
PlayerHandler.resetHiddenPlayers();
|
||||||
|
ReplayGuiRegistry.show();
|
||||||
|
LightingHandler.setLighting(false);
|
||||||
|
|
||||||
|
if (mc.theWorld != null) {
|
||||||
|
mc.theWorld.sendQuittingDisconnectingPacket();
|
||||||
|
mc.loadWorld(null);
|
||||||
|
}
|
||||||
|
|
||||||
inReplay = false;
|
inReplay = false;
|
||||||
|
lastExit = System.currentTimeMillis();
|
||||||
|
|
||||||
FMLCommonHandler.instance().bus().post(new ReplayExitEvent());
|
FMLCommonHandler.instance().bus().post(new ReplayExitEvent());
|
||||||
}
|
}
|
||||||
@@ -553,4 +572,8 @@ public class ReplayHandler {
|
|||||||
positionKeyframes.recalculate(ReplayMod.replaySettings.isLinearMovement());
|
positionKeyframes.recalculate(ReplayMod.replaySettings.isLinearMovement());
|
||||||
timeKeyframes.recalculate(ReplayMod.replaySettings.isLinearMovement());
|
timeKeyframes.recalculate(ReplayMod.replaySettings.isLinearMovement());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Restrictions getRestrictions() {
|
||||||
|
return restrictions;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,11 +14,14 @@ import io.netty.channel.ChannelHandlerContext;
|
|||||||
import io.netty.channel.ChannelInboundHandlerAdapter;
|
import io.netty.channel.ChannelInboundHandlerAdapter;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.client.gui.GuiDownloadTerrain;
|
import net.minecraft.client.gui.GuiDownloadTerrain;
|
||||||
|
import net.minecraft.client.gui.GuiErrorScreen;
|
||||||
|
import net.minecraft.client.resources.I18n;
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.network.EnumConnectionState;
|
import net.minecraft.network.EnumConnectionState;
|
||||||
import net.minecraft.network.NetworkManager;
|
import net.minecraft.network.NetworkManager;
|
||||||
import net.minecraft.network.Packet;
|
import net.minecraft.network.Packet;
|
||||||
import net.minecraft.network.play.server.*;
|
import net.minecraft.network.play.server.*;
|
||||||
|
import net.minecraft.util.IChatComponent;
|
||||||
import net.minecraft.world.EnumDifficulty;
|
import net.minecraft.world.EnumDifficulty;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
import net.minecraft.world.WorldSettings.GameType;
|
import net.minecraft.world.WorldSettings.GameType;
|
||||||
@@ -290,6 +293,38 @@ public class ReplaySender extends ChannelInboundHandlerAdapter {
|
|||||||
* @return The processed packet or {@code null} if no packet shall be sent
|
* @return The processed packet or {@code null} if no packet shall be sent
|
||||||
*/
|
*/
|
||||||
protected Packet processPacket(Packet p) throws Exception {
|
protected Packet processPacket(Packet p) throws Exception {
|
||||||
|
if (p instanceof S3FPacketCustomPayload) {
|
||||||
|
S3FPacketCustomPayload packet = (S3FPacketCustomPayload) p;
|
||||||
|
if (Restrictions.PLUGIN_CHANNEL.equals(packet.getChannelName())) {
|
||||||
|
final String unknown = ReplayHandler.getRestrictions().handle(packet);
|
||||||
|
if (unknown == null) {
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
// Failed to parse options, make sure that under no circumstances further packets are parsed
|
||||||
|
terminateReplay();
|
||||||
|
// Then end replay and show error GUI
|
||||||
|
mc.addScheduledTask(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
ReplayHandler.endReplay();
|
||||||
|
mc.displayGuiScreen(new GuiErrorScreen(
|
||||||
|
I18n.format("replaymod.error.unknownrestriction1"),
|
||||||
|
I18n.format("replaymod.error.unknownrestriction2", unknown)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (p instanceof S40PacketDisconnect) {
|
||||||
|
IChatComponent reason = ((S40PacketDisconnect) p).func_149165_c();
|
||||||
|
if ("Please update to view this replay.".equals(reason.getUnformattedText())) {
|
||||||
|
// This version of the mod supports replay restrictions so we are allowed
|
||||||
|
// to remove this packet.
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(BAD_PACKETS.contains(p.getClass())) return null;
|
if(BAD_PACKETS.contains(p.getClass())) return null;
|
||||||
|
|
||||||
if(ReplayProcess.isVideoRecording() && ReplayHandler.isInPath()) {
|
if(ReplayProcess.isVideoRecording() && ReplayHandler.isInPath()) {
|
||||||
@@ -484,7 +519,7 @@ public class ReplaySender extends ChannelInboundHandlerAdapter {
|
|||||||
Thread.sleep(10);
|
Thread.sleep(10);
|
||||||
}
|
}
|
||||||
REPLAY_LOOP:
|
REPLAY_LOOP:
|
||||||
while (true) {
|
while (!terminate) {
|
||||||
synchronized (ReplaySender.this) {
|
synchronized (ReplaySender.this) {
|
||||||
if (dis == null) {
|
if (dis == null) {
|
||||||
dis = new DataInputStream(replayFile.recording().get());
|
dis = new DataInputStream(replayFile.recording().get());
|
||||||
|
|||||||
@@ -0,0 +1,52 @@
|
|||||||
|
package eu.crushedpixel.replaymod.replay;
|
||||||
|
|
||||||
|
import net.minecraft.network.PacketBuffer;
|
||||||
|
import net.minecraft.network.play.server.S3FPacketCustomPayload;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restrictions set by the server,
|
||||||
|
* @see <a href="https://gist.github.com/Johni0702/2547c463e51f65f312cb">Replay Restrictions Gist</a>
|
||||||
|
*/
|
||||||
|
public class Restrictions {
|
||||||
|
public static final String PLUGIN_CHANNEL = "Replay|Restrict";
|
||||||
|
private boolean noXray;
|
||||||
|
private boolean noNoclip;
|
||||||
|
private boolean onlyFirstPerson;
|
||||||
|
private boolean onlyRecordingPlayer;
|
||||||
|
|
||||||
|
public String handle(S3FPacketCustomPayload packet) {
|
||||||
|
PacketBuffer buffer = packet.getBufferData();
|
||||||
|
while (buffer.isReadable()) {
|
||||||
|
String name = buffer.readStringFromBuffer(64);
|
||||||
|
boolean active = buffer.readBoolean();
|
||||||
|
// if ("no_xray".equals(name)) {
|
||||||
|
// noXray = active;
|
||||||
|
// } else if ("no_noclip".equals(name)) {
|
||||||
|
// noNoclip = active;
|
||||||
|
// } else if ("only_first_person".equals(name)) {
|
||||||
|
// onlyFirstPerson = active;
|
||||||
|
// } else if ("only_recording_player".equals(name)) {
|
||||||
|
// onlyRecordingPlayer = active;
|
||||||
|
// } else {
|
||||||
|
return name;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isNoXray() {
|
||||||
|
return noXray;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isNoNoclip() {
|
||||||
|
return noNoclip;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isOnlyFirstPerson() {
|
||||||
|
return onlyFirstPerson;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isOnlyRecordingPlayer() {
|
||||||
|
return onlyRecordingPlayer;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -415,3 +415,7 @@ replaymod.gui.objects.properties.name=Object Name
|
|||||||
replaymod.gui.objects.empty=No Objects added
|
replaymod.gui.objects.empty=No Objects added
|
||||||
replaymod.gui.objects.defaultname=New Object
|
replaymod.gui.objects.defaultname=New Object
|
||||||
replaymod.gui.objects=Custom Objects
|
replaymod.gui.objects=Custom Objects
|
||||||
|
|
||||||
|
#Errors
|
||||||
|
replaymod.error.unknownrestriction1=This replay cannot be played with your current version.
|
||||||
|
replaymod.error.unknownrestriction2=It tried to enforce %s which is unknown.
|
||||||
Reference in New Issue
Block a user