Made Replay Settings actually persist over the course of two Minecraft sessions.

Started breaking video rendering. Time to put it back together.
This commit is contained in:
Marius Metzger
2015-04-05 00:41:49 +02:00
parent f3cb4011fc
commit 82160b68d4
7 changed files with 118 additions and 93 deletions

View File

@@ -75,18 +75,8 @@ public class ReplayMod
config = new Configuration(event.getSuggestedConfigurationFile()); config = new Configuration(event.getSuggestedConfigurationFile());
config.load(); config.load();
Property recServer = config.get("settings", "enableRecordingServer", true, "Defines whether a recording should be started upon joining a server."); replaySettings = new ReplaySettings();
Property recSP = config.get("settings", "enableRecordingSingleplayer", true, "Defines whether a recording should be started upon joining a singleplayer world."); replaySettings.readValues();
Property showNot = ReplayMod.instance.config.get("settings", "showNotifications", true, "Defines whether notifications should be sent to the player.");
Property linear = ReplayMod.instance.config.get("settings", "forceLinearPath", false, "Defines whether travelling paths should be linear instead of interpolated.");
Property lighting = ReplayMod.instance.config.get("settings", "enableLighting", false, "If enabled, the whole map is lighted.");
Property vq = ReplayMod.instance.config.get("settings", "videoQuality", 0.5f, "The quality of the exported video files from 0.1 to 0.9");
Property framerate = ReplayMod.instance.config.get("settings", "videoFramerate", 30, "The framerate of the exported video files from 10 to 120");
replaySettings = new ReplaySettings(recServer.getBoolean(true), recSP.getBoolean(true), showNot.getBoolean(true),
linear.getBoolean(false), lighting.getBoolean(false), framerate.getInt(30), (float)vq.getDouble(0.5));
config.save();
} }
@EventHandler @EventHandler

View File

