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.load();
Property recServer = config.get("settings", "enableRecordingServer", true, "Defines whether a recording should be started upon joining a server.");
Property recSP = config.get("settings", "enableRecordingSingleplayer", true, "Defines whether a recording should be started upon joining a singleplayer world.");
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();
replaySettings = new ReplaySettings();
replaySettings.readValues();
}
@EventHandler

View File

@@ -121,8 +121,7 @@ public class GuiReplayOverlay extends Gui {
@SubscribeEvent
public void tick(TickEvent event) {
if(!ReplayHandler.isInReplay()) return;
if(ReplayHandler.isInPath() && !ReplayProcess.isVideoRecording()) ReplayProcess.tickReplay();
ReplayProcess.unblock();
if(ReplayHandler.isInPath()) ReplayProcess.unblockAndTick();
if(ReplayHandler.getCameraEntity() != null)
ReplayHandler.getCameraEntity().updateMovement();
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.GuiScreen;
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 eu.crushedpixel.replaymod.ReplayMod;
import eu.crushedpixel.replaymod.settings.ReplaySettings;
import eu.crushedpixel.replaymod.settings.ReplaySettings.Option;
public class GuiReplaySettings extends GuiScreen {
@@ -28,8 +35,7 @@ public class GuiReplaySettings extends GuiScreen {
private GuiButton recordServerButton, recordSPButton, sendChatButton, linearButton, lightingButton, resourcePackButton;
public GuiReplaySettings(GuiScreen parentGuiScreen)
{
public GuiReplaySettings(GuiScreen parentGuiScreen) {
this.parentGuiScreen = parentGuiScreen;
}
@@ -40,6 +46,8 @@ public class GuiReplaySettings extends GuiScreen {
Option[] aoptions = Option.values();
ReplaySettings settings = ReplayMod.replaySettings;
int k = 0;
int i = 0;
for (Option o : aoptions) {
@@ -47,36 +55,37 @@ public class GuiReplaySettings extends GuiScreen {
switch(o) {
case lighting:
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;
case linear:
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;
case notifications:
this.buttonList.add(sendChatButton = new GuiButton(SEND_CHAT,
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;
case recordServer:
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;
case recordSingleplayer:
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;
case useResources:
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;
case videoFramerate:
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;
case videoQuality:
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;
default:
break;

View File

@@ -9,10 +9,10 @@ import eu.crushedpixel.replaymod.ReplayMod;
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, "");
this.sliderValue = normalizeValue(initialQuality);
this.displayString = displayKey+": "+translate(initialQuality);
this.sliderValue = normalizeValue(d);
this.displayString = displayKey+": "+translate(d);
this.displayKey = displayKey;
}

View File

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

View File

@@ -6,6 +6,7 @@ import net.minecraft.client.Minecraft;
import net.minecraft.client.settings.GameSettings.Options;
import net.minecraft.util.Timer;
import net.minecraftforge.common.config.Configuration;
import net.minecraftforge.common.config.Property;
import eu.crushedpixel.replaymod.ReplayMod;
import eu.crushedpixel.replaymod.reflection.MCPNames;
import eu.crushedpixel.replaymod.replay.ReplayHandler;
@@ -43,15 +44,15 @@ public class ReplaySettings {
}
}
public ReplaySettings(boolean enableRecordingServer,
boolean enableRecordingSingleplayer, boolean showNotifications, boolean forceLinearPath, boolean lightingEnabled, int framerate, float videoQuality) {
setEnableRecordingServer(enableRecordingServer);
setEnableRecordingSingleplayer(enableRecordingSingleplayer);
setLinearMovement(forceLinearPath);
setShowNotifications(showNotifications);
setLightingEnabled(lightingEnabled);
setVideoFramerate(Math.min(120, Math.max(10, framerate)));
setVideoQuality(Math.min(0.9f, Math.max(0.1f, videoQuality)));
public void readValues() {
Configuration config = ReplayMod.config;
for(Option o : Option.values()) {
Property p = getConfigSetting(config, o);
o.setValue(getValueObject(p));
}
config.save();
}
public int getVideoFramerate() {
@@ -61,8 +62,8 @@ public class ReplaySettings {
Option.videoFramerate.setValue(Math.min(120, Math.max(10, framerate)));
rewriteSettings();
}
public float getVideoQuality() {
return (Float)Option.videoQuality.getValue();
public double getVideoQuality() {
return (Double)Option.videoQuality.getValue();
}
public void setVideoQuality(float 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"));
for(Option o : Option.values()) {
addConfigSetting(ReplayMod.instance.config, o);
getConfigSetting(ReplayMod.instance.config, o);
}
ReplayMod.instance.config.save();
}
private void addConfigSetting(Configuration config, Option o) {
private Property getConfigSetting(Configuration config, Option o) {
Object value = o.getValue();
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) {
config.get("settings", o.name(), (Boolean)o.getValue());
return config.get("settings", o.name(), (Boolean)o.getValue());
} 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) {
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.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Queue;
import java.util.concurrent.LinkedBlockingQueue;
import org.monte.media.Buffer;
import org.monte.media.Format;
@@ -42,6 +44,8 @@ public class VideoWriter {
}
isRecording = true;
toWrite = new LinkedBlockingQueue<BufferedImage>();
try {
File folder = new File("./replay_videos/");
folder.mkdirs();
@@ -69,8 +73,39 @@ public class VideoWriter {
} catch (IOException e) {
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) {
if(requestFinish || !isRecording) {
IllegalStateException up = new IllegalStateException(
@@ -78,20 +113,22 @@ public class VideoWriter {
throw up; //lolololo^2
}
try {
buf.data = image;
out.write(track, buf);
} catch (IOException e) {
e.printStackTrace();
}
toWrite.add(image);
}
public static void endRecording() {
if(!isRecording) return;
isRecording = false;
requestFinish = true;
}
private static void write() {
try {
out.close();
} catch(Exception e) {
BufferedImage img = toWrite.poll();
if(img != null) {
buf.data = img;
out.write(track, buf);
}
} catch (IOException e) {
e.printStackTrace();
}
}