Cleaned up even more GUIs
Added possibility to create Thumbnails and show them in the Replay Manager
This commit is contained in:
@@ -1,8 +1,5 @@
|
||||
package eu.crushedpixel.replaymod;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.common.config.Configuration;
|
||||
import net.minecraftforge.common.config.Property;
|
||||
@@ -10,18 +7,13 @@ import net.minecraftforge.fml.common.FMLCommonHandler;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
import net.minecraftforge.fml.common.Mod.EventHandler;
|
||||
import net.minecraftforge.fml.common.Mod.Instance;
|
||||
import net.minecraftforge.fml.common.SidedProxy;
|
||||
import net.minecraftforge.fml.common.event.FMLInitializationEvent;
|
||||
import net.minecraftforge.fml.common.event.FMLPostInitializationEvent;
|
||||
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
|
||||
import eu.crushedpixel.replaymod.api.client.ApiClient;
|
||||
import eu.crushedpixel.replaymod.api.client.ApiException;
|
||||
import eu.crushedpixel.replaymod.api.client.holders.AuthKey;
|
||||
import eu.crushedpixel.replaymod.authentication.AuthenticationHandler;
|
||||
import eu.crushedpixel.replaymod.events.GuiEventHandler;
|
||||
import eu.crushedpixel.replaymod.events.GuiReplayOverlay;
|
||||
import eu.crushedpixel.replaymod.events.RecordingHandler;
|
||||
import eu.crushedpixel.replaymod.events.ReplayTickHandler;
|
||||
import eu.crushedpixel.replaymod.recording.ConnectionEventHandler;
|
||||
import eu.crushedpixel.replaymod.settings.ReplaySettings;
|
||||
|
||||
@@ -78,9 +70,6 @@ public class ReplayMod
|
||||
public void init(FMLInitializationEvent event) {
|
||||
FMLCommonHandler.instance().bus().register(new ConnectionEventHandler());
|
||||
MinecraftForge.EVENT_BUS.register(new GuiEventHandler());
|
||||
ReplayTickHandler tickHandler = new ReplayTickHandler();
|
||||
FMLCommonHandler.instance().bus().register(tickHandler);
|
||||
MinecraftForge.EVENT_BUS.register(tickHandler);
|
||||
|
||||
recordingHandler = new RecordingHandler();
|
||||
FMLCommonHandler.instance().bus().register(recordingHandler);
|
||||
|
||||
@@ -3,7 +3,9 @@ package eu.crushedpixel.replaymod.api.client;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.util.List;
|
||||
@@ -26,6 +28,7 @@ import eu.crushedpixel.replaymod.api.client.holders.Category;
|
||||
import eu.crushedpixel.replaymod.api.client.holders.FileInfo;
|
||||
import eu.crushedpixel.replaymod.api.client.holders.Success;
|
||||
import eu.crushedpixel.replaymod.api.client.holders.UserFiles;
|
||||
import eu.crushedpixel.replaymod.utils.StreamTools;
|
||||
|
||||
public class ApiClient {
|
||||
|
||||
@@ -61,23 +64,25 @@ public class ApiClient {
|
||||
builder.put("auth", auth);
|
||||
builder.put("category", category.getId());
|
||||
String url = builder.toString();
|
||||
|
||||
|
||||
HttpClient client = new DefaultHttpClient();
|
||||
HttpPost post = new HttpPost(url);
|
||||
|
||||
((InputStream)client).close();
|
||||
|
||||
|
||||
FileEntity entity = new FileEntity(file);
|
||||
post.setEntity(entity);
|
||||
HttpResponse response = client.execute(post);
|
||||
|
||||
JsonElement element = jsonParser.parse(EntityUtils.toString(response.getEntity()));
|
||||
try {
|
||||
ApiError err = gson.fromJson(element, ApiError.class);
|
||||
if(err.getDesc() != null) {
|
||||
throw new ApiException(err);
|
||||
}
|
||||
} catch(Exception e) {}
|
||||
|
||||
//((InputStream)client).close(); TODO: Find working solution
|
||||
|
||||
if(response.getStatusLine().getStatusCode() != 200) {
|
||||
JsonElement element = jsonParser.parse(EntityUtils.toString(response.getEntity()));
|
||||
try {
|
||||
ApiError err = gson.fromJson(element, ApiError.class);
|
||||
if(err.getDesc() != null) {
|
||||
throw new ApiException(err);
|
||||
}
|
||||
} catch(Exception e) {}
|
||||
}
|
||||
}
|
||||
|
||||
public void downloadFile(String auth, int file, File target) throws IOException {
|
||||
@@ -86,11 +91,19 @@ public class ApiClient {
|
||||
builder.put("id", file);
|
||||
String url = builder.toString();
|
||||
URL website = new URL(url);
|
||||
InputStream is = website.openStream();
|
||||
try { //If valid json, an error occured
|
||||
jsonParser.parse(StreamTools.readStreamtoString(is));
|
||||
} catch(Exception e) {
|
||||
HttpURLConnection con = (HttpURLConnection)website.openConnection();
|
||||
InputStream is = con.getInputStream();
|
||||
|
||||
if(con.getResponseCode() == 200) {
|
||||
Files.copy(is, target.toPath(), StandardCopyOption.REPLACE_EXISTING);
|
||||
} else {
|
||||
JsonElement element = jsonParser.parse(StreamTools.readStreamtoString(is));
|
||||
try {
|
||||
ApiError err = gson.fromJson(element, ApiError.class);
|
||||
if(err.getDesc() != null) {
|
||||
throw new ApiException(err);
|
||||
}
|
||||
} catch(Exception e) {}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
|
||||
import eu.crushedpixel.replaymod.api.client.holders.ApiError;
|
||||
import eu.crushedpixel.replaymod.utils.StreamTools;
|
||||
|
||||
public class SimpleApiClient {
|
||||
|
||||
@@ -73,7 +74,7 @@ public class SimpleApiClient {
|
||||
HttpURLConnection.setFollowRedirects(false);
|
||||
try {
|
||||
URL url = new URL(urlString);
|
||||
httpUrlConnection = (HttpURLConnection) url.openConnection();
|
||||
httpUrlConnection = (HttpURLConnection)url.openConnection();
|
||||
|
||||
httpUrlConnection.setRequestMethod("GET");
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ public class CameraEntity extends EntityPlayer {
|
||||
private double decay = 6; //decays by 75% per second;
|
||||
|
||||
private long lastCall = 0;
|
||||
|
||||
|
||||
//frac = time since last tick
|
||||
public void updateMovement() {
|
||||
Minecraft mc = Minecraft.getMinecraft();
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package eu.crushedpixel.replaymod.events;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
@@ -9,38 +10,49 @@ import net.minecraft.client.gui.GuiDisconnected;
|
||||
import net.minecraft.client.gui.GuiIngameMenu;
|
||||
import net.minecraft.client.gui.GuiMainMenu;
|
||||
import net.minecraft.client.gui.GuiOptions;
|
||||
import net.minecraft.client.gui.GuiVideoSettings;
|
||||
import net.minecraft.client.gui.inventory.GuiInventory;
|
||||
import net.minecraft.client.resources.I18n;
|
||||
import net.minecraft.client.settings.GameSettings.Options;
|
||||
import net.minecraftforge.client.event.GuiOpenEvent;
|
||||
import net.minecraftforge.client.event.GuiScreenEvent.ActionPerformedEvent;
|
||||
import net.minecraftforge.client.event.GuiScreenEvent.InitGuiEvent;
|
||||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||
import eu.crushedpixel.replaymod.ReplayMod;
|
||||
import eu.crushedpixel.replaymod.authentication.AuthenticationHandler;
|
||||
import eu.crushedpixel.replaymod.gui.GuiExitReplay;
|
||||
import eu.crushedpixel.replaymod.gui.GuiReplayManager;
|
||||
import eu.crushedpixel.replaymod.gui.GuiReplaySaving;
|
||||
import eu.crushedpixel.replaymod.gui.GuiReplaySettings;
|
||||
import eu.crushedpixel.replaymod.recording.ConnectionEventHandler;
|
||||
import eu.crushedpixel.replaymod.gui.replaymanager.GuiReplayManager;
|
||||
import eu.crushedpixel.replaymod.gui.replaymanager.ResourceHelper;
|
||||
import eu.crushedpixel.replaymod.replay.ReplayHandler;
|
||||
|
||||
public class GuiEventHandler {
|
||||
|
||||
private static Minecraft mc = Minecraft.getMinecraft();
|
||||
|
||||
private static List<Class> allowedGUIs = new ArrayList<Class>() {
|
||||
{
|
||||
add(GuiReplaySettings.class);
|
||||
add(GuiReplaySaving.class);
|
||||
add(GuiIngameMenu.class);
|
||||
add(GuiOptions.class);
|
||||
add(GuiVideoSettings.class);
|
||||
}
|
||||
};
|
||||
|
||||
@SubscribeEvent
|
||||
public void onGui(GuiOpenEvent event) {
|
||||
if(!AuthenticationHandler.isAuthenticated()) return;
|
||||
if(event.gui != null && GuiReplaySaving.replaySaving && !allowedGUIs.contains(event.gui.getClass())) {
|
||||
event.gui = new GuiReplaySaving(event.gui);
|
||||
return;
|
||||
}
|
||||
if(!(event.gui instanceof GuiReplayManager)) ResourceHelper.freeResources();
|
||||
if(event.gui instanceof GuiChat || event.gui instanceof GuiInventory) {
|
||||
if(ReplayHandler.replayActive()) {
|
||||
event.setCanceled(true);
|
||||
}
|
||||
}
|
||||
|
||||
else if(event.gui instanceof GuiIngameMenu) {
|
||||
if(ReplayHandler.replayActive()) {
|
||||
event.gui = new GuiExitReplay();
|
||||
}
|
||||
}
|
||||
|
||||
else if(event.gui instanceof GuiDisconnected) {
|
||||
if(!ReplayHandler.replayActive() && System.currentTimeMillis() - ReplayHandler.lastExit < 5000) {
|
||||
event.setCanceled(true);
|
||||
@@ -53,7 +65,18 @@ public class GuiEventHandler {
|
||||
|
||||
@SubscribeEvent
|
||||
public void onInit(InitGuiEvent event) {
|
||||
if(event.gui instanceof GuiMainMenu) {
|
||||
if(event.gui instanceof GuiIngameMenu && ReplayHandler.replayActive()) {
|
||||
for(GuiButton b : new ArrayList<GuiButton>(event.buttonList)) {
|
||||
if(b.id == 1) {
|
||||
b.displayString = "Exit Replay";
|
||||
b.yPosition -= 24*2;
|
||||
} else if(b.id >= 5 && b.id <= 7) {
|
||||
event.buttonList.remove(b);
|
||||
} else if(b.id != 4) {
|
||||
b.yPosition -= 24*2;
|
||||
}
|
||||
}
|
||||
} else if(event.gui instanceof GuiMainMenu) {
|
||||
int i1 = event.gui.height / 4 + 48;
|
||||
|
||||
for(GuiButton b : (List<GuiButton>)event.buttonList) {
|
||||
@@ -69,18 +92,32 @@ public class GuiEventHandler {
|
||||
event.buttonList.add(new GuiButton(9001, event.gui.width / 2 - 155, event.gui.height / 6 + 48 - 6 - 24, 310, 20, "Replay Mod Settings..."));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@SubscribeEvent
|
||||
public void onButton(ActionPerformedEvent event) {
|
||||
if(!AuthenticationHandler.isAuthenticated()) return;
|
||||
if(event.gui instanceof GuiMainMenu && event.button.id == REPLAY_MANAGER_ID) {
|
||||
if(ConnectionEventHandler.saving) {
|
||||
Minecraft.getMinecraft().displayGuiScreen(new GuiReplaySaving());
|
||||
} else {
|
||||
Minecraft.getMinecraft().displayGuiScreen(new GuiReplayManager());
|
||||
}
|
||||
mc.displayGuiScreen(new GuiReplayManager());
|
||||
} else if(event.gui instanceof GuiOptions && event.button.id == REPLAY_OPTIONS_ID) {
|
||||
Minecraft.getMinecraft().displayGuiScreen(new GuiReplaySettings(event.gui));
|
||||
mc.displayGuiScreen(new GuiReplaySettings(event.gui));
|
||||
}
|
||||
|
||||
if(ReplayHandler.isReplaying() && event.gui instanceof GuiIngameMenu && event.button.id == 1) {
|
||||
event.button.enabled = false;
|
||||
Thread t = new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mc.displayGuiScreen(new GuiReplaySaving(new GuiMainMenu()));
|
||||
ReplayHandler.setSpeed(1f);
|
||||
ReplayHandler.endReplay();
|
||||
|
||||
mc.gameSettings.setOptionFloatValue(Options.GAMMA, ReplayHandler.getInitialGamma());
|
||||
|
||||
ReplayHandler.lastExit = System.currentTimeMillis();
|
||||
mc.theWorld.sendQuittingDisconnectingPacket();
|
||||
}
|
||||
});
|
||||
t.run();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.client.GuiIngameForge;
|
||||
import net.minecraftforge.client.event.MouseEvent;
|
||||
import net.minecraftforge.client.event.RenderGameOverlayEvent;
|
||||
import net.minecraftforge.client.event.RenderGameOverlayEvent.ElementType;
|
||||
import net.minecraftforge.client.event.RenderHandEvent;
|
||||
import net.minecraftforge.client.event.RenderWorldLastEvent;
|
||||
import net.minecraftforge.fml.client.FMLClientHandler;
|
||||
@@ -43,6 +44,7 @@ import eu.crushedpixel.replaymod.holders.TimeKeyframe;
|
||||
import eu.crushedpixel.replaymod.reflection.MCPNames;
|
||||
import eu.crushedpixel.replaymod.replay.ReplayHandler;
|
||||
import eu.crushedpixel.replaymod.replay.ReplayProcess;
|
||||
import eu.crushedpixel.replaymod.screenshot.ReplayScreenshot;
|
||||
|
||||
public class GuiReplayOverlay extends Gui {
|
||||
|
||||
@@ -77,6 +79,8 @@ public class GuiReplayOverlay extends Gui {
|
||||
|
||||
private boolean mouseDown = false;
|
||||
|
||||
private boolean requestScreenshot = false;
|
||||
|
||||
private Field drawBlockOutline;
|
||||
|
||||
public GuiReplayOverlay() {
|
||||
@@ -114,6 +118,10 @@ public class GuiReplayOverlay extends Gui {
|
||||
if(mc != null && mc.thePlayer != null)
|
||||
MinecraftTicker.runMouseKeyboardTick(mc);
|
||||
}
|
||||
if(requestScreenshot) {
|
||||
requestScreenshot = false;
|
||||
ReplayScreenshot.saveScreenshot(mc.getFramebuffer());
|
||||
}
|
||||
}
|
||||
|
||||
public void resetUI() throws Exception {
|
||||
@@ -128,10 +136,42 @@ public class GuiReplayOverlay extends Gui {
|
||||
public void onRenderGui(RenderGameOverlayEvent.Post event) throws IllegalArgumentException, IllegalAccessException {
|
||||
if(!ReplayHandler.replayActive()) {
|
||||
GuiIngameForge.renderExperiance = true;
|
||||
GuiIngameForge.renderArmor = true;
|
||||
GuiIngameForge.renderAir = true;
|
||||
GuiIngameForge.renderHealth = true;
|
||||
GuiIngameForge.renderHotbar = true;
|
||||
GuiIngameForge.renderFood = true;
|
||||
GuiIngameForge.renderBossHealth = true;
|
||||
GuiIngameForge.renderCrosshairs = true;
|
||||
GuiIngameForge.renderHelmet = true;
|
||||
GuiIngameForge.renderPortal = true;
|
||||
GuiIngameForge.renderHealthMount = true;
|
||||
GuiIngameForge.renderJumpBar = true;
|
||||
GuiIngameForge.renderObjective = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if(event.type == ElementType.PLAYER_LIST) {
|
||||
if(event.isCancelable()) {
|
||||
event.setCanceled(true);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
GuiIngameForge.renderExperiance = false;
|
||||
GuiIngameForge.renderArmor = false;
|
||||
GuiIngameForge.renderAir = false;
|
||||
GuiIngameForge.renderHealth = false;
|
||||
GuiIngameForge.renderHotbar = false;
|
||||
GuiIngameForge.renderFood = false;
|
||||
GuiIngameForge.renderBossHealth = false;
|
||||
GuiIngameForge.renderCrosshairs = false;
|
||||
GuiIngameForge.renderHelmet = false;
|
||||
GuiIngameForge.renderPortal = false;
|
||||
GuiIngameForge.renderHealthMount = false;
|
||||
GuiIngameForge.renderJumpBar = false;
|
||||
GuiIngameForge.renderObjective = false;
|
||||
|
||||
GL11.glEnable(GL11.GL_BLEND);
|
||||
drawBlockOutline.set(Minecraft.getMinecraft().entityRenderer, false);
|
||||
|
||||
@@ -204,11 +244,11 @@ public class GuiReplayOverlay extends Gui {
|
||||
|
||||
CameraEntity cam = ReplayHandler.getCameraEntity();
|
||||
if(cam != null) {
|
||||
ReplayHandler.setLastPosition(new Position(cam.posX, cam.posY, cam.posZ, cam.rotationPitch, cam.rotationYaw));
|
||||
ReplayHandler.setLastPosition(new Position(cam.posX, cam.posY, cam.posZ, cam.rotationPitch, cam.rotationYaw));
|
||||
} else {
|
||||
ReplayHandler.setLastPosition(null);
|
||||
}
|
||||
|
||||
|
||||
ReplayHandler.setReplayPos((int)time);
|
||||
}
|
||||
}
|
||||
@@ -316,7 +356,7 @@ public class GuiReplayOverlay extends Gui {
|
||||
try {
|
||||
speedSlider.drawButton(mc, mouseX, mouseY);
|
||||
} catch(Exception e) {}
|
||||
|
||||
|
||||
GlStateManager.resetColor();
|
||||
|
||||
Entity player = ReplayHandler.getCameraEntity();
|
||||
@@ -746,7 +786,7 @@ public class GuiReplayOverlay extends Gui {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@SubscribeEvent
|
||||
public void onMouseMove(MouseEvent event) {
|
||||
if(!ReplayHandler.replayActive()) return;
|
||||
@@ -783,15 +823,16 @@ public class GuiReplayOverlay extends Gui {
|
||||
|
||||
@SubscribeEvent
|
||||
public void onKeyInput(KeyInputEvent event) {
|
||||
|
||||
if(!ReplayHandler.replayActive()) return;
|
||||
if(FMLClientHandler.instance().isGUIOpen(GuiMouseInput.class)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(Keyboard.isKeyDown(Keyboard.KEY_V) && !Keyboard.isRepeatEvent() && Keyboard.getKeyCount() == 1) {
|
||||
|
||||
if(Keyboard.isKeyDown(Keyboard.KEY_V) && !Keyboard.isRepeatEvent()) {
|
||||
ReplayMod.replaySettings.setLightingEnabled(!ReplayMod.replaySettings.isLightingEnabled());
|
||||
}
|
||||
|
||||
|
||||
KeyBinding[] keyBindings = Minecraft.getMinecraft().gameSettings.keyBindings;
|
||||
for(KeyBinding kb : keyBindings) {
|
||||
if(!kb.isKeyDown()) {
|
||||
@@ -833,6 +874,12 @@ public class GuiReplayOverlay extends Gui {
|
||||
mc.displayGuiScreen(new GuiMouseInput());
|
||||
continue;
|
||||
}
|
||||
|
||||
//TODO: Register key handlers
|
||||
if(kb.getKeyDescription().equals("key.screenshot") && kb.isPressed()) {
|
||||
ReplayScreenshot.prepareScreenshot();
|
||||
requestScreenshot = true;
|
||||
}
|
||||
} catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
package eu.crushedpixel.replaymod.events;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.WorldRenderer;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.world.WorldSettings.GameType;
|
||||
import net.minecraftforge.client.event.FOVUpdateEvent;
|
||||
import net.minecraftforge.client.event.RenderWorldEvent;
|
||||
import net.minecraftforge.event.entity.player.AchievementEvent;
|
||||
import net.minecraftforge.event.entity.player.PlayerEvent;
|
||||
import net.minecraftforge.event.entity.player.PlayerFlyableFallEvent;
|
||||
import net.minecraftforge.event.entity.player.PlayerInteractEvent;
|
||||
import net.minecraftforge.fml.common.eventhandler.Event;
|
||||
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.gameevent.TickEvent.PlayerTickEvent;
|
||||
import net.minecraftforge.fml.common.gameevent.TickEvent.ServerTickEvent;
|
||||
import eu.crushedpixel.replaymod.reflection.MCPNames;
|
||||
import eu.crushedpixel.replaymod.replay.ReplayHandler;
|
||||
|
||||
public class ReplayTickHandler {
|
||||
|
||||
private Minecraft mc = Minecraft.getMinecraft();
|
||||
|
||||
@SubscribeEvent
|
||||
public void onPlayer(PlayerEvent event) {
|
||||
if(ReplayHandler.replayActive() && event.isCancelable()) {
|
||||
event.setCanceled(true);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
package eu.crushedpixel.replaymod.gui;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import eu.crushedpixel.replaymod.replay.ReplayHandler;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiButton;
|
||||
import net.minecraft.client.gui.GuiIngameMenu;
|
||||
import net.minecraft.client.gui.GuiMainMenu;
|
||||
import net.minecraft.client.multiplayer.WorldClient;
|
||||
import net.minecraft.client.resources.I18n;
|
||||
import net.minecraft.client.settings.GameSettings.Options;
|
||||
|
||||
public class GuiExitReplay extends GuiIngameMenu {
|
||||
|
||||
@Override
|
||||
public void initGui()
|
||||
{
|
||||
this.buttonList.clear();
|
||||
byte b0 = -16;
|
||||
boolean flag = true;
|
||||
this.buttonList.add(new GuiButton(1, this.width / 2 - 100, this.height / 4 + 120 + b0, I18n.format("menu.returnToMenu", new Object[0])));
|
||||
|
||||
if (!this.mc.isIntegratedServerRunning())
|
||||
{
|
||||
((GuiButton)this.buttonList.get(0)).displayString = I18n.format("Exit Replay", new Object[0]);
|
||||
}
|
||||
|
||||
this.buttonList.add(new GuiButton(4, this.width / 2 - 100, this.height / 4 + 24 + b0, I18n.format("menu.returnToGame", new Object[0])));
|
||||
this.buttonList.add(new GuiButton(0, this.width / 2 - 100, this.height / 4 + 96 + b0, 98, 20, I18n.format("menu.options", new Object[0])));
|
||||
this.buttonList.add(new GuiButton(12, this.width / 2 + 2, this.height / 4 + 96 + b0, 98, 20, I18n.format("fml.menu.modoptions")));
|
||||
GuiButton guibutton;
|
||||
this.buttonList.add(guibutton = new GuiButton(7, this.width / 2 - 100, this.height / 4 + 72 + b0, 200, 20, I18n.format("menu.shareToLan", new Object[0])));
|
||||
this.buttonList.add(new GuiButton(5, this.width / 2 - 100, this.height / 4 + 48 + b0, 98, 20, I18n.format("gui.achievements", new Object[0])));
|
||||
this.buttonList.add(new GuiButton(6, this.width / 2 + 2, this.height / 4 + 48 + b0, 98, 20, I18n.format("gui.stats", new Object[0])));
|
||||
guibutton.enabled = this.mc.isSingleplayer() && !this.mc.getIntegratedServer().getPublic();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void actionPerformed(GuiButton button) throws IOException
|
||||
{
|
||||
if(button.id == 1) {
|
||||
button.enabled = false;
|
||||
|
||||
Thread t = new Thread(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
mc.displayGuiScreen(new GuiReplaySaving());
|
||||
ReplayHandler.endReplay();
|
||||
ReplayHandler.setSpeed(1f);
|
||||
|
||||
mc.gameSettings.setOptionFloatValue(Options.GAMMA, ReplayHandler.getInitialGamma());
|
||||
|
||||
ReplayHandler.lastExit = System.currentTimeMillis();
|
||||
mc.theWorld.sendQuittingDisconnectingPacket();
|
||||
}
|
||||
});
|
||||
|
||||
t.run();
|
||||
|
||||
} else {
|
||||
super.actionPerformed(button);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package eu.crushedpixel.replaymod.gui;
|
||||
|
||||
import java.awt.Color;
|
||||
|
||||
import eu.crushedpixel.replaymod.gui.replaymanager.GuiReplayManager;
|
||||
import eu.crushedpixel.replaymod.recording.ConnectionEventHandler;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiIngameMenu;
|
||||
@@ -10,14 +11,22 @@ import net.minecraftforge.fml.client.FMLClientHandler;
|
||||
|
||||
public class GuiReplaySaving extends GuiScreen {
|
||||
|
||||
public static boolean replaySaving = false;
|
||||
|
||||
private GuiScreen waiting = null;
|
||||
|
||||
public GuiReplaySaving(GuiScreen waiting) {
|
||||
this.waiting = waiting;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawScreen(int mouseX, int mouseY, float partialTicks) {
|
||||
this.drawDefaultBackground();
|
||||
this.drawCenteredString(this.fontRendererObj, "Saving Replay File...", this.width / 2, 20, 16777215);
|
||||
this.drawCenteredString(this.fontRendererObj, "Please wait while your recent Replay is being saved.", this.width / 2, 40, 16777215);
|
||||
super.drawScreen(mouseX, mouseY, partialTicks);
|
||||
if(!ConnectionEventHandler.saving) {
|
||||
Minecraft.getMinecraft().displayGuiScreen(new GuiReplayManager());
|
||||
if(!replaySaving) {
|
||||
Minecraft.getMinecraft().displayGuiScreen(waiting);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package eu.crushedpixel.replaymod.gui;
|
||||
package eu.crushedpixel.replaymod.gui.replaymanager;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
@@ -1,11 +1,15 @@
|
||||
package eu.crushedpixel.replaymod.gui;
|
||||
package eu.crushedpixel.replaymod.gui.replaymanager;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.zip.ZipInputStream;
|
||||
|
||||
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.Gui;
|
||||
@@ -13,6 +17,8 @@ import net.minecraft.client.gui.GuiListExtended.IGuiListEntry;
|
||||
import net.minecraft.client.renderer.GlStateManager;
|
||||
import net.minecraft.client.renderer.Tessellator;
|
||||
import net.minecraft.client.renderer.WorldRenderer;
|
||||
import net.minecraft.client.renderer.texture.DynamicTexture;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import eu.crushedpixel.replaymod.recording.ReplayMetaData;
|
||||
|
||||
public class GuiReplayListEntry implements IGuiListEntry {
|
||||
@@ -22,8 +28,11 @@ public class GuiReplayListEntry implements IGuiListEntry {
|
||||
|
||||
private ReplayMetaData metaData;
|
||||
private String fileName;
|
||||
|
||||
|
||||
|
||||
private final ResourceLocation textureResource;
|
||||
private DynamicTexture dynTex = null;
|
||||
|
||||
private BufferedImage image = null;
|
||||
|
||||
public ReplayMetaData getMetaData() {
|
||||
return metaData;
|
||||
@@ -41,20 +50,34 @@ public class GuiReplayListEntry implements IGuiListEntry {
|
||||
this.fileName = fileName;
|
||||
}
|
||||
|
||||
private boolean selected = false;
|
||||
private GuiReplayListExtended parent;
|
||||
|
||||
public GuiReplayListEntry(GuiReplayListExtended parent, String fileName, ReplayMetaData metaData) {
|
||||
public GuiReplayListEntry(GuiReplayListExtended parent, String fileName, ReplayMetaData metaData, BufferedImage image) {
|
||||
this.metaData = metaData;
|
||||
this.fileName = fileName;
|
||||
this.parent = parent;
|
||||
this.textureResource = new ResourceLocation("thumbs/"+fileName);
|
||||
dynTex = null;
|
||||
this.image = image;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawEntry(int slotIndex, int x, int y, int listWidth, int slotHeight, int mouseX, int mouseY, boolean isSelected)
|
||||
{
|
||||
public void drawEntry(int slotIndex, int x, int y, int listWidth, int slotHeight, int mouseX, int mouseY, boolean isSelected) {
|
||||
minecraft.fontRendererObj.drawString(fileName, x + 3, y + 1, 16777215);
|
||||
|
||||
//Draw thumbnail
|
||||
if(image != null) {
|
||||
if(dynTex == null) {
|
||||
dynTex = new DynamicTexture(image);
|
||||
minecraft.getTextureManager().loadTexture(textureResource, dynTex);
|
||||
dynTex.updateDynamicTexture();
|
||||
ResourceHelper.registerResource(textureResource);
|
||||
}
|
||||
|
||||
minecraft.getTextureManager().bindTexture(textureResource); //Will be freed by the ResourceHelper
|
||||
Gui.drawScaledCustomSizeModalRect(x-60, y, 0, 0, 1280, 720, 57, 32, 1280, 720);
|
||||
}
|
||||
|
||||
List<String> list = new ArrayList<String>();
|
||||
list.add(metaData.getServerName()+" ("+dateFormat.format(new Date(metaData.getDate()))+")");
|
||||
|
||||
@@ -67,6 +90,8 @@ public class GuiReplayListEntry implements IGuiListEntry {
|
||||
for (int l1 = 0; l1 < Math.min(list.size(), 2); ++l1) {
|
||||
minecraft.fontRendererObj.drawString((String)list.get(l1), x + 3, y + 12 + minecraft.fontRendererObj.FONT_HEIGHT * l1, 8421504);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1,5 +1,6 @@
|
||||
package eu.crushedpixel.replaymod.gui;
|
||||
package eu.crushedpixel.replaymod.gui.replaymanager;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@@ -48,6 +49,7 @@ public class GuiReplayListExtended extends GuiListExtended {
|
||||
|
||||
for (int j1 = 0; j1 < i1; ++j1)
|
||||
{
|
||||
|
||||
int k1 = p_148120_2_ + j1 * this.slotHeight + this.headerPadding;
|
||||
int l1 = this.slotHeight - 4;
|
||||
|
||||
@@ -76,7 +78,7 @@ public class GuiReplayListExtended extends GuiListExtended {
|
||||
tessellator.draw();
|
||||
GlStateManager.enableTexture2D();
|
||||
}
|
||||
|
||||
|
||||
this.drawSlot(j1, p_148120_1_, k1, l1, p_148120_3_, p_148120_4_);
|
||||
}
|
||||
}
|
||||
@@ -88,8 +90,8 @@ public class GuiReplayListExtended extends GuiListExtended {
|
||||
entries = new ArrayList<GuiReplayListEntry>();
|
||||
}
|
||||
|
||||
public void addEntry(String fileName, ReplayMetaData metaData) {
|
||||
entries.add(new GuiReplayListEntry(this, fileName, metaData));
|
||||
public void addEntry(String fileName, ReplayMetaData metaData, BufferedImage image) {
|
||||
entries.add(new GuiReplayListEntry(this, fileName, metaData, image));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1,5 +1,11 @@
|
||||
package eu.crushedpixel.replaymod.gui;
|
||||
package eu.crushedpixel.replaymod.gui.replaymanager;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.ByteBufInputStream;
|
||||
import io.netty.buffer.Unpooled;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
@@ -12,10 +18,13 @@ import java.util.Comparator;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
import net.minecraft.client.gui.GuiButton;
|
||||
import net.minecraft.client.gui.GuiScreen;
|
||||
import net.minecraft.client.gui.GuiYesNo;
|
||||
import net.minecraft.client.gui.GuiYesNoCallback;
|
||||
import net.minecraft.client.renderer.texture.TextureUtil;
|
||||
import net.minecraft.client.resources.I18n;
|
||||
import net.minecraft.util.Util;
|
||||
|
||||
@@ -28,9 +37,11 @@ import org.lwjgl.input.Keyboard;
|
||||
import com.google.gson.Gson;
|
||||
import com.mojang.realmsclient.util.Pair;
|
||||
|
||||
import eu.crushedpixel.replaymod.gui.GuiReplaySettings;
|
||||
import eu.crushedpixel.replaymod.recording.ConnectionEventHandler;
|
||||
import eu.crushedpixel.replaymod.recording.ReplayMetaData;
|
||||
import eu.crushedpixel.replaymod.replay.ReplayHandler;
|
||||
import eu.crushedpixel.replaymod.utils.ImageUtils;
|
||||
|
||||
public class GuiReplayManager extends GuiScreen implements GuiYesNoCallback {
|
||||
|
||||
@@ -41,12 +52,12 @@ public class GuiReplayManager extends GuiScreen implements GuiYesNoCallback {
|
||||
private String hoveringText;
|
||||
private boolean initialized;
|
||||
private GuiReplayListExtended replayGuiList;
|
||||
private List<Pair<File, ReplayMetaData>> replayFileList = new ArrayList<Pair<File, ReplayMetaData>>();
|
||||
private List<Pair<Pair<File, ReplayMetaData>, BufferedImage>> replayFileList = new ArrayList<Pair<Pair<File, ReplayMetaData>, BufferedImage>>();
|
||||
private GuiButton loadButton, folderButton, renameButton, deleteButton, cancelButton, settingsButton;
|
||||
|
||||
private static Gson gson = new Gson();
|
||||
private boolean replaying = false;
|
||||
|
||||
|
||||
private static final int LOAD_BUTTON_ID = 9001;
|
||||
private static final int FOLDER_BUTTON_ID = 9002;
|
||||
private static final int RENAME_BUTTON_ID = 9003;
|
||||
@@ -55,14 +66,14 @@ public class GuiReplayManager extends GuiScreen implements GuiYesNoCallback {
|
||||
private static final int CANCEL_BUTTON_ID = 9006;
|
||||
|
||||
private boolean delete_file = false;
|
||||
|
||||
|
||||
private void reloadFiles() {
|
||||
replayGuiList.clearEntries();
|
||||
replayFileList = new ArrayList<Pair<File, ReplayMetaData>>();
|
||||
replayFileList = new ArrayList<Pair<Pair<File, ReplayMetaData>, BufferedImage>>();
|
||||
|
||||
File folder = new File("./replay_recordings/");
|
||||
folder.mkdirs();
|
||||
|
||||
|
||||
for(File file : folder.listFiles()) {
|
||||
if(("."+FilenameUtils.getExtension(file.getAbsolutePath())).equals(ConnectionEventHandler.ZIP_FILE_EXTENSION)) {
|
||||
try {
|
||||
@@ -70,14 +81,33 @@ public class GuiReplayManager extends GuiScreen implements GuiYesNoCallback {
|
||||
ZipArchiveEntry recfile = archive.getEntry("recording"+ConnectionEventHandler.TEMP_FILE_EXTENSION);
|
||||
ZipArchiveEntry metadata = archive.getEntry("metaData"+ConnectionEventHandler.JSON_FILE_EXTENSION);
|
||||
|
||||
ZipArchiveEntry image = archive.getEntry("thumb");
|
||||
BufferedImage img = null;
|
||||
if(image != null) {
|
||||
InputStream is = archive.getInputStream(image);
|
||||
is.skip(7);
|
||||
BufferedImage bimg = ImageIO.read(is);
|
||||
if(bimg != null) {
|
||||
img = ImageUtils.scaleImage(bimg, new Dimension(1280, 720));
|
||||
}
|
||||
|
||||
/* Old way of reading thumbnail
|
||||
else {
|
||||
is = archive.getInputStream(image);
|
||||
bimg = ImageIO.read(is);
|
||||
img = ImageUtils.scaleImage(bimg, new Dimension(1280, 720));
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
InputStream is = archive.getInputStream(metadata);
|
||||
BufferedReader br = new BufferedReader(new InputStreamReader(is));
|
||||
|
||||
|
||||
String json = br.readLine();
|
||||
|
||||
|
||||
ReplayMetaData metaData = gson.fromJson(json, ReplayMetaData.class);
|
||||
|
||||
replayFileList.add(Pair.of(file, metaData));
|
||||
|
||||
replayFileList.add(Pair.of(Pair.of(file, metaData), img));
|
||||
|
||||
archive.close();
|
||||
} catch(Exception e) {
|
||||
@@ -85,21 +115,25 @@ public class GuiReplayManager extends GuiScreen implements GuiYesNoCallback {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Collections.sort(replayFileList, new FileAgeComparator());
|
||||
|
||||
for(Pair<File, ReplayMetaData> p : replayFileList) {
|
||||
replayGuiList.addEntry(FilenameUtils.getBaseName(p.first().getName()), p.second());
|
||||
|
||||
for(Pair<Pair<File, ReplayMetaData>, BufferedImage> p : replayFileList) {
|
||||
replayGuiList.addEntry(FilenameUtils.getBaseName(p.first().first().getName()), p.first().second(), p.second());
|
||||
}
|
||||
}
|
||||
|
||||
public class FileAgeComparator implements Comparator<Pair<File, ReplayMetaData>> {
|
||||
|
||||
public class FileAgeComparator implements Comparator<Pair<Pair<File, ReplayMetaData>, BufferedImage>> {
|
||||
|
||||
@Override
|
||||
public int compare(Pair<File, ReplayMetaData> o1, Pair<File, ReplayMetaData> o2) {
|
||||
return (int)(new Date(o2.second().getDate()).compareTo(new Date(o1.second().getDate())));
|
||||
public int compare(Pair<Pair<File, ReplayMetaData>, BufferedImage> o1, Pair<Pair<File, ReplayMetaData>, BufferedImage> o2) {
|
||||
try {
|
||||
return (int)(new Date(o2.first().second().getDate()).compareTo(new Date(o1.first().second().getDate())));
|
||||
} catch(Exception e) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void initGui()
|
||||
@@ -183,7 +217,7 @@ public class GuiReplayManager extends GuiScreen implements GuiYesNoCallback {
|
||||
}
|
||||
else if(button.id == RENAME_BUTTON_ID)
|
||||
{
|
||||
File file = replayFileList.get(replayGuiList.selected).first();
|
||||
File file = replayFileList.get(replayGuiList.selected).first().first();
|
||||
this.mc.displayGuiScreen(new GuiRenameReplay(this, file));
|
||||
}
|
||||
else if(button.id == FOLDER_BUTTON_ID)
|
||||
@@ -241,7 +275,7 @@ public class GuiReplayManager extends GuiScreen implements GuiYesNoCallback {
|
||||
|
||||
if (result)
|
||||
{
|
||||
replayFileList.get(replayGuiList.selected).first().delete();
|
||||
replayFileList.get(replayGuiList.selected).first().first().delete();
|
||||
replayFileList.remove(replayGuiList.selected);
|
||||
}
|
||||
|
||||
@@ -265,16 +299,15 @@ public class GuiReplayManager extends GuiScreen implements GuiYesNoCallback {
|
||||
deleteButton.enabled = b;
|
||||
}
|
||||
|
||||
public void loadReplay(int id)
|
||||
{
|
||||
mc.displayGuiScreen((GuiScreen)null);
|
||||
public void loadReplay(int id) {
|
||||
mc.displayGuiScreen((GuiScreen)null);
|
||||
|
||||
try {
|
||||
ReplayHandler.startReplay(replayFileList.get(id).first());
|
||||
try {
|
||||
ReplayHandler.startReplay(replayFileList.get(id).first().first());
|
||||
} catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package eu.crushedpixel.replaymod.gui.replaymanager;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
|
||||
public class ResourceHelper {
|
||||
|
||||
private static List<ResourceLocation> openResources = new ArrayList<ResourceLocation>();
|
||||
|
||||
public static void registerResource(ResourceLocation loc) {
|
||||
openResources.add(loc);
|
||||
}
|
||||
|
||||
public static void freeResources() {
|
||||
for(ResourceLocation loc : openResources) {
|
||||
Minecraft.getMinecraft().getTextureManager().deleteTexture(loc);
|
||||
}
|
||||
|
||||
openResources = new ArrayList<ResourceLocation>();
|
||||
}
|
||||
}
|
||||
@@ -39,8 +39,6 @@ public class ConnectionEventHandler {
|
||||
private static PacketListener packetListener = null;
|
||||
|
||||
private static boolean isRecording = false;
|
||||
|
||||
public static boolean saving = false;
|
||||
|
||||
public static boolean isRecording() {
|
||||
return isRecording;
|
||||
|
||||
@@ -23,6 +23,7 @@ import net.minecraft.client.Minecraft;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
|
||||
import eu.crushedpixel.replaymod.gui.GuiReplaySaving;
|
||||
import eu.crushedpixel.replaymod.holders.PacketData;
|
||||
|
||||
public abstract class DataListener extends ChannelInboundHandlerAdapter {
|
||||
@@ -144,7 +145,7 @@ public abstract class DataListener extends ChannelInboundHandlerAdapter {
|
||||
byte[] buffer = new byte[1024];
|
||||
|
||||
try {
|
||||
ConnectionEventHandler.saving = true;
|
||||
GuiReplaySaving.replaySaving = true;
|
||||
|
||||
String mcversion = Minecraft.getMinecraft().getVersion();
|
||||
String[] pl = players.toArray(new String[players.size()]);
|
||||
@@ -181,10 +182,10 @@ public abstract class DataListener extends ChannelInboundHandlerAdapter {
|
||||
|
||||
file.delete();
|
||||
|
||||
ConnectionEventHandler.saving = false;
|
||||
GuiReplaySaving.replaySaving = false;
|
||||
} catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
ConnectionEventHandler.saving = false;
|
||||
GuiReplaySaving.replaySaving = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -389,4 +389,11 @@ public class ReplayHandler {
|
||||
public static Position getLastPosition() {
|
||||
return lastPosition;
|
||||
}
|
||||
|
||||
public static File getReplayFile() {
|
||||
if(replaySender != null) {
|
||||
return replaySender.getReplayFile();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -523,4 +523,8 @@ public class ReplaySender extends ChannelInboundHandlerAdapter {
|
||||
//return timeInfo.get().getSpeed();
|
||||
}
|
||||
|
||||
public File getReplayFile() {
|
||||
return replayFile;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,234 @@
|
||||
package eu.crushedpixel.replaymod.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();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -20,9 +20,9 @@ public class ReplaySettings {
|
||||
private boolean showNotifications = true;
|
||||
private boolean forceLinearPath = false;
|
||||
private boolean lightingEnabled = false;
|
||||
|
||||
|
||||
private static Field mcTimer;
|
||||
|
||||
|
||||
static {
|
||||
try {
|
||||
mcTimer = Minecraft.class.getDeclaredField(MCPNames.field("field_71428_T"));
|
||||
@@ -89,13 +89,17 @@ public class ReplaySettings {
|
||||
Minecraft.getMinecraft().gameSettings.setOptionFloatValue(Options.GAMMA, ReplayHandler.getInitialGamma());
|
||||
}
|
||||
try {
|
||||
Timer timer = (Timer)mcTimer.get(Minecraft.getMinecraft());
|
||||
timer.elapsedPartialTicks++;
|
||||
timer.renderPartialTicks++;
|
||||
if(ReplayHandler.isPaused()) {
|
||||
Timer timer = (Timer)mcTimer.get(Minecraft.getMinecraft());
|
||||
timer.elapsedPartialTicks++;
|
||||
timer.renderPartialTicks++;
|
||||
} else {
|
||||
Minecraft.getMinecraft().entityRenderer.updateCameraAndRender(0);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
|
||||
rewriteSettings();
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
package eu.crushedpixel.replaymod.utils;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
public class ImageUtils {
|
||||
|
||||
public static BufferedImage scaleImage(BufferedImage img, Dimension d) {
|
||||
img = scaleByHalf(img, d);
|
||||
img = scaleExact(img, d);
|
||||
return img;
|
||||
}
|
||||
|
||||
private static BufferedImage scaleByHalf(BufferedImage img, Dimension d) {
|
||||
int w = img.getWidth();
|
||||
int h = img.getHeight();
|
||||
float factor = getBinFactor(w, h, d);
|
||||
|
||||
// make new size
|
||||
w *= factor;
|
||||
h *= factor;
|
||||
BufferedImage scaled = new BufferedImage(w, h,
|
||||
BufferedImage.TYPE_INT_RGB);
|
||||
Graphics2D g = scaled.createGraphics();
|
||||
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
|
||||
RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
|
||||
g.drawImage(img, 0, 0, w, h, null);
|
||||
g.dispose();
|
||||
return scaled;
|
||||
}
|
||||
|
||||
private static BufferedImage scaleExact(BufferedImage img, Dimension d) {
|
||||
float factor = getFactor(img.getWidth(), img.getHeight(), d);
|
||||
|
||||
// create the image
|
||||
int w = (int) (img.getWidth() * factor);
|
||||
int h = (int) (img.getHeight() * factor);
|
||||
BufferedImage scaled = new BufferedImage(w, h,
|
||||
BufferedImage.TYPE_INT_RGB);
|
||||
|
||||
Graphics2D g = scaled.createGraphics();
|
||||
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
|
||||
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
|
||||
g.drawImage(img, 0, 0, w, h, null);
|
||||
g.dispose();
|
||||
return scaled;
|
||||
}
|
||||
|
||||
static float getBinFactor(int width, int height, Dimension dim) {
|
||||
float factor = 1;
|
||||
float target = getFactor(width, height, dim);
|
||||
if (target <= 1) { while (factor / 2 > target) { factor /= 2; }
|
||||
} else { while (factor * 2 < target) { factor *= 2; } }
|
||||
return factor;
|
||||
}
|
||||
|
||||
static float getFactor(int width, int height, Dimension dim) {
|
||||
float sx = dim.width / (float) width;
|
||||
float sy = dim.height / (float) height;
|
||||
return Math.min(sx, sy);
|
||||
}
|
||||
|
||||
public static BufferedImage cropImage(BufferedImage src, Rectangle rect) {
|
||||
return src.getSubimage(rect.x, rect.y, rect.width, rect.height);
|
||||
}
|
||||
}
|
||||
@@ -15,7 +15,7 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
package eu.crushedpixel.replaymod.api.client;
|
||||
package eu.crushedpixel.replaymod.utils;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
@@ -0,0 +1,59 @@
|
||||
package eu.crushedpixel.replaymod.utils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
public class ZipFileUtils {
|
||||
|
||||
public static void deleteZipEntry(File zipFile,
|
||||
String[] files) throws IOException {
|
||||
// get a temp file
|
||||
File tempFile = File.createTempFile(zipFile.getName(), null);
|
||||
// delete it, otherwise you cannot rename your existing zip to it.
|
||||
tempFile.delete();
|
||||
tempFile.deleteOnExit();
|
||||
boolean renameOk=zipFile.renameTo(tempFile);
|
||||
if (!renameOk)
|
||||
{
|
||||
throw new RuntimeException("could not rename the file "+zipFile.getAbsolutePath()+" to "+tempFile.getAbsolutePath());
|
||||
}
|
||||
byte[] buf = new byte[1024];
|
||||
|
||||
ZipInputStream zin = new ZipInputStream(new FileInputStream(tempFile));
|
||||
ZipOutputStream zout = new ZipOutputStream(new FileOutputStream(zipFile));
|
||||
|
||||
ZipEntry entry = zin.getNextEntry();
|
||||
while (entry != null) {
|
||||
String name = entry.getName();
|
||||
boolean toBeDeleted = false;
|
||||
for (String f : files) {
|
||||
if (f.equals(name)) {
|
||||
toBeDeleted = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!toBeDeleted) {
|
||||
// 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();
|
||||
}
|
||||
// Close the streams
|
||||
zin.close();
|
||||
// Compress the files
|
||||
// Complete the ZIP file
|
||||
zout.close();
|
||||
tempFile.delete();
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user