Moved Key Events to KeyInputHandler
Added Spectator Menu and Mode to Replay
This commit is contained in:
@@ -12,6 +12,7 @@ import java.util.UUID;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiScreen;
|
||||
import net.minecraft.client.network.NetHandlerPlayClient;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.network.EnumPacketDirection;
|
||||
import net.minecraft.network.NetworkManager;
|
||||
import net.minecraft.network.play.INetHandlerPlayClient;
|
||||
@@ -26,6 +27,7 @@ import eu.crushedpixel.replaymod.holders.KeyframeComparator;
|
||||
import eu.crushedpixel.replaymod.holders.Position;
|
||||
import eu.crushedpixel.replaymod.holders.PositionKeyframe;
|
||||
import eu.crushedpixel.replaymod.holders.TimeKeyframe;
|
||||
import eu.crushedpixel.replaymod.registry.ReplayGuiRegistry;
|
||||
|
||||
public class ReplayHandler {
|
||||
|
||||
@@ -35,7 +37,7 @@ public class ReplayHandler {
|
||||
private static OpenEmbeddedChannel channel;
|
||||
|
||||
private static int realTimelinePosition = 0;
|
||||
|
||||
|
||||
private static Keyframe selectedKeyframe;
|
||||
|
||||
private static boolean isReplaying = false;
|
||||
@@ -49,15 +51,39 @@ public class ReplayHandler {
|
||||
public static long lastExit = 0;
|
||||
|
||||
private static float gamma = 0f;
|
||||
|
||||
|
||||
private static Entity currentEntity = null;
|
||||
|
||||
public static void spectateEntity(Entity e) {
|
||||
currentEntity = e;
|
||||
mc.setRenderViewEntity(currentEntity);
|
||||
}
|
||||
|
||||
public static Entity getSpectatedEntity() {
|
||||
return currentEntity;
|
||||
}
|
||||
|
||||
public static void spectateCamera() {
|
||||
if(currentEntity != null) {
|
||||
Position prev = new Position(currentEntity);
|
||||
cameraEntity.movePath(prev);
|
||||
}
|
||||
currentEntity = cameraEntity;
|
||||
mc.setRenderViewEntity(cameraEntity);
|
||||
}
|
||||
|
||||
public static boolean isCamera() {
|
||||
return currentEntity == cameraEntity;
|
||||
}
|
||||
|
||||
public static void setInitialGamma(float initial) {
|
||||
gamma = initial;
|
||||
}
|
||||
|
||||
|
||||
public static float getInitialGamma() {
|
||||
return gamma;
|
||||
}
|
||||
|
||||
|
||||
public static void setReplaying(boolean replaying) {
|
||||
isReplaying = replaying;
|
||||
}
|
||||
@@ -73,11 +99,11 @@ public class ReplayHandler {
|
||||
public static boolean isReplaying() {
|
||||
return isReplaying;
|
||||
}
|
||||
|
||||
|
||||
public static void setCameraEntity(CameraEntity entity) {
|
||||
if(entity == null) return;
|
||||
cameraEntity = entity;
|
||||
mc.setRenderViewEntity(cameraEntity);
|
||||
spectateCamera();
|
||||
}
|
||||
|
||||
public static CameraEntity getCameraEntity() {
|
||||
@@ -135,7 +161,7 @@ public class ReplayHandler {
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
public static int getTimeKeyframeCount() {
|
||||
int size = 0;
|
||||
for(Keyframe kf : keyframes) {
|
||||
@@ -240,7 +266,7 @@ public class ReplayHandler {
|
||||
|
||||
public static void resetKeyframes() {
|
||||
keyframes = new ArrayList<Keyframe>();
|
||||
|
||||
|
||||
selectKeyframe(null);
|
||||
}
|
||||
|
||||
@@ -249,7 +275,7 @@ public class ReplayHandler {
|
||||
replaySender.jumpToTime(pos);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static boolean isHurrying() {
|
||||
if(replaySender != null) {
|
||||
return replaySender.isHurrying();
|
||||
@@ -299,7 +325,7 @@ public class ReplayHandler {
|
||||
}
|
||||
|
||||
public static void startReplay(File file) throws NoSuchMethodException, SecurityException, NoSuchFieldException {
|
||||
|
||||
|
||||
ChatMessageRequests.initialize();
|
||||
mc.ingameGUI.getChatGUI().clearChatMessages();
|
||||
resetKeyframes();
|
||||
@@ -372,11 +398,11 @@ public class ReplayHandler {
|
||||
public static Keyframe getSelected() {
|
||||
return selectedKeyframe;
|
||||
}
|
||||
|
||||
|
||||
public static int getRealTimelineCursor() {
|
||||
return realTimelinePosition;
|
||||
}
|
||||
|
||||
|
||||
public static void setRealTimelineCursor(int pos) {
|
||||
realTimelinePosition = pos;
|
||||
}
|
||||
@@ -385,7 +411,7 @@ public class ReplayHandler {
|
||||
public static void setLastPosition(Position position) {
|
||||
lastPosition = position;
|
||||
}
|
||||
|
||||
|
||||
public static Position getLastPosition() {
|
||||
return lastPosition;
|
||||
}
|
||||
|
||||
@@ -8,8 +8,8 @@ import io.netty.channel.ChannelInboundHandlerAdapter;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.EOFException;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.lang.reflect.Field;
|
||||
@@ -332,7 +332,7 @@ public class ReplaySender extends ChannelInboundHandlerAdapter {
|
||||
hasRestarted = false;
|
||||
}
|
||||
|
||||
} catch(EOFException eof) {
|
||||
} catch(IOException eof) {
|
||||
setReplaySpeed(0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,233 @@
|
||||
package eu.crushedpixel.replaymod.replay.screenshot;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.nio.IntBuffer;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiScreen;
|
||||
import net.minecraft.client.renderer.GlStateManager;
|
||||
import net.minecraft.client.renderer.OpenGlHelper;
|
||||
import net.minecraft.client.renderer.texture.TextureUtil;
|
||||
import net.minecraft.client.shader.Framebuffer;
|
||||
|
||||
import org.lwjgl.BufferUtils;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
import org.lwjgl.opengl.GL12;
|
||||
|
||||
import eu.crushedpixel.replaymod.chat.ChatMessageRequests;
|
||||
import eu.crushedpixel.replaymod.chat.ChatMessageRequests.ChatMessageType;
|
||||
import eu.crushedpixel.replaymod.gui.GuiReplaySaving;
|
||||
import eu.crushedpixel.replaymod.replay.ReplayHandler;
|
||||
import eu.crushedpixel.replaymod.utils.ImageUtils;
|
||||
|
||||
public class ReplayScreenshot {
|
||||
|
||||
private static Minecraft mc = Minecraft.getMinecraft();
|
||||
private static IntBuffer pixelBuffer;
|
||||
private static int[] pixelValues;
|
||||
|
||||
private static final byte[] uniqueBytes = new byte[]{0,1,1,2,3,5,8};
|
||||
|
||||
private static long last_finish = -1;
|
||||
|
||||
private static boolean before;
|
||||
private static double beforeSpeed;
|
||||
private static GuiScreen beforeScreen;
|
||||
|
||||
public static void prepareScreenshot() {
|
||||
before = mc.gameSettings.hideGUI;
|
||||
beforeSpeed = ReplayHandler.getSpeed();
|
||||
beforeScreen = mc.currentScreen;
|
||||
}
|
||||
|
||||
public static void saveScreenshot(Framebuffer buffer) {
|
||||
|
||||
try {
|
||||
GuiReplaySaving.replaySaving = true;
|
||||
|
||||
mc.gameSettings.hideGUI = true;
|
||||
mc.currentScreen = null;
|
||||
|
||||
mc.entityRenderer.updateCameraAndRender(0);
|
||||
ReplayHandler.setSpeed(0);
|
||||
|
||||
int width = mc.displayWidth;
|
||||
int height = mc.displayHeight;
|
||||
|
||||
if (OpenGlHelper.isFramebufferEnabled())
|
||||
{
|
||||
width = buffer.framebufferTextureWidth;
|
||||
height = buffer.framebufferTextureHeight;
|
||||
}
|
||||
|
||||
int k = width * height;
|
||||
|
||||
if (pixelBuffer == null || pixelBuffer.capacity() < k)
|
||||
{
|
||||
pixelBuffer = BufferUtils.createIntBuffer(k);
|
||||
pixelValues = new int[k];
|
||||
}
|
||||
|
||||
GL11.glPixelStorei(GL11.GL_PACK_ALIGNMENT, 1);
|
||||
GL11.glPixelStorei(GL11.GL_UNPACK_ALIGNMENT, 1);
|
||||
pixelBuffer.clear();
|
||||
|
||||
if (OpenGlHelper.isFramebufferEnabled()) {
|
||||
GlStateManager.bindTexture(buffer.framebufferTexture);
|
||||
GL11.glGetTexImage(GL11.GL_TEXTURE_2D, 0, GL12.GL_BGRA, GL12.GL_UNSIGNED_INT_8_8_8_8_REV, pixelBuffer);
|
||||
}
|
||||
else {
|
||||
GL11.glReadPixels(0, 0, width, height, GL12.GL_BGRA, GL12.GL_UNSIGNED_INT_8_8_8_8_REV, pixelBuffer);
|
||||
}
|
||||
|
||||
pixelBuffer.get(pixelValues);
|
||||
TextureUtil.processPixelValues(pixelValues, width, height);
|
||||
BufferedImage bufferedimage = null;
|
||||
|
||||
|
||||
if (OpenGlHelper.isFramebufferEnabled())
|
||||
{
|
||||
bufferedimage = new BufferedImage(buffer.framebufferWidth, buffer.framebufferHeight, 1);
|
||||
int l = buffer.framebufferTextureHeight - buffer.framebufferHeight;
|
||||
|
||||
for (int i1 = l; i1 < buffer.framebufferTextureHeight; ++i1)
|
||||
{
|
||||
for (int j1 = 0; j1 < buffer.framebufferWidth; ++j1)
|
||||
{
|
||||
bufferedimage.setRGB(j1, i1 - l, pixelValues[i1 * buffer.framebufferTextureWidth + j1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
bufferedimage = new BufferedImage(width, height, 1);
|
||||
bufferedimage.setRGB(0, 0, width, height, pixelValues, 0, width);
|
||||
}
|
||||
|
||||
final BufferedImage fbi = bufferedimage;
|
||||
|
||||
mc.gameSettings.hideGUI = before;
|
||||
mc.currentScreen = beforeScreen;
|
||||
ReplayHandler.setSpeed(beforeSpeed);
|
||||
|
||||
//The actual cropping and saving should be executed in a separate thread
|
||||
Thread ioThread = new Thread(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
|
||||
|
||||
float aspect = 1280f/720f;
|
||||
|
||||
Rectangle rect;
|
||||
if((float)fbi.getWidth()/(float)fbi.getHeight() <= aspect) {
|
||||
int h = Math.round(fbi.getWidth()/aspect);
|
||||
int y = (fbi.getHeight()/2) - (h/2);
|
||||
System.out.println(h+" | "+y);
|
||||
rect = new Rectangle(0, y, fbi.getWidth(), h);
|
||||
} else {
|
||||
int w = Math.round(fbi.getHeight()*aspect);
|
||||
int x = (fbi.getWidth()/2) - (w/2);
|
||||
rect = new Rectangle(x, 0, w, fbi.getHeight());
|
||||
}
|
||||
|
||||
final BufferedImage nbi = ImageUtils.cropImage(fbi, rect);
|
||||
|
||||
File replayFile = ReplayHandler.getReplayFile();
|
||||
|
||||
File folder = new File("./replay_recordings/");
|
||||
folder.mkdirs();
|
||||
|
||||
File temp = File.createTempFile("thumb", null);
|
||||
|
||||
int h = 720;
|
||||
int w = 1280;
|
||||
//int w = width*(h/height);
|
||||
|
||||
BufferedImage img = ImageUtils.scaleImage(nbi, new Dimension(w, h));
|
||||
|
||||
ImageIO.write(img, "jpg", temp);
|
||||
|
||||
File tempFile = File.createTempFile(replayFile.getName(), null);
|
||||
tempFile.delete(); tempFile.deleteOnExit();
|
||||
|
||||
replayFile.renameTo(tempFile);
|
||||
|
||||
replayFile.delete();
|
||||
replayFile.createNewFile();
|
||||
|
||||
byte[] buf = new byte[1024];
|
||||
|
||||
ZipInputStream zin = new ZipInputStream(new FileInputStream(tempFile));
|
||||
ZipOutputStream zout = new ZipOutputStream(new FileOutputStream(replayFile));
|
||||
|
||||
FileInputStream fis = new FileInputStream(temp);
|
||||
|
||||
ZipEntry entry = zin.getNextEntry();
|
||||
while (entry != null) {
|
||||
String name = entry.getName();
|
||||
|
||||
if(!name.contains("thumb")) {
|
||||
// Add ZIP entry to output stream.
|
||||
zout.putNextEntry(new ZipEntry(name));
|
||||
// Transfer bytes from the ZIP file to the output file
|
||||
int len;
|
||||
while ((len = zin.read(buf)) > 0) {
|
||||
zout.write(buf, 0, len);
|
||||
}
|
||||
}
|
||||
|
||||
entry = zin.getNextEntry();
|
||||
}
|
||||
|
||||
zout.putNextEntry(new ZipEntry("thumb"));
|
||||
int len;
|
||||
//Add unique bytes to the end of the file
|
||||
zout.write(uniqueBytes);
|
||||
|
||||
while ((len = fis.read(buf)) > 0) {
|
||||
zout.write(buf, 0, len);
|
||||
}
|
||||
|
||||
// Close the streams
|
||||
fis.close();
|
||||
zin.close();
|
||||
// Compress the files
|
||||
// Complete the ZIP file
|
||||
zout.close();
|
||||
tempFile.delete();
|
||||
temp.delete();
|
||||
|
||||
ChatMessageRequests.addChatMessage("Thumbnail has been successfully saved", ChatMessageType.INFORMATION);
|
||||
} catch(Exception e) {}
|
||||
finally {
|
||||
GuiReplaySaving.replaySaving = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
ioThread.start();
|
||||
}
|
||||
catch (Exception exception) {
|
||||
mc.gameSettings.hideGUI = before;
|
||||
mc.currentScreen = beforeScreen;
|
||||
ReplayHandler.setSpeed(beforeSpeed);
|
||||
exception.printStackTrace();
|
||||
ChatMessageRequests.addChatMessage("Thumbnail could not be saved", ChatMessageType.WARNING);
|
||||
}
|
||||
|
||||
last_finish = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package eu.crushedpixel.replaymod.replay.spectate;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
|
||||
import eu.crushedpixel.replaymod.entities.CameraEntity;
|
||||
import eu.crushedpixel.replaymod.gui.GuiSpectateSelection;
|
||||
import eu.crushedpixel.replaymod.replay.ReplayHandler;
|
||||
|
||||
public class SpectateHandler {
|
||||
|
||||
private static Minecraft mc = Minecraft.getMinecraft();
|
||||
|
||||
private static Predicate<EntityPlayer> playerPredicate = new Predicate<EntityPlayer>() {
|
||||
@Override
|
||||
public boolean apply(EntityPlayer input) {
|
||||
if(input instanceof CameraEntity || input == mc.thePlayer) return false;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
public static void openSpectateSelection() {
|
||||
if(!ReplayHandler.replayActive()) {
|
||||
return;
|
||||
}
|
||||
|
||||
List<EntityPlayer> players = mc.theWorld.getEntities(EntityPlayer.class, playerPredicate);
|
||||
mc.displayGuiScreen(new GuiSpectateSelection(players));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user