@@ -121,8 +121,7 @@ public class GuiReplayOverlay extends Gui {
@SubscribeEvent @SubscribeEvent
public void tick(TickEvent event) { public void tick(TickEvent event) {
if(!ReplayHandler.isInReplay()) return; if(!ReplayHandler.isInReplay()) return;
if(ReplayHandler.isInPath() && !ReplayProcess.isVideoRecording()) ReplayProcess.tickReplay(); if(ReplayHandler.isInPath()) ReplayProcess.unblockAndTick();
ReplayProcess.unblock();
if(ReplayHandler.getCameraEntity() != null) if(ReplayHandler.getCameraEntity() != null)
ReplayHandler.getCameraEntity().updateMovement(); ReplayHandler.getCameraEntity().updateMovement();
if(!ReplayHandler.isInPath()) onMouseMove(new MouseEvent()); if(!ReplayHandler.isInPath()) onMouseMove(new MouseEvent());

View File

@@ -7,8 +7,15 @@ import java.util.Map.Entry;
import net.minecraft.client.gui.GuiButton; import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiScreen; import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.resources.I18n; import net.minecraft.client.resources.I18n;
import net.minecraft.entity.item.EntityArmorStand;
import net.minecraft.network.play.server.S0EPacketSpawnObject;
import net.minecraft.network.play.server.S0FPacketSpawnMob;
import net.minecraft.network.play.server.S14PacketEntity;
import net.minecraft.network.play.server.S14PacketEntity.S15PacketEntityRelMove;
import net.minecraft.network.play.server.S14PacketEntity.S16PacketEntityLook;
import net.minecraftforge.fml.client.FMLClientHandler; import net.minecraftforge.fml.client.FMLClientHandler;
import eu.crushedpixel.replaymod.ReplayMod; import eu.crushedpixel.replaymod.ReplayMod;
import eu.crushedpixel.replaymod.settings.ReplaySettings;
import eu.crushedpixel.replaymod.settings.ReplaySettings.Option; import eu.crushedpixel.replaymod.settings.ReplaySettings.Option;
public class GuiReplaySettings extends GuiScreen { public class GuiReplaySettings extends GuiScreen {
@@ -28,8 +35,7 @@ public class GuiReplaySettings extends GuiScreen {
private GuiButton recordServerButton, recordSPButton, sendChatButton, linearButton, lightingButton, resourcePackButton; private GuiButton recordServerButton, recordSPButton, sendChatButton, linearButton, lightingButton, resourcePackButton;
public GuiReplaySettings(GuiScreen parentGuiScreen) public GuiReplaySettings(GuiScreen parentGuiScreen) {
{
this.parentGuiScreen = parentGuiScreen; this.parentGuiScreen = parentGuiScreen;
} }
@@ -40,6 +46,8 @@ public class GuiReplaySettings extends GuiScreen {
Option[] aoptions = Option.values(); Option[] aoptions = Option.values();
ReplaySettings settings = ReplayMod.replaySettings;
int k = 0; int k = 0;
int i = 0; int i = 0;
for (Option o : aoptions) { for (Option o : aoptions) {
@@ -47,36 +55,37 @@ public class GuiReplaySettings extends GuiScreen {
switch(o) { switch(o) {
case lighting: case lighting:
this.buttonList.add(lightingButton = new GuiButton(ENABLE_LIGHTING, this.width / 2 - 155 + i % 2 * 160, this.buttonList.add(lightingButton = new GuiButton(ENABLE_LIGHTING, this.width / 2 - 155 + i % 2 * 160,
this.height / 6 + 24 * (i >> 1), 150, 20, "Enable Lighting: "+onOff((Boolean)o.getValue()))); this.height / 6 + 24 * (i >> 1), 150, 20, "Enable Lighting: "+onOff(settings.isLightingEnabled())));
break; break;
case linear: case linear:
this.buttonList.add(linearButton = new GuiButton(FORCE_LINEAR, this.width / 2 - 155 + i % 2 * 160, this.buttonList.add(linearButton = new GuiButton(FORCE_LINEAR, this.width / 2 - 155 + i % 2 * 160,
this.height / 6 + 24 * (i >> 1), 150, 20, "Camera Path: "+linearOnOff((Boolean)o.getValue()))); this.height / 6 + 24 * (i >> 1), 150, 20, "Camera Path: "+linearOnOff(settings.isLinearMovement())));
break; break;
case notifications: case notifications:
this.buttonList.add(sendChatButton = new GuiButton(SEND_CHAT, this.buttonList.add(sendChatButton = new GuiButton(SEND_CHAT,
this.width / 2 - 155 + i % 2 * 160, this.height / 6 + 24 * (i >> 1), 150, 20, this.width / 2 - 155 + i % 2 * 160, this.height / 6 + 24 * (i >> 1), 150, 20,
"Enable Notifications: "+onOff((Boolean)o.getValue()))); "Enable Notifications: "+onOff(settings.isShowNotifications())));
break; break;
case recordServer: case recordServer:
this.buttonList.add(recordServerButton = new GuiButton(RECORDSERVER_ID, this.buttonList.add(recordServerButton = new GuiButton(RECORDSERVER_ID,
this.width / 2 - 155 + i % 2 * 160, this.height / 6 + 24 * (i >> 1), 150, 20, "Record Server: "+onOff((Boolean)o.getValue()))); this.width / 2 - 155 + i % 2 * 160, this.height / 6 + 24 * (i >> 1), 150, 20, "Record Server: "
+onOff(settings.isEnableRecordingServer())));
break; break;
case recordSingleplayer: case recordSingleplayer:
this.buttonList.add(recordSPButton = new GuiButton(RECORDSP_ID, this.width / 2 - 155 + i % 2 * 160, this.buttonList.add(recordSPButton = new GuiButton(RECORDSP_ID, this.width / 2 - 155 + i % 2 * 160,
this.height / 6 + 24 * (i >> 1), 150, 20, "Record Singleplayer: "+onOff((Boolean)o.getValue()))); this.height / 6 + 24 * (i >> 1), 150, 20, "Record Singleplayer: "+onOff(settings.isEnableRecordingSingleplayer())));
break; break;
case useResources: case useResources:
this.buttonList.add(resourcePackButton = new GuiButton(RESOURCEPACK_ID, this.width / 2 - 155 + i % 2 * 160, this.buttonList.add(resourcePackButton = new GuiButton(RESOURCEPACK_ID, this.width / 2 - 155 + i % 2 * 160,
this.height / 6 + 24 * (i >> 1), 150, 20, "Server Resource Packs: "+onOff((Boolean)o.getValue()))); this.height / 6 + 24 * (i >> 1), 150, 20, "Server Resource Packs: "+onOff(settings.getUseResourcePacks())));
break; break;
case videoFramerate: case videoFramerate:
this.buttonList.add(new GuiVideoFramerateSlider(FRAMERATE_SLIDER_ID, this.buttonList.add(new GuiVideoFramerateSlider(FRAMERATE_SLIDER_ID,
this.width / 2 - 155 + i % 2 * 160, this.height / 6 + 24 * (i >> 1), (Integer)o.getValue(), "Video Framerate")); this.width / 2 - 155 + i % 2 * 160, this.height / 6 + 24 * (i >> 1), settings.getVideoFramerate(), "Video Framerate"));
break; break;
case videoQuality: case videoQuality:
this.buttonList.add(new GuiVideoQualitySlider(QUALITY_SLIDER_ID, this.buttonList.add(new GuiVideoQualitySlider(QUALITY_SLIDER_ID,
this.width / 2 - 155 + i % 2 * 160, this.height / 6 + 24 * (i >> 1), (Float)o.getValue(), "Video Quality")); this.width / 2 - 155 + i % 2 * 160, this.height / 6 + 24 * (i >> 1), (float)settings.getVideoQuality(), "Video Quality"));
break; break;
default: default:
break; break;

View File

@@ -9,10 +9,10 @@ import eu.crushedpixel.replaymod.ReplayMod;
public class GuiVideoQualitySlider extends GuiButton { public class GuiVideoQualitySlider extends GuiButton {
public GuiVideoQualitySlider(int buttonId, int p_i45017_2_, int p_i45017_3_, float initialQuality, String displayKey) { public GuiVideoQualitySlider(int buttonId, int p_i45017_2_, int p_i45017_3_, float d, String displayKey) {
super(buttonId, p_i45017_2_, p_i45017_3_, 150, 20, ""); super(buttonId, p_i45017_2_, p_i45017_3_, 150, 20, "");
this.sliderValue = normalizeValue(initialQuality); this.sliderValue = normalizeValue(d);
this.displayString = displayKey+": "+translate(initialQuality); this.displayString = displayKey+": "+translate(d);
this.displayKey = displayKey; this.displayKey = displayKey;
} }

View File

@@ -1,10 +1,9 @@
package eu.crushedpixel.replaymod.replay; package eu.crushedpixel.replaymod.replay;
import java.io.File; import java.awt.image.BufferedImage;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiScreen; import net.minecraft.client.gui.GuiScreen;
import net.minecraft.enchantment.Enchantment;
import eu.crushedpixel.replaymod.ReplayMod; import eu.crushedpixel.replaymod.ReplayMod;
import eu.crushedpixel.replaymod.chat.ChatMessageRequests; import eu.crushedpixel.replaymod.chat.ChatMessageRequests;
import eu.crushedpixel.replaymod.chat.ChatMessageRequests.ChatMessageType; import eu.crushedpixel.replaymod.chat.ChatMessageRequests.ChatMessageType;
@@ -87,33 +86,8 @@ public class ReplayProcess {
ChatMessageRequests.addChatMessage("Replay started!", ChatMessageType.INFORMATION); ChatMessageRequests.addChatMessage("Replay started!", ChatMessageType.INFORMATION);
if(isVideoRecording()) { if(isVideoRecording()) {
ticks = 0;
MCTimerHandler.setTimerSpeed(1); MCTimerHandler.setTimerSpeed(1);
MCTimerHandler.setPassiveTimer(); MCTimerHandler.setPassiveTimer();
Thread t = new Thread(new Runnable() {
@Override
public void run() {
while(ReplayHandler.isInPath()) {
if(!blocked) {
mc.addScheduledTask(new Runnable() {
@Override
public void run() {
ReplayProcess.tickReplay();
}
});
} else {
try {
Thread.sleep(10);
} catch(Exception e) {
e.printStackTrace();
}
}
}
}
});
t.start();
} }
} }
@@ -130,12 +104,13 @@ public class ReplayProcess {
private static boolean blocked = false; private static boolean blocked = false;
private static boolean deepBlock = false; private static boolean deepBlock = false;
private static float ticks = 0;
private static boolean requestFinish = false; private static boolean requestFinish = false;
public static void unblock() { public static void unblockAndTick() {
if(!deepBlock) blocked = false; if(!deepBlock) blocked = false;
if(!blocked || !isVideoRecording())
ReplayProcess.tickReplay();
else System.out.println("nope");
} }
public static void tickReplay() { public static void tickReplay() {
@@ -144,7 +119,6 @@ public class ReplayProcess {
private static void pathTick(boolean recording) { private static void pathTick(boolean recording) {
if(ReplayHandler.isHurrying()) { if(ReplayHandler.isHurrying()) {
if(!recording)
lastRealTime = System.currentTimeMillis(); lastRealTime = System.currentTimeMillis();
return; return;
} }
@@ -193,7 +167,7 @@ public class ReplayProcess {
if(!calculated) { if(!calculated) {
calculated = true; calculated = true;
if(posCount > 1) if(posCount > 1 && motionSpline != null)
motionSpline.calcSpline(); motionSpline.calcSpline();
} }
@@ -320,7 +294,8 @@ public class ReplayProcess {
if(!VideoWriter.isRecording() && ReplayHandler.isInPath()) { if(!VideoWriter.isRecording() && ReplayHandler.isInPath()) {
VideoWriter.startRecording(mc.displayWidth, mc.displayHeight); VideoWriter.startRecording(mc.displayWidth, mc.displayHeight);
} else { } else {
VideoWriter.writeImage(ScreenCapture.captureScreen()); final BufferedImage screen = ScreenCapture.captureScreen();
VideoWriter.writeImage(screen);
} }
} catch(Exception e) { } catch(Exception e) {
e.printStackTrace(); e.printStackTrace();

View File

@@ -6,6 +6,7 @@ import net.minecraft.client.Minecraft;
import net.minecraft.client.settings.GameSettings.Options; import net.minecraft.client.settings.GameSettings.Options;
import net.minecraft.util.Timer; import net.minecraft.util.Timer;
import net.minecraftforge.common.config.Configuration; import net.minecraftforge.common.config.Configuration;
import net.minecraftforge.common.config.Property;
import eu.crushedpixel.replaymod.ReplayMod; import eu.crushedpixel.replaymod.ReplayMod;
import eu.crushedpixel.replaymod.reflection.MCPNames; import eu.crushedpixel.replaymod.reflection.MCPNames;
import eu.crushedpixel.replaymod.replay.ReplayHandler; import eu.crushedpixel.replaymod.replay.ReplayHandler;
@@ -43,15 +44,15 @@ public class ReplaySettings {
} }
} }
public ReplaySettings(boolean enableRecordingServer, public void readValues() {
boolean enableRecordingSingleplayer, boolean showNotifications, boolean forceLinearPath, boolean lightingEnabled, int framerate, float videoQuality) { Configuration config = ReplayMod.config;
setEnableRecordingServer(enableRecordingServer);
setEnableRecordingSingleplayer(enableRecordingSingleplayer); for(Option o : Option.values()) {
setLinearMovement(forceLinearPath); Property p = getConfigSetting(config, o);
setShowNotifications(showNotifications); o.setValue(getValueObject(p));
setLightingEnabled(lightingEnabled); }
setVideoFramerate(Math.min(120, Math.max(10, framerate)));
setVideoQuality(Math.min(0.9f, Math.max(0.1f, videoQuality))); config.save();
} }
public int getVideoFramerate() { public int getVideoFramerate() {
@@ -61,8 +62,8 @@ public class ReplaySettings {
Option.videoFramerate.setValue(Math.min(120, Math.max(10, framerate))); Option.videoFramerate.setValue(Math.min(120, Math.max(10, framerate)));
rewriteSettings(); rewriteSettings();
} }
public float getVideoQuality() { public double getVideoQuality() {
return (Float)Option.videoQuality.getValue(); return (Double)Option.videoQuality.getValue();
} }
public void setVideoQuality(float videoQuality) { public void setVideoQuality(float videoQuality) {
Option.videoQuality.setValue(Math.min(0.9f, Math.max(0.1f, videoQuality))); Option.videoQuality.setValue(Math.min(0.9f, Math.max(0.1f, videoQuality)));
@@ -135,22 +136,36 @@ public class ReplaySettings {
ReplayMod.instance.config.removeCategory(ReplayMod.instance.config.getCategory("settings")); ReplayMod.instance.config.removeCategory(ReplayMod.instance.config.getCategory("settings"));
for(Option o : Option.values()) { for(Option o : Option.values()) {
addConfigSetting(ReplayMod.instance.config, o); getConfigSetting(ReplayMod.instance.config, o);
} }
ReplayMod.instance.config.save(); ReplayMod.instance.config.save();
} }
private void addConfigSetting(Configuration config, Option o) { private Property getConfigSetting(Configuration config, Option o) {
Object value = o.getValue(); Object value = o.getValue();
if(value instanceof Integer) { if(value instanceof Integer) {
config.get("settings", o.name(), (Integer)o.getValue()); return config.get("settings", o.name(), (Integer)o.getValue());
} else if(value instanceof Boolean) { } else if(value instanceof Boolean) {
config.get("settings", o.name(), (Boolean)o.getValue()); return config.get("settings", o.name(), (Boolean)o.getValue());
} else if(value instanceof Double) { } else if(value instanceof Double) {
config.get("settings", o.name(), (Double)o.getValue()); return config.get("settings", o.name(), (Double)o.getValue());
} else if(value instanceof Float) {
return config.get("settings", o.name(), (double)(Float)o.getValue());
} else if(value instanceof String) { } else if(value instanceof String) {
config.get("settings", o.name(), (String)o.getValue()); return config.get("settings", o.name(), (String)o.getValue());
} }
return null;
}
private Object getValueObject(Property p) {
if(p.isIntValue()) {
return p.getInt();
} else if(p.isDoubleValue()) {
return p.getDouble();
} else if(p.isBooleanValue()) {
return p.getBoolean();
}
return null;
} }
} }

View File

@@ -5,6 +5,8 @@ import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Calendar; import java.util.Calendar;
import java.util.Queue;
import java.util.concurrent.LinkedBlockingQueue;
import org.monte.media.Buffer; import org.monte.media.Buffer;
import org.monte.media.Format; import org.monte.media.Format;
@@ -42,6 +44,8 @@ public class VideoWriter {
} }
isRecording = true; isRecording = true;
toWrite = new LinkedBlockingQueue<BufferedImage>();
try { try {
File folder = new File("./replay_videos/"); File folder = new File("./replay_videos/");
folder.mkdirs(); folder.mkdirs();
@@ -69,7 +73,38 @@ public class VideoWriter {
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
Thread t = new Thread(new Runnable() {
@Override
public void run() {
while(true) {
if(toWrite.isEmpty()) {
if(requestFinish) {
requestFinish = false;
isRecording = false;
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
} }
return;
}
try {
Thread.sleep(10);
} catch(Exception e) {
e.printStackTrace();
}
} else {
write();
}
}
}
});
t.start();
}
private static Queue<BufferedImage> toWrite = new LinkedBlockingQueue<BufferedImage>();
public static void writeImage(BufferedImage image) { public static void writeImage(BufferedImage image) {
if(requestFinish || !isRecording) { if(requestFinish || !isRecording) {
@@ -78,20 +113,22 @@ public class VideoWriter {
throw up; //lolololo^2 throw up; //lolololo^2
} }
try { toWrite.add(image);
buf.data = image;
out.write(track, buf);
} catch (IOException e) {
e.printStackTrace();
}
} }
public static void endRecording() { public static void endRecording() {
if(!isRecording) return; if(!isRecording) return;
isRecording = false; requestFinish = true;
}
private static void write() {
try { try {
out.close(); BufferedImage img = toWrite.poll();
} catch(Exception e) { if(img != null) {
buf.data = img;
out.write(track, buf);
}
} catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }